Ver código fonte

质检系统任务流程优化

lvy 1 dia atrás
pai
commit
8738320d0b

+ 491 - 6
blade-service/blade-business/src/main/java/org/springblade/business/controller/FixedFlowController.java

@@ -1,7 +1,9 @@
 package org.springblade.business.controller;
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
@@ -13,20 +15,30 @@ import org.springblade.business.entity.FixedFlowLink;
 import org.springblade.business.entity.Task;
 import org.springblade.business.service.IFixedFlowLinkService;
 import org.springblade.business.service.IFixedFlowService;
+import org.springblade.business.service.impl.TaskServiceImpl;
 import org.springblade.business.vo.FixedFlowVO;
 import org.springblade.common.utils.SnowFlakeUtil;
 import org.springblade.core.boot.ctrl.BladeController;
+import org.springblade.core.log.exception.ServiceException;
+import org.springblade.core.secure.utils.AuthUtil;
 import org.springblade.core.tool.api.R;
+import org.springblade.core.tool.utils.BeanUtil;
 import org.springblade.core.tool.utils.Func;
 import org.springblade.core.tool.utils.ObjectUtil;
 import org.springblade.manager.dto.SaveUserInfoByProjectDTO;
+import org.springblade.manager.entity.ProjectInfo;
 import org.springblade.manager.entity.SignPfxFile;
 import org.springblade.manager.feign.ContractClient;
 import org.springblade.manager.feign.ProjectAssignmentUserClient;
+import org.springblade.manager.feign.ProjectClient;
+import org.springblade.manager.feign.SignPfxClient;
 import org.springblade.manager.vo.RoleSignPfxUserVO;
 import org.springblade.manager.vo.RoleSignPfxUserVO1;
 import org.springblade.manager.vo.RoleSignPfxUserVO2;
 import org.springblade.manager.vo.RoleSignPfxUserVO3;
+import org.springblade.meter.dto.PageFixedFlowDTO;
+import org.springblade.meter.dto.SaveFixedFlowDTO;
+import org.springblade.meter.dto.UpdateFixedFlowDTO;
 import org.springblade.system.feign.ISysClient;
 import org.springblade.system.user.entity.User;
 import org.springblade.system.user.feign.IUserClient;
@@ -34,12 +46,13 @@ import org.springblade.system.vo.RoleVO;
 import org.springframework.beans.BeanUtils;
 import org.springframework.jdbc.core.BeanPropertyRowMapper;
 import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.transaction.annotation.Isolation;
+import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.bind.annotation.*;
 
 import javax.validation.Valid;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
+import java.util.*;
+import java.util.stream.Collectors;
 
 /**
  * 控制器
@@ -67,14 +80,16 @@ public class FixedFlowController extends BladeController {
 
     private final JdbcTemplate jdbcTemplate;
 
+    private final ProjectClient projectClient;
+
+    private final TaskServiceImpl taskServiceImpl;
     /**
      * 获取系统所有角色划分
      */
     @GetMapping("/queryAllRoleList")
     @ApiOperationSupport(order = 9)
     @ApiOperation(value = "获取系统所有角色划分")
