简单的系统拖拽规则DragRuleServiceImpl部分

package cn.git.rules.service.drag.impl;

import cn.git.common.drag.CommonDragRuleConstant;
import cn.git.common.drag.dto.DragChainDTO;
import cn.git.common.drag.dto.DragRuleDTO;
import cn.git.common.exception.ServiceException;
import cn.git.common.page.CustomPageUtil;
import cn.git.common.page.PageBean;
import cn.git.common.page.PaginationContext;
import cn.git.common.sequence.SequenceConstant;
import cn.git.common.util.CommonDragRuleUtil;
import cn.git.common.util.LogUtil;
import cn.git.redis.RedisUtil;
import cn.git.rules.constant.RuleConstant;
import cn.git.rules.drag.DragRuleServerUtil;
import cn.git.rules.drag.enums.DragRuleSequenceEnum;
import cn.git.rules.dto.drag.DragRuleChainAllParamDTO;
import cn.git.rules.entity.TbSysDragChain;
import cn.git.rules.entity.TbSysDragRule;
import cn.git.rules.entity.TbSysProduct;
import cn.git.rules.entity.TbSysProductDragChain;
import cn.git.rules.mapper.TbSysDragChainMapper;
import cn.git.rules.mapper.TbSysDragRuleMapper;
import cn.git.rules.mapper.TbSysProductDragChainMapper;
import cn.git.rules.mapper.TbSysProductMapper;
import cn.git.rules.mapstruct.DragRuleConvert;
import cn.git.rules.service.drag.DragRuleService;
import cn.git.rules.vo.drag.DragRuleChainAllParamDescOutVO;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.camunda.bpm.model.bpmn.Bpmn;
import org.camunda.bpm.model.bpmn.BpmnModelInstance;
import org.camunda.bpm.model.bpmn.instance.FlowElement;
import org.camunda.bpm.model.bpmn.instance.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @description: 拖拽规则service
 * @program: bank-credit-sy
 * @author: lixuchun
 * @create: 2024-02-22 11:55:33
 */
@Slf4j
@Service
public class DragRuleServiceImpl implements DragRuleService {

    @Autowired
    private CustomPageUtil customPageUtil;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private DragRuleServerUtil dragRuleServerUtil;

    @Autowired
    private CommonDragRuleUtil commonDragRuleUtil;

    @Autowired
    private DragRuleConvert dragRuleConvert;

    @Autowired
    private TbSysDragRuleMapper tbSysDragRuleMapper;

    @Autowired
    private TbSysDragChainMapper tbSysDragChainMapper;

    @Autowired
    private TbSysProductDragChainMapper productDragChainMapper;

    @Autowired
    private TbSysProductMapper tbSysProductMapper;

    @Autowired
    private HttpServletResponse response;

    /**
     * 添加拖拽规则方法
     *
     * @param dragRuleDTO
     */
    @Override
    public void addDragRule(DragRuleDTO dragRuleDTO) {
        // 判定数据库中是否已经存在,已经存在则不允许新增
        if (ObjectUtil.isNotNull(tbSysDragRuleMapper.selectById(dragRuleDTO.getDragRuleId()))) {
            throw new ServiceException(StrUtil.format("规则id[{}]已经存在,不允许重复添加!",
                    dragRuleDTO.getDragRuleId()));
        }
        // 判断缓存中是否存在拖拽规则信息,如果不存在则证明 dragRuleId 传递有误
        Object dragRuleDTOObj = redisUtil.hget(RuleConstant.DRAG_RULES, dragRuleDTO.getDragRuleId()).toString();
        if (ObjectUtil.isNull(dragRuleDTOObj)) {
            throw new ServiceException(StrUtil.format("通过规则id[{}]获取拖拽规则缓存信息失败!",
                    dragRuleDTO.getDragRuleId()));
        }
        // 获取缓存dragRule信息,获取出参参数信息
        DragRuleDTO cacheDragRuleDTO = JSONObject.parseObject(dragRuleDTOObj.toString(), DragRuleDTO.class);
        JSONObject outputParamJSON = JSON.parseObject(cacheDragRuleDTO.getOutputParam());

        // 拖拽自定义比较参数
        String dragOptionParamsStr = null;
        // 传入自定义参数校验
        if (ObjectUtil.isNotEmpty(dragRuleDTO.getCustomOptionParamList())) {
            // 获取多个自定义参数比较规则
            List<List<DragRuleDTO.CustomOptionParam>> customOptionParamsList = dragRuleDTO.getCustomOptionParamList();
            for (List<DragRuleDTO.CustomOptionParam> paramList : customOptionParamsList) {
                if (ObjectUtil.isEmpty(paramList)) {
                    continue;
                }
                // 进行数类型校验自定义参数格式以及参
                dragRuleServerUtil.checkCustomOptionParam(paramList);
            }
            dragOptionParamsStr = JSONObject.toJSONString(dragRuleDTO.getCustomOptionParamList());
            dragRuleDTO.setCustomOptionParam(dragOptionParamsStr);
        }

        // 传递参数校验,传递参数必须为规则方法出参参数
        String crossParamStr = null;
        if (ObjectUtil.isNotEmpty(dragRuleDTO.getCrossParamDescList())) {
            List<String> crossParamList = dragRuleDTO.getCrossParamDescList().stream().map(
                    DragRuleDTO.DragRuleParamsDesc::getParamName
            ).collect(Collectors.toList());
            dragRuleDTO.setCrossParamList(crossParamList);
            for (String crossParam : dragRuleDTO.getCrossParamList()) {
                if (!outputParamJSON.containsKey(crossParam)) {
                    String errorMessage = StrUtil.format("拖拽规则传递参数必须为规则方法出参参数,[{}]不满足条件,请确认!",
                            crossParam);
                    throw new ServiceException(errorMessage);
                }
            }
            crossParamStr = dragRuleDTO.getCrossParamList().stream().map(
                    String::toString
            ).collect(Collectors.joining(StrUtil.COMMA));

            // 将outParamDescList转换为map,获取crossParamDesc描述信息
            Map<String, DragRuleDTO.DragRuleParamsDesc> outParamDescMap = dragRuleDTO.getOutputParamDescList().stream()
                    .collect(
                            Collectors.toMap(DragRuleDTO.DragRuleParamsDesc::getParamName,
                                    Function.identity())
                    );
            List<DragRuleDTO.DragRuleParamsDesc> crossParamDescList = new ArrayList<>();
            dragRuleDTO.getCrossParamList().forEach(paramName -> {
                DragRuleDTO.DragRuleParamsDesc dragRuleParamsDesc = outParamDescMap.get(paramName);
                if (ObjectUtil.isNotNull(dragRuleParamsDesc)) {
                    crossParamDescList.add(dragRuleParamsDesc);
                }
            });
            dragRuleDTO.setCrossParamDescList(crossParamDescList);
        }

        // 规则信息插入数据库
        TbSysDragRule tbSysDragRule = dragRuleConvert.dragRuleDTOToDragRule(dragRuleDTO);
        tbSysDragRule.setCrossParam(crossParamStr);
        tbSysDragRuleMapper.insert(tbSysDragRule);

        // 修改缓存信息
        cacheDragRuleDTO.setCrossParam(crossParamStr);
        cacheDragRuleDTO.setCrossParamList(dragRuleDTO.getCrossParamList());
        cacheDragRuleDTO.setIfLoadDB(RuleConstant.NUM_1_STR);
        cacheDragRuleDTO.setCrossParamDescList(dragRuleDTO.getCrossParamDescList());
        cacheDragRuleDTO.setCustomOptionParam(dragOptionParamsStr);
        cacheDragRuleDTO.setCustomOptionParamList(dragRuleDTO.getCustomOptionParamList());
        redisUtil.hset(RuleConstant.DRAG_RULES, dragRuleDTO.getDragRuleId(), JSONObject.toJSONString(cacheDragRuleDTO));
    }

    /**
     * 通过id查询拖拽规则
     *
     * @param dragRuleId
     * @return
     */
    @Override
    public DragRuleDTO findById(String dragRuleId) {
        // 判断缓存中是否存在拖拽规则信息,如果不存在则证明 dragRuleId 传递有误
        Object dragRuleDTOObj = redisUtil.hget(RuleConstant.DRAG_RULES, dragRuleId);
        if (ObjectUtil.isNull(dragRuleDTOObj)) {
            throw new ServiceException(StrUtil.format("通过规则id[{}]获取拖拽规则缓存信息失败!", dragRuleId));
        }
        DragRuleDTO dragRuleDTO = JSONObject.parseObject(dragRuleDTOObj.toString(), DragRuleDTO.class);
        TbSysDragRule tbSysDragRule = tbSysDragRuleMapper.selectById(dragRuleId);
        if (ObjectUtil.isNotNull(tbSysDragRule)) {
            dragRuleDTO.setIfLoadDB(RuleConstant.NUM_1_STR);
            // 传递参数设置
            if (StrUtil.isNotBlank(tbSysDragRule.getCrossParam())) {
                dragRuleDTO.setCrossParam(tbSysDragRule.getCrossParam());
                dragRuleDTO.setCrossParamList(Arrays.asList(dragRuleDTO.getCrossParam().split(StrUtil.COMMA)));
                // 将outParamDescList转换为map,获取crossParamDesc描述信息
                Map<String, DragRuleDTO.DragRuleParamsDesc> outParamDescMap = dragRuleDTO.getOutputParamDescList().stream()
                        .collect(
                                Collectors.toMap(DragRuleDTO.DragRuleParamsDesc::getParamName,
                                        Function.identity())
                        );
                List<DragRuleDTO.DragRuleParamsDesc> crossParamDescList = new ArrayList<>();
                dragRuleDTO.getCrossParamList().forEach(paramName -> {
                    DragRuleDTO.DragRuleParamsDesc dragRuleParamsDesc = outParamDescMap.get(paramName);
                    if (ObjectUtil.isNotNull(dragRuleParamsDesc)) {
                        crossParamDescList.add(dragRuleParamsDesc);
                    }
                });
                dragRuleDTO.setCrossParamDescList(crossParamDescList);
            }

            // 自定义参数设置
            if (StrUtil.isNotBlank(tbSysDragRule.getCustomOptionParam())) {
                String customOptionParam = tbSysDragRule.getCustomOptionParam();
                dragRuleDTO.setCustomOptionParam(customOptionParam);

                // 将json类型转换为 List<List<DragRuleDTO.CustomOptionParam>> 类型
                List customOptionParamsList = JSONObject.parseArray(customOptionParam, List.class);
                List<List<DragRuleDTO.CustomOptionParam>> typeList = new ArrayList<>();
                for (Object customParamList : customOptionParamsList) {
                    List<JSONObject> jsonParamList = (List<JSONObject>) customParamList;
                    List<DragRuleDTO.CustomOptionParam> innerParamList = jsonParamList.stream().map(jsonParam -> {
                        return JSONObject.parseObject(jsonParam.toJSONString(), DragRuleDTO.CustomOptionParam.class);
                    }).collect(Collectors.toList());
                    typeList.add(innerParamList);
                }

                dragRuleDTO.setCustomOptionParamList(typeList);
            }
        }
        return dragRuleDTO;
    }

