工作流结合业务流程设计方案

审批业务流程图如下:
在这里插入图片描述
在这里插入图片描述

**

一、 enum设计

1.DefectProcessEnum 整个流程的业务逻辑Enum

/**
 * 整个流程的业务逻辑
 */
public enum DefectProcessEnum {
    DEFECT_EDIT("DEFECT_EDIT", "缺陷编辑", 0),
    INVALID_DEFECT("INVALID_DEFECT", "无效缺陷", 1),
    DEFECT_REVIEW("DEFECT_REVIEW", "缺陷审核", 2),
    DEFECT_CONFIRM("DEFECT_CONFIRM", "缺陷确认", 3),
    VALID_DEFECT("VALID_DEFECT", "有效缺陷", 4),
    WORK_ORDER_EDIT("WORK_ORDER_EDIT", "工单编辑", 5),
    WORK_ORDER_ACTIVE("WORK_ORDER_ACTIVE", "工单生效", 6),
    JOB_TICKET_EDIT("JOB_TICKET_EDIT", "工作票编辑", 7),
    JOB_TICKET_IN_PROGRESS("JOB_TICKET_IN_PROGRESS", "工作票执行中", 8),
    JOB_TICKET_COMPLETED_RECORD_PENDING("WORK_COMPLETED_RECORD_PENDING", "工作票完成-待填写记录", 9),
    TICKET_COMPLETED_WAITING_CLOSE_ORDER("TICKET_COMPLETED_WAITING_CLOSE_ORDER", "工作票完成—待关闭工单", 10),
    WORK_ORDER_TO_BE_CLOSED("WORK_ORDER_TO_BE_CLOSED", "工单待关闭", 10),
    ORDER_COMPLETED("ORDER_COMPLETED", "工单完成", 11),
    TICKET_COMPLETED_WAITING_CLOSE_DEFECT("TICKET_COMPLETED_WAITING_CLOSE_DEFECT", "工作票完成—待关闭缺陷", 12),
    DEFECTS_TO_BE_CLOSED("DEFECTS_TO_BE_CLOSED", "缺陷待关闭", 12),
    DEFECT_COMPLETION("DEFECT_COMPLETION", "缺陷完成", 13),
    TICKET_COMPLETED("TICKET_COMPLETED", "工作票完成", 14);


  
    private String key;//JSON串中绑定的key值
      private String value;  //业务流程名称
    private Integer step;  //步骤

    DefectProcessEnum(String key, String value, Integer step) {
        this.key = key;
        this.value = value;
        this.step = step;
    }

    public static String getValue(String key) {

        for (DefectProcessEnum stateEnum : DefectProcessEnum.values()) {
            if (stateEnum.key.equals(key)) {
                return stateEnum.value;
            }
        }
        return "";
    }
    // 根据 step 获取符合条件的数据集合的方法
    public static List<DefectProcessEnum> getByStep(int step) {
        List<DefectProcessEnum> result = new ArrayList<>();
        for (DefectProcessEnum status : DefectProcessEnum.values()) {
            if (status.getStep() == step) {
                result.add(status);
            }
        }
        return result;
    }
    public String getKey() {
        return key;
    }

    public String getValue() {
        return value;
    }

    public Integer getStep() {
        return step;
    }
}

2.TaskStatusEnum 流程状态

//流程状态
    public enum TaskStatusEnum {
        COMPLETED(0, "已完成"),
        IN_PROGRESS(1, "进行中"),
        UNPROCESSED(2, "无/未处理");

        private int code;
        private String description;

        TaskStatusEnum(int code, String description) {
            this.code = code;
            this.description = description;
        }

        public int getCode() {
            return code;
        }

        public String getDescription() {
            return description;
        }

        // 如果需要的话,可以根据code获取枚举值
        public static TaskStatusEnum fromCode(int code) {
            for (TaskStatusEnum status : values()) {
                if (status.getCode() == code) {
                    return status;
                }
            }
            throw new IllegalArgumentException("Invalid code: " + code);
        }
    }

