refactor(oa/erp): 优化临时任务及变更相关代码规范

1. 简化校验提示文案,移除冗余说明文字
2. 重构ErpTempTaskVo和ErpTempTaskChangeVo的Excel注解,统一字典配置
3. 完善ErpTempTaskChangeService的校验逻辑和删除校验
4. 新增ErpServerInfoBo服务器信息业务对象
5. 优化临时任务查询排序和参数处理
6. 增强任务变更的内容解析和字段更新逻辑
7. 修复代码缩进和格式化问题
dev
zch 1 week ago
parent d2588fa33c
commit 9f5ffe343c

@ -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<String, Object> variables;
private RemoteFlowInstanceBizExt bizExt;
public Map<String, Object> 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;
}
}

@ -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;
/**

@ -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;
/**

@ -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;
}

@ -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;
/**
* /00.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;
}

@ -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<ErpTempTaskChangeVo> queryPageList(ErpTempTaskChangeBo bo, PageQuery pageQuery) {
MPJLambdaWrapper<ErpTempTaskChange> lqw = buildQueryWrapper(bo);
Page<ErpTempTaskChangeVo> result = baseMapper.selectCustomErpTempTaskChangeVoList(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
*
*
* @param bo
* @param pageQuery
* @return
*/
@Override
public TableDataInfo<ErpTempTaskChangeVo> queryPageList(ErpTempTaskChangeBo bo, PageQuery pageQuery) {
MPJLambdaWrapper<ErpTempTaskChange> lqw = buildQueryWrapper(bo);
Page<ErpTempTaskChangeVo> result = baseMapper.selectCustomErpTempTaskChangeVoList(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
*
@ -72,26 +72,15 @@ public class ErpTempTaskChangeServiceImpl implements IErpTempTaskChangeService {
private MPJLambdaWrapper<ErpTempTaskChange> buildQueryWrapper(ErpTempTaskChangeBo bo) {
Map<String, Object> params = bo.getParams();
MPJLambdaWrapper<ErpTempTaskChange> 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<Long> 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;
}

@ -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<Map<String, Object>> CHANGE_CONTENT_TYPE = new TypeReference<>() {
};
private final ErpTempTaskMapper baseMapper;
private final ErpTempTaskChangeMapper changeMapper;
@ -108,48 +118,36 @@ public class ErpTempTaskServiceImpl implements IErpTempTaskService {
private MPJLambdaWrapper<ErpTempTask> buildQueryWrapper(ErpTempTaskBo bo) {
Map<String, Object> params = bo.getParams();
MPJLambdaWrapper<ErpTempTask> 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<Long> 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<ErpTempTaskChange>()
.in(ErpTempTaskChange::getTempTaskId, ids));
}
return deleted;
}
/**
@ -463,32 +468,21 @@ public class ErpTempTaskServiceImpl implements IErpTempTaskService {
}
private Map<String, Object> buildWorkflowVariables(ErpTempTaskBo bo) {
Map<String, Object> variables = bo.getVariables();
Map<String, Object> sourceVariables = bo.getVariables();
Map<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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);

Loading…
Cancel
Save