    /**
     * 修改拖拽规则
     *
     * @param dragRuleDTO
     */
    @Override
    public void updateDragRule(DragRuleDTO dragRuleDTO) {
        // 判断缓存中是否存在拖拽规则信息,如果不存在则证明 dragRuleId 传递有误
        Object dragRuleDTOObj = redisUtil.hget(RuleConstant.DRAG_RULES, dragRuleDTO.getDragRuleId());
        if (ObjectUtil.isNull(dragRuleDTOObj)) {
            throw new ServiceException(StrUtil.format("通过规则id[{}]获取拖拽规则缓存信息失败!",
                    dragRuleDTO.getDragRuleId()));
        }
        // 获取缓存dragRule信息,获取出参参数信息
        DragRuleDTO cacheDragRuleDTO = JSONObject.parseObject(dragRuleDTOObj.toString(), DragRuleDTO.class);
        JSONObject outputParamJSON = JSON.parseObject(cacheDragRuleDTO.getOutputParam());

        // 拖拽自定义比较参数
        String dragOptionParamsStr = null;
        // 传入自定义参数校验
        if (ObjectUtil.isNotEmpty(dragRuleDTO.getCustomOptionParamList())) {
            // 获取多个自定义参数比较规则
            List<List<DragRuleDTO.CustomOptionParam>> customOptionParamsList = dragRuleDTO.getCustomOptionParamList();
            for (List<DragRuleDTO.CustomOptionParam> paramList : customOptionParamsList) {
                if (ObjectUtil.isEmpty(paramList)) {
                    continue;
                }
                // 进行数类型校验自定义参数格式以及参
                dragRuleServerUtil.checkCustomOptionParam(paramList);
            }
            dragOptionParamsStr = JSONObject.toJSONString(dragRuleDTO.getCustomOptionParamList());
            dragRuleDTO.setCustomOptionParam(dragOptionParamsStr);
        } else if (ObjectUtil.isEmpty(dragRuleDTO.getCustomOptionParamList())) {
            // 设置自定义参数信息为空
            dragRuleDTO.setCustomOptionParam(null);
            dragRuleDTO.setCustomOptionParamList(null);
        }

        // 传递参数校验,传递参数必须为规则方法出参参数
        String crossParamStr = null;
        if (ObjectUtil.isNotEmpty(dragRuleDTO.getCrossParamDescList())) {
            // 设置传递参数list
            List<String> crossParamList = dragRuleDTO.getCrossParamDescList().stream().map(
                    DragRuleDTO.DragRuleParamsDesc::getParamName
            ).collect(Collectors.toList());
            dragRuleDTO.setCrossParamList(crossParamList);

            // 中专参数校验,当前规则传递参数影响所有调用此规则的规则链,需要全部进行校验
            for (String crossParam : dragRuleDTO.getCrossParamList()) {
                if (!outputParamJSON.containsKey(crossParam)) {
                    String errorMessage = StrUtil.format("拖拽规则传递参数必须为规则方法出参参数,[{}]不满足条件,请确认!",
                            crossParam);
                    throw new ServiceException(errorMessage);
                }
            }
            crossParamStr = dragRuleDTO.getCrossParamList().stream().map(
                    String::toString
            ).collect(Collectors.joining(StrUtil.COMMA));

            // 设置传递参数字符串
            dragRuleDTO.setCrossParam(crossParamStr);

            // 将outParamDescList转换为map,获取crossParamDesc描述信息
            Map<String, DragRuleDTO.DragRuleParamsDesc> outParamDescMap = dragRuleDTO
                    .getOutputParamDescList().stream()
                    .collect(Collectors.toMap(
                            DragRuleDTO.DragRuleParamsDesc::getParamName,
                            Function.identity(),
                            (k1, k2) -> k2)
                    );
            List<DragRuleDTO.DragRuleParamsDesc> crossParamDescList = new ArrayList<>();
            dragRuleDTO.getCrossParamList().forEach(paramName -> {
                DragRuleDTO.DragRuleParamsDesc dragRuleParamsDesc = outParamDescMap.get(paramName);
                if (ObjectUtil.isNotNull(dragRuleParamsDesc)) {
                    crossParamDescList.add(dragRuleParamsDesc);
                }
            });
            dragRuleDTO.setCrossParamDescList(crossParamDescList);
        } else {
            // 设置传递参数为空
            dragRuleDTO.setCrossParamList(null);
            dragRuleDTO.setCrossParam(null);
            dragRuleDTO.setCrossParamDescList(null);
        }

        // 获取全部带有当前规则的规则链信息
        QueryWrapper<TbSysDragChain> chainQueryWrapper = new QueryWrapper<>();
        chainQueryWrapper.lambda().like(TbSysDragChain::getDragRuleChain, dragRuleDTO.getDragRuleId());
        List<TbSysDragChain> dragRuleChainList = tbSysDragChainMapper.selectList(chainQueryWrapper);
        if (ObjectUtil.isNotEmpty(dragRuleChainList)) {
            // 开始进行规则链中规则校验
            for (TbSysDragChain dragRuleChain : dragRuleChainList) {
                dragRuleServerUtil.checkDragRuleUpdateLegal(dragRuleChain, dragRuleDTO);
            }
        }

        // 修改信息
        TbSysDragRule tbSysDragRule = dragRuleConvert.dragRuleDTOToDragRule(dragRuleDTO);
        tbSysDragRule.setCrossParam(crossParamStr);
        tbSysDragRule.setCustomOptionParam(dragOptionParamsStr);
        tbSysDragRuleMapper.updateCrossParamAndOptionParam(tbSysDragRule);

        // 修改缓存信息
        cacheDragRuleDTO.setIfLoadDB(RuleConstant.NUM_1_STR);
        cacheDragRuleDTO.setCrossParam(crossParamStr);
        cacheDragRuleDTO.setCrossParamList(dragRuleDTO.getCrossParamList());
        cacheDragRuleDTO.setCrossParamDescList(dragRuleDTO.getCrossParamDescList());
        cacheDragRuleDTO.setCustomOptionParam(dragOptionParamsStr);
        cacheDragRuleDTO.setCustomOptionParamList(dragRuleDTO.getCustomOptionParamList());
        redisUtil.hset(RuleConstant.DRAG_RULES, dragRuleDTO.getDragRuleId(), JSONObject.toJSONString(cacheDragRuleDTO));
    }

    /**
     * 删除拖拽规则
     *
     * @param id
     */
    @Override
    public void deleteDragRule(String id) {
        // 判断缓存中是否存在拖拽规则信息,如果不存在则证明 dragRuleId 传递有误
        Object dragRuleDTOObj = redisUtil.hget(RuleConstant.DRAG_RULES, id);
        if (ObjectUtil.isNull(dragRuleDTOObj)) {
            throw new ServiceException(StrUtil.format("通过规则id[{}]未获取到缓存规则信息,删除失败!", id));
        }
        // 获取缓存dragRule信息,获取出参参数信息
        DragRuleDTO cacheDragRuleDTO = JSONObject.parseObject(dragRuleDTOObj.toString(), DragRuleDTO.class);

        // 当前规则如果有规则链引用,则不能删除当前规则信息
        QueryWrapper<TbSysDragChain> chainQueryWrapper = new QueryWrapper<>();
        chainQueryWrapper.lambda().like(TbSysDragChain::getDragRuleChain, id);
        List<TbSysDragChain> dragRuleChainList = tbSysDragChainMapper.selectList(chainQueryWrapper);
        if (ObjectUtil.isNotEmpty(dragRuleChainList)) {
            // 拼接引用产品链信息
            String chainInfo = dragRuleChainList.stream().map(dragRuleChain -> "【规则链uri: "
                    .concat(dragRuleChain.getUri())
                    .concat(StrUtil.COMMA)
                    .concat("规则链id为: ")
                    .concat(dragRuleChain.getDragRuleChainId())
                    .concat("】")
            ).collect(Collectors.joining(StrUtil.COMMA));
            throw new ServiceException(StrUtil.format("当前拖拽规则[{}]有规则链[{}]引用,不能删除!", id, chainInfo));
        }

        // 产品规则链信息校验,如果产品规则链包含当前规则信息,需要先删除产品规则链中规则信息
        QueryWrapper<TbSysProductDragChain> productChainQueryWrapper = new QueryWrapper<>();
        productChainQueryWrapper.lambda().like(TbSysProductDragChain::getDragRuleChain, id);
        List<TbSysProductDragChain> productChainList = productDragChainMapper.selectList(productChainQueryWrapper);
        if (ObjectUtil.isNotEmpty(productChainList)) {
            // 使用产品规则中的uri,进行逗号分割,作为提示信息
            String chainInfo = productChainList.stream().map(productChain -> "【产品规则uri: "
                    .concat(productChain.getUri())
                    .concat(StrUtil.COMMA)
                    .concat("产品为productCd: ")
                    .concat(productChain.getProductCd())
                    .concat("】")).collect(Collectors.joining());
            throw new ServiceException(StrUtil
                    .format("当前删除规则[{}]被产品规则[{}]引用,请先删除产品规则链", id, chainInfo));
        }

        // 开始删除规则信息
        tbSysDragRuleMapper.deleteById(id);

        // 设定规则缓存信息是否落库字段为否,并清空自定义参数信息
        cacheDragRuleDTO.setIfLoadDB(RuleConstant.NUM_0_STR);
        cacheDragRuleDTO.setCrossParam(null);
        cacheDragRuleDTO.setCrossParamList(null);
        cacheDragRuleDTO.setCrossParamDescList(null);
        cacheDragRuleDTO.setCustomOptionParam(null);
        cacheDragRuleDTO.setCustomOptionParamList(null);
        redisUtil.hset(RuleConstant.DRAG_RULES, id, JSONObject.toJSONString(cacheDragRuleDTO));
    }

