feat(oa-erp): 新增软件部临时任务及变更管理模块

实现临时任务全生命周期管理,包含任务创建、审批、关闭、变更记录与审批功能,配套完整的CRUD接口与前端路由。
dev
zch 3 weeks ago
parent f62cbac7f4
commit 18d6488010

@ -0,0 +1,116 @@
package org.dromara.oa.erp.controller;
import java.util.List;
import lombok.RequiredArgsConstructor;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import org.dromara.common.idempotent.annotation.RepeatSubmit;
import org.dromara.common.log.annotation.Log;
import org.dromara.common.web.core.BaseController;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.excel.utils.ExcelUtil;
import org.dromara.oa.erp.domain.vo.ErpTempTaskChangeVo;
import org.dromara.oa.erp.domain.bo.ErpTempTaskChangeBo;
import org.dromara.oa.erp.service.IErpTempTaskChangeService;
import org.dromara.common.mybatis.core.page.TableDataInfo;
/**
*
* 访:/oa/erp/erpTempTaskChange
*
* @author zch
* @date 2026-06-17
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/erp/erpTempTaskChange")
public class ErpTempTaskChangeController extends BaseController {
private final IErpTempTaskChangeService erpTempTaskChangeService;
/**
*
*/
@SaCheckPermission("oa:erp:erpTempTaskChange:list")
@GetMapping("/list")
public TableDataInfo<ErpTempTaskChangeVo> list(ErpTempTaskChangeBo bo, PageQuery pageQuery) {
return erpTempTaskChangeService.queryPageList(bo, pageQuery);
}
/**
*
*/
@SaCheckPermission("oa:erp:erpTempTaskChange:export")
@Log(title = "临时任务变更记录", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(ErpTempTaskChangeBo bo, HttpServletResponse response) {
List<ErpTempTaskChangeVo> list = erpTempTaskChangeService.queryList(bo);
ExcelUtil.exportExcel(list, "临时任务变更记录", ErpTempTaskChangeVo.class, response);
}
/**
*
*
* @param changeId
*/
@SaCheckPermission("oa:erp:erpTempTaskChange:query")
@GetMapping("/{changeId}")
public R<ErpTempTaskChangeVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable("changeId") Long changeId) {
return R.ok(erpTempTaskChangeService.queryById(changeId));
}
/**
*
*/
@SaCheckPermission("oa:erp:erpTempTaskChange:add")
@Log(title = "临时任务变更记录", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody ErpTempTaskChangeBo bo) {
return toAjax(erpTempTaskChangeService.insertByBo(bo));
}
/**
*
*/
@SaCheckPermission("oa:erp:erpTempTaskChange:edit")
@Log(title = "临时任务变更记录", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody ErpTempTaskChangeBo bo) {
return toAjax(erpTempTaskChangeService.updateByBo(bo));
}
/**
*
*
* @param changeIds
*/
@SaCheckPermission("oa:erp:erpTempTaskChange:remove")
@Log(title = "临时任务变更记录", businessType = BusinessType.DELETE)
@DeleteMapping("/{changeIds}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable("changeIds") Long[] changeIds) {
return toAjax(erpTempTaskChangeService.deleteWithValidByIds(List.of(changeIds), true));
}
/**
*
*/
@GetMapping("/getErpTempTaskChangeList")
public R<List<ErpTempTaskChangeVo>> getErpTempTaskChangeList(ErpTempTaskChangeBo bo) {
List<ErpTempTaskChangeVo> list = erpTempTaskChangeService.queryList(bo);
return R.ok(list);
}
}

@ -0,0 +1,172 @@
package org.dromara.oa.erp.controller;
import java.util.List;
import lombok.RequiredArgsConstructor;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import org.dromara.common.idempotent.annotation.RepeatSubmit;
import org.dromara.common.log.annotation.Log;
import org.dromara.common.web.core.BaseController;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.excel.utils.ExcelUtil;
import org.dromara.oa.erp.domain.bo.ErpTempTaskChangeBo;
import org.dromara.oa.erp.domain.vo.ErpTempTaskChangeVo;
import org.dromara.oa.erp.domain.vo.ErpTempTaskVo;
import org.dromara.oa.erp.domain.bo.ErpTempTaskBo;
import org.dromara.oa.erp.service.IErpTempTaskService;
import org.dromara.common.mybatis.core.page.TableDataInfo;
/**
*
* 访:/oa/erp/tempTask
*
* @author zch
* @date 2026-06-17
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/erp/tempTask")
public class ErpTempTaskController extends BaseController {
private final IErpTempTaskService erpTempTaskService;
/**
*
*/
@SaCheckPermission("oa:erp:tempTask:list")
@GetMapping("/list")
public TableDataInfo<ErpTempTaskVo> list(ErpTempTaskBo bo, PageQuery pageQuery) {
return erpTempTaskService.queryPageList(bo, pageQuery);
}
/**
*
*/
@SaCheckPermission("oa:erp:tempTask:export")
@Log(title = "软件部临时任务主", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(ErpTempTaskBo bo, HttpServletResponse response) {
List<ErpTempTaskVo> list = erpTempTaskService.queryList(bo);
ExcelUtil.exportExcel(list, "软件部临时任务主", ErpTempTaskVo.class, response);
}
/**
*
*
* @param tempTaskId
*/
@SaCheckPermission("oa:erp:tempTask:query")
@GetMapping("/{tempTaskId}")
public R<ErpTempTaskVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable("tempTaskId") Long tempTaskId) {
return R.ok(erpTempTaskService.queryById(tempTaskId));
}
/**
*
*/
@SaCheckPermission("oa:erp:tempTask:add")
@Log(title = "软件部临时任务主", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody ErpTempTaskBo bo) {
return toAjax(erpTempTaskService.insertByBo(bo));
}
/**
*
*/
@SaCheckPermission("oa:erp:tempTask:edit")
@Log(title = "软件部临时任务主", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody ErpTempTaskBo bo) {
return toAjax(erpTempTaskService.updateByBo(bo));
}
/**
*
*
* @param tempTaskIds
*/
@SaCheckPermission("oa:erp:tempTask:remove")
@Log(title = "软件部临时任务主", businessType = BusinessType.DELETE)
@DeleteMapping("/{tempTaskIds}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable("tempTaskIds") Long[] tempTaskIds) {
return toAjax(erpTempTaskService.deleteWithValidByIds(List.of(tempTaskIds), true));
}
/**
*
*/
@GetMapping("/getErpTempTaskList")
public R<List<ErpTempTaskVo>> getErpTempTaskList(ErpTempTaskBo bo) {
List<ErpTempTaskVo> list = erpTempTaskService.queryList(bo);
return R.ok(list);
}
/**
*
*/
@SaCheckPermission("oa:erp:tempTask:submit")
@Log(title = "软件部临时任务提交审批", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PostMapping("/submit")
public R<ErpTempTaskVo> submit(@RequestBody ErpTempTaskBo bo) {
return R.ok(erpTempTaskService.tempTaskSubmitAndFlowStart(bo));
}
/**
*
*/
@SaCheckPermission("oa:erp:tempTask:close")
@Log(title = "软件部临时任务关闭", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PostMapping("/close")
public R<Void> close(@RequestBody ErpTempTaskBo bo) {
return toAjax(erpTempTaskService.closeTask(bo));
}
/**
*
*/
@SaCheckPermission("oa:erp:tempTask:query")
@GetMapping("/{tempTaskId}/changes")
public R<List<ErpTempTaskChangeVo>> changes(@NotNull(message = "主键不能为空")
@PathVariable("tempTaskId") Long tempTaskId) {
return R.ok(erpTempTaskService.queryChangeList(tempTaskId));
}
/**
*
*/
@SaCheckPermission("oa:erp:tempTask:change")
@Log(title = "软件部临时任务变更", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping("/change")
public R<Void> change(@RequestBody ErpTempTaskChangeBo bo) {
return toAjax(erpTempTaskService.saveChange(bo));
}
/**
*
*/
@SaCheckPermission("oa:erp:tempTask:changeApprove")
@Log(title = "软件部临时任务变更审批", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PostMapping("/change/approve")
public R<Void> approveChange(@RequestBody ErpTempTaskChangeBo bo) {
return toAjax(erpTempTaskService.approveChange(bo));
}
}

@ -0,0 +1,240 @@
package org.dromara.oa.erp.domain;
import org.dromara.common.tenant.core.TenantEntity;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.math.BigDecimal;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import java.io.Serial;
/**
* erp_temp_task
*
* @author zch
* @date 2026-06-17
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("erp_temp_task")
public class ErpTempTask extends TenantEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* ID
*/
@TableId(value = "temp_task_id", type = IdType.ASSIGN_ID)
private Long tempTaskId;
/**
* LSRW+yyyyMMdd+4稿
*/
private String tempTaskCode;
/**
*
*/
private String taskTitle;
/**
*
*/
private String taskDesc;
/**
* 1 2 3 4
*/
private String priority;
/**
* /
*/
private String urgentReason;
/**
* =
*/
private Date requireTime;
/**
* =
*/
private Date confirmFinishTime;
/**
*
*/
private Date actualStartTime;
/**
* /
*/
private Date actualFinishTime;
/**
* ID
*/
private Long projectId;
/**
*
*/
private String projectCode;
/**
*
*/
private String projectName;
/**
* ID
*/
private Long pmId;
/**
*
*/
private String pmName;
/**
* ID
*/
private Long contractId;
/**
*
*/
private String contractCode;
/**
* ID
*/
private Long requesterId;
/**
*
*/
private String requesterName;
/**
* ID
*/
private Long requestDeptId;
/**
*
*/
private String requestDeptName;
/**
* /ID
*/
private Long dispatcherId;
/**
*
*/
private String dispatcherName;
/**
* /ID//
*/
private Long softwareLeaderId;
/**
*
*/
private String softwareLeaderName;
/**
* ID
*/
private Long assigneeId;
/**
*
*/
private String assigneeName;
/**
* /
*/
private BigDecimal estimateWorkload;
/**
* /00.5
*/
private BigDecimal actualWorkload;
/**
* 1 2/ 3
*/
private String finishResult;
/**
* /1 2 3 4 5 6 7
*/
private String terminateReason;
/**
* 0/
*/
private String finishRemark;
/**
* ID
*/
private Long relatedTaskId;
/**
*
*/
private String relatedTaskCode;
/**
* 1 2 3 4 5 6 7
*/
private String relateReason;
/**
*
*/
private String relateRemark;
/**
* 1 2(/) 3 4
*/
private String taskStatus;
/**
* draft/waiting/finish/back/cancel/invalid/termination
*/
private String flowStatus;
/**
* ID
*/
private String ccUserIds;
/**
* ID
*/
private String ossId;
/**
*
*/
private String remark;
/**
* 0 1
*/
@TableLogic
private String delFlag;
}

@ -0,0 +1,124 @@
package org.dromara.oa.erp.domain;
import org.dromara.common.tenant.core.TenantEntity;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import java.io.Serial;
/**
* erp_temp_task_change
*
* @author zch
* @date 2026-06-17
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("erp_temp_task_change")
public class ErpTempTaskChange extends TenantEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* ID
*/
@TableId(value = "change_id", type = IdType.AUTO)
private Long changeId;
/**
* ID
*/
private Long tempTaskId;
/**
*
*/
private String tempTaskCode;
/**
* 1 2 3 4/ 5 6 7/
*/
private String changeType;
/**
*
*/
private String changeReason;
/**
*
*/
private String beforeContent;
/**
*
*/
private String afterContent;
/**
* /
*/
private String workloadEffect;
/**
* /
*/
private String timeEffect;
/**
* //
*/
private String scopeEffect;
/**
* ID//
*/
private Long changeUserId;
/**
*
*/
private String changeUserName;
/**
* 1 2 3退 4/
*/
private String approveResult;
/**
* ID
*/
private Long approverId;
/**
*
*/
private String approverName;
/**
*
*/
private String approveComment;
/**
*
*/
private Date approveTime;
/**
*
*/
private String flowStatus;
/**
*
*/
@TableLogic
private String delFlag;
}

@ -0,0 +1,268 @@
package org.dromara.oa.erp.domain.bo;
import org.dromara.oa.erp.domain.ErpTempTask;
import org.dromara.common.mybatis.core.domain.BaseEntity;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import io.github.linpeilie.annotations.AutoMapper;
import cn.hutool.core.util.ObjectUtil;
import lombok.Data;
import lombok.EqualsAndHashCode;
import jakarta.validation.constraints.*;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import org.dromara.workflow.api.domain.RemoteFlowInstanceBizExt;
/**
* erp_temp_task
*
* @author zch
* @date 2026-06-17
*/
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = ErpTempTask.class, reverseConvertGenerate = false)
public class ErpTempTaskBo extends BaseEntity {
/**
* ID
*/
@NotNull(message = "临时任务ID不能为空", groups = { EditGroup.class })
private Long tempTaskId;
/**
* LSRW+yyyyMMdd+4稿
*/
private String tempTaskCode;
/**
*
*/
private String taskTitle;
/**
*
*/
@NotBlank(message = "任务描述(发起必填)不能为空", groups = { AddGroup.class, EditGroup.class })
private String taskDesc;
/**
* 1 2 3 4
*/
private String priority;
/**
* /
*/
private String urgentReason;
/**
* =
*/
@NotNull(message = "需求时间=发起方期望最晚完成时间(发起必填)不能为空", groups = { AddGroup.class, EditGroup.class })
private Date requireTime;
/**
* =
*/
private Date confirmFinishTime;
/**
*
*/
private Date actualStartTime;
/**
* /
*/
private Date actualFinishTime;
/**
* ID
*/
private Long projectId;
/**
*
*/
private String projectCode;
/**
*
*/
private String projectName;
/**
* ID
*/
private Long pmId;
/**
*
*/
private String pmName;
/**
* ID
*/
private Long contractId;
/**
*
*/
private String contractCode;
/**
* ID
*/
private Long requesterId;
/**
*
*/
private String requesterName;
/**
* ID
*/
private Long requestDeptId;
/**
*
*/
private String requestDeptName;
/**
* /ID
*/
private Long dispatcherId;
/**
*
*/
private String dispatcherName;
/**
* /ID//
*/
private Long softwareLeaderId;
/**
*
*/
private String softwareLeaderName;
/**
* ID
*/
private Long assigneeId;
/**
*
*/
private String assigneeName;
/**
* /
*/
private BigDecimal estimateWorkload;
/**
* /00.5
*/
private BigDecimal actualWorkload;
/**
* 1 2/ 3
*/
private String finishResult;
/**
* /1 2 3 4 5 6 7
*/
private String terminateReason;
/**
* 0/
*/
private String finishRemark;
/**
* ID
*/
private Long relatedTaskId;
/**
*
*/
private String relatedTaskCode;
/**
* 1 2 3 4 5 6 7
*/
private String relateReason;
/**
*
*/
private String relateRemark;
/**
* 1 2(/) 3 4
*/
private String taskStatus;
/**
* draft/waiting/finish/back/cancel/invalid/termination
*/
private String flowStatus;
/**
* ID
*/
private String ccUserIds;
/**
* ID
*/
private String ossId;
/**
*
*/
private String remark;
/**
* OATT
*/
private String flowCode;
/**
*
*/
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;
}
}

