diff --git a/ruoyi-activiti/src/main/java/com/ruoyi/process/general/service/IProcessService.java b/ruoyi-activiti/src/main/java/com/ruoyi/process/general/service/IProcessService.java index e43c260b..5395f929 100644 --- a/ruoyi-activiti/src/main/java/com/ruoyi/process/general/service/IProcessService.java +++ b/ruoyi-activiti/src/main/java/com/ruoyi/process/general/service/IProcessService.java @@ -37,6 +37,8 @@ public interface IProcessService { boolean complete(String taskId, String instanceId, String itemName, String itemContent, String module, Map variables, HttpServletRequest request); + boolean complete2(String taskId, String instanceId, String itemName, String itemContent, String module, Map variables, HttpServletRequest request); + /** * 判断流程是否结束 * @return diff --git a/ruoyi-activiti/src/main/java/com/ruoyi/process/general/service/impl/ProcessServiceImpl.java b/ruoyi-activiti/src/main/java/com/ruoyi/process/general/service/impl/ProcessServiceImpl.java index b74043c6..6c0e76d0 100644 --- a/ruoyi-activiti/src/main/java/com/ruoyi/process/general/service/impl/ProcessServiceImpl.java +++ b/ruoyi-activiti/src/main/java/com/ruoyi/process/general/service/impl/ProcessServiceImpl.java @@ -187,7 +187,75 @@ public class ProcessServiceImpl implements IProcessService { } return agree; } + @Override + public boolean complete2(String taskId, String instanceId, String itemName, String itemContent, String module, Map variables, HttpServletRequest request) { + Enumeration parameterNames = request.getParameterNames(); + String comment = null; // 批注 + boolean agree = true; + try { + while (parameterNames.hasMoreElements()) { + String parameterName = parameterNames.nextElement(); + if (parameterName.startsWith("p_")) { + // 参数结构:p_B_name,p为参数的前缀,B为类型,name为属性名称 + String[] parameter = parameterName.split("_"); + if (parameter.length == 3) { + String paramValue = request.getParameter(parameterName); + Object value = paramValue; + if (parameter[1].equals("B")) { + value = BooleanUtils.toBoolean(paramValue); + agree = (boolean) value; + } else if (parameter[1].equals("DT")) { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm"); + value = sdf.parse(paramValue); + } else if (parameter[1].equals("COM")) { + comment = paramValue; + } + variables.put(parameter[2], value); + } else { + throw new RuntimeException("invalid parameter for activiti variable: " + parameterName); + } + } + } + if (StringUtils.isNotEmpty(comment)) { + identityService.setAuthenticatedUserId(ShiroUtils.getLoginName()); + comment = agree ? "【同意】" + comment : "【拒绝】" + comment; + taskService.addComment(taskId, instanceId, comment); + } + // 被委派人处理完成任务 + // p.s. 被委托的流程需要先 resolved 这个任务再提交。 + // 所以在 complete 之前需要先 resolved + // resolveTask() 要在 claim() 之前,不然 act_hi_taskinst 表的 assignee 字段会为 null + taskService.resolveTask(taskId, variables); + // 只有签收任务,act_hi_taskinst 表的 assignee 字段才不为 null + taskService.claim(taskId, ShiroUtils.getLoginName()); + taskService.complete(taskId, variables); + // 更新待办事项状态 + BizTodoItem query = new BizTodoItem(); + query.setTaskId(taskId); + // 考虑到候选用户组(或签,多个待办只要一人审批通过就行),会有多个 todoitem 办理同个 task + List updateList = CollectionUtils.isEmpty(bizTodoItemService.selectBizTodoItemList(query)) ? null : bizTodoItemService.selectBizTodoItemList(query); + for (BizTodoItem update: updateList) { + // 找到当前登录用户的 todoitem,置为已办 + if (update.getTodoUserId().equals(ShiroUtils.getLoginName())) { + update.setIsView("1"); + update.setIsHandle("1"); + update.setHandleUserId(ShiroUtils.getLoginName()); + update.setHandleUserName(ShiroUtils.getSysUser().getUserName()); + update.setHandleTime(DateUtils.getNowDate()); + bizTodoItemService.updateBizTodoItem(update); + } else { + bizTodoItemService.deleteBizTodoItemById(update.getId()); // 删除候选用户组其他 todoitem + } + } + + // 下一节点处理人待办事项 + bizTodoItemService.insertTodoItem(instanceId, itemName, itemContent, module); + } catch (Exception e) { + logger.error("error on complete task {}, variables={}", new Object[]{taskId, variables, e}); + } + return agree; + } @Override public boolean judgeProcessIsFinish(String instanceId) { boolean result = false; diff --git a/ruoyi-activiti/src/main/java/com/ruoyi/process/todoitem/service/IBizTodoItemService.java b/ruoyi-activiti/src/main/java/com/ruoyi/process/todoitem/service/IBizTodoItemService.java index 74112e8d..33937393 100644 --- a/ruoyi-activiti/src/main/java/com/ruoyi/process/todoitem/service/IBizTodoItemService.java +++ b/ruoyi-activiti/src/main/java/com/ruoyi/process/todoitem/service/IBizTodoItemService.java @@ -61,6 +61,9 @@ public interface IBizTodoItemService { * @return 结果 */ public int deleteBizTodoItemById(Long id); + + int insertTodoItem2(String instanceId, String itemName, String itemContent, String module); + int insertTodoItem(String instanceId, BizLeaveVo leave, String module); public List getTodoItemList(Map paraMap); diff --git a/ruoyi-activiti/src/main/java/com/ruoyi/process/todoitem/service/impl/BizTodoItemServiceImpl.java b/ruoyi-activiti/src/main/java/com/ruoyi/process/todoitem/service/impl/BizTodoItemServiceImpl.java index 8fca4aa3..1ac55b97 100644 --- a/ruoyi-activiti/src/main/java/com/ruoyi/process/todoitem/service/impl/BizTodoItemServiceImpl.java +++ b/ruoyi-activiti/src/main/java/com/ruoyi/process/todoitem/service/impl/BizTodoItemServiceImpl.java @@ -204,7 +204,76 @@ public class BizTodoItemServiceImpl implements IBizTodoItemService { } return counter; } + @Override + public int insertTodoItem2(String instanceId, String itemName, String itemContent, String module) { + BizTodoItem todoItem = new BizTodoItem(); + todoItem.setItemName(itemName); + todoItem.setItemContent(itemContent); + todoItem.setIsView("0"); + todoItem.setIsHandle("0"); + todoItem.setModule(module); + todoItem.setTodoTime(DateUtils.getNowDate()); + List taskList = taskService.createTaskQuery().processInstanceId(instanceId).active().list(); + int counter = 0; + for (Task task: taskList) { + // todoitem 去重 + List bizTodoItem = bizTodoItemMapper.selectTodoItemByTaskId(task.getId(),null); + if (!CollectionUtils.isEmpty(bizTodoItem)) continue; + BizTodoItem newItem = new BizTodoItem(); + BeanUtils.copyProperties(todoItem, newItem); + newItem.setInstanceId(instanceId); + newItem.setTaskId(task.getId()); + newItem.setTaskName("task" + task.getTaskDefinitionKey().substring(0, 1).toUpperCase() + task.getTaskDefinitionKey().substring(1)); + newItem.setNodeName(task.getName()); + String assignee = task.getAssignee(); + //todo 如果是本部门经理审核节点,查询当前提交的用户是部门角色,提取申请人对应部门经理 + if (task.getTaskDefinitionKey().equals("deptManagerAudit")) { + //查询当前提交的用户是部门角色,提取申请人对应部门经理 + String todoUserId = bizTodoItemMapper.selectTodoUserByTaskId(task.getId()); + SysUser todoUser = userMapper.selectUserByLoginName(todoUserId); + newItem.setTodoUserId(todoUser.getLoginName()); + newItem.setTodoUserName(todoUser.getUserName()); + } + //todo 如果是本部门主管审核节点,查询当前提交的是提交人部门,提取申请人对应部门主管角色 + if (task.getTaskDefinitionKey().equals("deptLeaderAudit")) { + //查询当前提交的用户是部门角色,提取申请人对应部门经理 + String todoUserId = bizTodoItemMapper.selectTodoUserByTaskId(task.getId()); + SysUser todoUser = userMapper.selectUserByLoginName(todoUserId); + newItem.setTodoUserId(todoUser.getLoginName()); + newItem.setTodoUserName(todoUser.getUserName()); + } + // 代理人 + if (StringUtils.isNotBlank(assignee)) { + newItem.setTodoUserId(assignee); + SysUser user = userMapper.selectUserByLoginName(assignee); + newItem.setTodoUserName(user.getUserName()); + bizTodoItemMapper.insertBizTodoItem(newItem); + counter++; + } else { + // 查询候选用户组,系统用户角色视图,group是角色 + List todoUserIdList = bizTodoItemMapper.selectTodoUserListByTaskId(task.getId()); + if (!CollectionUtils.isEmpty(todoUserIdList)) { + for (String todoUserId: todoUserIdList) { + SysUser todoUser = userMapper.selectUserByLoginName(todoUserId); + newItem.setTodoUserId(todoUser.getLoginName()); + newItem.setTodoUserName(todoUser.getUserName()); + bizTodoItemMapper.insertBizTodoItem(newItem); + counter++; + } + } else { + // 查询候选用户,用户id匹配的上 + String todoUserId = bizTodoItemMapper.selectTodoUserByTaskId(task.getId()); + SysUser todoUser = userMapper.selectUserByLoginName(todoUserId); + newItem.setTodoUserId(todoUser.getLoginName()); + newItem.setTodoUserName(todoUser.getUserName()); + bizTodoItemMapper.insertBizTodoItem(newItem); + counter++; + } + } + } + return counter; + } @Override public int insertTodoItem(String instanceId, BizLeaveVo leave, String module) { BizTodoItem todoItem = new BizTodoItem(); diff --git a/ruoyi-admin/src/main/java/com/ruoyi/erp/controller/ErpBomController.java b/ruoyi-admin/src/main/java/com/ruoyi/erp/controller/ErpBomController.java index e261c18b..ddd82844 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/erp/controller/ErpBomController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/erp/controller/ErpBomController.java @@ -31,10 +31,7 @@ import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Set; +import java.util.*; /** * 物料bom信息Controller @@ -87,8 +84,24 @@ public class ErpBomController extends BaseController startPage(); List list = erpBomService.selectErpBomList(erpBomVo); return getDataTable(list); - - + } + @RequiresPermissions("erp:bom:list") + @PostMapping("/reverseList") + @ResponseBody + public TableDataInfo selectErpBomVoReverse(ErpBomVo erpBomVo,HttpServletRequest request) { + Map map = new HashMap<>(); + map.put("materialNo", erpBomVo.getMaterialNo()); + map.put("materialName", erpBomVo.getMaterialName()); + List materialList = erpBomService.selectErpBomByMaterialNos(erpBomVo.getMaterialNo()); + //将返回结果根据父节点进行排序 + List parentIds = erpBomService.getAllParentIds(materialList); + Map map2 = new HashMap<>(); + map2.put("parentIds", parentIds); + ErpBomVo erpBomVo1 = new ErpBomVo(); + List list1 = erpBomService.selectErpBomList(erpBomVo1); + startPage(); + List list = erpBomService.selectErpBomListReverse(list1); + return getDataTable(list); } /** diff --git a/ruoyi-admin/src/main/java/com/ruoyi/erp/mapper/ErpBomMapper.java b/ruoyi-admin/src/main/java/com/ruoyi/erp/mapper/ErpBomMapper.java index a2e83480..5f797782 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/erp/mapper/ErpBomMapper.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/erp/mapper/ErpBomMapper.java @@ -5,6 +5,7 @@ import com.ruoyi.erp.domain.ErpBomVo; import com.ruoyi.erp.domain.ErpMaterialVo; import java.util.List; +import java.util.Map; /** * bomMapper接口 @@ -134,4 +135,8 @@ public interface ErpBomMapper ErpBomVo selectErpBomByMaterialNo(String materialNo); + List selectErpBomByMaterialNos(String materialNo); + + List selectSubBomsByParentMaterialNo(Map params, List materialTypes); + List selectErpBomByParentIds(Map params); } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/erp/service/IErpBomService.java b/ruoyi-admin/src/main/java/com/ruoyi/erp/service/IErpBomService.java index 0df5e941..6c18effe 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/erp/service/IErpBomService.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/erp/service/IErpBomService.java @@ -7,6 +7,7 @@ import org.activiti.engine.runtime.ProcessInstance; import org.springframework.transaction.annotation.Transactional; import java.util.List; +import java.util.Map; /** * bomService接口 @@ -36,6 +37,16 @@ public interface IErpBomService List selectErpBomAllLevelList(ErpBom erpBom); + void recursionSubBom(List resultList, String materialNo, Long level); + + List getAllParentIds(List startIds); + + void collectParentIdsRecursively(List parents, Long currentId); + + List selectErpBomListReverse(List erpBomVoList); + + + List selectErpBomByMaterialNos(String materialNo); /** * 新增bom * diff --git a/ruoyi-admin/src/main/java/com/ruoyi/erp/service/impl/ErpBomServiceImpl.java b/ruoyi-admin/src/main/java/com/ruoyi/erp/service/impl/ErpBomServiceImpl.java index e00aa1d5..e57c0796 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/erp/service/impl/ErpBomServiceImpl.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/erp/service/impl/ErpBomServiceImpl.java @@ -15,6 +15,7 @@ import com.ruoyi.erp.mapper.ErpBomMapper; import com.ruoyi.erp.mapper.ErpMaterialMapper; import com.ruoyi.erp.service.IErpBomService; import com.ruoyi.erp.service.IErpMaterialService; +import com.ruoyi.framework.web.service.CategoryService; import com.ruoyi.process.general.service.IProcessService; import com.ruoyi.process.todoitem.mapper.BizTodoItemMapper; import com.ruoyi.system.mapper.SysUserMapper; @@ -31,10 +32,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import javax.servlet.http.HttpServletRequest; -import java.math.BigDecimal; import java.util.*; -import java.util.regex.Pattern; /** * bomService业务层处理 @@ -80,6 +78,8 @@ private ISysAttachService attachService; @Autowired private ErpMaterialMapper materialMapper; + @Autowired + private CategoryService categoryService; /** * 查询bom * @@ -181,8 +181,8 @@ private ISysAttachService attachService; return resultList; } - - private void recursionSubBom(List resultList, String materialNo, Long level) { + @Override + public void recursionSubBom(List resultList, String materialNo, Long level) { ErpBom subBom = erpBomMapper.selectErpBomByOneMaterialNo(materialNo); if(subBom!=null){ Long subId = subBom.getId(); @@ -204,6 +204,93 @@ private ISysAttachService attachService; } } + // 获取所有父节点id + @Override + public List getAllParentIds(List startList) { + List allParentIds = new ArrayList<>(); + List startIds = new ArrayList<>(); + for (ErpBomVo erpBomVo : startList) { + Long id = erpBomVo.getId(); + startIds.add(id); + } + for (Long startId : startIds) { + collectParentIdsRecursively(allParentIds, startId); + } + return allParentIds; + } + // 递归获取所有父节点id + @Override + public void collectParentIdsRecursively(List parents, Long currentId) { + // 新增条件:遇到parentId为0时停止递归 + if (currentId.equals(0)) { + return; + } + Map param = new HashMap<>(); + param.put("parentId", currentId); + List children = erpBomMapper.selectErpBomByParentIds(param); + for (ErpBomVo child : children) { + // 避免循环引用,这里假设id和parentId不会相等 + if (!parents.contains(child.getId())) { + parents.add(child.getId()); + // 继续递归,直到遇到parentId为0的节点 + collectParentIdsRecursively(parents, child.getId()); + } + } + } + @Override + public List selectErpBomListReverse(List erpBomVoList) + { + List returnList = new ArrayList<>(); + for (ErpBomVo bomVo: erpBomVoList) { + SysUser sysUser = userMapper.selectUserByLoginName(bomVo.getCreateBy()); + if (sysUser != null) { + bomVo.setCreateUserName(sysUser.getUserName()); + } + SysUser sysUser2 = userMapper.selectUserByLoginName(bomVo.getApplyUser()); + if (sysUser2 != null) { + bomVo.setApplyUserName(sysUser2.getUserName()); + } + String instanceId = bomVo.getInstanceId(); + // 当前环节 + if (StringUtils.isNotBlank(instanceId)) { + List taskList = taskService.createTaskQuery() + .processInstanceId(instanceId) +// .singleResult(); + .list(); // 例如请假会签,会同时拥有多个任务 + if (!org.springframework.util.CollectionUtils.isEmpty(taskList)) { + TaskEntityImpl task = (TaskEntityImpl) taskList.get(0); + String taskId = task.getId(); + bomVo.setTaskId(taskId); + // 设置待办用户 + List todoUserList = todoItemMapper.selectUndealTodoUserList(taskId); + if(!org.springframework.util.CollectionUtils.isEmpty(taskList)){ + bomVo.setTodoUserId(String.join(",",todoUserList)); + } + if (task.getSuspensionState() == 2) { + bomVo.setTaskName("已挂起"); + bomVo.setSuspendState("2"); + } else { + bomVo.setTaskName(task.getName()); + bomVo.setSuspendState("1"); + } + } else { + // 已办结或者已撤销 + bomVo.setTaskName("已结束"); + } + } else { + bomVo.setTaskName("未启动"); + } + returnList.add(bomVo); + } + Integer total = erpBomVoList.size(); + return returnList; + } + + @Override + public List selectErpBomByMaterialNos(String materialNo) { + return erpBomMapper.selectErpBomByMaterialNos(materialNo); + } + /** * 新增bom * diff --git a/ruoyi-admin/src/main/resources/mapper/erp/ErpBomMapper.xml b/ruoyi-admin/src/main/resources/mapper/erp/ErpBomMapper.xml index af429518..ec09d73c 100644 --- a/ruoyi-admin/src/main/resources/mapper/erp/ErpBomMapper.xml +++ b/ruoyi-admin/src/main/resources/mapper/erp/ErpBomMapper.xml @@ -137,6 +137,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and erp.apply_user = #{applyUser} and erp.apply_time = #{applyTime} and (erp.material_no like concat('%',#{keyword},'%') or erp.material_name like concat('%',#{keyword},'%')) + + and erp.id in + + #{parendId} + + and erp.level = 0 + and erp.bom_no != '' order by erp.create_time desc @@ -397,4 +405,118 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" on erp_material.id = file.rel_id where erp.material_no = #{materialNo} + + + + \ No newline at end of file diff --git a/ruoyi-admin/src/main/resources/templates/erp/bom/add.html b/ruoyi-admin/src/main/resources/templates/erp/bom/add.html index e7eb25bd..098e901f 100644 --- a/ruoyi-admin/src/main/resources/templates/erp/bom/add.html +++ b/ruoyi-admin/src/main/resources/templates/erp/bom/add.html @@ -102,7 +102,7 @@ - + diff --git a/ruoyi-admin/src/main/resources/templates/erp/bom/edit.html b/ruoyi-admin/src/main/resources/templates/erp/bom/edit.html index ca819eb2..cc502196 100644 --- a/ruoyi-admin/src/main/resources/templates/erp/bom/edit.html +++ b/ruoyi-admin/src/main/resources/templates/erp/bom/edit.html @@ -91,6 +91,7 @@ +