    /**
     * 分页查询拖拽规则信息
     * 参数有规则描述信息,模糊查询
     * 参数有规则id信息,精确查询
     * 查询结果由两部分拼接而成,注意:只有表数据中有数据才能进行规则链添加
     *  1:通过缓存信息,可以获取规则入参,出参等信息
     *  2:通过表数据,可以获取传递参数,自定义比较参数等
     *
     * @param dragRuleDTO
     * @return
     */
    @Override
    public PageBean<DragRuleDTO> getDragRulePage(DragRuleDTO dragRuleDTO) {
        // 获取所有拖拽规则缓存信息
        Map<Object, Object> cacheDragRuleObjMap = redisUtil.hmget(RuleConstant.DRAG_RULES);
        if (ObjectUtil.isEmpty(cacheDragRuleObjMap)) {
            throw new ServiceException("当前缓存中没有拖拽规则信息,请确认是否缓存中没有数据!");
        }

        // 将Map<Object, Object>类型,转换为Map<String, DragRuleDTO>类型,并且过滤出符合条件的规则信息
        Map<String, DragRuleDTO> cacheDragRuleMap = cacheDragRuleObjMap
                .entrySet()
                .stream()
                .filter(entry -> {
                    // 缓存信息,需要校验通过id,规则描述以及是否规则已经落库筛选
                    DragRuleDTO filterRule = JSONObject.parseObject((String) entry.getValue(), DragRuleDTO.class);
                    // id校验
                    boolean ifRuleIdCheck = true;
                    if (StrUtil.isNotBlank(dragRuleDTO.getDragRuleId())) {
                        ifRuleIdCheck = dragRuleDTO.getDragRuleId().equals(filterRule.getDragRuleId());
                    }
                    // 规则描述校验
                    boolean ifRuleDescCheck = true;
                    if (StrUtil.isNotBlank(dragRuleDTO.getRuleDesc())) {
                        ifRuleDescCheck = filterRule.getRuleDesc().contains(dragRuleDTO.getRuleDesc());
                    }
                    // 是否落库
                    boolean ifLoadDB = true;
                    if (StrUtil.isNotBlank(dragRuleDTO.getIfLoadDB())) {
                        ifLoadDB = dragRuleDTO.getIfLoadDB().equals(filterRule.getIfLoadDB());
                    }
                    return (ifRuleDescCheck && ifRuleIdCheck && ifLoadDB);
                })
                .collect(Collectors.toMap(
                        entry -> (String) entry.getKey(),
                        entry -> JSONObject.parseObject((String) entry.getValue(), DragRuleDTO.class)
                ));

        // 查询表中已经保存的规则信息,并且将信息转换为map
        QueryWrapper<TbSysDragRule> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(StrUtil.isNotBlank(dragRuleDTO.getDragRuleId()),
                TbSysDragRule::getDragRuleId,
                dragRuleDTO.getDragRuleId());
        queryWrapper.lambda().like(StrUtil.isNotBlank(dragRuleDTO.getRuleDesc()),
                TbSysDragRule::getRuleDesc,
                dragRuleDTO.getRuleDesc());
        List<TbSysDragRule> tbSysDragRuleList = tbSysDragRuleMapper.selectList(queryWrapper);
        Map<String, TbSysDragRule> tbSysDragRuleMap = new HashMap<>(RuleConstant.DEFAULT_MAP_SIZE);
        if (ObjectUtil.isNotEmpty(tbSysDragRuleList)) {
            tbSysDragRuleMap = tbSysDragRuleList.stream().collect(Collectors.toMap(
                    TbSysDragRule::getDragRuleId,
                    Function.identity(),
                    (k1, k2) -> k2
            ));
        }

        // 将缓存信息以及表中存在信息进行整合,注意其中表中的数据是经过保存的,可以进行使用,非表中的数据不允许使用,前端展示置灰,保存后正常使用
        Map<String, TbSysDragRule> finalTbSysDragRuleMap = tbSysDragRuleMap;
        List<DragRuleDTO> displayDragDTOList = cacheDragRuleMap.entrySet().stream().map(entry -> {
            // 设置返回参数信息
            DragRuleDTO localDragDTO = entry.getValue();
            String ruleDesc = entry.getValue().getRuleDesc();
            // 判断当前规则是否在表中存在,如果存在则设置是否落库为落库
            TbSysDragRule tbSysDragRule = finalTbSysDragRuleMap.get(localDragDTO.getDragRuleId());
            if (ObjectUtil.isNotNull(tbSysDragRule)) {
                localDragDTO = dragRuleConvert.dragRuleInitToDragRuleDTO(tbSysDragRule, localDragDTO);
                localDragDTO.setIfLoadDB(RuleConstant.NUM_1_STR);
                localDragDTO.setRuleDesc(ruleDesc);
                // 设置传递参数
                if (StrUtil.isNotBlank(tbSysDragRule.getCrossParam())) {
                    List<String> crossParamList = Arrays.asList(StrUtil.split(tbSysDragRule.getCrossParam(), RuleConstant.COMMA));
                    localDragDTO.setCrossParamList(crossParamList);
                    // 将outParamDescList转换为map,获取crossParamDesc描述信息
                    Map<String, DragRuleDTO.DragRuleParamsDesc> outParamDescMap = localDragDTO.getOutputParamDescList().stream()
                            .collect(
                                    Collectors.toMap(DragRuleDTO.DragRuleParamsDesc::getParamName,
                                            Function.identity())
                            );
                    List<DragRuleDTO.DragRuleParamsDesc> crossParamDescList = new ArrayList<>();
                    crossParamList.forEach(paramName -> {
                        DragRuleDTO.DragRuleParamsDesc dragRuleParamsDesc = outParamDescMap.get(paramName);
                        if (ObjectUtil.isNotNull(dragRuleParamsDesc)) {
                            crossParamDescList.add(dragRuleParamsDesc);
                        }
                    });
                    localDragDTO.setCrossParamDescList(crossParamDescList);
                }
                // 设置自定义参数信息
                if (StrUtil.isNotBlank(tbSysDragRule.getCustomOptionParam())) {
                    String customOptionParam = tbSysDragRule.getCustomOptionParam();

                    // 将json类型转换为 List<List<DragRuleDTO.CustomOptionParam>> 类型
                    List customOptionParamsList = JSONObject.parseArray(customOptionParam, List.class);
                    List<List<DragRuleDTO.CustomOptionParam>> typeList = new ArrayList<>();
                    for (Object customParamList : customOptionParamsList) {
                        List<JSONObject> jsonParamList = (List<JSONObject>) customParamList;
                        List<DragRuleDTO.CustomOptionParam> innerParamList = jsonParamList.stream().map(jsonParam -> {
                            return JSONObject.parseObject(jsonParam.toJSONString(), DragRuleDTO.CustomOptionParam.class);
                        }).collect(Collectors.toList());
                        typeList.add(innerParamList);
                    }
                }
            }
            return localDragDTO;
        }).collect(Collectors.toList());

        // 封装分页信息对象
        PageBean<DragRuleDTO> pageBean = customPageUtil.setFlowListPage(
                displayDragDTOList, PaginationContext.getPageNum(), PaginationContext.getPageSize());

        return pageBean;
    }

    /**
     * 添加链信息
     *
     * @param dragRuleChain 规则链
     * @param uri
     * @param file
     */
    @Override
    public void addChain(String dragRuleChain, String uri, MultipartFile file) throws IOException {
        // 解析文件内容,分别获取Task任务列表以及全部节点信息
        List<String> fileChainList = new ArrayList<>();
        try (InputStream inputStream = file.getInputStream();) {
            // 解析bpmn xml文件信息
            BpmnModelInstance modelInstance = Bpmn.readModelFromStream(inputStream);
            // 类型比较
            List<FlowElement> flowElements = (List<FlowElement>) modelInstance.getModelElementsByType(FlowElement.class);
            for (FlowElement element : flowElements) {
                Class<? extends FlowElement> elementType = element.getClass();
                // 获取类型名称
                String elementSimpleName = elementType.getSimpleName();
                // start,end,SequenceFlow以及Task类型为合法类型,其余类型为非法类型
                if (!dragRuleServerUtil.checkProcessFileType(elementSimpleName)) {
                    throw new ServiceException("当前规则链只支持Task节点链,其他类型暂不支持!");
                }
            }

            // task任务节点数量比较
            for (Task task : modelInstance.getModelElementsByType(Task.class)) {
                String taskName = task.getName();
                fileChainList.add(taskName);
            }
        } catch (IOException e) {
            String errorMessage = LogUtil.getStackTraceInfo(e);
            throw new ServiceException(StrUtil.format("解析文件内容异常,异常信息为[{}],请确认!", errorMessage));
        }

        // 文件内容判定,至少一个task任务
        if (fileChainList.size() == 0) {
            throw new ServiceException("规则链文件至少一个规则信息,请确认!");
        }

        // 文件名称,以及base64编码字符串
        String fileName = file.getOriginalFilename();
        String fileBase64Str = Base64.getEncoder().encodeToString(file.getBytes());

        // 获取缓存信息,作为最终返回参数
        Object dragRuleChainObj = redisUtil.hget(CommonDragRuleConstant.DRAG_RULE_CHAIN_FLAG, uri);
        if (ObjectUtil.isNull(dragRuleChainObj)) {
            throw new ServiceException(StrUtil.format("当前缓存中没有uri[{}]规则链信息,请确认是否缓存中没有数据!", uri));
        }
        DragChainDTO cacheDragChainDTO = JSONObject.parseObject(dragRuleChainObj.toString(), DragChainDTO.class);

        // 获取规则对应链信息,多个规则以逗号分隔
        String[] dragRuleChainIds = StrUtil.split(dragRuleChain, RuleConstant.COMMA);


        // 获取规则是否都为落库规则,如果不是落库规则以及文件中不存在该规则则抛出异常
        if (dragRuleChainIds.length > 0) {
            // 判定dragRuleChainIds是否重复
            Set<String> dragRuleChainSet = new HashSet<>();
            Collections.addAll(dragRuleChainSet, dragRuleChainIds);
            if (dragRuleChainSet.size() != dragRuleChainIds.length) {
                throw new ServiceException("当前规则链对应规则存在重复规则,请确认!");
            }

            QueryWrapper<TbSysDragRule> dragRuleQueryWrapper = new QueryWrapper<>();
            dragRuleQueryWrapper.lambda().in(TbSysDragRule::getDragRuleId, dragRuleChainIds);
            List<TbSysDragRule> dragRuleList = tbSysDragRuleMapper.selectList(dragRuleQueryWrapper);
            // 如果规则全部没有落库直接提示
            if (ObjectUtil.isEmpty(dragRuleList)) {
                String idStr = StrUtil.join(RuleConstant.COMMA, dragRuleChainIds);
                throw new ServiceException(StrUtil.format("当前保存规则链规则[{}]没有先进行落库保存操作,请先进行规则落库操作!", idStr));
            }
            // 部分没有落库需要进行比对,找出没有落库数据
            if (dragRuleList.size() != dragRuleChainIds.length) {
                // 找出不在数据库中的规则id
                List<String> dbIdList = dragRuleList.stream().map(
                        TbSysDragRule::getDragRuleId
                ).collect(Collectors.toList());
                List<String> differIdList = Arrays.stream(dragRuleChainIds)
                        .filter(id -> !dbIdList.contains(id))
                        .collect(Collectors.toList());
                String idStr = StrUtil.join(RuleConstant.COMMA, differIdList);
                throw new ServiceException(StrUtil.format("当前保存规则链部分规则[{}]没有先进行落库保存操作,请先进行规则落库操作!", idStr));
            }

            // 校验传入dragRule顺序与文件顺序以及长度是否一致,不一致则抛出异常
            if (fileChainList.size() != dragRuleChainIds.length) {
                throw new ServiceException("当前规则链长度与规则文件长度不一致,请确认!");
            }
            for (int i = 0; i < dragRuleChainIds.length; i++) {
                if (!dragRuleChainIds[i].equals(fileChainList.get(i))) {
                    throw new ServiceException("规则链传入规则与文件内规则顺序不一致,请确认!");
                }
            }
            cacheDragChainDTO.setDragRuleChain(dragRuleChain);
        }

        // 校验当前规则链参数是否合法,满足所有规则入参出参
        commonDragRuleUtil.checkDragRuleWithParamLegal(cacheDragChainDTO);

        // 开始添加规则链信息
        TbSysDragChain tbSysDragChain = dragRuleConvert.dragChainDTOToTbSysDragChain(cacheDragChainDTO);
        tbSysDragChain.setDragRuleChain(dragRuleChain);
        tbSysDragChain.setChainFileName(fileName);
        tbSysDragChain.setChainFile(fileBase64Str);
        tbSysDragChainMapper.insert(tbSysDragChain);

        // 修改规则链缓存信息
        cacheDragChainDTO.setIfLoadDB(RuleConstant.NUM_1_STR);
        redisUtil.hset(CommonDragRuleConstant.DRAG_RULE_CHAIN_FLAG,
                cacheDragChainDTO.getUri(), JSONObject.toJSONString(cacheDragChainDTO));
    }