@ -0,0 +1,121 @@
package org.dromara.oa.erp.domain.bo;
import org.dromara.oa.erp.domain.ErpTempTaskChange;
import org.dromara.common.mybatis.core.domain.BaseEntity;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import lombok.EqualsAndHashCode;
import jakarta.validation.constraints.*;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
/**
* erp_temp_task_change
*
* @author zch
* @date 2026-06-17
*/
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = ErpTempTaskChange.class, reverseConvertGenerate = false)
public class ErpTempTaskChangeBo extends BaseEntity {
/**
* ID
*/
@NotNull(message = "变更记录ID不能为空", groups = { EditGroup.class })
private Long changeId;
/**
* ID
*/
@NotNull(message = "临时任务ID不能为空", groups = { AddGroup.class, EditGroup.class })
private Long tempTaskId;
/**
*
*/
private String tempTaskCode;
/**
* 1 2 3 4/ 5 6 7/
*/
@NotBlank(message = "变更项类型1任务描述 2工时 3需求时间 4指派人/执行人 5可报工项目 6执行范围 7终止/不执行不能为空", groups = { AddGroup.class, EditGroup.class })
private String changeType;
/**
*
*/
@NotBlank(message = "变更原因不能为空", groups = { AddGroup.class, EditGroup.class })
private String changeReason;
/**
*
*/
private String beforeContent;
/**
*
*/
private String afterContent;
/**
* /
*/
private String workloadEffect;
/**
* /
*/
private String timeEffect;
/**
* //
*/
private String scopeEffect;
/**
* ID//
*/
@NotNull(message = "变更发起人ID发起人/执行人/软件部领导)不能为空", groups = { AddGroup.class, EditGroup.class })
private Long changeUserId;
/**
*
*/
private String changeUserName;
/**
* 1 2 3退 4/
*/
private String approveResult;
/**
* ID
*/
private Long approverId;
/**
*
*/
private String approverName;
/**
*
*/
private String approveComment;
/**
*
*/
private Date approveTime;
/**
*
*/
private String flowStatus;
}

@ -0,0 +1,148 @@
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;
import org.dromara.common.excel.annotation.ExcelDictFormat;
import org.dromara.common.excel.convert.ExcelDictConvert;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
/**
* erp_temp_task_change
*
* @author zch
* @date 2026-06-17
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = ErpTempTaskChange.class)
public class ErpTempTaskChangeVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* ID
*/
@ExcelProperty(value = "变更记录ID")
private Long changeId;
/**
* ID
*/
@ExcelProperty(value = "临时任务ID")
private Long tempTaskId;
/**
*
*/
@ExcelProperty(value = "任务编号快照")
private String tempTaskCode;
/**
* 1 2 3 4/ 5 6 7/
*/
@ExcelProperty(value = "变更项类型1任务描述 2工时 3需求时间 4指派人/执行人 5可报工项目 6执行范围 7终止/不执行")
private String changeType;
/**
*
*/
@ExcelProperty(value = "变更原因")
private String changeReason;
/**
*
*/
@ExcelProperty(value = "变更前内容")
private String beforeContent;
/**
*
*/
@ExcelProperty(value = "变更后内容")
private String afterContent;
/**
* /
*/
@ExcelProperty(value = "工时影响", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "变=更后预计工时/增减")
private String workloadEffect;
/**
* /
*/
@ExcelProperty(value = "时间影响", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "是=否影响需求/确认完成时间")
private String timeEffect;
/**
* //
*/
@ExcelProperty(value = "执行影响说明", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "是=否影响排期/其他任务/范围")
private String scopeEffect;
/**
* ID//
*/
@ExcelProperty(value = "变更发起人ID", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "发=起人/执行人/软件部领导")
private Long changeUserId;
/**
*
*/
@ExcelProperty(value = "变更发起人姓名快照")
private String changeUserName;
/**
* 1 2 3退 4/
*/
@ExcelProperty(value = "审批结论1通过 2不通过 3退回补充 4终止/不执行")
private String approveResult;
/**
* ID
*/
@ExcelProperty(value = "审批人ID", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "软=件部领导")
private Long approverId;
/**
*
*/
@ExcelProperty(value = "审批人姓名快照")
private String approverName;
/**
*
*/
@ExcelProperty(value = "审批意见")
private String approveComment;
/**
*
*/
@ExcelProperty(value = "审批时间")
private Date approveTime;
/**
*
*/
@ExcelProperty(value = "变更审批流程状态", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "如=走独立审批")
private String flowStatus;
}

