소스 검색

1、转正审批接口
2、关闭接口调整

dongpo 1 년 전
부모
커밋
b1f02d518e
17개의 변경된 파일928개의 추가작업 그리고 487개의 파일을 삭제
  1. 9 2
      yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/ErrorCodeConstants.java
  2. 85 54
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/conversion/OaConversionController.java
  3. 22 11
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/conversion/vo/OaConversionRespVO.java
  4. 3 3
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/entry/OaEntryController.java
  5. 3 4
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/universal/OaUniversalController.java
  6. 2 2
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/universal/vo/OaUniversalRespVO.java
  7. 0 3
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/universal/vo/OaUniversalSaveReqVO.java
  8. 5 1
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java
  9. 28 9
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/oa/conversion/OaConversionDO.java
  10. 0 1
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/oa/conversion/OaConversionMapper.java
  11. 16 39
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/conversion/OaConversionService.java
  12. 505 119
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/conversion/OaConversionServiceImpl.java
  13. 1 1
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/entry/OaEntryService.java
  14. 15 10
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/entry/OaEntryServiceImpl.java
  15. 1 1
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/universal/OaUniversalService.java
  16. 15 10
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/universal/OaUniversalServiceImpl.java
  17. 218 217
      yudao-module-bpm/yudao-module-bpm-biz/src/test/java/cn/iocoder/yudao/module/bpm/service/oa/conversion/OaConversionServiceImplTest.java

+ 9 - 2
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/ErrorCodeConstants.java