3.TaskTypeEnum 以下这个是分别在创建缺陷单和工单分别使用的json,内容结构如下

    /**
     * 两个地方可以创建流程,1,创建缺陷使用的json,2,工单创建使用的json 3.创建工作票使用的json
     */
    public enum TaskTypeEnum {
        DEFECT_JSON("缺陷JSON", "{\"CURRENT_STEP\":0,\"DEFECT_EDIT\":{\"name\":\"所有人\",\"description\":\"缺陷编辑\",\"step\":0,\"status\":0},\"INVALID_DEFECT\":{\"name\":\"--\",\"description\":\"无效缺陷\",\"step\":1,\"status\":2},\"DEFECT_REVIEW\":{\"name\":\"高级授权人\",\"description\":\"缺陷审核\",\"step\":2,\"status\":2},\"DEFECT_CONFIRM\":{\"name\":\"专业主管\",\"description\":\"缺陷确认\",\"step\":3,\"status\":2},\"VALID_DEFECT\":{\"name\":\"高级授权人\",\"description\":\"有效缺陷\",\"step\":4,\"status\":2},\"WORK_ORDER_EDIT\":{\"name\":\"高级授权人\",\"description\":\"工单编辑\",\"step\":5,\"status\":2},\"WORK_ORDER_ACTIVE\":{\"name\":\"高级授权人\",\"description\":\"工单生效\",\"step\":6,\"status\":2},\"JOB_TICKET_EDIT\":{\"name\":\"高级授权人\",\"description\":\"工作票编辑\",\"step\":7,\"status\":2},\"JOB_TICKET_IN_PROGRESS\":{\"name\":\"高级授权人\",\"description\":\"工作票执行中\",\"step\":8,\"status\":2},\"JOB_TICKET_COMPLETED_RECORD_PENDING\":{\"name\":\"干练人员\",\"description\":\"工作票完成-待填写记录\",\"step\":9,\"status\":2},\"TICKET_COMPLETED_WAITING_CLOSE_ORDER\":{\"name\":\"--\",\"description\":\"工作票完成—待关闭工单\",\"step\":10,\"status\":2},\"WORK_ORDER_TO_BE_CLOSED\":{\"name\":\"高级授权人\",\"description\":\"工单待关闭\",\"step\":10,\"status\":2},\"ORDER_COMPLETED\":{\"name\":\"--\",\"description\":\"工单完成\",\"step\":11,\"status\":2},\"TICKET_COMPLETED_WAITING_CLOSE_DEFECT\":{\"name\":\"--\",\"description\":\"工作票完成—待关闭缺陷\",\"step\":12,\"status\":2},\"DEFECTS_TO_BE_CLOSED\":{\"name\":\"高级授权人\",\"description\":\"缺陷待关闭\",\"step\":12,\"status\":2},\"DEFECT_COMPLETION\":{\"name\":\"--\",\"description\":\"缺陷完成\",\"step\":13,\"status\":2},\"TICKET_COMPLETED\":{\"name\":\"--\",\"description\":\"工作票完成\",\"step\":14,\"status\":2}}"),
        WORK_ORDER_JSON("工单JSON", "{\"CURRENT_STEP\":0,\"DEFECT_EDIT\":{\"name\":\"所有人\",\"description\":\"缺陷编辑\",\"step\":0,\"status\":0},\"INVALID_DEFECT\":{\"name\":\"--\",\"description\":\"无效缺陷\",\"step\":1,\"status\":0},\"DEFECT_REVIEW\":{\"name\":\"高级授权人\",\"description\":\"缺陷审核\",\"step\":2,\"status\":0},\"DEFECT_CONFIRM\":{\"name\":\"专业主管\",\"description\":\"缺陷确认\",\"step\":3,\"status\":0},\"VALID_DEFECT\":{\"name\":\"高级授权人\",\"description\":\"有效缺陷\",\"step\":4,\"status\":0},\"WORK_ORDER_EDIT\":{\"name\":\"高级授权人\",\"description\":\"工单编辑\",\"step\":5,\"status\":0},\"WORK_ORDER_ACTIVE\":{\"name\":\"高级授权人\",\"description\":\"工单生效\",\"step\":6,\"status\":2},\"JOB_TICKET_EDIT\":{\"name\":\"高级授权人\",\"description\":\"工作票编辑\",\"step\":7,\"status\":2},\"JOB_TICKET_IN_PROGRESS\":{\"name\":\"高级授权人\",\"description\":\"工作票执行中\",\"step\":8,\"status\":2},\"JOB_TICKET_COMPLETED_RECORD_PENDING\":{\"name\":\"干练人员\",\"description\":\"工作票完成-待填写记录\",\"step\":9,\"status\":2},\"TICKET_COMPLETED_WAITING_CLOSE_ORDER\":{\"name\":\"--\",\"description\":\"工作票完成—待关闭工单\",\"step\":10,\"status\":2},\"WORK_ORDER_TO_BE_CLOSED\":{\"name\":\"高级授权人\",\"description\":\"工单待关闭\",\"step\":10,\"status\":2},\"ORDER_COMPLETED\":{\"name\":\"--\",\"description\":\"工单完成\",\"step\":11,\"status\":2},\"TICKET_COMPLETED_WAITING_CLOSE_DEFECT\":{\"name\":\"--\",\"description\":\"工作票完成—待关闭缺陷\",\"step\":12,\"status\":2},\"DEFECTS_TO_BE_CLOSED\":{\"name\":\"高级授权人\",\"description\":\"缺陷待关闭\",\"step\":12,\"status\":2},\"DEFECT_COMPLETION\":{\"name\":\"--\",\"description\":\"缺陷完成\",\"step\":13,\"status\":2},\"TICKET_COMPLETED\":{\"name\":\"--\",\"description\":\"工作票完成\",\"step\":14,\"status\":2}}"),
        WORK_TICKET_JSON("工作票JSON","{\"CURRENT_STEP\":0,\"DEFECT_EDIT\":{\"name\":\"所有人\",\"description\":\"缺陷编辑\",\"step\":0,\"status\":0},\"INVALID_DEFECT\":{\"name\":\"--\",\"description\":\"无效缺陷\",\"step\":1,\"status\":0},\"DEFECT_REVIEW\":{\"name\":\"高级授权人\",\"description\":\"缺陷审核\",\"step\":2,\"status\":0},\"DEFECT_CONFIRM\":{\"name\":\"专业主管\",\"description\":\"缺陷确认\",\"step\":3,\"status\":0},\"VALID_DEFECT\":{\"name\":\"高级授权人\",\"description\":\"有效缺陷\",\"step\":4,\"status\":0},\"WORK_ORDER_EDIT\":{\"name\":\"高级授权人\",\"description\":\"工单编辑\",\"step\":5,\"status\":0},\"WORK_ORDER_ACTIVE\":{\"name\":\"高级授权人\",\"description\":\"工单生效\",\"step\":6,\"status\":0},\"JOB_TICKET_EDIT\":{\"name\":\"高级授权人\",\"description\":\"工作票编辑\",\"step\":7,\"status\":0},\"JOB_TICKET_IN_PROGRESS\":{\"name\":\"高级授权人\",\"description\":\"工作票执行中\",\"step\":8,\"status\":2},\"JOB_TICKET_COMPLETED_RECORD_PENDING\":{\"name\":\"干练人员\",\"description\":\"工作票完成-待填写记录\",\"step\":9,\"status\":2},\"TICKET_COMPLETED_WAITING_CLOSE_ORDER\":{\"name\":\"--\",\"description\":\"工作票完成—待关闭工单\",\"step\":10,\"status\":2},\"WORK_ORDER_TO_BE_CLOSED\":{\"name\":\"高级授权人\",\"description\":\"工单待关闭\",\"step\":10,\"status\":2},\"ORDER_COMPLETED\":{\"name\":\"--\",\"description\":\"工单完成\",\"step\":11,\"status\":2},\"TICKET_COMPLETED_WAITING_CLOSE_DEFECT\":{\"name\":\"--\",\"description\":\"工作票完成—待关闭缺陷\",\"step\":12,\"status\":2},\"DEFECTS_TO_BE_CLOSED\":{\"name\":\"高级授权人\",\"description\":\"缺陷待关闭\",\"step\":12,\"status\":2},\"DEFECT_COMPLETION\":{\"name\":\"--\",\"description\":\"缺陷完成\",\"step\":13,\"status\":2},\"TICKET_COMPLETED\":{\"name\":\"--\",\"description\":\"工作票完成\",\"step\":14,\"status\":2}}");

        private String key;
        private String value;

        TaskTypeEnum(String key, String value) {
            this.key = key;
            this.value = value;
        }

        public String getValue() {
            return value;
        }

        public String getKey() {
            return key;
        }
    }

