From cc78d40b9d4f9af7edf807ec66ea99102190dc1d Mon Sep 17 00:00:00 2001 From: WenG <450292408@qq.com> Date: Fri, 6 May 2022 22:55:26 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BA=86oa=E7=9A=84=E6=8A=84?= =?UTF-8?q?=E9=80=81=E3=80=81=E6=89=93=E5=8D=B0=E3=80=81=E5=BC=BA=E5=88=B6?= =?UTF-8?q?=E7=BB=93=E6=9D=9F=E6=8C=89=E9=92=AE=E5=B1=9E=E6=80=A7=EF=BC=8C?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=B5=81=E7=A8=8B=E5=BC=BA=E5=88=B6=E7=BB=93?= =?UTF-8?q?=E6=9D=9F=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/oa/OaFormReportController.java | 22 +++++- .../enums/oa/TaskCommentTypeEnum.java | 3 +- .../activiti/pojo/dtos/oa/NodeButtonDTO.java | 30 +++++++ .../activiti/IActivitiModelService.java | 4 + .../service/oa/IOaFormReportService.java | 13 ++- .../oa/impl/OaFormReportServiceImpl.java | 79 ++++++++++++++++++- .../mybatis/mapper/oa/node-button-mapper.xml | 37 +++++++-- 7 files changed, 174 insertions(+), 14 deletions(-) diff --git a/module-activiti/src/main/java/ink/wgink/module/activiti/controller/api/oa/OaFormReportController.java b/module-activiti/src/main/java/ink/wgink/module/activiti/controller/api/oa/OaFormReportController.java index 183b66ac..485f363b 100644 --- a/module-activiti/src/main/java/ink/wgink/module/activiti/controller/api/oa/OaFormReportController.java +++ b/module-activiti/src/main/java/ink/wgink/module/activiti/controller/api/oa/OaFormReportController.java @@ -76,15 +76,16 @@ public class OaFormReportController extends DefaultBaseController { @ApiOperation(value = "更新回退", notes = "更新回退接口") @ApiImplicitParams({ + @ApiImplicitParam(name = "processInstanceId", value = "流程实例ID", paramType = "path"), @ApiImplicitParam(name = "taskId", value = "当前任务ID", paramType = "path"), @ApiImplicitParam(name = "nodeId", value = "跳转节点ID", paramType = "path") }) @PutMapping("update-go-back/process-instance-id/{processInstanceId}/task-id/{taskId}/node-id/{nodeId}") - public SuccessResult update(@PathVariable("processInstanceId") String processInstanceId, + public synchronized SuccessResult updateGoBack(@PathVariable("processInstanceId") String processInstanceId, @PathVariable("taskId") String taskId, @PathVariable("nodeId") String nodeId, @RequestBody Map params) { - String reason = params.get(IOaFormReportService.KEY_GO_BACK_REASON); + String reason = params.get(IOaFormReportService.KEY_REASON); if (StringUtils.isBlank(reason)) { throw new ParamsException("回退原因不能为空"); } @@ -92,6 +93,23 @@ public class OaFormReportController extends DefaultBaseController { return new SuccessResult(); } + @ApiOperation(value = "更新强制结束", notes = "更新强制结束接口") + @ApiImplicitParams({ + @ApiImplicitParam(name = "processInstanceId", value = "流程实例ID", paramType = "path"), + @ApiImplicitParam(name = "taskId", value = "当前任务ID", paramType = "path") + }) + @PutMapping("update-forced-end/process-instance-id/{processInstanceId}/task-id/{taskId}") + public synchronized SuccessResult updateForcedEnd(@PathVariable("processInstanceId") String processInstanceId, + @PathVariable("taskId") String taskId, + @RequestBody Map params) { + String reason = params.get(IOaFormReportService.KEY_REASON); + if (StringUtils.isBlank(reason)) { + throw new ParamsException("结束原因不能为空"); + } + oaFormReportService.updateForcedEnd(processInstanceId, taskId, reason); + return new SuccessResult(); + } + @GetMapping("get/code/{formCode}/version/{formVersion}/uid/{uid}") public Map get(@PathVariable("formCode") String formCode, @PathVariable("formVersion") Integer formVersion, @PathVariable("uid") String uid) { return oaFormReportService.get(formCode, formVersion, uid); diff --git a/module-activiti/src/main/java/ink/wgink/module/activiti/enums/oa/TaskCommentTypeEnum.java b/module-activiti/src/main/java/ink/wgink/module/activiti/enums/oa/TaskCommentTypeEnum.java index a03af907..06d28dab 100644 --- a/module-activiti/src/main/java/ink/wgink/module/activiti/enums/oa/TaskCommentTypeEnum.java +++ b/module-activiti/src/main/java/ink/wgink/module/activiti/enums/oa/TaskCommentTypeEnum.java @@ -10,7 +10,8 @@ package ink.wgink.module.activiti.enums.oa; public enum TaskCommentTypeEnum { SIGN("sign", "签批"), JOINTLY_SIGN("jointlySign", "会签"), - GO_BACK("goBack", "回退"); + GO_BACK("goBack", "回退"), + FORCED_END("forcedEnd", "强制结束"); private String value; private String text; diff --git a/module-activiti/src/main/java/ink/wgink/module/activiti/pojo/dtos/oa/NodeButtonDTO.java b/module-activiti/src/main/java/ink/wgink/module/activiti/pojo/dtos/oa/NodeButtonDTO.java index c6077527..65dfc622 100644 --- a/module-activiti/src/main/java/ink/wgink/module/activiti/pojo/dtos/oa/NodeButtonDTO.java +++ b/module-activiti/src/main/java/ink/wgink/module/activiti/pojo/dtos/oa/NodeButtonDTO.java @@ -26,6 +26,12 @@ public class NodeButtonDTO { private Integer btnAttachment; @ApiModelProperty(name = "btnGoBack", value = "回退") private Integer btnGoBack; + @ApiModelProperty(name = "btnForcedEnd", value = "强制结束") + private Integer btnForcedEnd; + @ApiModelProperty(name = "btnPrint", value = "打印") + private Integer btnPrint; + @ApiModelProperty(name = "btnCc", value = "抄送") + private Integer btnCc; public String getNodeButtonId() { return nodeButtonId == null ? "" : nodeButtonId.trim(); @@ -82,4 +88,28 @@ public class NodeButtonDTO { public void setBtnGoBack(Integer btnGoBack) { this.btnGoBack = btnGoBack; } + + public Integer getBtnForcedEnd() { + return btnForcedEnd; + } + + public void setBtnForcedEnd(Integer btnForcedEnd) { + this.btnForcedEnd = btnForcedEnd; + } + + public Integer getBtnPrint() { + return btnPrint; + } + + public void setBtnPrint(Integer btnPrint) { + this.btnPrint = btnPrint; + } + + public Integer getBtnCc() { + return btnCc; + } + + public void setBtnCc(Integer btnCc) { + this.btnCc = btnCc; + } } diff --git a/module-activiti/src/main/java/ink/wgink/module/activiti/service/activiti/IActivitiModelService.java b/module-activiti/src/main/java/ink/wgink/module/activiti/service/activiti/IActivitiModelService.java index 46d1402d..8a2bca71 100644 --- a/module-activiti/src/main/java/ink/wgink/module/activiti/service/activiti/IActivitiModelService.java +++ b/module-activiti/src/main/java/ink/wgink/module/activiti/service/activiti/IActivitiModelService.java @@ -67,6 +67,10 @@ public interface IActivitiModelService { * 回退连线ID */ String GO_BACK_FLOW_ID = "goBackFlow"; + /** + * 强制结束 + */ + String FORCED_END_FLOW_ID = "forcedEnd"; /** * 保存模型 diff --git a/module-activiti/src/main/java/ink/wgink/module/activiti/service/oa/IOaFormReportService.java b/module-activiti/src/main/java/ink/wgink/module/activiti/service/oa/IOaFormReportService.java index 3217bff0..f4cf21d8 100644 --- a/module-activiti/src/main/java/ink/wgink/module/activiti/service/oa/IOaFormReportService.java +++ b/module-activiti/src/main/java/ink/wgink/module/activiti/service/oa/IOaFormReportService.java @@ -25,7 +25,7 @@ public interface IOaFormReportService { String KEY_SELECT_TYPE = "selectType"; String KEY_IS_NEXT_END_EVENT = "isNextEndEvent"; String KEY_RECORD_FIELDS = "recordFields"; - String KEY_GO_BACK_REASON = "reason"; + String KEY_REASON = "reason"; /** * 签批关键字后缀 */ @@ -113,10 +113,19 @@ public interface IOaFormReportService { * @param processInstanceId * @param currentTaskId * @param jumpNodeId - * @param reason 错误原因 + * @param reason 错误原因 */ void updateGoBack(String processInstanceId, String currentTaskId, String jumpNodeId, String reason); + /** + * 强制结束 + * + * @param processInstanceId + * @param currentTaskId + * @param reason + */ + void updateForcedEnd(String processInstanceId, String currentTaskId, String reason); + /** * 表单详情 * diff --git a/module-activiti/src/main/java/ink/wgink/module/activiti/service/oa/impl/OaFormReportServiceImpl.java b/module-activiti/src/main/java/ink/wgink/module/activiti/service/oa/impl/OaFormReportServiceImpl.java index 6aa3c946..fb896b08 100644 --- a/module-activiti/src/main/java/ink/wgink/module/activiti/service/oa/impl/OaFormReportServiceImpl.java +++ b/module-activiti/src/main/java/ink/wgink/module/activiti/service/oa/impl/OaFormReportServiceImpl.java @@ -22,10 +22,7 @@ import ink.wgink.pojo.app.AppTokenUser; import ink.wgink.pojo.bos.UserInfoBO; import ink.wgink.pojo.result.SuccessResultList; import ink.wgink.util.date.DateUtil; -import org.activiti.bpmn.model.BpmnModel; -import org.activiti.bpmn.model.MultiInstanceLoopCharacteristics; -import org.activiti.bpmn.model.SequenceFlow; -import org.activiti.bpmn.model.UserTask; +import org.activiti.bpmn.model.*; import org.activiti.engine.*; import org.activiti.engine.history.HistoricProcessInstance; import org.activiti.engine.history.HistoricTaskInstance; @@ -264,6 +261,80 @@ public class OaFormReportServiceImpl extends DefaultBaseService implements IOaFo } } + @Override + public void updateForcedEnd(String processInstanceId, String currentTaskId, String reason) { + LOG.debug("OA强制结束"); + Task currentTask = taskService.createTaskQuery().taskId(currentTaskId).singleResult(); + if (currentTask == null) { + throw new SearchException("任务不存在或已被处理"); + } + UserInfoBO currentUser = securityComponent.getCurrentUser(); + String userId = currentUser.getUserId(); + String userName = currentUser.getUserName(); + + List historicTaskInstances = historyService.createHistoricTaskInstanceQuery().processInstanceId(processInstanceId).unfinished().list(); + BpmnModel bpmnModel = activitiModelService.getBpmnModelByProcessDefinitionId(currentTask.getProcessDefinitionId()); + + LOG.debug("1. 获取当前节点"); + UserTask currentUserTask = (UserTask) bpmnModel.getFlowElement(currentTask.getTaskDefinitionKey()); + LOG.debug("2. 获取结束节点"); + List endEvents = bpmnModel.getMainProcess().findFlowElementsOfType(EndEvent.class); + LOG.debug("3. 获取当前节点输出流序列"); + List outgoingFlows = currentUserTask.getOutgoingFlows(); + LOG.debug("4. 缓存原始输出流"); + List oldOutgoingFlows = new ArrayList<>(); + oldOutgoingFlows.addAll(currentUserTask.getOutgoingFlows()); + LOG.debug("5. 创建新序列流"); + currentUserTask.getOutgoingFlows().clear(); + List newOutgoingFlows = new ArrayList<>(); + SequenceFlow newOutgoingFlow = new SequenceFlow(); + newOutgoingFlow.setId(IActivitiModelService.FORCED_END_FLOW_ID); + newOutgoingFlow.setSourceFlowElement(currentUserTask); + LOG.debug("6. 当前节点指向第一个结束节点"); + newOutgoingFlow.setTargetFlowElement(endEvents.get(0)); + newOutgoingFlows.add(newOutgoingFlow); + currentUserTask.setOutgoingFlows(newOutgoingFlows); + try { + LOG.debug("7. 判断当前节点类型"); + MultiInstanceLoopCharacteristics currentUserTaskLoopCharacteristics = currentUserTask.getLoopCharacteristics(); + if (currentUserTaskLoopCharacteristics == null) { + LOG.debug("7.1 当前节点为普通节点"); + } else { + LOG.debug("7.2 当前节点为会签节点"); + LOG.debug("7.2.1 自动完成其它节点"); + for (HistoricTaskInstance historicTaskInstance : historicTaskInstances) { + // 当前任务不处理 + if (StringUtils.equals(historicTaskInstance.getId(), currentTaskId)) { + continue; + } + /// 未完成的 + TaskCommentBO taskCommentBO = new TaskCommentBO(); + taskCommentBO.setType(TaskCommentTypeEnum.FORCED_END); + taskCommentBO.setContent("其他人强制结束(自动完成)"); + taskCommentBO.setTime(DateUtil.getTime()); + taskCommentBO.setUserId(userId); + taskCommentBO.setUserName(userName); + taskService.addComment(historicTaskInstance.getId(), processInstanceId, TaskCommentTypeEnum.FORCED_END.getValue(), JSONObject.toJSONString(taskCommentBO)); + taskService.complete(historicTaskInstance.getId()); + } + } + LOG.debug("7.2.2 完成当前节点"); + TaskCommentBO taskCommentBO = new TaskCommentBO(); + taskCommentBO.setType(TaskCommentTypeEnum.FORCED_END); + taskCommentBO.setContent(reason); + taskCommentBO.setTime(DateUtil.getTime()); + taskCommentBO.setUserId(userId); + taskCommentBO.setUserName(userName); + taskService.addComment(currentTaskId, processInstanceId, TaskCommentTypeEnum.FORCED_END.getValue(), JSONObject.toJSONString(taskCommentBO)); + taskService.complete(currentTaskId); + } catch (Exception e) { + e.printStackTrace(); + throw new SystemException(e); + } finally { + LOG.debug("8. 恢复连线"); + currentUserTask.setOutgoingFlows(oldOutgoingFlows); + } + } /** * 保存记录的字段列表 diff --git a/module-activiti/src/main/resources/mybatis/mapper/oa/node-button-mapper.xml b/module-activiti/src/main/resources/mybatis/mapper/oa/node-button-mapper.xml index a4100438..6de77d16 100644 --- a/module-activiti/src/main/resources/mybatis/mapper/oa/node-button-mapper.xml +++ b/module-activiti/src/main/resources/mybatis/mapper/oa/node-button-mapper.xml @@ -10,6 +10,9 @@ + + + @@ -23,8 +26,11 @@ `form_id` char(36) DEFAULT NULL COMMENT '表单ID', `node_id` char(60) DEFAULT NULL COMMENT '节点ID', `node_index` int(11) DEFAULT NULL COMMENT '节点下标', - `btn_attachment` varchar(255) DEFAULT NULL COMMENT '附件上传', - `btn_go_back` varchar(255) DEFAULT NULL COMMENT '回退', + `btn_attachment` int(1) DEFAULT NULL COMMENT '附件上传按钮', + `btn_go_back` int(1) DEFAULT NULL COMMENT '回退按钮', + `btn_forced_end` int(1) DEFAULT NULL COMMENT '强制结束按钮', + `btn_print` int(1) DEFAULT NULL COMMENT '打印按钮', + `btn_cc` int(1) DEFAULT NULL COMMENT '抄送按钮', PRIMARY KEY (`id`), UNIQUE KEY `node_button_id` (`node_button_id`), KEY `model_id` (`model_id`,`model_version`), @@ -44,7 +50,10 @@ node_id, node_index, btn_attachment, - btn_go_back + btn_go_back, + btn_forced_end, + btn_print, + btn_cc ) VALUES( #{nodeButtonId}, #{modelId}, @@ -53,7 +62,10 @@ #{nodeId}, #{nodeIndex}, #{btnAttachment}, - #{btnGoBack} + #{btnGoBack}, + #{btnForcedEnd}, + #{btnPrint}, + #{btnCc} ) @@ -82,6 +94,18 @@ SET btn_attachment = #{btnAttachment}, + + + btn_go_back = #{btnGoBack}, + + + btn_forced_end = #{btnForcedEnd}, + + + btn_print = #{btnPrint}, + + + btn_cc = #{btnCc}, node_button_id = #{nodeButtonId} WHERE @@ -120,7 +144,10 @@ node_id, node_index, btn_attachment, - btn_go_back + btn_go_back, + btn_forced_end, + btn_print, + btn_cc FROM oa_node_button WHERE