@ -0,0 +1,306 @@
package org.dromara.oa.erp.domain.vo;
import java.math.BigDecimal;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.dromara.oa.erp.domain.ErpTempTask;
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import cn.idev.excel.annotation.ExcelProperty;
import org.dromara.common.excel.annotation.ExcelDictFormat;
import org.dromara.common.excel.convert.ExcelDictConvert;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
/**
* erp_temp_task
*
* @author zch
* @date 2026-06-17
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = ErpTempTask.class)
public class ErpTempTaskVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* ID
*/
@ExcelProperty(value = "临时任务ID")
private Long tempTaskId;
/**
* LSRW+yyyyMMdd+4稿
*/
@ExcelProperty(value = "任务编号", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "L=SRW+yyyyMMdd+4位草稿即生成且全程不变")
private String tempTaskCode;
/**
*
*/
@ExcelProperty(value = "任务标题")
private String taskTitle;
/**
*
*/
@ExcelProperty(value = "任务描述", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "发=起必填")
private String taskDesc;
/**
* 1 2 3 4
*/
@ExcelProperty(value = "优先级1普通 2较急 3紧急 4特急")
private String priority;
/**
* /
*/
@ExcelProperty(value = "紧急原因", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "优=先级为紧急/特急时必填")
private String urgentReason;
/**
* =
*/
@ExcelProperty(value = "需求时间=发起方期望最晚完成时间", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "发=起必填")
private Date requireTime;
/**
* =
*/
@ExcelProperty(value = "确认完成时间=领导审核确认的承诺完成时间")
private Date confirmFinishTime;
/**
*
*/
@ExcelProperty(value = "实际开始时间", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "仅=记周期,不计工时")
private Date actualStartTime;
/**
* /
*/
@ExcelProperty(value = "实际结束/关闭时间", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "仅=记周期,不计工时")
private Date actualFinishTime;
/**
* ID
*/
@ExcelProperty(value = "主报工项目ID")
private Long projectId;
/**
*
*/
@ExcelProperty(value = "项目编号快照")
private String projectCode;
/**
*
*/
@ExcelProperty(value = "项目名称快照")
private String projectName;
/**
* ID
*/
@ExcelProperty(value = "项目经理用户ID快照")
private Long pmId;
/**
*
*/
@ExcelProperty(value = "项目经理姓名快照")
private String pmName;
/**
* ID
*/
@ExcelProperty(value = "关联合同ID", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "选=填")
private Long contractId;
/**
*
*/
@ExcelProperty(value = "合同编号快照")
private String contractCode;
/**
* ID
*/
@ExcelProperty(value = "发起人ID")
private Long requesterId;
/**
*
*/
@ExcelProperty(value = "发起人姓名快照")
private String requesterName;
/**
* ID
*/
@ExcelProperty(value = "发起部门ID")
private Long requestDeptId;
/**
*
*/
@ExcelProperty(value = "发起部门名称快照")
private String requestDeptName;
/**
* /ID
*/
@ExcelProperty(value = "指派人/建议承接人ID", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "非=必填")
private Long dispatcherId;
/**
*
*/
@ExcelProperty(value = "指派人姓名快照")
private String dispatcherName;
/**
* /ID//
*/
@ExcelProperty(value = "软件部领导/审批人ID", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "审=核/加批/变更审批")
private Long softwareLeaderId;
/**
*
*/
@ExcelProperty(value = "软件部领导姓名快照")
private String softwareLeaderName;
/**
* ID
*/
@ExcelProperty(value = "主执行人ID", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "唯=一,领导审核确定")
private Long assigneeId;
/**
*
*/
@ExcelProperty(value = "主执行人姓名快照")
private String assigneeName;
/**
* /
*/
@ExcelProperty(value = "预计工时/小时", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "指=派人确认阶段补齐,领导审核认可")
private BigDecimal estimateWorkload;
/**
* /00.5
*/
@ExcelProperty(value = "实际消耗工时/小时", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "关=闭时填写0需说明最小0.5")
private BigDecimal actualWorkload;
/**
* 1 2/ 3
*/
@ExcelProperty(value = "完成结果1已完成 2不执行/终止 3部分完成后终止", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "仅=闭环写入")
private String finishResult;
/**
* /1 2 3 4 5 6 7
*/
@ExcelProperty(value = "不执行/终止原因1无需处理 2重复任务 3需求取消 4条件不满足 5资源不支持 6范围不合理 7其他")
private String terminateReason;
/**
* 0/
*/
@ExcelProperty(value = "完成说明", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "关=闭必填0工时/终止其他原因在此补充")
private String finishRemark;
/**
* ID
*/
@ExcelProperty(value = "关联原任务ID")
private Long relatedTaskId;
/**
*
*/
@ExcelProperty(value = "关联原任务编号快照")
private String relatedTaskCode;
/**
* 1 2 3 4 5 6 7
*/
@ExcelProperty(value = "关联原因1关闭后异议 2遗漏补充 3返工处理 4换人承接 5需求延续 6重新发起 7其他")
private String relateReason;
/**
*
*/
@ExcelProperty(value = "关联原因补充说明")
private String relateRemark;
/**
* 1 2(/) 3 4
*/
@ExcelProperty(value = "业务状态1暂存 2进行中(审批/执行) 3已结束 4作废")
private String taskStatus;
/**
* draft/waiting/finish/back/cancel/invalid/termination
*/
@ExcelProperty(value = "流程状态draft/waiting/finish/back/cancel/invalid/termination")
private String flowStatus;
/**
* ID
*/
@ExcelProperty(value = "抄送人员用户ID", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "多=个逗号分隔,实际抄送由工作流承载")
private String ccUserIds;
/**
* ID
*/
@ExcelProperty(value = "附件ID", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "非=必填,多个逗号分隔")
private String ossId;
/**
*
*/
@ExcelProperty(value = "备注")
private String remark;
/**
*
*/
private Long changeCount;
/**
*
*/
private Long pendingChangeCount;
}

@ -0,0 +1,153 @@
package org.dromara.oa.erp.mapper;
import java.util.List;
import java.util.Collection;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Param;
import org.dromara.oa.erp.domain.ErpTempTaskChange;
import org.dromara.oa.erp.domain.vo.ErpTempTaskChangeVo;
import org.dromara.common.mybatis.annotation.DataColumn;
import org.dromara.common.mybatis.annotation.DataPermission;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
/**
* Mapper
*
* @author zch
* @date 2026-06-17
*/
public interface ErpTempTaskChangeMapper extends BaseMapperPlus<ErpTempTaskChange, ErpTempTaskChangeVo> {
/**
*
*
* @param page
* @param queryWrapper
* @return
*/
@DataPermission({
@DataColumn(key = "deptName", value = "t.create_dept"),
@DataColumn(key = "userName", value = "t.create_by")
})
public Page<ErpTempTaskChangeVo> selectCustomErpTempTaskChangeVoList(@Param("page") Page<ErpTempTaskChangeVo> page, @Param(Constants.WRAPPER) MPJLambdaWrapper<ErpTempTaskChange> queryWrapper);
/**
*
*
* @param queryWrapper
* @return
*/
@DataPermission({
@DataColumn(key = "deptName", value = "t.create_dept"),
@DataColumn(key = "userName", value = "t.create_by")
})
public List<ErpTempTaskChangeVo> selectCustomErpTempTaskChangeVoList(@Param(Constants.WRAPPER) MPJLambdaWrapper<ErpTempTaskChange> queryWrapper);
/**
* ID
*
* @param changeId ID
* @return
*/
ErpTempTaskChangeVo selectCustomErpTempTaskChangeVoById(@Param("changeId") Long changeId);
/**
* ID
*
* @param ids ID
* @return
*/
List<ErpTempTaskChangeVo> selectCustomErpTempTaskChangeVoByIds(@Param("ids") Collection<Long> ids);
/**
*
*
* @param queryWrapper
* @return
*/
@DataPermission({
@DataColumn(key = "deptName", value = "t.create_dept"),
@DataColumn(key = "userName", value = "t.create_by")
})
Long countCustomErpTempTaskChange(@Param(Constants.WRAPPER) Wrapper<ErpTempTaskChange> queryWrapper);
/**
*
*
* @param page
* @param queryWrapper
* @return
*/
@DataPermission({
@DataColumn(key = "deptName", value = "t.create_dept"),
@DataColumn(key = "userName", value = "t.create_by")
})
Page<ErpTempTaskChangeVo> selectCustomErpTempTaskChangeVoPage(@Param("page") Page<ErpTempTaskChangeVo> page, @Param(Constants.WRAPPER) Wrapper<ErpTempTaskChange> queryWrapper);
/**
*
*
* @param list
* @return
*/
int batchInsertErpTempTaskChange(@Param("list") List<ErpTempTaskChange> list);
/**
*
*
* @param list
* @return
*/
int batchUpdateErpTempTaskChange(@Param("list") List<ErpTempTaskChange> list);
/**
*
*
* @param queryWrapper
* @return
*/
int deleteCustomErpTempTaskChange(@Param(Constants.WRAPPER) Wrapper<ErpTempTaskChange> queryWrapper);
/**
* ID
*
* @param ids ID
* @return
*/
int deleteCustomErpTempTaskChangeByIds(@Param("ids") Collection<Long> ids);
/**
*
*
* @param queryWrapper
* @return
*/
@DataPermission({
@DataColumn(key = "deptName", value = "t.create_dept"),
@DataColumn(key = "userName", value = "t.create_by")
})
Boolean existsErpTempTaskChange(@Param(Constants.WRAPPER) Wrapper<ErpTempTaskChange> queryWrapper);
/**
*
*
* @param tempTaskId ID
* @return
*/
@DataPermission({
@DataColumn(key = "deptName", value = "t.create_dept"),
@DataColumn(key = "userName", value = "t.create_by")
})
List<ErpTempTaskChangeVo> selectByTempTaskId(@Param("tempTaskId") Long tempTaskId);
/**
*
*
* @param tempTaskId ID
* @return
*/
Long countPendingByTempTaskId(@Param("tempTaskId") Long tempTaskId);
}