json示例描述

	{
	    “CURRENT_STEP”:0,//当前的步骤,每走一步则进行更新该数据
		"DEFECT_EDIT": {  //DEFECT_EDIT 字段是和DefectProcessEnum 中的key是匹配的
			"name": "所有人",  //页面展示使用
			"description": "缺陷编辑", //页面展示使用
			"step": 0,   //当前的步骤的序号
			"status": 0  //当前的状态使用TaskStatusEnum  
		},................
	}

二、设计到的数据库表

1.wn_defect 缺陷单表
2.wn_work_order 工单表
3.wn_permit_to_work 工作票表

以上三个表分别添加一个字段flow_json

三、现有逻辑:

一个缺陷可以绑定多个工单,一个工单可以创建多个工作票

四、根据以上现有逻辑业务流程设计思路如下:

缺陷单业务逻辑:
1.在创建缺陷单时获取TaskTypeEnum 中的DEFECT_JSON 这个的value数据存入到flow_json
2.对应缺陷单审批每审批一次都需要更新flow_json这个字段中的JSON对应流程的状态
工单业务逻辑
1.创建工单绑定缺陷,将缺陷中的json赋值到工单中,并且修改对应的状态更新到当前创建的工单数据中
2.直接创建工单不绑定缺陷则获取TaskTypeEnum 中的WORK_ORDER_JSON 这个value数据存入到flow_json
工作票业务逻辑
1.根据工单创建工作票时,获取到TaskTypeEnum 中的WORK_TICKET_JSON参数里的json修改对应步骤的状态存入flow_json字中。
2.新增完成工作票以后更新工单,缺陷单最新状态(跑的最慢的那个状态),根据工单查询该工单绑定的所有工作票,找到json中CURRENT_STEP这个字段最小值的json赋值到工单json以及工作票 json中

如果设计到删除工作票,和删除工单,逻辑同上例如,删除工作票,取工单下绑定的工作票列表找到json中CURRENT_STEP这个字段最小值的json赋值到工单json以及工作票 json中


五、补充后续核心Utils