    /**
     * 添加产品链信息初始化校验
     *
     * @param uri           uri
     * @param productCd     产品cd
     */
    @Override
    public void addProductChainInit(String uri, String productCd) throws IOException {
        // 校验uri对应规则链默认是否已经配置
        QueryWrapper<TbSysDragChain> dragChainQueryWrapper = new QueryWrapper<>();
        dragChainQueryWrapper.lambda().eq(TbSysDragChain::getUri, uri);
        TbSysDragChain tbSysDragChain = tbSysDragChainMapper.selectOne(dragChainQueryWrapper);
        if (ObjectUtil.isNull(tbSysDragChain)) {
            throw new ServiceException(StrUtil.format("当前拖拽规则默认规则未配置,请先前往参数管理=>规则链管理中,配置默认规则链!"));
        }

        // 校验当前产品规则链是否已经配置,如果配置则不能新增
        QueryWrapper<TbSysProductDragChain> productChainQueryWrapper = new QueryWrapper<>();
        productChainQueryWrapper.lambda().eq(TbSysProductDragChain::getUri, uri)
                .eq(TbSysProductDragChain::getProductCd, productCd);
        if (productDragChainMapper.selectCount(productChainQueryWrapper) > 0) {
            throw new ServiceException(StrUtil.format("当前产品[{}]对应uri[{}]已经存在规则链信息,不能进行新增操作!",
                    productCd, uri));
        }
    }

    /**
     * 添加产品链信息
     *
     * @param dragRuleChain
     * @param uri
     * @param file
     * @param productCd
     */
    @Override
    public void addProductChain(String dragRuleChain, String uri, MultipartFile file, String productCd) throws IOException {
        // 查看当前产品信息是否已经存在,如果存在则不能新增
        QueryWrapper<TbSysProductDragChain> productChainQueryWrapper = new QueryWrapper<>();
        productChainQueryWrapper.lambda().eq(TbSysProductDragChain::getUri, uri)
                .eq(TbSysProductDragChain::getProductCd, productCd);
        if (productDragChainMapper.selectCount(productChainQueryWrapper) > 0) {
            throw new ServiceException(StrUtil.format("当前产品[{}]对应uri[{}]已经存在规则链信息,新增失败!",
                    productCd, uri));
        }

        // 解析文件内容,分别获取Task任务列表以及全部节点信息
        List<String> fileChainList = new ArrayList<>();
        try (InputStream inputStream = file.getInputStream();) {
            // 解析bpmn xml文件信息
            BpmnModelInstance modelInstance = Bpmn.readModelFromStream(inputStream);
            // 类型比较
            List<FlowElement> flowElements = (List<FlowElement>) modelInstance.getModelElementsByType(FlowElement.class);
            for (FlowElement element : flowElements) {
                Class<? extends FlowElement> elementType = element.getClass();
                // 获取类型名称
                String elementSimpleName = elementType.getSimpleName();
                // start,end,SequenceFlow以及Task类型为合法类型,其余类型为非法类型
                if (!dragRuleServerUtil.checkProcessFileType(elementSimpleName)) {
                    throw new ServiceException("当前规则链只支持Task节点链,其他类型暂不支持!");
                }
            }

            // task任务节点数量比较
            for (Task task : modelInstance.getModelElementsByType(Task.class)) {
                String taskName = task.getName();
                fileChainList.add(taskName);
            }
        } catch (IOException e) {
            String errorMessage = LogUtil.getStackTraceInfo(e);
            throw new ServiceException(StrUtil.format("解析文件内容异常,异常信息为[{}],请确认!", errorMessage));
        }

        // 文件内容判定,至少一个task任务
        if (fileChainList.size() == 0) {
            throw new ServiceException("规则链文件至少一个规则信息,请确认!");
        }

        // 新增产品链规则是否落库校验
        if (StrUtil.isNotBlank(dragRuleChain)) {
            List<String> dragRuleIdList = Arrays.stream(dragRuleChain.split(RuleConstant.COMMA))
                    .collect(Collectors.toList());

            // 判定dragRuleIdList是否重复
            if (dragRuleIdList.size() != dragRuleIdList.stream().distinct().count()) {
                throw new ServiceException("当前规则链中规则存在重复,请确认!");
            }

            QueryWrapper<TbSysDragRule> dragRuleQueryWrapper = new QueryWrapper<>();
            dragRuleQueryWrapper.lambda().in(TbSysDragRule::getDragRuleId, dragRuleIdList);
            List<TbSysDragRule> dragRuleList = tbSysDragRuleMapper.selectList(dragRuleQueryWrapper);
            // 所有规则都没有落库
            if (ObjectUtil.isEmpty(dragRuleList)) {
                throw new ServiceException("当前规则链规则没有先进行落库保存操作,请先进行规则落库操作!");
            } else if (dragRuleList.size() != dragRuleIdList.size()) {
                // 查询出部分落库规则数据,但是部分规则没有落库,获取dragRuleList中,dragRuleIdList中不存在的dragRuleId
                List<String> dragRuleDifferList = dragRuleIdList.stream()
                        .filter(dragRuleId -> !dragRuleList.stream()
                                .map(TbSysDragRule::getDragRuleId)
                                .collect(Collectors.toList())
                                .contains(dragRuleId))
                        .collect(Collectors.toList());
                String dragDifferStr = String.join(StrUtil.COMMA, dragRuleDifferList);
                throw new ServiceException(StrUtil
                        .format("当前规则链部分规则[{}]没有先进行落库保存操作,请先进行规则落库操作!", dragDifferStr));
            }
        }

        // 规则链默认配置必填校验
        QueryWrapper<TbSysDragChain> dragChainQueryWrapper = new QueryWrapper<>();
        dragChainQueryWrapper.lambda().eq(TbSysDragChain::getUri, uri);
        TbSysDragChain tbSysDragChain = tbSysDragChainMapper.selectOne(dragChainQueryWrapper);
        if (ObjectUtil.isNull(tbSysDragChain)) {
            throw new ServiceException(StrUtil.format("当前拖拽规则默认规则未配置,请先前往参数管理=>规则链管理中,配置默认规则链!"));
        }

        // 文件名称,以及base64编码字符串
        String fileName = file.getOriginalFilename();
        String fileBase64Str = Base64.getEncoder().encodeToString(file.getBytes());

        // 前端调用了规则链校验接口,后端便不进行校验了,直接写入产品规则链信息
        TbSysProductDragChain tbSysProductDragChain = new TbSysProductDragChain();
        tbSysProductDragChain.setProductChainId(IdUtil.simpleUUID());
        tbSysProductDragChain.setProductCd(productCd);
        tbSysProductDragChain.setChainFile(fileBase64Str);
        tbSysProductDragChain.setChainFileName(fileName);
        tbSysProductDragChain.setUri(uri);
        tbSysProductDragChain.setDragRuleChain(dragRuleChain);
        tbSysProductDragChain.setCtime(new Date());
        tbSysProductDragChain.setMtime(new Date());
        productDragChainMapper.insert(tbSysProductDragChain);

        // 缓存key为 uri + ":" + productCd格式
        String productChainKey = uri.concat(StrUtil.COLON).concat(productCd);
        redisUtil.hset(CommonDragRuleConstant.DRAG_RULE_PRODUCT_CHAIN_FLAG,
                productChainKey, JSONObject.toJSONString(tbSysProductDragChain));
    }

