diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/bo/ErpServerInfoBo.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/bo/ErpServerInfoBo.java new file mode 100644 index 00000000..1e392430 --- /dev/null +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/bo/ErpServerInfoBo.java @@ -0,0 +1,73 @@ +package org.dromara.oa.erp.domain.bo; + +import cn.hutool.core.util.ObjectUtil; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.dromara.common.core.validate.EditGroup; +import org.dromara.common.mybatis.core.domain.BaseEntity; +import org.dromara.oa.erp.domain.ErpServerInfo; +import org.dromara.workflow.api.domain.RemoteFlowInstanceBizExt; + +import jakarta.validation.constraints.NotNull; +import java.math.BigDecimal; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +/** + * 服务器基础信息业务对象 erp_server_info + * + * @author zch + * @date 2026-06-03 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@AutoMapper(target = ErpServerInfo.class, reverseConvertGenerate = false) +public class ErpServerInfoBo extends BaseEntity { + + @NotNull(message = "服务器ID不能为空", groups = { EditGroup.class }) + private Long serverId; + private String serverCode; + private String serverName; + private Integer version; + private String isCurrent; + private String serverType; + private String acquisitionType; + private String osType; + private String hasPublicIp; + private String ipAddress; + private String location; + private BigDecimal purchaseAmount; + private String brand; + private String model; + private String hardwareSpec; + private Date leaseStartDate; + private Date leaseEndDate; + private Integer leasePackageYears; + private BigDecimal leaseAmount; + private String serverStatus; + private String flowStatus; + private String extAttr; + private String remark; + private String flowCode; + private String handler; + private Map variables; + private RemoteFlowInstanceBizExt bizExt; + + public Map getVariables() { + if (variables == null) { + variables = new HashMap<>(16); + } + variables.entrySet().removeIf(entry -> Objects.isNull(entry.getValue())); + return variables; + } + + public RemoteFlowInstanceBizExt getBizExt() { + if (ObjectUtil.isNull(bizExt)) { + bizExt = new RemoteFlowInstanceBizExt(); + } + return bizExt; + } +} diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/bo/ErpTempTaskBo.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/bo/ErpTempTaskBo.java index fc6ea025..b56e32f3 100644 --- a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/bo/ErpTempTaskBo.java +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/bo/ErpTempTaskBo.java @@ -46,7 +46,7 @@ public class ErpTempTaskBo extends BaseEntity { /** * 任务描述(发起必填) */ - @NotBlank(message = "任务描述(发起必填)不能为空", groups = { AddGroup.class, EditGroup.class }) + @NotBlank(message = "任务描述不能为空", groups = { AddGroup.class, EditGroup.class }) private String taskDesc; /** @@ -62,7 +62,7 @@ public class ErpTempTaskBo extends BaseEntity { /** * 需求时间=发起方期望最晚完成时间(发起必填) */ - @NotNull(message = "需求时间=发起方期望最晚完成时间(发起必填)不能为空", groups = { AddGroup.class, EditGroup.class }) + @NotNull(message = "需求时间不能为空", groups = { AddGroup.class, EditGroup.class }) private Date requireTime; /** diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/bo/ErpTempTaskChangeBo.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/bo/ErpTempTaskChangeBo.java index 73cefe59..c7aad90d 100644 --- a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/bo/ErpTempTaskChangeBo.java +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/bo/ErpTempTaskChangeBo.java @@ -42,7 +42,7 @@ public class ErpTempTaskChangeBo extends BaseEntity { /** * 变更项类型:1任务描述 2工时 3需求时间 4指派人/执行人 5可报工项目 6执行范围 7终止/不执行 */ - @NotBlank(message = "变更项类型:1任务描述 2工时 3需求时间 4指派人/执行人 5可报工项目 6执行范围 7终止/不执行不能为空", groups = { AddGroup.class, EditGroup.class }) + @NotBlank(message = "变更类型不能为空", groups = { AddGroup.class, EditGroup.class }) private String changeType; /** @@ -79,7 +79,7 @@ public class ErpTempTaskChangeBo extends BaseEntity { /** * 变更发起人ID(发起人/执行人/软件部领导) */ - @NotNull(message = "变更发起人ID(发起人/执行人/软件部领导)不能为空", groups = { AddGroup.class, EditGroup.class }) + @NotNull(message = "变更发起人ID不能为空", groups = { AddGroup.class, EditGroup.class }) private Long changeUserId; /** diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/vo/ErpTempTaskChangeVo.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/vo/ErpTempTaskChangeVo.java index ccf88b16..c6185be6 100644 --- a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/vo/ErpTempTaskChangeVo.java +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/vo/ErpTempTaskChangeVo.java @@ -1,7 +1,6 @@ package org.dromara.oa.erp.domain.vo; import java.util.Date; -import com.fasterxml.jackson.annotation.JsonFormat; import org.dromara.oa.erp.domain.ErpTempTaskChange; import cn.idev.excel.annotation.ExcelIgnoreUnannotated; import cn.idev.excel.annotation.ExcelProperty; @@ -12,7 +11,6 @@ import lombok.Data; import java.io.Serial; import java.io.Serializable; -import java.util.Date; @@ -33,25 +31,24 @@ public class ErpTempTaskChangeVo implements Serializable { /** * 变更记录ID */ - @ExcelProperty(value = "变更记录ID") private Long changeId; /** * 临时任务ID */ - @ExcelProperty(value = "临时任务ID") private Long tempTaskId; /** * 任务编号快照 */ - @ExcelProperty(value = "任务编号快照") + @ExcelProperty(value = "任务编号") private String tempTaskCode; /** - * 变更项类型:1任务描述 2工时 3需求时间 4指派人/执行人 5可报工项目 6执行范围 7终止/不执行 + * 变更项类型 */ - @ExcelProperty(value = "变更项类型:1任务描述 2工时 3需求时间 4指派人/执行人 5可报工项目 6执行范围 7终止/不执行") + @ExcelProperty(value = "变更类型", converter = ExcelDictConvert.class) + @ExcelDictFormat(dictType = "temp_task_change_type") private String changeType; /** @@ -73,56 +70,50 @@ public class ErpTempTaskChangeVo implements Serializable { private String afterContent; /** - * 工时影响(变更后预计工时/增减) + * 工时影响 */ - @ExcelProperty(value = "工时影响", converter = ExcelDictConvert.class) - @ExcelDictFormat(readConverterExp = "变=更后预计工时/增减") + @ExcelProperty(value = "工时影响") private String workloadEffect; /** - * 时间影响(是否影响需求/确认完成时间) + * 时间影响 */ - @ExcelProperty(value = "时间影响", converter = ExcelDictConvert.class) - @ExcelDictFormat(readConverterExp = "是=否影响需求/确认完成时间") + @ExcelProperty(value = "时间影响") private String timeEffect; /** - * 执行影响说明(是否影响排期/其他任务/范围) + * 执行影响说明 */ - @ExcelProperty(value = "执行影响说明", converter = ExcelDictConvert.class) - @ExcelDictFormat(readConverterExp = "是=否影响排期/其他任务/范围") + @ExcelProperty(value = "执行影响") private String scopeEffect; /** - * 变更发起人ID(发起人/执行人/软件部领导) + * 变更发起人ID */ - @ExcelProperty(value = "变更发起人ID", converter = ExcelDictConvert.class) - @ExcelDictFormat(readConverterExp = "发=起人/执行人/软件部领导") private Long changeUserId; /** * 变更发起人姓名快照 */ - @ExcelProperty(value = "变更发起人姓名快照") + @ExcelProperty(value = "变更发起人") private String changeUserName; /** - * 审批结论:1通过 2不通过 3退回补充 4终止/不执行 + * 审批结论 */ - @ExcelProperty(value = "审批结论:1通过 2不通过 3退回补充 4终止/不执行") + @ExcelProperty(value = "审批结论", converter = ExcelDictConvert.class) + @ExcelDictFormat(dictType = "temp_task_change_result") private String approveResult; /** - * 审批人ID(软件部领导) + * 审批人ID */ - @ExcelProperty(value = "审批人ID", converter = ExcelDictConvert.class) - @ExcelDictFormat(readConverterExp = "软=件部领导") private Long approverId; /** * 审批人姓名快照 */ - @ExcelProperty(value = "审批人姓名快照") + @ExcelProperty(value = "审批人") private String approverName; /** @@ -138,11 +129,16 @@ public class ErpTempTaskChangeVo implements Serializable { private Date approveTime; /** - * 变更审批流程状态(如走独立审批) + * 变更审批流程状态 */ - @ExcelProperty(value = "变更审批流程状态", converter = ExcelDictConvert.class) - @ExcelDictFormat(readConverterExp = "如=走独立审批") + @ExcelProperty(value = "审批状态", converter = ExcelDictConvert.class) + @ExcelDictFormat(dictType = "wf_business_status") private String flowStatus; + /** + * 创建时间 + */ + @ExcelProperty(value = "创建时间") + private Date createTime; } diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/vo/ErpTempTaskVo.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/vo/ErpTempTaskVo.java index 23a67e4a..604fe5ab 100644 --- a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/vo/ErpTempTaskVo.java +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/vo/ErpTempTaskVo.java @@ -13,7 +13,6 @@ import lombok.Data; import java.io.Serial; import java.io.Serializable; -import java.util.Date; @@ -34,14 +33,12 @@ public class ErpTempTaskVo implements Serializable { /** * 临时任务ID */ - @ExcelProperty(value = "临时任务ID") private Long tempTaskId; /** - * 任务编号(LSRW+yyyyMMdd+4位,草稿即生成且全程不变) + * 任务编号 */ - @ExcelProperty(value = "任务编号", converter = ExcelDictConvert.class) - @ExcelDictFormat(readConverterExp = "L=SRW+yyyyMMdd+4位,草稿即生成且全程不变") + @ExcelProperty(value = "任务编号") private String tempTaskCode; /** @@ -51,240 +48,219 @@ public class ErpTempTaskVo implements Serializable { private String taskTitle; /** - * 任务描述(发起必填) + * 任务描述 */ - @ExcelProperty(value = "任务描述", converter = ExcelDictConvert.class) - @ExcelDictFormat(readConverterExp = "发=起必填") + @ExcelProperty(value = "任务描述") private String taskDesc; /** * 优先级:1普通 2较急 3紧急 4特急 */ - @ExcelProperty(value = "优先级:1普通 2较急 3紧急 4特急") + @ExcelProperty(value = "优先级", converter = ExcelDictConvert.class) + @ExcelDictFormat(dictType = "temp_task_priority") private String priority; /** - * 紧急原因(优先级为紧急/特急时必填) + * 紧急原因 */ - @ExcelProperty(value = "紧急原因", converter = ExcelDictConvert.class) - @ExcelDictFormat(readConverterExp = "优=先级为紧急/特急时必填") + @ExcelProperty(value = "紧急原因") private String urgentReason; /** - * 需求时间=发起方期望最晚完成时间(发起必填) + * 需求时间 */ - @ExcelProperty(value = "需求时间=发起方期望最晚完成时间", converter = ExcelDictConvert.class) - @ExcelDictFormat(readConverterExp = "发=起必填") + @ExcelProperty(value = "需求时间") private Date requireTime; /** - * 确认完成时间=领导审核确认的承诺完成时间 + * 确认完成时间 */ - @ExcelProperty(value = "确认完成时间=领导审核确认的承诺完成时间") + @ExcelProperty(value = "确认完成时间") private Date confirmFinishTime; /** - * 实际开始时间(仅记周期,不计工时) + * 实际开始时间 */ - @ExcelProperty(value = "实际开始时间", converter = ExcelDictConvert.class) - @ExcelDictFormat(readConverterExp = "仅=记周期,不计工时") + @ExcelProperty(value = "实际开始时间") private Date actualStartTime; /** - * 实际结束/关闭时间(仅记周期,不计工时) + * 实际结束/关闭时间 */ - @ExcelProperty(value = "实际结束/关闭时间", converter = ExcelDictConvert.class) - @ExcelDictFormat(readConverterExp = "仅=记周期,不计工时") + @ExcelProperty(value = "实际结束时间") private Date actualFinishTime; /** * 主报工项目ID */ - @ExcelProperty(value = "主报工项目ID") private Long projectId; /** * 项目编号快照 */ - @ExcelProperty(value = "项目编号快照") + @ExcelProperty(value = "项目编号") private String projectCode; /** * 项目名称快照 */ - @ExcelProperty(value = "项目名称快照") + @ExcelProperty(value = "项目名称") private String projectName; /** * 项目经理用户ID快照 */ - @ExcelProperty(value = "项目经理用户ID快照") private Long pmId; /** * 项目经理姓名快照 */ - @ExcelProperty(value = "项目经理姓名快照") + @ExcelProperty(value = "项目经理") private String pmName; /** - * 关联合同ID(选填) + * 关联合同ID */ - @ExcelProperty(value = "关联合同ID", converter = ExcelDictConvert.class) - @ExcelDictFormat(readConverterExp = "选=填") private Long contractId; /** * 合同编号快照 */ - @ExcelProperty(value = "合同编号快照") + @ExcelProperty(value = "合同编号") private String contractCode; /** * 发起人ID */ - @ExcelProperty(value = "发起人ID") private Long requesterId; /** * 发起人姓名快照 */ - @ExcelProperty(value = "发起人姓名快照") + @ExcelProperty(value = "发起人") private String requesterName; /** * 发起部门ID */ - @ExcelProperty(value = "发起部门ID") private Long requestDeptId; /** * 发起部门名称快照 */ - @ExcelProperty(value = "发起部门名称快照") + @ExcelProperty(value = "发起部门") private String requestDeptName; /** - * 指派人/建议承接人ID(非必填) + * 指派人/建议承接人ID */ - @ExcelProperty(value = "指派人/建议承接人ID", converter = ExcelDictConvert.class) - @ExcelDictFormat(readConverterExp = "非=必填") private Long dispatcherId; /** * 指派人姓名快照 */ - @ExcelProperty(value = "指派人姓名快照") + @ExcelProperty(value = "指派人") private String dispatcherName; /** - * 软件部领导/审批人ID(审核/加批/变更审批) + * 软件部领导/审批人ID */ - @ExcelProperty(value = "软件部领导/审批人ID", converter = ExcelDictConvert.class) - @ExcelDictFormat(readConverterExp = "审=核/加批/变更审批") private Long softwareLeaderId; /** * 软件部领导姓名快照 */ - @ExcelProperty(value = "软件部领导姓名快照") + @ExcelProperty(value = "软件部领导") private String softwareLeaderName; /** - * 主执行人ID(唯一,领导审核确定) + * 主执行人ID */ - @ExcelProperty(value = "主执行人ID", converter = ExcelDictConvert.class) - @ExcelDictFormat(readConverterExp = "唯=一,领导审核确定") private Long assigneeId; /** * 主执行人姓名快照 */ - @ExcelProperty(value = "主执行人姓名快照") + @ExcelProperty(value = "主执行人") private String assigneeName; /** - * 预计工时/小时(指派人确认阶段补齐,领导审核认可) + * 预计工时/小时 */ - @ExcelProperty(value = "预计工时/小时", converter = ExcelDictConvert.class) - @ExcelDictFormat(readConverterExp = "指=派人确认阶段补齐,领导审核认可") + @ExcelProperty(value = "预计工时(小时)") private BigDecimal estimateWorkload; /** - * 实际消耗工时/小时(关闭时填写,0需说明,最小0.5) + * 实际消耗工时/小时 */ - @ExcelProperty(value = "实际消耗工时/小时", converter = ExcelDictConvert.class) - @ExcelDictFormat(readConverterExp = "关=闭时填写,0需说明,最小0.5") + @ExcelProperty(value = "实际消耗工时(小时)") private BigDecimal actualWorkload; /** - * 完成结果:1已完成 2不执行/终止 3部分完成后终止(仅闭环写入) + * 完成结果:1已完成 2不执行/终止 3部分完成后终止 */ - @ExcelProperty(value = "完成结果:1已完成 2不执行/终止 3部分完成后终止", converter = ExcelDictConvert.class) - @ExcelDictFormat(readConverterExp = "仅=闭环写入") + @ExcelProperty(value = "完成结果", converter = ExcelDictConvert.class) + @ExcelDictFormat(dictType = "temp_task_finish_result") private String finishResult; /** - * 不执行/终止原因:1无需处理 2重复任务 3需求取消 4条件不满足 5资源不支持 6范围不合理 7其他 + * 不执行/终止原因 */ - @ExcelProperty(value = "不执行/终止原因:1无需处理 2重复任务 3需求取消 4条件不满足 5资源不支持 6范围不合理 7其他") + @ExcelProperty(value = "终止原因", converter = ExcelDictConvert.class) + @ExcelDictFormat(dictType = "temp_task_terminate_reason") private String terminateReason; /** - * 完成说明(关闭必填;0工时/终止其他原因在此补充) + * 完成说明 */ - @ExcelProperty(value = "完成说明", converter = ExcelDictConvert.class) - @ExcelDictFormat(readConverterExp = "关=闭必填;0工时/终止其他原因在此补充") + @ExcelProperty(value = "完成说明") private String finishRemark; /** * 关联原任务ID */ - @ExcelProperty(value = "关联原任务ID") private Long relatedTaskId; /** * 关联原任务编号快照 */ - @ExcelProperty(value = "关联原任务编号快照") + @ExcelProperty(value = "关联原任务编号") private String relatedTaskCode; /** - * 关联原因:1关闭后异议 2遗漏补充 3返工处理 4换人承接 5需求延续 6重新发起 7其他 + * 关联原因 */ - @ExcelProperty(value = "关联原因:1关闭后异议 2遗漏补充 3返工处理 4换人承接 5需求延续 6重新发起 7其他") + @ExcelProperty(value = "关联原因", converter = ExcelDictConvert.class) + @ExcelDictFormat(dictType = "temp_task_relate_reason") private String relateReason; /** * 关联原因补充说明 */ - @ExcelProperty(value = "关联原因补充说明") private String relateRemark; /** * 业务状态:1暂存 2进行中(审批/执行) 3已结束 4作废 */ - @ExcelProperty(value = "业务状态:1暂存 2进行中(审批/执行) 3已结束 4作废") + @ExcelProperty(value = "业务状态", converter = ExcelDictConvert.class) + @ExcelDictFormat(dictType = "temp_task_status") private String taskStatus; /** - * 流程状态:draft/waiting/finish/back/cancel/invalid/termination + * 流程状态 */ - @ExcelProperty(value = "流程状态:draft/waiting/finish/back/cancel/invalid/termination") + @ExcelProperty(value = "流程状态", converter = ExcelDictConvert.class) + @ExcelDictFormat(dictType = "wf_business_status") private String flowStatus; /** - * 抄送人员用户ID(多个逗号分隔,实际抄送由工作流承载) + * 抄送人员用户ID */ - @ExcelProperty(value = "抄送人员用户ID", converter = ExcelDictConvert.class) - @ExcelDictFormat(readConverterExp = "多=个逗号分隔,实际抄送由工作流承载") private String ccUserIds; /** - * 附件ID(非必填,多个逗号分隔) + * 附件ID */ - @ExcelProperty(value = "附件ID", converter = ExcelDictConvert.class) - @ExcelDictFormat(readConverterExp = "非=必填,多个逗号分隔") private String ossId; /** @@ -303,4 +279,10 @@ public class ErpTempTaskVo implements Serializable { */ private Long pendingChangeCount; + /** + * 创建时间 + */ + @ExcelProperty(value = "创建时间") + private Date createTime; + } diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/impl/ErpTempTaskChangeServiceImpl.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/impl/ErpTempTaskChangeServiceImpl.java index d0323924..c8fd8241 100644 --- a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/impl/ErpTempTaskChangeServiceImpl.java +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/impl/ErpTempTaskChangeServiceImpl.java @@ -2,12 +2,12 @@ package org.dromara.oa.erp.service.impl; import org.dromara.common.core.utils.MapstructUtils; import org.dromara.common.core.utils.StringUtils; - import org.dromara.common.mybatis.core.page.TableDataInfo; - import org.dromara.common.mybatis.core.page.PageQuery; - import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import org.dromara.common.core.exception.ServiceException; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.common.mybatis.core.page.PageQuery; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.github.yulichang.toolkit.JoinWrappers; import com.github.yulichang.wrapper.MPJLambdaWrapper; -import com.baomidou.mybatisplus.core.toolkit.Wrappers; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.dromara.oa.erp.domain.bo.ErpTempTaskChangeBo; @@ -43,19 +43,19 @@ public class ErpTempTaskChangeServiceImpl implements IErpTempTaskChangeService { return baseMapper.selectVoById(changeId); } - /** - * 分页查询临时任务变更记录列表 - * - * @param bo 查询条件 - * @param pageQuery 分页参数 - * @return 临时任务变更记录分页列表 - */ - @Override - public TableDataInfo queryPageList(ErpTempTaskChangeBo bo, PageQuery pageQuery) { - MPJLambdaWrapper lqw = buildQueryWrapper(bo); - Page result = baseMapper.selectCustomErpTempTaskChangeVoList(pageQuery.build(), lqw); - return TableDataInfo.build(result); - } + /** + * 分页查询临时任务变更记录列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 临时任务变更记录分页列表 + */ + @Override + public TableDataInfo queryPageList(ErpTempTaskChangeBo bo, PageQuery pageQuery) { + MPJLambdaWrapper lqw = buildQueryWrapper(bo); + Page result = baseMapper.selectCustomErpTempTaskChangeVoList(pageQuery.build(), lqw); + return TableDataInfo.build(result); + } /** * 查询符合条件的临时任务变更记录列表 @@ -72,26 +72,15 @@ public class ErpTempTaskChangeServiceImpl implements IErpTempTaskChangeService { private MPJLambdaWrapper buildQueryWrapper(ErpTempTaskChangeBo bo) { Map params = bo.getParams(); MPJLambdaWrapper lqw = JoinWrappers.lambda(ErpTempTaskChange.class) - .selectAll(ErpTempTaskChange.class) - .eq(ErpTempTaskChange::getDelFlag, "0") - .eq(bo.getTempTaskId() != null, ErpTempTaskChange::getTempTaskId, bo.getTempTaskId()) - .eq(StringUtils.isNotBlank(bo.getTempTaskCode()), ErpTempTaskChange::getTempTaskCode, bo.getTempTaskCode()) - .eq(StringUtils.isNotBlank(bo.getChangeType()), ErpTempTaskChange::getChangeType, bo.getChangeType()) - .eq(StringUtils.isNotBlank(bo.getChangeReason()), ErpTempTaskChange::getChangeReason, bo.getChangeReason()) - .eq(StringUtils.isNotBlank(bo.getBeforeContent()), ErpTempTaskChange::getBeforeContent, bo.getBeforeContent()) - .eq(StringUtils.isNotBlank(bo.getAfterContent()), ErpTempTaskChange::getAfterContent, bo.getAfterContent()) - .eq(StringUtils.isNotBlank(bo.getWorkloadEffect()), ErpTempTaskChange::getWorkloadEffect, bo.getWorkloadEffect()) - .eq(StringUtils.isNotBlank(bo.getTimeEffect()), ErpTempTaskChange::getTimeEffect, bo.getTimeEffect()) - .eq(StringUtils.isNotBlank(bo.getScopeEffect()), ErpTempTaskChange::getScopeEffect, bo.getScopeEffect()) - .eq(bo.getChangeUserId() != null, ErpTempTaskChange::getChangeUserId, bo.getChangeUserId()) - .like(StringUtils.isNotBlank(bo.getChangeUserName()), ErpTempTaskChange::getChangeUserName, bo.getChangeUserName()) - .eq(StringUtils.isNotBlank(bo.getApproveResult()), ErpTempTaskChange::getApproveResult, bo.getApproveResult()) - .eq(bo.getApproverId() != null, ErpTempTaskChange::getApproverId, bo.getApproverId()) - .like(StringUtils.isNotBlank(bo.getApproverName()), ErpTempTaskChange::getApproverName, bo.getApproverName()) - .eq(StringUtils.isNotBlank(bo.getApproveComment()), ErpTempTaskChange::getApproveComment, bo.getApproveComment()) - .eq(bo.getApproveTime() != null, ErpTempTaskChange::getApproveTime, bo.getApproveTime()) - .eq(StringUtils.isNotBlank(bo.getFlowStatus()), ErpTempTaskChange::getFlowStatus, bo.getFlowStatus()) -; + .selectAll(ErpTempTaskChange.class) + .eq(ErpTempTaskChange::getDelFlag, "0") + .eq(bo.getTempTaskId() != null, ErpTempTaskChange::getTempTaskId, bo.getTempTaskId()) + .eq(StringUtils.isNotBlank(bo.getTempTaskCode()), ErpTempTaskChange::getTempTaskCode, bo.getTempTaskCode()) + .eq(StringUtils.isNotBlank(bo.getChangeType()), ErpTempTaskChange::getChangeType, bo.getChangeType()) + .like(StringUtils.isNotBlank(bo.getChangeUserName()), ErpTempTaskChange::getChangeUserName, bo.getChangeUserName()) + .eq(StringUtils.isNotBlank(bo.getApproveResult()), ErpTempTaskChange::getApproveResult, bo.getApproveResult()) + .eq(StringUtils.isNotBlank(bo.getFlowStatus()), ErpTempTaskChange::getFlowStatus, bo.getFlowStatus()) + .orderByDesc(ErpTempTaskChange::getCreateTime); return lqw; } @@ -128,8 +117,19 @@ public class ErpTempTaskChangeServiceImpl implements IErpTempTaskChangeService { /** * 保存前的数据校验 */ - private void validEntityBeforeSave(ErpTempTaskChange entity){ - //TODO 做一些数据校验,如唯一约束 + private void validEntityBeforeSave(ErpTempTaskChange entity) { + if (entity == null) { + throw new ServiceException("变更记录数据不能为空"); + } + if (entity.getTempTaskId() == null) { + throw new ServiceException("关联临时任务ID不能为空"); + } + if (StringUtils.isBlank(entity.getChangeType())) { + throw new ServiceException("变更类型不能为空"); + } + if (StringUtils.isBlank(entity.getChangeReason())) { + throw new ServiceException("变更原因不能为空"); + } } /** @@ -141,8 +141,14 @@ public class ErpTempTaskChangeServiceImpl implements IErpTempTaskChangeService { */ @Override public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { - if(isValid){ - //TODO 做一些业务上的校验,判断是否需要校验 + if (isValid) { + // 已审批的变更记录不允许删除 + for (Long id : ids) { + ErpTempTaskChange change = baseMapper.selectById(id); + if (change != null && StringUtils.isNotBlank(change.getApproveResult())) { + throw new ServiceException("已审批的变更记录不允许删除"); + } + } } return baseMapper.deleteByIds(ids) > 0; } diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/impl/ErpTempTaskServiceImpl.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/impl/ErpTempTaskServiceImpl.java index 15f2d582..42a34066 100644 --- a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/impl/ErpTempTaskServiceImpl.java +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/impl/ErpTempTaskServiceImpl.java @@ -8,7 +8,11 @@ import org.dromara.common.core.utils.DateUtils; import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.mybatis.core.page.PageQuery; import cn.hutool.core.convert.Convert; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; import com.github.yulichang.toolkit.JoinWrappers; import com.github.yulichang.wrapper.MPJLambdaWrapper; import lombok.extern.slf4j.Slf4j; @@ -32,11 +36,14 @@ import org.dromara.oa.erp.domain.vo.ErpTempTaskVo; import org.dromara.oa.erp.domain.ErpTempTask; import org.dromara.oa.erp.mapper.ErpTempTaskMapper; import org.dromara.oa.erp.service.IErpTempTaskService; +import org.springframework.transaction.annotation.Transactional; import java.util.List; import java.util.Map; import java.util.Collection; +import java.util.Collections; import java.util.Date; +import java.util.HashMap; import java.util.Objects; import java.math.BigDecimal; @@ -58,6 +65,9 @@ public class ErpTempTaskServiceImpl implements IErpTempTaskService { private static final String STATUS_FINISHED = "3"; private static final String STATUS_INVALID = "4"; private static final BigDecimal MIN_WORKLOAD_STEP = new BigDecimal("0.5"); + private static final ObjectMapper CHANGE_CONTENT_OBJECT_MAPPER = new ObjectMapper(); + private static final TypeReference> CHANGE_CONTENT_TYPE = new TypeReference<>() { + }; private final ErpTempTaskMapper baseMapper; private final ErpTempTaskChangeMapper changeMapper; @@ -108,48 +118,36 @@ public class ErpTempTaskServiceImpl implements IErpTempTaskService { private MPJLambdaWrapper buildQueryWrapper(ErpTempTaskBo bo) { Map params = bo.getParams(); MPJLambdaWrapper lqw = JoinWrappers.lambda(ErpTempTask.class) - .selectAll(ErpTempTask.class) - .eq(ErpTempTask::getDelFlag, "0") - .eq(StringUtils.isNotBlank(bo.getTempTaskCode()), ErpTempTask::getTempTaskCode, bo.getTempTaskCode()) - .eq(StringUtils.isNotBlank(bo.getTaskTitle()), ErpTempTask::getTaskTitle, bo.getTaskTitle()) - .eq(StringUtils.isNotBlank(bo.getTaskDesc()), ErpTempTask::getTaskDesc, bo.getTaskDesc()) - .eq(StringUtils.isNotBlank(bo.getPriority()), ErpTempTask::getPriority, bo.getPriority()) - .eq(StringUtils.isNotBlank(bo.getUrgentReason()), ErpTempTask::getUrgentReason, bo.getUrgentReason()) - .eq(bo.getRequireTime() != null, ErpTempTask::getRequireTime, bo.getRequireTime()) - .eq(bo.getConfirmFinishTime() != null, ErpTempTask::getConfirmFinishTime, bo.getConfirmFinishTime()) - .eq(bo.getActualStartTime() != null, ErpTempTask::getActualStartTime, bo.getActualStartTime()) - .eq(bo.getActualFinishTime() != null, ErpTempTask::getActualFinishTime, bo.getActualFinishTime()) - .eq(bo.getProjectId() != null, ErpTempTask::getProjectId, bo.getProjectId()) - .eq(StringUtils.isNotBlank(bo.getProjectCode()), ErpTempTask::getProjectCode, bo.getProjectCode()) - .like(StringUtils.isNotBlank(bo.getProjectName()), ErpTempTask::getProjectName, bo.getProjectName()) - .eq(bo.getPmId() != null, ErpTempTask::getPmId, bo.getPmId()) - .like(StringUtils.isNotBlank(bo.getPmName()), ErpTempTask::getPmName, bo.getPmName()) - .eq(bo.getContractId() != null, ErpTempTask::getContractId, bo.getContractId()) - .eq(StringUtils.isNotBlank(bo.getContractCode()), ErpTempTask::getContractCode, bo.getContractCode()) - .eq(bo.getRequesterId() != null, ErpTempTask::getRequesterId, bo.getRequesterId()) - .like(StringUtils.isNotBlank(bo.getRequesterName()), ErpTempTask::getRequesterName, bo.getRequesterName()) - .eq(bo.getRequestDeptId() != null, ErpTempTask::getRequestDeptId, bo.getRequestDeptId()) - .like(StringUtils.isNotBlank(bo.getRequestDeptName()), ErpTempTask::getRequestDeptName, bo.getRequestDeptName()) - .eq(bo.getDispatcherId() != null, ErpTempTask::getDispatcherId, bo.getDispatcherId()) - .like(StringUtils.isNotBlank(bo.getDispatcherName()), ErpTempTask::getDispatcherName, bo.getDispatcherName()) - .eq(bo.getSoftwareLeaderId() != null, ErpTempTask::getSoftwareLeaderId, bo.getSoftwareLeaderId()) - .like(StringUtils.isNotBlank(bo.getSoftwareLeaderName()), ErpTempTask::getSoftwareLeaderName, bo.getSoftwareLeaderName()) - .eq(bo.getAssigneeId() != null, ErpTempTask::getAssigneeId, bo.getAssigneeId()) - .like(StringUtils.isNotBlank(bo.getAssigneeName()), ErpTempTask::getAssigneeName, bo.getAssigneeName()) - .eq(bo.getEstimateWorkload() != null, ErpTempTask::getEstimateWorkload, bo.getEstimateWorkload()) - .eq(bo.getActualWorkload() != null, ErpTempTask::getActualWorkload, bo.getActualWorkload()) - .eq(StringUtils.isNotBlank(bo.getFinishResult()), ErpTempTask::getFinishResult, bo.getFinishResult()) - .eq(StringUtils.isNotBlank(bo.getTerminateReason()), ErpTempTask::getTerminateReason, bo.getTerminateReason()) - .eq(StringUtils.isNotBlank(bo.getFinishRemark()), ErpTempTask::getFinishRemark, bo.getFinishRemark()) - .eq(bo.getRelatedTaskId() != null, ErpTempTask::getRelatedTaskId, bo.getRelatedTaskId()) - .eq(StringUtils.isNotBlank(bo.getRelatedTaskCode()), ErpTempTask::getRelatedTaskCode, bo.getRelatedTaskCode()) - .eq(StringUtils.isNotBlank(bo.getRelateReason()), ErpTempTask::getRelateReason, bo.getRelateReason()) - .eq(StringUtils.isNotBlank(bo.getRelateRemark()), ErpTempTask::getRelateRemark, bo.getRelateRemark()) - .eq(StringUtils.isNotBlank(bo.getTaskStatus()), ErpTempTask::getTaskStatus, bo.getTaskStatus()) - .eq(StringUtils.isNotBlank(bo.getFlowStatus()), ErpTempTask::getFlowStatus, bo.getFlowStatus()) - .eq(StringUtils.isNotBlank(bo.getCcUserIds()), ErpTempTask::getCcUserIds, bo.getCcUserIds()) - .eq(StringUtils.isNotBlank(bo.getOssId()), ErpTempTask::getOssId, bo.getOssId()) -; + .selectAll(ErpTempTask.class) + .eq(ErpTempTask::getDelFlag, "0") + .eq(StringUtils.isNotBlank(bo.getTempTaskCode()), ErpTempTask::getTempTaskCode, bo.getTempTaskCode()) + .like(StringUtils.isNotBlank(bo.getTaskTitle()), ErpTempTask::getTaskTitle, bo.getTaskTitle()) + .like(StringUtils.isNotBlank(bo.getTaskDesc()), ErpTempTask::getTaskDesc, bo.getTaskDesc()) + .eq(StringUtils.isNotBlank(bo.getPriority()), ErpTempTask::getPriority, bo.getPriority()) + .eq(bo.getProjectId() != null, ErpTempTask::getProjectId, bo.getProjectId()) + .like(StringUtils.isNotBlank(bo.getProjectName()), ErpTempTask::getProjectName, bo.getProjectName()) + .eq(bo.getRequesterId() != null, ErpTempTask::getRequesterId, bo.getRequesterId()) + .like(StringUtils.isNotBlank(bo.getRequesterName()), ErpTempTask::getRequesterName, bo.getRequesterName()) + .eq(bo.getRequestDeptId() != null, ErpTempTask::getRequestDeptId, bo.getRequestDeptId()) + .like(StringUtils.isNotBlank(bo.getRequestDeptName()), ErpTempTask::getRequestDeptName, bo.getRequestDeptName()) + .eq(bo.getDispatcherId() != null, ErpTempTask::getDispatcherId, bo.getDispatcherId()) + .like(StringUtils.isNotBlank(bo.getDispatcherName()), ErpTempTask::getDispatcherName, bo.getDispatcherName()) + .eq(bo.getAssigneeId() != null, ErpTempTask::getAssigneeId, bo.getAssigneeId()) + .like(StringUtils.isNotBlank(bo.getAssigneeName()), ErpTempTask::getAssigneeName, bo.getAssigneeName()) + .eq(StringUtils.isNotBlank(bo.getFinishResult()), ErpTempTask::getFinishResult, bo.getFinishResult()) + .eq(StringUtils.isNotBlank(bo.getTerminateReason()), ErpTempTask::getTerminateReason, bo.getTerminateReason()) + .eq(bo.getRelatedTaskId() != null, ErpTempTask::getRelatedTaskId, bo.getRelatedTaskId()) + .eq(StringUtils.isNotBlank(bo.getRelatedTaskCode()), ErpTempTask::getRelatedTaskCode, bo.getRelatedTaskCode()) + .eq(StringUtils.isNotBlank(bo.getRelateReason()), ErpTempTask::getRelateReason, bo.getRelateReason()) + .eq(StringUtils.isNotBlank(bo.getTaskStatus()), ErpTempTask::getTaskStatus, bo.getTaskStatus()) + .eq(StringUtils.isNotBlank(bo.getFlowStatus()), ErpTempTask::getFlowStatus, bo.getFlowStatus()) + .orderByDesc(ErpTempTask::getCreateTime); + if (params != null) { + String beginActualFinishTime = Convert.toStr(params.get("beginActualFinishTime")); + String endActualFinishTime = Convert.toStr(params.get("endActualFinishTime")); + lqw.ge(StringUtils.isNotBlank(beginActualFinishTime), ErpTempTask::getActualFinishTime, beginActualFinishTime) + .le(StringUtils.isNotBlank(endActualFinishTime), ErpTempTask::getActualFinishTime, endActualFinishTime); + } return lqw; } @@ -249,6 +247,7 @@ public class ErpTempTaskServiceImpl implements IErpTempTaskService { ErpTempTask update = new ErpTempTask(); update.setTempTaskId(task.getTempTaskId()); + update.setActualStartTime(bo.getActualStartTime()); update.setActualWorkload(bo.getActualWorkload()); update.setFinishResult(bo.getFinishResult()); update.setTerminateReason(bo.getTerminateReason()); @@ -365,6 +364,7 @@ public class ErpTempTaskServiceImpl implements IErpTempTaskService { * @return 是否删除成功 */ @Override + @Transactional(rollbackFor = Exception.class) public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { if(isValid){ for (Long id : ids) { @@ -384,7 +384,12 @@ public class ErpTempTaskServiceImpl implements IErpTempTaskService { } } } - return baseMapper.deleteByIds(ids) > 0; + boolean deleted = baseMapper.deleteByIds(ids) > 0; + if (deleted) { + changeMapper.delete(new LambdaQueryWrapper() + .in(ErpTempTaskChange::getTempTaskId, ids)); + } + return deleted; } /** @@ -463,32 +468,21 @@ public class ErpTempTaskServiceImpl implements IErpTempTaskService { } private Map buildWorkflowVariables(ErpTempTaskBo bo) { - Map variables = bo.getVariables(); + Map sourceVariables = bo.getVariables(); + Map variables = new HashMap<>(); variables.put("ignore", true); variables.put("has_dispatcher", bo.getDispatcherId() == null ? "0" : "1"); - variables.putIfAbsent("extra_approval_required", "0"); - variables.putIfAbsent("has_change", "0"); + variables.put("extra_approval_required", sourceVariables.getOrDefault("extra_approval_required", "0")); + variables.put("has_change", sourceVariables.getOrDefault("has_change", "0")); variables.put("dispatcherId", bo.getDispatcherId()); variables.put("requesterId", bo.getRequesterId()); variables.put("requestDeptId", bo.getRequestDeptId()); variables.put("softwareLeaderId", bo.getSoftwareLeaderId()); variables.put("assigneeId", bo.getAssigneeId()); variables.put("ccUserIds", bo.getCcUserIds()); - variables.put("taskTitle", bo.getTaskTitle()); - variables.put("taskDesc", bo.getTaskDesc()); - variables.put("priority", bo.getPriority()); - variables.put("urgentReason", bo.getUrgentReason()); - variables.put("requireTime", bo.getRequireTime()); - variables.put("confirmFinishTime", bo.getConfirmFinishTime()); variables.put("projectId", bo.getProjectId()); - variables.put("contractId", bo.getContractId()); variables.put("estimateWorkload", bo.getEstimateWorkload()); - variables.put("actualWorkload", bo.getActualWorkload()); - variables.put("finishResult", bo.getFinishResult()); - variables.put("terminateReason", bo.getTerminateReason()); - variables.put("finishRemark", bo.getFinishRemark()); - variables.put("relatedTaskId", bo.getRelatedTaskId()); - variables.put("relateReason", bo.getRelateReason()); + variables.put("confirmFinishTime", bo.getConfirmFinishTime()); variables.entrySet().removeIf(entry -> Objects.isNull(entry.getValue())); return variables; } @@ -590,6 +584,9 @@ public class ErpTempTaskServiceImpl implements IErpTempTaskService { if (StringUtils.isBlank(bo.getBeforeContent()) && StringUtils.isBlank(bo.getAfterContent())) { throw new ServiceException("变更前内容和变更后内容不能同时为空"); } + if (List.of("1", "2", "3", "4", "5").contains(bo.getChangeType()) && StringUtils.isBlank(bo.getAfterContent())) { + throw new ServiceException("当前变更类型必须填写变更后内容"); + } } private void applyApprovedChange(ErpTempTask task, ErpTempTaskChange change) { @@ -602,18 +599,89 @@ public class ErpTempTaskServiceImpl implements IErpTempTaskService { } else if ("3".equals(change.getChangeType()) && StringUtils.isNotBlank(change.getAfterContent())) { update.setConfirmFinishTime(parseDate(change.getAfterContent())); } else if ("4".equals(change.getChangeType()) && StringUtils.isNotBlank(change.getAfterContent())) { - update.setAssigneeId(Convert.toLong(change.getAfterContent())); + Map afterContent = parseChangeContent(change.getAfterContent()); + Long assigneeId = readLong(afterContent, "assigneeId", "userId", "id", "value"); + if (assigneeId == null) { + throw new ServiceException("变更后的主执行人不能为空"); + } + update.setAssigneeId(assigneeId); + String assigneeName = readString(afterContent, "assigneeName", "nickName", "userName", "name", "label"); + if (StringUtils.isBlank(assigneeName) && Objects.equals(task.getAssigneeId(), assigneeId)) { + assigneeName = task.getAssigneeName(); + } + if (StringUtils.isNotBlank(assigneeName)) { + update.setAssigneeName(assigneeName); + } } else if ("5".equals(change.getChangeType()) && StringUtils.isNotBlank(change.getAfterContent())) { - update.setProjectId(Convert.toLong(change.getAfterContent())); - } else if ("7".equals(change.getChangeType())) { - update.setFinishResult("2"); - update.setTerminateReason(StringUtils.isNotBlank(change.getAfterContent()) ? change.getAfterContent() : "7"); + Map afterContent = parseChangeContent(change.getAfterContent()); + Long projectId = readLong(afterContent, "projectId", "id", "value"); + if (projectId == null) { + throw new ServiceException("变更后的主报工项目不能为空"); + } + update.setProjectId(projectId); + String projectCode = readString(afterContent, "projectCode", "code"); + String projectName = readString(afterContent, "projectName", "name", "label"); + Long pmId = readLong(afterContent, "pmId", "managerId"); + String pmName = readString(afterContent, "pmName", "managerName"); + if (Objects.equals(task.getProjectId(), projectId)) { + projectCode = StringUtils.blankToDefault(projectCode, task.getProjectCode()); + projectName = StringUtils.blankToDefault(projectName, task.getProjectName()); + pmId = pmId == null ? task.getPmId() : pmId; + pmName = StringUtils.blankToDefault(pmName, task.getPmName()); + } + if (StringUtils.isNotBlank(projectCode)) { + update.setProjectCode(projectCode); + } + if (StringUtils.isNotBlank(projectName)) { + update.setProjectName(projectName); + } + if (pmId != null) { + update.setPmId(pmId); + } + if (StringUtils.isNotBlank(pmName)) { + update.setPmName(pmName); + } } else { return; } baseMapper.updateById(update); } + private Map parseChangeContent(String content) { + if (StringUtils.isBlank(content)) { + return Collections.emptyMap(); + } + String trimmed = content.trim(); + if (!trimmed.startsWith("{")) { + return Collections.singletonMap("value", trimmed); + } + try { + return CHANGE_CONTENT_OBJECT_MAPPER.readValue(trimmed, CHANGE_CONTENT_TYPE); + } catch (JsonProcessingException e) { + throw new ServiceException("变更后的内容格式不正确"); + } + } + + private Long readLong(Map content, String... keys) { + for (String key : keys) { + Object value = content.get(key); + if (value != null && StringUtils.isNotBlank(Convert.toStr(value))) { + return Convert.toLong(value); + } + } + return null; + } + + private String readString(Map content, String... keys) { + for (String key : keys) { + Object value = content.get(key); + if (value != null && StringUtils.isNotBlank(Convert.toStr(value))) { + return Convert.toStr(value); + } + } + return null; + } + private BigDecimal parseWorkload(String value) { try { return new BigDecimal(value);