package wnoa.utils;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import wnoa.base.UserInfo;
import wnoa.entity.WnDefectEntity;
import wnoa.entity.WnPermitToWorkEntity;
import wnoa.entity.WnWorkOrderEntity;
import wnoa.enums.DefectProcessEnum;
import wnoa.enums.WorkOrderEnum;
import wnoa.exception.DataException;
import wnoa.mapper.WnDefectMapper;
import wnoa.mapper.WnPermitToWorkMapper;
import wnoa.mapper.WnWorkOrderMapper;
import wnoa.service.*;
import wnoa.util.UserProvider;

import java.util.*;

/**
 * 业务流程工具类
 *
 * @author 23882
 */
@Service
public class WnBusinessFlowUtils {
    @Autowired
    private WnDocumentMakeService wnDocumentMakeService;
    @Autowired
    private UserProvider userProvider;
    @Autowired   //工作票Mapper
    private WnPermitToWorkMapper wnPermitToWorkMapper;
    @Autowired   //工作票service
    private WnPermitToWorkService wnPermitToWorkService;
    @Autowired   //工单service
    private WnWorkOrderService wnWorkOrderService;
    @Autowired  //工单maper
    private WnWorkOrderMapper wnWorkOrderMapper;
    @Autowired  //缺陷单Service
    private WnDefectService wnDefectService;
    @Autowired //缺陷单Mapper
    private WnDefectMapper wnDefectMapper;
    @Autowired
    private WnFlowTransferRecordsService wnFlowTransferRecordsService;

    /**
     * 审批流程工具类
     *
     * @param key    DefectProcessEnum  中的key
     * @param id     要操作的数据id
     * @param status TaskTypeEnum  中的key
     */
    public void businessFlow(String key, String id, String status) {
        if (StringUtils.isEmpty(id)) {
            throw new DataException("操作的id不允许为空!");
        }
        String flowJson = StringUtils.EMPTY;
        //根据不同的状态获取不同的数据,如果id可以查询到数据则使用id查询回来的json进行操作,如果id查询不回来则使用初始化的json
        DefectProcessEnum.TaskTypeEnum taskTypeEnumValue = DefectProcessEnum.TaskTypeEnum.getTaskTypeEnumValue(status);
        if (null != taskTypeEnumValue) {
            switch (taskTypeEnumValue) {
                case DEFECT_JSON:
                    System.out.println("缺陷JSON");
                    break;
                case WORK_ORDER_JSON:
                    WnWorkOrderEntity wnWorkOrderEntity = wnWorkOrderMapper.selectById(id);
                    if (null != wnWorkOrderEntity) {
                        flowJson = StringUtils.isNotEmpty(wnWorkOrderEntity.getFlowJson()) ? wnWorkOrderEntity.getFlowJson() : taskTypeEnumValue.getValue();
                    } else {
                        flowJson = taskTypeEnumValue.getValue();
                    }
                    System.out.println("工单JSON");
                    break;
                case WORK_TICKET_JSON:
                    WnPermitToWorkEntity wnPermitToWorkEntity = wnPermitToWorkMapper.selectById(id);
                    if (null != wnPermitToWorkEntity) {
                        flowJson = StringUtils.isNotEmpty(wnPermitToWorkEntity.getFlowJson()) ? wnPermitToWorkEntity.getFlowJson() : taskTypeEnumValue.getValue();
                    }
                    System.out.println("工作票JSON");
                    break;
            }
        }
        if (StringUtils.isEmpty(flowJson)) {
            throw new DataException("要修改的流程id暂未查询到流程数据");
        }
        //根据不同的key执行不同的逻辑
        DefectProcessEnum defectProcessEnumValue = DefectProcessEnum.getDefectProcessEnumValue(key);
        if (null != defectProcessEnumValue) {
            switch (defectProcessEnumValue) {
                case DEFECT_EDIT:
                    System.out.println("缺陷编辑");
                    break;
                case INVALID_DEFECT:
                    System.out.println("无效缺陷");
                    break;
                case DEFECT_REVIEW:
                    System.out.println("缺陷审核");
                    break;
                case DEFECT_CONFIRM:
                    System.out.println("缺陷确认");
                    break;
                case VALID_DEFECT:
                    System.out.println("有效缺陷");
                    break;
                case WORK_ORDER_EDIT:
                    updateFlowJsonOrder(id, flowJson, WorkOrderEnum.WORK_ORDER_EDIT.getValue());
                    System.out.println("工单编辑");
                    break;
                case WORK_ORDER_ACTIVE:
                    updateFlowJsonOrder(id, operateJSON(defectProcessEnumValue, flowJson),WorkOrderEnum.WORK_ORDER_ACTIVE.getValue());
                    System.out.println("工单生效");
                    break;
                case JOB_TICKET_EDIT:
                    //工作票编辑,初始化json
                    updateFlowJson(id, flowJson, defectProcessEnumValue.getValue());
                    System.out.println("工作票编辑");
                    break;
                case JOB_TICKET_IN_PROGRESS:
                    //根据id修改json,更新工单以及缺陷单最慢的json
                    updateFlowJson(id, operateJSON(defectProcessEnumValue, flowJson), defectProcessEnumValue.getValue());
                    System.out.println("工作票执行中");
                    break;
                case JOB_TICKET_COMPLETED_RECORD_PENDING:
                    //根据id修改json,更新工单以及缺陷单最慢的json
                    updateFlowJson(id, operateJSON(defectProcessEnumValue, flowJson), defectProcessEnumValue.getValue());
                    System.out.println("工作票完成-待填写记录");
                    break;
                case TICKET_COMPLETED_WAITING_CLOSE_ORDER:
                case WORK_ORDER_TO_BE_CLOSED:
                    updateFlowJson(id, operateJSON(defectProcessEnumValue, flowJson), defectProcessEnumValue.getValue());
                    System.out.println("工作票完成—待关闭工单");
                    break;
                case ORDER_COMPLETED:
                    System.out.println("工单完成");
                    break;
                case TICKET_COMPLETED_WAITING_CLOSE_DEFECT:
                case DEFECTS_TO_BE_CLOSED:
                    System.out.println("工作票完成—待关闭缺陷");
                    break;
                case DEFECT_COMPLETION:
                    System.out.println("缺陷完成");
                    break;
                case TICKET_COMPLETED:
                    System.out.println("工作票完成");
                    break;
                default:
                    throw new IllegalArgumentException("Unknown task status: " + status);
            }
        }
    }

