diff --git a/src/main/java/com/xdap/self_development/controller/BenchmarkingReportController.java b/src/main/java/com/xdap/self_development/controller/BenchmarkingReportController.java index 312a8d3..13f0b81 100644 --- a/src/main/java/com/xdap/self_development/controller/BenchmarkingReportController.java +++ b/src/main/java/com/xdap/self_development/controller/BenchmarkingReportController.java @@ -4,6 +4,7 @@ import com.definesys.mpaas.common.http.Response; import com.xdap.self_development.controller.form.BenchmarkingReportPageForm; import com.xdap.self_development.controller.form.HandleApprovalRequest; import com.xdap.self_development.controller.form.SaveBenchmarkingReportForm; +import com.xdap.self_development.controller.form.UpdateBenchmarkingReportForm; import com.xdap.self_development.exception.CommonException; import com.xdap.self_development.pojo.BenchmarkingReport; import com.xdap.self_development.pojo.view.ApprovalFlowView; @@ -50,6 +51,21 @@ public class BenchmarkingReportController { return Response.ok().setMessage("保存成功"); } + // 修改对标报告并发起审批 + @PostMapping("/restartReportApproval") + public Response restartReportApproval( + @Valid UpdateBenchmarkingReportForm form, + BindingResult bindingResult + ) { + if (bindingResult.hasErrors()) { + bindingResult.getFieldErrors().forEach(error -> { + throw new CommonException(error.getDefaultMessage()); + }); + } + benchmarkingReportService.restartReportApproval(form); + return Response.ok().setMessage("重新提交成功"); + } + // 筛选对标报告及待办 @PostMapping("/getReportAndTodoByCondition") public Response getBenchmarkingReportByCondition( diff --git a/src/main/java/com/xdap/self_development/controller/form/UpdateBenchmarkingReportForm.java b/src/main/java/com/xdap/self_development/controller/form/UpdateBenchmarkingReportForm.java new file mode 100644 index 0000000..c9be116 --- /dev/null +++ b/src/main/java/com/xdap/self_development/controller/form/UpdateBenchmarkingReportForm.java @@ -0,0 +1,53 @@ +package com.xdap.self_development.controller.form; + +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotEmpty; +import java.util.List; + +@Data +public class UpdateBenchmarkingReportForm { + @NotBlank(message = "原对标报告id不能为空") + private String reportId; + + @NotBlank(message = "标题不能为空") + private String title; + @NotBlank(message = "厂家名称不能为空") + private String manufacturerName; + @NotBlank(message = "产品型号不能为空") + private String modelName; + @NotBlank(message = "厂家简称不能为空") + private String manufacturerAbbreviation; + @NotBlank(message = "产品型号简称不能为空") + private String modelAbbreviation; + @NotBlank(message = "产品编号不能为空") + private String productNumber; + @NotBlank(message = "模块不能为空") + private String module; + @NotBlank(message = "板块不能为空") + private String plate; + @NotBlank(message = "平台不能为空") + private String platform; + @NotBlank(message = "系列不能为空") + private String series; + @NotBlank(message = "细分市场不能为空") + private String marketSegment; + @NotBlank(message = "项目名称不能为空") + private String projectName; + @NotBlank(message = "项目编号不能为空") + private String projectNumber; + + private String fileUrl; + + @NotEmpty(message = "校对人员不能为空") + private List proofreadUsers; + @NotEmpty(message = "审核人员不能为空") + private List reviewUsers; + private List countersignUsers; // 可选 + @NotEmpty(message = "批准人员不能为空") + private List approveUsers; + @NotBlank(message = "发起人不能为空") + private String createBy; + private String explanation; +} diff --git a/src/main/java/com/xdap/self_development/pojo/view/TodoAndReportView.java b/src/main/java/com/xdap/self_development/pojo/view/TodoAndReportView.java index a3b75d3..6f0b93e 100644 --- a/src/main/java/com/xdap/self_development/pojo/view/TodoAndReportView.java +++ b/src/main/java/com/xdap/self_development/pojo/view/TodoAndReportView.java @@ -11,7 +11,7 @@ import java.sql.Timestamp; @SQL(view = "getReportByUserIdAndIds", sql = "SELECT br.id AS \"reportId\", af.id AS \"flowId\", br.* FROM yfsjglpt_model_approval_flow af JOIN yfsjglpt_model_benchmarking_report br ON af.template_id = br.id WHERE br.title like CONCAT('%', #title, '%') and br.manufacturer_name like CONCAT('%', #manufacturerName, '%') and br.model_name like CONCAT('%', #modelName, '%') and br.product_number like CONCAT('%', #productNumber, '%') and br.module like CONCAT('%', #module, '%') and br.plate like CONCAT('%', #plate, '%') and br.platform like CONCAT('%', #platform, '%') and br.series like CONCAT('%', #series, '%') and br.market_segment like CONCAT('%', #marketSegment, '%') and br.project_name like CONCAT('%', #projectName, '%') and br.project_number like CONCAT('%', #projectNumber, '%') and br.status like CONCAT('%', #status, '%') and af.flow_type = 2 AND af.id NOT IN (#ids) AND af.create_by = #createBy"), @SQL(view = "getTodoAndReport", - sql = "SELECT br.id AS \"reportId\", af.id AS \"flowId\", br.* FROM yfsjglpt_model_approval_flow af JOIN yfsjglpt_model_benchmarking_report br ON af.template_id = br.id WHERE br.title like CONCAT('%', #title, '%') and br.manufacturer_name like CONCAT('%', #manufacturerName, '%') and br.model_name like CONCAT('%', #modelName, '%') and br.product_number like CONCAT('%', #productNumber, '%') and br.module like CONCAT('%', #module, '%') and br.plate like CONCAT('%', #plate, '%') and br.platform like CONCAT('%', #platform, '%') and br.series like CONCAT('%', #series, '%') and br.market_segment like CONCAT('%', #marketSegment, '%') and br.project_name like CONCAT('%', #projectName, '%') and br.project_number like CONCAT('%', #projectNumber, '%') and br.status like CONCAT('%', #status, '%') and af.flow_type = 2 AND af.id IN (#ids)") + sql = "SELECT br.id AS \"reportId\", af.id AS \"flowId\", br.* FROM yfsjglpt_model_approval_flow af JOIN yfsjglpt_model_benchmarking_report br ON af.template_id = br.id WHERE br.title like CONCAT('%', #title, '%') and br.manufacturer_name like CONCAT('%', #manufacturerName, '%') and br.model_name like CONCAT('%', #modelName, '%') and br.product_number like CONCAT('%', #productNumber, '%') and br.module like CONCAT('%', #module, '%') and br.plate like CONCAT('%', #plate, '%') and br.platform like CONCAT('%', #platform, '%') and br.series like CONCAT('%', #series, '%') and br.market_segment like CONCAT('%', #marketSegment, '%') and br.project_name like CONCAT('%', #projectName, '%') and br.project_number like CONCAT('%', #projectNumber, '%') and br.status like CONCAT('%', #status, '%') and af.flow_type = 2 AND (af.id IN (#ids) OR af.create_by = #createBy) ORDER BY CASE br.status WHEN 'COMPLETE' THEN 1 WHEN 'APPROVING' THEN 2 WHEN 'REJECTED' THEN 3 ELSE 4 END ASC") }) @Data public class TodoAndReportView { diff --git a/src/main/java/com/xdap/self_development/service/BenchmarkingReportService.java b/src/main/java/com/xdap/self_development/service/BenchmarkingReportService.java index 2840080..36ec5ee 100644 --- a/src/main/java/com/xdap/self_development/service/BenchmarkingReportService.java +++ b/src/main/java/com/xdap/self_development/service/BenchmarkingReportService.java @@ -3,6 +3,7 @@ package com.xdap.self_development.service; import com.xdap.self_development.controller.form.BenchmarkingReportPageForm; import com.xdap.self_development.controller.form.HandleApprovalRequest; import com.xdap.self_development.controller.form.SaveBenchmarkingReportForm; +import com.xdap.self_development.controller.form.UpdateBenchmarkingReportForm; import com.xdap.self_development.pojo.BenchmarkingReport; import com.xdap.self_development.pojo.view.ApprovalFlowView; import com.xdap.self_development.pojo.view.TodoAndReportView; @@ -16,6 +17,8 @@ public interface BenchmarkingReportService { List getBenchmarkingReportByCondition(@Valid BenchmarkingReportPageForm form); void saveBenchmarkingReport(@Valid SaveBenchmarkingReportForm form); + + void restartReportApproval(@Valid UpdateBenchmarkingReportForm form); void handleReportApproval(@Valid HandleApprovalRequest request); diff --git a/src/main/java/com/xdap/self_development/service/impl/BenchmarkingReportServiceImpl.java b/src/main/java/com/xdap/self_development/service/impl/BenchmarkingReportServiceImpl.java index bb5d12f..dce2fac 100644 --- a/src/main/java/com/xdap/self_development/service/impl/BenchmarkingReportServiceImpl.java +++ b/src/main/java/com/xdap/self_development/service/impl/BenchmarkingReportServiceImpl.java @@ -8,6 +8,7 @@ import com.xdap.self_development.config.BusinessDatabase; import com.xdap.self_development.controller.form.BenchmarkingReportPageForm; import com.xdap.self_development.controller.form.HandleApprovalRequest; import com.xdap.self_development.controller.form.SaveBenchmarkingReportForm; +import com.xdap.self_development.controller.form.UpdateBenchmarkingReportForm; import com.xdap.self_development.exception.CommonException; import com.xdap.self_development.feign.ApaasMyTokenFeign; import com.xdap.self_development.feign.dto.AppTokenDTO; @@ -64,8 +65,8 @@ public class BenchmarkingReportServiceImpl implements BenchmarkingReportService @Override @Transactional(rollbackFor = CommonException.class) public void saveBenchmarkingReport(SaveBenchmarkingReportForm form) { - // 1. 创建对标报告并保存 BenchmarkingReport report = new BenchmarkingReport(); + // 1. 创建对标报告并保存 BeanUtils.copyProperties(form, report); report.setFilePath(form.getFileUrl() == null ? "" : form.getFileUrl()); report.setUploadTime(Timestamp.valueOf(LocalDateTime.now())); @@ -93,6 +94,37 @@ public class BenchmarkingReportServiceImpl implements BenchmarkingReportService }); } + @Override + public void restartReportApproval(UpdateBenchmarkingReportForm form) { + BenchmarkingReport originalReport = bd.getBusinessDatabase() + .eq("id", form.getReportId()).doQueryFirst(BenchmarkingReport.class); + BeanUtils.copyProperties(form, originalReport); + originalReport.setFilePath(form.getFileUrl() == null ? "" : form.getFileUrl()); + originalReport.setUploadTime(Timestamp.valueOf(LocalDateTime.now())); + originalReport.setStatus("APPROVING"); + originalReport.setCreateBy(form.getCreateBy()); + bd.getBusinessDatabase().doUpdate(originalReport); + + ApprovalFlow flow = new ApprovalFlow(); + flow.setTemplateId(originalReport.getId()); + flow.setCurrentNode("PROOFREAD"); + flow.setFlowStatus("APPROVING"); + flow.setProofreadUsers(JSON.toJSONString(form.getProofreadUsers())); + flow.setReviewUsers(JSON.toJSONString(form.getReviewUsers())); + flow.setCountersignUsers(JSON.toJSONString(form.getCountersignUsers())); + flow.setApproveUsers(JSON.toJSONString(form.getApproveUsers())); + flow.setCreateBy(form.getCreateBy()); + flow.setCreatedTime(Timestamp.valueOf(LocalDateTime.now())); + flow.setFlowType(2); // 设置为报告审批流程 + flow.setExplanation(form.getExplanation()); + bd.getBusinessDatabase().doInsert(flow); + + form.getProofreadUsers().forEach(userId -> { + redisTemplate.opsForSet().add(TODO_PREFIX + userId, flow.getId()); + }); + } + + @Override public String uploadFile(MultipartFile file, String userId) { String currentTenantId = runtimeAppContextService.getCurrentTenantId(); @@ -126,35 +158,11 @@ public class BenchmarkingReportServiceImpl implements BenchmarkingReportService @Override public List getBenchmarkingReportByCondition(BenchmarkingReportPageForm form) { List approvalList = new ArrayList<>(); - Set flowIds = redisTemplate.opsForSet().members(TODO_PREFIX + form.getCreateBy()); - - if (flowIds != null && !flowIds.isEmpty()) { - List ids = new ArrayList<>(flowIds); - List todoList =bd.getBusinessDatabase() - .viewQueryMode(true) - .view("getTodoAndReport") - .setVar("ids", ids) - .setVar("title", form.getTitle()) - .setVar("manufacturerName", form.getManufacturerName()) - .setVar("modelName", form.getModelName()) - .setVar("productNumber", form.getProductNumber()) - .setVar("module", form.getModule()) - .setVar("plate", form.getPlate()) - .setVar("platform", form.getPlatform()) - .setVar("series", form.getSeries()) - .setVar("marketSegment", form.getMarketSegment()) - .setVar("projectName", form.getProjectName()) - .setVar("projectNumber", form.getProjectNumber()) - .setVar("status", form.getStatus()) - .doQuery(TodoAndReportView.class); - setCurrentApprovers(approvalList, todoList); - - } - - List ids = (flowIds == null || flowIds.isEmpty()) ? new ArrayList<>(Collections.singleton("")) : new ArrayList<>(flowIds); - List todoAndTemplateViews = bd.getBusinessDatabase() + Set flowIds = new HashSet<>(Objects.requireNonNull(redisTemplate.opsForSet().members(TODO_PREFIX + form.getCreateBy()))); + List ids = new ArrayList<>(flowIds); + List todoList =bd.getBusinessDatabase() .viewQueryMode(true) - .view("getReportByUserIdAndIds") + .view("getTodoAndReport") .setVar("ids", ids) .setVar("createBy", form.getCreateBy()) .setVar("title", form.getTitle()) @@ -170,8 +178,7 @@ public class BenchmarkingReportServiceImpl implements BenchmarkingReportService .setVar("projectNumber", form.getProjectNumber()) .setVar("status", form.getStatus()) .doQuery(TodoAndReportView.class); - setCurrentApprovers(approvalList, todoAndTemplateViews); - + setCurrentApprovers(approvalList, todoList); return approvalList; } @@ -200,32 +207,26 @@ public class BenchmarkingReportServiceImpl implements BenchmarkingReportService String currentNode = flow.getCurrentNode(); // 验证当前用户是否有权限处理 if (!hasPermission(flow, currentNode, request.getUserId())) { - throw new CommonException("无权限处理或已被处理"); + throw new CommonException("无权限处理"); } - if (!"COUNTERSIGN".equals(currentNode)) { - String lockKey = FLOW_LOCK_PREFIX + flow.getId() + ":" + currentNode; - String lockValue = UUID.randomUUID().toString(); - boolean lockAcquired = redisLockUtil - .tryLock(lockKey, lockValue, FLOW_LOCK_EXPIRE_SECONDS, TimeUnit.SECONDS); - - if (!lockAcquired) { - throw new CommonException("当前节点正在处理,请稍后重试"); + String lockKey = FLOW_LOCK_PREFIX + flow.getId() + ":" + currentNode; + String lockValue = UUID.randomUUID().toString(); + boolean lockAcquired = redisLockUtil + .tryLock(lockKey, lockValue, FLOW_LOCK_EXPIRE_SECONDS, TimeUnit.SECONDS); + if (!lockAcquired) { + throw new CommonException("当前节点正在处理,请稍后重试"); + } + try { + String processedKey = NODE_PROCESSED_PREFIX + flow.getId() + ":" + currentNode; + long processedCount = Optional.ofNullable(redisTemplate.opsForSet().size(processedKey)) + .orElse(0L); + if (processedCount > 0) { + throw new CommonException("此节点已被他人处理"); } - - try { - String processedKey = NODE_PROCESSED_PREFIX + flow.getId() + ":" + currentNode; - long processedCount = Optional.ofNullable(redisTemplate.opsForSet().size(processedKey)) - .orElse(0L); - if (processedCount > 0) { - throw new CommonException("此节点已被他人处理"); - } - processApprovalLogic(flow, request, currentNode); - } finally { - redisLockUtil.unlock(lockKey, lockValue); - } - } else { processApprovalLogic(flow, request, currentNode); + } finally { + redisLockUtil.unlock(lockKey, lockValue); } } @@ -245,7 +246,6 @@ public class BenchmarkingReportServiceImpl implements BenchmarkingReportService approvalFlowView.setExplanation(flow.getExplanation()); approvalFlowView.setProofreadNodes(getNodeList(flowId, "PROOFREAD")); approvalFlowView.setReviewNodes(getNodeList(flowId, "REVIEW")); - approvalFlowView.setCountersignNodes(getNodeList(flowId, "COUNTERSIGN")); approvalFlowView.setApproveNodes(getNodeList(flowId, "APPROVE")); approvalFlowView.setFlowStatus(flow.getFlowStatus()); @@ -277,8 +277,6 @@ public class BenchmarkingReportServiceImpl implements BenchmarkingReportService return JSON.parseArray(flow.getProofreadUsers()).toJavaList(String.class).contains(userId); case "REVIEW": return JSON.parseArray(flow.getReviewUsers()).toJavaList(String.class).contains(userId); - case "COUNTERSIGN": - return flow.getCountersignUsers() != null && JSON.parseArray(flow.getCountersignUsers()).toJavaList(String.class).contains(userId); case "APPROVE": return JSON.parseArray(flow.getApproveUsers()).toJavaList(String.class).contains(userId); default: @@ -369,12 +367,7 @@ public class BenchmarkingReportServiceImpl implements BenchmarkingReportService Long processedCount = redisTemplate.opsForSet().size(key); if (processedCount == null) processedCount = 0L; - // 会签节点需要所有人处理,其他节点只需1人 - if ("COUNTERSIGN".equals(node)) { - return processedCount.equals((long) JSON.parseArray(flow.getCountersignUsers()).size()); - } else { - return processedCount >= 1; - } + return processedCount >= 1; } private String getNextNode(String currentNode, ApprovalFlow flow) { @@ -382,9 +375,6 @@ public class BenchmarkingReportServiceImpl implements BenchmarkingReportService case "PROOFREAD": return "REVIEW"; case "REVIEW": - return flow.getCountersignUsers() != null && !JSON.parseArray(flow.getCountersignUsers()).isEmpty() - ? "COUNTERSIGN" : "APPROVE"; - case "COUNTERSIGN": return "APPROVE"; case "APPROVE": return null; // 流程结束 @@ -416,18 +406,12 @@ public class BenchmarkingReportServiceImpl implements BenchmarkingReportService private void clearAllTodo(ApprovalFlow flow) { clearNodeTodo(flow, "PROOFREAD"); clearNodeTodo(flow, "REVIEW"); - if (flow.getCountersignUsers() != null) { - clearNodeTodo(flow, "COUNTERSIGN"); - } clearNodeTodo(flow, "APPROVE"); } private void clearProcessed(ApprovalFlow flow) { redisTemplate.delete(NODE_PROCESSED_PREFIX + flow.getId() + ":" + "PROOFREAD"); redisTemplate.delete(NODE_PROCESSED_PREFIX + flow.getId() + ":" + "REVIEW"); - if (flow.getCountersignUsers() != null) { - redisTemplate.delete(NODE_PROCESSED_PREFIX + flow.getId() + ":" + "COUNTERSIGN"); - } redisTemplate.delete(NODE_PROCESSED_PREFIX + flow.getId() + ":" + "APPROVE"); } @@ -442,7 +426,6 @@ public class BenchmarkingReportServiceImpl implements BenchmarkingReportService switch (node) { case "PROOFREAD": return JSON.parseArray(flow.getProofreadUsers()).toJavaList(String.class); case "REVIEW": return JSON.parseArray(flow.getReviewUsers()).toJavaList(String.class); - case "COUNTERSIGN": return JSON.parseArray(flow.getCountersignUsers()).toJavaList(String.class); case "APPROVE": return JSON.parseArray(flow.getApproveUsers()).toJavaList(String.class); default: return Collections.emptyList(); } diff --git a/src/main/java/com/xdap/self_development/service/impl/ParameterServiceImpl.java b/src/main/java/com/xdap/self_development/service/impl/ParameterServiceImpl.java index 98e1bb9..4028de4 100644 --- a/src/main/java/com/xdap/self_development/service/impl/ParameterServiceImpl.java +++ b/src/main/java/com/xdap/self_development/service/impl/ParameterServiceImpl.java @@ -47,7 +47,6 @@ public class ParameterServiceImpl implements ParameterService { } //todo 获取指定子系统下的用户的权限,权限应该为:参数的 parameterNumber - List menuParamViews = modelRoleService.selectPersByUser("zjh"); return bd.getBusinessDatabase() .viewQueryMode(true)