From e9895d000bf722b708af01b5d89af7c0f147d31d Mon Sep 17 00:00:00 2001 From: fuliqi <fuliqi@qq.com> Date: 星期一, 23 十二月 2024 09:50:27 +0800 Subject: [PATCH] Merge remote-tracking branch 'origin/master' --- business/src/main/java/com/ycl/service/impl/ProjectProcessServiceImpl.java | 55 +++++++++---- flowable/src/main/java/com/ycl/service/common/TaskCommonService.java | 85 +++++++++++++++++++++ flowable/src/main/java/com/ycl/service/impl/FlowTaskServiceImpl.java | 32 ++++--- business/src/main/java/com/ycl/controller/ProjectProcessController.java | 8 ++ business/src/main/java/com/ycl/domain/form/RejectTaskForm.java | 36 +++++++++ business/src/main/java/com/ycl/service/ProjectProcessService.java | 9 ++ 6 files changed, 191 insertions(+), 34 deletions(-) diff --git a/business/src/main/java/com/ycl/controller/ProjectProcessController.java b/business/src/main/java/com/ycl/controller/ProjectProcessController.java index 1018841..ad52818 100644 --- a/business/src/main/java/com/ycl/controller/ProjectProcessController.java +++ b/business/src/main/java/com/ycl/controller/ProjectProcessController.java @@ -2,6 +2,7 @@ import com.ycl.common.group.Update; import com.ycl.common.group.Add; +import com.ycl.domain.form.RejectTaskForm; import com.ycl.domain.query.TaskQuery; import org.springframework.validation.annotation.Validated; import org.springframework.security.access.prepost.PreAuthorize; @@ -81,6 +82,13 @@ return projectProcessService.taskIsAuditing(processDefId, taskId); } + @PostMapping("/detail/task/reject") + @ApiOperation(value = "椹冲洖", notes = "椹冲洖") +// @PreAuthorize("@ss.hasPermi('projectProcess:detail')") + public Result rejectTask(@RequestBody RejectTaskForm form) { + return projectProcessService.rejectTask(form); + } + @GetMapping("/to_do_task") @ApiOperation(value = "鍒嗛〉", notes = "鍒嗛〉") diff --git a/business/src/main/java/com/ycl/domain/form/RejectTaskForm.java b/business/src/main/java/com/ycl/domain/form/RejectTaskForm.java new file mode 100644 index 0000000..3abdbc2 --- /dev/null +++ b/business/src/main/java/com/ycl/domain/form/RejectTaskForm.java @@ -0,0 +1,36 @@ +package com.ycl.domain.form; + +import lombok.Data; + +/** + * @author锛歺p + * @date锛�2024/12/13 13:51 + */ +@Data +public class RejectTaskForm { + + /** + * 褰撳墠浠诲姟id + * + */ + private String taskId; + + /** + * 琚┏鍥炵殑浠诲姟瀹氫箟id + * + */ + private String rejectedTaskDefKey; + + /** + * 瀹℃牳鎰忚 + * + */ + private String auditOpinion; + + /** + * 娴佺▼瀹炰緥id + * + */ + private String processInsId; + +} diff --git a/business/src/main/java/com/ycl/service/ProjectProcessService.java b/business/src/main/java/com/ycl/service/ProjectProcessService.java index ea82840..2beb75d 100644 --- a/business/src/main/java/com/ycl/service/ProjectProcessService.java +++ b/business/src/main/java/com/ycl/service/ProjectProcessService.java @@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.extension.service.IService; import com.ycl.common.base.Result; import com.ycl.domain.form.ProjectProcessForm; +import com.ycl.domain.form.RejectTaskForm; import com.ycl.domain.query.ProjectProcessQuery; import com.ycl.domain.query.TaskQuery; import com.ycl.domain.vo.CustomerTaskVO; @@ -78,4 +79,12 @@ * @return */ Result taskIsAuditing(String processDefinitionId, String taskId); + + /** + * 椹冲洖浠诲姟 + * + * @param form + * @return + */ + Result rejectTask(RejectTaskForm form); } diff --git a/business/src/main/java/com/ycl/service/impl/ProjectProcessServiceImpl.java b/business/src/main/java/com/ycl/service/impl/ProjectProcessServiceImpl.java index 71e3bcc..46d7ee4 100644 --- a/business/src/main/java/com/ycl/service/impl/ProjectProcessServiceImpl.java +++ b/business/src/main/java/com/ycl/service/impl/ProjectProcessServiceImpl.java @@ -19,6 +19,7 @@ import com.ycl.domain.dto.FlowTaskDto; import com.ycl.domain.entity.ProjectInfo; import com.ycl.domain.entity.ProjectProcess; +import com.ycl.domain.form.RejectTaskForm; import com.ycl.domain.vo.CustomerTaskVO; import com.ycl.domain.vo.ProjectProcessDetailVO; import com.ycl.mapper.ProjectInfoMapper; @@ -358,6 +359,13 @@ return Result.ok().data(needAuditing); } + @Override + public Result rejectTask(RejectTaskForm form) { + Task task = taskService.createTaskQuery().taskId(form.getTaskId()).singleResult(); + taskCommonService.reject(form.getRejectedTaskDefKey(), task.getTaskDefinitionKey(), task.getProcessInstanceId(), form.getTaskId(), form.getAuditOpinion()); + return Result.ok("椹冲洖鎴愬姛"); + } + /** * 鏌ヨ寰呭姙浠诲姟 * @@ -486,12 +494,14 @@ Task task = taskService.createTaskQuery().processInstanceId(process.getId()).taskDefinitionKey(userTask.getId()).singleResult(); if (Objects.isNull(task)) { // 濡傛灉浠诲姟鍦ㄨ繍琛屾椂娌℃壘鍒帮紝閭d箞鍙兘涓烘湭寮�濮嬫垨鑰呭凡瀹屾垚锛岄渶瑕佷粠鍘嗗彶浠诲姟涓啀鎵句竴涓� - HistoricTaskInstance historicTask = historyService.createHistoricTaskInstanceQuery() + List<HistoricTaskInstance> historicTasks = historyService.createHistoricTaskInstanceQuery() .processInstanceId(process.getProcessInstanceId()) .taskDefinitionKey(userTask.getId()) .includeIdentityLinks() - .singleResult(); - if (Objects.isNull(historicTask)) { + .orderByHistoricTaskInstanceStartTime() + .desc() + .list(); + if (CollectionUtils.isEmpty(historicTasks)) { vo.setPromoterName("鏆傛棤"); vo.setPromoterUnitName("鏆傛棤"); // 鏈紑濮嬬殑浠诲姟锛屽叾鍏宠仈鐨勭敤鎴风粍杩欎簺閮藉彲浠ヤ粠UserTask涓嬁鍒帮紝鍥犱负鏈韩鏈紑濮嬬殑浠诲姟鏄病鏈塼ask鐨勶紝鎵�浠ヨ繖閲岀洿鎺ユ煡 @@ -534,18 +544,18 @@ } else { vo.setTaskStatus(TaskStatusEnum.FINISHED); // 濡傛灉鏄凡瀹屾垚鐨勶紝淇℃伅闇�瑕佸崟鐙祴鍊� - vo.setTaskId(historicTask.getId()); - vo.setExecutionId(historicTask.getExecutionId()); - vo.setCreateTime(historicTask.getStartTime()); + vo.setTaskId(historicTasks.get(0).getId()); + vo.setExecutionId(historicTasks.get(0).getExecutionId()); + vo.setCreateTime(historicTasks.get(0).getStartTime()); // 鏌ヨ瀹為檯澶勭悊浜� - long handlerUserId = Long.parseLong(historicTask.getAssignee()); + long handlerUserId = Long.parseLong(historicTasks.get(0).getAssignee()); SysUser handlerUser = sysUserService.selectUserById(handlerUserId); if (Objects.nonNull(handlerUser)) { vo.setHandlerId(handlerUserId); vo.setHandlerName(handlerUser.getNickName()); } - vo.setTaskDefinitionKey(historicTask.getTaskDefinitionKey()); - this.setPromoterAndHandler(vo, historicTask.getIdentityLinks()); + vo.setTaskDefinitionKey(historicTasks.get(0).getTaskDefinitionKey()); + this.setPromoterAndHandler(vo, historicTasks.get(0).getIdentityLinks()); } } else { vo.setTaskStatus(TaskStatusEnum.TODO); @@ -602,12 +612,14 @@ Task task = taskService.createTaskQuery().processInstanceId(process.getId()).taskDefinitionKey(userTask.getId()).singleResult(); if (Objects.isNull(task)) { // 濡傛灉浠诲姟鍦ㄨ繍琛屾椂娌℃壘鍒帮紝閭d箞鍙兘涓烘湭寮�濮嬫垨鑰呭凡瀹屾垚锛屽彧鏌ヨ鏈紑濮嬬殑 - HistoricTaskInstance historicTask = historyService.createHistoricTaskInstanceQuery() + List<HistoricTaskInstance> historicTasks = historyService.createHistoricTaskInstanceQuery() .processInstanceId(process.getProcessInstanceId()) .taskDefinitionKey(userTask.getId()) .includeIdentityLinks() - .singleResult(); - if (Objects.isNull(historicTask)) { + .orderByHistoricTaskInstanceStartTime() + .desc() + .list(); + if (CollectionUtils.isEmpty(historicTasks)) { // 鏈紑濮嬬殑浠诲姟锛屽叾鍏宠仈鐨勭敤鎴风粍杩欎簺閮藉彲浠ヤ粠UserTask涓嬁鍒帮紝鍥犱负鏈韩鏈紑濮嬬殑浠诲姟鏄病鏈塼ask鐨勶紝鎵�浠ヨ繖閲岀洿鎺ユ煡 if (StringUtils.isNotBlank(userTask.getAssignee())) { vo.setHandlerType(HandlerTypeEnum.USER); @@ -675,12 +687,14 @@ Task task = taskService.createTaskQuery().processInstanceId(process.getId()).taskDefinitionKey(userTask.getId()).singleResult(); if (Objects.isNull(task)) { // 濡傛灉浠诲姟鍦ㄨ繍琛屾椂娌℃壘鍒帮紝閭d箞鍙兘涓烘湭寮�濮嬫垨鑰呭凡瀹屾垚锛屽彧鏌ヨ鏈紑濮嬬殑 - HistoricTaskInstance historicTask = historyService.createHistoricTaskInstanceQuery() + List<HistoricTaskInstance> historicTasks = historyService.createHistoricTaskInstanceQuery() .processInstanceId(process.getProcessInstanceId()) .taskDefinitionKey(userTask.getId()) .includeIdentityLinks() - .singleResult(); - if (Objects.isNull(historicTask)) { + .orderByHistoricTaskInstanceStartTime() + .desc() + .list(); + if (CollectionUtils.isEmpty(historicTasks)) { num++; } } @@ -792,10 +806,15 @@ // 鍙戣捣浜哄簲涓轰笂涓�鑺傜偣鐨勫鐞嗕汉 List<String> beforeNodeKey = taskCommonService.getBeforeNodeInfo(taskVO.getProcessDefId(), taskVO.getTaskDefinitionKey()); List<SysUser> userList = beforeNodeKey.stream().map(key -> { - HistoricTaskInstance historicTaskInstance = historyService.createHistoricTaskInstanceQuery().taskDefinitionKey(key).singleResult(); - if (Objects.nonNull(historicTaskInstance)) { + List<HistoricTaskInstance> historicTaskInstances = historyService.createHistoricTaskInstanceQuery() + .processInstanceId(taskVO.getProcessInsId()) + .taskDefinitionKey(key) + .orderByHistoricTaskInstanceStartTime() + .desc() + .list(); // 涔嬫墍浠ョ敤list鏄洜涓哄鏋滄煇涓换鍔¤椹冲洖杩囷紝涓斿鏋滆浠诲姟鍐嶆鎵ц鏃朵細鏈夊鏉℃暟鎹紝鍙栨渶鏂扮殑涓�鏉� + if (! CollectionUtils.isEmpty(historicTaskInstances)) { // 瀹為檯棰嗗彇杩欎釜浠诲姟鐨勪汉锛屼篃灏辨槸澶勭悊浜� - String assignee = historicTaskInstance.getAssignee(); + String assignee = historicTaskInstances.get(0).getAssignee(); SysUser startUser = sysUserService.selectUserById(Long.parseLong(assignee)); return startUser; } else { diff --git a/flowable/src/main/java/com/ycl/service/common/TaskCommonService.java b/flowable/src/main/java/com/ycl/service/common/TaskCommonService.java index af2d729..f46627d 100644 --- a/flowable/src/main/java/com/ycl/service/common/TaskCommonService.java +++ b/flowable/src/main/java/com/ycl/service/common/TaskCommonService.java @@ -2,6 +2,7 @@ import com.alibaba.fastjson2.JSONObject; import com.ycl.common.constant.ProcessConstants; +import com.ycl.common.enums.FlowComment; import com.ycl.domain.entity.SysForm; import com.ycl.domain.vo.FormDetailVO; import com.ycl.flow.FindNextNodeUtil; @@ -9,9 +10,13 @@ import lombok.RequiredArgsConstructor; import org.flowable.bpmn.model.*; import org.flowable.bpmn.model.Process; +import org.flowable.engine.HistoryService; import org.flowable.engine.RepositoryService; import org.flowable.engine.RuntimeService; +import org.flowable.engine.TaskService; import org.flowable.engine.repository.ProcessDefinition; +import org.flowable.task.api.Task; +import org.flowable.task.api.history.HistoricTaskInstance; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; @@ -29,9 +34,11 @@ private final RuntimeService runtimeService; private final RepositoryService repositoryService; + private final TaskService taskService; + private final HistoryService historyService; /** - * 閫氳繃褰撳墠鑺傜偣瀹氫箟key锛岃幏鍙栧叾涓婁竴涓妭鐐逛互鍙婂綋鍓嶈妭鐐圭殑淇℃伅锛屽鏋滃墠闈㈡槸骞惰鐨勪細杩斿洖澶氫釜 + * 閫氳繃褰撳墠鑺傜偣瀹氫箟key锛岃幏鍙栧叾涓婁竴涓妭鐐圭殑淇℃伅锛屽鏋滃墠闈㈡槸骞惰鐨勪細杩斿洖澶氫釜(鍖呭惈褰撳墠鑺傜偣) * * @param processDefId 娴佺▼瀹氫箟id * @param currentNodeDefId 褰撳墠鑺傜偣瀹氫箟id @@ -91,6 +98,52 @@ defKeys.add(formDetailVO); } + this.beforeNodeInfo(currentElement, defKeys); + + return defKeys; + } + + + /** + * 鑾峰彇褰撳墠鑺傜偣鐨勫墠缃妭鐐癸紝涓嶅寘鍚綋鍓嶈妭鐐� + * + * @param processDefId + * @param currentNodeDefId + * @return + */ + public List<FormDetailVO> getBeforeNodeList(String processDefId, String currentNodeDefId) { + // 鑾峰彇娴佺▼瀹氫箟 + ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery() + .processDefinitionId(processDefId) + .singleResult(); + + // 鑾峰彇娴佺▼妯″瀷 + BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefId); + if (bpmnModel == null) { + throw new RuntimeException("BpmnModel not found for processDefinitionId: " + processDefId); + } + + // 鑾峰彇娴佺▼瀵硅薄 + Process process = bpmnModel.getProcessById(processDefinition.getKey()); + if (process == null) { + throw new RuntimeException("Process not found for processDefinitionId: " + processDefId); + } + + // 閬嶅巻娴佺▼鍏冪礌锛屾壘鍒板搴旂殑浠诲姟鑺傜偣 + Collection<FlowElement> flowElements = process.getFlowElements(); + UserTask currentElement = null; + for (FlowElement flowElement : flowElements) { + if (flowElement instanceof UserTask && flowElement.getId().equals(currentNodeDefId)) { + currentElement = (UserTask) flowElement; + break; + } + } + if (Objects.isNull(currentElement)) { + throw new RuntimeException("鏈壘鍒拌浠诲姟鐨勬祦绋嬪畾涔夎妭鐐�"); + } + + List<FormDetailVO> defKeys = new ArrayList<>(2); + this.beforeNodeInfo(currentElement, defKeys); return defKeys; @@ -209,4 +262,34 @@ return Boolean.FALSE; } + + /** + * 椹冲洖浠诲姟 + * + * @param rejectedTaskDefKey 琚┏鍥炵殑浠诲姟key + * @param rejectTaskDefKey 鎵ц椹冲洖鎿嶄綔鎵�鍦ㄧ殑浠诲姟key + * @param processInsId 娴佺▼瀹炰緥id + * @param taskId 褰撳墠浠诲姟id + * @param msg 瀹℃牳鎰忚 + */ + public void reject(String rejectedTaskDefKey, String rejectTaskDefKey, String processInsId, String taskId, String msg) { + // 椹冲洖鐨勬牳蹇僡pi锛歳untimeService.createChangeActivityStateBuilder().moveXXX 鐨刟pi锛屽彲浠ヨ缃粠褰撳墠鑺傜偣绉诲姩鍒扮洰鏍囪妭鐐� + // 椹冲洖鐨勬牳蹇冿細闇�瑕佹壘鍒板綋鍓嶈妭鐐广�佷互鍙婅娴佽浆鍒扮殑鐩爣鑺傜偣銆傚叾涓瘮杈冮夯鐑︾殑鏄鐞嗗苟琛岀瓑姣旇緝澶嶆潅鐨勬儏鍐� + /** + * 椹冲洖鐨勬儏鍐靛垎涓轰互涓嬩笁绉嶏細 + * + * 1. 濡傛灉鎵ц椹冲洖鎿嶄綔鐨勪换鍔℃槸鍦ㄥ苟琛岀粨鏉熺殑鍚庝竴涓妭鐐癸紝閭d箞琚┏鍥炵殑浠诲姟灞炰簬骞惰涓殑鏌愪釜鍒嗘敮鐨勭粨鏉熻妭鐐� + * 2. 濡傛灉鎵ц椹冲洖鎿嶄綔鐨勮妭鐐规槸骞惰寮�濮嬪悗鐨勬煇涓�鍒嗘敮鐨勫紑濮嬭妭鐐癸紝閭d箞璇ヨ妭鐐瑰拰琚┏鍥炶妭鐐瑰疄闄呬笂灞炰簬涓茶锛� 鍙笉杩囬渶瑕佸悓鏃舵妸鍏跺畠骞惰鍒嗘敮涔熼┏鍥炰簡锛堣繖閲屽苟涓嶉渶瑕佹墜鍔ㄥ鐞嗭級 + * 3. 濡傛灉 琚┏鍥炶妭鐐瑰拰椹冲洖鑺傜偣灞炰簬涓茶锛屽垯鐩存帴椹冲洖鏃犻渶鑰冭檻鍏跺畠 + */ + // 鎵�浠ラ噸瑕佺殑鏄垽鏂袱涓换鍔′箣闂存槸鍚﹀瓨鍦ㄧ壒娈婅妭鐐癸紝鐩墠鍙厛鑰冭檻骞惰缃戝叧 + + // 璁剧疆涓ゆ潯璇勮 + List<HistoricTaskInstance> rejectedTaskList = historyService.createHistoricTaskInstanceQuery().processInstanceId(processInsId).taskDefinitionKey(rejectedTaskDefKey).orderByHistoricTaskInstanceStartTime().desc().list(); + String msg1 = "椹冲洖浜嗭細銆�" + rejectedTaskList.get(0).getName() + "銆戯紝椹冲洖鍘熷洜锛�"; + taskService.addComment(taskId, processInsId, FlowComment.REJECT.getType(), msg1 + msg); + // TODO 鐩存帴浣跨敤杩欎釜api濂藉儚鏈夐棶棰� + runtimeService.createChangeActivityStateBuilder().processInstanceId(processInsId).moveActivityIdTo(rejectTaskDefKey, rejectedTaskDefKey).changeState(); + } + } diff --git a/flowable/src/main/java/com/ycl/service/impl/FlowTaskServiceImpl.java b/flowable/src/main/java/com/ycl/service/impl/FlowTaskServiceImpl.java index cf45ee2..aff08d2 100644 --- a/flowable/src/main/java/com/ycl/service/impl/FlowTaskServiceImpl.java +++ b/flowable/src/main/java/com/ycl/service/impl/FlowTaskServiceImpl.java @@ -1215,26 +1215,28 @@ // 杩欓噷鍙渶瑕佹煡鑷韩浠ュ強涓婁竴涓妭鐐�(濡傛灉骞惰鐨勬湁澶氫釜)鐨勮〃鍗曟暟鎹� List<FormDetailVO> beforeNodes = taskCommonService.getBeforeNodeDefInfo(processDefId, processDefKey, sysFormService, Boolean.TRUE); List<String> beforeNodeDefIds = beforeNodes.stream().filter(item -> !item.getCurrent() || currentNeedData).map(FormDetailVO::getBeforeNodeDefId).collect(Collectors.toList()); - Map<String, Object> newP = new HashMap<>(); - if (CollectionUtils.isNotEmpty(beforeNodeDefIds)) { - for (String key : parameters.keySet()) { - // 杩囨护鎷垮埌鐩爣鏁版嵁锛屽皢鐩爣琛ㄥ崟鏁版嵁鏀惧埌鏂癿ap涓� - if (beforeNodeDefIds.stream().anyMatch(defId -> key.startsWith(defId))) { - if (key.contains(ProcessConstants.TASK_FORM_KEY)) { - newP.put(key, parameters.get(key)); - } - else { - newP.put(key.split("&")[1], parameters.get(key)); - } - } - } - } - // 鎷垮埌鐩爣琛ㄥ崟鍚庯紝鍐嶅鐞嗘瘡涓〃鍗曠殑鏁版嵁 + // 澶勭悊姣忎釜琛ㄥ崟鐨勬暟鎹� for (FormDetailVO formDetailVO : beforeNodes) { if (formDetailVO.getCurrent() && !currentNeedData) { continue; // 璺宠繃褰撳墠鑺傜偣锛屽洜涓哄綋鍓嶈妭鐐瑰湪鑾峰彇鍓嶇疆鑺傜偣鏃跺凡缁忚缃繃浜�(浣嗚〃鍗曟暟鎹病鏈夌粰) } + + Map<String, Object> newP = new HashMap<>(); + if (CollectionUtils.isNotEmpty(beforeNodeDefIds)) { + for (String key : parameters.keySet()) { + // 杩囨护鎷垮埌鐩爣琛ㄥ崟鏁版嵁锛屽皢鐩爣琛ㄥ崟鏁版嵁鏀惧埌鏂癿ap涓� + if (key.startsWith(formDetailVO.getBeforeNodeDefId())) { + if (key.contains(ProcessConstants.TASK_FORM_KEY)) { + newP.put(key, parameters.get(key)); + } + else { + newP.put(key.split("&")[1], parameters.get(key)); + } + } + } + } + Object form = newP.get(formDetailVO.getBeforeNodeDefId() + "&" + ProcessConstants.TASK_FORM_KEY); if (Objects.nonNull(form)) { JSONObject formJson = JSONObject.parseObject(JSON.toJSONString(form)); -- Gitblit v1.8.0