@@ -53,7 +53,8 @@ public interface ErrorCodeConstants {
     ErrorCode TASK_SIGN_DELETE_NO_PARENT = new ErrorCode(1_009_005_012, "任务减签失败,被减签的任务必须是通过加签生成的任务");
     ErrorCode TASK_TRANSFER_FAIL_USER_REPEAT = new ErrorCode(1_009_005_013, "任务转办失败,转办人和当前审批人为同一人");
     ErrorCode TASK_TRANSFER_FAIL_USER_NOT_EXISTS = new ErrorCode(1_009_005_014, "任务转办失败,转办人不存在");
-    ErrorCode TASK_REVOCATION_NO_ALLOWED = new ErrorCode(1_009_006_015, "操作失败,原因:只有已提交状态的流程才能由申请人撤回!");
+    ErrorCode TASK_REVOCATION_NOT_ALLOWED = new ErrorCode(1_009_006_015, "操作失败,原因:只有已提交状态的流程才能由申请人撤回!");
+    ErrorCode TASK_CLOSE_NOT_ALLOWED = new ErrorCode(1_009_006_016, "操作失败,原因:只有已驳回或已撤回状态的流程才能由申请人关闭!");
     ErrorCode TASK_CREATE_FAIL_NO_CANDIDATE_USER = new ErrorCode(1_009_006_003, "操作失败,原因:找不到任务的审批人!");
     ErrorCode TASK_CREATE_FAIL_NO_START_SELECT_ASSIGNEE = new ErrorCode(1_009_006_004, "操作失败,原因:请选择审批人!");
 
@@ -91,7 +92,6 @@ public interface ErrorCodeConstants {
     ErrorCode OA_ENTRY_NOT_EXISTS = new ErrorCode(1009012000, "入职流程信息不存在");
 
 
-
     // ========== 请假流程信息 1-009-017-000 ==========
     ErrorCode OA_LEAVE_NOT_EXISTS = new ErrorCode(1009017000, "请假流程信息不存在");
 
@@ -106,4 +106,11 @@ public interface ErrorCodeConstants {
     // ========== 通用事项审批流程信息 1-009_017_006 ==========
     ErrorCode OA_UNIVERSAL_NOT_EXISTS = new ErrorCode(1009017006, "通用事项审批流程信息不存在");
 
+
+    // ========== 员工信息 1_009_018_000 ==========
+    ErrorCode OA_EMPLOYEE_NOT_EXISTS = new ErrorCode(1_009_018_000, "员工信息不存在");
+
+    // ========== 登录用户信息 1_009_018_000 ==========
+    ErrorCode OA_LOGIN_USER_NOT_EXISTS = new ErrorCode(1_009_018_000, "登录用户不存在");
+
 }

+ 85 - 54
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/conversion/OaConversionController.java

@@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.bpm.controller.admin.oa.conversion;
 
 import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
-import cn.iocoder.yudao.framework.common.pojo.PageParam;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
@@ -10,12 +9,12 @@ import cn.iocoder.yudao.module.bpm.controller.admin.oa.conversion.vo.OaConversio
 import cn.iocoder.yudao.module.bpm.controller.admin.oa.conversion.vo.OaConversionRespVO;
 import cn.iocoder.yudao.module.bpm.controller.admin.oa.conversion.vo.OaConversionSaveReqVO;
 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskApproveReqVO;
-import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.conversion.OaConversionDO;
+import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskReturnReqVO;
 import cn.iocoder.yudao.module.bpm.service.oa.conversion.OaConversionService;
+import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.Parameter;
 import io.swagger.v3.oas.annotations.tags.Tag;
-import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
@@ -27,7 +26,6 @@ import java.util.List;
 
 import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
-import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
 
 @Tag(name = "管理后台 - 转正流程信息")
 @RestController
@@ -38,87 +36,120 @@ public class OaConversionController {
     @Resource
     private OaConversionService oaConversionService;
 
-    @PostMapping("/start")
-    @Operation(summary = "提交或暂存转正流程信息")
-    @PreAuthorize("@ss.hasPermission('bpm:oa-conversion:start')")
-    public CommonResult<Long> startOaConversion(@Valid @RequestBody OaConversionSaveReqVO createReqVO) {
-        return success(oaConversionService.startOaConversion(getLoginUserId(), createReqVO));
+    @PostMapping("/staging")
+    @Operation(summary = "暂存转正审批流程信息")
+    @ApiOperationSupport(order = 1)
+    // @PreAuthorize("@ss.hasPermission('bpm:oa-conversion:staging')")
+    public CommonResult<Long> startOaConversion(@RequestBody OaConversionSaveReqVO stagingReqVO) {
+        Long oaConversionId = oaConversionService.stagingOaConversion(stagingReqVO);
+        return success(oaConversionId, "暂存成功");
     }
 
-    @PostMapping("/completeTure")
-    @Operation(summary = "审批同意转正流程信息")
-    @PreAuthorize("@ss.hasPermission('bpm:oa-entry:complete-true')")
-    public CommonResult<Long> completeTrueOaConversion(@Valid @RequestBody BpmTaskApproveReqVO reqVO) {
-        return success(oaConversionService.completeTrueOaConversion(getLoginUserId(), reqVO));
+    @PostMapping("/commit")
+    @Operation(summary = "提交转正审批流程信息")
+    @ApiOperationSupport(order = 2)
+    // @PreAuthorize("@ss.hasPermission('bpm:oa-conversion:commit')")
+    public CommonResult<Long> commitOaConversion(@Valid @RequestBody OaConversionSaveReqVO commitReqVO) {
+        Long oaConversionId = oaConversionService.commitOaConversion(commitReqVO);
+        return success(oaConversionId, "提交成功");
     }
 
-    @PostMapping("/completeFalse")
-    @Operation(summary = "驳回或撤回转正流程信息")
-    @PreAuthorize("@ss.hasPermission('bpm:oa-entry:complete-false')")
-    public CommonResult<Long> completeFalseOaConversion(@Valid @RequestBody BpmTaskApproveReqVO reqVO) {
-        return success(oaConversionService.completeFalseOaConversion(getLoginUserId(), reqVO));
+    @PostMapping("/agree")
+    @Operation(summary = "审批同意转正审批流程信息")
+    @ApiOperationSupport(order = 3)
+    // @PreAuthorize("@ss.hasPermission('bpm:oa-conversion:agree')")
+    public CommonResult<Long> agreeOaConversion(@Valid @RequestBody BpmTaskApproveReqVO agreeReqVO) {
+        Long result = oaConversionService.agreeOaConversion(agreeReqVO);
+        return success(result, "审批成功");
     }
 
-    @PostMapping("/updateComplete")
-    @Operation(summary = "驳回和撤回后再次提交或关闭转正流程信息")
-    @PreAuthorize("@ss.hasPermission('bpm:oa-entry:update-complete')")
-    public CommonResult<Long> updateCompleteOaConversion(@Valid @RequestBody OaConversionSaveReqVO createReqVO) {
-        return success(oaConversionService.updateCompleteOaConversion(getLoginUserId(), createReqVO, createReqVO.getBpmTaskApproveReqVO()));
+    @PostMapping("/disagree")
+    @Operation(summary = "驳回转正审批流程信息")
+    @ApiOperationSupport(order = 4)
+    // @PreAuthorize("@ss.hasPermission('bpm:oa-conversion:disagree')")
+    public CommonResult<Long> disagreeOaConversion(@Valid @RequestBody BpmTaskReturnReqVO disagreeReqVO) {
+        Long result = oaConversionService.disagreeOaConversion(disagreeReqVO);
+        return success(result, "驳回成功");
     }
 
+    @PostMapping("/revocation")
+    @Operation(summary = "撤回转正审批流程信息")
+    @ApiOperationSupport(order = 5)
+    // @PreAuthorize("@ss.hasPermission('bpm:oa-conversion:revocation')")
+    public CommonResult<Long> revocationOaConversion(@Valid @RequestBody BpmTaskApproveReqVO revocationReqVO) {
+        Long result = oaConversionService.revocationOaConversion(revocationReqVO);
+        return success(result, "撤回成功");
+    }
 
-    @PostMapping("/create")
-    @Operation(summary = "创建转正流程信息")
-    @PreAuthorize("@ss.hasPermission('bpm:oa-conversion:create')")
-    public CommonResult<Long> createOaConversion(@Valid @RequestBody OaConversionSaveReqVO createReqVO) {
-        return success(oaConversionService.createOaConversion(createReqVO));
+    @PostMapping("/reCommit")
+    @Operation(summary = "驳回或撤回后再次提交转正审批流程信息")
+    @ApiOperationSupport(order = 6)
+    // @PreAuthorize("@ss.hasPermission('bpm:oa-conversion:re-commit')")
+    public CommonResult<Long> reCommitOaConversion(@Valid @RequestBody OaConversionSaveReqVO reCommitReqVO) {
+        Long result = oaConversionService.reCommitOaConversion(reCommitReqVO);
+        return success(result, "再次提交成功");
     }
 
-    @PutMapping("/update")
-    @Operation(summary = "更新转正流程信息")
-    @PreAuthorize("@ss.hasPermission('bpm:oa-conversion:update')")
-    public CommonResult<Boolean> updateOaConversion(@Valid @RequestBody OaConversionSaveReqVO updateReqVO) {
-        oaConversionService.updateOaConversion(updateReqVO);
-        return success(true);
+    @DeleteMapping("/close")
+    @Operation(summary = "驳回或撤回后关闭转正审批流程信息")
+    @ApiOperationSupport(order = 7)
+    // @PreAuthorize("@ss.hasPermission('bpm:oa-entry:close')")
+    public CommonResult<Long> closeOaConversion(@RequestParam("id") Long id) {
+        Long result = oaConversionService.closeOaConversion(id);
+
+        return success(result, "关闭成功");
     }
 
     @DeleteMapping("/delete")
-    @Operation(summary = "删除转正流程信息")
+    @Operation(summary = "删除转正审批流程信息")
+    @ApiOperationSupport(order = 8)
     @Parameter(name = "id", description = "编号", required = true)
-    @PreAuthorize("@ss.hasPermission('bpm:oa-conversion:delete')")
+    // @PreAuthorize("@ss.hasPermission('bpm:oa-conversion:delete')")
     public CommonResult<Boolean> deleteOaConversion(@RequestParam("id") Long id) {
         oaConversionService.deleteOaConversion(id);
-        return success(true);
+        return success(true, "删除成功");
     }
 
     @GetMapping("/get")
-    @Operation(summary = "获得转正流程信息")
-    @Parameter(name = "id", description = "编号", required = true, example = "1024")
-    @PreAuthorize("@ss.hasPermission('bpm:oa-conversion:query')")
+    @Operation(summary = "根据id获得转正审批流程信息")
+    @Parameter(name = "id", description = "编号", required = true, example = "1")
+    @ApiOperationSupport(order = 9)
+    // @PreAuthorize("@ss.hasPermission('bpm:oa-conversion:query-id')")
     public CommonResult<OaConversionRespVO> getOaConversion(@RequestParam("id") Long id) {
-        OaConversionDO oaConversion = oaConversionService.getOaConversion(id);
-        return success(BeanUtils.toBean(oaConversion, OaConversionRespVO.class));
+        OaConversionRespVO respVO = oaConversionService.getOaConversion(id);
+        return success(respVO, "查询对象成功");
+    }
+
+    @GetMapping("/getByProcInstId")
+    @Operation(summary = "根据流程实例id获得转正审批流程信息")
+    @Parameter(name = "procInstId", description = "流程实例id", required = true, example = "9528a78d-457e-11ef-853c-4c034fce6445")
+    @ApiOperationSupport(order = 10)
+    // @PreAuthorize("@ss.hasPermission('bpm:oa-conversion:query-proc-inst-id')")
+    public CommonResult<OaConversionRespVO> getOaConversionByProcInstId(@RequestParam("procInstId") String procInstId) {
+        OaConversionRespVO respVO = oaConversionService.getOaConversionByProcInstId(procInstId);
+        return success(respVO, "查询对象成功");
     }
 
     @GetMapping("/page")
-    @Operation(summary = "获得转正流程信息分页")
-    @PreAuthorize("@ss.hasPermission('bpm:oa-conversion:query')")
+    @Operation(summary = "获得转正审批流程信息分页")
+    @ApiOperationSupport(order = 11)
+    // @PreAuthorize("@ss.hasPermission('bpm:oa-conversion:query-page')")
     public CommonResult<PageResult<OaConversionRespVO>> getOaConversionPage(@Valid OaConversionPageReqVO pageReqVO) {
-        PageResult<OaConversionDO> pageResult = oaConversionService.getOaConversionPage(pageReqVO);
-        return success(BeanUtils.toBean(pageResult, OaConversionRespVO.class));
+        return success(oaConversionService.getOaConversionPage(pageReqVO), "查询列表成功");
     }
 
     @GetMapping("/export-excel")
-    @Operation(summary = "导出转正流程信息 Excel")
-    @PreAuthorize("@ss.hasPermission('bpm:oa-conversion:export')")
+    @Operation(summary = "导出转正审批流程信息 Excel")
+    @ApiOperationSupport(order = 12)
+    // @PreAuthorize("@ss.hasPermission('bpm:oa-conversion:export')")
     @ApiAccessLog(operateType = EXPORT)
     public void exportOaConversionExcel(@Valid OaConversionPageReqVO pageReqVO,
-              HttpServletResponse response) throws IOException {
-        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
-        List<OaConversionDO> list = oaConversionService.getOaConversionPage(pageReqVO).getList();
+                                       HttpServletResponse response) throws IOException {
+        PageResult<OaConversionRespVO> pageResult = oaConversionService.exportOaConversionExcel(pageReqVO);
+        List<OaConversionRespVO> list = pageResult.getList();
         // 导出 Excel
-        ExcelUtils.write(response, "转正流程信息.xls", "数据", OaConversionRespVO.class,
-                        BeanUtils.toBean(list, OaConversionRespVO.class));
+        ExcelUtils.write(response, "转正审批流程信息.xls", "数据", OaConversionRespVO.class,
+                BeanUtils.toBean(list, OaConversionRespVO.class));
     }
 
 }

+ 22 - 11
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/conversion/vo/OaConversionRespVO.java

@@ -1,5 +1,8 @@
 package cn.iocoder.yudao.module.bpm.controller.admin.oa.conversion.vo;
 
+import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskRespVO;
+import cn.iocoder.yudao.module.infra.api.file.dto.FileDTO;
+import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.*;
 import java.util.*;
@@ -25,10 +28,6 @@ public class OaConversionRespVO {
     @ExcelProperty("转正人id")
     private Long employeeId;
 
-    @Schema(description = "转正人uuid", example = "12691")
-    @ExcelProperty("转正人uuid")
-    private String employeeUuid;
-
     @Schema(description = "转正员工姓名", example = "李四")
     @ExcelProperty("转正员工姓名")
     private String employeeName;
@@ -37,17 +36,13 @@ public class OaConversionRespVO {
     @ExcelProperty("用户账号id")
     private Long userId;
 
-    @Schema(description = "用户账号uuid", example = "14280")
-    @ExcelProperty("用户账号uuid")
-    private String userUuid;
-
     @Schema(description = "部门id", example = "14341")
     @ExcelProperty("部门id")
     private Long deptId;
 
-    @Schema(description = "部门uuid", example = "3755")
-    @ExcelProperty("部门uuid")
-    private String deptUuid;
+    @Schema(description = "部门名称")
+    @ExcelProperty("部门名称")
+    private String deptName;
 
     @Schema(description = "职位")
     @ExcelProperty("职位")
@@ -101,6 +96,10 @@ public class OaConversionRespVO {
     @ExcelProperty("当前审核人员工uuid")
     private String currentAuditEmployeeUuid;
 
+    @Schema(description = "当前审核人员工姓名")
+    @ExcelProperty("当前审核人员工姓名")
+    private String currentAuditEmployeeName;
+
     @Schema(description = "最后审核时间")
     @ExcelProperty("最后审核时间")
     private LocalDateTime finalAuditDate;
@@ -113,4 +112,16 @@ public class OaConversionRespVO {
     @ExcelProperty("创建时间")
     private LocalDateTime createTime;
 
+    @Schema(description = "附件列表")
+    private List<FileDTO> fileList;
+
+    @Schema(description = "审批记录列表")
+    private List<BpmTaskRespVO> auditRecordList;
+
+    @Schema(description = "审批人员列表")
+    private List<AdminUserRespDTO> auditUserList;
+
+    @Schema(description = "当前用户待处理的任务id")
+    private String taskId;
+
 }

+ 3 - 3
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/entry/OaEntryController.java

@@ -91,12 +91,12 @@ public class OaEntryController {
         return success(result, "再次提交成功");
     }
 
-    @PostMapping("/close")
+    @DeleteMapping("/close")
     @Operation(summary = "驳回或撤回后关闭入职审批流程信息")
     @ApiOperationSupport(order = 7)
     // @PreAuthorize("@ss.hasPermission('bpm:oa-entry:close')")
-    public CommonResult<Long> updateCompleteOaEntry(@RequestBody OaEntrySaveReqVO closeReqVO) {
-        Long result = oaEntryService.closeOaEntry(closeReqVO);
+    public CommonResult<Long> closeOaEntry(@RequestParam("id") Long id) {
+        Long result = oaEntryService.closeOaEntry(id);
 
         return success(result, "关闭成功");
     }

+ 3 - 4
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/universal/OaUniversalController.java

@@ -15,7 +15,6 @@ import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.Parameter;
 import io.swagger.v3.oas.annotations.tags.Tag;
-import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
@@ -91,12 +90,12 @@ public class OaUniversalController {
         return success(result, "再次提交成功");
     }
 
-    @PostMapping("/close")
+    @DeleteMapping("/close")
     @Operation(summary = "驳回或撤回后关闭通用事项审批流程信息")
     @ApiOperationSupport(order = 7)
     // @PreAuthorize("@ss.hasPermission('bpm:oa-entry:close')")
-    public CommonResult<Long> updateCompleteOaUniversal(@RequestBody OaUniversalSaveReqVO closeReqVO) {
-        Long result = oaUniversalService.closeOaUniversal(closeReqVO);
+    public CommonResult<Long> closeOaUniversal(@RequestParam("id") Long id) {
+        Long result = oaUniversalService.closeOaUniversal(id);
 
         return success(result, "关闭成功");
     }

+ 2 - 2
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/universal/vo/OaUniversalRespVO.java

@@ -104,8 +104,8 @@ public class OaUniversalRespVO {
     @ExcelProperty("当前审核人员工uuid")
     private String currentAuditEmployeeUuid;
 
-    @Schema(description = "当前审核人员工uuid")
-    @ExcelProperty("当前审核人员工uuid")
+    @Schema(description = "当前审核人员工姓名")
+    @ExcelProperty("当前审核人员工姓名")
     private String currentAuditEmployeeName;
 
     @Schema(description = "最后审核时间")

+ 0 - 3
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/universal/vo/OaUniversalSaveReqVO.java

@@ -1,12 +1,9 @@
 package cn.iocoder.yudao.module.bpm.controller.admin.oa.universal.vo;
 
-import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskApproveReqVO;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 
 import javax.validation.constraints.NotBlank;
-import javax.validation.constraints.NotEmpty;
-import javax.validation.constraints.NotNull;
 import java.util.List;
 
 @Schema(description = "管理后台 - 通用事项审批流程信息新增/修改 Request VO")

+ 5 - 1
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java

@@ -52,7 +52,11 @@ public interface BpmTaskConvert {
         return BeanUtils.toBean(pageResult, BpmTaskRespVO.class, taskVO -> {
             Task task = taskMap.get(taskVO.getId());
             Map<String, Object> processVariables = task.getProcessVariables();
-            taskVO.setStatus((Integer) processVariables.get(BpmConstants.PROCESS_INSTANCE_VARIABLE_STATUS));
+            Object status = processVariables.get(BpmConstants.PROCESS_INSTANCE_VARIABLE_STATUS);
+            if (status instanceof String) {
+                status = Integer.valueOf((String) status);
+            }
+            taskVO.setStatus((Integer) status);
             ProcessInstance processInstance = processInstanceMap.get(taskVO.getProcessInstanceId());
             if (processInstance == null) {
                 return;

+ 28 - 9
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/oa/conversion/OaConversionDO.java

@@ -44,6 +44,10 @@ public class OaConversionDO extends BaseDO {
      * 转正员工姓名
      */
     private String employeeName;
+    /**
+     * 申请员工手机号
+     */
+    private String employeePhone;
     /**
      * 用户账号id
      */
@@ -96,14 +100,6 @@ public class OaConversionDO extends BaseDO {
      * 审核状态(0暂存、1已提交、2审核中、3已审核、4已关闭、5已驳回)
      */
     private String auditStatus;
-    /**
-     * 当前审核人用户id
-     */
-    private Long currentAuditUserId;
-    /**
-     * 当前审核人用户uuid
-     */
-    private String currentAuditUserUuid;
     /**
      * 当前审核人员工id
      */
@@ -112,13 +108,36 @@ public class OaConversionDO extends BaseDO {
      * 当前审核人员工uuid
      */
     private String currentAuditEmployeeUuid;
+    /**
+     * 当前审核人员工姓名
+     */
+    private String currentAuditEmployeeName;
+    /**
+     * 当前审核人用户id
+     */
+    private Long currentAuditUserId;
+    /**
+     * 当前审核人用户uuid
+     */
+    private String currentAuditUserUuid;
     /**
      * 最后审核时间
      */
     private LocalDateTime finalAuditDate;
+    /**
+     * 申请人选择的审批人
+     */
+    private String startUserSelectAssignees;
     /**
      * 数据来源,0流程添加、1手动添加
      */
     private String infoSource;
-
+    /**
+     * 申请人id
+     */
+    private Long applyEmployeeId;
+    /**
+     * 申请人姓名
+     */
+    private String applyEmployeeName;
 }

+ 0 - 1
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/oa/conversion/OaConversionMapper.java

@@ -20,7 +20,6 @@ public interface OaConversionMapper extends BaseMapperX<OaConversionDO> {
                 .eqIfPresent(OaConversionDO::getConversionId, reqVO.getConversionId())
                 .eqIfPresent(OaConversionDO::getEmployeeId, reqVO.getEmployeeId())
                 .eqIfPresent(OaConversionDO::getEmployeeUuid, reqVO.getEmployeeUuid())
-                .likeIfPresent(OaConversionDO::getEmployeeName, reqVO.getEmployeeName())
                 .eqIfPresent(OaConversionDO::getUserId, reqVO.getUserId())
                 .eqIfPresent(OaConversionDO::getUserUuid, reqVO.getUserUuid())
                 .eqIfPresent(OaConversionDO::getDeptId, reqVO.getDeptId())

+ 16 - 39
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/conversion/OaConversionService.java

@@ -2,65 +2,42 @@ package cn.iocoder.yudao.module.bpm.service.oa.conversion;
 
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.module.bpm.controller.admin.oa.conversion.vo.OaConversionPageReqVO;
+import cn.iocoder.yudao.module.bpm.controller.admin.oa.conversion.vo.OaConversionRespVO;
 import cn.iocoder.yudao.module.bpm.controller.admin.oa.conversion.vo.OaConversionSaveReqVO;
 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskApproveReqVO;
+import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskReturnReqVO;
 import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.conversion.OaConversionDO;
 import com.baomidou.mybatisplus.extension.service.IService;
 
-import javax.validation.Valid;
-
 /**
  * 转正流程信息 Service 接口
  *
  * @author 芋道源码
  */
-public interface OaConversionService extends IService<OaConversionDO>{
+public interface OaConversionService {
 
-    Long startOaConversion(Long userId, @Valid OaConversionSaveReqVO createReqVO);
+    Long stagingOaConversion(OaConversionSaveReqVO stagingReqVO);
 
-    Long completeTrueOaConversion(Long userId, BpmTaskApproveReqVO reqVO);
+    Long commitOaConversion(OaConversionSaveReqVO commitReqVO);
 
-    Long completeFalseOaConversion(Long userId, BpmTaskApproveReqVO reqVO);
+    Long agreeOaConversion(BpmTaskApproveReqVO agreeReqVO);
 
-    Long updateCompleteOaConversion(Long userId, @Valid OaConversionSaveReqVO createReqVO, @Valid BpmTaskApproveReqVO reqVO);
+    Long disagreeOaConversion(BpmTaskReturnReqVO disagreeReqVO);
 
+    Long revocationOaConversion(BpmTaskApproveReqVO revocationReqVO);
 
-    /**
-     * 创建转正流程信息
-     *
-     * @param createReqVO 创建信息
-     * @return 编号
-     */
-    Long createOaConversion(@Valid OaConversionSaveReqVO createReqVO);
+    Long reCommitOaConversion(OaConversionSaveReqVO reCommitReqVO);
 
-    /**
-     * 更新转正流程信息
-     *
-     * @param updateReqVO 更新信息
-     */
-    void updateOaConversion(@Valid OaConversionSaveReqVO updateReqVO);
+    Long closeOaConversion(Long id);
 
-    /**
-     * 删除转正流程信息
-     *
-     * @param id 编号
-     */
     void deleteOaConversion(Long id);
 
-    /**
-     * 获得转正流程信息
-     *
-     * @param id 编号
-     * @return 转正流程信息
-     */
-    OaConversionDO getOaConversion(Long id);
+    OaConversionRespVO getOaConversion(Long id);
+
+    OaConversionRespVO getOaConversionByProcInstId(String procInstId);
+
+    PageResult<OaConversionRespVO> getOaConversionPage(OaConversionPageReqVO pageReqVO);
 
-    /**
-     * 获得转正流程信息分页
-     *
-     * @param pageReqVO 分页查询
-     * @return 转正流程信息分页
-     */
-    PageResult<OaConversionDO> getOaConversionPage(OaConversionPageReqVO pageReqVO);
+    PageResult<OaConversionRespVO> exportOaConversionExcel(OaConversionPageReqVO pageReqVO);
 
 }

+ 505 - 119
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/conversion/OaConversionServiceImpl.java

@@ -2,19 +2,34 @@ package cn.iocoder.yudao.module.bpm.service.oa.conversion;
 
 import cn.hutool.core.collection.CollectionUtil;
 import cn.hutool.core.util.IdUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
 import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi;
 import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;
 import cn.iocoder.yudao.module.bpm.controller.admin.oa.conversion.vo.OaConversionPageReqVO;
+import cn.iocoder.yudao.module.bpm.controller.admin.oa.conversion.vo.OaConversionRespVO;
 import cn.iocoder.yudao.module.bpm.controller.admin.oa.conversion.vo.OaConversionSaveReqVO;
 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskApproveReqVO;
+import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskRespVO;
 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskReturnReqVO;
 import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.conversion.OaConversionDO;
 import cn.iocoder.yudao.module.bpm.dal.mysql.oa.conversion.OaConversionMapper;
+import cn.iocoder.yudao.module.bpm.enums.DictDataConstants;
+import cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants;
+import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmConstants;
 import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService;
+import cn.iocoder.yudao.module.infra.api.file.FileApi;
+import cn.iocoder.yudao.module.infra.api.file.dto.FileDTO;
+import cn.iocoder.yudao.module.system.api.dept.DeptApi;
+import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
+import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
+import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import org.apache.commons.lang3.StringUtils;
 import org.flowable.engine.TaskService;
 import org.flowable.task.api.Task;
@@ -24,13 +39,11 @@ import org.springframework.validation.annotation.Validated;
 
 import javax.annotation.Resource;
 import java.time.LocalDateTime;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
+import java.util.stream.Collectors;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
-import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.OA_CONVERSION_NOT_EXISTS;
+import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.OA_UNIVERSAL_NOT_EXISTS;
 
 /**
  * 转正流程信息 Service 实现类
@@ -39,7 +52,7 @@ import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.OA_CONVERSION
  */
 @Service
 @Validated
-public class OaConversionServiceImpl extends ServiceImpl<OaConversionMapper, OaConversionDO> implements OaConversionService {
+public class OaConversionServiceImpl implements OaConversionService {
 
     /**
      * OA 转正对应的流程定义 KEY
@@ -58,91 +71,211 @@ public class OaConversionServiceImpl extends ServiceImpl<OaConversionMapper, OaC
     @Resource
     private TaskService taskService;
 
+    @Resource
+    private FileApi fileApi;
+
+    @Resource
+    private AdminUserApi adminUserApi;
+
+    @Resource
+    private DeptApi deptApi;
 
     @Override
     @Transactional
-    public Long startOaConversion(Long userId, OaConversionSaveReqVO createReqVO) {
-        //判断是否已经发起流程
-        Boolean auditPass = createReqVO.getAuditPass();
-        // 创建单据uuid
-        String uuid = IdUtil.fastSimpleUUID();
-        OaConversionDO oaConversion = BeanUtils.toBean(createReqVO, OaConversionDO.class);
+    public Long stagingOaConversion(OaConversionSaveReqVO stagingReqVO) {
+        // 登录人信息
+        Long loginUserId = SecurityFrameworkUtils.getLoginUserId();
+        AdminUserRespDTO loginUser = adminUserApi.getUser(loginUserId);
+        Objects.requireNonNull(loginUser, "登录用户不能为空");
+        // 转正人信息
+        AdminUserRespDTO employee = adminUserApi.getUser(stagingReqVO.getEmployeeId());
+
+        OaConversionDO oaConversion = BeanUtils.toBean(stagingReqVO, OaConversionDO.class);
         if (StringUtils.isBlank(oaConversion.getConversionId())) {
+            // 创建单据uuid
+            String uuid = IdUtil.fastSimpleUUID();
             oaConversion.setConversionId(uuid);
         }
+        if (employee != null) {
+            oaConversion.setEmployeeId(loginUser.getId());
+            oaConversion.setEmployeeName(loginUser.getNickname());
+            oaConversion.setEmployeePhone(loginUser.getMobile());
+            oaConversion.setDeptId(loginUser.getDeptId());
+            oaConversion.setPosition("员工职位");
+            oaConversion.setUserId(loginUser.getId());
+        }
+        oaConversion.setAuditStatus(DictDataConstants.OA_AUDIT_STATUS_STAGING);
+        oaConversion.setInfoSource("0");
+        oaConversion.setApplyEmployeeId(loginUser.getId());
+        oaConversion.setApplyEmployeeName(loginUser.getNickname());
+        // 暂存不保存审批人信息
+        oaConversion.setStartUserSelectAssignees(null);
         // 保存或更新表单信息
-        this.saveOrUpdate(oaConversion);
-
-        // 提交
-        if (auditPass) {
-            // 发起 BPM 流程
-            Map<String, Object> processInstanceVariables = new HashMap<>();
-            processInstanceVariables.put("auditPass", auditPass);
-            //添加审批人信息
-            Map<String, List<Long>> startUserSelectAssignees = new HashMap<>();
-            startUserSelectAssignees.put("approver", createReqVO.getStartUserSelectAssignees());
-            String processInstanceId = processInstanceApi
-                    .createProcessInstance(userId,
-                            new BpmProcessInstanceCreateReqDTO()
-                                    .setProcessDefinitionKey(PROCESS_KEY)
-                                    .setVariables(processInstanceVariables)
-                                    .setBusinessKey(String.valueOf(oaConversion.getId()))
-                                    .setStartUserSelectAssignees(startUserSelectAssignees));
-
-            //获取下一个审批人
-            Task task = taskService.createTaskQuery().processInstanceId(processInstanceId).singleResult();
-
-            // 将工作流的编号,单据状态 最后一次审批时间 当前审批人  更新到 OA 转正中
-            oaConversionMapper.updateById(new OaConversionDO()
-                    .setId(oaConversion.getId())
-                    .setProcInstId(processInstanceId)
-                    .setAuditStatus("1")
-                    .setConversionId(uuid)
-                    .setFinalAuditDate(LocalDateTime.now())
-                    .setCurrentAuditEmployeeId(Long.valueOf(task.getAssignee())));
+        if (oaConversion.getId() == null) {
+            oaConversionMapper.insert(oaConversion);
+        } else {
+            oaConversionMapper.updateById(oaConversion);
+        }
+        // 保存业务uuid到附件中
+        saveFileList(stagingReqVO.getFileIdList(), oaConversion.getConversionId());
 
-            // TODO 发送通知
+        return oaConversion.getId();
+    }
 
-        }else {
-            // 暂存,不发起流程
-            // 将单据状态 更新到 OA转正中
-            oaConversionMapper.updateById(new OaConversionDO()
-                    .setId(oaConversion.getId())
-                    .setAuditStatus("0"));
+    @Override
+    @Transactional
+    public Long commitOaConversion(OaConversionSaveReqVO commitReqVO) {
+        if (CollectionUtil.isEmpty(commitReqVO.getStartUserSelectAssignees())) {
+            throw exception(ErrorCodeConstants.TASK_CREATE_FAIL_NO_START_SELECT_ASSIGNEE);
+        }
+        // 登录人信息
+        Long loginUserId = SecurityFrameworkUtils.getLoginUserId();
+        AdminUserRespDTO loginUser = adminUserApi.getUser(loginUserId);
+        if (loginUser == null) {
+            throw exception(ErrorCodeConstants.OA_LOGIN_USER_NOT_EXISTS);
+        }
+        // 转正人信息
+        AdminUserRespDTO employee = adminUserApi.getUser(commitReqVO.getEmployeeId());
+        if (employee == null) {
+            throw exception(ErrorCodeConstants.OA_EMPLOYEE_NOT_EXISTS);
         }
 
-        // TODO 保存或更新附件uuid
-        if (CollectionUtil.isNotEmpty(createReqVO.getFileIdList())) {
+
+        OaConversionDO oaConversion = BeanUtils.toBean(commitReqVO, OaConversionDO.class);
+        if (StringUtils.isBlank(oaConversion.getConversionId())) {
+            // 创建单据uuid
+            String uuid = IdUtil.fastSimpleUUID();
+            oaConversion.setConversionId(uuid);
         }
+        oaConversion.setEmployeeId(employee.getId());
+        oaConversion.setEmployeeName(employee.getNickname());
+        oaConversion.setEmployeePhone(employee.getMobile());
+        oaConversion.setDeptId(employee.getDeptId());
+        oaConversion.setPosition("员工职位");
+        oaConversion.setUserId(loginUser.getId());
+        oaConversion.setInfoSource("0");
+        oaConversion.setApplyEmployeeId(loginUser.getId());
+        oaConversion.setApplyEmployeeName(loginUser.getNickname());
+        // 保存或更新表单信息
+        if (oaConversion.getId() == null) {
+            oaConversionMapper.insert(oaConversion);
+        } else {
+            OaConversionDO oaConversionDO = oaConversionMapper.selectById(oaConversion.getId());
+            if (StrUtil.isNotBlank(oaConversionDO.getProcInstId())) {
+                throw exception(ErrorCodeConstants.PROCESS_INSTANCE_CREATE_FAIL_HAS_PROCESS);
+            }
+            oaConversionMapper.updateById(oaConversion);
+        }
+        // 发起流程
+        Map<String, Object> processInstanceVariables = new HashMap<>();
+        processInstanceVariables.put("auditPass", "true");
+        // 添加审批人信息
+        Map<String, List<Long>> startUserSelectAssignees = new HashMap<>();
+        List<Long> selectAssignees = commitReqVO.getStartUserSelectAssignees();
+        startUserSelectAssignees.put("approver", selectAssignees);
+        String processInstanceId = processInstanceApi
+                .createProcessInstance(loginUser.getId(),
+                        new BpmProcessInstanceCreateReqDTO()
+                                .setProcessDefinitionKey(PROCESS_KEY)
+                                .setVariables(processInstanceVariables)
+                                .setBusinessKey(String.valueOf(oaConversion.getId()))
+                                .setStartUserSelectAssignees(startUserSelectAssignees));
+
+        //获取下一个审批人
+        Task task = taskService.createTaskQuery().processInstanceId(processInstanceId).singleResult();
 
-        // 返回
+        // 审批同意
+        BpmTaskApproveReqVO agreeReqVO = new BpmTaskApproveReqVO();
+        agreeReqVO.setId(task.getId());
+        agreeReqVO.setReason("[首次提交]");
+        agreeReqVO.setTaskStatus(Integer.valueOf(DictDataConstants.OA_AUDIT_STATUS_COMMITTED));
+        taskService.setVariable(task.getId(), BpmConstants.PROCESS_INSTANCE_VARIABLE_STATUS, DictDataConstants.OA_AUDIT_STATUS_COMMITTED);
+        taskService.setVariable(task.getId(), "auditPass", "true");
+        bpmTaskService.approveTask(loginUserId, agreeReqVO);
+
+        Task nextTask = taskService.createTaskQuery().processInstanceId(processInstanceId).singleResult();
+        if (nextTask == null) {
+            throw exception(ErrorCodeConstants.TASK_CREATE_FAIL_NO_START_SELECT_ASSIGNEE);
+        }
+        Long currentAuditEmployeeId = Long.valueOf(nextTask.getAssignee());
+        AdminUserRespDTO currentAuditEmployee = adminUserApi.getUser(currentAuditEmployeeId);
+
+
+        // 将工作流的流程实例ID、单据状态、最后一次审批时间、当前审批人更新到单据信息中
+        oaConversionMapper.updateById(new OaConversionDO()
+                .setId(oaConversion.getId())
+                .setProcInstId(processInstanceId)
+                .setAuditStatus(DictDataConstants.OA_AUDIT_STATUS_COMMITTED)
+                .setFinalAuditDate(LocalDateTime.now())
+                .setCurrentAuditEmployeeId(currentAuditEmployeeId)
+                .setCurrentAuditEmployeeName(currentAuditEmployee.getNickname())
+                .setStartUserSelectAssignees(selectAssignees.stream().map(String::valueOf).collect(Collectors.joining(","))));
+        // 保存业务uuid到附件中
+        saveFileList(commitReqVO.getFileIdList(), oaConversion.getConversionId());
+        // TODO DP 发送提交成功站内信
         return oaConversion.getId();
     }
+
     @Override
-    public Long completeTrueOaConversion(Long userId, BpmTaskApproveReqVO reqVO) {
-        Task currentTask = bpmTaskService.getTask(reqVO.getId());
+    @Transactional
+    public Long agreeOaConversion(BpmTaskApproveReqVO agreeReqVO) {
+        // 登录人信息
+        Long loginUserId = SecurityFrameworkUtils.getLoginUserId();
+        // TODO DP 根据登录人查询出对应的员工信息
+
+        Task currentTask = bpmTaskService.getTask(agreeReqVO.getId());
+        if (currentTask == null) {
+            throw exception(ErrorCodeConstants.TASK_NOT_EXISTS);
+        }
+        // 先更新为审批中
+        taskService.setVariable(currentTask.getId(), BpmConstants.PROCESS_INSTANCE_VARIABLE_STATUS, DictDataConstants.OA_AUDIT_STATUS_AUDITING);
+        LambdaQueryWrapper<OaConversionDO> lambdaQueryWrapper = new LambdaQueryWrapper<>();
+        lambdaQueryWrapper.eq(OaConversionDO::getProcInstId, currentTask.getProcessInstanceId());
+        OaConversionDO oaConversion = oaConversionMapper.selectOne(lambdaQueryWrapper);
+        // 如果是最后一个人审批同意,设置流程审批状态为已审核
+        String[] auditPersons = oaConversion.getStartUserSelectAssignees().split(",");
+        String lastAuditPerson = Arrays.stream(auditPersons)
+                .reduce((first, second) -> second)
+                .orElse(null);
+        if (currentTask.getAssignee().equals(lastAuditPerson)) {
+            // 更新为已审核(暂时未生效,未找到原因,先不处理)
+            taskService.setVariable(agreeReqVO.getId(),BpmConstants.PROCESS_INSTANCE_VARIABLE_STATUS, DictDataConstants.OA_AUDIT_STATUS_AUDITED);
+        }
         // 审批同意
-        bpmTaskService.approveTask(userId, reqVO);
+        String reason = "[同意]";
+        if (StrUtil.isNotBlank(agreeReqVO.getReason())) {
+            reason = reason + agreeReqVO.getReason();
+        }
+        agreeReqVO.setReason(reason);
+        agreeReqVO.setTaskStatus(Integer.valueOf(DictDataConstants.OA_AUDIT_STATUS_AUDITING));
+        taskService.setVariable(agreeReqVO.getId(), "auditPass", "true");
+        bpmTaskService.approveTask(loginUserId, agreeReqVO);
 
         Task nextTask = taskService.createTaskQuery().processInstanceId(currentTask.getProcessInstanceId()).singleResult();
+        OaConversionDO oaConversionDO = new OaConversionDO();
         if (nextTask != null) {
-            LambdaUpdateWrapper<OaConversionDO> updateWrapper = new LambdaUpdateWrapper<>();
-            updateWrapper.set(OaConversionDO::getAuditStatus, "2")
-                    .set(OaConversionDO::getCurrentAuditEmployeeId, nextTask.getAssignee())
-                    .set(OaConversionDO::getFinalAuditDate, new Date())
-                    .eq(OaConversionDO::getProcInstId, currentTask.getProcessInstanceId());
-            oaConversionMapper.update(updateWrapper);
+            Long currentAuditEmployeeId = Long.valueOf(nextTask.getAssignee());
+            AdminUserRespDTO currentAuditEmployee = adminUserApi.getUser(currentAuditEmployeeId);
+
+            // 如果审批人重复,实际未结束,再次更新为审核中
+            taskService.setVariable(nextTask.getId(), BpmConstants.PROCESS_INSTANCE_VARIABLE_STATUS, DictDataConstants.OA_AUDIT_STATUS_AUDITING);
+            oaConversionDO.setAuditStatus(DictDataConstants.OA_AUDIT_STATUS_AUDITING)
+                    .setCurrentAuditEmployeeId(currentAuditEmployeeId)
+                    .setCurrentAuditEmployeeName(currentAuditEmployee.getNickname())
+                    .setFinalAuditDate(LocalDateTime.now())
+                    .setId(oaConversion.getId());
+
         } else {
-            LambdaUpdateWrapper<OaConversionDO> updateWrapper = new LambdaUpdateWrapper<>();
-            updateWrapper.set(OaConversionDO::getAuditStatus, "3")
-                    .set(OaConversionDO::getCurrentAuditEmployeeId, null)
-                    .set(OaConversionDO::getFinalAuditDate, new Date())
-                    .eq(OaConversionDO::getProcInstId, currentTask.getProcessInstanceId());
-            oaConversionMapper.update(updateWrapper);
+            oaConversionDO.setAuditStatus(DictDataConstants.OA_AUDIT_STATUS_AUDITED)
+                    .setCurrentAuditEmployeeId(null)
+                    .setCurrentAuditEmployeeName(null)
+                    .setFinalAuditDate(LocalDateTime.now())
+                    .setId(oaConversion.getId());
 
             // TODO 复制业务单据信息到业务模块单据表
 
         }
+        oaConversionMapper.updateById(oaConversionDO);
         // 发送通知
 
         // 返回
@@ -150,81 +283,187 @@ public class OaConversionServiceImpl extends ServiceImpl<OaConversionMapper, OaC
     }
 
     @Override
-    public Long completeFalseOaConversion(Long userId, BpmTaskApproveReqVO reqVO) {
+    @Transactional
+    public Long disagreeOaConversion(BpmTaskReturnReqVO disagreeReqVO) {
+        // 登录人信息
+        Long loginUserId = SecurityFrameworkUtils.getLoginUserId();
+        // TODO DP 根据登录人查询出对应的员工信息
 
-        Task currentTask = bpmTaskService.getTask(reqVO.getId());
+        Task currentTask = bpmTaskService.getTask(disagreeReqVO.getId());
 
-        BpmTaskReturnReqVO reqVO2 = BeanUtils.toBean(reqVO, BpmTaskReturnReqVO.class);
-        reqVO2.setTargetTaskDefinitionKey("modifyApply");
-        bpmTaskService.returnTask(userId, reqVO2);
+        disagreeReqVO.setTargetTaskDefinitionKey("modifyApply");
+        disagreeReqVO.setReason("[驳回]" + disagreeReqVO.getReason());
+        disagreeReqVO.setTaskStatus(Integer.valueOf(DictDataConstants.OA_AUDIT_STATUS_RETURNED));
+        taskService.setVariable(disagreeReqVO.getId(), "auditPass", "false");
+        taskService.setVariable(disagreeReqVO.getId(),BpmConstants.PROCESS_INSTANCE_VARIABLE_STATUS, DictDataConstants.OA_AUDIT_STATUS_RETURNED);
+        bpmTaskService.returnTask(loginUserId, disagreeReqVO);
 
         Task nextTask = taskService.createTaskQuery().processInstanceId(currentTask.getProcessInstanceId()).singleResult();
+        Long currentAuditEmployeeId = Long.valueOf(nextTask.getAssignee());
+        AdminUserRespDTO currentAuditEmployee = adminUserApi.getUser(currentAuditEmployeeId);
 
         // 更新单据状态,当前处理人,最后处理时间
         LambdaUpdateWrapper<OaConversionDO> updateWrapper = new LambdaUpdateWrapper<>();
-        updateWrapper.set(OaConversionDO::getCurrentAuditEmployeeId, nextTask.getAssignee())
-                .set(OaConversionDO::getFinalAuditDate, new Date())
-                .set(OaConversionDO::getAuditStatus, "0")
+        updateWrapper.set(OaConversionDO::getCurrentAuditEmployeeId, currentAuditEmployeeId)
+                .set(OaConversionDO::getCurrentAuditEmployeeName, currentAuditEmployee.getNickname())
+                .set(OaConversionDO::getFinalAuditDate, LocalDateTime.now())
+                .set(OaConversionDO::getAuditStatus, DictDataConstants.OA_AUDIT_STATUS_RETURNED)
                 .eq(OaConversionDO::getProcInstId, currentTask.getProcessInstanceId());
         oaConversionMapper.update(updateWrapper);
 
         // 发送通知
 
-        // 返回
         return 1L;
     }
 
     @Override
-    public Long updateCompleteOaConversion(Long userId, OaConversionSaveReqVO createReqVO, BpmTaskApproveReqVO reqVO) {
-        // 判断是否已经发起流程
-        Boolean auditPass = createReqVO.getAuditPass();
+    @Transactional
+    public Long revocationOaConversion(BpmTaskApproveReqVO revocationReqVO) {
+        // 登录人信息
+        Long loginUserId = SecurityFrameworkUtils.getLoginUserId();
+        // TODO DP 根据登录人查询出对应的员工信息
+
+        Task currentTask = bpmTaskService.getTask(revocationReqVO.getId());
+        if (currentTask == null) {
+            throw ServiceExceptionUtil.exception(ErrorCodeConstants.TASK_NOT_EXISTS);
+        }
+        LambdaQueryWrapper<OaConversionDO> lambdaQueryWrapper = new LambdaQueryWrapper<OaConversionDO>()
+                .eq(OaConversionDO::getProcInstId, currentTask.getProcessInstanceId());
+        OaConversionDO oaConversionDO = oaConversionMapper.selectOne(lambdaQueryWrapper);
+        if (!DictDataConstants.OA_AUDIT_STATUS_COMMITTED.equals(oaConversionDO.getAuditStatus())
+                || !Objects.equals(String.valueOf(loginUserId), oaConversionDO.getCreator())) {
+            throw ServiceExceptionUtil.exception(ErrorCodeConstants.TASK_REVOCATION_NOT_ALLOWED);
+        }
 
-        OaConversionDO oaConversion = BeanUtils.toBean(createReqVO, OaConversionDO.class);
+        BpmTaskReturnReqVO returnReqVO = BeanUtils.toBean(revocationReqVO, BpmTaskReturnReqVO.class);
+        returnReqVO.setTargetTaskDefinitionKey("modifyApply");
+        String reason = "[撤回]";
+        if (StrUtil.isNotBlank(returnReqVO.getReason())) {
+            reason = reason + returnReqVO.getReason();
+        }
+        returnReqVO.setReason(reason);
+        returnReqVO.setTaskStatus(Integer.valueOf(DictDataConstants.OA_AUDIT_STATUS_RECALLED));
+        taskService.setVariable(currentTask.getId(),BpmConstants.PROCESS_INSTANCE_VARIABLE_STATUS, DictDataConstants.OA_AUDIT_STATUS_RECALLED);
+        bpmTaskService.revocationTask(loginUserId, returnReqVO);
 
-        Task currentTask = taskService.createTaskQuery().processInstanceId(oaConversion.getProcInstId()).singleResult();
+        Task nextTask = taskService.createTaskQuery().processInstanceId(currentTask.getProcessInstanceId()).singleResult();
+        Long currentAuditEmployeeId = Long.valueOf(nextTask.getAssignee());
+        AdminUserRespDTO currentAuditEmployee = adminUserApi.getUser(currentAuditEmployeeId);
 
-        //审批通过
-        bpmTaskService.approveTask(userId, reqVO);
+        // 更新单据状态,当前处理人,最后处理时间
+        LambdaUpdateWrapper<OaConversionDO> updateWrapper = new LambdaUpdateWrapper<>();
+        updateWrapper.set(OaConversionDO::getCurrentAuditEmployeeId, currentAuditEmployeeId)
+                .set(OaConversionDO::getCurrentAuditEmployeeName, currentAuditEmployee.getNickname())
+                .set(OaConversionDO::getFinalAuditDate, LocalDateTime.now())
+                .set(OaConversionDO::getAuditStatus, DictDataConstants.OA_AUDIT_STATUS_RECALLED)
+                .eq(OaConversionDO::getProcInstId, currentTask.getProcessInstanceId());
+        oaConversionMapper.update(updateWrapper);
 
-        // 提交
-        if (auditPass) {
-            Task nextTask = taskService.createTaskQuery().processInstanceId(currentTask.getProcessInstanceId()).singleResult();
+        // 发送通知
 
-            oaConversion.setAuditStatus("1");
-            oaConversion.setCurrentAuditEmployeeId(Long.valueOf(nextTask.getAssignee()));
-            oaConversion.setFinalAuditDate(LocalDateTime.now());
-            oaConversionMapper.updateById(oaConversion);
+        return 1L;
+    }
 
-        } else {
-            OaConversionDO oaConversionClose = new OaConversionDO();
-            oaConversionClose.setId(oaConversion.getId());
-            oaConversionClose.setAuditStatus("4");
-            oaConversionClose.setCurrentAuditEmployeeId(null);
-            oaConversionClose.setFinalAuditDate(LocalDateTime.now());
-            oaConversionMapper.updateById(oaConversionClose);
+    @Override
+    @Transactional
+    public Long reCommitOaConversion(OaConversionSaveReqVO reCommitReqVO) {
+        if (reCommitReqVO.getId() == null) {
+            throw exception(ErrorCodeConstants.SERVICE_ID_NOT_EXISTS);
+        }
+        // 登录人信息
+        Long loginUserId = SecurityFrameworkUtils.getLoginUserId();
+        AdminUserRespDTO loginUser = adminUserApi.getUser(loginUserId);
+        if (loginUser == null) {
+            throw exception(ErrorCodeConstants.OA_LOGIN_USER_NOT_EXISTS);
+        }
+        // 转正人信息
+        AdminUserRespDTO employee = adminUserApi.getUser(reCommitReqVO.getEmployeeId());
+        if (employee == null) {
+            throw exception(ErrorCodeConstants.OA_EMPLOYEE_NOT_EXISTS);
         }
 
-        return oaConversion.getId();
-    }
+        OaConversionDO oaConversionNew = BeanUtils.toBean(reCommitReqVO, OaConversionDO.class);
+        OaConversionDO oaConversionOld = oaConversionMapper.selectById(oaConversionNew.getId());
+        oaConversionNew.setConversionId(oaConversionOld.getConversionId())
+                .setProcInstId(oaConversionOld.getProcInstId());
+
+        oaConversionNew.setEmployeeId(employee.getId());
+        oaConversionNew.setEmployeeName(employee.getNickname());
+        oaConversionNew.setEmployeePhone(employee.getMobile());
+        oaConversionNew.setDeptId(employee.getDeptId());
+        oaConversionNew.setPosition("员工职位");
+        oaConversionNew.setUserId(loginUser.getId());
+        oaConversionNew.setApplyEmployeeId(loginUser.getId());
+        oaConversionNew.setApplyEmployeeName(loginUser.getNickname());
+
+        Task currentTask = taskService.createTaskQuery().processInstanceId(oaConversionNew.getProcInstId()).singleResult();
+        BpmTaskApproveReqVO approveReqVO = new BpmTaskApproveReqVO();
+        approveReqVO.setId(currentTask.getId())
+                .setReason("[再次提交]");
+        approveReqVO.setTaskStatus(Integer.valueOf(DictDataConstants.OA_AUDIT_STATUS_COMMITTED));
+        if (CollectionUtil.isNotEmpty(reCommitReqVO.getStartUserSelectAssignees())) {
+            // 添加审批人信息到流程参数中
+            Map<String, List<Long>> startUserSelectAssignees = new HashMap<>();
+            List<Long> selectAssignees = reCommitReqVO.getStartUserSelectAssignees();
+            startUserSelectAssignees.put("approver", selectAssignees);
+            taskService.setVariable(currentTask.getId(), BpmConstants.PROCESS_INSTANCE_VARIABLE_START_USER_SELECT_ASSIGNEES, startUserSelectAssignees);
+            // 保存审批人信息
+            oaConversionNew.setStartUserSelectAssignees(selectAssignees.stream().map(String::valueOf).collect(Collectors.joining(",")));
+        }
+        taskService.setVariable(currentTask.getId(), "auditPass", "true");
+        taskService.setVariable(currentTask.getId(),BpmConstants.PROCESS_INSTANCE_VARIABLE_STATUS, DictDataConstants.OA_AUDIT_STATUS_COMMITTED);
+        // 再次提交,和审批通过逻辑相同
+        bpmTaskService.approveTask(loginUserId, approveReqVO);
 
+        Task nextTask = taskService.createTaskQuery().processInstanceId(currentTask.getProcessInstanceId()).singleResult();
+        Long currentAuditEmployeeId = Long.valueOf(nextTask.getAssignee());
+        AdminUserRespDTO currentAuditEmployee = adminUserApi.getUser(currentAuditEmployeeId);
+        oaConversionNew.setAuditStatus(DictDataConstants.OA_AUDIT_STATUS_COMMITTED)
+                .setCurrentAuditEmployeeId(currentAuditEmployeeId)
+                .setCurrentAuditEmployeeName(currentAuditEmployee.getNickname())
+                .setFinalAuditDate(LocalDateTime.now());
+        oaConversionMapper.updateById(oaConversionNew);
 
+        // 保存业务uuid到附件中
+        saveFileList(reCommitReqVO.getFileIdList(), oaConversionNew.getConversionId());
 
-    @Override
-    public Long createOaConversion(OaConversionSaveReqVO createReqVO) {
-        // 插入
-        OaConversionDO oaConversion = BeanUtils.toBean(createReqVO, OaConversionDO.class);
-        oaConversionMapper.insert(oaConversion);
-        // 返回
-        return oaConversion.getId();
+        return 1L;
     }
 
     @Override
-    public void updateOaConversion(OaConversionSaveReqVO updateReqVO) {
-        // 校验存在
-        validateOaConversionExists(updateReqVO.getId());
-        // 更新
-        OaConversionDO updateObj = BeanUtils.toBean(updateReqVO, OaConversionDO.class);
-        oaConversionMapper.updateById(updateObj);
+    @Transactional
+    public Long closeOaConversion(Long id) {
+        if (id == null) {
+            throw exception(ErrorCodeConstants.SERVICE_ID_NOT_EXISTS);
+        }
+        // 登录人信息
+        Long loginUserId = SecurityFrameworkUtils.getLoginUserId();
+        // TODO DP 根据登录人查询出对应的员工信息
+
+        OaConversionDO oaConversionDO = oaConversionMapper.selectById(id);
+        if (!DictDataConstants.OA_AUDIT_STATUS_RETURNED.equals(oaConversionDO.getAuditStatus())
+                && !DictDataConstants.OA_AUDIT_STATUS_RECALLED.equals(oaConversionDO.getAuditStatus())) {
+            throw exception(ErrorCodeConstants.TASK_CLOSE_NOT_ALLOWED);
+        }
+
+        Task currentTask = taskService.createTaskQuery().processInstanceId(oaConversionDO.getProcInstId()).singleResult();
+        BpmTaskApproveReqVO approveReqVO = new BpmTaskApproveReqVO();
+        approveReqVO.setId(currentTask.getId())
+                .setReason("[关闭]");
+        approveReqVO.setTaskStatus(Integer.valueOf(DictDataConstants.OA_AUDIT_STATUS_CLOSED));
+        taskService.setVariable(currentTask.getId(), "auditPass", "false");
+        taskService.setVariable(currentTask.getId(),BpmConstants.PROCESS_INSTANCE_VARIABLE_STATUS, DictDataConstants.OA_AUDIT_STATUS_CLOSED);
+        // 关闭,使用审批通过的方法实现
+        bpmTaskService.approveTask(loginUserId, approveReqVO);
+
+        LambdaUpdateWrapper<OaConversionDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
+        lambdaUpdateWrapper.set(OaConversionDO::getAuditStatus, DictDataConstants.OA_AUDIT_STATUS_CLOSED)
+                .set(OaConversionDO::getCurrentAuditEmployeeId, null)
+                .set(OaConversionDO::getCurrentAuditEmployeeName, null)
+                .set(OaConversionDO::getFinalAuditDate, LocalDateTime.now())
+                .eq(OaConversionDO::getId, id);
+        oaConversionMapper.update(lambdaUpdateWrapper);
+        return 1L;
     }
 
     @Override
@@ -235,20 +474,167 @@ public class OaConversionServiceImpl extends ServiceImpl<OaConversionMapper, OaC
         oaConversionMapper.deleteById(id);
     }
 
-    private void validateOaConversionExists(Long id) {
-        if (oaConversionMapper.selectById(id) == null) {
-            throw exception(OA_CONVERSION_NOT_EXISTS);
+    @Override
+    public OaConversionRespVO getOaConversion(Long id) {
+        // 登录人信息
+        Long loginUserId = SecurityFrameworkUtils.getLoginUserId();
+        // TODO DP 根据登录人查询出对应的员工信息
+
+        OaConversionDO oaConversionDO = oaConversionMapper.selectById(id);
+        OaConversionRespVO oaConversionRespVO = BeanUtils.toBean(oaConversionDO, OaConversionRespVO.class);
+        if (oaConversionDO.getDeptId() != null) {
+            DeptRespDTO dept = deptApi.getDept(oaConversionDO.getDeptId());
+            if (dept != null) {
+                oaConversionRespVO.setDeptName(dept.getName());
+            }
+        }
+
+        String procInstId = oaConversionDO.getProcInstId();
+        if (StrUtil.isNotBlank(procInstId)) {
+            Task task = taskService.createTaskQuery()
+                    .processInstanceId(procInstId)
+                    .taskAssignee(String.valueOf(loginUserId))
+                    .singleResult();
+            if (DictDataConstants.OA_AUDIT_STATUS_COMMITTED.equals(oaConversionDO.getAuditStatus())) {
+                // 如果是已提交,不限制任务处理人是当前登录人,用于直接撤回
+                task = taskService.createTaskQuery()
+                        .processInstanceId(procInstId)
+                        .singleResult();
+            }
+            if (task != null) {
+                oaConversionRespVO.setTaskId(task.getId());
+            }
+        }
+
+        // 附件列表
+        List<FileDTO> fileList = fileApi.getFileDTOListByBiz(oaConversionDO.getConversionId());
+        oaConversionRespVO.setFileList(fileList);
+
+        // 审批记录
+        if (StrUtil.isNotBlank(oaConversionDO.getProcInstId())) {
+            List<BpmTaskRespVO> auditRecordList = bpmTaskService.getAuditRecordListByProcessInstanceId(oaConversionDO.getProcInstId());
+            oaConversionRespVO.setAuditRecordList(auditRecordList);
         }
+
+        // 审批人
+        String startUserSelectAssignees = oaConversionDO.getStartUserSelectAssignees();
+        if (StrUtil.isNotEmpty(startUserSelectAssignees)) {
+            List<Long> userIdList = Arrays.stream(startUserSelectAssignees.split(","))
+                    .map(Long::valueOf).collect(Collectors.toList());
+            List<AdminUserRespDTO> userList = adminUserApi.getUserList(userIdList);
+            List<AdminUserRespDTO> auditUserList = new ArrayList<>();
+            for (Long userId : userIdList) {
+                for (AdminUserRespDTO adminUserRespDTO : userList) {
+                    if (Objects.equals(userId, adminUserRespDTO.getId())) {
+                        auditUserList.add(adminUserRespDTO);
+                        break;
+                    }
+                }
+            }
+            oaConversionRespVO.setAuditUserList(auditUserList);
+        }
+
+        return oaConversionRespVO;
     }
 
     @Override
-    public OaConversionDO getOaConversion(Long id) {
-        return oaConversionMapper.selectById(id);
+    public OaConversionRespVO getOaConversionByProcInstId(String procInstId) {
+        OaConversionDO oaConversionDO = oaConversionMapper.selectOne(OaConversionDO::getProcInstId, procInstId);
+        OaConversionRespVO oaConversionRespVO = BeanUtils.toBean(oaConversionDO, OaConversionRespVO.class);
+        if (oaConversionDO.getDeptId() != null) {
+            DeptRespDTO dept = deptApi.getDept(oaConversionDO.getDeptId());
+            if (dept != null) {
+                oaConversionRespVO.setDeptName(dept.getName());
+            }
+        }
+
+        // 附件列表
+        List<FileDTO> fileList = fileApi.getFileDTOListByBiz(oaConversionDO.getConversionId());
+        oaConversionRespVO.setFileList(fileList);
+
+        // 审批记录
+        if (StrUtil.isNotBlank(oaConversionDO.getProcInstId())) {
+            List<BpmTaskRespVO> auditRecordList = bpmTaskService.getAuditRecordListByProcessInstanceId(oaConversionDO.getProcInstId());
+            oaConversionRespVO.setAuditRecordList(auditRecordList);
+        }
+
+        // 审批人
+        String startUserSelectAssignees = oaConversionDO.getStartUserSelectAssignees();
+        if (StrUtil.isNotEmpty(startUserSelectAssignees)) {
+            List<Long> userIdList = Arrays.stream(startUserSelectAssignees.split(","))
+                    .map(Long::valueOf).collect(Collectors.toList());
+            List<AdminUserRespDTO> userList = adminUserApi.getUserList(userIdList);
+            List<AdminUserRespDTO> auditUserList = new ArrayList<>();
+            for (Long userId : userIdList) {
+                for (AdminUserRespDTO adminUserRespDTO : userList) {
+                    if (Objects.equals(userId, adminUserRespDTO.getId())) {
+                        auditUserList.add(adminUserRespDTO);
+                        break;
+                    }
+                }
+            }
+            oaConversionRespVO.setAuditUserList(auditUserList);
+        }
+
+        return oaConversionRespVO;
     }
 
     @Override
-    public PageResult<OaConversionDO> getOaConversionPage(OaConversionPageReqVO pageReqVO) {
-        return oaConversionMapper.selectPage(pageReqVO);
+    public PageResult<OaConversionRespVO> getOaConversionPage(OaConversionPageReqVO pageReqVO) {
+        PageResult<OaConversionDO> oaConversionDOPageResult = oaConversionMapper.selectPage(pageReqVO);
+        PageResult<OaConversionRespVO> oaConversionRespVOPageResult = BeanUtils.toBean(oaConversionDOPageResult, OaConversionRespVO.class);
+
+        List<OaConversionRespVO> oaConversionRespVOList = oaConversionRespVOPageResult.getList();
+        if (CollectionUtil.isNotEmpty(oaConversionRespVOList)) {
+            List<Long> employeeIdList = oaConversionRespVOList.stream().map(OaConversionRespVO::getCurrentAuditEmployeeId).collect(Collectors.toList());
+            List<AdminUserRespDTO> employeeList = adminUserApi.getUserList(employeeIdList);
+            for (OaConversionRespVO respVO : oaConversionRespVOList) {
+                for (AdminUserRespDTO employee : employeeList) {
+                    if (respVO.getCurrentAuditEmployeeId() == employee.getId()) {
+                        respVO.setCurrentAuditEmployeeName(employee.getNickname());
+                        break;
+                    }
+                }
+            }
+
+            List<Long> deptIdList = oaConversionRespVOList.stream().map(OaConversionRespVO::getDeptId).collect(Collectors.toList());
+            List<DeptRespDTO> deptList = deptApi.getDeptList(deptIdList);
+            for (OaConversionRespVO respVO : oaConversionRespVOList) {
+                for (DeptRespDTO dept : deptList) {
+                    if (respVO.getDeptId() == dept.getId()) {
+                        respVO.setDeptName(dept.getName());
+                        break;
+                    }
+                }
+            }
+        }
+
+        return oaConversionRespVOPageResult;
+    }
+
+    @Override
+    public PageResult<OaConversionRespVO> exportOaConversionExcel(OaConversionPageReqVO pageReqVO) {
+        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
+        return getOaConversionPage(pageReqVO);
+    }
+
+    private void validateOaConversionExists(Long id) {
+        OaConversionDO oaConversionDO = oaConversionMapper.selectById(id);
+        if (oaConversionDO == null) {
+            throw exception(OA_UNIVERSAL_NOT_EXISTS);
+        }
+        if (!DictDataConstants.OA_AUDIT_STATUS_STAGING.equals(oaConversionDO.getAuditStatus())) {
+            throw exception(ErrorCodeConstants.DELETE_FAIL_NOT_STAGING);
+        }
+    }
+
+    /**
+     * 保存业务uuid到附件中
+     */
+    private void saveFileList(List<Long> fileIdList, String serviceId) {
+        if (CollectionUtil.isNotEmpty(fileIdList) && StrUtil.isNotEmpty(serviceId)) {
+            fileApi.updateFileBiz(fileIdList, serviceId);
+        }
     }
 
 }

+ 1 - 1
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/entry/OaEntryService.java

@@ -26,7 +26,7 @@ public interface OaEntryService {
 
     Long reCommitOaEntry(OaEntrySaveReqVO reCommitReqVO);
 
-    Long closeOaEntry(OaEntrySaveReqVO closeReqVO);
+    Long closeOaEntry(Long id);
 
     void deleteOaEntry(Long id);
 

+ 15 - 10
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/entry/OaEntryServiceImpl.java

@@ -294,7 +294,7 @@ public class OaEntryServiceImpl implements OaEntryService {
         OaEntryDO oaEntryDO = oaEntryMapper.selectOne(lambdaQueryWrapper);
         if (!DictDataConstants.OA_AUDIT_STATUS_COMMITTED.equals(oaEntryDO.getAuditStatus())
                 || !Objects.equals(String.valueOf(loginUserId), oaEntryDO.getCreator())) {
-            throw ServiceExceptionUtil.exception(ErrorCodeConstants.TASK_REVOCATION_NO_ALLOWED);
+            throw ServiceExceptionUtil.exception(ErrorCodeConstants.TASK_REVOCATION_NOT_ALLOWED);
         }
 
         BpmTaskReturnReqVO returnReqVO = BeanUtils.toBean(revocationReqVO, BpmTaskReturnReqVO.class);
@@ -371,18 +371,21 @@ public class OaEntryServiceImpl implements OaEntryService {
 
     @Override
     @Transactional
-    public Long closeOaEntry(OaEntrySaveReqVO closeReqVO) {
-        if (closeReqVO.getId() == null) {
+    public Long closeOaEntry(Long id) {
+        if (id == null) {
             throw exception(ErrorCodeConstants.SERVICE_ID_NOT_EXISTS);
         }
         // 登录人信息
         Long loginUserId = SecurityFrameworkUtils.getLoginUserId();
         // TODO DP 根据登录人查询出对应的员工信息
 
-        OaEntryDO oaEntryNew = BeanUtils.toBean(closeReqVO, OaEntryDO.class);
-        OaEntryDO oaEntryOld = oaEntryMapper.selectById(oaEntryNew.getId());
+        OaEntryDO oaEntryDO = oaEntryMapper.selectById(id);
+        if (!DictDataConstants.OA_AUDIT_STATUS_RETURNED.equals(oaEntryDO.getAuditStatus())
+                && !DictDataConstants.OA_AUDIT_STATUS_RECALLED.equals(oaEntryDO.getAuditStatus())) {
+            throw exception(ErrorCodeConstants.TASK_CLOSE_NOT_ALLOWED);
+        }
 
-        Task currentTask = taskService.createTaskQuery().processInstanceId(oaEntryOld.getProcInstId()).singleResult();
+        Task currentTask = taskService.createTaskQuery().processInstanceId(oaEntryDO.getProcInstId()).singleResult();
         BpmTaskApproveReqVO approveReqVO = new BpmTaskApproveReqVO();
         approveReqVO.setId(currentTask.getId())
                 .setReason("[关闭]");
@@ -392,10 +395,12 @@ public class OaEntryServiceImpl implements OaEntryService {
         // 关闭,使用审批通过的方法实现
         bpmTaskService.approveTask(loginUserId, approveReqVO);
 
-        oaEntryOld.setAuditStatus(DictDataConstants.OA_AUDIT_STATUS_CLOSED)
-                .setCurrentAuditEmployeeId(-1L)
-                .setFinalAuditDate(LocalDateTime.now());
-        oaEntryMapper.updateById(oaEntryOld);
+        LambdaUpdateWrapper<OaEntryDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
+        lambdaUpdateWrapper.set(OaEntryDO::getAuditStatus, DictDataConstants.OA_AUDIT_STATUS_CLOSED)
+                .set(OaEntryDO::getCurrentAuditEmployeeId, null)
+                .set(OaEntryDO::getFinalAuditDate, LocalDateTime.now())
+                .eq(OaEntryDO::getId, id);
+        oaEntryMapper.update(lambdaUpdateWrapper);
 
         return 1L;
     }

+ 1 - 1
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/universal/OaUniversalService.java

@@ -26,7 +26,7 @@ public interface OaUniversalService {
 
     Long reCommitOaUniversal(OaUniversalSaveReqVO reCommitReqVO);
 
-    Long closeOaUniversal(OaUniversalSaveReqVO closeReqVO);
+    Long closeOaUniversal(Long id);
 
     void deleteOaUniversal(Long id);
 

+ 15 - 10
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/universal/OaUniversalServiceImpl.java

@@ -309,7 +309,7 @@ public class OaUniversalServiceImpl implements OaUniversalService {
         OaUniversalDO oaUniversalDO = oaUniversalMapper.selectOne(lambdaQueryWrapper);
         if (!DictDataConstants.OA_AUDIT_STATUS_COMMITTED.equals(oaUniversalDO.getAuditStatus())
             || !Objects.equals(String.valueOf(loginUserId), oaUniversalDO.getCreator())) {
-            throw ServiceExceptionUtil.exception(ErrorCodeConstants.TASK_REVOCATION_NO_ALLOWED);
+            throw ServiceExceptionUtil.exception(ErrorCodeConstants.TASK_REVOCATION_NOT_ALLOWED);
         }
 
         BpmTaskReturnReqVO returnReqVO = BeanUtils.toBean(revocationReqVO, BpmTaskReturnReqVO.class);
@@ -386,18 +386,21 @@ public class OaUniversalServiceImpl implements OaUniversalService {
 
     @Override
     @Transactional
-    public Long closeOaUniversal(OaUniversalSaveReqVO closeReqVO) {
-        if (closeReqVO.getId() == null) {
+    public Long closeOaUniversal(Long id) {
+        if (id == null) {
             throw exception(ErrorCodeConstants.SERVICE_ID_NOT_EXISTS);
         }
         // 登录人信息
         Long loginUserId = SecurityFrameworkUtils.getLoginUserId();
         // TODO DP 根据登录人查询出对应的员工信息
 
-        OaUniversalDO oaUniversalNew = BeanUtils.toBean(closeReqVO, OaUniversalDO.class);
-        OaUniversalDO oaUniversalOld = oaUniversalMapper.selectById(oaUniversalNew.getId());
+        OaUniversalDO oaUniversalDO = oaUniversalMapper.selectById(id);
+        if (!DictDataConstants.OA_AUDIT_STATUS_RETURNED.equals(oaUniversalDO.getAuditStatus())
+            && !DictDataConstants.OA_AUDIT_STATUS_RECALLED.equals(oaUniversalDO.getAuditStatus())) {
+            throw exception(ErrorCodeConstants.TASK_CLOSE_NOT_ALLOWED);
+        }
 
-        Task currentTask = taskService.createTaskQuery().processInstanceId(oaUniversalOld.getProcInstId()).singleResult();
+        Task currentTask = taskService.createTaskQuery().processInstanceId(oaUniversalDO.getProcInstId()).singleResult();
         BpmTaskApproveReqVO approveReqVO = new BpmTaskApproveReqVO();
         approveReqVO.setId(currentTask.getId())
                 .setReason("[关闭]");
@@ -407,10 +410,12 @@ public class OaUniversalServiceImpl implements OaUniversalService {
         // 关闭,使用审批通过的方法实现
         bpmTaskService.approveTask(loginUserId, approveReqVO);
 
-        oaUniversalOld.setAuditStatus(DictDataConstants.OA_AUDIT_STATUS_CLOSED)
-                .setCurrentAuditEmployeeId(-1L)
-                .setFinalAuditDate(LocalDateTime.now());
-        oaUniversalMapper.updateById(oaUniversalOld);
+        LambdaUpdateWrapper<OaUniversalDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
+        lambdaUpdateWrapper.set(OaUniversalDO::getAuditStatus, DictDataConstants.OA_AUDIT_STATUS_CLOSED)
+                .set(OaUniversalDO::getCurrentAuditEmployeeId, null)
+                .set(OaUniversalDO::getFinalAuditDate, LocalDateTime.now())
+                .eq(OaUniversalDO::getId, id);
+        oaUniversalMapper.update(lambdaUpdateWrapper);
 
         return 1L;
     }

+ 218 - 217
yudao-module-bpm/yudao-module-bpm-biz/src/test/java/cn/iocoder/yudao/module/bpm/service/oa/conversion/OaConversionServiceImplTest.java

@@ -1,217 +1,218 @@
-package cn.iocoder.yudao.module.bpm.service.oa.conversion;
-
-import cn.iocoder.yudao.module.bpm.controller.admin.oa.conversion.vo.OaConversionPageReqVO;
-import cn.iocoder.yudao.module.bpm.controller.admin.oa.conversion.vo.OaConversionSaveReqVO;
-import cn.iocoder.yudao.module.bpm.service.oa.conversion.OaConversionServiceImpl;
-import org.junit.jupiter.api.Disabled;
-import org.junit.jupiter.api.Test;
-
-import javax.annotation.Resource;
-
-import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
-
-import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.conversion.OaConversionDO;
-import cn.iocoder.yudao.module.bpm.dal.mysql.oa.conversion.OaConversionMapper;
-import cn.iocoder.yudao.framework.common.pojo.PageResult;
-
-import org.springframework.context.annotation.Import;
-
-import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*;
-import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.*;
-import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
-import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.*;
-import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.*;
-import static org.junit.jupiter.api.Assertions.*;
-
-/**
- * {@link OaConversionServiceImpl} 的单元测试类
- *
- * @author 芋道源码
- */
-@Import(OaConversionServiceImpl.class)
-public class OaConversionServiceImplTest extends BaseDbUnitTest {
-
-    @Resource
-    private OaConversionServiceImpl oaConversionService;
-
-    @Resource
-    private OaConversionMapper oaConversionMapper;
-
-    @Test
-    public void testCreateOaConversion_success() {
-        // 准备参数
-        OaConversionSaveReqVO createReqVO = randomPojo(OaConversionSaveReqVO.class).setId(null);
-
-        // 调用
-        Long oaConversionId = oaConversionService.createOaConversion(createReqVO);
-        // 断言
-        assertNotNull(oaConversionId);
-        // 校验记录的属性是否正确
-        OaConversionDO oaConversion = oaConversionMapper.selectById(oaConversionId);
-        assertPojoEquals(createReqVO, oaConversion, "id");
-    }
-
-    @Test
-    public void testUpdateOaConversion_success() {
-        // mock 数据
-        OaConversionDO dbOaConversion = randomPojo(OaConversionDO.class);
-        oaConversionMapper.insert(dbOaConversion);// @Sql: 先插入出一条存在的数据
-        // 准备参数
-        OaConversionSaveReqVO updateReqVO = randomPojo(OaConversionSaveReqVO.class, o -> {
-            o.setId(dbOaConversion.getId()); // 设置更新的 ID
-        });
-
-        // 调用
-        oaConversionService.updateOaConversion(updateReqVO);
-        // 校验是否更新正确
-        OaConversionDO oaConversion = oaConversionMapper.selectById(updateReqVO.getId()); // 获取最新的
-        assertPojoEquals(updateReqVO, oaConversion);
-    }
-
-    @Test
-    public void testUpdateOaConversion_notExists() {
-        // 准备参数
-        OaConversionSaveReqVO updateReqVO = randomPojo(OaConversionSaveReqVO.class);
-
-        // 调用, 并断言异常
-        assertServiceException(() -> oaConversionService.updateOaConversion(updateReqVO), OA_CONVERSION_NOT_EXISTS);
-    }
-
-    @Test
-    public void testDeleteOaConversion_success() {
-        // mock 数据
-        OaConversionDO dbOaConversion = randomPojo(OaConversionDO.class);
-        oaConversionMapper.insert(dbOaConversion);// @Sql: 先插入出一条存在的数据
-        // 准备参数
-        Long id = dbOaConversion.getId();
-
-        // 调用
-        oaConversionService.deleteOaConversion(id);
-       // 校验数据不存在了
-       assertNull(oaConversionMapper.selectById(id));
-    }
-
-    @Test
-    public void testDeleteOaConversion_notExists() {
-        // 准备参数
-        Long id = randomLongId();
-
-        // 调用, 并断言异常
-        assertServiceException(() -> oaConversionService.deleteOaConversion(id), OA_CONVERSION_NOT_EXISTS);
-    }
-
-    @Test
-    // @Disabled  // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解
-    public void testGetOaConversionPage() {
-       // mock 数据
-       OaConversionDO dbOaConversion = randomPojo(OaConversionDO.class, o -> { // 等会查询到
-           o.setConversionId(null);
-           o.setEmployeeId(null);
-           o.setEmployeeUuid(null);
-           o.setEmployeeName(null);
-           o.setUserId(null);
-           o.setUserUuid(null);
-           o.setDeptId(null);
-           o.setDeptUuid(null);
-           o.setPosition(null);
-           o.setEntryDate(null);
-           o.setProbationEndDate(null);
-           o.setConversionDate(null);
-           o.setConversionReason(null);
-           o.setWorkSummary(null);
-           o.setRemarks(null);
-           o.setProcInstId(null);
-           o.setAuditStatus(null);
-           o.setCurrentAuditUserId(null);
-           o.setCurrentAuditUserUuid(null);
-           o.setCurrentAuditEmployeeId(null);
-           o.setCurrentAuditEmployeeUuid(null);
-           o.setFinalAuditDate(null);
-           o.setInfoSource(null);
-           o.setCreateTime(null);
-       });
-       oaConversionMapper.insert(dbOaConversion);
-       // 测试 conversionId 不匹配
-       oaConversionMapper.insert(cloneIgnoreId(dbOaConversion, o -> o.setConversionId(null)));
-       // 测试 employeeId 不匹配
-       oaConversionMapper.insert(cloneIgnoreId(dbOaConversion, o -> o.setEmployeeId(null)));
-       // 测试 employeeUuid 不匹配
-       oaConversionMapper.insert(cloneIgnoreId(dbOaConversion, o -> o.setEmployeeUuid(null)));
-       // 测试 employeeName 不匹配
-       oaConversionMapper.insert(cloneIgnoreId(dbOaConversion, o -> o.setEmployeeName(null)));
-       // 测试 userId 不匹配
-       oaConversionMapper.insert(cloneIgnoreId(dbOaConversion, o -> o.setUserId(null)));
-       // 测试 userUuid 不匹配
-       oaConversionMapper.insert(cloneIgnoreId(dbOaConversion, o -> o.setUserUuid(null)));
-       // 测试 deptId 不匹配
-       oaConversionMapper.insert(cloneIgnoreId(dbOaConversion, o -> o.setDeptId(null)));
-       // 测试 deptUuid 不匹配
-       oaConversionMapper.insert(cloneIgnoreId(dbOaConversion, o -> o.setDeptUuid(null)));
-       // 测试 position 不匹配
-       oaConversionMapper.insert(cloneIgnoreId(dbOaConversion, o -> o.setPosition(null)));
-       // 测试 entryDate 不匹配
-       oaConversionMapper.insert(cloneIgnoreId(dbOaConversion, o -> o.setEntryDate(null)));
-       // 测试 probationEndDate 不匹配
-       oaConversionMapper.insert(cloneIgnoreId(dbOaConversion, o -> o.setProbationEndDate(null)));
-       // 测试 conversionDate 不匹配
-       oaConversionMapper.insert(cloneIgnoreId(dbOaConversion, o -> o.setConversionDate(null)));
-       // 测试 conversionReason 不匹配
-       oaConversionMapper.insert(cloneIgnoreId(dbOaConversion, o -> o.setConversionReason(null)));
-       // 测试 workSummary 不匹配
-       oaConversionMapper.insert(cloneIgnoreId(dbOaConversion, o -> o.setWorkSummary(null)));
-       // 测试 remarks 不匹配
-       oaConversionMapper.insert(cloneIgnoreId(dbOaConversion, o -> o.setRemarks(null)));
-       // 测试 procInstId 不匹配
-       oaConversionMapper.insert(cloneIgnoreId(dbOaConversion, o -> o.setProcInstId(null)));
-       // 测试 auditStatus 不匹配
-       oaConversionMapper.insert(cloneIgnoreId(dbOaConversion, o -> o.setAuditStatus(null)));
-       // 测试 currentAuditUserId 不匹配
-       oaConversionMapper.insert(cloneIgnoreId(dbOaConversion, o -> o.setCurrentAuditUserId(null)));
-       // 测试 currentAuditUserUuid 不匹配
-       oaConversionMapper.insert(cloneIgnoreId(dbOaConversion, o -> o.setCurrentAuditUserUuid(null)));
-       // 测试 currentAuditEmployeeId 不匹配
-       oaConversionMapper.insert(cloneIgnoreId(dbOaConversion, o -> o.setCurrentAuditEmployeeId(null)));
-       // 测试 currentAuditEmployeeUuid 不匹配
-       oaConversionMapper.insert(cloneIgnoreId(dbOaConversion, o -> o.setCurrentAuditEmployeeUuid(null)));
-       // 测试 finalAuditDate 不匹配
-       oaConversionMapper.insert(cloneIgnoreId(dbOaConversion, o -> o.setFinalAuditDate(null)));
-       // 测试 infoSource 不匹配
-       oaConversionMapper.insert(cloneIgnoreId(dbOaConversion, o -> o.setInfoSource(null)));
-       // 测试 createTime 不匹配
-       oaConversionMapper.insert(cloneIgnoreId(dbOaConversion, o -> o.setCreateTime(null)));
-       // 准备参数
-       OaConversionPageReqVO reqVO = new OaConversionPageReqVO();
-       reqVO.setConversionId(null);
-       reqVO.setEmployeeId(null);
-       reqVO.setEmployeeUuid(null);
-       reqVO.setEmployeeName(null);
-       reqVO.setUserId(null);
-       reqVO.setUserUuid(null);
-       reqVO.setDeptId(null);
-       reqVO.setDeptUuid(null);
-       reqVO.setPosition(null);
-       reqVO.setEntryDate(null);
-       reqVO.setProbationEndDate(null);
-       reqVO.setConversionDate(null);
-       reqVO.setConversionReason(null);
-       reqVO.setWorkSummary(null);
-       reqVO.setRemarks(null);
-       reqVO.setProcInstId(null);
-       reqVO.setAuditStatus(null);
-       reqVO.setCurrentAuditUserId(null);
-       reqVO.setCurrentAuditUserUuid(null);
-       reqVO.setCurrentAuditEmployeeId(null);
-       reqVO.setCurrentAuditEmployeeUuid(null);
-       reqVO.setFinalAuditDate(buildBetweenTime(2023, 2, 1, 2023, 2, 28));
-       reqVO.setInfoSource(null);
-       reqVO.setCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28));
-
-       // 调用
-       PageResult<OaConversionDO> pageResult = oaConversionService.getOaConversionPage(reqVO);
-       // 断言
-       assertEquals(1, pageResult.getTotal());
-       assertEquals(1, pageResult.getList().size());
-       assertPojoEquals(dbOaConversion, pageResult.getList().get(0));
-    }
-
-}
+// package cn.iocoder.yudao.module.bpm.service.oa.conversion;
+//
+// import cn.iocoder.yudao.module.bpm.controller.admin.oa.conversion.vo.OaConversionPageReqVO;
+// import cn.iocoder.yudao.module.bpm.controller.admin.oa.conversion.vo.OaConversionRespVO;
+// import cn.iocoder.yudao.module.bpm.controller.admin.oa.conversion.vo.OaConversionSaveReqVO;
+// import cn.iocoder.yudao.module.bpm.service.oa.conversion.OaConversionServiceImpl;
+// import org.junit.jupiter.api.Disabled;
+// import org.junit.jupiter.api.Test;
+//
+// import javax.annotation.Resource;
+//
+// import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
+//
+// import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.conversion.OaConversionDO;
+// import cn.iocoder.yudao.module.bpm.dal.mysql.oa.conversion.OaConversionMapper;
+// import cn.iocoder.yudao.framework.common.pojo.PageResult;
+//
+// import org.springframework.context.annotation.Import;
+//
+// import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*;
+// import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.*;
+// import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
+// import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.*;
+// import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.*;
+// import static org.junit.jupiter.api.Assertions.*;
+//
+// /**
+//  * {@link OaConversionServiceImpl} 的单元测试类
+//  *
+//  * @author 芋道源码
+//  */
+// @Import(OaConversionServiceImpl.class)
+// public class OaConversionServiceImplTest extends BaseDbUnitTest {
+//
+//     @Resource
+//     private OaConversionServiceImpl oaConversionService;
+//
+//     @Resource
+//     private OaConversionMapper oaConversionMapper;
+//
+//     @Test
+//     public void testCreateOaConversion_success() {
+//         // 准备参数
+//         OaConversionSaveReqVO createReqVO = randomPojo(OaConversionSaveReqVO.class).setId(null);
+//
+//         // 调用
+//         Long oaConversionId = oaConversionService.stagingOaConversion(createReqVO);
+//         // 断言
+//         assertNotNull(oaConversionId);
+//         // 校验记录的属性是否正确
+//         OaConversionDO oaConversion = oaConversionMapper.selectById(oaConversionId);
+//         assertPojoEquals(createReqVO, oaConversion, "id");
+//     }
+//
+//     @Test
+//     public void testUpdateOaConversion_success() {
+//         // mock 数据
+//         OaConversionDO dbOaConversion = randomPojo(OaConversionDO.class);
+//         oaConversionMapper.insert(dbOaConversion);// @Sql: 先插入出一条存在的数据
+//         // 准备参数
+//         OaConversionSaveReqVO updateReqVO = randomPojo(OaConversionSaveReqVO.class, o -> {
+//             o.setId(dbOaConversion.getId()); // 设置更新的 ID
+//         });
+//
+//         // 调用
+//         oaConversionService.updateOaConversion(updateReqVO);
+//         // 校验是否更新正确
+//         OaConversionDO oaConversion = oaConversionMapper.selectById(updateReqVO.getId()); // 获取最新的
+//         assertPojoEquals(updateReqVO, oaConversion);
+//     }
+//
+//     @Test
+//     public void testUpdateOaConversion_notExists() {
+//         // 准备参数
+//         OaConversionSaveReqVO updateReqVO = randomPojo(OaConversionSaveReqVO.class);
+//
+//         // 调用, 并断言异常
+//         assertServiceException(() -> oaConversionService.updateOaConversion(updateReqVO), OA_CONVERSION_NOT_EXISTS);
+//     }
+//
+//     @Test
+//     public void testDeleteOaConversion_success() {
+//         // mock 数据
+//         OaConversionDO dbOaConversion = randomPojo(OaConversionDO.class);
+//         oaConversionMapper.insert(dbOaConversion);// @Sql: 先插入出一条存在的数据
+//         // 准备参数
+//         Long id = dbOaConversion.getId();
+//
+//         // 调用
+//         oaConversionService.deleteOaConversion(id);
+//        // 校验数据不存在了
+//        assertNull(oaConversionMapper.selectById(id));
+//     }
+//
+//     @Test
+//     public void testDeleteOaConversion_notExists() {
+//         // 准备参数
+//         Long id = randomLongId();
+//
+//         // 调用, 并断言异常
+//         assertServiceException(() -> oaConversionService.deleteOaConversion(id), OA_CONVERSION_NOT_EXISTS);
+//     }
+//
+//     @Test
+//     // @Disabled  // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解
+//     public void testGetOaConversionPage() {
+//        // mock 数据
+//        OaConversionDO dbOaConversion = randomPojo(OaConversionDO.class, o -> { // 等会查询到
+//            o.setConversionId(null);
+//            o.setEmployeeId(null);
+//            o.setEmployeeUuid(null);
+//            o.setEmployeeName(null);
+//            o.setUserId(null);
+//            o.setUserUuid(null);
+//            o.setDeptId(null);
+//            o.setDeptUuid(null);
+//            o.setPosition(null);
+//            o.setEntryDate(null);
+//            o.setProbationEndDate(null);
+//            o.setConversionDate(null);
+//            o.setConversionReason(null);
+//            o.setWorkSummary(null);
+//            o.setRemarks(null);
+//            o.setProcInstId(null);
+//            o.setAuditStatus(null);
+//            o.setCurrentAuditUserId(null);
+//            o.setCurrentAuditUserUuid(null);
+//            o.setCurrentAuditEmployeeId(null);
+//            o.setCurrentAuditEmployeeUuid(null);
+//            o.setFinalAuditDate(null);
+//            o.setInfoSource(null);
+//            o.setCreateTime(null);
+//        });
+//        oaConversionMapper.insert(dbOaConversion);
+//        // 测试 conversionId 不匹配
+//        oaConversionMapper.insert(cloneIgnoreId(dbOaConversion, o -> o.setConversionId(null)));
+//        // 测试 employeeId 不匹配
+//        oaConversionMapper.insert(cloneIgnoreId(dbOaConversion, o -> o.setEmployeeId(null)));
+//        // 测试 employeeUuid 不匹配
+//        oaConversionMapper.insert(cloneIgnoreId(dbOaConversion, o -> o.setEmployeeUuid(null)));
+//        // 测试 employeeName 不匹配
+//        oaConversionMapper.insert(cloneIgnoreId(dbOaConversion, o -> o.setEmployeeName(null)));
+//        // 测试 userId 不匹配
+//        oaConversionMapper.insert(cloneIgnoreId(dbOaConversion, o -> o.setUserId(null)));
+//        // 测试 userUuid 不匹配
+//        oaConversionMapper.insert(cloneIgnoreId(dbOaConversion, o -> o.setUserUuid(null)));
+//        // 测试 deptId 不匹配
+//        oaConversionMapper.insert(cloneIgnoreId(dbOaConversion, o -> o.setDeptId(null)));
+//        // 测试 deptUuid 不匹配
+//        oaConversionMapper.insert(cloneIgnoreId(dbOaConversion, o -> o.setDeptUuid(null)));
+//        // 测试 position 不匹配
+//        oaConversionMapper.insert(cloneIgnoreId(dbOaConversion, o -> o.setPosition(null)));
+//        // 测试 entryDate 不匹配
+//        oaConversionMapper.insert(cloneIgnoreId(dbOaConversion, o -> o.setEntryDate(null)));
+//        // 测试 probationEndDate 不匹配
+//        oaConversionMapper.insert(cloneIgnoreId(dbOaConversion, o -> o.setProbationEndDate(null)));
+//        // 测试 conversionDate 不匹配
+//        oaConversionMapper.insert(cloneIgnoreId(dbOaConversion, o -> o.setConversionDate(null)));
+//        // 测试 conversionReason 不匹配
+//        oaConversionMapper.insert(cloneIgnoreId(dbOaConversion, o -> o.setConversionReason(null)));
+//        // 测试 workSummary 不匹配
+//        oaConversionMapper.insert(cloneIgnoreId(dbOaConversion, o -> o.setWorkSummary(null)));
+//        // 测试 remarks 不匹配
+//        oaConversionMapper.insert(cloneIgnoreId(dbOaConversion, o -> o.setRemarks(null)));
+//        // 测试 procInstId 不匹配
+//        oaConversionMapper.insert(cloneIgnoreId(dbOaConversion, o -> o.setProcInstId(null)));
+//        // 测试 auditStatus 不匹配
+//        oaConversionMapper.insert(cloneIgnoreId(dbOaConversion, o -> o.setAuditStatus(null)));
+//        // 测试 currentAuditUserId 不匹配
+//        oaConversionMapper.insert(cloneIgnoreId(dbOaConversion, o -> o.setCurrentAuditUserId(null)));
+//        // 测试 currentAuditUserUuid 不匹配
+//        oaConversionMapper.insert(cloneIgnoreId(dbOaConversion, o -> o.setCurrentAuditUserUuid(null)));
+//        // 测试 currentAuditEmployeeId 不匹配
+//        oaConversionMapper.insert(cloneIgnoreId(dbOaConversion, o -> o.setCurrentAuditEmployeeId(null)));
+//        // 测试 currentAuditEmployeeUuid 不匹配
+//        oaConversionMapper.insert(cloneIgnoreId(dbOaConversion, o -> o.setCurrentAuditEmployeeUuid(null)));
+//        // 测试 finalAuditDate 不匹配
+//        oaConversionMapper.insert(cloneIgnoreId(dbOaConversion, o -> o.setFinalAuditDate(null)));
+//        // 测试 infoSource 不匹配
+//        oaConversionMapper.insert(cloneIgnoreId(dbOaConversion, o -> o.setInfoSource(null)));
+//        // 测试 createTime 不匹配
+//        oaConversionMapper.insert(cloneIgnoreId(dbOaConversion, o -> o.setCreateTime(null)));
+//        // 准备参数
+//        OaConversionPageReqVO reqVO = new OaConversionPageReqVO();
+//        reqVO.setConversionId(null);
+//        reqVO.setEmployeeId(null);
+//        reqVO.setEmployeeUuid(null);
+//        reqVO.setEmployeeName(null);
+//        reqVO.setUserId(null);
+//        reqVO.setUserUuid(null);
+//        reqVO.setDeptId(null);
+//        reqVO.setDeptUuid(null);
+//        reqVO.setPosition(null);
+//        reqVO.setEntryDate(null);
+//        reqVO.setProbationEndDate(null);
+//        reqVO.setConversionDate(null);
+//        reqVO.setConversionReason(null);
+//        reqVO.setWorkSummary(null);
+//        reqVO.setRemarks(null);
+//        reqVO.setProcInstId(null);
+//        reqVO.setAuditStatus(null);
+//        reqVO.setCurrentAuditUserId(null);
+//        reqVO.setCurrentAuditUserUuid(null);
+//        reqVO.setCurrentAuditEmployeeId(null);
+//        reqVO.setCurrentAuditEmployeeUuid(null);
+//        reqVO.setFinalAuditDate(buildBetweenTime(2023, 2, 1, 2023, 2, 28));
+//        reqVO.setInfoSource(null);
+//        reqVO.setCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28));
+//
+//        // 调用
+//        PageResult<OaConversionRespVO> pageResult = oaConversionService.getOaConversionPage(reqVO);
+//        // 断言
+//        assertEquals(1, pageResult.getTotal());
+//        assertEquals(1, pageResult.getList().size());
+//        assertPojoEquals(dbOaConversion, pageResult.getList().get(0));
+//     }
+//
+// }