@ -0,0 +1,135 @@
package org.dromara.oa.erp.mapper;
import java.util.List;
import java.util.Collection;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Param;
import org.dromara.oa.erp.domain.ErpTempTask;
import org.dromara.oa.erp.domain.vo.ErpTempTaskVo;
import org.dromara.common.mybatis.annotation.DataColumn;
import org.dromara.common.mybatis.annotation.DataPermission;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
/**
* Mapper
*
* @author zch
* @date 2026-06-17
*/
public interface ErpTempTaskMapper extends BaseMapperPlus<ErpTempTask, ErpTempTaskVo> {
/**
*
*
* @param page
* @param queryWrapper
* @return
*/
@DataPermission({
@DataColumn(key = "deptName", value = "t.create_dept"),
@DataColumn(key = "userName", value = "t.create_by")
})
public Page<ErpTempTaskVo> selectCustomErpTempTaskVoList(@Param("page") Page<ErpTempTaskVo> page, @Param(Constants.WRAPPER) MPJLambdaWrapper<ErpTempTask> queryWrapper);
/**
*
*
* @param queryWrapper
* @return
*/
@DataPermission({
@DataColumn(key = "deptName", value = "t.create_dept"),
@DataColumn(key = "userName", value = "t.create_by")
})
public List<ErpTempTaskVo> selectCustomErpTempTaskVoList(@Param(Constants.WRAPPER) MPJLambdaWrapper<ErpTempTask> queryWrapper);
/**
* ID
*
* @param tempTaskId ID
* @return
*/
ErpTempTaskVo selectCustomErpTempTaskVoById(@Param("tempTaskId") Long tempTaskId);
/**
* ID
*
* @param ids ID
* @return
*/
List<ErpTempTaskVo> selectCustomErpTempTaskVoByIds(@Param("ids") Collection<Long> ids);
/**
*
*
* @param queryWrapper
* @return
*/
@DataPermission({
@DataColumn(key = "deptName", value = "t.create_dept"),
@DataColumn(key = "userName", value = "t.create_by")
})
Long countCustomErpTempTask(@Param(Constants.WRAPPER) Wrapper<ErpTempTask> queryWrapper);
/**
*
*
* @param page
* @param queryWrapper
* @return
*/
@DataPermission({
@DataColumn(key = "deptName", value = "t.create_dept"),
@DataColumn(key = "userName", value = "t.create_by")
})
Page<ErpTempTaskVo> selectCustomErpTempTaskVoPage(@Param("page") Page<ErpTempTaskVo> page, @Param(Constants.WRAPPER) Wrapper<ErpTempTask> queryWrapper);
/**
*
*
* @param list
* @return
*/
int batchInsertErpTempTask(@Param("list") List<ErpTempTask> list);
/**
*
*
* @param list
* @return
*/
int batchUpdateErpTempTask(@Param("list") List<ErpTempTask> list);
/**
*
*
* @param queryWrapper
* @return
*/
int deleteCustomErpTempTask(@Param(Constants.WRAPPER) Wrapper<ErpTempTask> queryWrapper);
/**
* ID
*
* @param ids ID
* @return
*/
int deleteCustomErpTempTaskByIds(@Param("ids") Collection<Long> ids);
/**
*
*
* @param queryWrapper
* @return
*/
@DataPermission({
@DataColumn(key = "deptName", value = "t.create_dept"),
@DataColumn(key = "userName", value = "t.create_by")
})
Boolean existsErpTempTask(@Param(Constants.WRAPPER) Wrapper<ErpTempTask> queryWrapper);
}