    /**
     * 修改链信息
     *
     * @param dragRuleChain
     * @param uri
     * @param file
     */
    @Override
    public void updateChain(String dragRuleChain, String uri, MultipartFile file) throws IOException {
        // 解析文件内容
        List<String> fileChainList = new ArrayList<>();
        try (InputStream inputStream = file.getInputStream();) {
            // 解析bpmn xml文件信息
            BpmnModelInstance modelInstance = Bpmn.readModelFromStream(inputStream);

            // 类型比较
            List<FlowElement> flowElements = (List<FlowElement>) modelInstance.getModelElementsByType(FlowElement.class);
            for (FlowElement element : flowElements) {
                Class<? extends FlowElement> elementType = element.getClass();
                // 获取类型名称
                String elementSimpleName = elementType.getSimpleName();
                // start,end,SequenceFlow以及Task类型为合法类型,其余类型为非法类型
                if (!dragRuleServerUtil.checkProcessFileType(elementSimpleName)) {
                    throw new ServiceException("当前规则链只支持Task节点链,其他类型暂不支持!");
                }
            }

            for (Task task : modelInstance.getModelElementsByType(Task.class)) {
                String taskName = task.getName();
                fileChainList.add(taskName);
            }
        } catch (IOException e) {
            String errorMessage = LogUtil.getStackTraceInfo(e);
            throw new ServiceException(StrUtil.format("解析文件内容异常,异常信息为[{}],请确认!", errorMessage));
        }
        // 文件内容判定,至少一个task任务
        if (fileChainList.size() == 0) {
            throw new ServiceException("规则链文件至少一个规则信息,请确认!");
        }

        // 文件名称,以及base64编码字符串
        String fileName = file.getOriginalFilename();
        String fileBase64Str = Base64.getEncoder().encodeToString(file.getBytes());

        // 获取缓存信息,作为最终返回参数
        Object dragRuleChainObj = redisUtil.hget(CommonDragRuleConstant.DRAG_RULE_CHAIN_FLAG, uri);
        if (ObjectUtil.isNull(dragRuleChainObj)) {
            throw new ServiceException(StrUtil.format("当前缓存中没有uri[{}]规则链信息,请确认是否缓存中没有数据!", uri));
        }
        DragChainDTO cacheDragChainDTO = JSONObject.parseObject(dragRuleChainObj.toString(), DragChainDTO.class);

        // 校验规则是否已经落库
        TbSysDragChain dragChain = tbSysDragChainMapper.selectById(cacheDragChainDTO.getDragRuleChainId());
        if (ObjectUtil.isNull(dragChain)) {
            throw new ServiceException(StrUtil.format("库中未获取到当前拖拽规则链[{}],不能进行修改操作!", cacheDragChainDTO.getDragRuleChainId()));
        }

        // 获取规则对应链信息,多个规则以逗号分隔
        String[] dragRuleChainIds = StrUtil.split(dragRuleChain, RuleConstant.COMMA);

        // 获取规则是否都为落库规则,如果不是落库规则直接抛出异常
        if (dragRuleChainIds.length > 0) {
            // 判定dragRuleChainIds是否重复
            Set<String> dragRuleChainSet = new HashSet<>();
            Collections.addAll(dragRuleChainSet, dragRuleChainIds);
            if (dragRuleChainSet.size() != dragRuleChainIds.length) {
                throw new ServiceException("当前规则链对应规则存在重复规则,请确认!");
            }

            // 获取数据库规则信息
            QueryWrapper<TbSysDragRule> dragRuleQueryWrapper = new QueryWrapper<>();
            dragRuleQueryWrapper.lambda().in(TbSysDragRule::getDragRuleId, dragRuleChainIds);
            List<TbSysDragRule> dragRuleList = tbSysDragRuleMapper.selectList(dragRuleQueryWrapper);
            // 如果规则全部没有落库直接提示
            if (ObjectUtil.isEmpty(dragRuleList)) {
                String idStr = StrUtil.join(RuleConstant.COMMA, dragRuleChainIds);
                throw new ServiceException(StrUtil.format("当前保存规则链规则[{}]没有先进行落库保存操作,请先进行规则落库操作!", idStr));
            }
            // 部分没有落库需要进行比对,找出没有落库数据
            if (dragRuleList.size() != dragRuleChainIds.length) {
                // 找出不在数据库中的规则id
                List<String> dbIdList = dragRuleList.stream().map(
                        TbSysDragRule::getDragRuleId
                ).collect(Collectors.toList());
                List<String> differIdList = Arrays.stream(dragRuleChainIds)
                        .filter(id -> !dbIdList.contains(id))
                        .collect(Collectors.toList());
                String idStr = StrUtil.join(RuleConstant.COMMA, differIdList);
                throw new ServiceException(StrUtil.format("当前保存规则链部分规则[{}]没有先进行落库保存操作,请先进行规则落库操作!", idStr));
            }

            // 校验传入dragRule顺序与文件顺序以及长度是否一致,不一致则抛出异常
            if (fileChainList.size() != dragRuleChainIds.length) {
                throw new ServiceException("当前规则链长度与规则文件长度不一致,请确认!");
            }
            for (int i = 0; i < dragRuleChainIds.length; i++) {
                if (!dragRuleChainIds[i].equals(fileChainList.get(i))) {
                    throw new ServiceException(StrUtil.format(
                            "规则链传入第[{}]个规则与文件内规则顺序不一致,内容分别为[{}]以及[{}]请确认!",
                            i + 1,
                            dragRuleChainIds[i],
                            fileChainList.get(i)));
                }
            }
            cacheDragChainDTO.setDragRuleChain(dragRuleChain);
        }

        // 校验当前规则链参数是否合法,满足所有规则入参出参
        commonDragRuleUtil.checkDragRuleWithParamLegal(cacheDragChainDTO);

        // 修改规则链信息
        TbSysDragChain tbSysDragChain = dragRuleConvert.dragChainDTOToTbSysDragChain(cacheDragChainDTO);
        tbSysDragChain.setChainFile(fileBase64Str);
        tbSysDragChain.setChainFileName(fileName);
        tbSysDragChain.setDragRuleChain(dragRuleChain);
        tbSysDragChainMapper.updateById(tbSysDragChain);

        // 修改缓存信息
        redisUtil.hset(CommonDragRuleConstant.DRAG_RULE_CHAIN_FLAG,
                cacheDragChainDTO.getUri(), JSONObject.toJSONString(cacheDragChainDTO));
    }

    /**
     * 修改产品链信息
     *
     * @param dragRuleChain 规则链
     * @param uri           uri
     * @param file          文件
     * @param productCd
     */
    @Override
    public void updateProductChain(String dragRuleChain, String uri, MultipartFile file, String productCd) throws IOException {
        // 查看当前产品信息是否已经存在,不存在不能进行修改操作
        QueryWrapper<TbSysProductDragChain> productChainQueryWrapper = new QueryWrapper<>();
        productChainQueryWrapper.lambda().eq(TbSysProductDragChain::getUri, uri)
                .eq(TbSysProductDragChain::getProductCd, productCd);
        TbSysProductDragChain productChain = productDragChainMapper.selectOne(productChainQueryWrapper);
        if (ObjectUtil.isNull(productChain)) {
            throw new ServiceException(StrUtil.format("当前产品[{}]对应uri[{}]不存在规则链信息,修改失败!",
                    productCd, uri));
        }

        // 解析文件内容
        List<String> fileChainList = new ArrayList<>();
        try (InputStream inputStream = file.getInputStream();) {
            // 解析bpmn xml文件信息
            BpmnModelInstance modelInstance = Bpmn.readModelFromStream(inputStream);

            // 类型比较
            List<FlowElement> flowElements = (List<FlowElement>) modelInstance.getModelElementsByType(FlowElement.class);
            for (FlowElement element : flowElements) {
                Class<? extends FlowElement> elementType = element.getClass();
                // 获取类型名称
                String elementSimpleName = elementType.getSimpleName();
                // start,end,SequenceFlow以及Task类型为合法类型,其余类型为非法类型
                if (!dragRuleServerUtil.checkProcessFileType(elementSimpleName)) {
                    throw new ServiceException("当前规则链只支持Task节点链,其他类型暂不支持!");
                }
            }

            for (Task task : modelInstance.getModelElementsByType(Task.class)) {
                String taskName = task.getName();
                fileChainList.add(taskName);
            }
        } catch (IOException e) {
            String errorMessage = LogUtil.getStackTraceInfo(e);
            throw new ServiceException(StrUtil.format("解析文件内容异常,异常信息为[{}],请确认!", errorMessage));
        }
        // 文件内容判定,至少一个task任务
        if (fileChainList.size() == 0) {
            throw new ServiceException("规则链文件至少一个规则信息,请确认!");
        }

        // 修改规则必须为落库规则校验
        if (StrUtil.isNotBlank(dragRuleChain)) {
            List<String> dragRuleIdList = Arrays.stream(dragRuleChain.split(RuleConstant.COMMA))
                    .collect(Collectors.toList());

            // 判定dragRuleIdList是否重复
            if (dragRuleIdList.size() != dragRuleIdList.stream().distinct().count()) {
                throw new ServiceException("当前规则链中规则存在重复,请确认!");
            }

            QueryWrapper<TbSysDragRule> dragRuleQueryWrapper = new QueryWrapper<>();
            dragRuleQueryWrapper.lambda().in(TbSysDragRule::getDragRuleId, dragRuleIdList);
            List<TbSysDragRule> dragRuleList = tbSysDragRuleMapper.selectList(dragRuleQueryWrapper);
            if (ObjectUtil.isEmpty(dragRuleList) || dragRuleList.size() != dragRuleIdList.size()) {
                throw new ServiceException(StrUtil
                        .format("当前规则链部分规则[{}]没有先进行落库保存操作,请先进行规则落库操作!", dragRuleChain));
            }
        }

        // 规则链默认配置必填校验
        QueryWrapper<TbSysDragChain> dragChainQueryWrapper = new QueryWrapper<>();
        dragChainQueryWrapper.lambda().eq(TbSysDragChain::getUri, uri);
        TbSysDragChain tbSysDragChain = tbSysDragChainMapper.selectOne(dragChainQueryWrapper);
        if (ObjectUtil.isNull(tbSysDragChain)) {
            throw new ServiceException(StrUtil.format("当前拖拽规则默认规则未配置,请先前往参数管理=>规则链管理中,配置默认规则链!"));
        }

        // 文件名称,以及base64编码字符串
        String fileName = file.getOriginalFilename();
        String fileBase64Str = Base64.getEncoder().encodeToString(file.getBytes());

        // 进行规则链规则信息修改
        productChain.setChainFile(fileBase64Str);
        productChain.setChainFileName(fileName);
        productChain.setMtime(new Date());
        productChain.setDragRuleChain(dragRuleChain);
        productDragChainMapper.updateById(productChain);

        // 更新缓存信息,更新key为 uri + ":" + productCd
        String updateKey = uri.concat(StrUtil.COLON).concat(productCd);
        redisUtil.hset(CommonDragRuleConstant.DRAG_RULE_PRODUCT_CHAIN_FLAG,
                updateKey, JSONObject.toJSONString(productChain));
    }

    /**
     * 通过uri查询链信息
     *
     * @param uri
     * @return
     */
    @Override
    public DragChainDTO getDragChain(String uri) {
        // 获取缓存信息,作为最终返回参数
        Object dragRuleChainObj = redisUtil.hget(CommonDragRuleConstant.DRAG_RULE_CHAIN_FLAG, uri);
        if (ObjectUtil.isNull(dragRuleChainObj)) {
            throw new ServiceException(StrUtil.format("当前缓存中没有uri[{}]规则链信息,请确认是否缓存中没有数据!", uri));
        }
        DragChainDTO dragChainDTO = JSONObject.parseObject(dragRuleChainObj.toString(), DragChainDTO.class);

        // 获取数据库信息,将id以及链信息进行整合,赋值到返回参数dto中
        QueryWrapper<TbSysDragChain> chainQueryWrapper = new QueryWrapper<>();
        chainQueryWrapper.lambda().eq(TbSysDragChain::getUri, uri);
        TbSysDragChain tbSysDragRuleChain = tbSysDragChainMapper.selectOne(chainQueryWrapper);
        if (ObjectUtil.isNotNull(tbSysDragRuleChain)) {
            dragChainDTO.setDragRuleChainId(tbSysDragRuleChain.getDragRuleChainId());
            dragChainDTO.setDragRuleChain(tbSysDragRuleChain.getDragRuleChain());
            dragChainDTO.setIfLoadDB(RuleConstant.NUM_1_STR);
        }

        return dragChainDTO;
    }

    /**
     * 通过uri和productCd查询链信息
     *
     * @param uri
     * @param productCd
     * @return
     */
    @Override
    public DragChainDTO getDragProductChain(String uri, String productCd) {
        // 获取缓存信息,作为最终返回参数
        Object dragRuleChainObj = redisUtil.hget(CommonDragRuleConstant.DRAG_RULE_CHAIN_FLAG, uri);
        if (ObjectUtil.isNull(dragRuleChainObj)) {
            throw new ServiceException(StrUtil.format("当前缓存中没有uri[{}]规则链信息,请确认是否缓存中没有数据!", uri));
        }
        DragChainDTO dragChainDTO = JSONObject.parseObject(dragRuleChainObj.toString(), DragChainDTO.class);

        // 获取数据库信息,将id以及链信息进行整合,赋值到返回参数dto中
        QueryWrapper<TbSysDragChain> chainQueryWrapper = new QueryWrapper<>();
        chainQueryWrapper.lambda().eq(TbSysDragChain::getUri, uri);
        TbSysDragChain tbSysDragRuleChain = tbSysDragChainMapper.selectOne(chainQueryWrapper);
        if (ObjectUtil.isNotNull(tbSysDragRuleChain)) {
            dragChainDTO.setDragRuleChainId(tbSysDragRuleChain.getDragRuleChainId());
            dragChainDTO.setDragRuleChain(tbSysDragRuleChain.getDragRuleChain());
            dragChainDTO.setIfLoadDB(RuleConstant.NUM_1_STR);
        }

        // 通过uri以及产品cd获取产品链信息
        QueryWrapper<TbSysProductDragChain> productChainQueryWrapper = new QueryWrapper<>();
        productChainQueryWrapper.lambda().eq(TbSysProductDragChain::getProductCd, productCd)
                .eq(TbSysProductDragChain::getUri, uri);
        TbSysProductDragChain productDragChain = productDragChainMapper.selectOne(productChainQueryWrapper);
        if (ObjectUtil.isNotNull(productDragChain)) {
            dragChainDTO.setProductChainId(productDragChain.getProductChainId());
            dragChainDTO.setDragProductRuleChain(productDragChain.getDragRuleChain());
            dragChainDTO.setIfLoadDB(RuleConstant.NUM_1_STR);
        }

        // 设置产品cd
        dragChainDTO.setProductCd(productCd);
        return dragChainDTO;
    }