-    public R<List<RoleSignPfxUserVO>> queryAllRoleList(@RequestParam String contractId) {
-        RoleSignPfxUserVO1 vo1 = new RoleSignPfxUserVO1();
+    public R<List<RoleSignPfxUserVO>> queryAllRoleList(@RequestParam String contractId, @RequestParam(required = false, defaultValue = "0") Integer  type) {
         //获取当前系统配置的角色划分
         List<RoleVO> roleVOS = this.sysClient.search().getData();
         //获取项目人员
@@ -95,6 +110,15 @@ public class FixedFlowController extends BladeController {
         //返回结果
         List<RoleSignPfxUserVO> result = new ArrayList<>();
         for (RoleVO vo : roleVOS) {
+            if (type != null && type == 1) {
+                // 除“超级管理员”外,其余只展示“业主方”、“监理方”、“施工方”。“超级管理员”只有用户角色为“超级管理员”时才展示。其余角色均不展示;
+                if (vo.getRoleName() == null || (!vo.getRoleName().contains("管理员") && !vo.getRoleName().contains("业主方") && !vo.getRoleName().contains("施工方") && !vo.getRoleName().contains("监理方"))) {
+                    continue;
+                }
+                if (!"administrator".equals(AuthUtil.getUserRole()) && vo.getRoleName() != null && "administrator".equals(vo.getRoleAlias())) {
+                    continue;
+                }
+            }
             //设置实体
             RoleSignPfxUserVO pfxUserVo = new RoleSignPfxUserVO();
             pfxUserVo.setRoleId(vo.getId());
@@ -129,6 +153,9 @@ public class FixedFlowController extends BladeController {
                         }
                     }
                     //设置子集
+                    if (childPfxUserVo.getSignPfxFileList() ==  null || childPfxUserVo.getSignPfxFileList().isEmpty()) {
+                        continue;
+                    }
                     pfxUserVo.getChildRoleList().add(childPfxUserVo);
                     pfxUserVo.getSignPfxFileList().addAll(childPfxUserVo.getSignPfxFileList());
                 }
@@ -174,7 +201,28 @@ public class FixedFlowController extends BladeController {
         if (vo.getCurrent() == null || vo.getSize() == null) {
             return R.data(-1, null, "缺少size或current参数");
         }
-        return R.data(this.fixedFlowService.selectFixedFlowPage(vo));
+        IPage<FixedFlowVO> page = this.fixedFlowService.selectFixedFlowPage(vo);
+        List<FixedFlowVO> records = page.getRecords();
+        if (records != null && !records.isEmpty()) {
+            Map<Boolean, List<FixedFlowVO>> groupMap = records.stream().collect(Collectors.groupingBy(record -> record.getFixedFlowName() != null && record.getFixedFlowName().contains("_") && record.getSort() == null));
+            List<FixedFlowVO> copyFixedFlowVOS = groupMap.get(true);
+            List<FixedFlowVO> fixedFlowVOS = groupMap.get(false);
+            if (copyFixedFlowVOS ==  null || copyFixedFlowVOS.isEmpty() || fixedFlowVOS ==  null || fixedFlowVOS.isEmpty()) {
+                return R.data(page);
+            }
+            Map<String, List<FixedFlowVO>> nameMap = copyFixedFlowVOS.stream().collect(Collectors.groupingBy(record -> record.getFixedFlowName().split("_")[0]));
+            List<FixedFlowVO> newData = new ArrayList<>();
+            for (FixedFlowVO flowVO : fixedFlowVOS) {
+                newData.add(flowVO);
+                List<FixedFlowVO> flowVOS = nameMap.get(flowVO.getFixedFlowName());
+                if (flowVOS != null && !flowVOS.isEmpty()) {
+                    flowVOS.sort(Comparator.comparing(FixedFlow::getFixedFlowName));
+                    newData.addAll(flowVOS);
+                }
+            }
+            page.setRecords(newData);
+        }
+        return R.data(page);
     }
 
     /**
@@ -282,5 +330,442 @@ public class FixedFlowController extends BladeController {
         return R.status(false);
     }
 
+    /**
+     * 复制
+     */
+    @PostMapping("/copy")
+    @ApiOperationSupport(order = 6)
+    @ApiOperation(value = "复制", notes = "传入fixedFlow id")
+    @Transactional(rollbackFor = Exception.class)
+    public R<String> copy(String ids) {
+        if (StringUtils.isBlank(ids)) {
+            return R.fail("请选择要复制的流程");
+        }
+        List<Long> idList = Func.toLongList(ids);
+        List<FixedFlow> fixedFlowList = this.fixedFlowService.listByIds(idList);
+        if (fixedFlowList.isEmpty()) {
+            return R.fail("选择的流程不存在");
+        }
+        List<FixedFlowLink> fixedFlowLinkList = this.fixedFlowLinkService.list(Wrappers.<FixedFlowLink>lambdaQuery().in(FixedFlowLink::getFixedFlowId, idList));
+        Map<Long, List<FixedFlowLink>> linkMap = fixedFlowLinkList.stream().collect(Collectors.groupingBy(FixedFlowLink::getFixedFlowId));
+        List<FixedFlowLink> newFixedFolwLinkList = new ArrayList<>();
+        Map<String, Long> nameCountMap = new HashMap<>();
+        StringBuilder sb = new StringBuilder();
+        fixedFlowList.forEach(fixedFlow -> {
+            //生成主表主键
+            long fixedFlowId = SnowFlakeUtil.getId();
+            sb.append(fixedFlowId).append( ",");
+            List<FixedFlowLink> sourceFixedFolwLinkList = linkMap.get(fixedFlow.getId());
+            if (sourceFixedFolwLinkList != null && !sourceFixedFolwLinkList.isEmpty()) {
+                for (FixedFlowLink fixedFlowLink : sourceFixedFolwLinkList) {
+                    FixedFlowLink newLink = new FixedFlowLink();
+                    BeanUtils.copyProperties(fixedFlowLink, newLink);
+                    newLink.setId(SnowFlakeUtil.getId());
+                    newLink.setFixedFlowId(fixedFlowId);
+                    newLink.setCreateUser(AuthUtil.getUserId());
+                    newLink.setCreateTime(new Date());
+                    newFixedFolwLinkList.add(newLink);
+                }
+            }
+            Long number = nameCountMap.get(fixedFlow.getFixedFlowName());
+            if (number == null) {
+                List<FixedFlow> list = this.fixedFlowService.list(Wrappers.<FixedFlow>lambdaQuery().select(FixedFlow::getFixedFlowName).likeRight(FixedFlow::getFixedFlowName, fixedFlow.getFixedFlowName())
+                        .eq(FixedFlow::getContractId, fixedFlow.getContractId()).ne(FixedFlow::getId, fixedFlow.getId()));
+                if (list.isEmpty()) {
+                    number = 0L;
+                } else {
+                    int length = fixedFlow.getFixedFlowName().split("_").length;
+                    number = list.stream().filter(item -> item.getFixedFlowName().split("_").length == length + 1).count();
+                }
+            }
+            nameCountMap.put(fixedFlow.getFixedFlowName(), number + 1);
+            fixedFlow.setId(fixedFlowId);
+            fixedFlow.setFixedFlowName(fixedFlow.getFixedFlowName() + "_" + (number + 1));
+            fixedFlow.setCreateTime(new Date());
+            fixedFlow.setCreateDept(fixedFlow.getId());
+            fixedFlow.setUpdateTime(new Date());
+            fixedFlow.setCreateUser(AuthUtil.getUserId());
+        });
+        boolean flow = this.fixedFlowService.saveBatch(fixedFlowList);
+        if (flow && !newFixedFolwLinkList.isEmpty()) {
+            flow = this.fixedFlowLinkService.saveBatch(newFixedFolwLinkList);
+        }
+        if (flow) {
+            return R.data(sb.deleteCharAt(sb.length() - 1).toString());
+        }
+        return R.status(false);
+    }
+
+    @PostMapping("/saveFixedFlow")
+    @ApiOperationSupport(order = 7)
+    @ApiOperation(value = "新增任务流程", notes = "传入dto")
+    public R<Object> saveFixedFlow(@RequestBody SaveFixedFlowDTO dto) {
+        if (ObjectUtil.isEmpty(dto.getFixedBranchList())) {
+            return R.fail("请选择任务流程人员");
+        }
+        if (ObjectUtil.isNotEmpty(dto.getFixedName()) && ObjectUtil.isNotEmpty(dto.getProjectId()) && ObjectUtil.isNotEmpty(dto.getContractId())) {
+            ProjectInfo projectInfo = projectClient.getById(dto.getProjectId() + "");
+            if (projectInfo == null) {
+                return R.fail("暂未找到项目信息,请稍后再试");
+            }
+            List<String> userIds = dto.getFixedBranchList().stream().map(SaveFixedFlowDTO.FixedBranch::getUserIds).collect(Collectors.toList());
+            List<User> users = jdbcTemplate.query("select id,name,acc_code,real_name from blade_user where is_deleted = 0 and id in (" + StringUtils.join(userIds, ",") + ")", new BeanPropertyRowMapper<>(User.class));
+            Map<Long, User> userMap = users.stream().collect(Collectors.toMap(User::getId, item -> item));
+            if (ObjectUtil.isEmpty( users)) {
+                return R.fail("请选择任务流程人员");
+            }
+            if (Objects.equals(projectInfo.getRemarkType(), 1)) {
+                //安心签,校验证书 检查签字证书信息
+                Set<String> notCertificateUserInfoSet = new HashSet<>();
+                //获取用户的证书信息
+                String ids = users.stream().map(user -> user.getId() + "").collect(Collectors.joining(","));
+                List<SignPfxFile> signPfxFiles = jdbcTemplate.query("select * from m_sign_pfx_file where is_register = 1 and certificate_user_id in ( " + ids + " )", new BeanPropertyRowMapper<>(SignPfxFile.class));
+                Map<String, List<SignPfxFile>> collect = signPfxFiles.stream().collect(Collectors.groupingBy(signPfxFile -> signPfxFile.getCertificateUserId() + ""));
+                for (String userId : userIds) {
+                    String[] split = userId.split(",");
+                    for (String s : split) {
+                        if (StringUtils.isNumeric( s)) {
+                            List<SignPfxFile> userPfxList = collect.get(s);
+                            if (userPfxList == null || userPfxList.isEmpty()) {
+                                notCertificateUserInfoSet.add(s);
+                            }
+                        }
+                    }
+                }
+                if (!notCertificateUserInfoSet.isEmpty()) {
+                    List<String> names = new ArrayList<>();
+                    for (String userId : notCertificateUserInfoSet) {
+                        User user = userMap.get(Long.parseLong(userId));
+                        if (user != null && user.getName() != null && !user.getName().isEmpty()) {
+                            names.add(user.getName());
+                        }
+                    }
+                    throw new ServiceException("未获取到用户【" + StringUtils.join(names, "、") + "】的签字证书信息");
+                }
+            } else {
+                // 东方中讯,校验用户 accCode
+                List<String> names = new ArrayList<>();
+                for (User user : users) {
+                    if (user.getAccCode() == null || user.getAccCode().isEmpty() || user.getAccCode().equals("null")) {
+                        names.add(user.getName());
+                    }
+                }
+                if (!names.isEmpty()) {
+                    throw new ServiceException("未获取到用户【" + StringUtils.join(names, "、") + "】的签字证书信息");
+                }
+            }
+            Long fixedFlowId = SnowFlakeUtil.getId();
+            FixedFlow fixedFlow = new FixedFlow();
+            fixedFlow.setId(fixedFlowId);
+            fixedFlow.setFixedFlowName(dto.getFixedName());
+            fixedFlow.setProjectId(dto.getProjectId());
+            fixedFlow.setContractId(dto.getContractId());
+            fixedFlow.setStatus(1);
+            fixedFlow.setIsMeter(0);
+            fixedFlow.setSort(0);
+            fixedFlow.setCreateTime(new Date());
+            boolean save = fixedFlowService.save(fixedFlow);
+            if (save) {
+                int userSort = 0;
+                for (int i = 0; i < dto.getFixedBranchList().size(); i++) {
+                    SaveFixedFlowDTO.FixedBranch fixedBranch = dto.getFixedBranchList().get(i);
+                    if(i>0){
+                        userSort += Func.toLongList(dto.getFixedBranchList().get(i-1).getUserIds()).size();
+                    }
+                    List<FixedFlowLink> saveList = new ArrayList<>();
+                    if (fixedBranch.getUserIds() ==  null) {
+                        continue;
+                    }
+                    for (String userId : fixedBranch.getUserIds().split(",")) {
+                        User user = userMap.get(Long.parseLong(userId));
+                        if (user == null) {
+                            continue;
+                        }
+                        FixedFlowLink fixedFlowLink = new FixedFlowLink();
+                        fixedFlowLink.setFixedFlowId(fixedFlowId);
+                        fixedFlowLink.setFixedFlowLink(fixedBranch.getName() == null ? dto.getFixedName() : fixedBranch.getName());
+                        fixedFlowLink.setFixedFlowLinkType(projectInfo.getApprovalType());
+                        fixedFlowLink.setFixedFlowLinkUser(Long.parseLong(userId));
+                        fixedFlowLink.setFixedFlowLinkUserName(user.getRealName());
+                        fixedFlowLink.setFixedFlowLinkSort(i+1);
+                        fixedFlowLink.setProjectId(dto.getProjectId());
+                        fixedFlowLink.setContractId(dto.getContractId());
+                        fixedFlowLink.setFixedFlowBranchSort(userSort+=1);
+                        fixedFlowLink.setFlowTaskType(fixedBranch.getFlowTaskType());
+                        saveList.add(fixedFlowLink);
+                    }
+                    if (!saveList.isEmpty()) {
+                        fixedFlowLinkService.saveBatch(saveList);
+                    }
+                }
+                return R.success("操作成功");
+            }
+        }
+        return R.fail("操作失败");
+    }
+
+    /**
+     * 自定义分页
+     */
+    @GetMapping("/getFixedFlowPage")
+    @ApiOperationSupport(order = 2)
+    @ApiOperation(value = "分页", notes = "传入fixedFlow")
+    public R<Page<FixedFlowVO>> getFixedFlowPage(PageFixedFlowDTO dto) {
+        if (dto.getCurrent() == null || dto.getSize() == null) {
+            return R.data(-1, null, "缺少size或current参数");
+        }
+
+        Page<FixedFlow> page = new Page<>(dto.getCurrent(), dto.getSize());
+        IPage<FixedFlow> fixedFlowsPage = fixedFlowService.getBaseMapper().selectPage(page,
+                Wrappers.<FixedFlow>lambdaQuery()
+                        .eq(FixedFlow::getContractId, dto.getContractId())
+                        .eq(FixedFlow::getProjectId, dto.getProjectId()).last(" and (is_meter is null or is_meter != 1) order by sort, fixed_flow_name, create_time desc"));
+        List<FixedFlow> fixedFlows = fixedFlowsPage.getRecords();
+        List<Long> collect = fixedFlows.stream().map(FixedFlow::getId).collect(Collectors.toList());
+        if (!collect.isEmpty()) {
+            List<FixedFlowLink> fixedFlowLinkList = fixedFlowLinkService.getBaseMapper().selectList(
+                    Wrappers.<FixedFlowLink>lambdaQuery()
+                            .in(FixedFlowLink::getFixedFlowId, collect)
+                            .orderByAsc(FixedFlowLink::getFixedFlowBranchSort)
+                            .orderByAsc(FixedFlowLink::getFixedFlowLinkSort)
+            );
+            Map<Long, List<FixedFlowLink>> group = fixedFlowLinkList.stream()
+                    .collect(Collectors.groupingBy(FixedFlowLink::getFixedFlowId,
+                            LinkedHashMap::new,
+                            Collectors.toList()));
+            //获取当前任务中所有的流程,并且去重,如果该流程已经存在,那么则不允许编辑和删除
+            List<Long> ids = taskServiceImpl.list(new LambdaQueryWrapper<Task>()
+                    .select(Task::getFixedFlowId)
+                    .eq(Task::getContractId, dto.getContractId())
+                    .isNotNull(Task::getFixedFlowId)
+                    .groupBy(Task::getFixedFlowId)).stream().map(Task::getFixedFlowId).collect(Collectors.toList());
+            List<FixedFlowVO> fixedFlowVOList = new ArrayList<>();
+            for (FixedFlow fixedFlow : fixedFlows) {
+                List<FixedFlowLink> one = group.getOrDefault(fixedFlow.getId(), null);
+                FixedFlowVO vo = new FixedFlowVO();
+                BeanUtil.copyProperties(fixedFlow, vo);
+                fixedFlowVOList.add(vo);
+                vo.setFixedFlowLinkList( one);
+                if (one != null) {
+                    /** 上面方法会去除同名流程*/
+                    for (FixedFlowLink link : one) {
+                        if (link.getFixedFlowBranchSort() == null ) {
+                            link.setFixedFlowBranchSort(link.getFixedFlowLinkSort());
+                            link.setFixedFlowLinkSort(1);
+                        }
+                        if (link.getFixedFlowLink() == null || link.getFixedFlowLink().isEmpty()) {
+                            link.setFixedFlowLink(fixedFlow.getFixedFlowName());
+                        }
+                    }
+                    List<String> names = one.stream().filter(l->l.getFixedFlowLinkSort() != null).collect(Collectors.groupingBy(
+                            FixedFlowLink::getFixedFlowLinkSort,
+                            Collectors.collectingAndThen(
+                                    Collectors.toList(),
+                                    l -> l.isEmpty() ? null : l.get(0)
+                            )
+                    )).values().stream().map(FixedFlowLink::getFixedFlowLink).collect(Collectors.toList());
+                    vo.setDeletedIs(!ids.contains(fixedFlow.getId()));
+                    vo.setLinkUserJoinString(StringUtils.join(names, ","));
+                }
+            }
+            Page<FixedFlowVO> resultMap = new Page<>();
+            resultMap.setCurrent(fixedFlowsPage.getCurrent());
+            resultMap.setSize(fixedFlowsPage.getSize());
+            resultMap.setTotal(fixedFlowsPage.getTotal());
+            resultMap.setRecords(fixedFlowVOList);
+//            Map<Boolean, List<FixedFlowVO>> groupMap = fixedFlowVOList.stream().collect(Collectors.groupingBy(record -> record.getFixedFlowName() != null && record.getFixedFlowName().contains("_") && record.getSort() == null));
+//            List<FixedFlowVO> copyFixedFlowVOS = groupMap.get(true);
+//            List<FixedFlowVO> fixedFlowVOS = groupMap.get(false);
+//            if (copyFixedFlowVOS ==  null || copyFixedFlowVOS.isEmpty() || fixedFlowVOS ==  null || fixedFlowVOS.isEmpty()) {
+//                return R.data(resultMap);
+//            }
+//            Map<String, List<FixedFlowVO>> nameMap = copyFixedFlowVOS.stream().collect(Collectors.groupingBy(record -> record.getFixedFlowName().split("_")[0]));
+//            List<FixedFlowVO> newData = new ArrayList<>(fixedFlowVOList);
+//            for (FixedFlowVO flowVO : fixedFlowVOS) {
+////                newData.add(flowVO);
+//                List<FixedFlowVO> flowVOS = nameMap.get(flowVO.getFixedFlowName());
+//                if (flowVOS != null && !flowVOS.isEmpty()) {
+//                    flowVOS.sort(Comparator.comparing(FixedFlow::getFixedFlowName));
+//                    newData.addAll(flowVOS);
+//                }
+//            }
+//            resultMap.setRecords(newData);
+            return R.data(resultMap);
+        }
+        return R.fail("暂无数据");
+    }
+    @GetMapping("/getFixedFlow")
+    @ApiOperationSupport(order = 25)
+    @ApiOperation(value = "获取预设流程信息", notes = "传入预设流程id")
+    public R<org.springblade.meter.vo.FixedFlowVO> getFixedFlow(@RequestParam String id) {
+        FixedFlow fixedFlow = jdbcTemplate.query("SELECT * FROM u_fixed_flow WHERE is_deleted = 0 AND id = ?", new Object[]{id}, new BeanPropertyRowMapper<>(FixedFlow.class)).stream().findAny().orElse(null);
+        if (fixedFlow != null) {
+            ProjectInfo projectInfo = projectClient.getById(fixedFlow.getProjectId() + "");
+            List<FixedFlowLink> fixedFlowLinkList = jdbcTemplate.query("SELECT * FROM u_fixed_flow_link WHERE is_deleted = 0 AND fixed_flow_id = ? ORDER BY fixed_flow_branch_sort,fixed_flow_link_sort", new Object[]{fixedFlow.getId()}, new BeanPropertyRowMapper<>(FixedFlowLink.class));
+            if (!fixedFlowLinkList.isEmpty()) {
+                for (FixedFlowLink link : fixedFlowLinkList) {
+                    if (link.getFixedFlowBranchSort() == null ) {
+                        link.setFixedFlowBranchSort(link.getFixedFlowLinkSort());
+                        link.setFixedFlowLinkSort(1);
+                    }
+                    if (link.getFixedFlowLink() == null || link.getFixedFlowLink().isEmpty()) {
+                        link.setFixedFlowLink(fixedFlow.getFixedFlowName());
+                    }
+                    if (link.getFixedFlowLinkType() == null) {
+                        link.setFixedFlowLinkType(projectInfo == null ? (link.getFlowTaskType() == null ? 2 : link.getFlowTaskType()) : projectInfo.getApprovalType());
+                    }
+                }
+                Map<String, List<FixedFlowLink>> group = fixedFlowLinkList.stream().collect(Collectors.groupingBy(
+                        obj -> obj.getFixedFlowLink() + "@@@" + obj.getFixedFlowLinkType() + "@@@"+obj.getFlowTaskType() + "@@@"+obj.getFixedFlowLinkSort(),
+                        LinkedHashMap::new,
+                        Collectors.toList())
+                );
+
+                org.springblade.meter.vo.FixedFlowVO vo = new org.springblade.meter.vo.FixedFlowVO();
+                vo.setFixedFlowId(fixedFlow.getId());
+                vo.setFixedFlowName(fixedFlow.getFixedFlowName());
+
+                List<org.springblade.meter.vo.FixedFlowVO.FixedBranchVO> fixedBranchVOList = new LinkedList<>();
+                for (Map.Entry<String, List<FixedFlowLink>> listEntry : group.entrySet()) {
+
+                    String nameAndType = listEntry.getKey();
+                    String name = nameAndType.split("@@@")[0];
+                    String type = nameAndType.split("@@@")[1];
+                    String flowTaskType = nameAndType.split("@@@")[2];
+
+                    org.springblade.meter.vo.FixedFlowVO.FixedBranchVO fixedBranchVO = new org.springblade.meter.vo.FixedFlowVO.FixedBranchVO();
+                    fixedBranchVO.setName(name);
+                    fixedBranchVO.setType(Integer.parseInt(type));
+                    fixedBranchVO.setFlowTaskType(Integer.valueOf(flowTaskType));
+
+                    List<org.springblade.meter.vo.FixedFlowVO.FixedBranchVO.User> userListResult = new LinkedList<>();
+                    List<FixedFlowLink> userList = listEntry.getValue();
+                    for (FixedFlowLink fixedFlowLink : userList) {
+                        org.springblade.meter.vo.FixedFlowVO.FixedBranchVO.User user = new org.springblade.meter.vo.FixedFlowVO.FixedBranchVO.User();
+                        user.setUserId(fixedFlowLink.getFixedFlowLinkUser());
+                        user.setUserName(fixedFlowLink.getFixedFlowLinkUserName());
+                        user.setSort(ObjectUtil.isNotEmpty(fixedFlowLink.getFixedFlowLinkSort()) ? fixedFlowLink.getFixedFlowLinkSort() : null);
+                        userListResult.add(user);
+                    }
+
+                    fixedBranchVO.setUserList(userListResult);
+                    fixedBranchVO.setUserIds(userListResult.stream().map(l->l.getUserId()+"").collect(Collectors.joining(",")));
+                    fixedBranchVOList.add(fixedBranchVO);
+                }
+
+                vo.setFixedBranchVOList(fixedBranchVOList);
+                return R.data(vo);
+            }
+        }
+        return R.data(null);
+    }
+
+    @PostMapping("/updateFixedFlow")
+    @ApiOperationSupport(order = 26)
+    @ApiOperation(value = "修改预设流程", notes = "传入dto")
+    @Transactional(isolation = Isolation.READ_COMMITTED)
+    public R<Object> updateFixedFlow(@RequestBody UpdateFixedFlowDTO dto) {
+        if (ObjectUtil.isEmpty(dto.getFixedBranchList()) || dto.getFixedBranchList().isEmpty()) {
+            return R.fail("请选择任务流程人员");
+        }
+        //校验是否被使用过
+        List<Task> tasks = jdbcTemplate.query("SELECT * FROM u_task WHERE contract_id = ? and is_deleted = 0 and status != 3 AND fixed_flow_id = ? ", new Object[]{dto.getContractId(), dto.getFixedFlowId()}, new BeanPropertyRowMapper<>(Task.class));
+        if (!tasks.isEmpty()) {
+            return R.fail("当前流程已经使用,不能修改");
+        }
+        if (ObjectUtil.isNotEmpty(dto.getFixedName())) {
+            ProjectInfo projectInfo = projectClient.getById(dto.getProjectId() + "");
+            if (projectInfo == null) {
+                return R.fail("暂未找到项目信息,请稍后再试");
+            }
+            /*检查签字证书信息*/
+            List<String> userIds = dto.getFixedBranchList().stream().map(UpdateFixedFlowDTO.FixedBranch::getUserIds).collect(Collectors.toList());
+            List<User> users = jdbcTemplate.query("select id,name,acc_code,real_name from blade_user where is_deleted = 0 and id in (" + StringUtils.join(userIds, ",") + ")", new BeanPropertyRowMapper<>(User.class));
+            Map<Long, User> userMap = users.stream().collect(Collectors.toMap(User::getId, item -> item));
+            if (ObjectUtil.isEmpty( users)) {
+                return R.fail("请选择任务流程人员");
+            }
+            if (Objects.equals(projectInfo.getRemarkType(), 1)) {
+                //安心签,校验证书 检查签字证书信息
+                Set<String> notCertificateUserInfoSet = new HashSet<>();
+                //获取用户的证书信息
+                String ids = users.stream().map(user -> user.getId() + "").collect(Collectors.joining(","));
+                List<SignPfxFile> signPfxFiles = jdbcTemplate.query("select * from m_sign_pfx_file where is_register = 1 and certificate_user_id in ( " + ids + " )", new BeanPropertyRowMapper<>(SignPfxFile.class));
+                Map<String, List<SignPfxFile>> collect = signPfxFiles.stream().collect(Collectors.groupingBy(signPfxFile -> signPfxFile.getCertificateUserId() + ""));
+                for (User user : users) {
+                    List<SignPfxFile> userPfxList = collect.get(user.getId() + "");
+                    if (userPfxList == null || userPfxList.isEmpty()) {
+                        notCertificateUserInfoSet.add(user.getId() + "");
+                    }
+                }
+                if (!notCertificateUserInfoSet.isEmpty()) {
+                    List<String> names = new ArrayList<>();
+                    for (String userId : notCertificateUserInfoSet) {
+                        User user = userMap.get(Long.parseLong(userId));
+                        if (user != null && user.getName() != null && !user.getName().isEmpty()) {
+                            names.add(user.getName());
+                        }
+                    }
+                    throw new ServiceException("未获取到用户【" + StringUtils.join(names, "、") + "】的签字证书信息");
+                }
+            } else {
+                // 东方中讯,校验用户 accCode
+                List<String> names = new ArrayList<>();
+                for (User user : users) {
+                    if (user.getAccCode() == null || user.getAccCode().isEmpty() || user.getAccCode().equals("null")) {
+                        names.add(user.getName());
+                    }
+                }
+                if (!names.isEmpty()) {
+                    throw new ServiceException("未获取到用户【" + StringUtils.join(names, "、") + "】的签字证书信息");
+                }
+            }
+            jdbcTemplate.update("DELETE FROM u_fixed_flow_link WHERE  fixed_flow_id = ? ", dto.getFixedFlowId());
+            int userSort = 0;
+            for (int i = 0; i < dto.getFixedBranchList().size(); i++) {
+                UpdateFixedFlowDTO.FixedBranch fixedBranch = dto.getFixedBranchList().get(i);
+                if (i > 0) {
+                    userSort += Func.toLongList(dto.getFixedBranchList().get(i - 1).getUserIds()).size();
+                }
+                if (fixedBranch.getUserIds() ==  null) {
+                    continue;
+                }
+                List<FixedFlowLink> saveList = new ArrayList<>();
+                for (String userId : fixedBranch.getUserIds().split(",")) {
+                    FixedFlowLink fixedFlowLink = new FixedFlowLink();
+                    fixedFlowLink.setFixedFlowId(dto.getFixedFlowId());
+                    fixedFlowLink.setFixedFlowLink(fixedBranch.getName());
+                    fixedFlowLink.setFixedFlowLinkType(fixedBranch.getType());
+                    fixedFlowLink.setFixedFlowLinkUser(Long.parseLong(userId));
+                    fixedFlowLink.setFixedFlowLinkUserName(userMap.get(Long.parseLong(userId)).getRealName());
+                    fixedFlowLink.setFixedFlowLinkSort(i + 1);
+                    fixedFlowLink.setProjectId(dto.getProjectId());
+                    fixedFlowLink.setContractId(dto.getContractId());
+                    fixedFlowLink.setFixedFlowBranchSort(userSort+=1);
+                    fixedFlowLink.setFlowTaskType(fixedBranch.getFlowTaskType());
+                    saveList.add(fixedFlowLink);
+                }
+                if (!saveList.isEmpty()) {
+                    fixedFlowLinkService.saveBatch(saveList);
+                }
+            }
+            fixedFlowService.update(Wrappers.<FixedFlow>lambdaUpdate().set(FixedFlow::getFixedFlowName, dto.getFixedName()).eq(FixedFlow::getId, dto.getFixedFlowId()));
+            return R.success("操作成功");
+        }
+        return R.fail("操作失败");
+    }
+
+    @PostMapping("/deleteFixedFlow")
+    @ApiOperationSupport(order = 27)
+    @ApiOperation(value = "刪除预设流程", notes = "传入预设流程id")
+    public R<Object> deleteFixedFlow(@RequestParam String id) {
+        List<Task> tasks = jdbcTemplate.query("SELECT * FROM u_task WHERE is_deleted = 0 and status != 3 AND fixed_flow_id = ? ", new Object[]{id}, new BeanPropertyRowMapper<>(Task.class));
+        if (tasks.size() > 0) {
+            return R.fail("当前流程已经使用,不能删除");
+        }
+        jdbcTemplate.update("DELETE FROM u_fixed_flow WHERE id = ?", new Object[]{id});
+        jdbcTemplate.update("DELETE FROM u_fixed_flow_link WHERE fixed_flow_id = ?", new Object[]{id});
+        return R.success("操作成功");
+    }
 
 }

+ 129 - 5
blade-service/blade-business/src/main/java/org/springblade/business/controller/TaskController.java

@@ -1257,6 +1257,36 @@ public class TaskController extends BladeController {
         if (task == null || (task.getStatus() != null && task.getStatus() == 3)) {
             return R.fail("任务已被撤回或者驳回");
         }
+        //校验当前项目是否为垂直审批
+        if (ObjectUtil.isEmpty(task.getProjectId())) {
+            throw new ServiceException("未获取到任务【" + task.getTaskName() + "】对应的项目信息");
+        }
+        ProjectInfo projectInfo = jdbcTemplate.query("select approval_type from m_project_info where id = " + task.getProjectId(), new BeanPropertyRowMapper<>(ProjectInfo.class)).stream().findAny().orElse(null);
+        //如果是垂直审批,那么检查当前用户是否符合当前顺序
+        if (projectInfo != null && projectInfo.getApprovalType() != null && new Integer(1).equals(projectInfo.getApprovalType())) {
+            List<TaskParallel> taskParallelList = jdbcTemplate.query("select id,process_instance_id,task_user,task_user_name,status from u_task_parallel where process_instance_id ='" + task.getProcessInstanceId() + "'", new BeanPropertyRowMapper<>(TaskParallel.class));
+            taskParallelList.sort(Comparator.comparing(TaskParallel::getId)); //根据id排序
+            Map<String, List<TaskParallel>> taskParallelGroup = taskParallelList.stream().collect(Collectors.groupingBy(TaskParallel::getProcessInstanceId));
+            for (Map.Entry<String, List<TaskParallel>> taskObj : taskParallelGroup.entrySet()) {
+                //获取当前审批人前面的审批人信息
+                List<TaskParallel> frontTaskUser = new LinkedList<>();
+                for (TaskParallel taskParallel : taskObj.getValue()) {
+                    Long userId = SecureUtil.getUserId();
+                    if (!userId.toString().equals(taskParallel.getTaskUser())) {
+                        frontTaskUser.add(taskParallel);
+                    } else {
+                        //如果是当前的审批人,那么直接跳过
+                        break;
+                    }
+                }
+                List<TaskParallel> resultTaskStatus = frontTaskUser.stream().filter(f -> !f.getStatus().equals(2)).collect(Collectors.toList());
+                if (!resultTaskStatus.isEmpty()) {
+                    String names = resultTaskStatus.stream().map(TaskParallel::getTaskUserName).collect(Collectors.joining("、"));
+                    throw new ServiceException("当前任务【" + task.getTaskName() + "】还有【" + names + "】未完成审批,请您稍后再试");
+                }
+            }
+        }
+        //正常流程(平行签直接执行,垂直签会校验完再执行)
         this.taskService.batchCompleteApprovalTask(taskApprovalVOS);
         if (!taskApprovalVO.isPass()) {
             JSONObject json = new JSONObject();
@@ -1644,8 +1674,12 @@ public class TaskController extends BladeController {
         }
         // 3.2 任务状态过滤
         if (ObjectUtil.isNotEmpty(dto.getStatusValue())) {
-            sqlString.append(" AND status = ?");
-            params.add(dto.getStatusValue());
+            if(dto.getStatusValue() .equals(4) ){//----先查询出所有待审批的 然后根据条件进行过滤出任务已经到当前登陆人的任务为可审批
+                sqlString.append(" AND status = 1");
+            }else {
+                sqlString.append(" AND status = ?");
+                params.add(dto.getStatusValue());
+            }
         }
         // 3.3 合同段过滤(区分合同类型)
         if (contractInfo != null && contractInfo.getContractType().equals(1)) {
@@ -1775,7 +1809,7 @@ public class TaskController extends BladeController {
         if (CollectionUtil.isNotEmpty(processInstanceIds)) {
             String idsStr = processInstanceIds.stream().map(id -> "'" + id + "'").collect(Collectors.joining(","));
             taskParallelGroupMap = jdbcTemplate.query(
-                    "select process_instance_id,task_user,task_user_name,e_visa_status,e_visa_content,parallel_process_instance_id,status from u_task_parallel where process_instance_id in(" + idsStr + ") order by id",
+                    "select process_instance_id,task_user,task_user_name,e_visa_status,e_visa_content,parallel_process_instance_id,status,sort from u_task_parallel where process_instance_id in(" + idsStr + ") order by id",
                     new BeanPropertyRowMapper<>(TaskParallel.class)
             ).stream().collect(Collectors.groupingBy(TaskParallel::getProcessInstanceId));
         }
@@ -1798,11 +1832,37 @@ public class TaskController extends BladeController {
         }
 
         // 6. 对原始数据执行业务过滤(核心:垂直签待办任务可见性判断)
+        //根据条件过滤出可审批的数据(流程审批-非自定义流程)   flowid为0的是自定义审批的流程
+        Map<Long, List<Task>> flowIdMaps = allResultList.stream().filter(task->!"0".equals(task.getFixedFlowId().toString())).collect(Collectors.groupingBy(Task::getFixedFlowId));
+        Map<Long, List<FixedFlowLink>> fixedsMap;
+        if(ObjectUtil.isNotEmpty(flowIdMaps)){
+            String join = StringUtils.join(flowIdMaps.keySet(), ",");
+            //结果集所有数据
+            String sql = "select fixed_flow_id ,fixed_flow_branch_sort,fixed_flow_link_type,fixed_flow_link_sort from u_fixed_flow_link where  is_deleted = 0  and  fixed_flow_id in ( "+join+")";
+            List<FixedFlowLink> fixedFlowLinks = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(FixedFlowLink.class));
+            fixedsMap = fixedFlowLinks.stream().collect(Collectors.groupingBy(FixedFlowLink::getFixedFlowId));
+        } else {
+            fixedsMap = new HashMap<>();
+        }
         Map<String, List<TaskParallel>> finalTaskParallelGroupMap = taskParallelGroupMap;
         List<Task> filteredList = allResultList.stream()
                 .filter(task -> {
+                    // 获取任务流程信息,判断是否是垂直签
+                    if (task.getFixedFlowId() != null && fixedsMap.containsKey(task.getFixedFlowId())) {
+                        // 预设流程
+                        List<FixedFlowLink> fixedFlowLinks = fixedsMap.get(task.getFixedFlowId());
+                        List<FixedFlowLink> linkList = fixedFlowLinks.stream().filter(link -> link.getFixedFlowLinkType() == null).collect(Collectors.toList());
+                        if (linkList.isEmpty()) {
+                            // 获取垂直流程
+                            List<FixedFlowLink> collect = fixedFlowLinks.stream().filter(link -> link.getFixedFlowLinkType() != null && link.getFixedFlowLinkType() == 1).collect(Collectors.toList());
+                            if (!collect.isEmpty()) {
+                                // 走垂直审批逻辑
+                                return handleTaskParallel(fixedFlowLinks, finalTaskParallelGroupMap.get(task.getProcessInstanceId()), SecureUtil.getUserId());
+                            }
+                        }
+                    }
                     // 仅处理垂直签+待办页面的过滤逻辑
-                    if (projectInfo != null && projectInfo.getApprovalType() == 1 && dto.getSelectedType() == 1) {
+                    if (((projectInfo != null && projectInfo.getApprovalType() == 1)) && dto.getSelectedType() == 1) {
                         List<TaskParallel> parallelList = finalTaskParallelGroupMap.get(task.getProcessInstanceId());
                         if (CollectionUtil.isEmpty(parallelList)) {
                             return false;
@@ -1838,7 +1898,6 @@ public class TaskController extends BladeController {
         if (startIndex < endIndex && CollectionUtil.isNotEmpty(filteredList)) {
             currentPageTaskList = filteredList.subList(startIndex, endIndex);
         }
-
         // 8. 转换当前页数据为VO(复用原逻辑,补充已废除任务日志信息)
         Map<String, List<TaskParallel>> finalTaskParallelGroupMap1 = taskParallelGroupMap;
         Map<String, List<OperationLog>> finalOperationLogMap = operationLogMap;
@@ -1949,6 +2008,71 @@ public class TaskController extends BladeController {
         return R.data(page);
     }
 
+    private boolean handleTaskParallel(List<FixedFlowLink> fixedFlowLinks, List<TaskParallel> taskParallels, Long userId) {
+        taskParallels.sort(Comparator.comparing(TaskParallel::getSort, Comparator.nullsLast(Comparator.naturalOrder())));
+        for (int i = 0; i < taskParallels.size(); i++) {
+            TaskParallel parallel = taskParallels.get(i);
+            parallel.setSort(i);
+        }
+        fixedFlowLinks.sort(Comparator.comparing(FixedFlowLink::getFixedFlowBranchSort, Comparator.nullsLast(Comparator.naturalOrder())));
+        for (int i = 0; i < fixedFlowLinks.size(); i++) {
+            FixedFlowLink link = fixedFlowLinks.get(i);
+            link.setFixedFlowBranchSort(i);
+        }
+        //查出当前电签到的节点sort
+        Optional<Integer> sortDq = taskParallels.stream()
+                .filter(t -> t.getStatus() == 1)
+                .min(Comparator.comparing(TaskParallel::getSort))
+                .map(TaskParallel::getSort);
+        //获取当前用户的sort值
+        List<Integer> userSort = taskParallels.stream()
+                .filter(t -> t.getTaskUser().equals(userId.toString()))
+                .sorted(Comparator.comparing(TaskParallel::getSort))
+                .map(TaskParallel::getSort).collect(Collectors.toList());
+        Integer dqSort = sortDq.orElse(null);
+        if(ObjectUtil.isNotEmpty(dqSort)){
+            List<Integer> list1 = userSort.stream().filter(a -> dqSort.compareTo(a) <= 0).collect(Collectors.toList());
+            if(ObjectUtil.isEmpty(list1)){
+                //当前用户已经签字过
+                return false;
+            }else {
+                //筛选出最近的一条没有电签的当前用户的sort
+                Integer userMinSort = Collections.min(list1);
+                if(userMinSort.toString().equals(dqSort.toString())){
+                    //当前用户就是下一个电签用户 可审批 放行
+                    return true;
+                }
+                FixedFlowLink dqFlowLink = null;
+                FixedFlowLink userFlowLink = null;
+                for (FixedFlowLink fixedFlowLink : fixedFlowLinks) {
+                    if (fixedFlowLink.getFixedFlowBranchSort() != null && fixedFlowLink.getFixedFlowBranchSort() >= dqSort && dqFlowLink == null) {
+                        dqFlowLink = fixedFlowLink;
+                    }
+                    if (fixedFlowLink.getFixedFlowBranchSort() != null && fixedFlowLink.getFixedFlowBranchSort() >= userMinSort && userFlowLink == null) {
+                        userFlowLink = fixedFlowLink;
+                    }
+                    if (dqFlowLink != null && userFlowLink != null) {
+                        break;
+                    }
+                }
+                if (dqFlowLink == null || userFlowLink == null) {
+                    return false;
+                }
+                if(Objects.equals(dqFlowLink.getFixedFlowLinkSort(), userFlowLink.getFixedFlowLinkSort())){
+                    //在同一个小流程里面去判断是否垂直还是水平
+                    //平行 通过
+                    return dqFlowLink.getFixedFlowLinkType() == 2;
+                }else {
+                    //不在一个小流程 不可审批
+                    return  false;
+                }
+            }
+        }else {
+            //全部签完了 肯定不是可审批
+            return false;
+        }
+    }
+
     @PostMapping("/pageset")
     @ApiOperationSupport(order = 1)
     @ApiOperation(value = "电签显示等待 batch中没有 用于跑电签数据的接口 手动调用", notes = "传入BusinessTaskDTO")

+ 5 - 41
blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TaskServiceImpl.java

@@ -1490,26 +1490,8 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
             vo.setStartTime(DateUtil.format(nowTime, "yyyy-MM-dd"));
             vo.setEndTime(DateUtil.format(DateUtils.addDays(nowTime, vo.getRestrictDay()), "yyyy-MM-dd"));
 
-//            Query query = new Query();
-//            query.setCurrent(1);
-//            query.setSize(999);
-            //获取流程
-//            List<FlowProcessVO> modeProcessVOS = this.newFlowClient.startFlowList("", query, 1);
-//            if (modeProcessVOS == null || modeProcessVOS.size() == 0) {
-//                return false;
-//            }
             //获取当中的审批流程
             String taskFlowId = SnowFlakeUtil.getId() + "";
-//            for (FlowProcessVO processVO : modeProcessVOS) {
-//                if ("approval".equals(processVO.getKey())) {
-//                    taskFlowId = processVO.getId();
-//                    break;
-//                }
-//            }
-//            //如果没有对应流程,直接返回
-//            if (StringUtils.isEmpty(taskFlowId)) {
-//                return false;
-//            }
             //获取选择的固定流程
             List<FixedFlowLink> links = new ArrayList<>();
             if (Long.valueOf("0").equals(vo.getFixedFlowId())) {
@@ -1528,33 +1510,15 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
                 }
             }
 
-            //启动主流程
-//            R<BladeFlow> result = this.flowClient.startProcessInstanceById(taskFlowId, FlowUtil.getBusinessKey(businessTable, String.valueOf(vo.getId())),
-//                    Kv.create().set(ProcessConstant.TASK_VARIABLE_CREATE_USER, AuthUtil.getUserName()).set("taskUser", TaskUtil.getTaskUser("")));
-//            if (result.isSuccess()) {
-//                log.debug("主流程已启动,流程ID:" + result.getData().getProcessInstanceId());
-//                //拼接并行的实例ID
-//                vo.setProcessInstanceId(result.getData().getProcessInstanceId());
-//            } else {
-//                throw new ServiceException("开启主流程失败");
-//            }
             vo.setProcessInstanceId(SnowFlakeUtil.getId() + "");
 
             //根据所选择的固定流程所含有的环节发起审批任务
             List<TaskParallel> taskParallelArray = new ArrayList<>();
-            for (FixedFlowLink link : links) {
-                //启动并行流程
-//                Kv variables = Kv.create()
-//                        //下一步流程审批人
-//                        .set("taskUser", TaskUtil.getTaskUser(link.getFixedFlowLinkUser().toString()));
-//                R<BladeFlow> linkResult = this.flowClient.startProcessInstanceById(taskFlowId, FlowUtil.getBusinessKey(businessTable, String.valueOf(vo.getId())), variables);
-//                if (linkResult.isSuccess()) {
-//                    log.debug("并行流程已启动,流程ID:" + linkResult.getData().getProcessInstanceId());
-//                    taskParallelArray.add(new TaskParallel(vo.getProcessInstanceId(), linkResult.getData().getProcessInstanceId(), link.getFixedFlowLinkUser().toString(), link.getFixedFlowLinkUserName()));
-//                } else {
-//                    throw new ServiceException("开启并行流程失败");
-//                }
-                taskParallelArray.add(new TaskParallel(vo.getProcessInstanceId(), SnowFlakeUtil.getId() + "", link.getFixedFlowLinkUser().toString(), link.getFixedFlowLinkUserName()));
+            for (int i = 0, linksSize = links.size(); i < linksSize; i++) {
+                FixedFlowLink link = links.get(i);
+                TaskParallel parallel = new TaskParallel(vo.getProcessInstanceId(), SnowFlakeUtil.getId() + "", link.getFixedFlowLinkUser().toString(), link.getFixedFlowLinkUserName());
+                parallel.setSort(link.getFixedFlowBranchSort() == null ? i : link.getFixedFlowBranchSort());
+                taskParallelArray.add(parallel);
             }
             //设置流程信息
             vo.setProcessDefinitionId(taskFlowId);