@ -0,0 +1,69 @@
package org.dromara.oa.erp.service;
import org.dromara.oa.erp.domain.ErpTempTaskChange;
import org.dromara.oa.erp.domain.vo.ErpTempTaskChangeVo;
import org.dromara.oa.erp.domain.bo.ErpTempTaskChangeBo;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import java.util.Collection;
import java.util.List;
/**
* Service
*
* @author zch
* @date 2026-06-17
*/
public interface IErpTempTaskChangeService {
/**
*
*
* @param changeId
* @return
*/
ErpTempTaskChangeVo queryById(Long changeId);
/**
*
*
* @param bo
* @param pageQuery
* @return
*/
TableDataInfo<ErpTempTaskChangeVo> queryPageList(ErpTempTaskChangeBo bo, PageQuery pageQuery);
/**
*
*
* @param bo
* @return
*/
List<ErpTempTaskChangeVo> queryList(ErpTempTaskChangeBo bo);
/**
*
*
* @param bo
* @return
*/
Boolean insertByBo(ErpTempTaskChangeBo bo);
/**
*
*
* @param bo
* @return
*/
Boolean updateByBo(ErpTempTaskChangeBo bo);
/**
*
*
* @param ids
* @param isValid
* @return
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
}

@ -0,0 +1,111 @@
package org.dromara.oa.erp.service;
import org.dromara.oa.erp.domain.ErpTempTask;
import org.dromara.oa.erp.domain.bo.ErpTempTaskChangeBo;
import org.dromara.oa.erp.domain.vo.ErpTempTaskChangeVo;
import org.dromara.oa.erp.domain.vo.ErpTempTaskVo;
import org.dromara.oa.erp.domain.bo.ErpTempTaskBo;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import java.util.Collection;
import java.util.List;
/**
* Service
*
* @author zch
* @date 2026-06-17
*/
public interface IErpTempTaskService {
/**
*
*
* @param tempTaskId
* @return
*/
ErpTempTaskVo queryById(Long tempTaskId);
/**
*
*
* @param bo
* @param pageQuery
* @return
*/
TableDataInfo<ErpTempTaskVo> queryPageList(ErpTempTaskBo bo, PageQuery pageQuery);
/**
*
*
* @param bo
* @return
*/
List<ErpTempTaskVo> queryList(ErpTempTaskBo bo);
/**
*
*
* @param bo
* @return
*/
Boolean insertByBo(ErpTempTaskBo bo);
/**
*
*
* @param bo
* @return
*/
Boolean updateByBo(ErpTempTaskBo bo);
/**
*
*
* @param bo
* @return
*/
ErpTempTaskVo tempTaskSubmitAndFlowStart(ErpTempTaskBo bo);
/**
*
*
* @param bo
* @return
*/
Boolean closeTask(ErpTempTaskBo bo);
/**
*
*
* @param tempTaskId ID
* @return
*/
List<ErpTempTaskChangeVo> queryChangeList(Long tempTaskId);
/**
*
*
* @param bo
* @return
*/
Boolean saveChange(ErpTempTaskChangeBo bo);
/**
*
*
* @param bo
* @return
*/
Boolean approveChange(ErpTempTaskChangeBo bo);
/**
*
*
* @param ids
* @param isValid
* @return
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
}

@ -0,0 +1,149 @@
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 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;
import org.dromara.oa.erp.domain.vo.ErpTempTaskChangeVo;
import org.dromara.oa.erp.domain.ErpTempTaskChange;
import org.dromara.oa.erp.mapper.ErpTempTaskChangeMapper;
import org.dromara.oa.erp.service.IErpTempTaskChangeService;
import java.util.List;
import java.util.Map;
import java.util.Collection;
/**
* Service
*
* @author zch
* @date 2026-06-17
*/
@RequiredArgsConstructor
@Service
public class ErpTempTaskChangeServiceImpl implements IErpTempTaskChangeService {
private final ErpTempTaskChangeMapper baseMapper;
/**
*
*
* @param changeId
* @return
*/
@Override
public ErpTempTaskChangeVo queryById(Long changeId){
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
* @return
*/
@Override
public List<ErpTempTaskChangeVo> queryList(ErpTempTaskChangeBo bo) {
MPJLambdaWrapper<ErpTempTaskChange> lqw = buildQueryWrapper(bo);
return baseMapper.selectCustomErpTempTaskChangeVoList(lqw);
}
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())
;
return lqw;
}
/**
*
*
* @param bo
* @return
*/
@Override
public Boolean insertByBo(ErpTempTaskChangeBo bo) {
ErpTempTaskChange add = MapstructUtils.convert(bo, ErpTempTaskChange.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setChangeId(add.getChangeId());
}
return flag;
}
/**
*
*
* @param bo
* @return
*/
@Override
public Boolean updateByBo(ErpTempTaskChangeBo bo) {
ErpTempTaskChange update = MapstructUtils.convert(bo, ErpTempTaskChange.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
/**
*
*/
private void validEntityBeforeSave(ErpTempTaskChange entity){
//TODO 做一些数据校验,如唯一约束
}
/**
*
*
* @param ids
* @param isValid
* @return
*/
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if(isValid){
//TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteByIds(ids) > 0;
}
}

@ -0,0 +1,632 @@
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.core.enums.BusinessStatusEnum;
import org.dromara.common.core.exception.ServiceException;
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.extension.plugins.pagination.Page;
import com.github.yulichang.toolkit.JoinWrappers;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import lombok.extern.slf4j.Slf4j;
import lombok.RequiredArgsConstructor;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.seata.spring.annotation.GlobalTransactional;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.common.tenant.helper.TenantHelper;
import org.dromara.oa.erp.domain.ErpTempTaskChange;
import org.dromara.oa.erp.mapper.ErpTempTaskChangeMapper;
import org.dromara.system.api.RemoteCodeRuleService;
import org.dromara.workflow.api.RemoteWorkflowService;
import org.dromara.workflow.api.domain.RemoteStartProcess;
import org.dromara.workflow.api.event.ProcessEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Service;
import org.dromara.oa.erp.domain.bo.ErpTempTaskBo;
import org.dromara.oa.erp.domain.bo.ErpTempTaskChangeBo;
import org.dromara.oa.erp.domain.vo.ErpTempTaskChangeVo;
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 java.util.List;
import java.util.Map;
import java.util.Collection;
import java.util.Date;
import java.util.Objects;
import java.math.BigDecimal;
/**
* Service
*
* @author zch
* @date 2026-06-17
*/
@RequiredArgsConstructor
@Service
@Slf4j
public class ErpTempTaskServiceImpl implements IErpTempTaskService {
private static final String FLOW_CODE = "OATT";
private static final String CODE_RULE = "LSRW";
private static final String STATUS_DRAFT = "1";
private static final String STATUS_RUNNING = "2";
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 final ErpTempTaskMapper baseMapper;
private final ErpTempTaskChangeMapper changeMapper;
@DubboReference(timeout = 30000)
private RemoteWorkflowService remoteWorkflowService;
@DubboReference(timeout = 30000)
private RemoteCodeRuleService remoteCodeRuleService;
/**
*
*
* @param tempTaskId
* @return
*/
@Override
public ErpTempTaskVo queryById(Long tempTaskId){
return baseMapper.selectCustomErpTempTaskVoById(tempTaskId);
}
/**
*
*
* @param bo
* @param pageQuery
* @return
*/
@Override
public TableDataInfo<ErpTempTaskVo> queryPageList(ErpTempTaskBo bo, PageQuery pageQuery) {
MPJLambdaWrapper<ErpTempTask> lqw = buildQueryWrapper(bo);
Page<ErpTempTaskVo> result = baseMapper.selectCustomErpTempTaskVoList(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
*
*
* @param bo
* @return
*/
@Override
public List<ErpTempTaskVo> queryList(ErpTempTaskBo bo) {
MPJLambdaWrapper<ErpTempTask> lqw = buildQueryWrapper(bo);
return baseMapper.selectCustomErpTempTaskVoList(lqw);
}
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())
;
return lqw;
}
/**
*
*
* @param bo
* @return
*/
@Override
public Boolean insertByBo(ErpTempTaskBo bo) {
prepareDraft(bo);
ErpTempTask add = MapstructUtils.convert(bo, ErpTempTask.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setTempTaskId(add.getTempTaskId());
}
return flag;
}
/**
*
*
* @param bo
* @return
*/
@Override
public Boolean updateByBo(ErpTempTaskBo bo) {
checkEditable(bo.getTempTaskId());
prepareDraft(bo);
ErpTempTask update = MapstructUtils.convert(bo, ErpTempTask.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
@Override
@GlobalTransactional(rollbackFor = Exception.class)
public ErpTempTaskVo tempTaskSubmitAndFlowStart(ErpTempTaskBo bo) {
validBeforeSubmit(bo);
prepareDraft(bo);
bo.setTaskStatus(STATUS_RUNNING);
bo.setFlowStatus(BusinessStatusEnum.WAITING.getStatus());
boolean saved;
if (bo.getTempTaskId() == null) {
ErpTempTask add = MapstructUtils.convert(bo, ErpTempTask.class);
validEntityBeforeSave(add);
saved = baseMapper.insert(add) > 0;
bo.setTempTaskId(add.getTempTaskId());
} else {
checkEditable(bo.getTempTaskId());
ErpTempTask update = MapstructUtils.convert(bo, ErpTempTask.class);
validEntityBeforeSave(update);
saved = baseMapper.updateById(update) > 0;
}
if (!saved || bo.getTempTaskId() == null) {
throw new ServiceException("临时任务保存失败,无法发起流程");
}
RemoteStartProcess startProcess = new RemoteStartProcess();
startProcess.setBusinessId(bo.getTempTaskId().toString());
startProcess.setFlowCode(FLOW_CODE);
startProcess.setVariables(buildWorkflowVariables(bo));
bo.getBizExt().setBusinessId(startProcess.getBusinessId());
bo.getBizExt().setBusinessCode(bo.getTempTaskCode());
bo.getBizExt().setBusinessTitle(buildBusinessTitle(bo));
startProcess.setBizExt(bo.getBizExt());
boolean started = remoteWorkflowService.startCompleteTask(startProcess);
if (!started) {
throw new ServiceException("流程发起异常");
}
return baseMapper.selectCustomErpTempTaskVoById(bo.getTempTaskId());
}
@Override
public Boolean closeTask(ErpTempTaskBo bo) {
if (bo.getTempTaskId() == null) {
throw new ServiceException("临时任务ID不能为空");
}
ErpTempTask task = baseMapper.selectById(bo.getTempTaskId());
if (task == null) {
throw new ServiceException("临时任务不存在");
}
if (StringUtils.isNotBlank(task.getFinishResult())) {
throw new ServiceException("临时任务已闭环,不能重复关闭");
}
Long userId = LoginHelper.getUserId();
if (task.getAssigneeId() != null && !Objects.equals(task.getAssigneeId(), userId)) {
throw new ServiceException("只有主执行人可以关闭临时任务");
}
if (hasPendingChange(task.getTempTaskId())) {
throw new ServiceException("存在待审批变更,不允许关闭,请先完成变更审批");
}
validBeforeClose(bo);
ErpTempTask update = new ErpTempTask();
update.setTempTaskId(task.getTempTaskId());
update.setActualWorkload(bo.getActualWorkload());
update.setFinishResult(bo.getFinishResult());
update.setTerminateReason(bo.getTerminateReason());
update.setFinishRemark(bo.getFinishRemark());
update.setActualFinishTime(new Date());
update.setTaskStatus(STATUS_FINISHED);
return baseMapper.updateById(update) > 0;
}
@Override
public List<ErpTempTaskChangeVo> queryChangeList(Long tempTaskId) {
if (tempTaskId == null) {
throw new ServiceException("临时任务ID不能为空");
}
return changeMapper.selectByTempTaskId(tempTaskId);
}
@Override
public Boolean saveChange(ErpTempTaskChangeBo bo) {
validBeforeChange(bo);
ErpTempTask task = baseMapper.selectById(bo.getTempTaskId());
if (task == null) {
throw new ServiceException("临时任务不存在");
}
if (StringUtils.isNotBlank(task.getFinishResult())) {
throw new ServiceException("临时任务已闭环,不能发起变更");
}
if (STATUS_DRAFT.equals(task.getTaskStatus())) {
throw new ServiceException("草稿任务请直接修改,不需要发起变更");
}
ErpTempTaskChange add = MapstructUtils.convert(bo, ErpTempTaskChange.class);
add.setTempTaskCode(task.getTempTaskCode());
add.setChangeUserId(LoginHelper.getUserId());
if (StringUtils.isBlank(add.getChangeUserName()) && LoginHelper.getLoginUser() != null) {
add.setChangeUserName(LoginHelper.getLoginUser().getNickname());
}
add.setApproveResult(null);
add.setApproverId(null);
add.setApproverName(null);
add.setApproveTime(null);
add.setFlowStatus(BusinessStatusEnum.WAITING.getStatus());
return changeMapper.insert(add) > 0;
}
@Override
public Boolean approveChange(ErpTempTaskChangeBo bo) {
if (bo.getChangeId() == null) {
throw new ServiceException("变更记录ID不能为空");
}
if (StringUtils.isBlank(bo.getApproveResult())) {
throw new ServiceException("变更审批结论不能为空");
}
ErpTempTaskChange change = changeMapper.selectById(bo.getChangeId());
if (change == null) {
throw new ServiceException("变更记录不存在");
}
if (StringUtils.isNotBlank(change.getApproveResult())) {
throw new ServiceException("变更记录已审批,不能重复处理");
}
ErpTempTask task = baseMapper.selectById(change.getTempTaskId());
if (task == null) {
throw new ServiceException("临时任务不存在");
}
if (StringUtils.isNotBlank(task.getFinishResult())) {
throw new ServiceException("临时任务已闭环,不能审批变更");
}
ErpTempTaskChange update = new ErpTempTaskChange();
update.setChangeId(change.getChangeId());
update.setApproveResult(bo.getApproveResult());
update.setApproveComment(bo.getApproveComment());
update.setApproverId(LoginHelper.getUserId());
if (LoginHelper.getLoginUser() != null) {
update.setApproverName(LoginHelper.getLoginUser().getNickname());
}
update.setApproveTime(new Date());
update.setFlowStatus(BusinessStatusEnum.FINISH.getStatus());
boolean flag = changeMapper.updateById(update) > 0;
if (flag && "1".equals(bo.getApproveResult())) {
applyApprovedChange(task, change);
}
return flag;
}
/**
*
*/
private void validEntityBeforeSave(ErpTempTask entity){
if (entity == null) {
throw new ServiceException("临时任务数据不能为空");
}
if (StringUtils.isBlank(entity.getTaskDesc())) {
throw new ServiceException("任务描述不能为空");
}
if (entity.getRequireTime() == null) {
throw new ServiceException("需求时间不能为空");
}
if (("3".equals(entity.getPriority()) || "4".equals(entity.getPriority()))
&& StringUtils.isBlank(entity.getUrgentReason())) {
throw new ServiceException("优先级为紧急或特急时必须填写紧急原因");
}
if (entity.getRelatedTaskId() != null) {
validRelatedTask(entity.getRelatedTaskId());
if (StringUtils.isBlank(entity.getRelateReason())) {
throw new ServiceException("关联原任务时必须选择关联原因");
}
}
}
/**
*
*
* @param ids
* @param isValid
* @return
*/
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if(isValid){
for (Long id : ids) {
ErpTempTask task = baseMapper.selectById(id);
if (task == null) {
continue;
}
if (StringUtils.isNotBlank(task.getFinishResult())) {
throw new ServiceException("已结束临时任务不能删除");
}
String flowStatus = task.getFlowStatus();
if (StringUtils.isNotBlank(flowStatus)
&& !BusinessStatusEnum.DRAFT.getStatus().equals(flowStatus)
&& !BusinessStatusEnum.BACK.getStatus().equals(flowStatus)
&& !BusinessStatusEnum.CANCEL.getStatus().equals(flowStatus)) {
throw new ServiceException("非草稿/退回/撤销状态临时任务不能删除");
}
}
}
return baseMapper.deleteByIds(ids) > 0;
}
/**
*
*/
@EventListener(condition = "#processEvent.flowCode == 'OATT'")
public void processHandler(ProcessEvent processEvent) {
TenantHelper.dynamic(processEvent.getTenantId(), () -> {
ErpTempTask task = baseMapper.selectById(Long.valueOf(processEvent.getBusinessId()));
if (task == null) {
log.warn("临时任务不存在, businessId: {}", processEvent.getBusinessId());
return;
}
task.setFlowStatus(processEvent.getStatus());
if (Objects.equals(processEvent.getStatus(), BusinessStatusEnum.WAITING.getStatus())) {
task.setTaskStatus(STATUS_RUNNING);
} else if (Objects.equals(processEvent.getStatus(), BusinessStatusEnum.FINISH.getStatus())) {
task.setTaskStatus(STATUS_FINISHED);
} else if (Objects.equals(processEvent.getStatus(), BusinessStatusEnum.INVALID.getStatus())
|| Objects.equals(processEvent.getStatus(), BusinessStatusEnum.TERMINATION.getStatus())) {
task.setTaskStatus(STATUS_INVALID);
} else if (Objects.equals(processEvent.getStatus(), BusinessStatusEnum.BACK.getStatus())
|| Objects.equals(processEvent.getStatus(), BusinessStatusEnum.CANCEL.getStatus())) {
task.setTaskStatus(STATUS_DRAFT);
}
baseMapper.updateById(task);
});
}
private void prepareDraft(ErpTempTaskBo bo) {
if (StringUtils.isBlank(bo.getTempTaskCode())) {
String tempTaskCode = remoteCodeRuleService.selectCodeRuleCode(CODE_RULE);
if (StringUtils.isBlank(tempTaskCode)) {
throw new ServiceException("生成临时任务编号失败");
}
bo.setTempTaskCode(tempTaskCode);
}
if (bo.getRequesterId() == null) {
bo.setRequesterId(LoginHelper.getUserId());
}
if (StringUtils.isBlank(bo.getRequesterName()) && LoginHelper.getLoginUser() != null) {
bo.setRequesterName(LoginHelper.getLoginUser().getNickname());
}
if (bo.getRequestDeptId() == null) {
bo.setRequestDeptId(LoginHelper.getDeptId());
}
if (StringUtils.isBlank(bo.getRequestDeptName()) && LoginHelper.getLoginUser() != null) {
bo.setRequestDeptName(LoginHelper.getLoginUser().getDeptName());
}
if (StringUtils.isBlank(bo.getPriority())) {
bo.setPriority("1");
}
if (StringUtils.isBlank(bo.getTaskStatus())) {
bo.setTaskStatus(STATUS_DRAFT);
}
if (StringUtils.isBlank(bo.getFlowStatus())) {
bo.setFlowStatus(BusinessStatusEnum.DRAFT.getStatus());
}
bo.setFlowCode(FLOW_CODE);
}
private void validBeforeSubmit(ErpTempTaskBo bo) {
if (bo == null) {
throw new ServiceException("临时任务数据不能为空");
}
if (StringUtils.isBlank(bo.getTaskDesc())) {
throw new ServiceException("任务描述不能为空");
}
if (bo.getRequireTime() == null) {
throw new ServiceException("需求时间不能为空");
}
if (("3".equals(bo.getPriority()) || "4".equals(bo.getPriority()))
&& StringUtils.isBlank(bo.getUrgentReason())) {
throw new ServiceException("优先级为紧急或特急时必须填写紧急原因");
}
}
private Map<String, Object> buildWorkflowVariables(ErpTempTaskBo bo) {
Map<String, Object> variables = bo.getVariables();
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("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.entrySet().removeIf(entry -> Objects.isNull(entry.getValue()));
return variables;
}
private String buildBusinessTitle(ErpTempTaskBo bo) {
String title = StringUtils.isNotBlank(bo.getTaskDesc()) ? bo.getTaskDesc() : bo.getTaskTitle();
StringBuilder builder = new StringBuilder();
builder.append(StringUtils.blankToDefault(bo.getTempTaskCode(), "临时任务"));
if (StringUtils.isNotBlank(title)) {
builder.append("-").append(StringUtils.substring(title, 0, 30));
}
if (StringUtils.isNotBlank(bo.getRequesterName())) {
builder.append("-发起人:").append(bo.getRequesterName());
}
if (StringUtils.isNotBlank(bo.getProjectName())) {
builder.append("-项目:").append(bo.getProjectName());
}
if (StringUtils.isNotBlank(bo.getPriority())) {
builder.append("-优先级:").append(bo.getPriority());
}
return builder.toString();
}
private void validBeforeClose(ErpTempTaskBo bo) {
if (bo.getActualWorkload() == null) {
throw new ServiceException("实际消耗工时不能为空");
}
if (bo.getActualWorkload().compareTo(BigDecimal.ZERO) < 0) {
throw new ServiceException("实际消耗工时不能小于0");
}
if (bo.getActualWorkload().remainder(MIN_WORKLOAD_STEP).compareTo(BigDecimal.ZERO) != 0) {
throw new ServiceException("实际消耗工时最小粒度为0.5小时");
}
if (bo.getActualWorkload().compareTo(BigDecimal.ZERO) == 0 && StringUtils.isBlank(bo.getFinishRemark())) {
throw new ServiceException("实际消耗工时为0时必须在完成说明中补充原因");
}
if (StringUtils.isBlank(bo.getFinishResult())) {
throw new ServiceException("完成结果不能为空");
}
if (StringUtils.isBlank(bo.getFinishRemark())) {
throw new ServiceException("完成说明不能为空");
}
if (("2".equals(bo.getFinishResult()) || "3".equals(bo.getFinishResult())) && StringUtils.isBlank(bo.getTerminateReason())) {
throw new ServiceException("完成结果为不执行/终止或部分完成后终止时必须选择终止原因");
}
if ("7".equals(bo.getTerminateReason()) && StringUtils.isBlank(bo.getFinishRemark())) {
throw new ServiceException("终止原因为其他时必须在完成说明中补充原因");
}
}
private void checkEditable(Long tempTaskId) {
if (tempTaskId == null) {
return;
}
ErpTempTask existing = baseMapper.selectById(tempTaskId);
if (existing == null) {
throw new ServiceException("临时任务不存在");
}
if (StringUtils.isNotBlank(existing.getFinishResult())) {
throw new ServiceException("临时任务已闭环,不能修改");
}
String flowStatus = existing.getFlowStatus();
if (StringUtils.isNotBlank(flowStatus)
&& !BusinessStatusEnum.DRAFT.getStatus().equals(flowStatus)
&& !BusinessStatusEnum.BACK.getStatus().equals(flowStatus)
&& !BusinessStatusEnum.CANCEL.getStatus().equals(flowStatus)) {
throw new ServiceException("当前流程状态不允许编辑");
}
}
private void validRelatedTask(Long relatedTaskId) {
ErpTempTask related = baseMapper.selectById(relatedTaskId);
if (related == null) {
throw new ServiceException("关联的原任务不存在");
}
if (StringUtils.isBlank(related.getFinishResult())) {
throw new ServiceException("关联的原任务尚未结束,未结束任务必须在原流程内处理");
}
}
private boolean hasPendingChange(Long tempTaskId) {
Long count = changeMapper.countPendingByTempTaskId(tempTaskId);
return count != null && count > 0;
}
private void validBeforeChange(ErpTempTaskChangeBo bo) {
if (bo == null) {
throw new ServiceException("变更记录不能为空");
}
if (bo.getTempTaskId() == null) {
throw new ServiceException("临时任务ID不能为空");
}
if (StringUtils.isBlank(bo.getChangeType())) {
throw new ServiceException("变更类型不能为空");
}
if (StringUtils.isBlank(bo.getChangeReason())) {
throw new ServiceException("变更原因不能为空");
}
if (StringUtils.isBlank(bo.getBeforeContent()) && StringUtils.isBlank(bo.getAfterContent())) {
throw new ServiceException("变更前内容和变更后内容不能同时为空");
}
}
private void applyApprovedChange(ErpTempTask task, ErpTempTaskChange change) {
ErpTempTask update = new ErpTempTask();
update.setTempTaskId(task.getTempTaskId());
if ("1".equals(change.getChangeType()) && StringUtils.isNotBlank(change.getAfterContent())) {
update.setTaskDesc(change.getAfterContent());
} else if ("2".equals(change.getChangeType()) && StringUtils.isNotBlank(change.getAfterContent())) {
update.setEstimateWorkload(parseWorkload(change.getAfterContent()));
} 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()));
} 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");
} else {
return;
}
baseMapper.updateById(update);
}
private BigDecimal parseWorkload(String value) {
try {
return new BigDecimal(value);
} catch (NumberFormatException e) {
throw new ServiceException("变更后的预计工时必须为数字");
}
}
private Date parseDate(String value) {
Date date = DateUtils.parseDate(value);
if (date == null) {
throw new ServiceException("变更后的时间格式不正确");
}
return date;
}
}

@ -0,0 +1,296 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.dromara.oa.erp.mapper.ErpTempTaskChangeMapper">
<resultMap type="org.dromara.oa.erp.domain.vo.ErpTempTaskChangeVo" id="ErpTempTaskChangeResult">
</resultMap>
<select id="selectCustomErpTempTaskChangeVoList" resultMap="ErpTempTaskChangeResult">
select t.change_id, t.tenant_id, t.temp_task_id, t.temp_task_code, t.change_type, t.change_reason, t.before_content, t.after_content, t.workload_effect, t.time_effect, t.scope_effect, t.change_user_id, t.change_user_name, t.approve_result, t.approver_id, t.approver_name, t.approve_comment, t.approve_time, t.flow_status, t.del_flag, t.create_dept, t.create_by, t.create_time, t.update_by, t.update_time from erp_temp_task_change t
<where>
<if test="ew != null and ew.sqlSegment != null and ew.sqlSegment != ''">
AND ${ew.sqlSegment}
</if>
</where>
order by t.create_time desc
</select>
<!-- 根据ID查询详情 -->
<select id="selectCustomErpTempTaskChangeVoById" resultMap="ErpTempTaskChangeResult">
select t.change_id, t.tenant_id, t.temp_task_id, t.temp_task_code, t.change_type, t.change_reason, t.before_content, t.after_content, t.workload_effect, t.time_effect, t.scope_effect, t.change_user_id, t.change_user_name, t.approve_result, t.approver_id, t.approver_name, t.approve_comment, t.approve_time, t.flow_status, t.del_flag, t.create_dept, t.create_by, t.create_time, t.update_by, t.update_time
from erp_temp_task_change t
where t.change_id = #{changeId}
</select>
<!-- 批量查询 - 根据ID列表 -->
<select id="selectCustomErpTempTaskChangeVoByIds" resultMap="ErpTempTaskChangeResult">
select t.change_id, t.tenant_id, t.temp_task_id, t.temp_task_code, t.change_type, t.change_reason, t.before_content, t.after_content, t.workload_effect, t.time_effect, t.scope_effect, t.change_user_id, t.change_user_name, t.approve_result, t.approver_id, t.approver_name, t.approve_comment, t.approve_time, t.flow_status, t.del_flag, t.create_dept, t.create_by, t.create_time, t.update_by, t.update_time
from erp_temp_task_change t
where t.change_id in
<foreach collection="ids" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</select>
<!-- 统计查询 -->
<select id="countCustomErpTempTaskChange" resultType="java.lang.Long">
select count(1) from erp_temp_task_change t
<where>
<if test="ew != null and ew.sqlSegment != null and ew.sqlSegment != ''">
AND ${ew.sqlSegment}
</if>
</where>
order by t.create_time desc
</select>
<!-- 分页查询(带自定义条件) -->
<select id="selectCustomErpTempTaskChangeVoPage" resultMap="ErpTempTaskChangeResult">
select t.change_id, t.tenant_id, t.temp_task_id, t.temp_task_code, t.change_type, t.change_reason, t.before_content, t.after_content, t.workload_effect, t.time_effect, t.scope_effect, t.change_user_id, t.change_user_name, t.approve_result, t.approver_id, t.approver_name, t.approve_comment, t.approve_time, t.flow_status, t.del_flag, t.create_dept, t.create_by, t.create_time, t.update_by, t.update_time
from erp_temp_task_change t
<where>
<if test="ew != null and ew.sqlSegment != null and ew.sqlSegment != ''">
AND ${ew.sqlSegment}
</if>
</where>
</select>
<!-- 批量插入 -->
<insert id="batchInsertErpTempTaskChange">
insert into erp_temp_task_change(
tenant_id,
temp_task_id,
temp_task_code,
change_type,
change_reason,
before_content,
after_content,
workload_effect,
time_effect,
scope_effect,
change_user_id,
change_user_name,
approve_result,
approver_id,
approver_name,
approve_comment,
approve_time,
flow_status,
del_flag,
create_dept,
create_by,
create_time,
update_by,
update_time
)
values
<foreach collection="list" item="item" separator=",">
(
#{item.tenantId},
#{item.tempTaskId},
#{item.tempTaskCode},
#{item.changeType},
#{item.changeReason},
#{item.beforeContent},
#{item.afterContent},
#{item.workloadEffect},
#{item.timeEffect},
#{item.scopeEffect},
#{item.changeUserId},
#{item.changeUserName},
#{item.approveResult},
#{item.approverId},
#{item.approverName},
#{item.approveComment},
#{item.approveTime},
#{item.flowStatus},
#{item.delFlag},
#{item.createDept},
#{item.createBy},
#{item.createTime},
#{item.updateBy},
#{item.updateTime}
)
</foreach>
</insert>
<!-- 批量更新 -->
<update id="batchUpdateErpTempTaskChange">
<foreach collection="list" item="item" separator=";">
update erp_temp_task_change t
<set>
<if test="item.tenantId != null and item.tenantId != ''">
t.tenant_id = #{item.tenantId},
</if>
<if test="item.tempTaskId != null">
t.temp_task_id = #{item.tempTaskId},
</if>
<if test="item.tempTaskCode != null and item.tempTaskCode != ''">
t.temp_task_code = #{item.tempTaskCode},
</if>
<if test="item.changeType != null and item.changeType != ''">
t.change_type = #{item.changeType},
</if>
<if test="item.changeReason != null and item.changeReason != ''">
t.change_reason = #{item.changeReason},
</if>
<if test="item.beforeContent != null and item.beforeContent != ''">
t.before_content = #{item.beforeContent},
</if>
<if test="item.afterContent != null and item.afterContent != ''">
t.after_content = #{item.afterContent},
</if>
<if test="item.workloadEffect != null and item.workloadEffect != ''">
t.workload_effect = #{item.workloadEffect},
</if>
<if test="item.timeEffect != null and item.timeEffect != ''">
t.time_effect = #{item.timeEffect},
</if>
<if test="item.scopeEffect != null and item.scopeEffect != ''">
t.scope_effect = #{item.scopeEffect},
</if>
<if test="item.changeUserId != null">
t.change_user_id = #{item.changeUserId},
</if>
<if test="item.changeUserName != null and item.changeUserName != ''">
t.change_user_name = #{item.changeUserName},
</if>
<if test="item.approveResult != null and item.approveResult != ''">
t.approve_result = #{item.approveResult},
</if>
<if test="item.approverId != null">
t.approver_id = #{item.approverId},
</if>
<if test="item.approverName != null and item.approverName != ''">
t.approver_name = #{item.approverName},
</if>
<if test="item.approveComment != null and item.approveComment != ''">
t.approve_comment = #{item.approveComment},
</if>
<if test="item.approveTime != null">
t.approve_time = #{item.approveTime},
</if>
<if test="item.flowStatus != null and item.flowStatus != ''">
t.flow_status = #{item.flowStatus},
</if>
<if test="item.delFlag != null and item.delFlag != ''">
t.del_flag = #{item.delFlag},
</if>
<if test="item.createDept != null">
t.create_dept = #{item.createDept},
</if>
<if test="item.createBy != null">
t.create_by = #{item.createBy},
</if>
<if test="item.createTime != null">
t.create_time = #{item.createTime},
</if>
<if test="item.updateBy != null">
t.update_by = #{item.updateBy},
</if>
<if test="item.updateTime != null">
t.update_time = #{item.updateTime}
</if>
</set>
where t.change_id = #{item.changeId}
</foreach>
</update>
<!-- 根据自定义条件删除 -->
<delete id="deleteCustomErpTempTaskChange">
delete from erp_temp_task_change t
<where>
<if test="ew != null and ew.sqlSegment != null and ew.sqlSegment != ''">
AND ${ew.sqlSegment}
</if>
</where>
</delete>
<!-- 根据ID列表批量删除 -->
<delete id="deleteCustomErpTempTaskChangeByIds">
delete from erp_temp_task_change t
where t.change_id in
<foreach collection="ids" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</delete>
<!-- 检查是否存在 -->
<select id="existsErpTempTaskChange" resultType="java.lang.Boolean">
select count(1) > 0 from erp_temp_task_change t
<where>
<if test="ew != null and ew.sqlSegment != null and ew.sqlSegment != ''">
AND ${ew.sqlSegment}
</if>
</where>
</select>
<select id="selectByTempTaskId" resultMap="ErpTempTaskChangeResult">
select t.change_id, t.tenant_id, t.temp_task_id, t.temp_task_code, t.change_type, t.change_reason, t.before_content, t.after_content, t.workload_effect, t.time_effect, t.scope_effect, t.change_user_id, t.change_user_name, t.approve_result, t.approver_id, t.approver_name, t.approve_comment, t.approve_time, t.flow_status, t.del_flag, t.create_dept, t.create_by, t.create_time, t.update_by, t.update_time
from erp_temp_task_change t
where t.temp_task_id = #{tempTaskId}
and t.del_flag = '0'
order by t.create_time desc
</select>
<select id="countPendingByTempTaskId" resultType="java.lang.Long">
select count(1)
from erp_temp_task_change t
where t.temp_task_id = #{tempTaskId}
and t.del_flag = '0'
and (
t.approve_result is null
or t.approve_result = ''
or t.flow_status = 'waiting'
)
</select>
</mapper>

@ -0,0 +1,438 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.dromara.oa.erp.mapper.ErpTempTaskMapper">
<resultMap type="org.dromara.oa.erp.domain.vo.ErpTempTaskVo" id="ErpTempTaskResult">
</resultMap>
<select id="selectCustomErpTempTaskVoList" resultMap="ErpTempTaskResult">
select t.temp_task_id, t.tenant_id, t.temp_task_code, t.task_title, t.task_desc, t.priority, t.urgent_reason, t.require_time, t.confirm_finish_time, t.actual_start_time, t.actual_finish_time, t.project_id, t.project_code, t.project_name, t.pm_id, t.pm_name, t.contract_id, t.contract_code, t.requester_id, t.requester_name, t.request_dept_id, t.request_dept_name, t.dispatcher_id, t.dispatcher_name, t.software_leader_id, t.software_leader_name, t.assignee_id, t.assignee_name, t.estimate_workload, t.actual_workload, t.finish_result, t.terminate_reason, t.finish_remark, t.related_task_id, t.related_task_code, t.relate_reason, t.relate_remark, t.task_status, t.flow_status, t.cc_user_ids, t.oss_id, t.remark, t.del_flag, t.create_dept, t.create_by, t.create_time, t.update_by, t.update_time, (select count(1) from erp_temp_task_change c where c.temp_task_id = t.temp_task_id and c.del_flag = '0') as change_count, (select count(1) from erp_temp_task_change c where c.temp_task_id = t.temp_task_id and c.del_flag = '0' and (c.approve_result is null or c.approve_result = '' or c.flow_status = 'waiting')) as pending_change_count from erp_temp_task t
<where>
<if test="ew != null and ew.sqlSegment != null and ew.sqlSegment != ''">
AND ${ew.sqlSegment}
</if>
</where>
order by t.create_time desc
</select>
<!-- 根据ID查询详情 -->
<select id="selectCustomErpTempTaskVoById" resultMap="ErpTempTaskResult">
select t.temp_task_id, t.tenant_id, t.temp_task_code, t.task_title, t.task_desc, t.priority, t.urgent_reason, t.require_time, t.confirm_finish_time, t.actual_start_time, t.actual_finish_time, t.project_id, t.project_code, t.project_name, t.pm_id, t.pm_name, t.contract_id, t.contract_code, t.requester_id, t.requester_name, t.request_dept_id, t.request_dept_name, t.dispatcher_id, t.dispatcher_name, t.software_leader_id, t.software_leader_name, t.assignee_id, t.assignee_name, t.estimate_workload, t.actual_workload, t.finish_result, t.terminate_reason, t.finish_remark, t.related_task_id, t.related_task_code, t.relate_reason, t.relate_remark, t.task_status, t.flow_status, t.cc_user_ids, t.oss_id, t.remark, t.del_flag, t.create_dept, t.create_by, t.create_time, t.update_by, t.update_time, (select count(1) from erp_temp_task_change c where c.temp_task_id = t.temp_task_id and c.del_flag = '0') as change_count, (select count(1) from erp_temp_task_change c where c.temp_task_id = t.temp_task_id and c.del_flag = '0' and (c.approve_result is null or c.approve_result = '' or c.flow_status = 'waiting')) as pending_change_count
from erp_temp_task t
where t.temp_task_id = #{tempTaskId}
</select>
<!-- 批量查询 - 根据ID列表 -->
<select id="selectCustomErpTempTaskVoByIds" resultMap="ErpTempTaskResult">
select t.temp_task_id, t.tenant_id, t.temp_task_code, t.task_title, t.task_desc, t.priority, t.urgent_reason, t.require_time, t.confirm_finish_time, t.actual_start_time, t.actual_finish_time, t.project_id, t.project_code, t.project_name, t.pm_id, t.pm_name, t.contract_id, t.contract_code, t.requester_id, t.requester_name, t.request_dept_id, t.request_dept_name, t.dispatcher_id, t.dispatcher_name, t.software_leader_id, t.software_leader_name, t.assignee_id, t.assignee_name, t.estimate_workload, t.actual_workload, t.finish_result, t.terminate_reason, t.finish_remark, t.related_task_id, t.related_task_code, t.relate_reason, t.relate_remark, t.task_status, t.flow_status, t.cc_user_ids, t.oss_id, t.remark, t.del_flag, t.create_dept, t.create_by, t.create_time, t.update_by, t.update_time
from erp_temp_task t
where t.temp_task_id in
<foreach collection="ids" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</select>
<!-- 统计查询 -->
<select id="countCustomErpTempTask" resultType="java.lang.Long">
select count(1) from erp_temp_task t
<where>
<if test="ew != null and ew.sqlSegment != null and ew.sqlSegment != ''">
AND ${ew.sqlSegment}
</if>
</where>
order by t.create_time desc
</select>
<!-- 分页查询(带自定义条件) -->
<select id="selectCustomErpTempTaskVoPage" resultMap="ErpTempTaskResult">
select t.temp_task_id, t.tenant_id, t.temp_task_code, t.task_title, t.task_desc, t.priority, t.urgent_reason, t.require_time, t.confirm_finish_time, t.actual_start_time, t.actual_finish_time, t.project_id, t.project_code, t.project_name, t.pm_id, t.pm_name, t.contract_id, t.contract_code, t.requester_id, t.requester_name, t.request_dept_id, t.request_dept_name, t.dispatcher_id, t.dispatcher_name, t.software_leader_id, t.software_leader_name, t.assignee_id, t.assignee_name, t.estimate_workload, t.actual_workload, t.finish_result, t.terminate_reason, t.finish_remark, t.related_task_id, t.related_task_code, t.relate_reason, t.relate_remark, t.task_status, t.flow_status, t.cc_user_ids, t.oss_id, t.remark, t.del_flag, t.create_dept, t.create_by, t.create_time, t.update_by, t.update_time
from erp_temp_task t
<where>
<if test="ew != null and ew.sqlSegment != null and ew.sqlSegment != ''">
AND ${ew.sqlSegment}
</if>
</where>
</select>
<!-- 批量插入 -->
<insert id="batchInsertErpTempTask">
insert into erp_temp_task(
tenant_id,
temp_task_code,
task_title,
task_desc,
priority,
urgent_reason,
require_time,
confirm_finish_time,
actual_start_time,
actual_finish_time,
project_id,
project_code,
project_name,
pm_id,
pm_name,
contract_id,
contract_code,
requester_id,
requester_name,
request_dept_id,
request_dept_name,
dispatcher_id,
dispatcher_name,
software_leader_id,
software_leader_name,
assignee_id,
assignee_name,
estimate_workload,
actual_workload,
finish_result,
terminate_reason,
finish_remark,
related_task_id,
related_task_code,
relate_reason,
relate_remark,
task_status,
flow_status,
cc_user_ids,
oss_id,
remark,
del_flag,
create_dept,
create_by,
create_time,
update_by,
update_time
)
values
<foreach collection="list" item="item" separator=",">
(
#{item.tenantId},
#{item.tempTaskCode},
#{item.taskTitle},
#{item.taskDesc},
#{item.priority},
#{item.urgentReason},
#{item.requireTime},
#{item.confirmFinishTime},
#{item.actualStartTime},
#{item.actualFinishTime},
#{item.projectId},
#{item.projectCode},
#{item.projectName},
#{item.pmId},
#{item.pmName},
#{item.contractId},
#{item.contractCode},
#{item.requesterId},
#{item.requesterName},
#{item.requestDeptId},
#{item.requestDeptName},
#{item.dispatcherId},
#{item.dispatcherName},
#{item.softwareLeaderId},
#{item.softwareLeaderName},
#{item.assigneeId},
#{item.assigneeName},
#{item.estimateWorkload},
#{item.actualWorkload},
#{item.finishResult},
#{item.terminateReason},
#{item.finishRemark},
#{item.relatedTaskId},
#{item.relatedTaskCode},
#{item.relateReason},
#{item.relateRemark},
#{item.taskStatus},
#{item.flowStatus},
#{item.ccUserIds},
#{item.ossId},
#{item.remark},
#{item.delFlag},
#{item.createDept},
#{item.createBy},
#{item.createTime},
#{item.updateBy},
#{item.updateTime}
)
</foreach>
</insert>
<!-- 批量更新 -->
<update id="batchUpdateErpTempTask">
<foreach collection="list" item="item" separator=";">
update erp_temp_task t
<set>
<if test="item.tenantId != null and item.tenantId != ''">
t.tenant_id = #{item.tenantId},
</if>
<if test="item.tempTaskCode != null and item.tempTaskCode != ''">
t.temp_task_code = #{item.tempTaskCode},
</if>
<if test="item.taskTitle != null and item.taskTitle != ''">
t.task_title = #{item.taskTitle},
</if>
<if test="item.taskDesc != null and item.taskDesc != ''">
t.task_desc = #{item.taskDesc},
</if>
<if test="item.priority != null and item.priority != ''">
t.priority = #{item.priority},
</if>
<if test="item.urgentReason != null and item.urgentReason != ''">
t.urgent_reason = #{item.urgentReason},
</if>
<if test="item.requireTime != null">
t.require_time = #{item.requireTime},
</if>
<if test="item.confirmFinishTime != null">
t.confirm_finish_time = #{item.confirmFinishTime},
</if>
<if test="item.actualStartTime != null">
t.actual_start_time = #{item.actualStartTime},
</if>
<if test="item.actualFinishTime != null">
t.actual_finish_time = #{item.actualFinishTime},
</if>
<if test="item.projectId != null">
t.project_id = #{item.projectId},
</if>
<if test="item.projectCode != null and item.projectCode != ''">
t.project_code = #{item.projectCode},
</if>
<if test="item.projectName != null and item.projectName != ''">
t.project_name = #{item.projectName},
</if>
<if test="item.pmId != null">
t.pm_id = #{item.pmId},
</if>
<if test="item.pmName != null and item.pmName != ''">
t.pm_name = #{item.pmName},
</if>
<if test="item.contractId != null">
t.contract_id = #{item.contractId},
</if>
<if test="item.contractCode != null and item.contractCode != ''">
t.contract_code = #{item.contractCode},
</if>
<if test="item.requesterId != null">
t.requester_id = #{item.requesterId},
</if>
<if test="item.requesterName != null and item.requesterName != ''">
t.requester_name = #{item.requesterName},
</if>
<if test="item.requestDeptId != null">
t.request_dept_id = #{item.requestDeptId},
</if>
<if test="item.requestDeptName != null and item.requestDeptName != ''">
t.request_dept_name = #{item.requestDeptName},
</if>
<if test="item.dispatcherId != null">
t.dispatcher_id = #{item.dispatcherId},
</if>
<if test="item.dispatcherName != null and item.dispatcherName != ''">
t.dispatcher_name = #{item.dispatcherName},
</if>
<if test="item.softwareLeaderId != null">
t.software_leader_id = #{item.softwareLeaderId},
</if>
<if test="item.softwareLeaderName != null and item.softwareLeaderName != ''">
t.software_leader_name = #{item.softwareLeaderName},
</if>
<if test="item.assigneeId != null">
t.assignee_id = #{item.assigneeId},
</if>
<if test="item.assigneeName != null and item.assigneeName != ''">
t.assignee_name = #{item.assigneeName},
</if>
<if test="item.estimateWorkload != null">
t.estimate_workload = #{item.estimateWorkload},
</if>
<if test="item.actualWorkload != null">
t.actual_workload = #{item.actualWorkload},
</if>
<if test="item.finishResult != null and item.finishResult != ''">
t.finish_result = #{item.finishResult},
</if>
<if test="item.terminateReason != null and item.terminateReason != ''">
t.terminate_reason = #{item.terminateReason},
</if>
<if test="item.finishRemark != null and item.finishRemark != ''">
t.finish_remark = #{item.finishRemark},
</if>
<if test="item.relatedTaskId != null">
t.related_task_id = #{item.relatedTaskId},
</if>
<if test="item.relatedTaskCode != null and item.relatedTaskCode != ''">
t.related_task_code = #{item.relatedTaskCode},
</if>
<if test="item.relateReason != null and item.relateReason != ''">
t.relate_reason = #{item.relateReason},
</if>
<if test="item.relateRemark != null and item.relateRemark != ''">
t.relate_remark = #{item.relateRemark},
</if>
<if test="item.taskStatus != null and item.taskStatus != ''">
t.task_status = #{item.taskStatus},
</if>
<if test="item.flowStatus != null and item.flowStatus != ''">
t.flow_status = #{item.flowStatus},
</if>
<if test="item.ccUserIds != null and item.ccUserIds != ''">
t.cc_user_ids = #{item.ccUserIds},
</if>
<if test="item.ossId != null and item.ossId != ''">
t.oss_id = #{item.ossId},
</if>
<if test="item.remark != null and item.remark != ''">
t.remark = #{item.remark},
</if>
<if test="item.delFlag != null and item.delFlag != ''">
t.del_flag = #{item.delFlag},
</if>
<if test="item.createDept != null">
t.create_dept = #{item.createDept},
</if>
<if test="item.createBy != null">
t.create_by = #{item.createBy},
</if>
<if test="item.createTime != null">
t.create_time = #{item.createTime},
</if>
<if test="item.updateBy != null">
t.update_by = #{item.updateBy},
</if>
<if test="item.updateTime != null">
t.update_time = #{item.updateTime}
</if>
</set>
where t.temp_task_id = #{item.tempTaskId}
</foreach>
</update>
<!-- 根据自定义条件删除 -->
<delete id="deleteCustomErpTempTask">
delete from erp_temp_task t
<where>
<if test="ew != null and ew.sqlSegment != null and ew.sqlSegment != ''">
AND ${ew.sqlSegment}
</if>
</where>
</delete>
<!-- 根据ID列表批量删除 -->
<delete id="deleteCustomErpTempTaskByIds">
delete from erp_temp_task t
where t.temp_task_id in
<foreach collection="ids" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</delete>
<!-- 检查是否存在 -->
<select id="existsErpTempTask" resultType="java.lang.Boolean">
select count(1) > 0 from erp_temp_task t
<where>
<if test="ew != null and ew.sqlSegment != null and ew.sqlSegment != ''">
AND ${ew.sqlSegment}
</if>
</where>
</select>
</mapper>
Loading…
Cancel
Save