    /**
     * 获取规则文件信息
     *
     * @param uri
     * @throws IOException
     */
    @Override
    public void downloadFile(String uri) throws IOException {
        QueryWrapper<TbSysDragChain> chainQueryWrapper = new QueryWrapper<>();
        chainQueryWrapper.lambda().eq(TbSysDragChain::getUri, uri);
        TbSysDragChain tbSysDragRuleChain = tbSysDragChainMapper.selectOne(chainQueryWrapper);
        if (ObjectUtil.isNull(tbSysDragRuleChain) || StrUtil.isBlank(tbSysDragRuleChain.getChainFile())) {
            throw new ServiceException(StrUtil.format("通过uri[{}]获取规则链文件信息为空!", uri));
        }

        // 获取文件信息
        String base64FileStr = tbSysDragRuleChain.getChainFile();
        String fileName = tbSysDragRuleChain.getChainFileName();
        byte[] decodedBytes = Base64.getDecoder().decode(base64FileStr);
        // 设置响应头信息,比如Content-Type和Content-Disposition
        response.setContentType(CommonDragRuleConstant.APPLICATION_XML);
        // 根据实际文件类型设置MIME类型,这里是XML文件
        response.setHeader(CommonDragRuleConstant.CONTENT_DISPOSITION, "attachment;filename=\"" + fileName + "\"");
        try (OutputStream out = response.getOutputStream()) {
            out.write(decodedBytes);
        } catch (IOException e) {
            // 处理IO异常
            String errorMessage = LogUtil.getStackTraceInfo(e);
            throw new ServiceException(StrUtil.format("下载文件异常,异常信息为[{}]", errorMessage));
        } finally {
            response.flushBuffer();
        }
    }

    /**
     * 单个产品规则链文件获取
     *
     * @param uri
     * @param productCd
     * @throws IOException
     */
    @Override
    public void downloadProductFile(String uri, String productCd) throws IOException {
        QueryWrapper<TbSysProductDragChain> chainQueryWrapper = new QueryWrapper<>();
        chainQueryWrapper.lambda().eq(TbSysProductDragChain::getUri, uri)
                .eq(TbSysProductDragChain::getProductCd, productCd);
        TbSysProductDragChain productDragChain = productDragChainMapper.selectOne(chainQueryWrapper);
        if (ObjectUtil.isNull(productDragChain) || StrUtil.isBlank(productDragChain.getChainFile())) {
            throw new ServiceException(StrUtil.format("通过uri[{}]以及产品cd[{}]获取产品规则链文件信息为空!",
                    uri, productCd));
        }

        // 获取文件信息
        String base64FileStr = productDragChain.getChainFile();
        String fileName = productDragChain.getChainFileName();
        byte[] decodedBytes = Base64.getDecoder().decode(base64FileStr);
        // 设置响应头信息,比如Content-Type和Content-Disposition
        response.setContentType(CommonDragRuleConstant.APPLICATION_XML);
        // 根据实际文件类型设置MIME类型,这里是XML文件
        response.setHeader(CommonDragRuleConstant.CONTENT_DISPOSITION, "attachment;filename=\"" + fileName + "\"");
        try (OutputStream out = response.getOutputStream()) {
            out.write(decodedBytes);
        } catch (IOException e) {
            // 处理IO异常
            String errorMessage = LogUtil.getStackTraceInfo(e);
            throw new ServiceException(StrUtil.format("下载文件异常,异常信息为[{}]", errorMessage));
        } finally {
            response.flushBuffer();
        }
    }

    /**
     * 获取规则文件信息
     *
     * @param uri
     */
    @Override
    public String getXMLStr(String uri) {
        QueryWrapper<TbSysDragChain> chainQueryWrapper = new QueryWrapper<>();
        chainQueryWrapper.lambda().eq(TbSysDragChain::getUri, uri);
        TbSysDragChain tbSysDragRuleChain = tbSysDragChainMapper.selectOne(chainQueryWrapper);
        if (ObjectUtil.isNull(tbSysDragRuleChain) || StrUtil.isBlank(tbSysDragRuleChain.getChainFile())) {
            throw new ServiceException(StrUtil.format("通过uri[{}]获取规则链文件信息为空!", uri));
        }

        // 获取文件信息
        String base64FileStr = tbSysDragRuleChain.getChainFile();
        byte[] decodedBytes = Base64.getDecoder().decode(base64FileStr);
        return new String(decodedBytes, StandardCharsets.UTF_8);
    }

    /**
     * 获取产品规则文件xml信息
     *
     * @param uri
     * @param productCd
     * @throws IOException
     */
    @Override
    public String getProductXMLStr(String uri, String productCd) throws IOException {
        QueryWrapper<TbSysProductDragChain> chainQueryWrapper = new QueryWrapper<>();
        chainQueryWrapper.lambda().eq(TbSysProductDragChain::getUri, uri)
                .eq(TbSysProductDragChain::getProductCd, productCd);
        TbSysProductDragChain tbSysDragRuleChain = productDragChainMapper.selectOne(chainQueryWrapper);
        if (ObjectUtil.isNull(tbSysDragRuleChain) || StrUtil.isBlank(tbSysDragRuleChain.getChainFile())) {
            throw new ServiceException(StrUtil.format("通过uri[{}]以及产品cd[{}]获取规则链文件信息为空!",
                    uri, productCd));
        }

        // 获取文件信息
        String base64FileStr = tbSysDragRuleChain.getChainFile();
        byte[] decodedBytes = Base64.getDecoder().decode(base64FileStr);
        return new String(decodedBytes, StandardCharsets.UTF_8);
    }

    /**
     * 分页查询链信息
     *
     * 规则链信息分为两部分,一部分为class定义规则切入点参数信息等,为初始化业务子模块获取,一部分为表中存储为保存规则链,存入表中
     * 分别进行controllerName,controllerDesc,methodName,methodDesc,uri,以及dragChain的模糊查询
     * @param dragChainDTO
     * @return
     */
    @Override
    public PageBean<DragChainDTO> getDragChainPage(DragChainDTO dragChainDTO) {
        // 获取所有规则链缓存信息
        Map<Object, Object> cacheDragChainObj = redisUtil.hmget(CommonDragRuleConstant.DRAG_RULE_CHAIN_FLAG);
        if (ObjectUtil.isEmpty(cacheDragChainObj)) {
            throw new ServiceException(StrUtil.format("获取规则链列表[DRAG_RULE_CHAIN_FLAG]缓存信息为空,请确认!"));
        }

        // 将Map<Object, Object>类型,转换为Map<String, DragChainDTO>类型,并且过滤出符合条件的规则信息
        Map<String, DragChainDTO> cacheDragChainMap = cacheDragChainObj
                .entrySet()
                .stream()
                .filter(entry -> {
                    // 当前过滤对象,分别进行 controllerName,controllerDesc,methodName,methodDesc,uri,ifLoadDB是否落库,模块校验以及 dragChain 的校验进行过滤
                    DragChainDTO localDragChainDTO = JSONObject.parseObject(entry.getValue().toString(), DragChainDTO.class);
                    // controllerName校验
                    boolean ifControllerNameCheck = true;
                    if (StrUtil.isNotBlank(dragChainDTO.getControllerName())) {
                        ifControllerNameCheck = localDragChainDTO.getControllerName().contains(dragChainDTO.getControllerName());
                    }
                    // controllerDesc校验
                    boolean ifControllerDescCheck = true;
                    if (StrUtil.isNotBlank(dragChainDTO.getControllerDesc())) {
                        ifControllerDescCheck = localDragChainDTO.getControllerDesc().contains(dragChainDTO.getControllerDesc());
                    }
                    // methodName校验
                    boolean ifMethodNameCheck = true;
                    if (StrUtil.isNotBlank(dragChainDTO.getMethodName())) {
                        ifMethodNameCheck = localDragChainDTO.getMethodName().contains(dragChainDTO.getMethodName());
                    }
                    // methodDesc校验
                    boolean ifMethodDescCheck = true;
                    if (StrUtil.isNotBlank(dragChainDTO.getMethodDesc())) {
                        ifMethodDescCheck = localDragChainDTO.getMethodDesc().contains(dragChainDTO.getMethodDesc());
                    }
                    // uri校验
                    boolean ifUriCheck = true;
                    if (StrUtil.isNotBlank(dragChainDTO.getUri())) {
                        ifUriCheck = localDragChainDTO.getUri().contains(dragChainDTO.getUri());
                    }
                    // 模块校验
                    boolean ifModuleCheck = true;
                    if (StrUtil.isNotBlank(dragChainDTO.getDragChainModule())) {
                        ifModuleCheck = localDragChainDTO.getUri().startsWith(dragChainDTO.getDragChainModule());
                    }
                    // 是否落库校验
                    boolean ifIfLoadDBCheck = true;
                    if (StrUtil.isNotBlank(dragChainDTO.getIfLoadDB())) {
                        ifIfLoadDBCheck = dragChainDTO.getIfLoadDB().equals(localDragChainDTO.getIfLoadDB());
                    }
                    // 规则链校验
                    boolean ifDragRuleChainCheck = true;
                    if (StrUtil.isNotBlank(dragChainDTO.getDragRuleChain())) {
                        if (StrUtil.isBlank(localDragChainDTO.getDragRuleChain())) {
                            ifDragRuleChainCheck = false;
                        } else {
                            ifDragRuleChainCheck = localDragChainDTO.getDragRuleChain().contains(dragChainDTO.getDragRuleChain());
                        }
                    }

                    // 最终结论需要全部满足
                    return ifControllerNameCheck
                            && ifControllerDescCheck
                            && ifMethodNameCheck
                            && ifMethodDescCheck
                            && ifUriCheck
                            && ifModuleCheck
                            && ifIfLoadDBCheck
                            && ifDragRuleChainCheck;
                })
                .collect(Collectors.toMap(
                        entry -> entry.getKey().toString(),
                        entry -> JSONObject.parseObject(entry.getValue().toString(), DragChainDTO.class),
                        (k1, k2) -> k2
                ));

        // 查询表中已经保存的规则链信息,并且将信息转换为map,分别进行controllerName,controllerDesc,methodName,methodDesc,uri,以及dragChain过滤
        QueryWrapper<TbSysDragChain> chainQueryWrapper = new QueryWrapper<>();
        chainQueryWrapper.lambda().like(StrUtil.isNotBlank(dragChainDTO.getControllerName()),
                TbSysDragChain::getControllerName, dragChainDTO.getControllerName());
        chainQueryWrapper.lambda().like(StrUtil.isNotBlank(dragChainDTO.getControllerDesc()),
                TbSysDragChain::getControllerDesc, dragChainDTO.getControllerDesc());
        chainQueryWrapper.lambda().like(StrUtil.isNotBlank(dragChainDTO.getMethodName()),
                TbSysDragChain::getMethodName, dragChainDTO.getMethodName());
        chainQueryWrapper.lambda().like(StrUtil.isNotBlank(dragChainDTO.getMethodDesc()),
                TbSysDragChain::getMethodDesc, dragChainDTO.getMethodDesc());
        chainQueryWrapper.lambda().like(StrUtil.isNotBlank(dragChainDTO.getUri()),
                TbSysDragChain::getUri, dragChainDTO.getUri());
        chainQueryWrapper.lambda().like(StrUtil.isNotBlank(dragChainDTO.getDragRuleChain()),
                TbSysDragChain::getDragRuleChain, dragChainDTO.getDragRuleChain());
        chainQueryWrapper.lambda().likeRight(StrUtil.isNotBlank(dragChainDTO.getDragChainModule()),
                TbSysDragChain::getUri, dragChainDTO.getDragChainModule());
        List<TbSysDragChain> tbSysDragRuleChainList = tbSysDragChainMapper.selectList(chainQueryWrapper);
        Map<String, TbSysDragChain> tbSysDragChainMap = new HashMap<>(RuleConstant.DEFAULT_MAP_SIZE);
        if (ObjectUtil.isNotEmpty(tbSysDragRuleChainList)) {
            tbSysDragChainMap = tbSysDragRuleChainList.stream().collect(Collectors.toMap(
                    TbSysDragChain::getDragRuleChainId,
                    Function.identity(),
                    (k1, k2) -> k2
            ));
        }

        // 将缓存信息以及表中存在规则链信息进行整合,注意其中表中的数据是经过保存的,可以进行使用,非表中的数据不允许使用,前端展示置灰,保存后正常使用
        Map<String, TbSysDragChain> finalTbSysDragChainMap = tbSysDragChainMap;
        List<DragChainDTO> displayDragChainDTOList = cacheDragChainMap
                .entrySet()
                .stream()
                .map(entry -> {
                    DragChainDTO localDragChainDTO = entry.getValue();
                    // 判断当前规则是否在表中存在,如果存在则设置是否落库为落库
                    TbSysDragChain tbSysDragChain = finalTbSysDragChainMap.get(localDragChainDTO.getDragRuleChainId());
                    if (ObjectUtil.isNotNull(tbSysDragChain)) {
                        localDragChainDTO.setIfLoadDB(RuleConstant.NUM_1_STR);
                        localDragChainDTO.setDragRuleChain(tbSysDragChain.getDragRuleChain());
                    }
                    // 设置模块信息英文描述转换为中文
                    localDragChainDTO.setDragChainModule(dragRuleServerUtil.modelEnDescToCHDesc(localDragChainDTO.getDragChainModule()));

                    // 设置产品链信息
                    if (StrUtil.isNotBlank(dragChainDTO.getProductCd())) {
                        // 通过产品cd以及uri查询产品规则链信息
                        QueryWrapper<TbSysProductDragChain> productDragChainQueryWrapper = new QueryWrapper<>();
                        productDragChainQueryWrapper.lambda().eq(TbSysProductDragChain::getProductCd, dragChainDTO.getProductCd())
                                .eq(TbSysProductDragChain::getUri, localDragChainDTO.getUri());
                        TbSysProductDragChain tbSysProductDragChain = productDragChainMapper.selectOne(productDragChainQueryWrapper);
                        if (ObjectUtil.isNotNull(tbSysProductDragChain)) {
                            // 设置产品链信息
                            localDragChainDTO.setDragProductRuleChain(tbSysProductDragChain.getDragRuleChain());
                        }

                    }
                    return localDragChainDTO;
                })
                .collect(Collectors.toList());

        // 封装分页信息对象
        PageBean<DragChainDTO> pageBean = customPageUtil.setFlowListPage(
                displayDragChainDTOList, PaginationContext.getPageNum(), PaginationContext.getPageSize());

        return pageBean;
    }

