package org.jeecg.modules.dncFlow.service.impl; import cn.hutool.core.util.StrUtil; import com.alibaba.fastjson.JSON; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.apache.commons.beanutils.BeanUtils; import org.apache.shiro.SecurityUtils; import org.flowable.common.engine.api.FlowableException; import org.flowable.engine.TaskService; import org.flowable.identitylink.api.IdentityLink; import org.flowable.task.api.Task; import org.jeecg.common.api.vo.Result; import org.jeecg.common.system.vo.LoginUser; import org.jeecg.modules.dnc.entity.DocInfo; import org.jeecg.modules.dnc.entity.PermissionStreamNew; import org.jeecg.modules.dnc.exception.ExceptionCast; import org.jeecg.modules.dnc.mapper.DocInfoMapper; import org.jeecg.modules.dnc.request.DocInfoQueryRequest; import org.jeecg.modules.dnc.response.ActivitiCode; import org.jeecg.modules.dnc.response.CommonCode; import org.jeecg.modules.dnc.response.UcenterCode; import org.jeecg.modules.dnc.service.IDocInfoService; import org.jeecg.modules.dnc.utils.ValidateUtil; import org.jeecg.modules.dncFlow.entity.DispatchFile; import org.jeecg.modules.dncFlow.mapper.DispatchFileMapper; import org.jeecg.modules.dncFlow.service.IDispatchFileService; import org.jeecg.modules.dncFlow.vo.DispatchFileFlowTaskVo; import org.jeecg.modules.flowable.apithird.business.entity.FlowMyBusiness; import org.jeecg.modules.flowable.apithird.business.service.IFlowMyBusinessService; import org.jeecg.modules.flowable.apithird.service.FlowCallBackServiceI; import org.jeecg.modules.flowable.apithird.service.FlowCommonService; import org.jeecg.modules.flowable.domain.vo.FlowHistoricalVo; import org.jeecg.modules.flowable.service.IFlowDefinitionService; import org.jeecg.modules.flowable.service.IFlowTaskService; import org.jeecg.modules.flowable.service.IHisWorkTaskService; import org.jeecg.modules.system.service.ISysUserRoleService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import java.lang.reflect.InvocationTargetException; import java.util.*; /** * @Description: nc程序与电子图版签派 * @Author: jeecg-boot * @Date: 2025-03-19 * @Version: V1.0 */ @Service("IDispatchFileService") public class DispatchFileServiceImpl extends ServiceImpl implements IDispatchFileService, FlowCallBackServiceI { @Autowired @Lazy private IDocInfoService docInfoService; @Resource private FlowCommonService flowCommonService; @Resource private IFlowDefinitionService flowDefinitionService; @Autowired private IFlowTaskService flowTaskService; @Autowired private TaskService taskService; @Autowired private IFlowMyBusinessService flowMyBusinessService; @Autowired private DocInfoMapper docInfoMapper; @Autowired private ISysUserRoleService sysUserRoleService; @Autowired private PermissionService permissionService; @Autowired private IHisWorkTaskService hisWorkTaskService; /** * 流程启动,保存对应的数据 * @param dispatchFile * @return */ @Override @Transactional(rollbackFor = {Exception.class}) public Result saveDispatchFile(DispatchFile dispatchFile){ //校验参数 checkParam(dispatchFile); //获取文件信息 DocInfo docInfo = docInfoService.getById(dispatchFile.getDocId()); PermissionStreamNew permissionStreams = getPermissionStreams(dispatchFile); if (permissionStreams==null){ return Result.error("用户没有权限"); } dispatchFile.setAttributionType(dispatchFile.getAttributionType()); dispatchFile.setAttributionId(dispatchFile.getAttributionId()); dispatchFile.setDocClassCode(dispatchFile.getDocClassCode()); super.save(dispatchFile); System.out.println("NC程序和电子样板审签流程:" + dispatchFile.getDocId()); flowCommonService.initActBusiness(docInfo.getDocName()+"."+docInfo.getDocSuffix()+"文件进行审签", dispatchFile.getId(), "IDispatchFileService", "nc_dispatch_file", null); Map variables = new HashMap<>(); variables.put("dataId", dispatchFile.getId()); variables.put("organization", "导入文档默认启动流程"); variables.put("comment", "导入文档默认启动流程"); variables.put("proofreading",true); Result result= flowDefinitionService.startProcessInstanceByKey("nc_dispatch_file", variables); if (!result.isSuccess()) { super.removeById(dispatchFile.getId()); }else { docInfo.setDocDispatchStatus(1); docInfoService.updateById(docInfo); } return result; } /** * 文件查询审签流程 * @param attributionId,attributionType,docId * @return */ @Override public Result queryDispatchDocFile(String attributionId, String attributionType, String docId){ DispatchFile dispatchFile=super.getOne(new LambdaQueryWrapper() .eq(DispatchFile::getAttributionId, attributionId).eq(DispatchFile::getAttributionType, attributionType) .eq(DispatchFile::getDocId, docId)); if (dispatchFile==null){ return Result.error("未找到对应审签文件"); }else { FlowMyBusiness flowMyBusiness=flowMyBusinessService.selectByDataId(dispatchFile.getId()); if (flowMyBusiness==null){ return Result.error("未找到对应审签流程"); }else { List queryHisTaskByProcInstId=hisWorkTaskService.queryHisTaskByProcInstId(flowMyBusiness.getProcessInstanceId()); return Result.ok(queryHisTaskByProcInstId); } } } /** * 重新启动 * @param dispatchFileFlowTaskVo */ @Override @Transactional(rollbackFor = {Exception.class}) public Result reStartDispatchFile(DispatchFileFlowTaskVo dispatchFileFlowTaskVo) { try { // 1. 获取当前用户并校验登录状态 LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal(); if (user == null) { return Result.error("用户未登录"); } // 2. 查询流程业务记录(处理空结果) List businessList = flowMyBusinessService.list( new QueryWrapper() .eq("process_instance_id", dispatchFileFlowTaskVo.getInstanceId()) ); if (businessList.isEmpty()) { return Result.error("流程记录不存在"); } FlowMyBusiness flowMyBusiness = businessList.get(0); // 3. 校验用户是否为候选处理人 List todoUsers = JSON.parseArray(flowMyBusiness.getTodoUsers(), String.class); if (todoUsers == null || !todoUsers.contains(user.getUsername())) { return Result.error("用户无权操作此任务"); } // 4. 认领任务(处理已被认领的情况) String taskId = flowMyBusiness.getTaskId(); Task task = taskService.createTaskQuery().taskId(taskId).singleResult(); if (task == null) { return Result.error("任务不存在或已完成"); } if (task.getAssignee() != null && !task.getAssignee().equals(user.getUsername())) { return Result.error("任务已被他人认领"); } taskService.claim(taskId, user.getUsername()); // 5. 完成任务并传递变量 Map variables = new HashMap<>(); variables.put("dataId", flowMyBusiness.getDataId()); variables.put("organization", dispatchFileFlowTaskVo.getComment()); variables.put("assignee", user.getUsername()); variables.put("comment", dispatchFileFlowTaskVo.getComment()); taskService.complete(taskId, variables); // 6. 获取下一任务并更新业务记录 List nextTasks = taskService.createTaskQuery() .processInstanceId(dispatchFileFlowTaskVo.getInstanceId()) .list(); if (!nextTasks.isEmpty()) { Task nextTask = nextTasks.get(0); // 假设取第一个任务 flowMyBusiness.setTaskId(nextTask.getId()); flowMyBusiness.setTaskName(nextTask.getName()); // 动态获取下一节点候选人(示例) List nextTodoUsers = getNextTaskCandidates(nextTask.getId()); flowMyBusiness.setTodoUsers(JSON.toJSONString(nextTodoUsers)); } else { // 流程已结束,清空任务信息 flowMyBusiness.setTaskId(null); flowMyBusiness.setTaskName(null); flowMyBusiness.setTodoUsers(null); } flowMyBusinessService.updateById(flowMyBusiness); return Result.ok("流程重启成功"); } catch (FlowableException e) { return Result.error("流程操作失败: " + e.getMessage()); } catch (Exception e) { return Result.error("系统错误: " + e.getMessage()); } } // 辅助方法:获取下一任务的所有候选信息(处理人、候选用户、候选组) private List getNextTaskCandidates(String taskId) { List links = taskService.getIdentityLinksForTask(taskId); List candidates = new ArrayList<>(); // 1. 获取直接处理人(assignee) links.stream() .filter(link -> "assignee".equals(link.getType())) .map(IdentityLink::getUserId) .filter(Objects::nonNull) .forEach(candidates::add); // 2. 获取候选用户和候选组 links.stream() .filter(link -> "candidate".equals(link.getType())) .forEach(link -> { if (link.getUserId() != null) { // 候选用户直接添加 candidates.add(link.getUserId()); } else if (link.getGroupId() != null) { // 候选组转换为实际用户(示例逻辑,需根据业务实现) List groupUsers = convertGroupToUsers(link.getGroupId()); candidates.addAll(groupUsers); } }); return candidates; } // 示例方法:将候选组ID转换为用户列表(需自定义实现) private List convertGroupToUsers(String groupId) { // 实际业务中调用服务接口获取组成员 return sysUserRoleService.getUserNameByRoleId(groupId); } /** * 审批操作 * @param dispatchFileFlowTaskVo * @return */ @Override @Transactional public Result auditDispatchFile(DispatchFileFlowTaskVo dispatchFileFlowTaskVo) { try { // 参数校验 if (!ValidateUtil.validateString(dispatchFileFlowTaskVo.getTaskId()) || !ValidateUtil.validateString(dispatchFileFlowTaskVo.getDataId())) { return Result.error(CommonCode.INVALID_PARAM.toString()); } LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal(); String userId = user.getId(); dispatchFileFlowTaskVo.setAssignee(user.getUsername()); if (!ValidateUtil.validateString(userId)) { return Result.error(UcenterCode.UCENTER_ACCOUNT_NOT_EXIST.toString()); } // 数据查询 DispatchFile dispatchFile = this.getById(dispatchFileFlowTaskVo.getDataId()); if (dispatchFile == null) { return Result.error(CommonCode.INVALID_PARAM.toString()); } DocInfo docInfo = docInfoService.getById(dispatchFile.getDocId()); if (docInfo == null) { return Result.error(ActivitiCode.ACT_DOC_ERROR.toString()); } // 2. 查询流程业务记录(处理空结果) List businessList = flowMyBusinessService.list( new QueryWrapper() .eq("process_instance_id", dispatchFileFlowTaskVo.getInstanceId()) ); if (businessList.isEmpty()) { return Result.error("流程记录不存在"); } FlowMyBusiness flowMyBusiness = businessList.get(0); // 3. 校验用户是否为候选处理人 List todoUsers = JSON.parseArray(flowMyBusiness.getTodoUsers(), String.class); if (todoUsers == null || !todoUsers.contains(user.getUsername())) { return Result.error("用户无权操作此任务"); } // 4. 认领任务(处理已被认领的情况) String taskId = flowMyBusiness.getTaskId(); Task task = taskService.createTaskQuery().taskId(taskId).singleResult(); if (task == null) { return Result.error("任务不存在或已完成"); } if (task.getAssignee() != null && !task.getAssignee().equals(user.getUsername())) { return Result.error("任务已被他人认领"); } taskService.claim(taskId, user.getUsername()); // 设置流程变量 Map values = setProcessVariables(dispatchFile, userId, dispatchFileFlowTaskVo); dispatchFileFlowTaskVo.setValues(values); // 完成流程任务 Result result = flowTaskService.complete(dispatchFileFlowTaskVo); if (result.isSuccess()) { // 更新状态 updateStatus(dispatchFile, docInfo, dispatchFileFlowTaskVo); docInfoService.updateById(docInfo); this.updateById(dispatchFile); } else { return result; } return Result.OK("操作成功"); } catch (Exception e) { return Result.error("操作失败:" + e.getMessage()); } } /** * 批量审批操作 * @param dispatchFileFlowTaskVo * @return */ @Override @Transactional public Result auditBatchDispatchFile(DispatchFileFlowTaskVo dispatchFileFlowTaskVo) throws InvocationTargetException, IllegalAccessException { if (dispatchFileFlowTaskVo.getTaskIds()==null || dispatchFileFlowTaskVo.getTaskIds().isEmpty()) { return Result.error(CommonCode.INVALID_PARAM.toString()); } if (dispatchFileFlowTaskVo.getTaskIds().contains(",")){ String[] taskIds = dispatchFileFlowTaskVo.getTaskIds().split(","); for (String taskId : taskIds) { FlowMyBusiness flowMyBusiness=flowMyBusinessService.getOne(new QueryWrapper().eq("task_id",taskId)); DispatchFileFlowTaskVo dispatchFileFlowTaskVoNew=new DispatchFileFlowTaskVo(); BeanUtils.copyProperties(dispatchFileFlowTaskVoNew, dispatchFileFlowTaskVo); dispatchFileFlowTaskVoNew.setTaskId(taskId); dispatchFileFlowTaskVoNew.setDataId(flowMyBusiness.getDataId()); dispatchFileFlowTaskVoNew.setInstanceId(flowMyBusiness.getProcessInstanceId()); if (dispatchFileFlowTaskVo.getTargetKey().equals("task_prepare")){ reStartDispatchFile(dispatchFileFlowTaskVoNew); }else { auditDispatchFile(dispatchFileFlowTaskVoNew); } } } return Result.OK("操作成功"); } /** * 查询审签基本信息 * @param id */ public Result queryDispatchFile(String id){ DispatchFile dispatchFile=this.getById(id); if (dispatchFile==null){ return Result.error("审签基本信息不存在"); } DocInfoQueryRequest docInfoQueryRequest=new DocInfoQueryRequest(); docInfoQueryRequest.setDocId(dispatchFile.getDocId()); docInfoQueryRequest.setAttributionId(dispatchFile.getAttributionId()); docInfoQueryRequest.setAttributionType(Integer.valueOf(dispatchFile.getAttributionType())); docInfoQueryRequest.setDocClassCode(dispatchFile.getDocClassCode()); List docInfoList = docInfoService.findList(docInfoQueryRequest); return Result.OK(docInfoList); } /** * 发起定型流程 */ @Override public Result submitProccess(DispatchFile dispatchFile) { checkParam(dispatchFile); super.save(dispatchFile); //获取文件信息 DocInfo docInfo = docInfoService.getById(dispatchFile.getDocId()); flowCommonService.initActBusiness(docInfo.getDocName()+"."+docInfo.getDocSuffix()+"文件进行定型", dispatchFile.getId(), "IDispatchFileService", "process_rf27duhy", null); Map variables = new HashMap<>(); variables.put("dataId", dispatchFile.getId()); variables.put("organization", "导入文档默认启动流程"); variables.put("comment", "导入文档默认启动流程"); variables.put("proofreading",true); Result result= flowDefinitionService.startProcessInstanceByKey("process_rf27duhy", variables); if (!result.isSuccess()) super.removeById(dispatchFile.getId()); return result; } private Map setProcessVariables(DispatchFile dispatchFile, String userId, DispatchFileFlowTaskVo dispatchFileFlowTaskVo) { Map values = new HashMap<>(); values.put("dataId", dispatchFile.getId()); values.put("organization", dispatchFile.getOrganization()); values.put("assignee", userId); values.put("comment", dispatchFileFlowTaskVo.getComment()); if (StrUtil.isNotBlank(dispatchFileFlowTaskVo.getProofreadStatus())) { values.put("proofreadStatus", dispatchFileFlowTaskVo.getProofreadStatus()); } if (dispatchFileFlowTaskVo.getRatify() != null) { values.put("ratify", dispatchFileFlowTaskVo.getRatify()); } if (dispatchFileFlowTaskVo.getCut() != null) { values.put("cut", dispatchFileFlowTaskVo.getCut()); } if (dispatchFileFlowTaskVo.getStereotype() != null) { values.put("stereotype", dispatchFileFlowTaskVo.getStereotype()); } return values; } private void updateStatus(DispatchFile dispatchFile, DocInfo docInfo, DispatchFileFlowTaskVo dispatchFileFlowTaskVo) { if (StrUtil.isNotBlank(dispatchFileFlowTaskVo.getProofreadStatus())) { switch (dispatchFileFlowTaskVo.getProofreadStatus()) { case "1": // 直接定型 dispatchFile.setCurrentNode("5"); docInfo.setDocDispatchStatus(5); break; case "2": // 校对通过 dispatchFile.setCurrentNode("2"); docInfo.setDocDispatchStatus(2); break; default: // 校对不通过 dispatchFile.setCurrentNode("1"); docInfo.setDocDispatchStatus(1); break; } } if (dispatchFileFlowTaskVo.getRatify() != null && dispatchFileFlowTaskVo.getRatify()) { dispatchFile.setCurrentNode("3"); docInfo.setDocDispatchStatus(3); } if (dispatchFileFlowTaskVo.getCut() != null && dispatchFileFlowTaskVo.getCut()) { dispatchFile.setCurrentNode("4"); docInfo.setDocDispatchStatus(4); } if (dispatchFileFlowTaskVo.getStereotype() != null && dispatchFileFlowTaskVo.getStereotype()) { dispatchFile.setCurrentNode("5"); docInfo.setDocDispatchStatus(5); } } //传参验证 public boolean checkParam(DispatchFile dispatchFile) { if (dispatchFile == null) { ExceptionCast.cast(CommonCode.INVALID_PARAM); } if (!ValidateUtil.validateString(dispatchFile.getAttributionId()) || !ValidateUtil.validateString(dispatchFile.getDocId()) || !ValidateUtil.validateString(dispatchFile.getFileId()) || !ValidateUtil.validateString(dispatchFile.getAttributionType())) { ExceptionCast.cast(CommonCode.INVALID_PARAM); } LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal(); String userId = user.getId(); if (!ValidateUtil.validateString(userId)) { ExceptionCast.cast(UcenterCode.UCENTER_ACCOUNT_NOT_EXIST); } return true; } private PermissionStreamNew getPermissionStreams(DispatchFile dispatchFile) { PermissionStreamNew permissionStreamNew = permissionService.getPermissionStreams(dispatchFile); if (permissionStreamNew == null) { ExceptionCast.cast(ActivitiCode.ACT_NODE_DEPART_NONE); } return permissionStreamNew; } @Override public void afterFlowHandle(FlowMyBusiness business) { business.getTaskNameId();//接下来审批的节点 business.getValues();//前端传进来的参数 business.getActStatus(); } @Override public Object getBusinessDataById(String dataId) { return this.getById(dataId); } @Override public Map flowValuesOfTask(String taskNameId, Map values) { return null; } @Override public List flowCandidateUsernamesOfTask(String taskNameId, Map values) { //业务是否干预流程,业务干预,流程干预,指定人员进行处理 return null; } }