    /**
     *  以下为状态流转核心方法
     * @param defectProcessEnumValue 当前要操作的业务Enum
     * @param flowJson               上一步的json
     * @return
     */
    private String operateJSON(DefectProcessEnum defectProcessEnumValue, String flowJson) {
        JSONObject flowJsonO = JSON.parseObject(flowJson);
        //根据json中的CURRENT_STEP这个字段判断当前这一步,将他修改成已完成
        Integer currentStep = flowJsonO.getInteger("CURRENT_STEP");
        List<DefectProcessEnum> currentNyStep = DefectProcessEnum.getByStep(currentStep);
        if (!currentNyStep.isEmpty()) {
            currentNyStep.forEach(defectProcessEnum -> {
                JSONObject jsonObject = flowJsonO.getJSONObject(defectProcessEnum.getKey());
                jsonObject.put("status", DefectProcessEnum.TaskStatusEnum.COMPLETED.getCode());
            });
        }
        //解析到当要修改的这一步json
        List<DefectProcessEnum> lowerByStep = DefectProcessEnum.getByStep(defectProcessEnumValue.getStep());
        if (!lowerByStep.isEmpty()) {
            lowerByStep.forEach(defectProcessEnum -> {
                JSONObject jsonObject = flowJsonO.getJSONObject(defectProcessEnum.getKey());
                jsonObject.put("status", DefectProcessEnum.TaskStatusEnum.IN_PROGRESS.getCode());
            });
            flowJsonO.put("CURRENT_STEP", defectProcessEnumValue.getStep());
        }
        return flowJsonO.toJSONString();
    }

    /**
     * 工作票修改json
     *
     * @param id       要修改的工作票数据id
     * @param flowJson 要修改的json
     */