    /**
     * 分页查询产品链信息
     *
     * @param dragChainDTO
     * @return
     */
    @Override
    public PageBean<DragChainDTO> getDragProductChainPage(DragChainDTO dragChainDTO) {
        // 获取所有产品规则链分页信息
        Page<DragChainDTO> page = new Page<>(PaginationContext.getPageNum(), PaginationContext.getPageSize());
        IPage<DragChainDTO> dragChainIPage = productDragChainMapper.selectDragProductPage(page, dragChainDTO);
        PageBean<DragChainDTO> pageBean = new PageBean<>(dragChainIPage);

        // 进行模块信息转义
        List<DragChainDTO> dragChainDTOList = pageBean.getResult();
        List<DragChainDTO> convertResult = dragChainDTOList.stream().map(chainDTO -> {
            // 从uri中判定当前模块信息
            String dragModuleCHN = dragRuleServerUtil.modelEnDescToCHDesc(chainDTO.getUri());
            chainDTO.setDragChainModule(dragModuleCHN);
            return chainDTO;
        }).collect(Collectors.toList());
        pageBean.setResult(convertResult);
        return pageBean;
    }

    /**
     * 通过id查询链信息
     *
     * @param uri
     * @return
     */
    @Override
    public void deleteChainByUri(String uri) {
        // 校验当前路径是否关联产品规则链信息,如果关联则不能删除,提示先删除产品先关信息
        QueryWrapper<TbSysProductDragChain> productDragChainQueryWrapper = new QueryWrapper<>();
        productDragChainQueryWrapper.lambda().eq(TbSysProductDragChain::getUri, uri);
        List<TbSysProductDragChain> productDragChainList = productDragChainMapper.selectList(productDragChainQueryWrapper);
        if (ObjectUtil.isNotEmpty(productDragChainList)) {
            // 获取所有产品cd以及中文名称信息
            List<String> productCdList = productDragChainList.stream().map(
                    TbSysProductDragChain::getProductCd
            ).collect(Collectors.toList());

            // 获取数据库中产品信息
            QueryWrapper<TbSysProduct> productQueryWrapper = new QueryWrapper<>();
            productQueryWrapper.lambda().in(TbSysProduct::getProductCd, productCdList);
            List<TbSysProduct> productList = tbSysProductMapper.selectList(productQueryWrapper);

            // 设置错误提示信息为:当前产品规则链对应[产品cd,产品名称],[产品cd,产品名称]下有配置产品规则,请先删除产品规则再删除当前默认规则链
            String errorMessage = productList.stream().map(product ->
                    StrUtil.format("[{},{}]", product.getProductCd(), product.getProductName())
            ).collect(Collectors.joining());
            errorMessage = "当前产品规则链对应".concat(errorMessage).concat("下有配置产品规则,请先删除产品规则再删除当前默认规则链!");

            throw new ServiceException(errorMessage);
        }

        // 获取规则链缓存信息,并且设置规则链信息为空,是否落库信息为0
        Object dragRuleChainObj = redisUtil.hget(CommonDragRuleConstant.DRAG_RULE_CHAIN_FLAG, uri);
        if (ObjectUtil.isNull(dragRuleChainObj)) {
            throw new ServiceException(StrUtil.format("当前缓存中没有uri[{}]规则链信息,删除失败!", uri));
        }
        DragChainDTO dragChainDTO = JSONObject.parseObject(dragRuleChainObj.toString(), DragChainDTO.class);
        dragChainDTO.setIfLoadDB(RuleConstant.NUM_0_STR);
        dragChainDTO.setDragRuleChain(null);

        // 规则表删除
        UpdateWrapper<TbSysDragChain> chainUpdateWrapper = new UpdateWrapper<>();
        chainUpdateWrapper.lambda().eq(TbSysDragChain::getUri, uri);
        tbSysDragChainMapper.delete(chainUpdateWrapper);

        // 重新缓存
        redisUtil.hset(CommonDragRuleConstant.DRAG_RULE_CHAIN_FLAG, uri, JSONObject.toJSONString(dragChainDTO));
    }

    /**
     * 通过uri以及产品cd删除产品链信息
     *
     * @param uri
     * @param productCd
     * @return
     */
    @Override
    public void deleteProductChainByUriAndProductCd(String uri, String productCd) {
        // 删除key为 uri + ":" + productCd格式
        String delKey = uri.concat(StrUtil.COLON).concat(productCd);

        // 获取规则链缓存信息,并且设置规则链信息为空,是否落库信息为0
        Object productDragChainObj = redisUtil.hget(CommonDragRuleConstant.DRAG_RULE_PRODUCT_CHAIN_FLAG, delKey);
        if (ObjectUtil.isNull(productDragChainObj)) {
            throw new ServiceException(StrUtil.format("当前缓存中没有uri[{}]规则链信息,删除失败!", uri));
        }

        // 规则表删除
        UpdateWrapper<TbSysProductDragChain> chainUpdateWrapper = new UpdateWrapper<>();
        chainUpdateWrapper.lambda().eq(TbSysProductDragChain::getUri, uri)
                .eq(TbSysProductDragChain::getProductCd, productCd);
        productDragChainMapper.delete(chainUpdateWrapper);

        // 删除缓存信息
        redisUtil.hdel(CommonDragRuleConstant.DRAG_RULE_PRODUCT_CHAIN_FLAG, delKey);
    }

    /**
     * 通过uri删除多条产品链信息
     *
     * @param uri
     * @return
     */
    @Override
    public void deleteProductChainByUri(String uri) {
        // 获取所有规则链规则信息
        QueryWrapper<TbSysProductDragChain> productDragChainQueryWrapper = new QueryWrapper<>();
        productDragChainQueryWrapper.lambda().eq(TbSysProductDragChain::getUri, uri);
        List<TbSysProductDragChain> productDragChainList = productDragChainMapper.selectList(productDragChainQueryWrapper);
        if (ObjectUtil.isEmpty(productDragChainList)) {
            throw new ServiceException(StrUtil.format("通过uri[{}]获取产品规则链信息为空,无删除数据!"));
        }

        // 通过uri删除table信息
        productDragChainMapper.delete(productDragChainQueryWrapper);

        // 获取productCd,用于拼接规则链缓存key信息,然后进行缓存信息删除
        List<String> productCdList = productDragChainList.stream().map(
                TbSysProductDragChain::getProductCd
        ).collect(Collectors.toList());

        // 循环删除缓存信息
        productCdList.forEach(productCd -> {
            // 缓存的键key由 uri + ":" + productCd 组成
            String delKey = uri.concat(StrUtil.COLON).concat(productCd);
            redisUtil.hdel(CommonDragRuleConstant.DRAG_RULE_PRODUCT_CHAIN_FLAG, delKey);
        });
    }