    private void updateFlowJson(String id, String flowJson, String nodeName) {
        //缺陷单编号
        String defectNumber = StringUtils.EMPTY;
        //工单id
        String workOrderId = StringUtils.EMPTY;
        //0缺陷单1工单2工作票
        Integer type = 2;
        //执行逻辑
        UserInfo userInfo = userProvider.get();
        LambdaUpdateWrapper<WnPermitToWorkEntity> wnPermitToWorkEntityUpdateWrapper = new LambdaUpdateWrapper<>();
        wnPermitToWorkEntityUpdateWrapper.eq(WnPermitToWorkEntity::getId, id);
        wnPermitToWorkEntityUpdateWrapper.set(WnPermitToWorkEntity::getFlowJson, flowJson);
        wnPermitToWorkEntityUpdateWrapper.set(WnPermitToWorkEntity::getLastModifyTime, new Date());
        wnPermitToWorkEntityUpdateWrapper.set(WnPermitToWorkEntity::getLastModifyUserId, userInfo.getUserId());
        wnPermitToWorkService.update(wnPermitToWorkEntityUpdateWrapper);
        //将最慢的工作票json复制到工单和缺陷单中
        LambdaQueryWrapper<WnPermitToWorkEntity> wnPermitToWorkEntityQueryWrapper = new LambdaQueryWrapper<>();
        wnPermitToWorkEntityQueryWrapper.eq(WnPermitToWorkEntity::getId, id);
        WnPermitToWorkEntity wnPermitToWorkEntity = wnPermitToWorkMapper.selectOne(wnPermitToWorkEntityQueryWrapper);
        if (null != wnPermitToWorkEntity) {
            //赋值工单id
            workOrderId = wnPermitToWorkEntity.getWorkOrderId();
            LambdaQueryWrapper<WnWorkOrderEntity> wnWorkOrderEntityQueryWrapper = new LambdaQueryWrapper<>();
            wnWorkOrderEntityQueryWrapper.eq(WnWorkOrderEntity::getId, wnPermitToWorkEntity.getWorkOrderId());
            //根据工单id查询该工单下绑定的所有工作票
            List<WnWorkOrderEntity> wnWorkOrderEntities = wnWorkOrderMapper.selectList(wnWorkOrderEntityQueryWrapper);
            if (!wnWorkOrderEntities.isEmpty()) {
                //查找最慢的工作票json
                HashMap<Integer, String> Map = new HashMap<>();
                wnWorkOrderEntities.forEach(wnPermitToWorkEntity1 -> {
                    JSONObject jsonObject = JSON.parseObject(wnPermitToWorkEntity1.getFlowJson());
                    if (null != jsonObject) {
                        Integer step = jsonObject.getInteger("CURRENT_STEP");
                        if (null != step) {
                            Map.put(step, wnPermitToWorkEntity1.getFlowJson());
                        }
                    }
                });
                //根据map中的key排序找到key最小的哪一个
                List<Integer> list = new ArrayList<>(Map.keySet());
                Collections.sort(list);
                if (!list.isEmpty()) {
                    Integer min = list.get(0);
                    String flowJson1 = Map.get(min);
                    //更新工单json
                    LambdaUpdateWrapper<WnWorkOrderEntity> wnWorkOrderEntityUpdateWrapper = new LambdaUpdateWrapper<>();
                    wnWorkOrderEntityUpdateWrapper.eq(WnWorkOrderEntity::getId, wnPermitToWorkEntity.getWorkOrderId());
                    wnWorkOrderEntityUpdateWrapper.set(WnWorkOrderEntity::getFlowJson, flowJson1);
                    wnWorkOrderEntityUpdateWrapper.set(WnWorkOrderEntity::getLastmodifytime, new Date());
                    wnWorkOrderEntityUpdateWrapper.set(WnWorkOrderEntity::getLastmodifyuserid, userInfo.getUserId());
                    wnWorkOrderService.update(wnWorkOrderEntityUpdateWrapper);
                    //根据工单找到缺陷单编号
                    LambdaQueryWrapper<WnWorkOrderEntity> wnDefectEntityQueryWrapper = new LambdaQueryWrapper<>();
                    wnDefectEntityQueryWrapper.eq(WnWorkOrderEntity::getId, wnPermitToWorkEntity.getWorkOrderId());
                    WnWorkOrderEntity wnWorkOrderEntity = wnWorkOrderMapper.selectOne(wnDefectEntityQueryWrapper);
                    if (wnWorkOrderEntity != null) {
                        //缺陷单编号不为空则更新缺陷单json
                        String defectOrderNumber = wnWorkOrderEntity.getDefectOrderNumber();
                        if (StringUtils.isNotEmpty(defectOrderNumber)) {
                            //赋值缺陷单编号
                            defectNumber = defectOrderNumber;
                            //更新缺陷单json
                            LambdaUpdateWrapper<WnDefectEntity> wnDefectEntityUpdateWrapper = new LambdaUpdateWrapper<>();
                            wnDefectEntityUpdateWrapper.eq(WnDefectEntity::getDefectNumber, wnPermitToWorkEntity.getDefectOrderNumber());
                            wnDefectEntityUpdateWrapper.set(WnDefectEntity::getFlowJson, flowJson1);
                            wnDefectEntityUpdateWrapper.set(WnDefectEntity::getLastmodifytime, new Date());
                            wnDefectEntityUpdateWrapper.set(WnDefectEntity::getLastmodifyuserid, userInfo.getUserId());
                            wnDefectService.update(wnDefectEntityUpdateWrapper);
                        }
                    }
                }
            }
            //记录流程状态
            wnFlowTransferRecordsService.saveTransfer(defectNumber, workOrderId, id, nodeName, type);
        }
    }
}

1.核心util方法入参示例

businessFlow(DefectProcessEnum.JOB_TICKET_IN_PROGRESS.getKey(),"123",DefectProcessEnum.TaskTypeEnum.WORK_TICKET_JSON.getKey());

六、前端代码如下

<template>
  <div class="box">
    <div class="list">
      <div><p class="green"></p><p>已完成</p></div>
      <div><p class="blue"></p><p>进行中</p></div>
      <div><p class="grey"></p><p>无/未处理</p></div>
    </div>
    <div class="confirmToVoidLeft"></div>
    <div class="confirmToVoidTop"></div>
    <div class="finishTobeClosed"></div>
    <div class="finishToFinish"></div>

<!--    缺陷编辑-->
    <flowChart style="transform: translateY(20px) translateX(400px)" :cont="flowData.DEFECT_EDIT"   :is-show="{bottom:true}"></flowChart>
<!--    缺陷审核-->
    <flowChart style="transform: translateY(110px) translateX(400px)" :cont="flowData.DEFECT_REVIEW"  :is-show="{left:true,bottom:true}"></flowChart>
<!--    无效缺陷-->
    <flowChart style="transform: translateY(10px) translateX(110px)" :cont="flowData.INVALID_DEFECT"   :is-show="{}"></flowChart>
<!--    缺陷确认-->
    <flowChart style="transform: translateY(100px) translateX(400px)" :cont="flowData.DEFECT_CONFIRM"  :is-show="{bottom:true}"></flowChart>
<!--    有效缺陷-->
    <flowChart style="transform: translateY(190px) translateX(400px)" :cont="flowData.VALID_DEFECT"   :is-show="{right:true}"></flowChart>
<!--    工单编辑-->
    <flowChart style="transform: translateY(90px) translateX(695px)" :cont="flowData.WORK_ORDER_EDIT"   :is-show="{bottom:true}"></flowChart>
<!--    工单生效-->
    <flowChart style="transform: translateY(180px) translateX(695px)" :cont="flowData.WORK_ORDER_ACTIVE"   :is-show="{right:true}"></flowChart>
<!--    工作票编辑-->
    <flowChart style="transform: translateY(80px) translateX(985px)" :cont="flowData.JOB_TICKET_EDIT"   :is-show="{bottom:true}"></flowChart>
<!--    工作票执行中-->
    <flowChart style="transform: translateY(170px) translateX(985px)" :cont="flowData.JOB_TICKET_IN_PROGRESS"  :is-show="{bottom:true}"></flowChart>
<!--    工作票完成-待填写记录-->
    <flowChart style="transform: translateY(260px) translateX(985px)" :cont="flowData.JOB_TICKET_COMPLETED_RECORD_PENDING" :is-show="{bottom:true,left:true}"></flowChart>
<!--    工作票完成-待关闭工单-->
    <flowChart style="transform: translateY(350px) translateX(985px)" :cont="flowData.TICKET_COMPLETED_WAITING_CLOSE_ORDER"  :is-show="{}"></flowChart>
<!--    工作票完成-待关闭缺陷-->
    <flowChart style="transform: translateY(395px) translateX(985px)" :cont="flowData.TICKET_COMPLETED_WAITING_CLOSE_DEFECT"   :is-show="{bottom:true}"></flowChart>
<!--    工作票完成-->
    <flowChart style="transform: translateY(490px) translateX(985px)" :cont="flowData.TICKET_COMPLETED"   :is-show="{}"></flowChart>
<!--    工单待关闭-->
    <flowChart style="transform: translateY(-145px) translateX(695px)" :cont="flowData.WORK_ORDER_TO_BE_CLOSED"   :is-show="{bottom:true}"></flowChart>
<!--    工单完成-->
    <flowChart style="transform: translateY(-50px) translateX(695px)" :cont="flowData.ORDER_COMPLETED"   :is-show="{bottom:true,left:true}"></flowChart>
<!--    缺陷待关闭-->
    <flowChart style="transform: translateY(-150px) translateX(400px)" :cont="flowData.DEFECTS_TO_BE_CLOSED"   :is-show="{bottom:true}"></flowChart>
<!--    缺陷完成-->
    <flowChart style="transform: translateY(-50px) translateX(400px)" :cont="flowData.DEFECT_COMPLETION"   :is-show="{bottom:true}"></flowChart>
    <div style="height: 200px"></div>
  </div>
</template>

<script>
import flowChart from './item.vue'
export default {
  props:['flowData'],
   components:{
     flowChart
   },
    data(){
      return {

      }
    },
    mounted() {

    }
}
</script>

<style scoped lang="scss">
    .box{
      height: 100%;
      width: 100%;
      background: #fff;
      overflow: auto;

      .confirmToVoidLeft{
        width: 180px;
        height: 2px;
        position: relative;
        background-color: #ccc;
        transform: translateY(450px) translateX(220px);

      }
      .confirmToVoidLeft::after{
        content: '';
        display: block;
        position: absolute;
        left: -10px;  /* 箭头位置 */
        top: -9px;  /* 箭头位置 */

        border-width: 10px 10px 10px 0;
        border-style: solid;
        border-color:  transparent  #ccc transparent transparent;
        //transform: rotateY(180deg);

      }
      .confirmToVoidTop{
        width: 126px;
        height: 2px;
        position: relative;
        background-color: #ccc;
        transform: translateY(385px) translateX(145px) rotateZ(90deg);
      }
      .confirmToVoidTop::after{
        content: '';
        display: block;
        position: absolute;
        left: -10px;  /* 箭头位置 */
        top: -9px;  /* 箭头位置 */
        border-width: 10px 10px 10px 0;
        border-style: solid;
        border-color:  transparent  #ccc transparent transparent;
      }


      .finishTobeClosed{
        width: 175px;
        height: 2px;
        position: relative;
        background-color: #ccc;
        transform: translateX(795px) translateY(1542px);
      }
      .finishTobeClosed::after{
        content: '';
        display: block;
        position: absolute;
        right: -10px;  /* 箭头位置 */
        top: -9px;  /* 箭头位置 */
        border-width: 10px  10px 10px 0;
        transform: rotateY(180deg) ;
        border-style: solid;
        border-color:  transparent  #ccc transparent transparent;
      }


      .finishToFinish{
        width: 475px;
        height: 2px;
        position: relative;
        background-color: #ccc;
        transform: translateX(500px) translateY(1742px);
      }
      .finishToFinish::after{
        content: '';
        display: block;
        position: absolute;
        right: -10px;  /* 箭头位置 */
        top: -9px;  /* 箭头位置 */
        border-width: 10px  10px 10px 0;
        transform: rotateY(180deg) ;
        border-style: solid;
        border-color:  transparent  #ccc transparent transparent;
      }
      .list{
        height: 50px;
        display: flex;
        width: 400px;
        justify-content: space-evenly;
        div{
          height: 100%;
          display: flex;
          align-items: center;
          p{
            margin: 0 5px;
          }
          .green{
            height: 20px;
            width: 20px;
            border-radius: 50%;
            background: #70b603;
            border: 2px solid #cccccc;
            box-shadow: 0 0 4px #70b603;
          }
          .blue{
            height: 20px;
            width: 20px;
            border-radius: 50%;
            background: #027db4;
            border: 2px solid #cccccc;
            box-shadow: 0 0 4px #027db4;
          }
          .grey{
            height: 20px;
            width: 20px;
            border-radius: 50%;
            background: #f1f1f1;
            border: 2px solid #cccccc;
            box-shadow: 0 0 4px #f1f1f1;
          }
        }
      }

    }
    .box::after{
      content: "";
      display: block;
      clear: both;
    }