    /**
     * 校验并获取规则链全部参数信息
     *
     * @param allParamDTO
     * @return
     */
    @Override
    public DragRuleChainAllParamDTO checkDragRuleChainAllParamDesc(DragRuleChainAllParamDTO allParamDTO) {
        // 首先获取规则链入参信息
        String uri = allParamDTO.getUri();
        DragChainDTO cacheDragChainDTO = null;
        if (StrUtil.isNotBlank(uri)) {
            // 通过uri获取规则链缓存信息
            Object dragRuleChainObj = redisUtil.hget(CommonDragRuleConstant.DRAG_RULE_CHAIN_FLAG, uri);
            if (ObjectUtil.isNull(dragRuleChainObj)) {
                throw new ServiceException(StrUtil.format("当前缓存中没有uri[{}]规则链信息,请确认是否缓存中没有数据!", uri));
            }
            // 通过缓存信息获取规则链自己入参参数信息
            cacheDragChainDTO = JSONObject.parseObject(dragRuleChainObj.toString(), DragChainDTO.class);
            allParamDTO.setDragRuleChainInParamDescList(cacheDragChainDTO.getInVOParamsDescList());
        }

        // 规则链是否为空校验,不为空,进行规则链全参数获取以及校验
        if (StrUtil.isNotBlank(allParamDTO.getDragRuleChain())) {
            // 进行规则链中所有规则校验,确定是否有参数缺失规则,进行提示
            cacheDragChainDTO.setDragRuleChain(allParamDTO.getDragRuleChain());
            // 如果传入规则链中规则id字符串不为空,则获取所有规则出入参信息,并且校验当前规则链是否合法
            DragRuleChainAllParamDescOutVO.DragIllegalRule dragIllegalRule = checkIllegalParam(cacheDragChainDTO, allParamDTO);
            allParamDTO.setDragIllegalRule(dragIllegalRule);
        }
        return allParamDTO;
    }

    /**
     * 开发人员使用获取拖拽规则规则名称
     * eg : ACC0005Tran,COL0025Tran ...
     *
     * @param sequenceEnum
     * @return
     */
    @Override
    public String getDragSequenceName(DragRuleSequenceEnum sequenceEnum) {

        // 获取序列尾缀信息,步长默认设置为1,格式 "0000" -> "9999"
        Double bizIndex = redisUtil.hincr(RuleConstant.DRAG_BIZ_SEQUENCE,
                sequenceEnum.getModule(),
                SequenceConstant.SEQUENCE_DEFAULT_STEP);

        // 序列尾缀信息转换为字符串类型,并且拼接尾缀信息
        String sequenceStr = StrUtil.toString(bizIndex.intValue());
        String subBasicSeqNo = StrUtil.sub(
                RuleConstant.DRAG_SEQUENCE_INIT_VAL,
                SequenceConstant.FLAG_INT_0,
                RuleConstant.NUM_4 - sequenceStr.length());

        // 获取最终序列信息 eg: ACC0005Tran
        String finalSequenceTran = sequenceEnum.getModuleAlias()
                .concat(subBasicSeqNo)
                .concat(sequenceStr)
                .concat(RuleConstant.TRAN_SUFFIX);
        return finalSequenceTran;
    }

    /**
     * 校验非法参数信息
     *
     * @param dragChainDTO
     * @param allParamDTO
     * @return
     */
    public DragRuleChainAllParamDescOutVO.DragIllegalRule checkIllegalParam(DragChainDTO dragChainDTO,
                                                                            DragRuleChainAllParamDTO allParamDTO) {
        // 设置最终返回参数信息
        DragRuleChainAllParamDescOutVO.DragIllegalRule illegalRule = null;

        // 参数信息列表
        List<DragRuleDTO> dragRuleList = new ArrayList<>();

        // 开始参数校验,入参参数需要满足调用规则参数校验,并且入参参数+规则返回参数(传递参数)需要满足规则链下一个规则的入参
        String dragRuleChain = dragChainDTO.getDragRuleChain();
        List<String> dragRuleChainList = Arrays.asList(dragRuleChain.split(StrUtil.COMMA).clone())
                .stream()
                .map(String::trim)
                .collect(Collectors.toList());

        // 只有一个规则,直接校验入参是否满足规则链第一个规则入参即可
        String errorMessage;
        if (dragRuleChainList.size() == 1) {
            String dragRuleId = dragRuleChainList.get(0);
            DragRuleDTO dragRuleDTO = commonDragRuleUtil.getDragRuleDTO(dragRuleId);
            if (ObjectUtil.isNull(dragRuleDTO)) {
                throw new ServiceException(StrUtil.format("通过规则id[{}]获取规则信息为空,请确认", dragRuleId));
            }
            // 分别获取规则参数以及规则链入参进行比较,如果入参不满足规则链第一个规则入参,直接抛出异常
            JSONObject dragRuleInParam = JSONObject.parseObject(dragRuleDTO.getInputParam());
            JSONObject dragChainInParam = JSONObject.parseObject(dragChainDTO.getMethodInParam());
            // 参数空值校验
            if (ObjectUtil.isEmpty(dragRuleInParam)) {
                errorMessage = StrUtil.format("拖拽规则规则链[{}]对应规则方法[{}]获取规则入参参数为空,规则id为[{}]请确认!",
                        dragChainDTO.getControllerName(),
                        dragChainDTO.getMethodName(),
                        dragRuleDTO.getDragRuleId());
                throw new ServiceException(errorMessage);
            }
            if (ObjectUtil.isEmpty(dragChainInParam)) {
                errorMessage = StrUtil.format("拖拽规则规则链[{}]切入点[{}]入参参数为空,请确认!",
                        dragChainDTO.getControllerName(),
                        dragChainDTO.getMethodName());
                throw new ServiceException(errorMessage);
            }

            // 设置规则参数信息
            dragRuleList.add(dragRuleDTO);

            // 参数包含校验,比较参数,切入点入参必须包含规则链第一个规则入参,不满足直接抛出异常
            Set<String> dragRuleInParamKeySet = dragRuleInParam.keySet();
            Set<String> dragChainInParamKeySet = dragChainInParam.keySet();
            Set<String> diffKeySet = dragRuleInParamKeySet.stream()
                    .filter(element -> !dragChainInParamKeySet.contains(element))
                    .collect(Collectors.toSet());
            if (ObjectUtil.isNotEmpty(diffKeySet)) {
                // Set集合数据转换为字符串,逗号分割
                String dragRuleDiffKeyStr = diffKeySet.stream()
                        .map(String::valueOf)
                        .collect(Collectors.joining(StrUtil.COMMA));
                errorMessage = StrUtil.format("规则链id[{}],规则包含列表第[1]个规则[{}],其入参参数不满足要求!\n缺少入参信息为: [{}]",
                        dragChainDTO.getDragRuleChainId(),
                        dragRuleDTO.getDragRuleId(),
                        dragRuleDiffKeyStr);

                // 设置参数校验失败信息
                illegalRule = new DragRuleChainAllParamDescOutVO.DragIllegalRule();
                illegalRule.setDragRuleId(dragRuleDTO.getDragRuleId());
                illegalRule.setErrorMessage(errorMessage);
                illegalRule.setRuleDesc(dragRuleDTO.getRuleDesc());
                illegalRule.setInVOParamsDescList(dragRuleDTO.getInputParamDescList());
                List<DragRuleDTO.DragRuleParamsDesc> differParamList = dragRuleDTO.getInputParamDescList().stream()
                        .filter(element -> diffKeySet.contains(element.getParamName()))
                        .collect(Collectors.toList());
                illegalRule.setIllegalParamDescList(differParamList);
            }
        } else {
            // 空值校验
            JSONObject dragChainInParam = JSONObject.parseObject(dragChainDTO.getMethodInParam());
            if (ObjectUtil.isEmpty(dragChainInParam)) {
                errorMessage = StrUtil.format("拖拽规则规则链[{}]控制层方法切入点[{}]入参参数为空,请确认!",
                        dragChainDTO.getControllerName(),
                        dragChainDTO.getMethodName());
                throw new ServiceException(errorMessage);
            }
            // 入参结果集,第一次入参参数为规则链切入点的入参参数,之后循环规则链规则,为规则链返回传递参数+切入点入参参数,再与下一个规则入参进行对比
            JSONObject resultInParam = dragChainInParam.clone();
            for (int i = 0; i < dragRuleChainList.size(); i++) {
                // 通过规则id,获取规则入参信息
                String dragRuleId = dragRuleChainList.get(i);
                DragRuleDTO dragRuleDTO = commonDragRuleUtil.getDragRuleDTO(dragRuleId);
                if (ObjectUtil.isNull(dragRuleDTO)) {
                    throw new ServiceException(StrUtil.format("通过规则id[{}]获取规则信息为空,请确认", dragRuleId));
                }

                // 添加规则入参信息
                dragRuleList.add(dragRuleDTO);

                JSONObject dragRuleInParam = JSONObject.parseObject(dragRuleDTO.getInputParam());
                // 进行参数校验,如果入参不满足规则链循环规则入参,直接抛出异常
                Set<String> dragRuleInParamKeySet = dragRuleInParam.keySet();
                Set<String> dragChainInParamKeySet = resultInParam.keySet();
                Set<String> diffKeySet = dragRuleInParamKeySet.stream()
                        .filter(element -> !dragChainInParamKeySet.contains(element))
                        .collect(Collectors.toSet());
                if (ObjectUtil.isNotEmpty(diffKeySet)) {
                    // Set集合数据转换为字符串,逗号分割
                    String dragRuleDiffKeyStr = diffKeySet.stream()
                            .map(String::valueOf)
                            .collect(Collectors.joining(StrUtil.COMMA));
                    errorMessage = StrUtil.format("规则链id[{}],规则包含列表第[{}]个规则[{}],其入参参数不满足要求!\n缺少入参信息为: [{}]",
                            dragChainDTO.getDragRuleChainId(),
                            i + 1,
                            dragRuleDTO.getDragRuleId(),
                            dragRuleDiffKeyStr);
                    // 设置参数校验失败信息
                    illegalRule = new DragRuleChainAllParamDescOutVO.DragIllegalRule();
                    illegalRule.setDragRuleId(dragRuleDTO.getDragRuleId());
                    illegalRule.setErrorMessage(errorMessage);
                    illegalRule.setRuleDesc(dragRuleDTO.getRuleDesc());
                    illegalRule.setInVOParamsDescList(dragRuleDTO.getInputParamDescList());
                    List<DragRuleDTO.DragRuleParamsDesc> differParamList = dragRuleDTO.getInputParamDescList().stream()
                            .filter(element -> diffKeySet.contains(element.getParamName()))
                            .collect(Collectors.toList());
                    illegalRule.setIllegalParamDescList(differParamList);
                    break;
                }
                // 设置规则返回参数作为传递参数设定到切入点入参参数中,作为下一入参参数校验集合,传递参数为字符串,多个参数以逗号分割
                if (StrUtil.isNotBlank(dragRuleDTO.getCrossParam())) {
                    String[] crossParams = dragRuleDTO.getCrossParam().split(StrUtil.COMMA);
                    for (int j = 0; j < crossParams.length; j++) {
                        resultInParam.put(crossParams[j], StrUtil.EMPTY);
                    }
                }
            }
        }
        // 设置参数列表信息
        allParamDTO.setDragRuleList(dragRuleList);
        return illegalRule;
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值