</style>

以上是具体到每一个流程

<script>
export default {
  props: ["cont","isShow","width"],
  data(){
    return {

    }
  },
  mounted() {


  }
}
</script>

<template>

    <div id="box" class="boxContent">
      <div class="line top-line top-arrow" :style="{display:(isShow.top?'block':'none')}"></div>
      <div class="line bottom-line bottom-arrow" :style="{display:(isShow.bottom?'block':'none')}"></div>
      <div class="line left-line left-arrow" :style="{display:(isShow.left?'block':'none')}"></div>
      <div class="line right-line right-arrow" :style="{display:(isShow.right?'block':'none')}"></div>
      <div class="title" :style="{height:'50%',background:(cont.status =='0' ? '#70b603':cont.status =='1'?'#027db4':'#ccc')}">
        {{cont.description}}
      </div>
      <div class="content">
        {{cont.name}}
      </div>
    </div>



</template>

<style scoped lang="scss">

//顶部的箭头
$_width: 80px;
  .boxContent {
    position: relative;
    width: 200px;
    height: 100px;
    border: 1px solid  #ccc;
    box-shadow: 1px 1px 20px #ccc;
    :hover{
      box-shadow: 1px 1px 12px #ccc;

    }
  }
  .title{
    display: flex;
    justify-content: center;
    align-items: center;
    color: #fff;
    font-weight: bold;
    font-size: 15px;
  }
  .content{
    font-size: 15px;
    padding: 10px;
    height: 50px;
  }
  .line {
    position: absolute;
    background-color: #ccc;
  }

  /* Top line with arrow */
  .top-line {
    top: -$_width;
    left: 50%;
    width: 2px;
    height: $_width;
    transform: translateX(-50%) ;

  }
  .top-arrow::after {
    content: '';
    position: absolute;
    top: -10px;
    left: 50%;
    transform: translateX(-50%) rotateX(180deg);
    border-width: 10px 10px 0 10px;
    border-style: solid;
    border-color: #ccc transparent transparent transparent;
  }

  /* Bottom line with arrow */
  .bottom-line {
    bottom: -$_width;
    left: 50%;
    width: 2px;
    height: $_width;
    transform: translateX(-50%);

  }
  .bottom-arrow::after {
    content: '';
    position: absolute;
    bottom: -10px;
    left: 50%;
    transform: translateX(-50%)  rotateX(180deg);
    border-width: 0 10px 10px 10px;
    border-style: solid;
    border-color: transparent transparent  #ccc transparent;

  }

  /* Left line with arrow */
  .left-line {
    top: 50%;
    left: -$_width;
    width:  $_width;
    height: 2px;
    transform: translateY(-50%);

  }
  .left-arrow::after {
    content: '';
    position: absolute;
    top: 50%;
    left: -10px;
    transform: translateY(-50%) rotateX(180deg);
    border-width: 10px 10px 10px 0;
    border-style: solid;
    border-color: transparent  #ccc transparent transparent;
  }

  /* Right line with arrow */
  .right-line {
    top: 50%;
    right: -$_width;
    width: $_width;
    height: 2px;
    transform: translateY(-50%);

  }
  .right-arrow::after {
    content: '';
    position: absolute;
    top: 50%;
    right: -10px;
    transform: translateY(-50%) rotate(0deg);
    border-width: 10px 0 10px 10px;
    border-style: solid;
    border-color: transparent transparent transparent  #ccc;
  }
</style>
**将以上进行封装**

七、最终效果图

在这里插入图片描述

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值