Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/service/impl/MdmIOServiceImpl.java
@@ -3,7 +3,7 @@
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.common.utils.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.protobuf.ServiceException;
import com.vci.ubcs.code.applyjtcodeservice.feign.IMdmInterJtClient;
@@ -13,9 +13,8 @@
import com.vci.ubcs.code.bo.CodeTemplateAttrSqlBO;
import com.vci.ubcs.code.dto.*;
import com.vci.ubcs.code.entity.CodeAllCode;
import com.vci.ubcs.code.enumpack.CodeDefaultLC;
import com.vci.ubcs.code.enumpack.CodeLevelTypeEnum;
import com.vci.ubcs.code.enumpack.sysIntegrationPushTypeEnum;
import com.vci.ubcs.code.entity.CodeSynonym;
import com.vci.ubcs.code.enumpack.*;
import com.vci.ubcs.code.lifecycle.CodeAllCodeLC;
import com.vci.ubcs.code.mapper.CommonsMapper;
import com.vci.ubcs.code.service.*;
@@ -58,6 +57,7 @@
import org.apache.poi.ss.usermodel.RichTextString;
import org.apache.poi.ss.usermodel.Workbook;
import org.springblade.core.redis.cache.BladeRedis;
import org.springblade.core.secure.BladeUser;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.Func;
@@ -68,8 +68,9 @@
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.xml.bind.ValidationEvent;
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
@@ -86,7 +87,9 @@
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
import static com.alibaba.druid.util.FnvHash.Constants.LIMIT;
@@ -97,7 +100,6 @@
@Service
@Slf4j
public class MdmIOServiceImpl implements MdmIOService {
   /**
    * 字段
@@ -143,7 +145,7 @@
    * 模板的服务
    */
   @Resource
   private CodeClstemplateServiceImpl templateService;
   private ICodeClstemplateService templateService;
   /**
    * 主数据引擎的服务
@@ -166,30 +168,41 @@
   private ICodeKeyAttrRepeatService keyRuleService;
   /**
    * 近义词规则查询服务
    */
   @Autowired
   ICodeSynonymService codeSynonymService;
   /**
    * 公式的服务
    */
   @Autowired
   private FormulaServiceImpl formulaService;
   /**
    * 规则的服务
    */
   @Autowired
   private ICodeRuleService ruleService;
   /**
    * 业务类型的服务
    */
   @Autowired
   private IBtmTypeClient btmTypeClient;
   /***
    * 申请集团编码服务
    */
   @Resource
   private IMdmInterJtClient mdmInterJtClient;
   /***
    * 密级服务
    */
   @Resource
   private IWebSecretClient secretService;
   /**
    * 日志保存工具类
    */
@@ -202,20 +215,25 @@
   public static final int EXPORT_LIMIT = 65535;
   /**
    * 自定义并发ForkJoinPool
    */
   private static final ForkJoinPool customForkJoinPool = new ForkJoinPool(Runtime.getRuntime().availableProcessors() - 1);
   /**
    * 批量申请:选取选中分类下的所有模板关键属性,相似属性,必填属性,写入execl中
    *
    * @param codeClassifyOid 分类的主键
    * @return excel的文件地址
    */
   @Override
   public String downloadTopImportExcel(String codeClassifyOid){
      List<CodeClassifyTemplateVO> templateVOList=new ArrayList<>();
      VciBaseUtil.alertNotNull("导出模板","导出的配置",codeClassifyOid,"主题库分类的主键");
   public String downloadTopImportExcel(String codeClassifyOid) {
      List<CodeClassifyTemplateVO> templateVOList = new ArrayList<>();
      VciBaseUtil.alertNotNull("导出模板", "导出的配置", codeClassifyOid, "主题库分类的主键");
      CodeClassifyVO codeClassifyVO = classifyService.getObjectByOid(codeClassifyOid);
      templateVOList= templateService.childTemplates(codeClassifyOid);
      List<CodeClassifyVO>  codeClassifyVOS=classifyService.getIdPathToNamePathByParentId(codeClassifyOid,true);
      templateVOList = templateService.childTemplates(codeClassifyOid);
      List<CodeClassifyVO> codeClassifyVOS = classifyService.getIdPathToNamePathByParentId(codeClassifyOid, true);
      WriteExcelOption eo = new WriteExcelOption();
      LinkedHashMap<String,CodeClassifyTemplateAttrVO> allFieldToOutNameMap=new LinkedHashMap<>();
      LinkedHashMap<String, CodeClassifyTemplateAttrVO> allFieldToOutNameMap = new LinkedHashMap<>();
      templateVOList.stream().forEach(templateVO -> {
         //组合格式的不导入,
         // 枚举的提供序列的选择
@@ -223,14 +241,14 @@
         //参照的自行输入名称
         //分类注入的不用,都是导入后自动处理的
         //编码,状态等字段不导入
         if(!CollectionUtils.isEmpty(templateVO.getAttributes())) {
         if (!CollectionUtils.isEmpty(templateVO.getAttributes())) {
            List<CodeClassifyTemplateAttrVO> templateAttrVOS = templateVO.getAttributes().stream().filter(s ->
               !DEFAULT_ATTR_LIST.contains(s.getId())
                  && StringUtils.isBlank(s.getComponentRule())
                  && StringUtils.isBlank(s.getClassifyInvokeAttr())
                  && (VciBaseUtil.getBoolean(s.getFormDisplayFlag()))
            ).collect(Collectors.toList());
            if(CollectionUtils.isEmpty(templateAttrVOS)){
            if (CollectionUtils.isEmpty(templateAttrVOS)) {
               throw new VciBaseException("模板没有配置任何【表单显示】为【是】的属性");
            }
            templateAttrVOS.stream().forEach(codetemplateAttr -> {
@@ -261,36 +279,36 @@
      //整理好所有模板需要写入execl的属性信息
      Workbook workbook = new HSSFWorkbook();
      LinkedList<WriteExcelData> excelDataList = new LinkedList<>();
      if(!CollectionUtils.isEmpty(allFieldToOutNameMap)){
         excelDataList.add(new WriteExcelData(0,0,"分类路径"));
      if (!CollectionUtils.isEmpty(allFieldToOutNameMap)) {
         excelDataList.add(new WriteExcelData(0, 0, "分类路径"));
         final int[] index = {0};
         allFieldToOutNameMap.values().stream().forEach(attrVO -> {
            Object text = attrVO.getName();
            text = exportKeyAndRequired(workbook,attrVO,text);
            text = exportKeyAndRequired(workbook, attrVO, text);
            int colIndex = 1 + index[0]++;
            WriteExcelData excelData = new WriteExcelData(0, colIndex, text);
            if(StringUtils.isNotBlank(attrVO.getCodeDateFormat())
            if (StringUtils.isNotBlank(attrVO.getCodeDateFormat())
               || VciFieldTypeEnum.VTDateTime.name().equalsIgnoreCase(attrVO.getAttributeDataType())
               || VciFieldTypeEnum.VTDate.name().equalsIgnoreCase(attrVO.getAttributeDataType())
               ||VciFieldTypeEnum.VTTime.name().equalsIgnoreCase(attrVO.getAttributeDataType())){
               || VciFieldTypeEnum.VTTime.name().equalsIgnoreCase(attrVO.getAttributeDataType())) {
               excelData.setDateFormat(VciDateUtil.DateTimeFormat);
            }
            if(text instanceof RichTextString){
            if (text instanceof RichTextString) {
               excelData.setFontColor(String.valueOf(HSSFColor.HSSFColorPredefined.RED.getIndex()));
            }
            excelDataList.add(excelData);
            if(StringUtils.isNotBlank(attrVO.getEnumString()) || StringUtils.isNotBlank(attrVO.getEnumId())){
            if (StringUtils.isNotBlank(attrVO.getEnumString()) || StringUtils.isNotBlank(attrVO.getEnumId())) {
               //添加数据有效性
               List<String> enumValueList = new ArrayList<>();
               enumValueList.add("");
               List<KeyValue> valueList = engineService.listComboboxItems(attrVO);
               if(!CollectionUtils.isEmpty(valueList)){
                  valueList.stream().forEach(kv->{
               if (!CollectionUtils.isEmpty(valueList)) {
                  valueList.stream().forEach(kv -> {
                     enumValueList.add(kv.getValue());
                  });
               }
               //默认加1万条
               WriteExcelData ed = new WriteExcelData(1,colIndex,"");
               WriteExcelData ed = new WriteExcelData(1, colIndex, "");
               ed.setRowTo(100);
               ed.setColTo(colIndex);
               ed.setValidation(true);
@@ -298,12 +316,12 @@
               ed.setValidationErrorMsg("请在序列中选择正确的值");
               excelDataList.add(ed);
            }
            if(VciFieldTypeEnum.VTBoolean.name().equalsIgnoreCase(attrVO.getAttributeDataType())){
            if (VciFieldTypeEnum.VTBoolean.name().equalsIgnoreCase(attrVO.getAttributeDataType())) {
               List<String> booleanList = new ArrayList<>();
               booleanList.add("是");
               booleanList.add("否");
               //默认加1万条
               WriteExcelData ed = new WriteExcelData(1,colIndex,"");
               WriteExcelData ed = new WriteExcelData(1, colIndex, "");
               ed.setRowTo(100);
               ed.setColTo(colIndex);
               ed.setValidation(true);
@@ -312,16 +330,16 @@
               excelDataList.add(ed);
            }
         });
         eo.addSheetDataList(codeClassifyVO.getName()+"导入模板",excelDataList);
         eo.addSheetDataList(codeClassifyVO.getName() + "导入模板", excelDataList);
      }
      LinkedList<WriteExcelData> classPathList = new LinkedList<>();
      classPathList.add(new WriteExcelData(0,0,"分类层级"));
      classPathList.add(new WriteExcelData(0, 0, "分类层级"));
      WriteExcelData idPathWriteExcelTitle=new WriteExcelData(0,1,"分类ID路径");
      WriteExcelData idPathWriteExcelTitle = new WriteExcelData(0, 1, "分类ID路径");
      idPathWriteExcelTitle.setWidth(20);
      idPathWriteExcelTitle.setCenter(false);
      classPathList.add(idPathWriteExcelTitle);
      WriteExcelData namePathWriteExcelTitle=new WriteExcelData(0,2,"分类名称路径");
      WriteExcelData namePathWriteExcelTitle = new WriteExcelData(0, 2, "分类名称路径");
      namePathWriteExcelTitle.setWidth(20);
      namePathWriteExcelTitle.setCenter(false);
      classPathList.add(namePathWriteExcelTitle);
@@ -329,23 +347,23 @@
      final int[] rowIndex = {1};
      codeClassifyVOS.stream().forEach(codeClassifyVO1 -> {
         classPathList.add(new WriteExcelData(rowIndex[0],0,codeClassifyVO1.getDataLevel()));
         classPathList.add(new WriteExcelData(rowIndex[0], 0, codeClassifyVO1.getDataLevel()));
         String idPath=codeClassifyVO1.getIdPath().startsWith("#")?codeClassifyVO1.getIdPath().substring(1):codeClassifyVO1.getIdPath();
         WriteExcelData idPathWriteExcelData=new WriteExcelData(rowIndex[0],1,idPath);
         String idPath = codeClassifyVO1.getIdPath().startsWith("#") ? codeClassifyVO1.getIdPath().substring(1) : codeClassifyVO1.getIdPath();
         WriteExcelData idPathWriteExcelData = new WriteExcelData(rowIndex[0], 1, idPath);
         idPathWriteExcelData.setWidth(30);
         idPathWriteExcelData.setCenter(false);
         classPathList.add(idPathWriteExcelData);
         String namePath=codeClassifyVO1.getNamePath().startsWith("#")?codeClassifyVO1.getNamePath().substring(1):codeClassifyVO1.getNamePath();
         WriteExcelData  namePathWriteExcelData=  new WriteExcelData(rowIndex[0],2,namePath);
         String namePath = codeClassifyVO1.getNamePath().startsWith("#") ? codeClassifyVO1.getNamePath().substring(1) : codeClassifyVO1.getNamePath();
         WriteExcelData namePathWriteExcelData = new WriteExcelData(rowIndex[0], 2, namePath);
         namePathWriteExcelData.setWidth(40);
         namePathWriteExcelData.setCenter(false);
         classPathList.add(namePathWriteExcelData);
         rowIndex[0]++;
      });
      WriteExcelData  excelData=new WriteExcelData();
      WriteExcelData excelData = new WriteExcelData();
      excelData.setMerged(true);
      excelData.setRow(1);
      excelData.setRowTo(2);
@@ -357,11 +375,11 @@
      excelData.setFontColor(String.valueOf(HSSFColor.HSSFColorPredefined.RED.getIndex()));
      classPathList.add(excelData);
      eo.addSheetDataList(codeClassifyVO.getName()+"分类对照表",classPathList);
      eo.addSheetDataList(codeClassifyVO.getName() + "分类对照表", classPathList);
      String excelName = LocalFileUtil.getDefaultTempFolder() + File.separator + codeClassifyVO.getName() + "_导入模板.xls";
      // eo.addSheetDataList(templateVOList.size()+"模板信息【请勿删除或移动】",tempEDList);
      ExcelUtil.writeDataToFile(excelName,eo);
      ExcelUtil.writeDataToFile(excelName, eo);
      return excelName;
   }
@@ -369,22 +387,22 @@
    * 生成导入的文件
    *
    * @param codeClassifyOid 分类的主键
    * @param isHistory 是否历史数据导入
    * @param isHistory       是否历史数据导入
    * @return excel的文件地址
    */
   @Override
   public String createImportExcel(String codeClassifyOid, boolean isHistory) {
      List<CodeClassifyTemplateVO> templateVOList=new ArrayList<>();
      VciBaseUtil.alertNotNull("导出模板","导出的配置",codeClassifyOid,"主题库分类的主键");
      List<CodeClassifyTemplateVO> templateVOList = new ArrayList<>();
      VciBaseUtil.alertNotNull("导出模板", "导出的配置", codeClassifyOid, "主题库分类的主键");
      CodeClassifyVO codeClassifyVO = classifyService.getObjectByOid(codeClassifyOid);
      //获取码段宽度
      //String secWidth = getCodeSegmentWidth(codeClassifyVO.getOid());
      String secWidth = getCodeSegmentWidth(codeClassifyVO.getOid());
      if(isHistory){
         templateVOList= templateService.childTemplates(codeClassifyOid);
      }else{
      if (isHistory) {
         templateVOList = templateService.childTemplates(codeClassifyOid);
      } else {
         //找模板
         CodeClassifyTemplateVO templateVO = engineService.getUsedTemplateByClassifyOid(codeClassifyOid);
         templateVOList.add(templateVO);
@@ -394,25 +412,26 @@
      eo.setAppend(true);
      //增加模板的信息导入
      LinkedList<WriteExcelData> tempEDList = new LinkedList<>();
      tempEDList.add(new WriteExcelData(0,0,"模板主键"));
      tempEDList.add(new WriteExcelData(0,1,"模板代号"));
      tempEDList.add(new WriteExcelData(0,2,"模板名称"));
      for(int j=0;j<templateVOList.size();j++){
         CodeClassifyTemplateVO  templateVO=templateVOList.get(j);
      tempEDList.add(new WriteExcelData(0, 0, "模板主键"));
      tempEDList.add(new WriteExcelData(0, 1, "模板代号"));
      tempEDList.add(new WriteExcelData(0, 2, "模板名称"));
      for (int j = 0; j < templateVOList.size(); j++) {
         CodeClassifyTemplateVO templateVO = templateVOList.get(j);
         CodeClassifyTemplateVO codeClassifyTemplateVO = new CodeClassifyTemplateVO();
         BeanUtils.copyProperties(templateVO,codeClassifyTemplateVO);
         BeanUtils.copyProperties(templateVO, codeClassifyTemplateVO);
         //组合格式的不导入,
         // 枚举的提供序列的选择
         //时间全部统一为yyyy-MM-dd HH:mm:ss
         //参照的自行输入名称
         //分类注入的不用,都是导入后自动处理的
         //编码,状态等字段不导入
         List<CodeClassifyTemplateAttrVO> codeClassifyTemplateAttrVOList=codeClassifyTemplateVO.getAttributes();
         if(!CollectionUtils.isEmpty(codeClassifyTemplateAttrVOList)) {
         List<CodeClassifyTemplateAttrVO> codeClassifyTemplateAttrVOList = codeClassifyTemplateVO.getAttributes();
         if (!CollectionUtils.isEmpty(codeClassifyTemplateAttrVOList)) {
            if (CollectionUtils.isEmpty(codeClassifyTemplateAttrVOList)) {
               throw new VciBaseException("模板没有配置属性");
            }
         }
         //剔除掉默认的属性,以及表单不显示的属性
         List<CodeClassifyTemplateAttrVO> templateAttrVOS = codeClassifyTemplateAttrVOList.stream().filter(s ->
            !DEFAULT_ATTR_LIST.contains(s.getId())
               && StringUtils.isBlank(s.getComponentRule())
@@ -427,40 +446,42 @@
         List<CodeClassifyTemplateAttrVO> idAttrVOList = codeClassifyTemplateVO.getAttributes().stream().filter(s -> s.getId().equalsIgnoreCase(CODE_FIELD)).collect(Collectors.toList());
         LinkedList<WriteExcelData> excelDataList = new LinkedList<>();
         Workbook workbook = new HSSFWorkbook();
         if(isHistory){
            excelDataList.add(new WriteExcelData(0,0,"分类路径",""));
            excelDataList.add(new WriteExcelData(0,1,"码段宽度",""));
            excelDataList.add(new WriteExcelData(0,2,!CollectionUtils.isEmpty(idAttrVOList)?idAttrVOList.get(0).getName():"企业编码",idAttrVOList.get(0).getId()));
         if (isHistory) {
            excelDataList.add(new WriteExcelData(0, 0, "分类路径", ""));
            excelDataList.add(new WriteExcelData(0, 1, "码段宽度", ""));
            excelDataList.add(new WriteExcelData(0, 2, !CollectionUtils.isEmpty(idAttrVOList) ? idAttrVOList.get(0).getName() : "企业编码", idAttrVOList.get(0).getId()));
            // 填充码段
            excelDataList.add(new WriteExcelData(1, 1, secWidth));
         }
         for (int i = 0; i < templateAttrVOS.size(); i++) {
            CodeClassifyTemplateAttrVO attrVO = templateAttrVOS.get(i);
            Object text = attrVO.getName();
            text = exportKeyAndRequired(workbook,attrVO,text);
            int colIndex = (isHistory?3:0) + i;
            WriteExcelData excelData = new WriteExcelData(0, colIndex, text,attrVO.getId());
            if(StringUtils.isNotBlank(attrVO.getCodeDateFormat())
            text = exportKeyAndRequired(workbook, attrVO, text);
            int colIndex = (isHistory ? 3 : 0) + i;
            WriteExcelData excelData = new WriteExcelData(0, colIndex, text, attrVO.getId());
            if (StringUtils.isNotBlank(attrVO.getCodeDateFormat())
               || VciFieldTypeEnum.VTDateTime.name().equalsIgnoreCase(attrVO.getAttributeDataType())
               || VciFieldTypeEnum.VTDate.name().equalsIgnoreCase(attrVO.getAttributeDataType())
               ||VciFieldTypeEnum.VTTime.name().equalsIgnoreCase(attrVO.getAttributeDataType())){
               || VciFieldTypeEnum.VTTime.name().equalsIgnoreCase(attrVO.getAttributeDataType())) {
               excelData.setDateFormat(VciDateUtil.DateTimeFormat);
            }
            if(text instanceof RichTextString){
            if (text instanceof RichTextString) {
               excelData.setFontColor(String.valueOf(HSSFColor.HSSFColorPredefined.RED.getIndex()));
            }
            excelDataList.add(excelData);
            if(StringUtils.isNotBlank(attrVO.getEnumString()) || StringUtils.isNotBlank(attrVO.getEnumId())){
            if (StringUtils.isNotBlank(attrVO.getEnumString()) || StringUtils.isNotBlank(attrVO.getEnumId())) {
               //添加数据有效性
               List<String> enumValueList = new ArrayList<>();
               enumValueList.add("");
               List<KeyValue> valueList = engineService.listComboboxItems(attrVO);
               if(!CollectionUtils.isEmpty(valueList)){
                  valueList.stream().forEach(kv->{
               if (!CollectionUtils.isEmpty(valueList)) {
                  valueList.stream().forEach(kv -> {
                     enumValueList.add(kv.getValue());
                  });
               }
               //默认加1万条
               WriteExcelData ed = new WriteExcelData(1,colIndex,"");
               WriteExcelData ed = new WriteExcelData(1, colIndex, "");
               ed.setRowTo(100);
               ed.setColTo(colIndex);
               ed.setValidation(true);
@@ -468,13 +489,13 @@
               ed.setValidationErrorMsg("请在序列中选择正确的值");
               excelDataList.add(ed);
            }
            if(VciFieldTypeEnum.VTBoolean.name().equalsIgnoreCase(attrVO.getAttributeDataType())){
            if (VciFieldTypeEnum.VTBoolean.name().equalsIgnoreCase(attrVO.getAttributeDataType())) {
               List<String> booleanList = new ArrayList<>();
               booleanList.add("是");
               booleanList.add("否");
               //默认加1万条
               WriteExcelData ed = new WriteExcelData(1,colIndex,"");
               WriteExcelData ed = new WriteExcelData(1, colIndex, "");
               ed.setRowTo(100);
               ed.setColTo(colIndex);
               ed.setValidation(true);
@@ -483,14 +504,14 @@
               excelDataList.add(ed);
            }
         }
         eo.addSheetDataList(j+templateVO.getName(),excelDataList);
         tempEDList.add(new WriteExcelData(j+1,0,templateVO.getOid()));
         tempEDList.add(new WriteExcelData(j+1,1,templateVO.getId()));
         tempEDList.add(new WriteExcelData(j+1,2,templateVO.getName()));
         eo.addSheetDataList(j + templateVO.getName(), excelDataList);
         tempEDList.add(new WriteExcelData(j + 1, 0, templateVO.getOid()));
         tempEDList.add(new WriteExcelData(j + 1, 1, templateVO.getId()));
         tempEDList.add(new WriteExcelData(j + 1, 2, templateVO.getName()));
      }
      String excelName = LocalFileUtil.getDefaultTempFolder() + File.separator + codeClassifyVO.getName() + (isHistory?"_历史数据导入模板.xls": "_导入模板.xls");
      eo.addSheetDataList(templateVOList.size()+"模板信息【请勿删除或移动】",tempEDList);
      ExcelUtil.writeDataToFile(excelName,eo);
      String excelName = LocalFileUtil.getDefaultTempFolder() + File.separator + codeClassifyVO.getName() + (isHistory ? "_历史数据导入模板.xls" : "_导入模板.xls");
      eo.addSheetDataList(templateVOList.size() + "模板信息【请勿删除或移动】", tempEDList);
      ExcelUtil.writeDataToFile(excelName, eo);
      return excelName;
   }
@@ -502,30 +523,30 @@
    */
   @Override
   public String downloadImportExcelBatchEdit(String codeClassifyOid) {
      List<CodeClassifyTemplateVO> templateVOList=new ArrayList<>();
      VciBaseUtil.alertNotNull("导出模板","导出的配置",codeClassifyOid,"主题库分类的主键");
      List<CodeClassifyTemplateVO> templateVOList = new ArrayList<>();
      VciBaseUtil.alertNotNull("导出模板", "导出的配置", codeClassifyOid, "主题库分类的主键");
      CodeClassifyVO codeClassifyVO = classifyService.getObjectByOid(codeClassifyOid);
      templateVOList= templateService.childTemplates(codeClassifyOid);
      templateVOList = templateService.childTemplates(codeClassifyOid);
      WriteExcelOption eo = new WriteExcelOption();
      eo.setAppend(true);
      //增加模板的信息导入
      LinkedList<WriteExcelData> tempEDList = new LinkedList<>();
      tempEDList.add(new WriteExcelData(0,0,"编号"));
      for(int j=0;j<templateVOList.size();j++){
         CodeClassifyTemplateVO  templateVO=templateVOList.get(j);
      tempEDList.add(new WriteExcelData(0, 0, "编号"));
      for (int j = 0; j < templateVOList.size(); j++) {
         CodeClassifyTemplateVO templateVO = templateVOList.get(j);
         CodeClassifyTemplateVO codeClassifyTemplateVO = new CodeClassifyTemplateVO();
         BeanUtils.copyProperties(templateVO,codeClassifyTemplateVO);
         BeanUtils.copyProperties(templateVO, codeClassifyTemplateVO);
         //组合格式的不导入,
         // 枚举的提供序列的选择
         //时间全部统一为yyyy-MM-dd HH:mm:ss
         //参照的自行输入名称
         //分类注入的不用,都是导入后自动处理的
         //编码,状态等字段不导入
         List<CodeClassifyTemplateAttrVO> codeClassifyTemplateAttrVOList=codeClassifyTemplateVO.getAttributes();
         if(!CollectionUtils.isEmpty(codeClassifyTemplateAttrVOList)) {
         List<CodeClassifyTemplateAttrVO> codeClassifyTemplateAttrVOList = codeClassifyTemplateVO.getAttributes();
         if (!CollectionUtils.isEmpty(codeClassifyTemplateAttrVOList)) {
            if (CollectionUtils.isEmpty(codeClassifyTemplateAttrVOList)) {
               throw new VciBaseException("模板没有配置属性");
            }
@@ -545,7 +566,7 @@
         LinkedList<WriteExcelData> excelDataList = new LinkedList<>();
         Workbook workbook = new HSSFWorkbook();
//         if(isHistory){
         excelDataList.add(new WriteExcelData(0,0,"编码(id)",""));
         excelDataList.add(new WriteExcelData(0, 0, "编码(id)", ""));
//            excelDataList.add(new WriteExcelData(0,1,"码段宽度",""));
//         excelDataList.add(new WriteExcelData(0,1,!CollectionUtils.isEmpty(idAttrVOList)?idAttrVOList.get(0).getName():"企业编码",idAttrVOList.get(0).getId()));
//         }
@@ -553,31 +574,31 @@
            CodeClassifyTemplateAttrVO attrVO = templateAttrVOS.get(i);
            Object text = attrVO.getName();
            text = exportKeyAndRequired(workbook,attrVO,text);
            text = exportKeyAndRequired(workbook, attrVO, text);
            int colIndex = 1 + i;
            WriteExcelData excelData = new WriteExcelData(0, colIndex, text,attrVO.getId());
            if(StringUtils.isNotBlank(attrVO.getCodeDateFormat())
            WriteExcelData excelData = new WriteExcelData(0, colIndex, text, attrVO.getId());
            if (StringUtils.isNotBlank(attrVO.getCodeDateFormat())
               || VciFieldTypeEnum.VTDateTime.name().equalsIgnoreCase(attrVO.getAttributeDataType())
               || VciFieldTypeEnum.VTDate.name().equalsIgnoreCase(attrVO.getAttributeDataType())
               ||VciFieldTypeEnum.VTTime.name().equalsIgnoreCase(attrVO.getAttributeDataType())){
               || VciFieldTypeEnum.VTTime.name().equalsIgnoreCase(attrVO.getAttributeDataType())) {
               excelData.setDateFormat(VciDateUtil.DateTimeFormat);
            }
            if(text instanceof RichTextString){
            if (text instanceof RichTextString) {
               excelData.setFontColor(String.valueOf(HSSFColor.HSSFColorPredefined.RED.getIndex()));
            }
            excelDataList.add(excelData);
            if(StringUtils.isNotBlank(attrVO.getEnumString()) || StringUtils.isNotBlank(attrVO.getEnumId())){
            if (StringUtils.isNotBlank(attrVO.getEnumString()) || StringUtils.isNotBlank(attrVO.getEnumId())) {
               //添加数据有效性
               List<String> enumValueList = new ArrayList<>();
               enumValueList.add("");
               List<KeyValue> valueList = engineService.listComboboxItems(attrVO);
               if(!CollectionUtils.isEmpty(valueList)){
                  valueList.stream().forEach(kv->{
               if (!CollectionUtils.isEmpty(valueList)) {
                  valueList.stream().forEach(kv -> {
                     enumValueList.add(kv.getValue());
                  });
               }
               //默认加1万条
               WriteExcelData ed = new WriteExcelData(1,colIndex,"");
               WriteExcelData ed = new WriteExcelData(1, colIndex, "");
               ed.setRowTo(100);
               ed.setColTo(colIndex);
               ed.setValidation(true);
@@ -585,13 +606,13 @@
               ed.setValidationErrorMsg("请在序列中选择正确的值");
               excelDataList.add(ed);
            }
            if(VciFieldTypeEnum.VTBoolean.name().equalsIgnoreCase(attrVO.getAttributeDataType())){
            if (VciFieldTypeEnum.VTBoolean.name().equalsIgnoreCase(attrVO.getAttributeDataType())) {
               List<String> booleanList = new ArrayList<>();
               booleanList.add("是");
               booleanList.add("否");
               //默认加1万条
               WriteExcelData ed = new WriteExcelData(1,colIndex,"");
               WriteExcelData ed = new WriteExcelData(1, colIndex, "");
               ed.setRowTo(100);
               ed.setColTo(colIndex);
               ed.setValidation(true);
@@ -600,65 +621,167 @@
               excelDataList.add(ed);
            }
         }
         eo.addSheetDataList(j+templateVO.getName(),excelDataList);
         tempEDList.add(new WriteExcelData(j+1,0,templateVO.getOid()));
         tempEDList.add(new WriteExcelData(j+1,1,templateVO.getId()));
         tempEDList.add(new WriteExcelData(j+1,2,templateVO.getName()));
         eo.addSheetDataList(j + templateVO.getName(), excelDataList);
         tempEDList.add(new WriteExcelData(j + 1, 0, templateVO.getOid()));
         tempEDList.add(new WriteExcelData(j + 1, 1, templateVO.getId()));
         tempEDList.add(new WriteExcelData(j + 1, 2, templateVO.getName()));
      }
      String excelName = LocalFileUtil.getDefaultTempFolder() + File.separator + codeClassifyVO.getName() + ("_属性批量修改模板.xls");
      eo.addSheetDataList(templateVOList.size()+"模板信息【请勿删除或移动】",tempEDList);
      ExcelUtil.writeDataToFile(excelName,eo);
      eo.addSheetDataList(templateVOList.size() + "模板信息【请勿删除或移动】", tempEDList);
      ExcelUtil.writeDataToFile(excelName, eo);
      return excelName;
   }
   /**
    * 获取码段宽度
    *
    * @param codeClassifyOid
    * @return
    */
   private String getCodeSegmentWidth(String codeClassifyOid){
      CodeClassifyVO codeClassifyVO = classifyService.getObjectByOid(codeClassifyOid);
   private String getCodeSegmentWidth(String codeClassifyOid) {
      CodeClassifyFullInfoBO classifyFullInfoBO = classifyService.getClassifyFullInfo(codeClassifyOid);
      // 要获取码段宽度,先要获取规则,当前没有往上找
      CodeRuleVO codeRuleByClassifyFullInfo = mdmEngineService.getCodeRuleByClassifyFullInfo(classifyService.getClassifyFullInfo(codeClassifyOid));
      List<CodeBasicSecVO> secVOList = codeRuleByClassifyFullInfo.getSecVOList();
      if(secVOList.isEmpty()){
      if (secVOList.isEmpty()) {
         return "";
      }
      StringBuffer secWidth = new StringBuffer("");
      for (int j = 0; j < secVOList.size(); j++) {
         CodeBasicSecVO secVO = secVOList.get(j);
         int width = VciBaseUtil.getInt(secVO.getCodeSecLength()) + ((secVO.getPrefixCode() + secVO.getSuffixCode()).length());
         secWidth.append(width).append("#");
      }
      secVOList.stream().forEach(item -> {
         switch (item.getSecType().toLowerCase(Locale.ROOT)) {
            case "codeclassifysec":
            case "codevariablesec":
            case "coderefersec":
            case "codefixedsec":
            case "codeattrsec":
            case "codeserialsec":
               countSecWith(item, secWidth);
               break;
            case "codelevelsec":
               //层级码段,需要从分类上获取相应的信息
               String secValue = "";
               if (CodeLevelTypeEnum.MIN.getValue().equalsIgnoreCase(item.getCodeLevelType())) {
                  //最小层,因为我们只能在叶子节点上申请编码,所以这个就是当前分类的
                  if (CodeGetValueTypeEnum.CURRENT.getValue().equalsIgnoreCase(item.getCodeGetValueType()) || CollectionUtils.isEmpty(classifyFullInfoBO.getParentClassifyVOs())) {
                     //就是当前分类的
                     secValue = classifyFullInfoBO.getCurrentClassifyVO().getId();
                  } else {
                     //我们需要从顶层开始找到当前分类为止
                     secValue = classifyFullInfoBO.getParentClassifyVOs().stream().sorted(((o1, o2) -> -o1.getDataLevel().compareTo(o2.getDataLevel()))).map(CodeClassifyVO::getId).collect(Collectors.joining()) + classifyFullInfoBO.getCurrentClassifyVO().getId();
                  }
               } else {
                  //指定层,我们需要通过上级的来获取
                  if (CollectionUtils.isEmpty(classifyFullInfoBO.getParentClassifyVOs())) {
                     //说明当前已经是最高的了
                     secValue = classifyFullInfoBO.getCurrentClassifyVO().getId();
                  } else {
                     //这个我们需要看看,层级是不是大于了最大层级的数
                     List<CodeClassifyVO> parentClassifyVOList = classifyFullInfoBO.getParentClassifyVOs().stream().sorted(((o1, o2) -> -o1.getDataLevel().compareTo(o2.getDataLevel()))).collect(Collectors.toList());
                     if (item.getCodeLevelValue() > (parentClassifyVOList.size() + 1)) {
                        //指定的层级比当前的层级还大了,所以只能获取当前层级了
                        if (CodeGetValueTypeEnum.CURRENT.getValue().equalsIgnoreCase(item.getCodeGetValueType())) {
                           secValue = classifyFullInfoBO.getCurrentClassifyVO().getId();
                        } else {
                           secValue = parentClassifyVOList.stream().map(CodeClassifyVO::getId).collect(Collectors.joining()) + classifyFullInfoBO.getCurrentClassifyVO().getId();
                        }
                     } else {
                        //我们获取其中指定层的内容
                        if (CodeGetValueTypeEnum.CURRENT.getValue().equalsIgnoreCase(item.getCodeGetValueType())) {
                           CodeClassifyVO classifyVO = parentClassifyVOList.stream().filter(s -> s.getDataLevel().intValue() == item.getCodeLevelValue().intValue()).findFirst().orElseGet(() -> null);
                           if (classifyVO != null) {
                              secValue = classifyVO.getId();
                           }
                        } else {
                           //小于等于的全部拿出来
                           secValue = parentClassifyVOList.stream().filter(s -> s.getDataLevel().intValue() <= item.getCodeLevelValue().intValue()).sorted(((o1, o2) -> -o1.getDataLevel().compareTo(o2.getDataLevel()))).map(CodeClassifyVO::getId).collect(Collectors.joining());
                        }
                     }
                  }
               }
               //看看长度是否需要截断
               if (!CodeCutTypeEnum.NONE.getValue().equalsIgnoreCase(item.getValueCutType()) &&
                  item.getValueCutLength() != null && item.getValueCutLength() > 0 && secValue.length() > item.getValueCutLength()) {
                  if (CodeCutTypeEnum.RIGHT.getValue().equalsIgnoreCase(item.getValueCutType())) {
                     //左截取是从左边剪掉,右截取是从右边剪掉--保留左边
                     secValue = secValue.substring(0, item.getValueCutLength());
                  } else {
                     secValue = secValue.substring(secValue.length() - item.getValueCutLength());
                  }
               }
               secValue = productCodeService.joinPreffixAndSuffix(item, secValue);
               secWidth.append(secValue.length()).append("#");
               break;
            case "codedatesec":
               String dateFormatStr = item.getCodeDateFormatStr();
               if (Func.isNotEmpty(dateFormatStr)) {
                  // 获取当前时间
                  Date currentDate = new Date();
                  // 指定日期格式
                  SimpleDateFormat dateFormat = new SimpleDateFormat(dateFormatStr);
                  // 将当前时间转换为指定日期格式
                  // 使用正则表达式去掉除数字以外的所有字符串
                  String cleanedDate = dateFormat.format(currentDate).replaceAll("[^0-9]", "");
                  int width = cleanedDate.length();
                  if (Func.isNotEmpty(item.getPrefixCode())) {
                     width += item.getPrefixCode().length();
                  }
                  if (Func.isNotEmpty(item.getSuffixCode())) {
                     width += item.getSuffixCode().length();
                  }
                  secWidth.append(width).append("#");
               }
               break;
         }
      });
      return secWidth.toString().substring(0, secWidth.length() - 1);
   }
   /**
    * 导出的时候封装必输和关键属性
    * @param attrVO 属性的显示对象
    * @param text 单元格的值
    * 计算码段长度加前后缀的长度
    *
    * @param codeBasicSecVO
    * @param secWidth
    */
   private Object exportKeyAndRequired(Workbook workbook,CodeClassifyTemplateAttrVO attrVO,Object text){
   private void countSecWith(CodeBasicSecVO codeBasicSecVO, StringBuffer secWidth) {
      if (Func.isNotEmpty(codeBasicSecVO.getCodeSecLength())) {
         int width = VciBaseUtil.getInt(codeBasicSecVO.getCodeSecLength());
         if (Func.isNotEmpty(codeBasicSecVO.getPrefixCode())) {
            width += codeBasicSecVO.getPrefixCode().length();
         }
         if (Func.isNotEmpty(codeBasicSecVO.getSuffixCode())) {
            width += codeBasicSecVO.getSuffixCode().length();
         }
         secWidth.append(width).append("#");
      } else {
         secWidth.append(0).append("#");
      }
   }
   /**
    * 导出的时候封装必输和关键属性
    *
    * @param attrVO 属性的显示对象
    * @param text   单元格的值
    */
   private Object exportKeyAndRequired(Workbook workbook, CodeClassifyTemplateAttrVO attrVO, Object text) {
      //必输加*,关键属性为蓝色
      if (VciBaseUtil.getBoolean(attrVO.getRequireFlag()) || VciBaseUtil.getBoolean(attrVO.getKeyAttrFlag())) {
         String value = text.toString();
         if(VciBaseUtil.getBoolean(attrVO.getRequireFlag())) {
         if (VciBaseUtil.getBoolean(attrVO.getRequireFlag())) {
            value += REQUIRED_CHAR;
         }
         if(VciBaseUtil.getBoolean(attrVO.getKeyAttrFlag())){
         if (VciBaseUtil.getBoolean(attrVO.getKeyAttrFlag())) {
            value += KEY_ATTR_CHAR;
         }
         RichTextString ts = new HSSFRichTextString(value);
         if(VciBaseUtil.getBoolean(attrVO.getRequireFlag())){
            Font font =  workbook.createFont();
         if (VciBaseUtil.getBoolean(attrVO.getRequireFlag())) {
            Font font = workbook.createFont();
            font.setColor(HSSFColor.HSSFColorPredefined.RED.getIndex());
            ts.applyFont(font);
         }
         if(VciBaseUtil.getBoolean(attrVO.getKeyAttrFlag())){
            Font font =  workbook.createFont();
         if (VciBaseUtil.getBoolean(attrVO.getKeyAttrFlag())) {
            Font font = workbook.createFont();
            font.setColor(HSSFColor.HSSFColorPredefined.BLUE.getIndex());
            ts.applyFont(font);
         }
@@ -672,19 +795,19 @@
    *
    * @param orderDTO 编码申请信息,必须包含分类主键和码段的信息
    * @param file     excel文件的信息
    * @return  有错误信息的excel的文件
    * @return 有错误信息的excel的文件
    */
   @Override
   public CodeImProtRusultVO batchImportCode(CodeOrderDTO orderDTO, File file) throws Exception {
      VciBaseUtil.alertNotNull(orderDTO,"编码申请相关的数据",orderDTO.getCodeClassifyOid(),"主题库分类主键");
      VciBaseUtil.alertNotNull(orderDTO, "编码申请相关的数据", orderDTO.getCodeClassifyOid(), "主题库分类主键");
      ReadExcelOption reo = new ReadExcelOption();
      reo.setReadAllSheet(true);
      List<SheetDataSet> sheetDataSetList = ExcelUtil.readDataObjectFromExcel(file,null,reo);
      if(CollectionUtils.isEmpty(sheetDataSetList) || CollectionUtils.isEmpty(sheetDataSetList.get(0).getRowData())
         ||sheetDataSetList.get(0).getRowData().size()<1){
      List<SheetDataSet> sheetDataSetList = ExcelUtil.readDataObjectFromExcel(file, null, reo);
      if (CollectionUtils.isEmpty(sheetDataSetList) || CollectionUtils.isEmpty(sheetDataSetList.get(0).getRowData())
         || sheetDataSetList.get(0).getRowData().size() < 1) {
         throw new VciBaseException("没有读取到任何的数据");
      }
      if(sheetDataSetList.size()>LIMIT+1){
      if (sheetDataSetList.size() > LIMIT + 1) {
         throw new VciBaseException("为了保证系统的稳定性,请一次不要导入超过1万条的数据");
      }
      //先找到每一行的标题,然后根据标题来获取对应的属性
@@ -693,17 +816,17 @@
      CodeClassifyTemplateVO templateVO = engineService.getUsedTemplateByClassifyOid(orderDTO.getCodeClassifyOid());
      //校验模板是不是最新的
      checkTemplateSync(sheetDataSetList,templateVO,0);
      checkTemplateSync(sheetDataSetList, templateVO, 0);
      //先不用管属性是否都存在,先转换一下数据
      Map<String,String> errorMap = new ConcurrentHashMap<>();
      String redisUUid=batchImportCodes(orderDTO,templateVO,dataSet,errorMap,true);
      Map<String, String> errorMap = new ConcurrentHashMap<>();
      String redisUUid = batchImportCodes(orderDTO, templateVO, dataSet, errorMap, true);
      CodeImProtRusultVO codeImProtRusultVO = new CodeImProtRusultVO();
      List<String> needRowIndexList = new ArrayList<>();
      String filePath = returnErrorToExcel(dataSet.getRowData(), errorMap, needRowIndexList, dataSet.getColName());
      if(StringUtils.isNotBlank(filePath)) {
      if (StringUtils.isNotBlank(filePath)) {
         codeImProtRusultVO.setFilePath(filePath);
      }
      if(StringUtils.isNotBlank(redisUUid)){
      if (StringUtils.isNotBlank(redisUUid)) {
         codeImProtRusultVO.setRedisUuid(redisUUid);
      }
//      return null;
@@ -719,24 +842,24 @@
    */
   @Override
   public CodeImProtRusultVO batchTopImportCode(String codeClassifyOid, String classifyAttr, File file) {
      VciBaseUtil.alertNotNull(codeClassifyOid,"分类的主键");
      VciBaseUtil.alertNotNull(codeClassifyOid, "分类的主键");
      ReadExcelOption reo = new ReadExcelOption();
      reo.setReadAllSheet(true);
      List<SheetDataSet> sheetDataSetList = ExcelUtil.readDataObjectFromExcel(file,null,reo);
      if(CollectionUtils.isEmpty(sheetDataSetList) || CollectionUtils.isEmpty(sheetDataSetList.get(0).getRowData())
         ||sheetDataSetList.get(0).getRowData().size()<1){
      List<SheetDataSet> sheetDataSetList = ExcelUtil.readDataObjectFromExcel(file, null, reo);
      if (CollectionUtils.isEmpty(sheetDataSetList) || CollectionUtils.isEmpty(sheetDataSetList.get(0).getRowData())
         || sheetDataSetList.get(0).getRowData().size() < 1) {
         throw new VciBaseException("没有读取到任何的数据");
      }
      if(sheetDataSetList.size()>LIMIT+1){
      if (sheetDataSetList.size() > LIMIT + 1) {
         throw new VciBaseException("为了保证系统的稳定性,请一次不要导入超过1万条的数据");
      }
      //先找到每一行的标题,然后根据标题来获取对应的属性
      SheetDataSet dataSet = sheetDataSetList.get(0);
      CodeClassifyFullInfoBO classifyFullInfo = classifyService.getClassifyFullInfo(codeClassifyOid);
      //获取当前模板
      CodeClassifyTemplateVO selectCodeClassifyTemplateVO =engineService.getUsedTemplateByClassifyOid(codeClassifyOid);
      Map<String,List<ColumnVO>> templateColumnVOMap=new HashMap<>();
      createTemplate(selectCodeClassifyTemplateVO,templateColumnVOMap);
      CodeClassifyTemplateVO selectCodeClassifyTemplateVO = engineService.getUsedTemplateByClassifyOid(codeClassifyOid);
      Map<String, List<ColumnVO>> templateColumnVOMap = new HashMap<>();
      createTemplate(selectCodeClassifyTemplateVO, templateColumnVOMap);
      List<CodeClassifyVO> childClassifyVOs = classifyService.listChildrenClassify(codeClassifyOid, true, classifyAttr, true);
      Map<String/**路径**/, CodeClassifyVO> pathMap = Optional.ofNullable(childClassifyVOs).orElseGet(() -> new ArrayList<>()).stream().collect(Collectors.toMap(s -> s.getPath().startsWith("#") ? s.getPath().substring(1) : s.getPath(), t -> t));
@@ -744,65 +867,66 @@
      List<String> titleRowData = dataSet.getColName();
      Map<String, String> errorMap = new ConcurrentHashMap<>();
      //首先将数据以模板的形式分开
      LinkedHashMap<String,List<CodeImprotDataVO>> codeclassifyDataMap=new LinkedHashMap<>();
      List<CodeImprotDataVO> codeClassifyDatas=new ArrayList<>();
      createExeclClassData(dataSet,pathMap,errorMap,codeClassifyDatas);
      LinkedHashMap<String, List<CodeImprotDataVO>> codeclassifyDataMap = new LinkedHashMap<>();
      List<CodeImprotDataVO> codeClassifyDatas = new ArrayList<>();
      createExeclClassData(dataSet, pathMap, errorMap, codeClassifyDatas);
      //根据模板将数据整合在一起,去校验
      Map<String/**模板oid**/, List<CodeImprotDataVO>/**数据对象**/> templateDatasMap =codeClassifyDatas.stream().collect(Collectors.toMap(CodeImprotDataVO::getTemplateOid,s->{
         List<CodeImprotDataVO> l=new ArrayList<>();
      Map<String/**模板oid**/, List<CodeImprotDataVO>/**数据对象**/> templateDatasMap = codeClassifyDatas.stream().collect(Collectors.toMap(CodeImprotDataVO::getTemplateOid, s -> {
         List<CodeImprotDataVO> l = new ArrayList<>();
         l.add(s);
         return l;
      },(List<CodeImprotDataVO> s1,List<CodeImprotDataVO> s2)->{
      }, (List<CodeImprotDataVO> s1, List<CodeImprotDataVO> s2) -> {
         s1.addAll(s2);
         return s1;
      }));
      String uuid=VciBaseUtil.getPk();
      List<CodeImportTemplateVO> codeImportTemplateVOS=new ArrayList<>();
      Map<String,CodeImportTemplateVO> codeRuleMap=new HashMap<>();
      String uuid = VciBaseUtil.getPk();
      List<CodeImportTemplateVO> codeImportTemplateVOS = new ArrayList<>();
      Map<String, CodeImportTemplateVO> codeRuleMap = new HashMap<>();
      //相似数据
      // Map<String,String>wpResembleMap=new HashMap<>();
      // List<CodeImprotDataVO> wpCodeImprotDataVOList=new ArrayList<>();
      //按照模板去整理数据
      templateDatasMap.keySet().stream().forEach(templateVOOid->{
         List<CodeImprotDataVO> codeImprotDataVOS= templateDatasMap.get(templateVOOid);
         CodeClassifyTemplateVO templateVO= templateService.getObjectHasAttrByOid(templateVOOid);
      templateDatasMap.keySet().stream().forEach(templateVOOid -> {
         List<CodeImprotDataVO> codeImprotDataVOS = templateDatasMap.get(templateVOOid);
         CodeClassifyTemplateVO templateVO = templateService.getObjectHasAttrByOid(templateVOOid);
         //除去默认的属性.还有只有表单显示的字段才导入
         List<CodeClassifyTemplateAttrVO> attrVOS = templateVO.getAttributes().stream().filter(s ->
            !DEFAULT_ATTR_LIST.contains(s.getId()) && VciBaseUtil.getBoolean(s.getFormDisplayFlag())
            !DEFAULT_ATTR_LIST.contains(s.getId()) &&
               ((Func.isNotEmpty(s.getClassifyInvokeAttr()) || Func.isNotEmpty(s.getClassifyInvokeAttrName())) || VciBaseUtil.getBoolean(s.getFormDisplayFlag()))
         ).collect(Collectors.toList());
         Map<String/**模板属性字段oid**/, String /**模板属性外部名称**/> fieldNameMap =attrVOS.stream().collect(Collectors.toMap(CodeClassifyTemplateAttrVO::getId,s->s.getName()));
         Map<String/**模板属性字段oid**/, String /**模板属性外部名称**/> fieldNameMap = attrVOS.stream().collect(Collectors.toMap(CodeClassifyTemplateAttrVO::getId, s -> s.getName()));
         List<ClientBusinessObject> allCboList=new ArrayList<>();
         List<ClientBusinessObject> allCboList = new ArrayList<>();
         codeImprotDataVOS.stream().forEach(codeImprotDataVO -> {
            List<ColumnVO>columnVOList =new ArrayList();
            String templateOid=selectCodeClassifyTemplateVO.getOid();
            if(templateColumnVOMap.containsKey(templateOid)){
               columnVOList= columnVOList=templateColumnVOMap.get(templateOid);
            }else{
               createTemplate(templateVO,templateColumnVOMap);
               columnVOList= columnVOList=templateColumnVOMap.get(templateOid);
            List<ColumnVO> columnVOList = new ArrayList();
            String templateOid = selectCodeClassifyTemplateVO.getOid();
            if (templateColumnVOMap.containsKey(templateOid)) {
               columnVOList = columnVOList = templateColumnVOMap.get(templateOid);
            } else {
               createTemplate(templateVO, templateColumnVOMap);
               columnVOList = columnVOList = templateColumnVOMap.get(templateOid);
            }
            String codeRuleOid=codeImprotDataVO.getCodeRuleOid();
            if(!codeRuleMap.containsKey(codeRuleOid)){
               CodeImportTemplateVO codeImportTemplateVO=new CodeImportTemplateVO();
            String codeRuleOid = codeImprotDataVO.getCodeRuleOid();
            if (!codeRuleMap.containsKey(codeRuleOid)) {
               CodeImportTemplateVO codeImportTemplateVO = new CodeImportTemplateVO();
               codeImportTemplateVO.setRoot(false);
               codeImportTemplateVO.setCodeClassifyOid(codeImprotDataVO.getCodeClassifyOid());
               codeImportTemplateVO.setCodeRuleOid(codeImprotDataVO.getCodeRuleOid());
               codeImportTemplateVO.setCodeTemplateOid (codeImprotDataVO.getTemplateOid());
               codeImportTemplateVO.setCodeClassifyVO( codeImprotDataVO.getCodeClassifyVO());
               codeImportTemplateVO.setCodeClassifyTemplateVO( codeImprotDataVO.getCodeClassifyTemplateVO());
               codeImportTemplateVO.setCodeTemplateOid(codeImprotDataVO.getTemplateOid());
               codeImportTemplateVO.setCodeClassifyVO(codeImprotDataVO.getCodeClassifyVO());
               codeImportTemplateVO.setCodeClassifyTemplateVO(codeImprotDataVO.getCodeClassifyTemplateVO());
               codeImportTemplateVO.setCodeRuleVO(codeImprotDataVO.getCodeRuleVO());
               List<String> colNames=codeImprotDataVO.getColNames();
               List<String> colNames = codeImprotDataVO.getColNames();
               codeImportTemplateVO.setCloNamesList(columnVOList);
               codeImportTemplateVOS.add(codeImportTemplateVO);
               codeRuleMap.put(codeRuleOid,codeImportTemplateVO);
               codeRuleMap.put(codeRuleOid, codeImportTemplateVO);
            }
            List<ClientBusinessObject> cboList=new ArrayList<>();
            excelToCbo(classifyFullInfo,codeImprotDataVO,cboList,true);
            List<ClientBusinessObject> cboList = new ArrayList<>();
            excelToCbo(classifyFullInfo, codeImprotDataVO, cboList, true);
            allCboList.addAll(cboList);
            //往选择的节点里面加数据
            // CodeImprotDataVO wpcodeImprotDataVO=new CodeImprotDataVO();
@@ -818,87 +942,86 @@
         //都转换完了。需要批量检查
         //如果出错了,我们依然执行有效的数据,无效的数据写回到excel中
         //2.判断必输项。。需要全部的属性,如果是必输,但是表单里面不显示的,只能是分类注入或者组合规则
         batchCheckRequiredAttrOnOrder(templateVO,allCboList,errorMap);
         batchCheckRequiredAttrOnOrder(templateVO, allCboList, errorMap);
         //3.判断关键属性
         CodeImportResultVO keyResultVO = batchCheckKeyAttrOnOrder(classifyFullInfo, templateVO, allCboList,errorMap);
         CodeImportResultVO keyResultVO = batchCheckKeyAttrOnOrder(classifyFullInfo, templateVO, allCboList, false, errorMap);
         Set<String> selfRepeatRowIndexList = keyResultVO.getSelfRepeatRowIndexList();
         Set<String> keyAttrRepeatRowIndexList = keyResultVO.getKeyAttrRepeatRowIndexList();
         if(!CollectionUtils.isEmpty(selfRepeatRowIndexList)){
            selfRepeatRowIndexList.stream().forEach(rowIndex->{
               errorMap.put(rowIndex,errorMap.getOrDefault(rowIndex,"") + ";在当前处理的数据文件中关键属性重复" );
         if (!CollectionUtils.isEmpty(selfRepeatRowIndexList)) {
            selfRepeatRowIndexList.stream().forEach(rowIndex -> {
               errorMap.put(rowIndex, errorMap.getOrDefault(rowIndex, "") + String.format(";在当前处理的数据文件中关键属性重复[%s],[%s];", keyResultVO.getKeyAttrRuleInfo(), keyResultVO.getSynonymRuleInfo()));
            });
         }
         if(!CollectionUtils.isEmpty(keyAttrRepeatRowIndexList)){
            keyAttrRepeatRowIndexList.stream().forEach(rowIndex->{
               errorMap.put(rowIndex, "关键属性与系统中的重复;" + errorMap.getOrDefault(rowIndex,"") );
         if (!CollectionUtils.isEmpty(keyAttrRepeatRowIndexList)) {
            keyAttrRepeatRowIndexList.stream().forEach(rowIndex -> {
               errorMap.put(rowIndex, errorMap.getOrDefault(rowIndex, "") + String.format("关键属性与系统中的重复[%s],[%s];", keyResultVO.getKeyAttrRuleInfo(), keyResultVO.getSynonymRuleInfo()));
            });
         }
         //分类注入
         // batchSwitchClassifyAttrOnOrder(attrVOS,allCboList,classifyFullInfo,false);
         //boolean
         reSwitchBooleanAttrOnOrder(attrVOS,allCboList);
         reSwitchBooleanAttrOnOrder(attrVOS, allCboList);
         //4.校验规则
         batchCheckVerifyOnOrder(attrVOS, allCboList,errorMap);
         batchCheckVerifyOnOrder(attrVOS, allCboList, errorMap);
         //是否需要校验枚举/参照
         //5.校验枚举是否正确
         batchSwitchEnumAttrOnOrder(attrVOS, allCboList, errorMap);
         //7.处理参照的情况
         batchSwitchReferAttrOnOrder(attrVOS,allCboList,errorMap);
         batchSwitchReferAttrOnOrder(attrVOS, allCboList, errorMap);
         //6.时间格式的验证
         //6.时间的,必须统一为yyyy-MM-dd HH:mm:ss
         batchSwitchDateAttrOnOrder(attrVOS,allCboList,errorMap);
         batchSwitchDateAttrOnOrder(attrVOS, allCboList, errorMap);
         //设置默认值
         batchSwitchAttrDefault(attrVOS, allCboList);
         //最后弄组合规则
         batchSwitchComponentAttrOnOrder(attrVOS,allCboList);
         batchSwitchComponentAttrOnOrder(attrVOS, allCboList);
         Map<String, ClientBusinessObject> rowIndexCboMap = allCboList.stream().filter(cbo -> cbo != null).collect(Collectors.toList()).stream().collect(Collectors.toMap(s -> s.getAttributeValue((IMPORT_ROW_INDEX)), t -> t));
         List<ClientBusinessObject> needSaveCboList = allCboList.stream().filter(cbo -> {
            String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX);
            return !errorMap.containsKey(rowIndex);
         }).collect(Collectors.toList());
         //相似校验
         Map<String,String>resembleMap=new HashMap<>();
         List<DataResembleVO> dataResembleVOS=new ArrayList<>();
         String btmtypeid= classifyFullInfo.getTopClassifyVO().getBtmTypeId();
         bathcResembleQuery(codeClassifyOid,templateVO,needSaveCboList,resembleMap,btmtypeid,dataResembleVOS);
         if(resembleMap.size()>0) {
            if(!CollectionUtils.isEmpty(dataResembleVOS)) {
         Map<String, String> resembleMap = new HashMap<>();
         List<DataResembleVO> dataResembleVOS = new ArrayList<>();
         String btmtypeid = classifyFullInfo.getTopClassifyVO().getBtmTypeId();
         //相似项查询规则
         bathcResembleQuery(codeClassifyOid, templateVO, needSaveCboList, resembleMap, btmtypeid, dataResembleVOS);
         if (resembleMap.size() > 0) {
            if (!CollectionUtils.isEmpty(dataResembleVOS)) {
               bladeRedis.set(uuid + "-resemble-data", dataResembleVOS);
               bladeRedis.expire(uuid + "-resemble-data",BATCHADD_REDIS_TIME);//redis过期时间
               bladeRedis.expire(uuid + "-resemble-data", BATCHADD_REDIS_TIME);//redis过期时间
               // createRedisDatas(uuid + "-resemble", codeImprotDataVOS, resembleMap, false);
               //  wpResembleMap.putAll(resembleMap);
            }
         }
         //排除错误的,剩下正确的
         Map<String,String> newErrorMap=new HashMap<>();
         Map<String, String> newErrorMap = new HashMap<>();
         newErrorMap.putAll(resembleMap);
         newErrorMap.putAll(errorMap);
         needSaveCboList = allCboList.stream().filter(cbo -> {
            String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX);
            return !newErrorMap.containsKey(rowIndex);
         }).collect(Collectors.toList());
         if(newErrorMap.size()>0) {
            createRedisDatas(uuid + "-resemble",codeImprotDataVOS, newErrorMap,false);
         if (newErrorMap.size() > 0) {
            createRedisDatas(uuid + "-resemble", codeImprotDataVOS, newErrorMap, false);
         }
         createRedisDatas(uuid + "-ok",codeImprotDataVOS, newErrorMap,true);
         createRedisDatas(uuid + "-ok", codeImprotDataVOS, newErrorMap, true);
      });
      //往物品节点上加模板
      List<String> needRowIndexList=new ArrayList<>();
      List<String> needRowIndexList = new ArrayList<>();
      CodeImProtRusultVO codeImProtRusultVO = new CodeImProtRusultVO();
      if(errorMap.size()>0) {
      if (errorMap.size() > 0) {
         String filePath = returnErrorToExcel(dataSet.getRowData(), errorMap, needRowIndexList, dataSet.getColName());
         if (StringUtils.isNotBlank(filePath)) {
            codeImProtRusultVO.setFilePath(filePath);
         }
      }
      if(StringUtils.isNotBlank(uuid)){
      if (StringUtils.isNotBlank(uuid)) {
         //将所有的分类存入缓存之中
         codeImProtRusultVO.setRedisUuid(uuid);
         /**  List<ColumnVO>columnVOList=new ArrayList<>();
@@ -929,9 +1052,9 @@
          return !newErrorMap.containsKey(rowIndex);
          }).collect(Collectors.toList());
          createRedisDatas(uuid + "-ok",selectCodeClassifyTemplateVO,wpCodeImprotDataVOList, newErrorMap,true,codeClassifyOid);****/
         if(codeImportTemplateVOS.size()>0){
            bladeRedis.set(uuid + "-class",codeImportTemplateVOS);
            bladeRedis.expire(uuid + "-class",BATCHADD_REDIS_TIME);
         if (codeImportTemplateVOS.size() > 0) {
            bladeRedis.set(uuid + "-class", codeImportTemplateVOS);
            bladeRedis.expire(uuid + "-class", BATCHADD_REDIS_TIME);
         }
      }
      return codeImProtRusultVO;
@@ -941,37 +1064,37 @@
    * 导入历史数据
    *
    * @param codeClassifyOid 分类的主键
    * @param classifyAttr 分类路径使用的属性
    * @param classifyAttr    分类路径使用的属性
    * @param file            excel文件的信息
    * @return 有错误信息的excel
    */
   @Override
   public CodeImProtRusultVO batchImportHistoryData(String codeClassifyOid, String classifyAttr,File file) throws  Throwable{
   public CodeImProtRusultVO batchImportHistoryData(String codeClassifyOid, String classifyAttr, File file) throws Throwable {
      try {
         VciBaseUtil.alertNotNull(codeClassifyOid,"分类的主键");
         VciBaseUtil.alertNotNull(codeClassifyOid, "分类的主键");
         ReadExcelOption reo = new ReadExcelOption();
         reo.setReadAllSheet(true);
         List<SheetDataSet> sheetDataSetList = ExcelUtil.readDataObjectFromExcel(file,null,reo);
         List<SheetDataSet> sheetDataSetList = ExcelUtil.readDataObjectFromExcel(file, null, reo);
         if (sheetDataSetList.size() > LIMIT + 1) {
            throw new VciBaseException("为了保证系统的稳定性,请一次不要导入超过1万条的数据");
         }
         Map<String,List<WriteExcelData>> shetNameMap=new HashMap<>();
         Map<String, List<WriteExcelData>> shetNameMap = new HashMap<>();
         //相似项目查重
         String uuid=VciBaseUtil.getPk();
         boolean isCreateUUid=false;
         boolean isExport=false;
         String uuid = VciBaseUtil.getPk();
         boolean isCreateUUid = false;
         boolean isExport = false;
         //long start = System.currentTimeMillis();
         // 记录导入成功的总数
         List<Integer> importCount = new ArrayList<>();
         CodeClassifyFullInfoBO classifyFullInfo = classifyService.getClassifyFullInfo(codeClassifyOid);
         for(int i=0;i<sheetDataSetList.size()-1;i++) {
         for (int i = 0; i < sheetDataSetList.size() - 1; i++) {
            if (CollectionUtils.isEmpty(sheetDataSetList) || CollectionUtils.isEmpty(sheetDataSetList.get(i).getRowData())
               || sheetDataSetList.get(i).getRowData().size() < 1) {
               continue;
            }
            // 单次导入数量限制
            if(sheetDataSetList.get(i).getRowData().size() > IMPORT_DATA_LIMIT){
               throw new ServiceException(StringUtil.format("为了保证系统的稳定性,请一次不要导入超过{}条的数据",IMPORT_DATA_LIMIT));
            if (sheetDataSetList.get(i).getRowData().size() > IMPORT_DATA_LIMIT) {
               throw new ServiceException(StringUtil.format("为了保证系统的稳定性,请一次不要导入超过{}条的数据", IMPORT_DATA_LIMIT));
            }
            //历史导入的时候不处理编码
            //----逻辑内容----
@@ -1002,13 +1125,13 @@
            Map<String/**路径**/, CodeClassifyVO> pathMap = Optional.ofNullable(childClassifyVOs).orElseGet(() -> new ArrayList<>()).stream().collect(Collectors.toMap(s -> s.getPath().startsWith("#") ? s.getPath().substring(1) : s.getPath(), t -> t));
            List<String> titleRowData = dataSet.getColName();
            Map<String, String> errorMap = new ConcurrentHashMap<>();
            pathMap.put("#current#",classifyFullInfo.getCurrentClassifyVO());
            pathMap.put("#current#", classifyFullInfo.getCurrentClassifyVO());
            try {
               List<CodeClassifyTemplateVO> templateVOList= checkSamesTemplate(titleRowData,sheetDataSetList,i,pathMap,errorMap);
               templateVO= templateVOList.get(0);
            }catch (Throwable e){
               throw  new VciBaseException(e.getMessage());
               List<CodeClassifyTemplateVO> templateVOList = checkSamesTemplate(titleRowData, sheetDataSetList, i, pathMap, errorMap);
               templateVO = templateVOList.get(0);
            } catch (Throwable e) {
               throw new VciBaseException(e.getMessage());
            }
            List<SheetRowData> needowDataList = rowDataList.stream().filter(cbo -> {
@@ -1084,7 +1207,7 @@
            batchSwitchReferAttrOnOrder(attrVOS, cboList, errorMap);
            //6.处理分类注入
            batchSwitchClassifyAttrOnOrder(attrVOS, cboList, classifyFullInfo,true);
            batchSwitchClassifyAttrOnOrder(attrVOS, cboList, classifyFullInfo, true);
            //设置默认值
            batchSwitchAttrDefault(attrVOS, cboList);
@@ -1093,17 +1216,17 @@
            batchSwitchComponentAttrOnOrder(attrVOS, cboList);
            //3.判断关键属性
            CodeImportResultVO keyResultVO = batchCheckKeyAttrOnOrder(classifyFullInfo, templateVO, cboList,errorMap);
            CodeImportResultVO keyResultVO = batchCheckKeyAttrOnOrder(classifyFullInfo, templateVO, cboList, false, errorMap);
            Set<String> selfRepeatRowIndexList = keyResultVO.getSelfRepeatRowIndexList();
            Set<String> keyAttrRepeatRowIndexList = keyResultVO.getKeyAttrRepeatRowIndexList();
            if (!CollectionUtils.isEmpty(selfRepeatRowIndexList)) {
               selfRepeatRowIndexList.stream().forEach(rowIndex -> {
                  errorMap.put(rowIndex, errorMap.getOrDefault(rowIndex, "") + ";在当前excel文件中关键属性重复");
                  errorMap.put(rowIndex, errorMap.getOrDefault(rowIndex, "") + String.format(";在当前excel文件中关键属性重复[%s],[%s];", keyResultVO.getKeyAttrRuleInfo(), keyResultVO.getSynonymRuleInfo()));
               });
            }
            if (!CollectionUtils.isEmpty(keyAttrRepeatRowIndexList)) {
               keyAttrRepeatRowIndexList.stream().forEach(rowIndex -> {
                  errorMap.put(rowIndex, "关键属性与系统中的重复;" + errorMap.getOrDefault(rowIndex, ""));
                  errorMap.put(rowIndex, errorMap.getOrDefault(rowIndex, "") + String.format("关键属性与系统中的重复[%s],[%s];", keyResultVO.getKeyAttrRuleInfo(), keyResultVO.getSynonymRuleInfo()));
               });
            }
            //4.校验规则
@@ -1123,21 +1246,23 @@
               List<String> rowIndexList = ruleRowIndexMap.get(ruleOid);
               List<ClientBusinessObject> thisCbos = cboList.stream().filter(cbo -> rowIndexList.contains(cbo.getAttributeValue(IMPORT_ROW_INDEX)) && !errorMap.containsKey(cbo.getAttributeValue(IMPORT_ROW_INDEX))).collect(Collectors.toList());
               //我们需要先查询一下,内容是否已经存在
               if(!CollectionUtils.isEmpty(thisCbos)){
               if (!CollectionUtils.isEmpty(thisCbos)) {
                  List<String> existIds = new ArrayList<>();
                  // TODO: 2024/12/3 Ludc 这儿查询做了修改改成组成一句sql查询,而不是分批次查询
                  LambdaQueryWrapper<CodeAllCode> wrapper =  Wrappers.<CodeAllCode>query().lambda()
                     .eq(CodeAllCode::getCodeRuleOid, ruleOid);
                  VciBaseUtil.switchCollectionForOracleIn(thisCbos).stream().forEach(cbos -> {
                     List<CodeAllCode> codeAllCodeList= codeAllCodeService.selectByWrapper(Wrappers.<CodeAllCode>query().lambda().eq(CodeAllCode::getCodeRuleOid, ruleOid)
                        .notIn(CodeAllCode::getId,cbos.stream().map(s -> s.getId()).collect(Collectors.toSet()).toArray(new String[0]))
                        .notIn(CodeAllCode::getLcStatus,CodeAllCodeLC.TASK_BACK.getValue() + "','" + CodeAllCodeLC.OBSOLETED.getValue())
                     );
                     existIds.addAll(Optional.ofNullable(codeAllCodeList).orElseGet(() -> new ArrayList<>()).stream().map(s -> {
                        String id = s.getId();
                        if (StringUtils.isBlank(id)) {
                           id = s.getId();
                        }
                        return id;
                     }).collect(Collectors.toList()));
                     wrapper.notIn(CodeAllCode::getId, cbos.stream().map(s -> s.getId()).collect(Collectors.toSet()).toArray(new String[0]));
                  });
                  wrapper.notIn(CodeAllCode::getLcStatus, CodeAllCodeLC.TASK_BACK.getValue() + "','" + CodeAllCodeLC.OBSOLETED.getValue());
                  List<CodeAllCode> codeAllCodeList = codeAllCodeService.selectByWrapper(wrapper);
                  existIds.addAll(Optional.ofNullable(codeAllCodeList).orElseGet(() -> new ArrayList<>()).stream().map(s -> {
                     String id = s.getId();
                     if (StringUtils.isBlank(id)) {
                        id = s.getId();
                     }
                     return id;
                  }).collect(Collectors.toList()));
                  List<String> existIdCbos = thisCbos.stream().filter(s -> {
                     String id = s.getId();
                     if (StringUtils.isBlank(id)) {
@@ -1162,7 +1287,7 @@
            Map<String, ClientBusinessObject> rowIndexCboMap = cboList.stream().filter(cbo -> cbo != null).collect(Collectors.toList()).stream().collect(Collectors.toMap(s -> s.getAttributeValue((IMPORT_ROW_INDEX)), t -> t));
            if (errorMap.size() > 0) {
               isExport=true;
               isExport = true;
               createRedisDatas(uuid + "-error", templateVO, rowIndexCboMap, dataSet, fieldIndexMap, errorMap, false);
            }
            createWriteExcelData(rowDataList, errorMap, new ArrayList<>(), titleRowData, shetNameMap, templateVO);
@@ -1174,6 +1299,7 @@
            Map<String, String> resembleMap = new HashMap<>();
            List<DataResembleVO> dataResembleVOS = new ArrayList<>();
            String btmtypeid = classifyFullInfo.getTopClassifyVO().getBtmTypeId();
            // 相似项查询
            bathcResembleQuery(templateVO.getCodeclassifyoid(), templateVO, needSaveCboList, resembleMap, btmtypeid, dataResembleVOS);
            if (resembleMap.size() > 0) {
               if (!CollectionUtils.isEmpty(dataResembleVOS)) {
@@ -1181,9 +1307,10 @@
                  createRedisDatas(uuid + "-resemble", templateVO, rowIndexCboMap, dataSet, fieldIndexMap, resembleMap, false);
               }
            }
            //生成class缓存
            Map<String, String> rowIndexClsOidMap = cboList.stream().filter(cbo -> cbo != null).collect(Collectors.toList()).stream().collect(Collectors.toMap(s -> s.getAttributeValue((IMPORT_ROW_INDEX)), t -> t.getAttributeValue(CODE_CLASSIFY_OID_FIELD)));
            createRedisByCodeClassify(uuid + "-class",templateVO,dataSet,fieldIndexMap,true);
            createRedisByCodeClassify(uuid + "-class", templateVO, dataSet, fieldIndexMap, true);
            //获取编码,查询在系统中是否被其他的引用了
            //排除错误的,剩下正确的
            Map<String, String> newErrorMap = new HashMap<>();
@@ -1194,26 +1321,27 @@
               String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX);
               return !newErrorMap.containsKey(rowIndex);
            }).collect(Collectors.toList());
            if((errorMap.size()>0&&needSaveCboList.size()>0)||resembleMap.size()>0){
               isCreateUUid=true;
            if ((errorMap.size() > 0 && needSaveCboList.size() > 0) || resembleMap.size() > 0) {
               isCreateUUid = true;
            }
            List<String> needRowIndexList = needSaveCboList.stream().filter(s -> errorMap.containsKey(s.getAttributeValue(IMPORT_ROW_INDEX))).map(s -> s.getAttributeValue(IMPORT_ROW_INDEX)).collect(Collectors.toList());
            if (isExport||newErrorMap.size() > 0) {
            if (isExport || newErrorMap.size() > 0) {
               createRedisDatas(uuid + "-ok", templateVO, rowIndexCboMap, dataSet, fieldIndexMap, newErrorMap, true);
            } else {
               List<BaseModel> dataCBOIdList=new ArrayList<>();
               List<BaseModel> dataCBOIdList = new ArrayList<>();
               //SessionInfo sessionInfo = VciBaseUtil.getCurrentUserSessionInfo();
               List<ClientBusinessObject> finalNeedSaveCboList = needSaveCboList;
               CodeClassifyTemplateVO finalTemplateVO = templateVO;
               final BladeUser user = AuthUtil.getUser();
               ruleRowIndexMap.keySet().parallelStream().forEach(ruleOid -> {
                  //VciBaseUtil.setCurrentUserSessionInfo(sessionInfo);
                  List<String> rowIndexList = ruleRowIndexMap.get(ruleOid);
                  List<ClientBusinessObject> thisCbos = finalNeedSaveCboList.stream().filter(cbo -> rowIndexList.contains(cbo.getAttributeValue(IMPORT_ROW_INDEX)) && !errorMap.containsKey(cbo.getAttributeValue(IMPORT_ROW_INDEX))).collect(Collectors.toList());
                  List<BaseModel> dataCBOList=new CopyOnWriteArrayList<>();
                  List<BaseModel> dataCBOList = new CopyOnWriteArrayList<>();
                  thisCbos.stream().forEach(clientBusinessObject -> {
                     BaseModel baseModel=new BaseModel();
                     BeanUtil.convert(clientBusinessObject,baseModel);
                     BaseModel baseModel = new BaseModel();
                     BeanUtil.convert(clientBusinessObject, baseModel);
                     //baseModel.setData(VciBaseUtil.objectToMapString(clientBusinessObject));
                     dataCBOList.add(baseModel);
                     dataCBOIdList.add(baseModel);
@@ -1222,13 +1350,13 @@
                  if (!CollectionUtils.isEmpty(thisCbos)) {
                     try {
                        // TODO 多线程流问题
                        productCodeService.productCodeAndSaveData(classifyFullInfo, finalTemplateVO, ruleVOMap.get(ruleOid), null, dataCBOList);
                        productCodeService.productCodeAndSaveData(classifyFullInfo, finalTemplateVO, ruleVOMap.get(ruleOid), null, dataCBOList, user);
                        importCount.add(dataCBOList.size());
                     } catch (Throwable e) {
                        log.error("批量产生编码的时候出错了", e);
                        thisCbos.stream().forEach(cbo -> {
                           String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX);
                           errorMap.put(rowIndex, errorMap.getOrDefault(rowIndex, "") + ";系统错误,存储数据的时候出错了:"+e.getMessage());
                           errorMap.put(rowIndex, errorMap.getOrDefault(rowIndex, "") + ";系统错误,存储数据的时候出错了:" + e.getMessage());
                        });
                     }
                  }
@@ -1240,10 +1368,8 @@
               engineService.batchSaveSelectChar(templateVO, dataCBOIdList);
            }
         }
         //long end = System.currentTimeMillis();
         //log.info("=============for执行时间================="+String.valueOf((end-start)/1000));
         String excelFileName="";
         if(isExport&&!CollectionUtils.isEmpty(shetNameMap)) {
         String excelFileName = "";
         if (isExport && !CollectionUtils.isEmpty(shetNameMap)) {
            excelFileName = LocalFileUtil.getDefaultTempFolder() + File.separator + "错误信息.xls";
            WriteExcelOption eo = new WriteExcelOption();
            shetNameMap.forEach((shetName, errorDataList) -> {
@@ -1255,21 +1381,24 @@
               throw new VciBaseException(LangBaseUtil.getErrorMsg(e));
            }
            ExcelUtil.writeDataToFile(excelFileName, eo);
            saveLogUtil.operateLog("历史数据导入", true, StringUtil.format("错误信息:{}", JSON.toJSONString(shetNameMap)));
         } else {
            // 历史数据导入时出现了相似项返回结果时不算导入成功
            if (shetNameMap.isEmpty() || !isCreateUUid) {
               saveLogUtil.operateLog("历史数据导入", false, StringUtil.format("导入到分类{}中,导入成功总数为:{}", JSON.toJSONString(classifyFullInfo), Func.isEmpty(importCount) ? 0 : importCount.get(0)));
            }
         }
         CodeImProtRusultVO codeImProtRusultVO=new CodeImProtRusultVO();
         if(StringUtils.isNotBlank(excelFileName)) {
         CodeImProtRusultVO codeImProtRusultVO = new CodeImProtRusultVO();
         if (StringUtils.isNotBlank(excelFileName)) {
            codeImProtRusultVO.setFilePath(excelFileName);
            codeImProtRusultVO.setFileOid("");
            saveLogUtil.operateLog("历史数据导入",true, StringUtil.format("错误信息:{}",JSON.toJSONString(shetNameMap)));
         }else{
            saveLogUtil.operateLog("历史数据导入",false, StringUtil.format("导入到分类{}中,导入成功总数为:{}", JSON.toJSONString(classifyFullInfo),importCount.get(0)));
         }
         if(isCreateUUid){
         if (isCreateUUid) {
            codeImProtRusultVO.setRedisUuid(uuid);
         }
         return codeImProtRusultVO;
      }catch (Exception e){
         saveLogUtil.operateLog("历史数据导入",true,e.toString());
      } catch (Exception e) {
         saveLogUtil.operateLog("历史数据导入", true, e.toString());
         throw e;
      }
   }
@@ -1278,32 +1407,33 @@
    * 导入批量编辑数据
    *
    * @param codeClassifyOid 分类的主键
    * @param classifyAttr 分类路径使用的属性
    * @param classifyAttr    分类路径使用的属性
    * @param file            excel文件的信息
    * @return 有错误信息的excel
    */
   @Transactional
   @Override
   public CodeImProtRusultVO batchImportEdit(String codeClassifyOid, String classifyAttr,File file) throws  Throwable{
      VciBaseUtil.alertNotNull(codeClassifyOid,"分类的主键");
   public CodeImProtRusultVO batchImportEdit(String codeClassifyOid, String classifyAttr, File file) throws Throwable {
      VciBaseUtil.alertNotNull(codeClassifyOid, "分类的主键");
      ReadExcelOption reo = new ReadExcelOption();
      reo.setReadAllSheet(true);
      List<SheetDataSet> sheetDataSetList = ExcelUtil.readDataObjectFromExcel(file,null,reo);
      List<SheetDataSet> sheetDataSetList = ExcelUtil.readDataObjectFromExcel(file, null, reo);
      if (sheetDataSetList.get(0).getRowData().size() > LIMIT + 1) {
         throw new ServiceException("为了保证系统的稳定性,请一次不要导入超过1万条的数据");
      }
      if (sheetDataSetList.get(0).getRowData().size() == 0) {
         throw new ServiceException("未读取到excle相关数据,请确认!!!");
      }
      boolean isExport=false;
      Map<String,List<WriteExcelData>> shetNameMap=new HashMap<>();
      for(int i=0;i<sheetDataSetList.size()-1;i++) {
      boolean isExport = false;
      Map<String, List<WriteExcelData>> shetNameMap = new HashMap<>();
      for (int i = 0; i < sheetDataSetList.size() - 1; i++) {
         if (CollectionUtils.isEmpty(sheetDataSetList) || CollectionUtils.isEmpty(sheetDataSetList.get(i).getRowData())
            || sheetDataSetList.get(i).getRowData().size() < 1) {
            continue;
         }
         // 单次导入数量限制
         if(sheetDataSetList.get(i).getRowData().size() > IMPORT_DATA_LIMIT){
            throw new ServiceException("为了保证系统的稳定性,请一次不要导入超过"+IMPORT_DATA_LIMIT+"条的数据");
         if (sheetDataSetList.get(i).getRowData().size() > IMPORT_DATA_LIMIT) {
            throw new ServiceException("为了保证系统的稳定性,请一次不要导入超过" + IMPORT_DATA_LIMIT + "条的数据");
         }
         //查询分类和模板
         CodeClassifyFullInfoBO classifyFullInfo = classifyService.getClassifyFullInfo(codeClassifyOid);
@@ -1313,22 +1443,22 @@
         List<SheetRowData> rowDataList = dataSet.getRowData();
         //找第一行,为了找标题
         CodeClassifyTemplateVO templateVO ;
         CodeClassifyTemplateVO templateVO;
         //都转换完了。需要批量检查
         //找所有的分类路径,需要校验路径是否正确,是否都在当前的分类的下级
         List<CodeClassifyVO> childClassifyVOs = classifyService.listChildrenClassify(codeClassifyOid, true, classifyAttr, true);
         Map<String/**路径**/, CodeClassifyVO> pathMap = Optional.ofNullable(childClassifyVOs).orElseGet(() -> new ArrayList<>()).stream().collect(Collectors.toMap(s -> s.getPath().startsWith("#") ? s.getPath().substring(1) : s.getPath(), t -> t));
         List<String> titleRowData = dataSet.getColName();
         Map<String, String> errorMap = new ConcurrentHashMap<>();
         pathMap.put("#current#",classifyFullInfo.getCurrentClassifyVO());
         pathMap.put("#current#", classifyFullInfo.getCurrentClassifyVO());
         try {
            titleRowData.add("分类路径");
            List<CodeClassifyTemplateVO> templateVOList= checkSamesTemplate(titleRowData,sheetDataSetList,i,pathMap,errorMap);
            titleRowData.remove(titleRowData.size()-1);
            templateVO= templateVOList.get(0);
         }catch (Throwable e){
            throw  new VciBaseException(e.getMessage());
            List<CodeClassifyTemplateVO> templateVOList = checkSamesTemplate(titleRowData, sheetDataSetList, i, pathMap, errorMap);
            titleRowData.remove(titleRowData.size() - 1);
            templateVO = templateVOList.get(0);
         } catch (Throwable e) {
            throw new ServiceException(e.getMessage());
         }
         CodeClassifyTemplateVO finalTemplateVO = templateVO;
@@ -1342,7 +1472,7 @@
         Map<Integer/**列号**/, String/**字段的名称**/> fieldIndexMap = new HashMap<>();
         Map<String/**中文名称**/, String/**英文名称**/> attrNameIdMap = attrVOS.stream().collect(Collectors.toMap(s -> s.getName(), t -> t.getId()));
         fieldIndexMap.put(0,"id");
         fieldIndexMap.put(0, "id");
         getFieldIndexMap(titleRowData, attrNameIdMap, fieldIndexMap);
         //先不用管属性是否都存在,先转换一下数据
         CodeOrderDTO orderDTO = new CodeOrderDTO();
@@ -1354,27 +1484,17 @@
            CodeTemplateAttrSqlBO sqlBO = mdmEngineService.getSqlByTemplateVO(classifyFullInfo.getTopClassifyVO().getBtmTypeId(), templateVO, conditionMap, new PageHelper(-1));
            //我们使用和业务类型的来查询
            List<Map> cbosB = commonsMapper.selectBySql(sqlBO.getSqlUnPage());
            if(cbosB.size() == 0){
               throw  new ServiceException("编码:"+ sheetRowData.getData().get(0) + ",未能查询到相关数据。");
            if (cbosB.size() == 0) {
               throw new ServiceException("编码:" + sheetRowData.getData().get(0) + ",未能查询到相关数据。");
            }
            excelToCboEdit(fieldIndexMap, sheetRowData, orderDTO, cbosB.get(0));
            orderDTO.setCopyFromVersion(orderDTO.getOid());
            orderDTO.setOid(null);
            try {
               mdmEngineService.upSaveCode(orderDTO);
               List<Map> newCbos = commonsMapper.selectBySql(sqlBO.getSqlUnPage());
               //对码值表进行处理替换创建数据的oid
               QueryWrapper<CodeAllCode> wrapper = new QueryWrapper<>();
               wrapper.eq("CREATECODEOID",orderDTO.getCopyFromVersion());
               List<CodeAllCode> codeAllCodes = codeAllCodeService.selectByWrapper(wrapper);
               codeAllCodes.get(0).setCreateCodeOid(newCbos.get(0).get("OID").toString());
               codeAllCodes.get(0).setLastModifyTime(new Date());
               codeAllCodes.get(0).setTs(new Date());
               codeAllCodes.get(0).setLastModifier(AuthUtil.getUser().getUserName());
               codeAllCodeService.updateBatchById(codeAllCodes);
            } catch (Throwable e) {
               log.error("批量产生编码的时候出错了", e);
               errorMap.put(sheetRowData.getRowIndex(), ";系统错误,存储数据的时候出错了:"+e.getMessage());
               errorMap.put(sheetRowData.getRowIndex(), ";系统错误,存储数据的时候出错了:" + e.getMessage());
            }
         }
         if (errorMap.size() > 0) {
@@ -1383,8 +1503,8 @@
         createWriteExcelData(rowDataList, errorMap, new ArrayList<>(), titleRowData, shetNameMap, finalTemplateVO);
      }
      String excelFileName="";
      if(isExport&&!CollectionUtils.isEmpty(shetNameMap)) {
      String excelFileName = "";
      if (isExport && !CollectionUtils.isEmpty(shetNameMap)) {
         excelFileName = LocalFileUtil.getDefaultTempFolder() + File.separator + "错误信息.xls";
         WriteExcelOption eo = new WriteExcelOption();
         shetNameMap.forEach((shetName, errorDataList) -> {
@@ -1397,14 +1517,14 @@
         }
         ExcelUtil.writeDataToFile(excelFileName, eo);
      }
      CodeImProtRusultVO codeImProtRusultVO=new CodeImProtRusultVO();
      if(StringUtils.isNotBlank(excelFileName)) {
      CodeImProtRusultVO codeImProtRusultVO = new CodeImProtRusultVO();
      if (StringUtils.isNotBlank(excelFileName)) {
         codeImProtRusultVO.setFilePath(excelFileName);
         codeImProtRusultVO.setFileOid("");
         saveLogUtil.operateLog("数据批量更改",true, StringUtil.format("错误信息:{}",JSON.toJSONString(shetNameMap)) );
      }else{
         saveLogUtil.operateLog("数据批量更改",false, StringUtil.format("导入成功总数为:{}",
            sheetDataSetList.size()-1));
         saveLogUtil.operateLog("数据批量更改", true, StringUtil.format("错误信息:{}", JSON.toJSONString(shetNameMap)));
      } else {
         saveLogUtil.operateLog("数据批量更改", false, StringUtil.format("导入成功总数为:{}",
            sheetDataSetList.size() - 1));
      }
      return codeImProtRusultVO;
   }
@@ -1431,29 +1551,29 @@
    * @param shetNameMap
    * @param templateVO
    */
   private void createWriteExcelData(Collection<SheetRowData> rowDataList, Map<String,String> errorMap,
                             List<String> needRowIndexList, List<String> titleRowData, Map<String,List<WriteExcelData>> shetNameMap, CodeClassifyTemplateVO templateVO){
      List<WriteExcelData> errorDataList=new ArrayList<>();
   private void createWriteExcelData(Collection<SheetRowData> rowDataList, Map<String, String> errorMap,
                             List<String> needRowIndexList, List<String> titleRowData, Map<String, List<WriteExcelData>> shetNameMap, CodeClassifyTemplateVO templateVO) {
      List<WriteExcelData> errorDataList = new ArrayList<>();
      Map<String, SheetRowData> rowIndexDataMap = rowDataList.stream().filter(s -> !needRowIndexList.contains(s.getRowIndex())).collect(Collectors.toMap(s -> s.getRowIndex(), t -> t));
      errorDataList.add(new WriteExcelData(0,0,"错误信息"));
      errorDataList.add(new WriteExcelData(0, 0, "错误信息"));
      for (int i = 0; i < titleRowData.size(); i++) {
         //错误信息在最后
         errorDataList.add(new WriteExcelData(0,i+1,titleRowData.get(i)));
         errorDataList.add(new WriteExcelData(0, i + 1, titleRowData.get(i)));
      }
      Integer[] newRowIndex = new Integer[]{1};
      errorMap.forEach((index,error)->{
      errorMap.forEach((index, error) -> {
         //错误信息全部组合到一起
         SheetRowData rowData = rowIndexDataMap.getOrDefault(index, null);
         if(rowData!=null){
            errorDataList.add(new WriteExcelData(newRowIndex[0],0,error));
            rowData.getData().forEach((colIndex,value)->{
               errorDataList.add(new WriteExcelData(newRowIndex[0],colIndex+1,value));
         if (rowData != null) {
            errorDataList.add(new WriteExcelData(newRowIndex[0], 0, error));
            rowData.getData().forEach((colIndex, value) -> {
               errorDataList.add(new WriteExcelData(newRowIndex[0], colIndex + 1, value));
            });
            newRowIndex[0]++;
         }
      });
      shetNameMap.put(templateVO.getName(),errorDataList);
      shetNameMap.put(templateVO.getName(), errorDataList);
   }
   /***
@@ -1461,7 +1581,7 @@
    * @param currentTemplateVO
    * @param templateColumnVOMap
    */
   private void createTemplate(CodeClassifyTemplateVO currentTemplateVO,Map<String,List<ColumnVO>>templateColumnVOMap){
   private void createTemplate(CodeClassifyTemplateVO currentTemplateVO, Map<String, List<ColumnVO>> templateColumnVOMap) {
      List<CodeClassifyTemplateAttrVO> templateAttrVOS = currentTemplateVO.getAttributes().stream().filter(s ->
         !DEFAULT_ATTR_LIST.contains(s.getId())
@@ -1469,66 +1589,65 @@
            && StringUtils.isBlank(s.getClassifyInvokeAttr())
            && (VciBaseUtil.getBoolean(s.getFormDisplayFlag()))
      ).collect(Collectors.toList());
      if(CollectionUtils.isEmpty(templateAttrVOS)){
      if (CollectionUtils.isEmpty(templateAttrVOS)) {
         throw new VciBaseException("模板没有配置任何【表单显示】为【是】的属性");
      }
      List<ColumnVO> columnVOList=new ArrayList<>();
      List<ColumnVO> columnVOList = new ArrayList<>();
      ColumnVO errorMsgColumnVO=new ColumnVO();
      ColumnVO errorMsgColumnVO = new ColumnVO();
      errorMsgColumnVO.setTitle("错误信息");
      errorMsgColumnVO.setField("errorMsg");
      columnVOList.add(errorMsgColumnVO);
      ColumnVO pathColumnVO=new ColumnVO();
      ColumnVO pathColumnVO = new ColumnVO();
      pathColumnVO.setTitle("分类路径");
      pathColumnVO.setField("codeclsfid");
      columnVOList.add(pathColumnVO);
      templateAttrVOS.stream().forEach(codetemplateAttr ->{
         String field=codetemplateAttr.getId();
         String name=codetemplateAttr.getName();
         ColumnVO columnVO=new ColumnVO();
      templateAttrVOS.stream().forEach(codetemplateAttr -> {
         String field = codetemplateAttr.getId();
         String name = codetemplateAttr.getName();
         ColumnVO columnVO = new ColumnVO();
         columnVO.setTitle(name);
         columnVO.setField(field);
         columnVO.setWidth(codetemplateAttr.getAttrTableWidth()==0?columnVO.getWidth():codetemplateAttr.getAttrTableWidth());
         columnVO.setWidth(codetemplateAttr.getAttrTableWidth() == 0 ? columnVO.getWidth() : codetemplateAttr.getAttrTableWidth());
         columnVOList.add(columnVO);
      });
      templateColumnVOMap.put(currentTemplateVO.getOid(),columnVOList);
      log.info("模板"+currentTemplateVO.getName()+"对应的属性"+columnVOList.size());
      templateColumnVOMap.put(currentTemplateVO.getOid(), columnVOList);
      log.info("模板" + currentTemplateVO.getName() + "对应的属性" + columnVOList.size());
   }
   /**
    * 错误信息返回excel
    * @param rowDataList 所有的导入数据
    * @param errorMap 错误的信息
    * @param needRowIndexList 需要写入的数据的行号
    * @param titleRowData 标题行
    *
    * @param rowDataList      所有的导入数据
    * @param errorMap         错误的信息
    * @param needRowIndexList 需要写入的数据的行号
    * @param titleRowData     标题行
    * @return 错误的excel文件,没有错误会返回空
    */
   private String returnErrorToExcel(Collection<SheetRowData> rowDataList,
                             Map<String,String> errorMap,
                             List<String> needRowIndexList,List<String> titleRowData){
      if(CollectionUtils.isEmpty(errorMap)){
                             Map<String, String> errorMap,
                             List<String> needRowIndexList, List<String> titleRowData) {
      if (CollectionUtils.isEmpty(errorMap)) {
         return "";
      }
      Map<String, SheetRowData> rowIndexDataMap = rowDataList.stream().filter(s -> !needRowIndexList.contains(s.getRowIndex())).collect(Collectors.toMap(s -> s.getRowIndex(), t -> t));
      List<WriteExcelData> errorDataList = new ArrayList<>();
      errorDataList.add(new WriteExcelData(0,0,"错误信息"));
      errorDataList.add(new WriteExcelData(0, 0, "错误信息"));
      for (int i = 0; i < titleRowData.size(); i++) {
         //错误信息在最后
         errorDataList.add(new WriteExcelData(0,i+1,titleRowData.get(i)));
         errorDataList.add(new WriteExcelData(0, i + 1, titleRowData.get(i)));
      }
      Integer[] newRowIndex = new Integer[]{1};
      errorMap.forEach((index,error)->{
      errorMap.forEach((index, error) -> {
         //错误信息全部组合到一起
         SheetRowData rowData = rowIndexDataMap.getOrDefault(index, null);
         if(rowData!=null){
            errorDataList.add(new WriteExcelData(newRowIndex[0],0,error));
            rowData.getData().forEach((colIndex,value)->{
               errorDataList.add(new WriteExcelData(newRowIndex[0],colIndex+1,value));
         if (rowData != null) {
            errorDataList.add(new WriteExcelData(newRowIndex[0], 0, error));
            rowData.getData().forEach((colIndex, value) -> {
               errorDataList.add(new WriteExcelData(newRowIndex[0], colIndex + 1, value));
            });
            newRowIndex[0]++;
         }
@@ -1540,23 +1659,24 @@
      } catch (IOException e) {
         throw new VciBaseException(LangBaseUtil.getErrorMsg(e));
      }
      ExcelUtil.writeDataToFile(excelFileName,eo);
      ExcelUtil.writeDataToFile(excelFileName, eo);
      return excelFileName;
   }
   /**
    * 校验模板是否为同步的
    *
    * @param sheetDataSetList excel里的内容
    * @param templateVO 模板的信息
    * @param templateVO       模板的信息
    */
   private void checkTemplateSync(List<SheetDataSet> sheetDataSetList,CodeClassifyTemplateVO templateVO,int i){
   private void checkTemplateSync(List<SheetDataSet> sheetDataSetList, CodeClassifyTemplateVO templateVO, int i) {
      String templateOidInExcel = "";
      String templateName="";
      if(!CollectionUtils.isEmpty(sheetDataSetList)
         && sheetDataSetList.size()>1 && !CollectionUtils.isEmpty(sheetDataSetList.get(sheetDataSetList.size()-1).getColName())){
         List<SheetRowData>  rowData=  sheetDataSetList.get(sheetDataSetList.size()-1).getRowData();
         templateName=rowData.get(i).getData().get(2);
         templateOidInExcel=rowData.get(i).getData().get(0);
      String templateName = "";
      if (!CollectionUtils.isEmpty(sheetDataSetList)
         && sheetDataSetList.size() > 1 && !CollectionUtils.isEmpty(sheetDataSetList.get(sheetDataSetList.size() - 1).getColName())) {
         List<SheetRowData> rowData = sheetDataSetList.get(sheetDataSetList.size() - 1).getRowData();
         templateName = rowData.get(i).getData().get(2);
         templateOidInExcel = rowData.get(i).getData().get(0);
         //templateOidInExcel = sheetDataSetList.get(sheetDataSetList.size()-1).getColName().get(sheetDataSetList.size()-i);
      }
       /* if(!CollectionUtils.isEmpty(sheetDataSetList)
@@ -1565,8 +1685,8 @@
            templateOidInExcel=rowData.get(i).getData().get(0);
           //templateOidInExcel = sheetDataSetList.get(sheetDataSetList.size()-1).getColName().get(sheetDataSetList.size()-i);
        }*/
      if(StringUtils.isBlank(templateOidInExcel) || !templateOidInExcel.equalsIgnoreCase(templateVO.getOid())){
         throw new VciBaseException("模板【"+templateName+"】中的数据获取的模版信息与当前模板不匹配,请确保excel文件里有【模板信息-请勿移动或删除】的工作表,且确保每次导入都是先下载的导入模板后添加的数据");
      if (StringUtils.isBlank(templateOidInExcel) || !templateOidInExcel.equalsIgnoreCase(templateVO.getOid())) {
         throw new VciBaseException("模板【" + templateName + "】中的数据获取的模版信息与当前模板不匹配,请确保excel文件里有【模板信息-请勿移动或删除】的工作表,且确保每次导入都是先下载的导入模板后添加的数据");
      }
   }
@@ -1578,112 +1698,114 @@
    * @param dataSet
    * @return
    */
   private String batchImportCodes(CodeOrderDTO orderDTO,CodeClassifyTemplateVO templateVO,SheetDataSet dataSet,Map<String,String> errorMap,boolean isEnumType) throws Exception {
      List<String> codeList=new ArrayList<>();
   private String batchImportCodes(CodeOrderDTO orderDTO, CodeClassifyTemplateVO templateVO, SheetDataSet dataSet, Map<String, String> errorMap, boolean isEnumType) throws Exception {
      List<String> codeList = new ArrayList<>();
      String uuid = "";
      try {
         CodeClassifyFullInfoBO classifyFullInfo = classifyService.getClassifyFullInfo(orderDTO.getCodeClassifyOid());
         //规则的主键需要去获取
         CodeRuleVO ruleVO = engineService.getCodeRuleByClassifyFullInfo(classifyFullInfo);
         //1.判断规则中除了流水码段,是否有其他码段
         engineService.checkSecValueOnOrder(ruleVO,orderDTO);
         engineService.checkSecValueOnOrder(ruleVO, orderDTO);
         List<SheetRowData> rowDataList = dataSet.getRowData();
         //除去默认的属性.还有只有表单显示的字段才导入
         List<CodeClassifyTemplateAttrVO> attrVOS = templateVO.getAttributes().stream().filter(s ->
            !DEFAULT_ATTR_LIST.contains(s.getId()) && VciBaseUtil.getBoolean(s.getFormDisplayFlag())
            !DEFAULT_ATTR_LIST.contains(s.getId()) &&
               ((Func.isNotEmpty(s.getClassifyInvokeAttr()) || Func.isNotEmpty(s.getClassifyInvokeAttrName())) || VciBaseUtil.getBoolean(s.getFormDisplayFlag()))
         ).collect(Collectors.toList());
         Map<Integer/**列号**/,String/**字段的名称**/> fieldIndexMap = new HashMap<>();
         Map<Integer/**列号**/, String/**字段的名称**/> fieldIndexMap = new HashMap<>();
         List<String> titleRowData = dataSet.getColName();
         Map<String/**中文名称**/, String/**英文名称**/> attrNameIdMap = attrVOS.stream().collect(Collectors.toMap(s -> s.getName(), t -> t.getId().toLowerCase(Locale.ROOT),(o1, o2)->o2));
         getFieldIndexMap(titleRowData,attrNameIdMap,fieldIndexMap);
         Map<String/**中文名称**/, String/**英文名称**/> attrNameIdMap = attrVOS.stream().collect(Collectors.toMap(s -> s.getName(), t -> t.getId().toLowerCase(Locale.ROOT), (o1, o2) -> o2));
         getFieldIndexMap(titleRowData, attrNameIdMap, fieldIndexMap);
         //需要判断是否所有的属性都在模板上了
         List<CodeClassifyTemplateAttrVO> unExistAttrVOs = attrVOS.stream().filter(s -> !fieldIndexMap.containsValue(s.getId().toLowerCase(Locale.ROOT))
            && StringUtils.isBlank(s.getComponentRule()) && StringUtils.isBlank(s.getClassifyInvokeAttr())//组合规则和分类注入确实没给用户导出去
         ).collect(Collectors.toList());
         if(!CollectionUtils.isEmpty(unExistAttrVOs)){
         if (!CollectionUtils.isEmpty(unExistAttrVOs)) {
            throw new VciBaseException("【" + unExistAttrVOs.stream().map(CodeClassifyTemplateAttrVO::getName) + "】这些属性在列表中没有找到");
         }
         List<ClientBusinessObject> cboList = new ArrayList<>();
         String fullPath = getFullPath(classifyFullInfo);
         excelToCbo(classifyFullInfo,fieldIndexMap,rowDataList,templateVO,cboList,fullPath,true);
         excelToCbo(classifyFullInfo, fieldIndexMap, rowDataList, templateVO, cboList, fullPath, true);
         //都转换完了。需要批量检查
         //如果出错了,我们依然执行有效的数据,无效的数据写回到excel中
         //2.判断必输项。。需要全部的属性,如果是必输,但是表单里面不显示的,只能是分类注入或者组合规则
         batchCheckRequiredAttrOnOrder(templateVO,cboList,errorMap);
         batchCheckRequiredAttrOnOrder(templateVO, cboList, errorMap);
         //3.判断关键属性
         CodeImportResultVO keyResultVO = batchCheckKeyAttrOnOrder(classifyFullInfo, templateVO, cboList,errorMap);
         CodeImportResultVO keyResultVO = batchCheckKeyAttrOnOrder(classifyFullInfo, templateVO, cboList, false, errorMap);
         Set<String> selfRepeatRowIndexList = keyResultVO.getSelfRepeatRowIndexList();
         Set<String> keyAttrRepeatRowIndexList = keyResultVO.getKeyAttrRepeatRowIndexList();
         if(!CollectionUtils.isEmpty(selfRepeatRowIndexList)){
            selfRepeatRowIndexList.stream().forEach(rowIndex->{
               errorMap.put(rowIndex,errorMap.getOrDefault(rowIndex,"") + ";在当前处理的数据文件中关键属性重复" );
         if (!CollectionUtils.isEmpty(selfRepeatRowIndexList)) {
            selfRepeatRowIndexList.stream().forEach(rowIndex -> {
               errorMap.put(rowIndex, errorMap.getOrDefault(rowIndex, "") + String.format(";在当前处理的数据文件中关键属性重复[%s],[%s];", keyResultVO.getKeyAttrRuleInfo(), keyResultVO.getSynonymRuleInfo()));
            });
         }
         if(!CollectionUtils.isEmpty(keyAttrRepeatRowIndexList)){
            keyAttrRepeatRowIndexList.stream().forEach(rowIndex->{
               errorMap.put(rowIndex,"关键属性与系统中的重复;" + errorMap.getOrDefault(rowIndex,""));
         if (!CollectionUtils.isEmpty(keyAttrRepeatRowIndexList)) {
            keyAttrRepeatRowIndexList.stream().forEach(rowIndex -> {
               errorMap.put(rowIndex, errorMap.getOrDefault(rowIndex, "") + String.format("关键属性与系统中的重复[%s],[%s];", keyResultVO.getKeyAttrRuleInfo(), keyResultVO.getSynonymRuleInfo()));
            });
         }
         //分类注入
         batchSwitchClassifyAttrOnOrder(attrVOS,cboList,classifyFullInfo,false);
         batchSwitchClassifyAttrOnOrder(attrVOS, cboList, classifyFullInfo, false);
         //boolean
         reSwitchBooleanAttrOnOrder(attrVOS,cboList);
         reSwitchBooleanAttrOnOrder(attrVOS, cboList);
         //4.校验规则
         batchCheckVerifyOnOrder(attrVOS, cboList,errorMap);
         if(isEnumType) {//是否需要校验枚举/参照
         batchCheckVerifyOnOrder(attrVOS, cboList, errorMap);
         if (isEnumType) {//是否需要校验枚举/参照
            //5.校验枚举是否正确
            batchSwitchEnumAttrOnOrder(attrVOS, cboList, errorMap);
            //7.处理参照的情况
            batchSwitchReferAttrOnOrder(attrVOS,cboList,errorMap);
            batchSwitchReferAttrOnOrder(attrVOS, cboList, errorMap);
         }
         //6.时间格式的验证
         //6.时间的,必须统一为yyyy-MM-dd HH:mm:ss
         batchSwitchDateAttrOnOrder(attrVOS,cboList,errorMap);
         batchSwitchDateAttrOnOrder(attrVOS, cboList, errorMap);
         //最后弄组合规则
         batchSwitchComponentAttrOnOrder(attrVOS,cboList);
         uuid=VciBaseUtil.getPk();
         batchSwitchComponentAttrOnOrder(attrVOS, cboList);
         uuid = VciBaseUtil.getPk();
         Map<String, ClientBusinessObject> rowIndexCboMap = cboList.stream().filter(cbo -> cbo != null).collect(Collectors.toList()).stream().collect(Collectors.toMap(s -> s.getAttributeValue((IMPORT_ROW_INDEX)), t -> t));
         if(errorMap.size()>0) {
            createRedisDatas(uuid + "-error",templateVO, rowIndexCboMap, dataSet, fieldIndexMap, errorMap,false);
         if (errorMap.size() > 0) {
            createRedisDatas(uuid + "-error", templateVO, rowIndexCboMap, dataSet, fieldIndexMap, errorMap, false);
         }
         boolean isCreateUUid=false;
         boolean isCreateUUid = false;
         List<ClientBusinessObject> needSaveCboList = cboList.stream().filter(cbo -> {
            String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX);
            return !errorMap.containsKey(rowIndex);
         }).collect(Collectors.toList());
         //相似校验
         Map<String,String>resembleMap=new HashMap<>();
         List<DataResembleVO> dataResembleVOS=new ArrayList<>();
         String btmtypeid= classifyFullInfo.getTopClassifyVO().getBtmTypeId();
         bathcResembleQuery(orderDTO.getCodeClassifyOid(),templateVO,needSaveCboList,resembleMap,btmtypeid,dataResembleVOS);
         if(resembleMap.size()>0) {
            isCreateUUid=true;
            if(!CollectionUtils.isEmpty(dataResembleVOS)) {
         Map<String, String> resembleMap = new HashMap<>();
         List<DataResembleVO> dataResembleVOS = new ArrayList<>();
         String btmtypeid = classifyFullInfo.getTopClassifyVO().getBtmTypeId();
         //相似项查询
         bathcResembleQuery(orderDTO.getCodeClassifyOid(), templateVO, needSaveCboList, resembleMap, btmtypeid, dataResembleVOS);
         if (resembleMap.size() > 0) {
            isCreateUUid = true;
            if (!CollectionUtils.isEmpty(dataResembleVOS)) {
               bladeRedis.set(uuid + "-resemble-data", dataResembleVOS);
               createRedisDatas(uuid + "-resemble",templateVO, rowIndexCboMap, dataSet, fieldIndexMap, resembleMap, false);
               createRedisDatas(uuid + "-resemble", templateVO, rowIndexCboMap, dataSet, fieldIndexMap, resembleMap, false);
            }
         }
         //排除错误的,剩下正确的
         Map<String,String> newErrorMap=new HashMap<>();
         Map<String, String> newErrorMap = new HashMap<>();
         newErrorMap.putAll(resembleMap);
         newErrorMap.putAll(errorMap);
         needSaveCboList = cboList.stream().filter(cbo -> {
            String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX);
            return !newErrorMap.containsKey(rowIndex);
         }).collect(Collectors.toList());
         if((errorMap.size()>0&&needSaveCboList.size()>0)||resembleMap.size()>0){
            isCreateUUid=true;
         if ((errorMap.size() > 0 && needSaveCboList.size() > 0) || resembleMap.size() > 0) {
            isCreateUUid = true;
         }
         createRedisByCodeClassify(uuid + "-class",templateVO,dataSet,fieldIndexMap,false);
         if(newErrorMap.size()>0) {
            createRedisDatas(uuid + "-ok",templateVO, rowIndexCboMap, dataSet, fieldIndexMap, newErrorMap,true);
         }else {
            uuid="";
         createRedisByCodeClassify(uuid + "-class", templateVO, dataSet, fieldIndexMap, false);
         if (newErrorMap.size() > 0) {
            createRedisDatas(uuid + "-ok", templateVO, rowIndexCboMap, dataSet, fieldIndexMap, newErrorMap, true);
         } else {
            uuid = "";
            final BladeUser user = AuthUtil.getUser();
            //要把以上的错误的都抛出后,再继续处理时间和组合规则
            needSaveCboList = cboList.stream().filter(cbo -> {
               String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX);
@@ -1693,17 +1815,17 @@
            if (!CollectionUtils.isEmpty(needSaveCboList)) {
               //9.我们处理业务数据
               //生成编码的内容
               List<String> dataCBOIdList=new ArrayList<>();
               List<BaseModel> dataCBOList=new ArrayList<>();
               List<String> dataCBOIdList = new ArrayList<>();
               List<BaseModel> dataCBOList = new ArrayList<>();
               cboList.stream().forEach(clientBusinessObject -> {
                  BaseModel baseModel=new BaseModel();
                  BeanUtil.convert(clientBusinessObject,baseModel);
                  BaseModel baseModel = new BaseModel();
                  BeanUtil.convert(clientBusinessObject, baseModel);
                  //baseModel.setData(VciBaseUtil.objectToMapString(clientBusinessObject));
                  dataCBOList.add(baseModel);
                  dataCBOIdList.add(baseModel.getOid());
               });
               try {
                  codeList = productCodeService.productCodeAndSaveData(classifyFullInfo,templateVO,ruleVO, orderDTO.getSecDTOList(),dataCBOList);
                  codeList = productCodeService.productCodeAndSaveData(classifyFullInfo, templateVO, ruleVO, orderDTO.getSecDTOList(), dataCBOList, user);
                  //如果是编码生成失败,则直接就失败了,其他的判断出来有错误的我们都统一返回到excel里面
                  engineService.batchSaveSelectChar(templateVO, dataCBOList);
               } catch (Exception e) {
@@ -1713,12 +1835,12 @@
               }
            }
         }
         if(!isCreateUUid){
            return uuid="";
         if (!isCreateUUid) {
            return uuid = "";
         }
         saveLogUtil.operateLog("批量申请编码",false, StringUtil.format("批量导入申请成功共{}条数据,生成的码值如下【{}】",codeList.size(),codeList));
      }catch (Exception e){
         saveLogUtil.operateLog("批量申请编码",true,e.toString());
         saveLogUtil.operateLog("批量申请编码", false, StringUtil.format("批量导入申请成功共{}条数据,生成的码值如下【{}】", codeList.size(), codeList));
      } catch (Exception e) {
         saveLogUtil.operateLog("批量申请编码", true, e.toString());
         throw e;
      }
      return uuid;
@@ -1726,11 +1848,11 @@
   @Override
   public List<CodeImportTemplateVO> gridclassifys(String redisOid) {
      List<CodeImportTemplateVO> codeImportTemplateVOs=new ArrayList<>();
      VciBaseUtil.alertNotNull(redisOid,"分类",redisOid,"分类缓存主键");
      List<CodeImportTemplateVO> redisServiceCacheObjects=bladeRedis.get(redisOid);
      if(redisServiceCacheObjects!=null){
         codeImportTemplateVOs=  redisServiceCacheObjects;
      List<CodeImportTemplateVO> codeImportTemplateVOs = new ArrayList<>();
      VciBaseUtil.alertNotNull(redisOid, "分类", redisOid, "分类缓存主键");
      List<CodeImportTemplateVO> redisServiceCacheObjects = bladeRedis.get(redisOid);
      if (redisServiceCacheObjects != null) {
         codeImportTemplateVOs = redisServiceCacheObjects;
      }
      return codeImportTemplateVOs;
   }
@@ -1743,24 +1865,24 @@
    */
   @Override
   public DataGrid<Map<String, String>> gridDatas(String codeClssifyOid, String redisOid) {
      VciBaseUtil.alertNotNull(redisOid,"导入相似数据",redisOid,"数据缓存主键");
      List<CodeImprotDataVO> codeImprotDataVOs = bladeRedis.get(redisOid+"-"+codeClssifyOid);
      VciBaseUtil.alertNotNull(redisOid, "导入相似数据", redisOid, "数据缓存主键");
      List<CodeImprotDataVO> codeImprotDataVOs = bladeRedis.get(redisOid + "-" + codeClssifyOid);
//      redisService.getCacheList(redisOid+"-"+codeClssifyOid);
      CodeImprotDataVO codeImprotDataVO=new CodeImprotDataVO();
      if(!CollectionUtils.isEmpty(codeImprotDataVOs)){
         if(StringUtils.isNotBlank(codeClssifyOid)){
            Map<String/**分类名称**/, CodeImprotDataVO/**英文名称**/> codeClassifyDatasMap = codeImprotDataVOs.stream().collect(Collectors.toMap(s -> s.getCodeClassifyOid(), t -> t,(o1, o2)->o2));
            if(codeClassifyDatasMap.containsKey(codeClssifyOid)){
               codeImprotDataVO= codeClassifyDatasMap.get(codeClssifyOid);
            }else{
               codeImprotDataVO=  codeImprotDataVOs.get(0);
      CodeImprotDataVO codeImprotDataVO = new CodeImprotDataVO();
      if (!CollectionUtils.isEmpty(codeImprotDataVOs)) {
         if (StringUtils.isNotBlank(codeClssifyOid)) {
            Map<String/**分类名称**/, CodeImprotDataVO/**英文名称**/> codeClassifyDatasMap = codeImprotDataVOs.stream().collect(Collectors.toMap(s -> s.getCodeClassifyOid(), t -> t, (o1, o2) -> o2));
            if (codeClassifyDatasMap.containsKey(codeClssifyOid)) {
               codeImprotDataVO = codeClassifyDatasMap.get(codeClssifyOid);
            } else {
               codeImprotDataVO = codeImprotDataVOs.get(0);
            }
         }
      }
      DataGrid<Map<String, String>> dataGrid = new DataGrid<>();
      List<Map<String, String>> dataList = new ArrayList<>();
      if(codeImprotDataVO!=null){
         dataList= codeImprotDataVO.getDatas();
      if (codeImprotDataVO != null) {
         dataList = codeImprotDataVO.getDatas();
      }
      dataGrid.setData(dataList);
      if (!CollectionUtils.isEmpty(dataList)) {
@@ -1770,23 +1892,23 @@
   }
   /**
    *
    * @param oid
    * @param redisOid
    * @return
    */
   @Override
   public DataGrid<Map<String,String>> gridRowResemble(String oid,String redisOid){
      VciBaseUtil.alertNotNull(redisOid,"导入相似数据",redisOid,"数据缓存主键");
      List<DataResembleVO> codeImprotDataVOs = bladeRedis.get(redisOid);;
   public DataGrid<Map<String, String>> gridRowResemble(String oid, String redisOid) {
      VciBaseUtil.alertNotNull(redisOid, "导入相似数据", redisOid, "数据缓存主键");
      List<DataResembleVO> codeImprotDataVOs = bladeRedis.get(redisOid);
      ;
      DataGrid<Map<String, String>> dataGrid = new DataGrid<>();
      List<Map<String, String>> dataList = new ArrayList<>();
      if(!CollectionUtils.isEmpty(codeImprotDataVOs)){
         Map<String/**分类名称**/, DataResembleVO/**数据对象**/> rowResembleDataMap = codeImprotDataVOs.stream().collect(Collectors.toMap(s -> s.getOid(), t -> t,(o1, o2)->o2));
         if(rowResembleDataMap.containsKey(oid)){
            DataResembleVO dataResembleVO=  rowResembleDataMap.get(oid);
            dataList= dataResembleVO.getDataList();
      if (!CollectionUtils.isEmpty(codeImprotDataVOs)) {
         Map<String/**分类名称**/, DataResembleVO/**数据对象**/> rowResembleDataMap = codeImprotDataVOs.stream().collect(Collectors.toMap(s -> s.getOid(), t -> t, (o1, o2) -> o2));
         if (rowResembleDataMap.containsKey(oid)) {
            DataResembleVO dataResembleVO = rowResembleDataMap.get(oid);
            dataList = dataResembleVO.getDataList();
         }
      }
@@ -1805,163 +1927,167 @@
    */
   @Override
   public String exportCode(CodeExportAttrDTO exportAttrDTO) {
      VciBaseUtil.alertNotNull(exportAttrDTO,"导出的配置",exportAttrDTO.getCodeClassifyOid(),"主题库分类的主键");
      VciBaseUtil.alertNotNull(exportAttrDTO, "导出的配置", exportAttrDTO.getCodeClassifyOid(), "主题库分类的主键");
      CodeClassifyFullInfoBO classifyFullInfo = classifyService.getClassifyFullInfo(exportAttrDTO.getCodeClassifyOid());
      //获取最新的模板
      CodeClassifyTemplateVO templateVO = engineService.getUsedTemplateByClassifyOid(exportAttrDTO.getCodeClassifyOid());
      //先查询数据
      String btmTypeId = classifyFullInfo.getTopClassifyVO().getBtmTypeId();
      Map<String, String> conditionMap = exportAttrDTO.getConditionMap();
      if(conditionMap == null){
      if (conditionMap == null) {
         conditionMap = new HashMap<>();
      }
      if(conditionMap.containsKey(VciQueryWrapperForDO.OID_FIELD)){
         conditionMap.put(VciQueryWrapperForDO.OID_FIELD,QueryOptionConstant.IN + "(" + VciBaseUtil.toInSql(conditionMap.get(VciQueryWrapperForDO.OID_FIELD)) + ")");
      if (conditionMap.containsKey(VciQueryWrapperForDO.OID_FIELD)) {
         conditionMap.put(VciQueryWrapperForDO.OID_FIELD, QueryOptionConstant.IN + "(" + VciBaseUtil.toInSql(conditionMap.get(VciQueryWrapperForDO.OID_FIELD)) + ")");
      }
      PageHelper pageHelper = new PageHelper(exportAttrDTO.getLimit()==null?-1:exportAttrDTO.getLimit());
      pageHelper.setPage(exportAttrDTO.getPage()==null?1:exportAttrDTO.getPage());
      PageHelper pageHelper = new PageHelper(exportAttrDTO.getLimit() == null ? -1 : exportAttrDTO.getLimit());
      pageHelper.setPage(exportAttrDTO.getPage() == null ? 1 : exportAttrDTO.getPage());
      pageHelper.setSort(exportAttrDTO.getSort());
      pageHelper.setOrder(exportAttrDTO.getOrder());
      pageHelper.addDefaultDesc("createTime");
      conditionMap.put("codeclsfpath","*" + exportAttrDTO.getCodeClassifyOid() + "*");
      conditionMap.put("codeclsfpath", "*" + exportAttrDTO.getCodeClassifyOid() + "*");
      conditionMap.put("lastr", "1");
      conditionMap.put("lastv", "1");
      R<List<BtmTypeVO>> listR = btmTypeClient.selectByIdCollection(Arrays.asList(btmTypeId));
      String tableName = "";
      if(listR.isSuccess() && !listR.getData().isEmpty()){
         tableName = Func.isNotBlank(listR.getData().get(0).getTableName()) ? listR.getData().get(0).getTableName():VciBaseUtil.getTableName(btmTypeId);
      }else{
      if (listR.isSuccess() && !listR.getData().isEmpty()) {
         tableName = Func.isNotBlank(listR.getData().get(0).getTableName()) ? listR.getData().get(0).getTableName() : VciBaseUtil.getTableName(btmTypeId);
      } else {
         tableName = VciBaseUtil.getTableName(btmTypeId);
      }
      String countSql = "select count(*) from (select * FROM " + tableName +" where 1=1" +
      String countSql = "select count(*) from " + tableName + " where 1=1" +
         " and lastr = '1'" +
         " and lastv='1'" +
         " and codeclsfpath like '%" + exportAttrDTO.getCodeClassifyOid() + "%' {}";
         " and codeclsfpath like '%" + exportAttrDTO.getCodeClassifyOid() + "%'";
      //先查询总数
      int total = 0;
      if(exportAttrDTO.getEndPage()!=null && exportAttrDTO.getEndPage()>0
         &&exportAttrDTO.getPage() !=null && exportAttrDTO.getPage() >0
         &&exportAttrDTO.getEndPage()>exportAttrDTO.getPage()){
      if (exportAttrDTO.getEndPage() != null && exportAttrDTO.getEndPage() > 0
         && exportAttrDTO.getPage() != null && exportAttrDTO.getPage() > 0
         && exportAttrDTO.getEndPage() > exportAttrDTO.getPage()) {
         //从多少页到多少页的查询方式,
         for(int i = exportAttrDTO.getPage() ;i <= exportAttrDTO.getEndPage();i++){
            PageHelper thisPage = new PageHelper(exportAttrDTO.getLimit()==null?-1:exportAttrDTO.getLimit());
            thisPage.setPage(exportAttrDTO.getPage()==null?1:exportAttrDTO.getPage());
         String countPageSql = "select count(*) from (select * FROM " + tableName + " where 1=1" +
            " and lastr = '1'" +
            " and lastv='1'" +
            " and codeclsfpath like '%" + exportAttrDTO.getCodeClassifyOid() + "%' {}";
         for (int i = exportAttrDTO.getPage(); i <= exportAttrDTO.getEndPage(); i++) {
            PageHelper thisPage = new PageHelper(exportAttrDTO.getLimit() == null ? -1 : exportAttrDTO.getLimit());
            thisPage.setPage(exportAttrDTO.getPage() == null ? 1 : exportAttrDTO.getPage());
            thisPage.setSort(exportAttrDTO.getSort());
            thisPage.setOrder(exportAttrDTO.getOrder());
            thisPage.addDefaultDesc("createTime");
            total += commonsMapper.queryCountBySql(StringUtil.format(countSql," limit " + exportAttrDTO.getLimit() +" offset "+ i +")subquery;"));
            total += commonsMapper.queryCountBySql(StringUtil.format(countPageSql, " limit " + exportAttrDTO.getLimit() + " offset " + i + ")subquery;"));
         }
      }else{
      } else {
         total = commonsMapper.queryCountBySql(countSql);
      }
      List<String> selectFieldList = new ArrayList<>();
      if(!CollectionUtils.isEmpty(exportAttrDTO.getAttrIdIndexMap())){
         selectFieldList = exportAttrDTO.getAttrIdIndexMap().values().stream().map(s->s.toLowerCase(Locale.ROOT)).collect(Collectors.toList());
      }else{
         selectFieldList = templateVO.getAttributes().stream().filter(s->VciBaseUtil.getBoolean(s.getFormDisplayFlag())
            ||VciBaseUtil.getBoolean(s.getTableDisplayFlag())).map(s->s.getId().toLowerCase(Locale.ROOT)).collect(Collectors.toList());
      if (!CollectionUtils.isEmpty(exportAttrDTO.getAttrIdIndexMap())) {
         selectFieldList = exportAttrDTO.getAttrIdIndexMap().values().stream().map(s -> s.toLowerCase(Locale.ROOT)).collect(Collectors.toList());
      } else {
         selectFieldList = templateVO.getAttributes().stream().filter(s -> VciBaseUtil.getBoolean(s.getFormDisplayFlag())
            || VciBaseUtil.getBoolean(s.getTableDisplayFlag())).map(s -> s.getId().toLowerCase(Locale.ROOT)).collect(Collectors.toList());
      }
      //参照让平台直接查询就行
      List<String> finalSelectFieldList = selectFieldList;
      List<CodeClassifyTemplateAttrVO> referAttrVOs = templateVO.getAttributes().stream().filter(
         s -> StringUtils.isNotBlank(s.getReferBtmId())
            &&
            (finalSelectFieldList.size() ==0 || finalSelectFieldList.contains(s.getId().toLowerCase(Locale.ROOT)))
            (finalSelectFieldList.size() == 0 || finalSelectFieldList.contains(s.getId().toLowerCase(Locale.ROOT)))
      ).collect(Collectors.toList());
      if(!CollectionUtils.isEmpty(referAttrVOs)){
      if (!CollectionUtils.isEmpty(referAttrVOs)) {
         for (int i = 0; i < referAttrVOs.size(); i++) {
            selectFieldList.add(referAttrVOs.get(i).getId() + ".name");
         }
      }
      List<String> excelNameList = new CopyOnWriteArrayList<>();
      String tempFolder = LocalFileUtil.getDefaultTempFolder();
      if(total>EXPORT_LIMIT){
      if (total > EXPORT_LIMIT) {
         //分组来执行
         int queryCount = (total-total%EXPORT_LIMIT)/EXPORT_LIMIT;
         if(total%EXPORT_LIMIT>0){
         int queryCount = (total - total % EXPORT_LIMIT) / EXPORT_LIMIT;
         if (total % EXPORT_LIMIT > 0) {
            queryCount = queryCount + 1;
         }
         List<Integer> indexList = new ArrayList<>();
         for (int i = 0; i <queryCount ; i++) {
         for (int i = 0; i < queryCount; i++) {
            indexList.add(i);
         }
         Map<String, String> finalConditionMap = conditionMap;
         //并行查询看看
         //SessionInfo sessionInfo = VciBaseUtil.getCurrentUserSessionInfo();
         indexList.stream().forEach(index->{
         indexList.stream().forEach(index -> {
            //线程的方式,所以需要设置当前用户
            //VciBaseUtil.setCurrentUserSessionInfo(sessionInfo);
            PageHelper thisPage = new PageHelper(EXPORT_LIMIT);
            thisPage.setPage(index+1);
            thisPage.setPage(index + 1);
            thisPage.setSort(exportAttrDTO.getSort());
            thisPage.setOrder(exportAttrDTO.getOrder());
            thisPage.addDefaultDesc("createTime");
            selectDataAndExportExcelName(btmTypeId, finalConditionMap,thisPage,finalSelectFieldList,
               classifyFullInfo,templateVO,exportAttrDTO,
               excelNameList,tempFolder,index);
            selectDataAndExportExcelName(btmTypeId, finalConditionMap, thisPage, finalSelectFieldList,
               classifyFullInfo, templateVO, exportAttrDTO,
               excelNameList, tempFolder, index);
         });
      }else{
      } else {
         pageHelper.setLimit(total);
         pageHelper.setPage(1);
         selectDataAndExportExcelName(btmTypeId,conditionMap,pageHelper,finalSelectFieldList,
            classifyFullInfo,templateVO,exportAttrDTO,
            excelNameList,tempFolder,1);
         selectDataAndExportExcelName(btmTypeId, conditionMap, pageHelper, finalSelectFieldList,
            classifyFullInfo, templateVO, exportAttrDTO,
            excelNameList, tempFolder, 1);
      }
      if(excelNameList.size() ==0){
      if (excelNameList.size() == 0) {
         throw new VciBaseException("没有数据可以被导出");
      }
      if(excelNameList.size() == 1){
      if (excelNameList.size() == 1) {
         return excelNameList.get(0);
      }
      //是多个,我们需要打成压缩包
      String zipFileName = LocalFileUtil.getDefaultTempFolder() + File.separator + classifyFullInfo.getCurrentClassifyVO().getId() + "_" + classifyFullInfo.getCurrentClassifyVO().getName() + "_导出_" + excelNameList.size()+".zip";
      String zipFileName = LocalFileUtil.getDefaultTempFolder() + File.separator + classifyFullInfo.getCurrentClassifyVO().getId() + "_" + classifyFullInfo.getCurrentClassifyVO().getName() + "_导出_" + excelNameList.size() + ".zip";
      VciZipUtil zipUtil = new VciZipUtil();
      File file = new File(tempFolder);
      zipUtil.addFileToZip(file,zipFileName);
      zipUtil.addFileToZip(file, zipFileName);
      File[] files = file.listFiles();
      for (int i = 0; i < files.length; i++) {
         LocalFileUtil.deleteTempFile(files[i],false);
         LocalFileUtil.deleteTempFile(files[i], false);
      }
      LocalFileUtil.deleteTempFile(file,true);
      LocalFileUtil.deleteTempFile(file, true);
      return zipFileName;
   }
   /**
    * 查询数据并导出到excel
    * @param btmTypeId 业务类型
    * @param conditionMap 查询条件
    * @param pageHelper 分页
    * @param selectFieldList 查询的字段
    *
    * @param btmTypeId        业务类型
    * @param conditionMap     查询条件
    * @param pageHelper       分页
    * @param selectFieldList  查询的字段
    * @param classifyFullInfo 分类的全部信息
    * @param templateVO 模板的信息
    * @param exportAttrDTO 导出的属性
    * @param excelNameList excel的文件名称
    * @param tempFolder 临时文件夹
    * @param excelIndex excel的顺序
    * @param templateVO       模板的信息
    * @param exportAttrDTO    导出的属性
    * @param excelNameList    excel的文件名称
    * @param tempFolder       临时文件夹
    * @param excelIndex       excel的顺序
    */
   private void selectDataAndExportExcelName(String btmTypeId, Map<String, String> conditionMap, PageHelper pageHelper, List<String> selectFieldList,
                                   CodeClassifyFullInfoBO classifyFullInfo, CodeClassifyTemplateVO templateVO, CodeExportAttrDTO exportAttrDTO,
                                   List<String> excelNameList, String tempFolder,
                                   Integer excelIndex) {
      DataGrid<Map<String, String>> dataGrid = engineService.queryGrid(btmTypeId, templateVO, conditionMap, pageHelper);
      if(dataGrid == null || CollectionUtils.isEmpty(dataGrid.getData())){
      if (dataGrid == null || CollectionUtils.isEmpty(dataGrid.getData())) {
         return;
      }
      //转换数据
      List<Map<String, String>> dataMap = dataGrid.getData();
      //封装查询出来的数据
      engineService.wrapperData(dataMap, templateVO, selectFieldList,false);
      engineService.wrapperData(dataMap, templateVO, selectFieldList, false);
      //modify by weidy@2022-09-27
      //因为在列表和表单的显示的时候,我们的开关类型页面会处理,但是在导出的时候,我们需要将true和false都替换成中文
      engineService.wrapperBoolean(dataMap,templateVO);
      Map<String, CodeClassifyTemplateAttrVO> attrVOMap = templateVO.getAttributes().stream().filter(s->selectFieldList.contains(s.getId().toLowerCase(Locale.ROOT))).collect(Collectors.toMap(s -> s.getId().toLowerCase(Locale.ROOT), t -> t));
      engineService.wrapperBoolean(dataMap, templateVO);
      Map<String, CodeClassifyTemplateAttrVO> attrVOMap = templateVO.getAttributes().stream().filter(s -> selectFieldList.contains(s.getId().toLowerCase(Locale.ROOT))).collect(Collectors.toMap(s -> s.getId().toLowerCase(Locale.ROOT), t -> t));
      Map<Integer, String> attrIdIndexMap = exportAttrDTO.getAttrIdIndexMap();
      if (CollectionUtils.isEmpty(attrIdIndexMap)) {
         attrIdIndexMap = templateVO.getAttributes().stream().filter(s->selectFieldList.contains(s.getId().toLowerCase(Locale.ROOT))).collect(Collectors.toMap(s -> s.getOrderNum(), t -> t.getId()));
         attrIdIndexMap = templateVO.getAttributes().stream().filter(s -> selectFieldList.contains(s.getId().toLowerCase(Locale.ROOT))).collect(Collectors.toMap(s -> s.getOrderNum(), t -> t.getId()));
      }
      List<Integer> indexList = attrIdIndexMap.keySet().stream().sorted().collect(Collectors.toList());
@@ -1980,9 +2106,9 @@
         if (attrVOMap.containsKey(attrId)) {
            CodeClassifyTemplateAttrVO attrVO = attrVOMap.get(attrId);
            Object text = attrVO.getName();
            text = exportKeyAndRequired(workbook,attrVO,text);
            text = exportKeyAndRequired(workbook, attrVO, text);
            WriteExcelData excelData = new WriteExcelData(0, i, text);
            if(text instanceof RichTextString){
            if (text instanceof RichTextString) {
               excelData.setFontColor(String.valueOf(HSSFColor.HSSFColorPredefined.RED.getIndex()));
            }
            excelDataList.add(excelData);
@@ -2003,7 +2129,7 @@
               if (StringUtils.isNotBlank(attrVO.getReferBtmId()) || StringUtils.isNotBlank(attrVO.getReferConfig())) {
                  attrId = attrId + "name";
               }
               if(VciQueryWrapperForDO.LC_STATUS_FIELD.equalsIgnoreCase(attrId)){
               if (VciQueryWrapperForDO.LC_STATUS_FIELD.equalsIgnoreCase(attrId)) {
                  attrId = VciQueryWrapperForDO.LC_STATUS_FIELD_TEXT.toLowerCase(Locale.ROOT);
               }
               excelDataList.add(new WriteExcelData(rowIndex[0], i, data.getOrDefault(attrId, "")));
@@ -2014,53 +2140,63 @@
      ExcelUtil.writeDataToFile(excelName, excelOption);
   }
   /**
    * 相似项查询出来之后再点击确认时调用的
    *
    * @param codeImprotSaveDatVOList
    * @param classifyAttr
    * @param isImprot
    * @return
    */
   @Override
   public R batchImportData(List<CodeImprotSaveDatVO> codeImprotSaveDatVOList, String classifyAttr, boolean isImprot) {
      WriteExcelOption eo = new WriteExcelOption();
      AtomicBoolean success= new AtomicBoolean(true);
      AtomicBoolean success = new AtomicBoolean(true);
      AtomicReference<CodeClassifyTemplateVO> codeClassifyTemplateVO = new AtomicReference<>();
      codeImprotSaveDatVOList.stream().forEach(codeImprotSaveDatVO -> {
         List<SheetRowData> rowDataList = new ArrayList<>();
         List<ClientBusinessObject>cboList=new ArrayList<>();
         List<String> colList=codeImprotSaveDatVO.getClos();
         CodeOrderDTO orderDTO= codeImprotSaveDatVO.getOrderDTO();
         List<Map<String, String>> dataList= codeImprotSaveDatVO.getDataList();
         List<ClientBusinessObject> cboList = new ArrayList<>();
         List<String> colList = codeImprotSaveDatVO.getClos();
         CodeOrderDTO orderDTO = codeImprotSaveDatVO.getOrderDTO();
         List<Map<String, String>> dataList = codeImprotSaveDatVO.getDataList();
         Map<Integer, String> fieldIndexMap = new HashMap();
         for (int i=0;i<dataList.size();i++){
            SheetRowData sheetRowData=new SheetRowData();
            Map<String,String> dataMap= dataList.get(i);
         for (int i = 0; i < dataList.size(); i++) {
            SheetRowData sheetRowData = new SheetRowData();
            Map<String, String> dataMap = dataList.get(i);
            Map<Integer, String> data = new HashMap();
            final int[] colIndex = {0};
            Map<Integer, String> finalFieldIndexMap = new HashMap<>();
            dataMap.forEach((field, value)->{
               if(!ROW_INDEX.equalsIgnoreCase(field) && !ERROR_MSG.equalsIgnoreCase(field)){
                  data.put(colIndex[0],value);
                  finalFieldIndexMap.put(colIndex[0]++,field);
            dataMap.forEach((field, value) -> {
               if (!ROW_INDEX.equalsIgnoreCase(field) && !ERROR_MSG.equalsIgnoreCase(field)) {
                  data.put(colIndex[0], value);
                  finalFieldIndexMap.put(colIndex[0]++, field);
               }
            });
            fieldIndexMap=finalFieldIndexMap;
            fieldIndexMap = finalFieldIndexMap;
            sheetRowData.setData(data);
            sheetRowData.setRowIndex(i+"");
            sheetRowData.setRowIndex(i + "");
            rowDataList.add(sheetRowData);
         }
         CodeClassifyFullInfoBO classifyFullInfo = classifyService.getClassifyFullInfo(orderDTO.getCodeClassifyOid());
         log.info("分类:"+classifyFullInfo.getCurrentClassifyVO().getName()+"数据:"+codeImprotSaveDatVO.getDataList().size());
         log.info("分类:" + classifyFullInfo.getCurrentClassifyVO().getName() + "数据:" + codeImprotSaveDatVO.getDataList().size());
         // CodeClassifyTemplateVO codeClassifyTemplateVO=   engineService.getUsedTemplateByClassifyOid(orderDTO.getCodeClassifyOid());
         CodeClassifyTemplateVO codeClassifyTemplateVO=  templateService.getObjectHasAttrByOid(orderDTO.getTemplateOid());
         codeClassifyTemplateVO.set(templateService.getObjectHasAttrByOid(orderDTO.getTemplateOid()));
         //规则的主键需要去获取
         CodeRuleVO ruleVO = engineService.getCodeRuleByClassifyFullInfo(classifyFullInfo);
         //除去默认的属性.还有只有表单显示的字段才导入
         List<CodeClassifyTemplateAttrVO> attrVOS = codeClassifyTemplateVO.getAttributes().stream().filter(s ->
            !DEFAULT_ATTR_LIST.contains(s.getId()) && VciBaseUtil.getBoolean(s.getFormDisplayFlag())
         List<CodeClassifyTemplateAttrVO> attrVOS = codeClassifyTemplateVO.get().getAttributes().stream().filter(s ->
            !DEFAULT_ATTR_LIST.contains(s.getId()) &&
               ((Func.isNotEmpty(s.getClassifyInvokeAttr()) || Func.isNotEmpty(s.getClassifyInvokeAttrName())) || VciBaseUtil.getBoolean(s.getFormDisplayFlag()))
         ).collect(Collectors.toList());
         String fullPath = getFullPath(classifyFullInfo);
         excelToCbo(classifyFullInfo,fieldIndexMap,rowDataList, codeClassifyTemplateVO,cboList,fullPath,!isImprot);
         Map<String,String> errorMap=new ConcurrentHashMap<>();
         Map<String/**路径**/, CodeClassifyVO> pathMap=new HashMap<>() ;
         excelToCbo(classifyFullInfo, fieldIndexMap, rowDataList, codeClassifyTemplateVO.get(), cboList, fullPath, !isImprot);
         Map<String, String> errorMap = new ConcurrentHashMap<>();
         Map<String/**路径**/, CodeClassifyVO> pathMap = new HashMap<>();
         //校验编码规则和码段是否正确
         Map<String, List<String>> ruleRowIndexMap = new ConcurrentHashMap<>();
         Map<String, CodeRuleVO> ruleVOMap =new ConcurrentHashMap<>();
         if(isImprot) {
         Map<String, CodeRuleVO> ruleVOMap = new ConcurrentHashMap<>();
         if (isImprot) {
            Map<String/**主键**/, String/**路径**/> childOidPathMap = getChildClassifyPathMap(classifyFullInfo, fullPath);
            //都转换完了。需要批量检查
            //找所有的分类路径,需要校验路径是否正确,是否都在当前的分类的下级
@@ -2083,44 +2219,45 @@
         }
         //分类注入
         batchSwitchClassifyAttrOnOrder(attrVOS,cboList,classifyFullInfo,isImprot);
         batchSwitchClassifyAttrOnOrder(attrVOS, cboList, classifyFullInfo, isImprot);
         //boolean
         reSwitchBooleanAttrOnOrder(attrVOS,cboList);
         reSwitchBooleanAttrOnOrder(attrVOS, cboList);
         //4.校验规则
         batchCheckVerifyOnOrder(attrVOS, cboList,errorMap);
         batchCheckVerifyOnOrder(attrVOS, cboList, errorMap);
         //5.校验枚举是否正确
         batchSwitchEnumAttrOnOrder(attrVOS, cboList, errorMap);
         //7.处理参照的情况
         batchSwitchReferAttrOnOrder(attrVOS,cboList,errorMap);
         batchSwitchReferAttrOnOrder(attrVOS, cboList, errorMap);
         //6.时间格式的验证
         //6.时间的,必须统一为yyyy-MM-dd HH:mm:ss
         batchSwitchDateAttrOnOrder(attrVOS,cboList,errorMap);
         batchSwitchDateAttrOnOrder(attrVOS, cboList, errorMap);
         //设置默认值
         batchSwitchAttrDefault(attrVOS, cboList);
         //最后弄组合规则
         batchSwitchComponentAttrOnOrder(attrVOS,cboList);
         batchSwitchComponentAttrOnOrder(attrVOS, cboList);
         //3.判断关键属性
         CodeImportResultVO keyResultVO = batchCheckKeyAttrOnOrder(classifyFullInfo, codeClassifyTemplateVO, cboList,errorMap);
         CodeImportResultVO keyResultVO = batchCheckKeyAttrOnOrder(classifyFullInfo, codeClassifyTemplateVO.get(), cboList, false, errorMap);
         Set<String> selfRepeatRowIndexList = keyResultVO.getSelfRepeatRowIndexList();
         Set<String> keyAttrRepeatRowIndexList = keyResultVO.getKeyAttrRepeatRowIndexList();
         if(!CollectionUtils.isEmpty(keyAttrRepeatRowIndexList)){
            keyAttrRepeatRowIndexList.stream().forEach(rowIndex->{
               errorMap.put(rowIndex,"关键属性与系统中的重复;" + errorMap.getOrDefault(rowIndex,""));
         if (!CollectionUtils.isEmpty(keyAttrRepeatRowIndexList)) {
            keyAttrRepeatRowIndexList.stream().forEach(rowIndex -> {
               errorMap.put(rowIndex, errorMap.getOrDefault(rowIndex, "") + String.format("关键属性与系统中的重复[%s],[%s];", keyResultVO.getKeyAttrRuleInfo(), keyResultVO.getSynonymRuleInfo()));
            });
         }
         //4.校验规则
         batchCheckVerifyOnOrder(attrVOS, cboList,errorMap);
         batchCheckVerifyOnOrder(attrVOS, cboList, errorMap);
         if(isImprot){
         if (isImprot) {
            List<ClientBusinessObject> needSaveCboList = cboList.stream().filter(cbo -> {
               String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX);
               return !errorMap.containsKey(rowIndex);
            }).collect(Collectors.toList());
            List<ClientBusinessObject> finalNeedSaveCboList = needSaveCboList;
            Map<String, CodeRuleVO> finalRuleVOMap = ruleVOMap;
            // TODO: 多线程流套多线程流,有坑,我把这儿改了
            // TODO: 多线程流套多线程流,有坑,我把这儿改成单线程了
            final BladeUser user = AuthUtil.getUser();
            ruleRowIndexMap.keySet().stream().forEach(ruleOid -> {
               List <BaseModel>dataCBOList=new CopyOnWriteArrayList<>();
               List<BaseModel> dataCBOList = new CopyOnWriteArrayList<>();
               List<String> rowIndexList = ruleRowIndexMap.get(ruleOid);
               List<ClientBusinessObject> thisCbos = needSaveCboList.stream().filter(cbo -> rowIndexList.contains(cbo.getAttributeValue(IMPORT_ROW_INDEX)) && !errorMap.containsKey(cbo.getAttributeValue(IMPORT_ROW_INDEX))).collect(Collectors.toList());
               if (!CollectionUtils.isEmpty(thisCbos)) {
@@ -2130,20 +2267,21 @@
                     dataCBOList.add(baseModel);
                  });
                  try {
                     productCodeService.productCodeAndSaveData(classifyFullInfo, codeClassifyTemplateVO, finalRuleVOMap.get(ruleOid), null, dataCBOList);
                     productCodeService.productCodeAndSaveData(classifyFullInfo, codeClassifyTemplateVO.get(), finalRuleVOMap.get(ruleOid), null, dataCBOList, user);
                  } catch (Throwable e) {
                     //success=false;
                     log.error("批量产生编码的时候出错了", e);
                     thisCbos.stream().forEach(cbo -> {
                        String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX);
                        errorMap.put(rowIndex, errorMap.getOrDefault(rowIndex, "") + ";系统错误,存储数据的时候出错了:"+e.getMessage());
                        errorMap.put(rowIndex, errorMap.getOrDefault(rowIndex, "") + ";系统错误,存储数据的时候出错了:" + e.getMessage());
                     });
                  }
               }
               engineService.batchSaveSelectChar(codeClassifyTemplateVO, dataCBOList);
               engineService.batchSaveSelectChar(codeClassifyTemplateVO.get(), dataCBOList);
            });
         }else {
            List<BaseModel> dataCBOList=new ArrayList<>();
         } else {
            final BladeUser user = AuthUtil.getUser();
            List<BaseModel> dataCBOList = new ArrayList<>();
            List<ClientBusinessObject> needSaveCboList = cboList.stream().filter(cbo -> {
               String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX);
               return !errorMap.containsKey(rowIndex);
@@ -2156,34 +2294,36 @@
                  dataCBOList.add(baseModel);
               });
               try {
                  productCodeService.productCodeAndSaveData(classifyFullInfo, codeClassifyTemplateVO, ruleVO, orderDTO.getSecDTOList(), dataCBOList);
                  productCodeService.productCodeAndSaveData(classifyFullInfo, codeClassifyTemplateVO.get(), ruleVO, orderDTO.getSecDTOList(), dataCBOList, user);
               } catch (Exception e) {
                  log.error("批量产生编码的时候出错了", e);
                  needSaveCboList.stream().forEach(cbo -> {
                     String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX);
                     errorMap.put(rowIndex, errorMap.getOrDefault(rowIndex, "") + ";系统错误,存储数据的时候出错了:"+e.getMessage());
                     errorMap.put(rowIndex, errorMap.getOrDefault(rowIndex, "") + ";系统错误,存储数据的时候出错了:" + e.getMessage());
                  });
               }
               //如果是编码生成失败,则直接就失败了,其他的判断出来有错误的我们都统一返回到excel里面
               engineService.batchSaveSelectChar(codeClassifyTemplateVO, dataCBOList);
               engineService.batchSaveSelectChar(codeClassifyTemplateVO.get(), dataCBOList);
            }
         }
         if(errorMap.size()>0) {
         if (errorMap.size() > 0) {
            success.set(false);
            LinkedList<WriteExcelData> excelDataList = new LinkedList<>();
            excelDataList.add(new WriteExcelData(0, 0, "错误信息"));
            final int[] index = {1};
            errorMap.forEach((key,v)->{
               excelDataList.add(new WriteExcelData(index[0]++, 0, "第"+(Integer.parseInt(key)+1)+"行数据:"+v));
            errorMap.forEach((key, v) -> {
               excelDataList.add(new WriteExcelData(index[0]++, 0, "第" + (Integer.parseInt(key) + 1) + "行数据:" + v));
            });
            eo.addSheetDataList(codeClassifyTemplateVO.getName() + "导入模板", excelDataList);
            eo.addSheetDataList(codeClassifyTemplateVO.get().getName() + "导入模板", excelDataList);
         }
      });
      if(!success.get()){
         String excelName = LocalFileUtil.getDefaultTempFolder() + File.separator + (isImprot?"批量历史错误信息.xls":"批量申请错误信息.xls");
         ExcelUtil.writeDataToFile(excelName,eo);
         return  R.fail(excelName);
      }else {
      if (!success.get()) {
         String excelName = LocalFileUtil.getDefaultTempFolder() + File.separator + (isImprot ? "批量历史错误信息.xls" : "批量申请错误信息.xls");
         ExcelUtil.writeDataToFile(excelName, eo);
         saveLogUtil.operateLog("历史数据导入", true, StringUtil.format("错误信息:{}", JSON.toJSONString(eo.getWriteDataMap())));
         return R.fail(excelName);
      } else {
         saveLogUtil.operateLog("历史数据导入", false, StringUtil.format("导入到分类{}中,导入成功总数为:{}", JSON.toJSONString(codeClassifyTemplateVO), Func.isEmpty(codeImprotSaveDatVOList.get(0).getDataList().size())));
         return R.success(isImprot ? "批量历史导入成功" : "批量申请成功");
      }
   }
@@ -2196,12 +2336,12 @@
    * @return
    */
   @Override
   public R deleteDatas(String redisOid,String codeClssifyOid,String dataOids) {
   public R deleteDatas(String redisOid, String codeClssifyOid, String dataOids) {
      VciBaseUtil.alertNotNull(redisOid, "数据删除", redisOid, "数据缓存主键");
      VciBaseUtil.alertNotNull(codeClssifyOid, "数据删除", codeClssifyOid, "编码规则缓存主键");
      VciBaseUtil.alertNotNull(dataOids, "数据删除", dataOids, "所需删除的数据主键");
      try {
         List<CodeImprotDataVO> codeImprotDataVOs = bladeRedis.lRange(redisOid + "-" + codeClssifyOid,0,-1);
         List<CodeImprotDataVO> codeImprotDataVOs = bladeRedis.lRange(redisOid + "-" + codeClssifyOid, 0, -1);
         List<String> dataOidList = new ArrayList<>();
         codeImprotDataVOs.stream().forEach(codeImprotDataVO -> {
            List<Map<String, String>> newDataList = new ArrayList<>();
@@ -2221,22 +2361,23 @@
         bladeRedis.set(redisOid + "-" + codeClssifyOid, codeImprotDataVOs);
         bladeRedis.expire(redisOid + "-" + codeClssifyOid, BATCHADD_REDIS_TIME);
         return R.success("删除缓存数据成功");
      }catch (Throwable e){
      } catch (Throwable e) {
         return R.fail("删除缓存数据失败!");
      }
   }
   /**
    * 集成批量申请数据
    * @param orderDTO 分类的主键
    * @param dataObjectVO 数据信息
    *
    * @param orderDTO                  分类的主键
    * @param dataObjectVO              数据信息
    * @param resultDataObjectDetailDOs 错误信息
    * @return 有错误信息的excel
    */
   @Override
   public void batchSyncApplyCode(CodeOrderDTO orderDTO, DataObjectVO dataObjectVO, LinkedList<XMLResultDataObjectDetailDO> resultDataObjectDetailDOs,boolean isCodeOrGroupCode) {
      Map<String,String> errorMap=new ConcurrentHashMap<>();
      VciBaseUtil.alertNotNull(orderDTO,"编码申请相关的数据",orderDTO.getCodeClassifyOid(),"主题库分类主键");
   public void batchSyncApplyCode(CodeOrderDTO orderDTO, DataObjectVO dataObjectVO, LinkedList<XMLResultDataObjectDetailDO> resultDataObjectDetailDOs, boolean isCodeOrGroupCode) {
      Map<String, String> errorMap = new ConcurrentHashMap<>();
      VciBaseUtil.alertNotNull(orderDTO, "编码申请相关的数据", orderDTO.getCodeClassifyOid(), "主题库分类主键");
      CodeClassifyFullInfoBO classifyFullInfo = classifyService.getClassifyFullInfo(orderDTO.getCodeClassifyOid());
      //规则的主键需要去获取
      CodeRuleVO ruleVO = engineService.getCodeRuleByClassifyFullInfo(classifyFullInfo);
@@ -2245,75 +2386,78 @@
      //查询分类和模板
      //先找到每一行的标题,然后根据标题来获取对应的属性
      List<RowDatas> rowDataList = dataObjectVO.getRowData();
      Map<String , RowDatas>rowDataMap=new LinkedHashMap<>();
      rowDataList.stream().forEach(rowData->{
         rowDataMap.put(rowData.getRowIndex(),rowData);
      Map<String, RowDatas> rowDataMap = new LinkedHashMap<>();
      rowDataList.stream().forEach(rowData -> {
         rowDataMap.put(rowData.getRowIndex(), rowData);
      });
      //找第一行,为了找标题
      CodeClassifyTemplateVO templateVO = engineService.getUsedTemplateByClassifyOid(orderDTO.getCodeClassifyOid());
      //校验模板是不是最新的
      //checkTemplateSync(sheetDataSetList,templateVO);
      //除去默认的属性.还有只有表单显示的字段才导入
      List<CodeClassifyTemplateAttrVO> attrVOS = templateVO.getAttributes().stream().filter(s ->!DEFAULT_SYNC_ATTR_LIST.contains(s.getId()) && VciBaseUtil.getBoolean(s.getFormDisplayFlag())
      //除去默认的属性.还有只有具有分类注入的才过滤出来
      List<CodeClassifyTemplateAttrVO> attrVOS = templateVO.getAttributes().stream().filter(
         s -> !DEFAULT_SYNC_ATTR_LIST.contains(s.getId()) &&
            ((Func.isNotEmpty(s.getClassifyInvokeAttr()) || Func.isNotEmpty(s.getClassifyInvokeAttrName())) || VciBaseUtil.getBoolean(s.getFormDisplayFlag()))
      ).collect(Collectors.toList());
      Map<Integer/**列号**/,String/**字段的名称**/> fieldIndexMap = new HashMap<>();
      Map<Integer/**列号**/, String/**字段的名称**/> fieldIndexMap = new HashMap<>();
      List<String> titleRowData = dataObjectVO.getColName();
      Map<String/**中文名称**/, String/**英文名称**/> attrNameIdMap = attrVOS.stream().collect(Collectors.toMap(s -> s.getName(), t -> t.getId().toLowerCase(Locale.ROOT),(o1, o2)->o2));
      getFieldIndexMap(titleRowData,attrNameIdMap,fieldIndexMap);
      Map<String/**中文名称**/, String/**英文名称**/> attrNameIdMap = attrVOS.stream().collect(Collectors.toMap(s -> s.getName(), t -> t.getId().toLowerCase(Locale.ROOT), (o1, o2) -> o2));
      getFieldIndexMap(titleRowData, attrNameIdMap, fieldIndexMap);
      //需要判断是否所有的属性都在模板上了
      List<CodeClassifyTemplateAttrVO> unExistAttrVOs = attrVOS.stream().filter(s -> !fieldIndexMap.containsValue(s.getId().toLowerCase(Locale.ROOT))
         && com.alibaba.cloud.commons.lang.StringUtils.isBlank(s.getComponentRule()) && com.alibaba.cloud.commons.lang.StringUtils.isBlank(s.getClassifyInvokeAttr())//组合规则和分类注入确实没给用户导出去
      ).collect(Collectors.toList());
      if(!CollectionUtils.isEmpty(unExistAttrVOs)){
         String message=unExistAttrVOs.stream().map(CodeClassifyTemplateAttrVO::getName).collect(Collectors.joining(SERIAL_UNIT_SPACE));
      if (!CollectionUtils.isEmpty(unExistAttrVOs)) {
         String message = unExistAttrVOs.stream().map(CodeClassifyTemplateAttrVO::getName).collect(Collectors.joining(SERIAL_UNIT_SPACE));
         throw new VciBaseException("【" + message + "】这些属性在excel中没有找到");
      }
      List<ClientBusinessObject> cboList = new ArrayList<>();
      String fullPath = getFullPath(classifyFullInfo);
      // List<CodeClassifyProcessTempVO> codeClassifyProcessTempVOS=codeClassifyProcessTempService.listProcessTemplate(templateVO.getOid(),"code_cls_flow_use_order");
      boolean isProcess=false;
      boolean isProcess = false;
      //注释掉此处下面所有都按照不判断流程存储状态了
      /** if(!CollectionUtils.isEmpty(codeClassifyProcessTempVOS)){
       isProcess=true;
       }***/
      Map<String,String> codeOidToSystemOidMap=new HashMap<>();//存储编码数据和集成系统数据oid对照映射
      excelToCbo(classifyFullInfo,titleRowData,fieldIndexMap,rowDataList,templateVO,cboList,fullPath,isProcess,"create",errorMap,codeOidToSystemOidMap);
      Map<String, String> codeOidToSystemOidMap = new HashMap<>();//存储编码数据和集成系统数据oid对照映射
      excelToCbo(classifyFullInfo, titleRowData, fieldIndexMap, rowDataList, templateVO, cboList, fullPath, isProcess, "create", errorMap, codeOidToSystemOidMap);
      //都转换完了。需要批量检查
      //如果出错了,我们依然执行有效的数据,无效的数据写回到excel中
      Map<String,String> errorKeyMap=new HashMap<>();
      Map<String, String> errorKeyMap = new ConcurrentHashMap<>();
      //1.分类注入
      batchSwitchClassifyAttrOnOrder(attrVOS,cboList,classifyFullInfo,false);
      batchSwitchClassifyAttrOnOrder(attrVOS, cboList, classifyFullInfo, false);
      //boolean
      reSwitchBooleanAttrOnOrder(attrVOS,cboList);
      reSwitchBooleanAttrOnOrder(attrVOS, cboList);
      // cboList.stream().forEach(cbo->{
      //2.校验规则
      batchCheckVerifyOnOrder(attrVOS, cboList,errorMap);
      batchCheckVerifyOnOrder(attrVOS, cboList, errorMap);
      //3.校验枚举是否正确
      batchSwitchEnumAttrOnOrder(attrVOS,cboList,errorMap);
      batchSwitchEnumAttrOnOrder(attrVOS, cboList, errorMap);
      //4.时间格式的验证
      //4.时间的,必须统一为yyyy-MM-dd HH:mm:ss
      batchSwitchDateAttrOnOrder(attrVOS,cboList,errorMap);
      batchSwitchDateAttrOnOrder(attrVOS, cboList, errorMap);
      //5.处理参照的情况
      batchSwitchReferAttrOnOrder(attrVOS,cboList,errorMap);
      batchSwitchReferAttrOnOrder(attrVOS, cboList, errorMap);
      //6设置默认值
      batchSwitchAttrDefault(attrVOS, cboList);
      //2.判断必输项。。需要全部的属性,如果是必输,但是表单里面不显示的,只能是分类注入或者组合规则
      batchCheckRequiredAttrOnOrder(templateVO,cboList,errorMap);
      batchCheckRequiredAttrOnOrder(templateVO, cboList, errorMap);
      //最后弄组合规则
      batchSwitchComponentAttrOnOrder(attrVOS,cboList);
      batchSwitchComponentAttrOnOrder(attrVOS, cboList);
      //3.判断关键属性
      CodeImportResultVO keyResultVO = batchCheckKeyAttrOnOrder(classifyFullInfo, templateVO, cboList,errorKeyMap);
      CodeImportResultVO keyResultVO = batchCheckKeyAttrOnOrder(classifyFullInfo, templateVO, cboList, false, errorKeyMap);
      log.info("================查重后的errorKeyMap错误信息================="+JSON.toJSONString(errorKeyMap));
      Set<String> selfRepeatRowIndexList = keyResultVO.getSelfRepeatRowIndexList();
      Set<String> keyAttrRepeatRowIndexList = keyResultVO.getKeyAttrRepeatRowIndexList();
      Map<String,List<String>>keyAttrOkOidTORepeatOidMap= keyResultVO.getKeyAttrOkOidTORepeatOidMap();
      if(!CollectionUtils.isEmpty(selfRepeatRowIndexList)){
         selfRepeatRowIndexList.stream().forEach(rowIndex->{
      Map<String, List<String>> keyAttrOkOidTORepeatOidMap = keyResultVO.getKeyAttrOkOidTORepeatOidMap();
      if (!CollectionUtils.isEmpty(selfRepeatRowIndexList)) {
         selfRepeatRowIndexList.stream().forEach(rowIndex -> {
               /* //传入数据之间关键属性的校验
                RowDatas rowData= rowDataMap.get(rowIndex);
                XMLResultDataObjectDetailDO resultDataObjectDetailDO=new XMLResultDataObjectDetailDO();
@@ -2323,14 +2467,14 @@
                resultDataObjectDetailDO.setMsg(errorMap.getOrDefault(rowIndex,"") + ";关键属性重复");
                resultDataObjectDetailDOs.add(resultDataObjectDetailDO);
                */
            errorKeyMap.put(rowIndex,errorMap.getOrDefault(rowIndex,"") + ";传入的数据中关键属性重复");
            errorKeyMap.put(rowIndex, errorKeyMap.getOrDefault(rowIndex, "") + String.format(";传入的数据中关键属性重复[%s],[%s];", keyResultVO.getKeyAttrRuleInfo(), keyResultVO.getSynonymRuleInfo()));
         });
      }
      /****
       * 关键属性与系统中重复的判断
       */
      if(!CollectionUtils.isEmpty(keyAttrRepeatRowIndexList)){
         keyAttrRepeatRowIndexList.stream().forEach(rowIndex->{
      if (!CollectionUtils.isEmpty(keyAttrRepeatRowIndexList)) {
         keyAttrRepeatRowIndexList.stream().forEach(rowIndex -> {
            //传入数据之间关键属性的校验
               /* RowDatas rowData= rowDataMap.get(rowIndex);
                XMLResultDataObjectDetailDO resultDataObjectDetailDO=new XMLResultDataObjectDetailDO();
@@ -2340,32 +2484,32 @@
                resultDataObjectDetailDO.setMsg(errorMap.getOrDefault(rowIndex,"") + ";关键属性与系统中的重复" );
                resultDataObjectDetailDOs.add(resultDataObjectDetailDO);
                */
            Map<String, List<BaseModel>> indexTODataMap=keyResultVO.getIndexTODataMap();
            if(indexTODataMap.containsKey(rowIndex)){
               List<BaseModel> baseModelList= indexTODataMap.get(rowIndex);
            Map<String, List<BaseModel>> indexTODataMap = keyResultVO.getIndexTODataMap();
            if (indexTODataMap.containsKey(rowIndex)) {
               List<BaseModel> baseModelList = indexTODataMap.get(rowIndex);
            }
            errorKeyMap.put(rowIndex, "关键属性与系统中的重复;" + errorKeyMap.getOrDefault(rowIndex,""));
            errorKeyMap.put(rowIndex, errorKeyMap.getOrDefault(rowIndex, "") + String.format("关键属性与系统中的重复[%s],[%s];", keyResultVO.getKeyAttrRuleInfo(), keyResultVO.getSynonymRuleInfo()));
         });
      }
      //校验属性是否正确错误信息
      if(errorMap.size()>0){
      if (errorMap.size() > 0) {
         String[] newMsg = {""};
         cboList.stream().forEach(cbo -> {
            String rowIndex =cbo.getAttributeValue(IMPORT_ROW_INDEX);
            if(errorMap.containsKey(rowIndex)){
               String oid=cbo.getOid();
               String sourceOid=oid;
               if(codeOidToSystemOidMap.containsKey(oid)){
                  sourceOid=codeOidToSystemOidMap.get(oid);
            String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX);
            if (errorMap.containsKey(rowIndex)) {
               String oid = cbo.getOid();
               String sourceOid = oid;
               if (codeOidToSystemOidMap.containsKey(oid)) {
                  sourceOid = codeOidToSystemOidMap.get(oid);
               }
               String code="";
               String groupCode="";
               String errorid="103";
               String mes=errorMap.get(rowIndex);
               XMLResultDataObjectDetailDO resultDataObjectDetailDO=new XMLResultDataObjectDetailDO();
               if(isCodeOrGroupCode){
               String code = "";
               String groupCode = "";
               String errorid = "103";
               String mes = errorMap.get(rowIndex);
               XMLResultDataObjectDetailDO resultDataObjectDetailDO = new XMLResultDataObjectDetailDO();
               if (isCodeOrGroupCode) {
                  resultDataObjectDetailDO.setCode(groupCode);
               }else{
               } else {
                  resultDataObjectDetailDO.setCode(code);
               }
               resultDataObjectDetailDO.setId(sourceOid);
@@ -2377,14 +2521,14 @@
      }
      Map<String,String> newKeyMap=new HashedMap();
      if(errorKeyMap.size()>0 ) {
         errorKeyMap.keySet().forEach(key->{
            if(!errorMap.containsKey(key)){
               newKeyMap.put(key,errorKeyMap.get(key));
      Map<String, String> newKeyMap = new HashedMap();
      if (errorKeyMap.size() > 0) {
         errorKeyMap.keySet().forEach(key -> {
            if (!errorMap.containsKey(key)) {
               newKeyMap.put(key, errorKeyMap.get(key));
            }
         });
         if(newKeyMap.size()>0) {
         if (newKeyMap.size() > 0) {
            List<BaseModel> editBoList = new ArrayList<>();
            Map<String, List<BaseModel>> indexTodataMap = keyResultVO.getIndexTODataMap();
            cboList.stream().forEach(cbo -> {
@@ -2395,42 +2539,42 @@
                  String sourceOid = oid;
                  String code = "";
                  String errorid = "201";
                  if(codeOidToSystemOidMap.containsKey(oid)){
                     sourceOid=codeOidToSystemOidMap.get(oid);
                  if (codeOidToSystemOidMap.containsKey(oid)) {
                     sourceOid = codeOidToSystemOidMap.get(oid);
                  }
                  List<BaseModel> newCboList = indexTodataMap.get(rowIndex);
                  if (!CollectionUtils.isEmpty(newCboList)) {
                     //处理关键属性查出多条的话,根据集成调用的当前分类代号取当前分类的码值。
                     Map<String/**编码**/, BaseModel/**重复编码数据**/> classOidTOBaseModelMap = new HashMap<>();
                        newCboList.stream().forEach(baseModel->{
                           String codeclsfid=baseModel.getData().get(CODE_CLASSIFY_OID_FIELD.toUpperCase(Locale.ROOT));
                           classOidTOBaseModelMap.put(codeclsfid,baseModel);
                        });
                     String codeclsfid= classifyFullInfo.getCurrentClassifyVO().getOid();
                     if(classOidTOBaseModelMap.containsKey(codeclsfid)){
                        BaseModel newCbo= classOidTOBaseModelMap.get(codeclsfid);
                        String lcstatus =newCbo.getLcStatus();
                        String newOid =newCbo.getOid();
                        Date ts =newCbo.getTs();
                        code = StringUtils.isBlank(newCbo.getId())?"":newCbo.getId();
                        if(isCodeOrGroupCode) {
                           code=newCbo.getData().getOrDefault("GROUPCODE","");
                           if(StringUtils.isBlank(code)){
                              errorid="1";
                              msg=";申请的编码类型为集团码,等待集团编码赋值";
                     newCboList.stream().forEach(baseModel -> {
                        String codeclsfid = baseModel.getData().get(CODE_CLASSIFY_OID_FIELD.toLowerCase(Locale.ROOT));
                        classOidTOBaseModelMap.put(codeclsfid, baseModel);
                     });
                     String codeclsfid = classifyFullInfo.getCurrentClassifyVO().getOid();
                     if (classOidTOBaseModelMap.containsKey(codeclsfid)) {
                        BaseModel newCbo = classOidTOBaseModelMap.get(codeclsfid);
                        String lcstatus = newCbo.getLcStatus();
                        String newOid = newCbo.getOid();
                        Date ts = newCbo.getTs();
                        code = StringUtils.isBlank(newCbo.getId()) ? "" : newCbo.getId();
                        if (isCodeOrGroupCode) {
                           code = newCbo.getData().getOrDefault("GROUPCODE", "");
                           if (StringUtils.isBlank(code)) {
                              errorid = "1";
                              msg = ";申请的编码类型为集团码,等待集团编码赋值";
                           }
                        }
                        String lastmodifier=newCbo.getLastModifier();
                        if (lcstatus!=null&&!lcstatus.equals(CodeDefaultLC.RELEASED.getValue())) {
                        String lastmodifier = newCbo.getLastModifier();
                        if (lcstatus != null && !lcstatus.equals(CodeDefaultLC.RELEASED.getValue())) {
                           newCbo.setOid(newOid);
                           newCbo.setLastModifier(lastmodifier);
                           newCbo.setTs(ts);
                           cbo.setLastModifier(cbo.getLastModifier());
                           editBoList.add(newCbo);
                        }
                     }else{
                        errorid="205";
                        msg+=";编码则属于其他分类。";
                     } else {
                        errorid = "205";
                        msg += ";编码则属于其他分类。";
                     }
                     XMLResultDataObjectDetailDO resultDataObjectDetailDO = new XMLResultDataObjectDetailDO();
                     resultDataObjectDetailDO.setCode(code);
@@ -2442,9 +2586,9 @@
                  }
               }
            });
            //关键熟悉更改
            //关键属性更改
            if (!CollectionUtils.isEmpty(editBoList)) {
               engineService.updateBatchByBaseModel(classifyFullInfo.getTopClassifyVO().getBtmTypeId(),editBoList);//保存数据
               engineService.updateBatchByBaseModel(classifyFullInfo.getTopClassifyVO().getBtmTypeId(), editBoList);//保存数据
            }
            errorMap.putAll(errorKeyMap);
         }
@@ -2454,49 +2598,50 @@
      //要把以上的错误的都抛出后,再继续处理时间和组合规则
      List<ClientBusinessObject> needSaveCboList = cboList.stream().filter(cbo -> {
         String rowIndex =cbo.getAttributeValue(IMPORT_ROW_INDEX);
         String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX);
         return !errorMap.containsKey(rowIndex);
      }).collect(Collectors.toList());
      List<String> needRowIndexList = new ArrayList<>();
      if(!CollectionUtils.isEmpty(needSaveCboList)) {
      if (!CollectionUtils.isEmpty(needSaveCboList)) {
         //9.我们处理业务数据
         //生成编码的内容
         List<String>allNeedSaveCboList=new ArrayList<>();
         List<BaseModel> dataCBOList=new ArrayList<>();
         List<String> allNeedSaveCboList = new ArrayList<>();
         List<BaseModel> dataCBOList = new ArrayList<>();
         final BladeUser user = AuthUtil.getUser();
         needSaveCboList.stream().forEach(clientBusinessObject -> {
            BaseModel baseModel=new BaseModel();
            BeanUtil.convert(clientBusinessObject,baseModel);
            BaseModel baseModel = new BaseModel();
            BeanUtil.convert(clientBusinessObject, baseModel);
            //(VciBaseUtil.objectToMapString(clientBusinessObject));
            dataCBOList.add(baseModel);
            allNeedSaveCboList.add(baseModel.getOid());
         });
         try {
            List<String>applyGroupCodeIdList=new ArrayList<>();
            productCodeService.productCodeAndSaveData(classifyFullInfo, templateVO, ruleVO, orderDTO.getSecDTOList(), dataCBOList);
            List<String> applyGroupCodeIdList = new ArrayList<>();
            productCodeService.productCodeAndSaveData(classifyFullInfo, templateVO, ruleVO, orderDTO.getSecDTOList(), dataCBOList, user);
            //如果是编码生成失败,则直接就失败了,其他的判断出来有错误的我们都统一返回到excel里面
            engineService.batchSaveSelectChar(templateVO, dataCBOList);
            // if(!isProcess){
            dataCBOList.stream().forEach(needSaveCbo->{
            dataCBOList.stream().forEach(needSaveCbo -> {
               XMLResultDataObjectDetailDO resultDataObjectDetailDO=new XMLResultDataObjectDetailDO();
               String code=StringUtils.isBlank(needSaveCbo.getId())?" ":needSaveCbo.getId();
               String groupCode=needSaveCbo.getData().getOrDefault("GROUPCODE"," ");
               XMLResultDataObjectDetailDO resultDataObjectDetailDO = new XMLResultDataObjectDetailDO();
               String code = StringUtils.isBlank(needSaveCbo.getId()) ? " " : needSaveCbo.getId();
               String groupCode = needSaveCbo.getData().getOrDefault("GROUPCODE", " ");
               //resultDataObjectDetailDO.setCode(needSaveCbo.getId());
               String msg="申请编码成功";
               String oid=needSaveCbo.getOid();
               String sourceOid=oid;
               String msg = "申请编码成功";
               String oid = needSaveCbo.getOid();
               String sourceOid = oid;
               applyGroupCodeIdList.add(oid);
               if(codeOidToSystemOidMap.containsKey(oid)){
                  sourceOid=codeOidToSystemOidMap.get(oid);
               if (codeOidToSystemOidMap.containsKey(oid)) {
                  sourceOid = codeOidToSystemOidMap.get(oid);
               }
               if(isCodeOrGroupCode) {
                  if(StringUtils.isBlank(groupCode)){
               if (isCodeOrGroupCode) {
                  if (StringUtils.isBlank(groupCode)) {
                     resultDataObjectDetailDO.setErrorid("1");
                     msg="申请的编码类型为集团码,等待集团编码赋值";
                     msg = "申请的编码类型为集团码,等待集团编码赋值";
                  }
                  resultDataObjectDetailDO.setCode(groupCode);
               }else{
               } else {
                  resultDataObjectDetailDO.setCode(code);
                  resultDataObjectDetailDO.setErrorid("0");
               }
@@ -2504,7 +2649,7 @@
               resultDataObjectDetailDO.setMsg(msg);
               resultDataObjectDetailDOs.add(resultDataObjectDetailDO);
               //处理传送的数据中关键属性重复的,直接拿到已经申请到编码的数据编码直接将赋给关键属性重复的数据
               LinkedList<XMLResultDataObjectDetailDO> repeatDataObjectDetailDOS=handleApplyDataKeyAttrRepeat(keyAttrOkOidTORepeatOidMap,codeOidToSystemOidMap,needSaveCbo,isCodeOrGroupCode);
               LinkedList<XMLResultDataObjectDetailDO> repeatDataObjectDetailDOS = handleApplyDataKeyAttrRepeat(keyAttrOkOidTORepeatOidMap, codeOidToSystemOidMap, needSaveCbo, isCodeOrGroupCode);
               resultDataObjectDetailDOs.addAll(repeatDataObjectDetailDOS);
            });
               /* }else{
@@ -2524,31 +2669,30 @@
                }*/
            //是否调用集团接口申请接口
            if(isCodeOrGroupCode){
               if(!CollectionUtils.isEmpty(applyGroupCodeIdList)) {
            if (isCodeOrGroupCode) {
               if (!CollectionUtils.isEmpty(applyGroupCodeIdList)) {
                  this.sendApplyGroupcode(applyGroupCodeIdList, classifyFullInfo.getTopClassifyVO().getId(), sysIntegrationPushTypeEnum.ACCPET_APPCODE.getValue());
               }
            }
         }catch (Throwable e){
         } catch (Throwable e) {
            e.printStackTrace();
            needSaveCboList.stream().forEach(needSaveCbo->{
               XMLResultDataObjectDetailDO resultDataObjectDetailDO=new XMLResultDataObjectDetailDO();
            needSaveCboList.stream().forEach(needSaveCbo -> {
               XMLResultDataObjectDetailDO resultDataObjectDetailDO = new XMLResultDataObjectDetailDO();
               resultDataObjectDetailDO.setCode("");
               String oid=needSaveCbo.getOid();
               String sourceOid=oid;
               if(codeOidToSystemOidMap.containsKey(oid)){
                  sourceOid=codeOidToSystemOidMap.get(oid);
               String oid = needSaveCbo.getOid();
               String sourceOid = oid;
               if (codeOidToSystemOidMap.containsKey(oid)) {
                  sourceOid = codeOidToSystemOidMap.get(oid);
               }
               resultDataObjectDetailDO.setId(sourceOid);
               resultDataObjectDetailDO.setErrorid("1");
               resultDataObjectDetailDO.setMsg("保存出现问题:"+e.getMessage());
               resultDataObjectDetailDO.setMsg("保存出现问题:" + e.getMessage());
               resultDataObjectDetailDOs.add(resultDataObjectDetailDO);
            });
         }
      }
   }
   /***
@@ -2558,31 +2702,32 @@
    * @param needSaveCbo
    * @param isCodeOrGroupCode
    */
   private LinkedList<XMLResultDataObjectDetailDO> handleApplyDataKeyAttrRepeat(Map<String,List<String>>keyAttrOkOidTORepeatOidMap,Map<String,String> codeOidToSystemOidMap,BaseModel needSaveCbo,boolean isCodeOrGroupCode){
      LinkedList<XMLResultDataObjectDetailDO> resultDataObjectDetailDOs=new LinkedList<>();
      String oid=needSaveCbo.getOid();
      if(keyAttrOkOidTORepeatOidMap.containsKey(oid)){
         List<String> repeatOidList= keyAttrOkOidTORepeatOidMap.get(oid);
         if(!CollectionUtils.isEmpty(repeatOidList)){
            String sourceNewOid=needSaveCbo.getOid();
            String sourceOid=sourceNewOid;
            if(codeOidToSystemOidMap.containsKey(oid)){
               sourceOid=codeOidToSystemOidMap.get(oid);
   private LinkedList<XMLResultDataObjectDetailDO> handleApplyDataKeyAttrRepeat(Map<String, List<String>> keyAttrOkOidTORepeatOidMap, Map<String, String> codeOidToSystemOidMap, BaseModel needSaveCbo, boolean isCodeOrGroupCode) {
      LinkedList<XMLResultDataObjectDetailDO> resultDataObjectDetailDOs = new LinkedList<>();
      String oid = needSaveCbo.getOid();
      if (keyAttrOkOidTORepeatOidMap.containsKey(oid)) {
         List<String> repeatOidList = keyAttrOkOidTORepeatOidMap.get(oid);
         if (!CollectionUtils.isEmpty(repeatOidList)) {
            String sourceNewOid = needSaveCbo.getOid();
            String sourceOid = sourceNewOid;
            if (codeOidToSystemOidMap.containsKey(oid)) {
               sourceOid = codeOidToSystemOidMap.get(oid);
            }
            String code=StringUtils.isBlank(needSaveCbo.getId())?" ":needSaveCbo.getId();
            String groupCode=needSaveCbo.getData().getOrDefault("GROUPCODE"," ");
            String code = StringUtils.isBlank(needSaveCbo.getId()) ? " " : needSaveCbo.getId();
            String groupCode = needSaveCbo.getData().getOrDefault("GROUPCODE", " ");
            String finalSourceOid = sourceOid;
            repeatOidList.stream().forEach(repeatOid->{
               if(codeOidToSystemOidMap.containsKey(repeatOid)){
                  XMLResultDataObjectDetailDO repeatresultDataObjectDetailDO=new XMLResultDataObjectDetailDO();
                  String repeatSourceOid=codeOidToSystemOidMap.get(repeatOid);
                  String repeatMsg="此数据与申请的编码数据id为【"+ finalSourceOid +"】的关键属性一致,则取相同编码";
                  if(isCodeOrGroupCode) {
                     if(StringUtils.isBlank(groupCode)){
                        repeatMsg="申请的编码类型为集团码,等待集团编码赋值";
            repeatOidList.stream().forEach(repeatOid -> {
               if (codeOidToSystemOidMap.containsKey(repeatOid)) {
                  XMLResultDataObjectDetailDO repeatresultDataObjectDetailDO = new XMLResultDataObjectDetailDO();
                  String repeatSourceOid = codeOidToSystemOidMap.get(repeatOid);
                  //String repeatMsg = "此数据与申请的编码数据id为【" + finalSourceOid + "】的关键属性一致,则取相同编码";
                  String repeatMsg = "此数据与申请的编码数据id为【" + code + "】的关键属性一致,则取相同编码";
                  if (isCodeOrGroupCode) {
                     if (StringUtils.isBlank(groupCode)) {
                        repeatMsg = "申请的编码类型为集团码,等待集团编码赋值";
                     }
                     repeatresultDataObjectDetailDO.setCode(groupCode);
                  }else{
                  } else {
                     repeatresultDataObjectDetailDO.setCode(code);
                  }
                  repeatresultDataObjectDetailDO.setId(repeatSourceOid);
@@ -2593,7 +2738,7 @@
            });
         }
      }
      return  resultDataObjectDetailDOs;
      return resultDataObjectDetailDOs;
   }
   /***
@@ -2605,9 +2750,9 @@
    */
   @Transactional(rollbackFor = VciBaseException.class)
   @Override
   public void batchSyncEditDatas(CodeClassifyVO codeClassifyVO, DataObjectVO dataObjectVO, LinkedList<XMLResultDataObjectDetailDO> resultDataObjectDetailDOs,boolean isCodeOrGroupCode) {
      String errorid="";
      String msg="";
   public void batchSyncEditDatas(CodeClassifyVO codeClassifyVO, DataObjectVO dataObjectVO, LinkedList<XMLResultDataObjectDetailDO> resultDataObjectDetailDOs, boolean isCodeOrGroupCode) {
      String errorid = "";
      String msg = "";
      //查询分类和模板
      //先找到每一行的标题,然后根据标题来获取对应的属性
      List<RowDatas> rowDataList = dataObjectVO.getRowData();
@@ -2624,7 +2769,8 @@
      //校验模板是不是最新的
      //checkTemplateSync(sheetDataSetList,templateVO);
      //除去默认的属性.还有只有表单显示的字段才导入
      List<CodeClassifyTemplateAttrVO> attrVOS = templateVO.getAttributes().stream().filter(s -> !DEFAULT_SYNC_ATTR_LIST.contains(s.getId()) && VciBaseUtil.getBoolean(s.getFormDisplayFlag())
      List<CodeClassifyTemplateAttrVO> attrVOS = templateVO.getAttributes().stream().filter(s -> !DEFAULT_SYNC_ATTR_LIST.contains(s.getId()) &&
         ((Func.isNotEmpty(s.getClassifyInvokeAttr()) || Func.isNotEmpty(s.getClassifyInvokeAttrName())) || VciBaseUtil.getBoolean(s.getFormDisplayFlag()))
      ).collect(Collectors.toList());
      Map<Integer/**列号**/, String/**字段的名称**/> fieldIndexMap = new HashMap<>();
      List<String> titleRowData = dataObjectVO.getColName();
@@ -2632,10 +2778,10 @@
      getFieldIndexMap(titleRowData, attrNameIdMap, fieldIndexMap);
      //Map<String, String> cboOidMap = new HashMap<>();
      //cboOidMap.put("id", QueryOptionConstant.IN + "(" + VciBaseUtil.toInSql(codeDataMap.keySet().toArray(new String[0])) + ")");
      String tableName ="";
      String tableName = "";
      try {
         R<BtmTypeVO> r = btmTypeClient.getAllAttributeByBtmId(templateVO.getBtmTypeId());
         if(!r.isSuccess()) {
         R<BtmTypeVO> r = btmTypeClient.getAllAttributeByBtmId(classifyFullInfo.getTopClassifyVO().getBtmTypeId());
         if (!r.isSuccess()) {
            throw new Throwable(r.getMsg());
         }
         BtmTypeVO btmTypeVO = r.getData();
@@ -2646,43 +2792,44 @@
         if (StringUtils.isBlank(tableName)) {
            throw new Throwable("根据业务类型未查询到业务类型相关联的表");
         }
      }catch (Throwable e){
         log.error("查询业务对象表"+e);
         XMLResultDataObjectDetailDO xmlResultDataObjectDetailDO=new XMLResultDataObjectDetailDO();
      } catch (Throwable e) {
         log.error("查询业务对象表" + e);
         XMLResultDataObjectDetailDO xmlResultDataObjectDetailDO = new XMLResultDataObjectDetailDO();
         xmlResultDataObjectDetailDO.setErrorid("103");
         xmlResultDataObjectDetailDO.setMsg("查询业务对象表"+e);
         xmlResultDataObjectDetailDO.setMsg("查询业务对象表" + e);
         xmlResultDataObjectDetailDO.setId("");
         xmlResultDataObjectDetailDO.setCode("");
         resultDataObjectDetailDOs.add(xmlResultDataObjectDetailDO);
         return;
      }
      StringBuffer sb=new StringBuffer();
      StringBuffer sb = new StringBuffer();
      sb.append(" select * from ");
      sb.append(tableName);
      sb.append(" where 1=1 ");
      sb.append(" and lastr=1 and lastv=1" );
      if(isCodeOrGroupCode) {
      sb.append(" and lastr=1 and lastv=1");
      if (isCodeOrGroupCode) {
         sb.append(" and ( groupcode in (");
         sb.append(VciBaseUtil.toInSql(codeDataMap.keySet().toArray(new String[0])));
         sb.append(")");
         sb.append(" or id in (");
         sb.append(VciBaseUtil.toInSql(codeDataMap.keySet().toArray(new String[0])));
         sb.append("))");
      }else{
      } else {
         sb.append(" and id in (");
         sb.append(VciBaseUtil.toInSql(codeDataMap.keySet().toArray(new String[0])));
         sb.append(")");
      }
      List<Map<String,String>> dataMapList=commonsMapper.queryByOnlySqlForMap(sb.toString());
      List<ClientBusinessObject> cboList=   ChangeMapTOClientBusinessObjects(dataMapList);
      List<Map<String, String>> dataMapList = commonsMapper.queryByOnlySqlForMap(sb.toString());
      DefaultAttrAssimtUtil.mapToLowerCase(dataMapList, true);
      List<ClientBusinessObject> cboList = ChangeMapTOClientBusinessObjects(dataMapList);
      Map<String, ClientBusinessObject> codeSystemObjectMap = cboList.stream().filter(systeDataObject -> systeDataObject != null && StringUtils.isNotBlank(systeDataObject.getId())).collect(Collectors.toList()).stream().collect(Collectors.toMap(s -> s.getId(), t -> t));
      Map<String, String> errorMap = new HashMap<>();
      List<CodeOrderDTO> codeOrderDTOList = new ArrayList<>();
      this.getCodeOrderDTOs(codeClassifyVO, templateVO, codeDataMap, codeSystemObjectMap, codeOrderDTOList, errorMap,isCodeOrGroupCode);
      this.getCodeOrderDTOs(codeClassifyVO, templateVO, codeDataMap, codeSystemObjectMap, codeOrderDTOList, errorMap, isCodeOrGroupCode);
      // List<CodeClassifyProcessTempVO> codeClassifyProcessTempVOS=codeClassifyProcessTempService.listProcessTemplate(templateVO.getOid(),"code_cls_flow_use_order");
      boolean isProcess=false;
      boolean isProcess = false;
      /**  if(!CollectionUtils.isEmpty(codeClassifyProcessTempVOS)){
       isProcess=true;
       }**/
@@ -2692,25 +2839,25 @@
      List<CodeAllCode> codeAllCodeList = new ArrayList<>();
      List<String> deleteList = new ArrayList<>();
      CodeClassifyTemplateVO firstTemplateVO = templateService.getObjectHasAttrByOid(orderDTOMap.values().stream().findFirst().get().getTemplateOid());
      // CodeClassifyTemplateVO firstTemplateVO = templateService.getObjectHasAttrByOid(orderDTOMap.values().stream().findFirst().get().getTemplateOid());
      Map<String, ClientBusinessObject> cboMap = cboList.stream().filter(cbo -> cbo != null).collect(Collectors.toList()).stream().collect(Collectors.toMap(s -> s.getId(), t -> t));
      //  boolean finalIsProcess = isProcess;
      // boolean finalIsProcess = isProcess;
      orderDTOMap.keySet().stream().forEach(code -> {
         CodeOrderDTO orderDTO = orderDTOMap.get(code);
         ClientBusinessObject cbo = cboMap.get(code);
         String dataStatus=cbo.getLcStatus();
         RowDatas rowData=codeDataMap.get(code);
         String status=rowData.getStatus();
         String lastModifier= rowData.getEditor();
         String operation=rowData.getOperation();
         if (cbo.getTs().compareTo(orderDTO.getTs())==0?false:true) {
         String dataStatus = cbo.getLcStatus();
         RowDatas rowData = codeDataMap.get(code);
         String status = rowData.getStatus();
         String lastModifier = rowData.getEditor();
         String operation = rowData.getOperation();
         if (cbo.getTs().compareTo(orderDTO.getTs()) == 0 ? false : true) {
            // throw new VciBaseException("数据不是最新的,可能他人已经修改,请刷新后再试");
            errorMap.put(orderDTO.getId(),errorMap.getOrDefault(orderDTO.getId(),"")+";数据不是最新的,可能他人已经修改,请刷新后再试");
            errorMap.put(orderDTO.getId(), errorMap.getOrDefault(orderDTO.getId(), "") + ";数据不是最新的,可能他人已经修改,请刷新后再试");
         }
           /* if (!CodeDefaultLC.EDITING.getValue().equalsIgnoreCase(cbo.getLcStatus()) && !orderDTO.isEditInProcess()) {
                throw new VciBaseException("数据不是{0}的状态,不允许修改", new String[]{CodeDefaultLC.EDITING.getText()});
            }*/
         if(operation.equals("update")) {
         if (operation.equals("update")) {
            //1.先注入,再组合,最后校验
            switchClassifyLevelOnOrder(templateVO, classifyFullInfo, orderDTO, errorMap);
            //2.处理组合规则。组合规则不能使用编码的属性,因为编码的生成可能是需要属性的
@@ -2728,30 +2875,40 @@
            //默认的内容不能变,所以只需要拷贝自定义的相关属性即可
            copyValueToCBO(classifyFullInfo, cbo, orderDTO, templateVO, true, errorMap);
            //企业码和集团码的不修改
            cbo.setDescription(StringUtils.isBlank(orderDTO.getDescription())?"":orderDTO.getDescription());
            cbo.setDescription(StringUtils.isBlank(orderDTO.getDescription()) ? "" : orderDTO.getDescription());
            cbo.setName(orderDTO.getName());
            try {
               cbo.setAttributeValueWithNoCheck("description", orderDTO.getDescription());
            //   cbo.setAttributeValue("name", orderDTO.getName());
               //主要处理大小写问题,将data里面的数据的key都转为小写
               HashMap<String, String> lowerData = new HashMap<>();
               Iterator<Map.Entry<String, String>> iterator = cbo.getData().entrySet().iterator();
               while (iterator.hasNext()) {
                  Map.Entry<String, String> next = iterator.next();
                  lowerData.put(next.getKey().toLowerCase(Locale.ROOT), next.getValue());
               }
               cbo.getData().clear();
               cbo.getData().putAll(lowerData);
               cbo.setAttributeValueWithNoCheck("description", (StringUtil.isNotBlank(orderDTO.getData()
                  .get("description")) ? orderDTO.getData().get("description") : orderDTO.getDescription()));
               //   cbo.setAttributeValue("name", orderDTO.getName());
               //  if(finalIsProcess){//在流程中不允许更改
               //     errorMap.put(code,errorMap.getOrDefault(code, errorMap.getOrDefault(code,"")+";数据"+code+"在流程中,不允许更改!"));
               //  }else{
               Date date=new Date();
               Date date = new Date();
               cbo.setLcStatus(status);
               cbo.setAttributeValue("lcstatus",status);
               cbo.setAttributeValue("lcstatus", status);
               cbo.setLastModifyTime(date);
               cbo.setLastModifier(lastModifier);
               cbo.setLastModifyTime(date);
               cbo.setAttributeValue("lastmodifier",lastModifier);
               cbo.setAttributeValue("lastmodifytime",new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(date));
               cbo.setAttributeValue("lastmodifier", lastModifier);
               cbo.setAttributeValue("lastmodifytime", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(date));
               cbo.setTs(date);
               cbo.setAttributeValue("ts",new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(date));
               cbo.setAttributeValue("ts", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(date));
               //  }
            } catch (VciBaseException e) {
               e.printStackTrace();
            }
            List<CodeAllCode>newCodeAllCodeList= codeAllCodeService.selectByWrapper(Wrappers.<CodeAllCode>query().lambda().eq(CodeAllCode::getCreateCodeOid, cbo.getOid()));
            List<CodeAllCode> newCodeAllCodeList = codeAllCodeService.selectByWrapper(Wrappers.<CodeAllCode>query().lambda().eq(CodeAllCode::getCreateCodeOid, cbo.getOid()));
            if (!CollectionUtils.isEmpty(newCodeAllCodeList)) {
               CodeAllCode codeCbo = newCodeAllCodeList.get(0);
               log.info("codeCbos code:" + codeCbo.getId());
@@ -2759,17 +2916,17 @@
               codeAllCodeList.add(codeCbo);
            }
            BaseModel baseModel=new BaseModel();
            BeanUtil.convert(cbo,baseModel);
            BaseModel baseModel = new BaseModel();
            BeanUtil.convert(cbo, baseModel);
            //baseModel.setData(VciBaseUtil.objectToMapString(cbo));
            updateList.add(baseModel);
         }else if(operation.equals("delete")){//如果在流程中不允许删除,不在流程中状态为发布或者停用的数据不允许删除,将其更改为停用,其他的情况直接删除
         } else if (operation.equals("delete")) {//如果在流程中不允许删除,不在流程中状态为发布或者停用的数据不允许删除,将其更改为停用,其他的情况直接删除
            //  if(finalIsProcess){
            //    errorMap.put(code,errorMap.getOrDefault(code, errorMap.getOrDefault(code,"")+";数据"+code+"在流程中,不允许删除!"));
            //}else {
            try {
               log.info("oid:" + cbo.getOid());
               List<CodeAllCode>newCodeAllCodeList= codeAllCodeService.selectByWrapper(Wrappers.<CodeAllCode>query().lambda().eq(CodeAllCode::getCreateCodeOid, cbo.getOid()));
               List<CodeAllCode> newCodeAllCodeList = codeAllCodeService.selectByWrapper(Wrappers.<CodeAllCode>query().lambda().eq(CodeAllCode::getCreateCodeOid, cbo.getOid()));
               log.info("codeCbos size:" + newCodeAllCodeList.size());
               if (!CollectionUtils.isEmpty(newCodeAllCodeList)) {
                  CodeAllCode codeCbo = newCodeAllCodeList.get(0);
@@ -2778,11 +2935,11 @@
                  codeAllCodeList.add(codeCbo);
               }
               deleteList.add(cbo.getOid());
            }catch (VciBaseException e) {
            } catch (VciBaseException e) {
               e.printStackTrace();
            }
            // }
         }else if(operation.equals("editstatus")){
         } else if (operation.equals("editstatus")) {
            try {
               //  if (finalIsProcess) {
               //      errorMap.put(code, errorMap.getOrDefault(code, errorMap.getOrDefault(code, "") + ";数据" + code + "在流程中,不允许更改状态!"));
@@ -2792,19 +2949,19 @@
               //  }
               List<CodeAllCode>newCodeAllCodeList= codeAllCodeService.selectByWrapper(Wrappers.<CodeAllCode>query().lambda().eq(CodeAllCode::getCreateCodeOid, cbo.getOid()));
               List<CodeAllCode> newCodeAllCodeList = codeAllCodeService.selectByWrapper(Wrappers.<CodeAllCode>query().lambda().eq(CodeAllCode::getCreateCodeOid, cbo.getOid()));
               if (!CollectionUtils.isEmpty(newCodeAllCodeList)) {
                  CodeAllCode codeCbo = codeAllCodeList.get(0);
                  CodeAllCode codeCbo = newCodeAllCodeList.get(0);
                  log.info("codeCbos code:" + codeCbo.getId());
                  codeCbo.setLcStatus(status);
                  codeAllCodeList.add(codeCbo);
               }
               BaseModel baseModel=new BaseModel();
               BeanUtil.convert(cbo,baseModel);
               BaseModel baseModel = new BaseModel();
               BeanUtil.convert(cbo, baseModel);
               //baseModel.setData(VciBaseUtil.objectToMapString(cbo));
               updateList.add(baseModel);
            }catch (VciBaseException e) {
            } catch (VciBaseException e) {
               e.printStackTrace();
            }
         }
@@ -2812,13 +2969,13 @@
      /**
       * 错误信息输出
       */
      if(errorMap.size()>0){
         errorMap.keySet().forEach(code->{
            if(codeDataMap.containsKey(code)){
               RowDatas rowDatas=  codeDataMap.get(code);
               String dataMsg=errorMap.get(code);
               String oid=rowDatas.getOid();
               XMLResultDataObjectDetailDO xmlResultDataObjectDetailDO=new XMLResultDataObjectDetailDO();
      if (errorMap.size() > 0) {
         errorMap.keySet().forEach(code -> {
            if (codeDataMap.containsKey(code)) {
               RowDatas rowDatas = codeDataMap.get(code);
               String dataMsg = errorMap.get(code);
               String oid = rowDatas.getOid();
               XMLResultDataObjectDetailDO xmlResultDataObjectDetailDO = new XMLResultDataObjectDetailDO();
               xmlResultDataObjectDetailDO.setErrorid("103");
               xmlResultDataObjectDetailDO.setMsg(dataMsg);
               xmlResultDataObjectDetailDO.setId(oid);
@@ -2826,37 +2983,34 @@
               resultDataObjectDetailDOs.add(xmlResultDataObjectDetailDO);
            }
         });
      }else {
      } else {
         //存储数据
         try {
            engineService.updateBatchByBaseModel(classifyFullInfo.getTopClassifyVO().getBtmTypeId(),updateList);
            engineService.updateBatchByBaseModel(classifyFullInfo.getTopClassifyVO().getBtmTypeId(), updateList);
            codeAllCodeService.saveOrUpdateBatch(codeAllCodeList);
            if(deleteList.size()>0) {
               commonsMapper.deleteByTaleAndOid(tableName, VciBaseUtil.array2String(deleteList.toArray(new String[]{})));
            if (deleteList.size() > 0) {
               commonsMapper.deleteByTaleAndOid(tableName, VciBaseUtil.toInSql(deleteList.toArray(new String[]{})));
            }
            //是否调用集团接口申请接口
            if(isCodeOrGroupCode){
               List<String> IdList=resultDataObjectDetailDOs.stream().filter(xMLResultDataObjectDetailDO-> com.alibaba.cloud.commons.lang.StringUtils.isNotBlank(xMLResultDataObjectDetailDO.getId())).map(XMLResultDataObjectDetailDO::getId).distinct().collect(Collectors.toList());
               if(!CollectionUtils.isEmpty(IdList)) {
                  this.sendApplyGroupcode(IdList, classifyFullInfo.getTopClassifyVO().getBtmTypeId(),sysIntegrationPushTypeEnum.ACCPET_EDITCODE.getValue());
            if (isCodeOrGroupCode) {
               List<String> IdList = resultDataObjectDetailDOs.stream().filter(xMLResultDataObjectDetailDO -> com.alibaba.cloud.commons.lang.StringUtils.isNotBlank(xMLResultDataObjectDetailDO.getId())).map(XMLResultDataObjectDetailDO::getId).distinct().collect(Collectors.toList());
               if (!CollectionUtils.isEmpty(IdList)) {
                  this.sendApplyGroupcode(IdList, classifyFullInfo.getTopClassifyVO().getBtmTypeId(), sysIntegrationPushTypeEnum.ACCPET_EDITCODE.getValue());
               }
            }
            errorid="0";
            msg="更新/状态更改/删除成功!";
         }catch (Throwable e){
            errorid="1";
            msg="保存失败:"+e;
         }finally {
            errorid = "0";
            msg = "更新/状态更改/删除成功!";
         } catch (Throwable e) {
            errorid = "1";
            msg = "保存失败:" + e;
         } finally {
            String finalMsg = msg;
            String finalErrorid = errorid;
            cboList.stream().forEach(cbo->{
               String code =cbo.getId();
               if(codeDataMap.containsKey(code)) {
                  RowDatas rowDatas=codeDataMap.get(code);
                  String oid=rowDatas.getOid();
            cboList.stream().forEach(cbo -> {
               String code = cbo.getId();
               if (codeDataMap.containsKey(code)) {
                  RowDatas rowDatas = codeDataMap.get(code);
                  String oid = rowDatas.getOid();
                  XMLResultDataObjectDetailDO xmlResultDataObjectDetailDO = new XMLResultDataObjectDetailDO();
                  xmlResultDataObjectDetailDO.setErrorid(finalErrorid);
                  xmlResultDataObjectDetailDO.setMsg(finalMsg);
@@ -2876,7 +3030,7 @@
    * @param templateVO 模板的显示对象,需要包含模板属性
    * @param orderDTO   编码申请的信息
    */
   private void checkRequiredAttrOnOrder(CodeClassifyTemplateVO templateVO, CodeOrderDTO orderDTO,Map<String,String> errorMap) {
   private void checkRequiredAttrOnOrder(CodeClassifyTemplateVO templateVO, CodeOrderDTO orderDTO, Map<String, String> errorMap) {
      Map<String, CodeClassifyTemplateAttrVO> requiredAttrMap = templateVO.getAttributes().stream().filter(
            s -> VciBaseUtil.getBoolean(s.getRequireFlag()) && StringUtils.isBlank(s.getComponentRule())
               && StringUtils.isBlank(s.getClassifyInvokeAttr()))
@@ -2885,7 +3039,7 @@
         requiredAttrMap.forEach((attrId, attrVO) -> {
            //只有企业编码,状态,备注,模板主键,分类主键这几个是固定的,其余都是自行配置的
            if (StringUtils.isBlank(getValueFromOrderDTO(orderDTO, attrId))) {
               errorMap.put(orderDTO.getId(),errorMap.getOrDefault(orderDTO.getId(),"") + ";属性【{"+attrVO.getName()+"}】必须要输入(选择)内容" );
               errorMap.put(orderDTO.getId(), errorMap.getOrDefault(orderDTO.getId(), "") + ";属性【{" + attrVO.getName() + "}】必须要输入(选择)内容");
               //  throw new VciBaseException("属性【{0}】必须要输入(选择)内容", new String[]{attrVO.getName()});
            }
         });
@@ -2925,13 +3079,13 @@
    * @param templateVO 模板的信息,必须包含属性的内容
    * @param orderDTO   编码申请的相关的信息
    */
   private void checkVerifyOnOrder(CodeClassifyTemplateVO templateVO, CodeOrderDTO orderDTO,Map<String,String> errorMap) {
   private void checkVerifyOnOrder(CodeClassifyTemplateVO templateVO, CodeOrderDTO orderDTO, Map<String, String> errorMap) {
      Map<String, CodeClassifyTemplateAttrVO> verifyAttrVOMap = templateVO.getAttributes().stream().filter(s -> StringUtils.isNotBlank(s.getVerifyRule())).collect(Collectors.toMap(s -> s.getId().toLowerCase(Locale.ROOT), t -> t));
      if (!CollectionUtils.isEmpty(verifyAttrVOMap)) {
         verifyAttrVOMap.forEach((attrId, attrVO) -> {
            String value = getValueFromOrderDTO(orderDTO, attrId);
            if (StringUtils.isNotBlank(value) && !value.matches(attrVO.getVerifyRule())) {
               errorMap.put(orderDTO.getId(),errorMap.getOrDefault(orderDTO.getId(),"")+";属性["+attrVO.getName()+"]的值不符合校验规则的要求");
               errorMap.put(orderDTO.getId(), errorMap.getOrDefault(orderDTO.getId(), "") + ";属性[" + attrVO.getName() + "]的值不符合校验规则的要求");
               //校验正则表达式
               // throw new VciBaseException("属性[{0}]的值不符合校验规则的要求", new String[]{attrVO.getName()});
            }
@@ -2946,31 +3100,40 @@
    * @param templateVO       模板的内容,必须包含模板属性
    * @param orderDTO         编码申请的相关的信息
    */
   private void checkKeyAttrOnOrder(CodeClassifyFullInfoBO classifyFullInfo, CodeClassifyTemplateVO templateVO, CodeOrderDTO orderDTO,Map<String,String> errorMap) {
   private void checkKeyAttrOnOrder(CodeClassifyFullInfoBO classifyFullInfo, CodeClassifyTemplateVO templateVO, CodeOrderDTO orderDTO, Map<String, String> errorMap) {
      //先获取关键属性的规则,也利用继承的方式
      CodeKeyAttrRepeatVO keyRuleVO = keyRuleService.getRuleByClassifyFullInfo(classifyFullInfo);
      //注意的是keyRuleVO可能为空,表示不使用规则控制
      //获取所有的关键属性
      Map<String, CodeClassifyTemplateAttrVO> ketAttrMap = templateVO.getAttributes().stream().filter(s -> VciBaseUtil.getBoolean(s.getKeyAttrFlag())).collect(Collectors.toMap(s -> s.getId().toLowerCase(Locale.ROOT), t -> t));
      // TODO:2024-02-01 先获取配置了近义词查询规则的属性,不同于关键属性,设置了近义词查询规则的属性可能是多条不同的近义词查询规则
      Map<String, CodeClassifyTemplateAttrVO> sysonymAttrMaps = templateVO.getAttributes().stream().filter(item -> Func.isNotBlank(item.getSysonymRuleOids())).collect(Collectors.toMap(s -> s.getId().toLowerCase(Locale.ROOT), t -> t));
      // 获取是否有配置近义词查询规则属性
      Map<String, List<CodeSynonym>> codeSynonymMaps = new HashMap<>();
      if (!sysonymAttrMaps.isEmpty()) {
         // 查询近义词规则,存储方式key:属性id,value近义词查询规则列表
         codeSynonymMaps = codeSynonymService.getCodeSynonymByOids(sysonymAttrMaps);
      }
      Map<String, String> conditionMap = new HashMap<>();
      boolean trimAll = keyRuleVO == null ? false : VciBaseUtil.getBoolean(keyRuleVO.getIgnoreallspaceflag());
      //全部去空的优先级大于去空
      boolean trim = keyRuleVO == null ? false : VciBaseUtil.getBoolean(keyRuleVO.getIgnorespaceflag());
      boolean ignoreCase = keyRuleVO == null ? false : VciBaseUtil.getBoolean(keyRuleVO.getIgnorecaseflag());
      boolean ignoreWidth = keyRuleVO == null ? false : VciBaseUtil.getBoolean(keyRuleVO.getIgnorewidthflag());
      Map<String, List<CodeSynonym>> finalCodeSynonymMaps = codeSynonymMaps;
      ketAttrMap.forEach((attrId, attrVO) -> {
         String value = getValueFromOrderDTO(orderDTO, attrId);
         if (value == null) {
            value = "";
         }
         engineService.wrapperKeyAttrConditionMap(value, keyRuleVO, attrId, trim, ignoreCase, ignoreWidth, trimAll, conditionMap);
         engineService.wrapperKeyAttrConditionMap(value, keyRuleVO, finalCodeSynonymMaps.get(attrId), attrId, trim, ignoreCase, ignoreWidth, trimAll, conditionMap);
      });
      //没有限制分类,但是一个模板只可能在一个业务类型里面,所以直接查询这个业务类型即可
      if (!CollectionUtils.isEmpty(conditionMap)) {
         String tableName="";
         String tableName = "";
         R<BtmTypeVO> r = btmTypeClient.getAllAttributeByBtmId(templateVO.getBtmTypeId());
         if(r.isSuccess()) {
         if (r.isSuccess()) {
            BtmTypeVO btmTypeVO = r.getData();
            if (btmTypeVO != null) {
               tableName = btmTypeVO.getTableName();
@@ -2978,16 +3141,16 @@
            }
         }
         if (StringUtils.isBlank(tableName)) {
            String errormsg="根据业务类型未查询到相关业务表";
            errorMap.put(orderDTO.getId(),errorMap.getOrDefault(orderDTO.getId(),"")+errormsg);
            String errormsg = "根据业务类型未查询到相关业务表";
            errorMap.put(orderDTO.getId(), errorMap.getOrDefault(orderDTO.getId(), "") + errormsg);
            return;
         }
         //final String[] sql = {"select count(*) from " + tableName + " t where 1 = 1 "};
         final String[] sql = {"select t.id from " + tableName + " t where 1 = 1 "};
         conditionMap.forEach((key, value) -> {
            if(StringUtils.isBlank(value)||value.equals(QueryOptionConstant.ISNULL)){
            if (StringUtils.isBlank(value) || value.equals(QueryOptionConstant.ISNULL)) {
               sql[0] += " and " + key + " is null ";
            }else{
            } else {
               sql[0] += " and " + key + " = " + value;
            }
@@ -3000,17 +3163,17 @@
         }
         // 不需要参与校验的规则oid
         String isParticipateCheckOids = classifyService.selectLeafByParentClassifyOid(classifyFullInfo.getTopClassifyVO().getOid(), classifyFullInfo.getCurrentClassifyVO().getOid());
         if(Func.isNotBlank(isParticipateCheckOids)){
            sql[0] += " and codeclsfid not in("+isParticipateCheckOids+")";
         if (Func.isNotBlank(isParticipateCheckOids)) {
            sql[0] += " and codeclsfid not in(" + isParticipateCheckOids + ")";
         }
         sql[0] += " and t.lastR = '1' and t.lastV = '1' ";
         List<String> repeatData = commonsMapper.selectList(sql[0]);
         if (!repeatData.isEmpty()) {
            String ruleInfoMsg = keyRuleVO == null ? "" : "查询规则:去除空格--{0},忽略大小写--{1},忽略全半角--{2},忽略全部空格--{3}";
            String[] objs = new String[]{trim ? "是" : "否", ignoreCase ? "是" : "否", ignoreWidth ? "是" : "否", trimAll ? "是" : "否"};
            String defaultValue=";根据您填写的关键属性的内容,结合关键属性查询规则,发现这个数据已经在系统中存在了,数据的编号如下:"+repeatData.stream().collect(Collectors.joining(","))+"。请修正!。";
            String errormsg=defaultValue+ MessageFormat.format(ruleInfoMsg, objs);
            errorMap.put(orderDTO.getId(),errorMap.getOrDefault(orderDTO.getId(),"")+errormsg);
            String defaultValue = ";根据您填写的关键属性的内容,结合关键属性查询规则,发现这个数据已经在系统中存在了,数据的编号如下:" + repeatData.stream().collect(Collectors.joining(",")) + "。请修正!。";
            String errormsg = defaultValue + MessageFormat.format(ruleInfoMsg, objs);
            errorMap.put(orderDTO.getId(), errorMap.getOrDefault(orderDTO.getId(), "") + errormsg);
            // throw new VciBaseException("根据您填写的关键属性的内容,结合关键属性查询规则,发现这个数据已经在系统中存在了。请修正!。" + ruleInfoMsg, objs);
         }
      }
@@ -3022,7 +3185,7 @@
    * @param templateVO 模板的显示对象,需要包含属性
    * @param orderDTO   编码申请的信息
    */
   private void checkEnumOnOrder(CodeClassifyTemplateVO templateVO, CodeOrderDTO orderDTO,Map<String,String> errorMap) {
   private void checkEnumOnOrder(CodeClassifyTemplateVO templateVO, CodeOrderDTO orderDTO, Map<String, String> errorMap) {
      //如果枚举可以修改,则不需要校验是否符合枚举的选项
      Map<String, CodeClassifyTemplateAttrVO> enumAttrVOMap = templateVO.getAttributes().stream().filter(s -> (StringUtils.isNotBlank(s.getEnumString()) || StringUtils.isNotBlank(s.getEnumId())) && !VciBaseUtil.getBoolean(s.getEnumEditFlag())).collect(Collectors.toMap(s -> s.getId().toLowerCase(Locale.ROOT), t -> t));
      if (!CollectionUtils.isEmpty(enumAttrVOMap)) {
@@ -3032,7 +3195,7 @@
               //有值才能校验
               List<KeyValue> comboboxKVs = this.engineService.listComboboxItems(attrVO);
               if (!comboboxKVs.stream().anyMatch(s -> value.equalsIgnoreCase(s.getKey()))) {
                  errorMap.put(orderDTO.getId(),errorMap.getOrDefault(orderDTO.getId(),"")+";属性【"+attrVO.getName()+"】的值不符合枚举的要求");
                  errorMap.put(orderDTO.getId(), errorMap.getOrDefault(orderDTO.getId(), "") + ";属性【" + attrVO.getName() + "】的值不符合枚举的要求");
                  //throw new VciBaseException("属性【{0}】的值不符合枚举的要求", new String[]{attrVO.getName()});
               }
            }
@@ -3072,7 +3235,7 @@
    */
   private void copyValueToCBO(CodeClassifyFullInfoBO classifyFullInfo, ClientBusinessObject cbo,
                        CodeOrderDTO orderDTO, CodeClassifyTemplateVO templateVO,
                        boolean edit,Map<String,String> errorMap) {
                        boolean edit, Map<String, String> errorMap) {
      String fullPath = "";
      if (!CollectionUtils.isEmpty(classifyFullInfo.getParentClassifyVOs())) {
         fullPath = classifyFullInfo.getParentClassifyVOs().stream().sorted(((o1, o2) -> o2.getDataLevel().compareTo(o1.getDataLevel())))
@@ -3117,6 +3280,7 @@
         log.error("设置默认的属性的值错误", e);
      }
   }
   /**
    * 设置新的值到申请对象上
    *
@@ -3160,7 +3324,7 @@
    * @param classifyFullInfoBO 分类的全路径
    * @param orderDTO           编码申请的信息
    */
   private void switchClassifyLevelOnOrder(CodeClassifyTemplateVO templateVO, CodeClassifyFullInfoBO classifyFullInfoBO, CodeOrderDTO orderDTO,Map<String,String> errorMap) {
   private void switchClassifyLevelOnOrder(CodeClassifyTemplateVO templateVO, CodeClassifyFullInfoBO classifyFullInfoBO, CodeOrderDTO orderDTO, Map<String, String> errorMap) {
      Map<String, CodeClassifyTemplateAttrVO> classifyAttrVOMap = templateVO.getAttributes().stream().filter(
         s -> StringUtils.isNotBlank(s.getClassifyInvokeAttr()) && StringUtils.isNotBlank(s.getClassifyInvokeLevel())
      ).collect(Collectors.toMap(s -> s.getId().toLowerCase(Locale.ROOT), t -> t));
@@ -3187,7 +3351,7 @@
            }
            if (classifyVO == null) {
               //说明层级有误
               errorMap.put(orderDTO.getId(),errorMap.getOrDefault(orderDTO.getId(),"")+";分类树上没有层级[" + attrVO.getClassifyInvokeLevel() + "]");
               errorMap.put(orderDTO.getId(), errorMap.getOrDefault(orderDTO.getId(), "") + ";分类树上没有层级[" + attrVO.getClassifyInvokeLevel() + "]");
               //orderDTO.getData().put(attrId, "分类树上没有层级[" + attrVO.getClassifyinvokelevel() + "]");
               // classifyVO = classifyFullInfoBO.getCurrentClassifyVO();
            } else {
@@ -3209,19 +3373,19 @@
    * @param errorMap
    * @return
    */
   private void getCodeOrderDTOs(CodeClassifyVO codeClassifyVO,CodeClassifyTemplateVO templateVO,Map<String ,RowDatas>codeDataMap,Map<String, ClientBusinessObject> codeSystemObjectMap,List<CodeOrderDTO> codeOrderDTOList,Map<String,String> errorMap,boolean isCodeOrGroupCode){
      codeSystemObjectMap.keySet().forEach(code->{
         ClientBusinessObject sysDataObject= codeSystemObjectMap.get(code);
         if(isCodeOrGroupCode){
            code=sysDataObject.getAttributeValue("GROUPCODE");
            if(StringUtils.isBlank(code)){
               code=sysDataObject.getId();
   private void getCodeOrderDTOs(CodeClassifyVO codeClassifyVO, CodeClassifyTemplateVO templateVO, Map<String, RowDatas> codeDataMap, Map<String, ClientBusinessObject> codeSystemObjectMap, List<CodeOrderDTO> codeOrderDTOList, Map<String, String> errorMap, boolean isCodeOrGroupCode) {
      codeSystemObjectMap.keySet().forEach(code -> {
         ClientBusinessObject sysDataObject = codeSystemObjectMap.get(code);
         if (isCodeOrGroupCode) {
         //   code = sysDataObject.getAttributeValue("GROUPCODE");
            if (StringUtils.isBlank(code)) {
               code = sysDataObject.getId();
            }
         }
         CodeOrderDTO orderDTO = new CodeOrderDTO();
         if(codeDataMap.containsKey(code)){
            RowDatas rowDatas=codeDataMap.get(code);
            Map<String, String> data= rowDatas.getFiledValue();
         if (codeDataMap.containsKey(code)) {
            RowDatas rowDatas = codeDataMap.get(code);
            Map<String, String> data = rowDatas.getFiledValue();
            orderDTO.setCodeClassifyOid(codeClassifyVO.getOid());//分类主键
            orderDTO.setOid(sysDataObject.getOid());//数据oid
            orderDTO.setLcStatus(rowDatas.getStatus());//状态
@@ -3229,16 +3393,16 @@
            orderDTO.setTs(sysDataObject.getTs());
            orderDTO.setBtmname(codeClassifyVO.getBtmname());//业务类型
            orderDTO.setDescription("集成调用:更新");//数据描述
            if(data.containsKey("name")){
               String name=data.get("name");
            if (data.containsKey("name")) {
               String name = data.get("name");
               orderDTO.setName(name);//名称属性值
            }
            orderDTO.setData(data);//设置数据
            orderDTO.setSecDTOList(null);//分类码段
            orderDTO.setEditInProcess(false);//是否在流程中
            orderDTO.setTemplateOid(templateVO.getOid());
         }else{
            errorMap.put("code","编码为:【"+code+"】的数据在系统中不存在");
         } else {
            errorMap.put("code", "编码为:【" + code + "】的数据在系统中不存在");
         }
         codeOrderDTOList.add(orderDTO);
      });
@@ -3246,15 +3410,16 @@
   /**
    * 获取分类的全路径
    *
    * @param classifyFullInfo 分类的全部信息
    * @return 全路径
    */
   private String getFullPath(CodeClassifyFullInfoBO classifyFullInfo){
   private String getFullPath(CodeClassifyFullInfoBO classifyFullInfo) {
      String fullPath = "";
      if(!CollectionUtils.isEmpty(classifyFullInfo.getParentClassifyVOs())){
      if (!CollectionUtils.isEmpty(classifyFullInfo.getParentClassifyVOs())) {
         fullPath = classifyFullInfo.getParentClassifyVOs().stream().sorted(((o1, o2) -> o1.getDataLevel().compareTo(o2.getDataLevel())))
            .map(CodeClassifyVO::getOid).collect(Collectors.joining("##"));
      }else{
      } else {
         fullPath = classifyFullInfo.getCurrentClassifyVO().getOid();
      }
      return fullPath;
@@ -3262,17 +3427,18 @@
   /**
    * 检查码段的长度是否符合要求
    * @param cboList 数据
    * @param classifyVOMap 分类映射
    * @param ruleVOMap 规则对象
    * @param ruleOidMap 分类包含规则
    * @param errorMap 错误的信息
    *
    * @param cboList         数据
    * @param classifyVOMap   分类映射
    * @param ruleVOMap       规则对象
    * @param ruleOidMap      分类包含规则
    * @param errorMap        错误的信息
    * @param ruleRowIndexMap 规则包含的行号,key是规则主键,value是包含的全部行号
    */
   private void checkSecLengthInHistory(List<ClientBusinessObject> cboList,Map<String,CodeClassifyVO> classifyVOMap,Map<String,CodeRuleVO> ruleVOMap,
                               Map<String/**分类主键**/,String/**规则主键**/> ruleOidMap,Map<String,String> errorMap,Map<String,List<String>> ruleRowIndexMap){
   private void checkSecLengthInHistory(List<ClientBusinessObject> cboList, Map<String, CodeClassifyVO> classifyVOMap, Map<String, CodeRuleVO> ruleVOMap,
                               Map<String/**分类主键**/, String/**规则主键**/> ruleOidMap, Map<String, String> errorMap, Map<String, List<String>> ruleRowIndexMap) {
      cboList.stream().forEach(cbo-> {
      cboList.stream().forEach(cbo -> {
         String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX);
         String secLength = cbo.getAttributeValue(CODE_SEC_LENGTH_FIELD);
         //找分类
@@ -3281,22 +3447,22 @@
         if (classifyVO != null) {
            //2#2#4#1这样的方式
            CodeRuleVO ruleVO = ruleVOMap.getOrDefault(ruleOidMap.get(classifyVO.getOid()), null);
            if(ruleVO!=null){
            if (ruleVO != null) {
               String[] secValues = secLength.split("#");
               //总长度和编码的长度
               String code = cbo.getAttributeValue(CODE_FIELD);
               if(code.length() != Arrays.stream(secValues).mapToInt(s->VciBaseUtil.getInt(s)).sum()){
                  errorMap.put(rowIndex,errorMap.getOrDefault(rowIndex,"") + ";码段宽度与系统中的编码规则不同" );
               }else if(secValues.length != ruleVO.getSecVOList().size()){
                  errorMap.put(rowIndex,errorMap.getOrDefault(rowIndex,"") + ";码段宽度与系统中的编码规则不同" );
               if (code.length() != Arrays.stream(secValues).mapToInt(s -> VciBaseUtil.getInt(s)).sum()) {
                  errorMap.put(rowIndex, errorMap.getOrDefault(rowIndex, "") + ";码段宽度与系统中的编码规则不同");
               } else if (secValues.length != ruleVO.getSecVOList().size()) {
                  errorMap.put(rowIndex, errorMap.getOrDefault(rowIndex, "") + ";码段宽度与系统中的编码规则不同");
               } else {
                  //每一个长度都不能超过码段的
                  boolean fined = false;
                  for (int j = 0; j < ruleVO.getSecVOList().size(); j++) {
                     CodeBasicSecVO secVO = ruleVO.getSecVOList().get(j);
                     String length= secValues[j];
                     if(StringUtils.isNotBlank(secVO.getCodeSecLength())&&VciBaseUtil.getInt(length)>(VciBaseUtil.getInt(secVO.getCodeSecLength())+((secVO.getPrefixCode()+secVO.getSuffixCode()).length()))){
                        errorMap.put(rowIndex,errorMap.getOrDefault(rowIndex,"") + ";码段宽度与系统中的编码规则不同" );
                     String length = secValues[j];
                     if (StringUtils.isNotBlank(secVO.getCodeSecLength()) && VciBaseUtil.getInt(length) > (VciBaseUtil.getInt(secVO.getCodeSecLength()) + ((secVO.getPrefixCode() + secVO.getSuffixCode()).length()))) {
                        errorMap.put(rowIndex, errorMap.getOrDefault(rowIndex, "") + ";码段宽度与系统中的编码规则不同");
                        fined = true;
                        break;
                     }
@@ -3314,15 +3480,15 @@
                   break;
                   }
                   }***/
                  if(!fined){
                  if (!fined) {
                     //暂时不取流水的内容,因为调用produceCode的时候去处理
                     List<String> rowIndexList = ruleRowIndexMap.getOrDefault(ruleVO.getOid(), new ArrayList<>());
                     rowIndexList.add(rowIndex);
                     ruleRowIndexMap.put(ruleVO.getOid(),rowIndexList);
                     ruleRowIndexMap.put(ruleVO.getOid(), rowIndexList);
                  }
               }
            }else{
               errorMap.put(rowIndex,errorMap.getOrDefault(rowIndex,"") + ";分类没有设置编码规则" );
            } else {
               errorMap.put(rowIndex, errorMap.getOrDefault(rowIndex, "") + ";分类没有设置编码规则");
            }
         }
      });
@@ -3330,61 +3496,62 @@
   /**
    * excel转换为cbo的对象
    *
    * @param classifyFullInfo 分类的全部信息
    * @param fieldIndexMap 字段的位置
    * @param rowDataList excel里的行数据
    * @param templateVO 模板的显示对象
    * @param cboList 数据的列表
    * @param fullPath 全路径
    * @param operation 操作类型
    * @param errorMap 错误信息记录
    * @param fieldIndexMap    字段的位置
    * @param rowDataList      excel里的行数据
    * @param templateVO       模板的显示对象
    * @param cboList          数据的列表
    * @param fullPath         全路径
    * @param operation        操作类型
    * @param errorMap         错误信息记录
    */
   private void excelToCbo(CodeClassifyFullInfoBO classifyFullInfo,List<String> titleRowData,Map<Integer,String> fieldIndexMap,List<RowDatas> rowDataList,
                     CodeClassifyTemplateVO templateVO,List<ClientBusinessObject> cboList,
                     String fullPath,boolean isProcess,String operation,Map<String,String> errorMap,Map<String,String> codeOidToSystemOidMap){
   private void excelToCbo(CodeClassifyFullInfoBO classifyFullInfo, List<String> titleRowData, Map<Integer, String> fieldIndexMap, List<RowDatas> rowDataList,
                     CodeClassifyTemplateVO templateVO, List<ClientBusinessObject> cboList,
                     String fullPath, boolean isProcess, String operation, Map<String, String> errorMap, Map<String, String> codeOidToSystemOidMap) {
      rowDataList.stream().forEach(rowData -> {
         String oid=rowData.getOid();
         String rowNumber=rowData.getRowIndex();
         String oid = rowData.getOid();
         String rowNumber = rowData.getRowIndex();
         ClientBusinessObject cbo = new ClientBusinessObject();
         DefaultAttrAssimtUtil.addDefaultAttrAssimt(cbo, classifyFullInfo.getTopClassifyVO().getBtmTypeId(),null);
         rowData.getData().forEach((index,value)->{
         DefaultAttrAssimtUtil.addDefaultAttrAssimt(cbo, classifyFullInfo.getTopClassifyVO().getBtmTypeId());
         rowData.getData().forEach((index, value) -> {
            String field = fieldIndexMap.get(index);
            if(StringUtils.isBlank(field)){
               errorMap.put(rowNumber,"属性:【" +titleRowData.get(index)+ "】在系统中不存在");
            if (StringUtils.isBlank(field)) {
               errorMap.put(rowNumber, "属性:【" + titleRowData.get(index) + "】在系统中不存在");
            }
            try {
               cbo.setAttributeValueWithNoCheck(field,value);
               if(WebUtil.isDefaultField(field)){
               cbo.setAttributeValueWithNoCheck(field, value);
               if (WebUtil.isDefaultField(field)) {
                  WebUtil.setValueToField(field, cbo, value);
               }
            } catch (VciBaseException e) {
               log.error("设置属性的值错误",e);
               errorMap.put(rowNumber,"属性:【" +titleRowData.get(index)+ "】在系统中不存在");
               log.error("设置属性的值错误", e);
               errorMap.put(rowNumber, "属性:【" + titleRowData.get(index) + "】在系统中不存在");
            }
         });
         try {
            cbo.setAttributeValue(IMPORT_ROW_INDEX,rowData.getRowIndex());
            cbo.setAttributeValue(CODE_TEMPLATE_OID_FIELD,templateVO.getOid());
            if(operation.equals("create")){
               log.info("分类对象:"+classifyFullInfo.getCurrentClassifyVO());
               log.info("codeClassoid:"+classifyFullInfo.getCurrentClassifyVO().getOid());
               cbo.setAttributeValue(CODE_CLASSIFY_OID_FIELD,classifyFullInfo.getCurrentClassifyVO().getOid());
               cbo.setAttributeValue(CODE_FULL_PATH_FILED,fullPath);
            cbo.setAttributeValue(IMPORT_ROW_INDEX, rowData.getRowIndex());
            cbo.setAttributeValue(CODE_TEMPLATE_OID_FIELD, templateVO.getOid());
            if (operation.equals("create")) {
               log.info("分类对象:" + classifyFullInfo.getCurrentClassifyVO());
               log.info("codeClassoid:" + classifyFullInfo.getCurrentClassifyVO().getOid());
               cbo.setAttributeValue(CODE_CLASSIFY_OID_FIELD, classifyFullInfo.getCurrentClassifyVO().getOid());
               cbo.setAttributeValue(CODE_FULL_PATH_FILED, fullPath);
               int secret = VciBaseUtil.getInt(cbo.getAttributeValue(SECRET_FIELD));
               if(secret == 0 || !secretService.checkDataSecret(secret).getData() ){
               if (secret == 0 || !secretService.checkDataSecret(secret).getData()) {
                  Integer userSecret = VciBaseUtil.getCurrentUserSecret();
                  String secretValue= String.valueOf((userSecret==null || userSecret ==0)? UserSecretEnum.NONE.getValue():userSecret);
                  cbo.setAttributeValue(SECRET_FIELD,secretValue);
                  String secretValue = String.valueOf((userSecret == null || userSecret == 0) ? UserSecretEnum.NONE.getValue() : userSecret);
                  cbo.setAttributeValue(SECRET_FIELD, secretValue);
               }
               if(rowData.getStatus().equals(CodeDefaultLC.DISABLE.getValue())){//停用
               if (rowData.getStatus().equals(CodeDefaultLC.DISABLE.getValue())) {//停用
                  cbo.setLcStatus(CodeDefaultLC.DISABLE.getValue());
               }else if(rowData.getStatus().equals(CodeDefaultLC.EDITING.getValue())){//编辑
               } else if (rowData.getStatus().equals(CodeDefaultLC.EDITING.getValue())) {//编辑
                  cbo.setLcStatus(CodeDefaultLC.EDITING.getValue());
               }else if(rowData.getStatus().equals(CodeDefaultLC.AUDITING.getValue())) {//审批中
               } else if (rowData.getStatus().equals(CodeDefaultLC.AUDITING.getValue())) {//审批中
                  cbo.setLcStatus(CodeDefaultLC.AUDITING.getValue());
               }else if(rowData.getStatus().equals(CodeDefaultLC.TASK_BACK.getValue())){//回收
               } else if (rowData.getStatus().equals(CodeDefaultLC.TASK_BACK.getValue())) {//回收
                  cbo.setLcStatus(CodeDefaultLC.TASK_BACK.getValue());
               }else{
               } else {
                  cbo.setLcStatus(CodeDefaultLC.RELEASED.getValue());//发布
               }
               /**  if(!isProcess){
@@ -3399,41 +3566,41 @@
                }
                }***/
               cbo.setCreator(rowData.getCreator());
               cbo.setLastModifier(rowData.getEditor()==null?"":rowData.getEditor());
            }else if(operation.equals("update")){
               cbo.setLastModifier(rowData.getEditor() == null ? "" : rowData.getEditor());
            } else if (operation.equals("update")) {
               //此时还没有转换路径
               //cbo.setAttributeValue(CODE_FULL_PATH_FILED, childOidPathMap.getOrDefault(rowData.getData().getOrDefault(CODE_CLASSIFY_OID_FIELD,""),fullPath));
               if(rowData.getStatus().equals(CodeDefaultLC.DISABLE.getValue())){//停用
               if (rowData.getStatus().equals(CodeDefaultLC.DISABLE.getValue())) {//停用
                  cbo.setLcStatus(CodeDefaultLC.DISABLE.getValue());
               }else if(rowData.getStatus().equals(CodeDefaultLC.RELEASED.getValue())){//发布
               } else if (rowData.getStatus().equals(CodeDefaultLC.RELEASED.getValue())) {//发布
                  cbo.setLcStatus(CodeDefaultLC.RELEASED.getValue());
               }else if(rowData.getStatus().equals(CodeDefaultLC.EDITING.getValue())){//编辑
               } else if (rowData.getStatus().equals(CodeDefaultLC.EDITING.getValue())) {//编辑
                  cbo.setLcStatus(CodeDefaultLC.EDITING.getValue());
               }else if(rowData.getStatus().equals(CodeDefaultLC.AUDITING.getValue())) {//审批中
               } else if (rowData.getStatus().equals(CodeDefaultLC.AUDITING.getValue())) {//审批中
                  cbo.setLcStatus(CodeDefaultLC.AUDITING.getValue());
               }else if(rowData.getStatus().equals(CodeDefaultLC.TASK_BACK.getValue())){//回收
               } else if (rowData.getStatus().equals(CodeDefaultLC.TASK_BACK.getValue())) {//回收
                  cbo.setLcStatus(CodeDefaultLC.TASK_BACK.getValue());
               }
               cbo.setLastModifier(rowData.getEditor() == null ? "" : rowData.getEditor());//修改者
            }else if(operation.equals("delete")){
               if(rowData.getStatus().equals(CodeDefaultLC.TASK_BACK.getValue())){//回收
            } else if (operation.equals("delete")) {
               if (rowData.getStatus().equals(CodeDefaultLC.TASK_BACK.getValue())) {//回收
                  cbo.setLcStatus(CodeDefaultLC.TASK_BACK.getValue());
               }else{
               } else {
                  cbo.setLcStatus(CodeDefaultLC.DISABLE.getValue());//停用
               }
            }
         }catch (Throwable e){
            log.error("设置默认的属性的值错误",e);
            if(e instanceof  VciBaseException){
               errorMap.put(rowNumber,"设置默认的属性的值错误"+((VciBaseException) e).getMessage());
            }else{
               errorMap.put(rowNumber,"设置默认的属性的值错误"+e.getMessage());
         } catch (Throwable e) {
            log.error("设置默认的属性的值错误", e);
            if (e instanceof VciBaseException) {
               errorMap.put(rowNumber, "设置默认的属性的值错误" + ((VciBaseException) e).getMessage());
            } else {
               errorMap.put(rowNumber, "设置默认的属性的值错误" + e.getMessage());
            }
         }finally {
            codeOidToSystemOidMap.put(cbo.getOid(),oid);
         } finally {
            codeOidToSystemOidMap.put(cbo.getOid(), oid);
         }
         cbo.setDescription("");
         cboList.add(cbo);
@@ -3443,48 +3610,49 @@
   /**
    * excel转换为cbo的对象
    * @param classifyFullInfo 分类的全部信息
    *
    * @param classifyFullInfo  分类的全部信息
    * @param codeImprotDataVO: 分类对应的数据
    * @param cboList 数据的列表
    * @param newCode 是否为批量申请
    * @param cboList           数据的列表
    * @param newCode           是否为批量申请
    */
   private void excelToCbo(CodeClassifyFullInfoBO classifyFullInfo,CodeImprotDataVO codeImprotDataVO,List<ClientBusinessObject> cboList, boolean newCode){
   private void excelToCbo(CodeClassifyFullInfoBO classifyFullInfo, CodeImprotDataVO codeImprotDataVO, List<ClientBusinessObject> cboList, boolean newCode) {
      String fullPath = getFullPath(classifyFullInfo);
      codeImprotDataVO.getDatas().stream().forEach(rowData -> {
         ClientBusinessObject cbo=new ClientBusinessObject();
         DefaultAttrAssimtUtil.addDefaultAttrAssimt(cbo, classifyFullInfo.getTopClassifyVO().getBtmTypeId(),null);
         rowData.forEach((field,value)->{
         ClientBusinessObject cbo = new ClientBusinessObject();
         DefaultAttrAssimtUtil.addDefaultAttrAssimt(cbo, classifyFullInfo.getTopClassifyVO().getBtmTypeId());
         rowData.forEach((field, value) -> {
            try {
               cbo.setAttributeValueWithNoCheck(field,value);
               if(WebUtil.isDefaultField(field)){
               cbo.setAttributeValueWithNoCheck(field, value);
               if (WebUtil.isDefaultField(field)) {
                  WebUtil.setValueToField(field, cbo, value);
               }
            } catch (VciBaseException e) {
               log.error("设置属性的值错误",e);
               log.error("设置属性的值错误", e);
            }
         });
         try {
            cbo.setAttributeValue(CODE_TEMPLATE_OID_FIELD,codeImprotDataVO.getTemplateOid());
            cbo.setAttributeValue(IMPORT_ROW_INDEX,rowData.get(IMPORT_ROW_INDEX));
            if(newCode){
               cbo.setAttributeValue(CODE_CLASSIFY_OID_FIELD,classifyFullInfo.getCurrentClassifyVO().getOid());
               cbo.setAttributeValue(CODE_FULL_PATH_FILED,fullPath);
            cbo.setAttributeValue(CODE_TEMPLATE_OID_FIELD, codeImprotDataVO.getTemplateOid());
            cbo.setAttributeValue(IMPORT_ROW_INDEX, rowData.get(IMPORT_ROW_INDEX));
            if (newCode) {
               cbo.setAttributeValue(CODE_CLASSIFY_OID_FIELD, classifyFullInfo.getCurrentClassifyVO().getOid());
               cbo.setAttributeValue(CODE_FULL_PATH_FILED, fullPath);
               //cbo.setLcStatus(CodeDefaultLC.EDITING.getValue());
               int secret = VciBaseUtil.getInt(cbo.getAttributeValue(SECRET_FIELD));
               if(secret == 0 || !secretService.checkDataSecret(secret).getData() ){
               if (secret == 0 || !secretService.checkDataSecret(secret).getData()) {
                  Integer userSecret = VciBaseUtil.getCurrentUserSecret();
                  cbo.setAttributeValue(SECRET_FIELD,String.valueOf((userSecret==null || userSecret ==0)? UserSecretEnum.NONE.getValue():userSecret));
                  cbo.setAttributeValue(SECRET_FIELD, String.valueOf((userSecret == null || userSecret == 0) ? UserSecretEnum.NONE.getValue() : userSecret));
               }
               cbo.setLcStatus(CodeDefaultLC.RELEASED.getValue());
            }else{
            } else {
               //此时还没有转换路径
               //cbo.setAttributeValue(CODE_FULL_PATH_FILED, childOidPathMap.getOrDefault(rowData.getData().getOrDefault(CODE_CLASSIFY_OID_FIELD,""),fullPath));
               cbo.setLcStatus(CodeDefaultLC.RELEASED.getValue());
            }
            rowData.put("oid",cbo.getOid());
            rowData.put("oid", cbo.getOid());
         }catch (Throwable e){
            log.error("设置默认的属性的值错误",e);
         } catch (Throwable e) {
            log.error("设置默认的属性的值错误", e);
         }
         cboList.add(cbo);
      });
@@ -3493,22 +3661,28 @@
   /**
    * excel转换为cbo的对象
    *
    * @param classifyFullInfo 分类的全部信息
    * @param fieldIndexMap 字段的位置
    * @param rowDataList excel里的行数据
    * @param templateVO 模板的显示对象
    * @param cboList 数据的列表
    * @param fullPath 全路径
    * @param newCode 是否为批量申请
    * @param fieldIndexMap    字段的位置
    * @param rowDataList      excel里的行数据
    * @param templateVO       模板的显示对象
    * @param cboList          数据的列表
    * @param fullPath         全路径
    * @param newCode          是否为批量申请
    */
   private void excelToCbo(CodeClassifyFullInfoBO classifyFullInfo,Map<Integer,String> fieldIndexMap,List<SheetRowData> rowDataList,
                     CodeClassifyTemplateVO templateVO,List<ClientBusinessObject> cboList,
                     String fullPath,boolean newCode){
   private void excelToCbo(CodeClassifyFullInfoBO classifyFullInfo, Map<Integer, String> fieldIndexMap, List<SheetRowData> rowDataList,
                     CodeClassifyTemplateVO templateVO, List<ClientBusinessObject> cboList,
                     String fullPath, boolean newCode) {
      rowDataList.stream().forEach(rowData -> {
         ClientBusinessObject cbo=new ClientBusinessObject();
         DefaultAttrAssimtUtil.addDefaultAttrAssimt(cbo, classifyFullInfo.getTopClassifyVO().getBtmTypeId(),null);
         rowData.getData().forEach((index,value)->{
               String field = fieldIndexMap.get(index);
         ClientBusinessObject cbo = new ClientBusinessObject();
         DefaultAttrAssimtUtil.addDefaultAttrAssimt(cbo, classifyFullInfo.getTopClassifyVO().getBtmTypeId());
         R<List<BtmTypeVO>> listR = btmTypeClient.selectByIdCollection(Collections.singletonList(classifyFullInfo.getTopClassifyVO().getBtmTypeId()));
         if (!listR.isSuccess() || listR.getData().size() == 0) {
            throw new VciBaseException("传入业务类型未查询到相应表单,请检查!");
         }
         cbo.setRevisionRule("".equals(listR.getData().get(0).getVersionRule()) ? "1" : listR.getData().get(0).getVersionRule());
         rowData.getData().forEach((index, value) -> {
            String field = fieldIndexMap.get(index);
            if (StringUtils.isBlank(field)) {
               throw new VciBaseException("第" + (index + 1) + "列的标题在系统中不存在");
            }
@@ -3522,26 +3696,26 @@
            }
         });
         try {
            cbo.setAttributeValue(CODE_TEMPLATE_OID_FIELD,templateVO.getOid());
            cbo.setAttributeValue(IMPORT_ROW_INDEX,rowData.getRowIndex());
            if(newCode){
               cbo.setAttributeValue(CODE_CLASSIFY_OID_FIELD,classifyFullInfo.getCurrentClassifyVO().getOid());
               cbo.setAttributeValue(CODE_FULL_PATH_FILED,fullPath);
            cbo.setAttributeValue(CODE_TEMPLATE_OID_FIELD, templateVO.getOid());
            cbo.setAttributeValue(IMPORT_ROW_INDEX, rowData.getRowIndex());
            if (newCode) {
               cbo.setAttributeValue(CODE_CLASSIFY_OID_FIELD, classifyFullInfo.getCurrentClassifyVO().getOid());
               cbo.setAttributeValue(CODE_FULL_PATH_FILED, fullPath);
               //cbo.setLcStatus(CodeDefaultLC.EDITING.getValue());
               int secret = VciBaseUtil.getInt(cbo.getAttributeValue(SECRET_FIELD));
               if(secret == 0 || !secretService.checkDataSecret(secret).getData() ){
               if (secret == 0 || !secretService.checkDataSecret(secret).getData()) {
                  Integer userSecret = VciBaseUtil.getCurrentUserSecret();
                  cbo.setAttributeValue(SECRET_FIELD,String.valueOf((userSecret==null || userSecret ==0)? UserSecretEnum.NONE.getValue():userSecret));
                  cbo.setAttributeValue(SECRET_FIELD, String.valueOf((userSecret == null || userSecret == 0) ? UserSecretEnum.NONE.getValue() : userSecret));
               }
               cbo.setLcStatus(CodeDefaultLC.RELEASED.getValue());
            }else{
            } else {
               //此时还没有转换路径
               //cbo.setAttributeValue(CODE_FULL_PATH_FILED, childOidPathMap.getOrDefault(rowData.getData().getOrDefault(CODE_CLASSIFY_OID_FIELD,""),fullPath));
               cbo.setLcStatus(CodeDefaultLC.RELEASED.getValue());
            }
         }catch (Throwable e){
            log.error("设置默认的属性的值错误",e);
         } catch (Throwable e) {
            log.error("设置默认的属性的值错误", e);
         }
         cboList.add(cbo);
      });
@@ -3550,21 +3724,22 @@
   /**
    * excel转换为cbo的对象
    *
    * @param fieldIndexMap 字段的位置
    * @param rowDataList excel里的行数据
    * @param orderDTO 整理的数据
    * @param map 数据的列表
    * @param rowDataList   excel里的行数据
    * @param orderDTO      整理的数据
    * @param map           数据的列表
    */
   private void excelToCboEdit(Map<Integer,String> fieldIndexMap,SheetRowData rowDataList,
                     CodeOrderDTO orderDTO,
                     Map map){
      rowDataList.getData().forEach((index,value)->{
            String field = fieldIndexMap.get(index);
            if (StringUtils.isBlank(field)) {
               throw new VciBaseException("第" + (index + 1) + "列的标题在系统中不存在");
            }
            map.put(field,value);
         });
   private void excelToCboEdit(Map<Integer, String> fieldIndexMap, SheetRowData rowDataList,
                        CodeOrderDTO orderDTO,
                        Map map) {
      rowDataList.getData().forEach((index, value) -> {
         String field = fieldIndexMap.get(index);
         if (StringUtils.isBlank(field)) {
            throw new VciBaseException("第" + (index + 1) + "列的标题在系统中不存在");
         }
         map.put(field.toUpperCase(), value);
      });
      try {
//         for (Map map : cbos) {
@@ -3588,9 +3763,9 @@
                  setter.invoke(orderDTO, ((BigDecimal) map.get(property.getName().toUpperCase())).intValue());
                  map.remove(property.getName().toUpperCase());
               } else if (map.containsKey(property.getName().toUpperCase())) {
                  if(setter.getParameterTypes()[0].getSimpleName().equals("String")){
                     setter.invoke(orderDTO, map.get(property.getName().toUpperCase()) == null ? null:String.valueOf(map.get(property.getName().toUpperCase())));
                  }else{
                  if (setter.getParameterTypes()[0].getSimpleName().equals("String")) {
                     setter.invoke(orderDTO, map.get(property.getName().toUpperCase()) == null ? null : String.valueOf(map.get(property.getName().toUpperCase())));
                  } else {
                     setter.invoke(orderDTO, map.get(property.getName().toUpperCase()));
                  }
                  map.remove(property.getName().toUpperCase());
@@ -3603,7 +3778,6 @@
      } catch (Exception e) {
         throw new VciBaseException("查询失败:" + e.getMessage());
      }
//      Iterator<Map.Entry<String, String>> iterator = cbos.entrySet().iterator();
@@ -3650,31 +3824,32 @@
   /**
    * 检查校验规则没有通过的内容
    * @param attrVOS 需要校验的属性
    *
    * @param attrVOS  需要校验的属性
    * @param dataList 数据的列表
    * @param errorMap 错误的信息映射
    * @return 校验不通过的行数
    */
   private void batchCheckVerifyOnOrder(Collection<CodeClassifyTemplateAttrVO> attrVOS, List<ClientBusinessObject> dataList,Map<String,String> errorMap) {
   private void batchCheckVerifyOnOrder(Collection<CodeClassifyTemplateAttrVO> attrVOS, List<ClientBusinessObject> dataList, Map<String, String> errorMap) {
      Map<String, CodeClassifyTemplateAttrVO> verifyAttrVOMap = attrVOS.stream().filter(s -> StringUtils.isNotBlank(s.getVerifyRule()) && StringUtils.isBlank(s.getComponentRule())
         &&StringUtils.isBlank(s.getClassifyInvokeAttr())
         && StringUtils.isBlank(s.getClassifyInvokeAttr())
      ).collect(Collectors.toMap(s -> s.getId().toLowerCase(Locale.ROOT), t -> t));
      if(!CollectionUtils.isEmpty(verifyAttrVOMap)){
         Map<String/**行号**/,List<String>/**校验不通过的属性**/> unPassCheckMap = new HashMap<>();
         verifyAttrVOMap.forEach((attrId,attrVO)->{
      if (!CollectionUtils.isEmpty(verifyAttrVOMap)) {
         Map<String/**行号**/, List<String>/**校验不通过的属性**/> unPassCheckMap = new HashMap<>();
         verifyAttrVOMap.forEach((attrId, attrVO) -> {
            dataList.stream().forEach(cbo -> {
               String value = cbo.getAttributeValue(attrId);
               if(StringUtils.isNotBlank(value) && !value.matches(attrVO.getVerifyRule())){
               if (StringUtils.isNotBlank(value) && !value.matches(attrVO.getVerifyRule())) {
                  String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX);
                  List<String> unPassAttrs = unPassCheckMap.getOrDefault(rowIndex, new ArrayList<>());
                  unPassAttrs.add(attrVO.getName());
                  unPassCheckMap.put(rowIndex,unPassAttrs);
                  unPassCheckMap.put(rowIndex, unPassAttrs);
               }
            });
         });
         if(!CollectionUtils.isEmpty(unPassCheckMap)){
            unPassCheckMap.forEach((rowIndex,unPassAttrs)->{
               errorMap.put(rowIndex,";属性[" + unPassAttrs.stream().collect(Collectors.joining(",")) + "]内容不符合校验规则的要求");
         if (!CollectionUtils.isEmpty(unPassCheckMap)) {
            unPassCheckMap.forEach((rowIndex, unPassAttrs) -> {
               errorMap.put(rowIndex, ";属性[" + unPassAttrs.stream().collect(Collectors.joining(",")) + "]内容不符合校验规则的要求");
            });
         }
      }
@@ -3682,16 +3857,17 @@
   /**
    * 批量转换时间都为指定的格式
    * @param attrVOS 模板属性
    * @param cboList 数据的列表
    *
    * @param attrVOS  模板属性
    * @param cboList  数据的列表
    * @param errorMap 错误的信息
    */
   private void batchSwitchDateAttrOnOrder(Collection<CodeClassifyTemplateAttrVO> attrVOS,List<ClientBusinessObject> cboList,Map<String,String> errorMap){
      Map<String, CodeClassifyTemplateAttrVO> dateAttrVOMap =attrVOS.stream().filter(s ->
   private void batchSwitchDateAttrOnOrder(Collection<CodeClassifyTemplateAttrVO> attrVOS, List<ClientBusinessObject> cboList, Map<String, String> errorMap) {
      Map<String, CodeClassifyTemplateAttrVO> dateAttrVOMap = attrVOS.stream().filter(s ->
         StringUtils.isNotBlank(s.getCodeDateFormat()) && VciBaseUtil.getBoolean(s.getCodeDateFormat()) && StringUtils.isBlank(s.getComponentRule())
            && StringUtils.isBlank(s.getClassifyInvokeAttr())
      ).collect(Collectors.toMap(s -> s.getId().toLowerCase(Locale.ROOT), t -> t));
      if(!CollectionUtils.isEmpty(dateAttrVOMap)) {
      if (!CollectionUtils.isEmpty(dateAttrVOMap)) {
         dateAttrVOMap.forEach((attrId, attrVO) -> {
            cboList.stream().forEach(cbo -> {
               String value = cbo.getAttributeValue(attrId);
@@ -3700,27 +3876,27 @@
               }
               if (StringUtils.isNotBlank(value)) {
                  boolean formated = false;
                  if(StringUtils.isNotBlank(attrVO.getCodeDateFormat())){
                  if (StringUtils.isNotBlank(attrVO.getCodeDateFormat())) {
                     try {
                        Date date = VciDateUtil.str2Date(value, attrVO.getCodeDateFormat());
                        if(date!=null){
                           cbo.setAttributeValue(attrId,value);
                        if (date != null) {
                           cbo.setAttributeValue(attrId, value);
                           formated = true;
                        }
                     } catch (Exception e) {
                        //说明不是这个格式
                     }
                  }
                  if(!formated) {
                  if (!formated) {
                     try {
                        DateConverter dateConverter = new DateConverter();
                        dateConverter.setAsText(value);
                        value = VciDateUtil.date2Str(dateConverter.getValue(), VciDateUtil.DateTimeMillFormat);
                        cbo.setAttributeValue(attrId,value);
                     }catch (Throwable e){
                        cbo.setAttributeValue(attrId, value);
                     } catch (Throwable e) {
                        //转换不了
                        String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX);
                        errorMap.put(rowIndex,errorMap.getOrDefault(rowIndex,"") + ";属性[" + attrVO.getName() + "]时间格式不正确" );
                        errorMap.put(rowIndex, errorMap.getOrDefault(rowIndex, "") + ";属性[" + attrVO.getName() + "]时间格式不正确");
                     }
                  }
               }
@@ -3731,23 +3907,24 @@
   /**
    * 系统模板中默认值设置
    * @param attrVOS 模板属性
    *
    * @param attrVOS  模板属性
    * @param dataList excel的数据内容
    */
   private void batchSwitchAttrDefault(Collection<CodeClassifyTemplateAttrVO> attrVOS,List<ClientBusinessObject> dataList) {
   private void batchSwitchAttrDefault(Collection<CodeClassifyTemplateAttrVO> attrVOS, List<ClientBusinessObject> dataList) {
      Map<String, CodeClassifyTemplateAttrVO> dateAttrVOMap = attrVOS.stream().filter(s -> StringUtils.isNotBlank(s.getDefaultValue())).collect(Collectors.toMap(s -> s.getId().toLowerCase(Locale.ROOT), t -> t));
      if(!CollectionUtils.isEmpty(dateAttrVOMap)) {
      if (!CollectionUtils.isEmpty(dateAttrVOMap)) {
         dateAttrVOMap.forEach((attrId, attrVO) -> {
            String defaultValue = attrVO.getDefaultValue();
            dataList.stream().forEach(cbo -> {
               String dataValue= cbo.getAttributeValue(attrId);
               if(StringUtils.isBlank(dataValue)){
                  dataValue=defaultValue;
               String dataValue = cbo.getAttributeValue(attrId);
               if (StringUtils.isBlank(dataValue)) {
                  dataValue = defaultValue;
               }
               try {
                  cbo.setAttributeValue(attrId, dataValue);
               }catch (Throwable e){
                  log.error("设置属性的错误",e);
               } catch (Throwable e) {
                  log.error("设置属性的错误", e);
               }
            });
         });
@@ -3756,10 +3933,11 @@
   /**
    * 转移boolean型的属性
    * @param attrVOS 属性的对象
    *
    * @param attrVOS  属性的对象
    * @param dataList 数据
    */
   private void reSwitchBooleanAttrOnOrder(Collection<CodeClassifyTemplateAttrVO> attrVOS,List<ClientBusinessObject> dataList){
   private void reSwitchBooleanAttrOnOrder(Collection<CodeClassifyTemplateAttrVO> attrVOS, List<ClientBusinessObject> dataList) {
      Map<String, CodeClassifyTemplateAttrVO> booleanAttrMap = attrVOS.stream().filter(
         s -> VciFieldTypeEnum.VTBoolean.name().equalsIgnoreCase(s.getAttributeDataType())
      ).collect(Collectors.toMap(s -> s.getId().toLowerCase(Locale.ROOT), t -> t));
@@ -3773,7 +3951,7 @@
                  } else {
                     cbo.setAttributeValue(attrId, BooleanEnum.FASLE.getValue());
                  }
               }catch (Throwable e){
               } catch (Throwable e) {
               }
            });
@@ -3783,26 +3961,27 @@
   /**
    * 处理组合规则
    * @param attrVOS 模板属性
    *
    * @param attrVOS  模板属性
    * @param dataList excel的数据内容
    */
   private void batchSwitchComponentAttrOnOrder(Collection<CodeClassifyTemplateAttrVO> attrVOS,List<ClientBusinessObject> dataList) {
   private void batchSwitchComponentAttrOnOrder(Collection<CodeClassifyTemplateAttrVO> attrVOS, List<ClientBusinessObject> dataList) {
      Map<String, CodeClassifyTemplateAttrVO> dateAttrVOMap = attrVOS.stream().filter(s -> StringUtils.isNotBlank(s.getComponentRule())).collect(Collectors.toMap(s -> s.getId().toLowerCase(Locale.ROOT), t -> t));
      if(!CollectionUtils.isEmpty(dateAttrVOMap)) {
      if (!CollectionUtils.isEmpty(dateAttrVOMap)) {
         dateAttrVOMap.forEach((attrId, attrVO) -> {
            dataList.stream().forEach(cbo -> {
               //从excel上把属性转换为map
               Map<String,String> thisRowDataMap = new HashMap<>();
               copyValueToMapFromCbos(cbo,thisRowDataMap);
               Map<String, String> thisRowDataMap = new HashMap<>();
               copyValueToMapFromCbos(cbo, thisRowDataMap);
               //组合内容
               String value = formulaService.getValueByFormula(thisRowDataMap,attrVO.getComponentRule());
               if(value == null){
               String value = formulaService.getValueByFormula(thisRowDataMap, attrVO.getComponentRule());
               if (value == null) {
                  value = "";
               }
               try {
                  cbo.setAttributeValue(attrId, value);
               }catch (Throwable e){
                  log.error("设置属性的错误",e);
               } catch (Throwable e) {
                  log.error("设置属性的错误", e);
               }
            });
         });
@@ -3811,58 +3990,60 @@
   /**
    * 转换参照的值
    * @param attrVOS 属性的显示对象
    *
    * @param attrVOS  属性的显示对象
    * @param dataList 数据列表
    * @param errorMap 错误的信息
    */
   private void batchSwitchReferAttrOnOrder(Collection<CodeClassifyTemplateAttrVO> attrVOS,List<ClientBusinessObject> dataList,Map<String,String> errorMap){
   private void batchSwitchReferAttrOnOrder(Collection<CodeClassifyTemplateAttrVO> attrVOS, List<ClientBusinessObject> dataList, Map<String, String> errorMap) {
      Map<String, CodeClassifyTemplateAttrVO> referAttrVOMap = attrVOS.stream().filter(
         s -> (StringUtils.isNotBlank(s.getReferBtmId()) || StringUtils.isNotBlank(s.getReferConfig()))
      ).collect(Collectors.toMap(s -> s.getId().toLowerCase(Locale.ROOT), t -> t));
      if(!CollectionUtils.isEmpty(referAttrVOMap)){
         Map<String/**表格和值的属性**/,Map<String/**显示属性的值**/,List<String>/**表格里的值**/>> linkValueMap = new HashMap<>();
         referAttrVOMap.forEach((attrId,attrVO)->{
      if (!CollectionUtils.isEmpty(referAttrVOMap)) {
         Map<String/**表格和值的属性**/, Map<String/**显示属性的值**/, List<String>/**表格里的值**/>> linkValueMap = new HashMap<>();
         referAttrVOMap.forEach((attrId, attrVO) -> {
            dataList.stream().forEach(cbo -> {
               String text = cbo.getAttributeValue(attrId);
               if(StringUtils.isNotBlank(text)){
               if (StringUtils.isNotBlank(text)) {
                  UIFormReferVO referVO = getReferVO(attrVO);
                  String valueField = getValueField(referVO);
                  String showText = getTextField(referVO);
                  String tableAndAttr = VciBaseUtil.getTableName(referVO.getReferType()) + "#" + valueField;
                  Map<String, List<String>> showTextMap = linkValueMap.getOrDefault(tableAndAttr, new HashMap<>());
                  List<String> textList = showTextMap.getOrDefault(showText, new ArrayList<>());
                  if(!textList.contains(text)) {
                  if (!textList.contains(text)) {
                     textList.add(text);
                  }
                  showTextMap.put(showText,textList);
                  linkValueMap.put(tableAndAttr,showTextMap);
                  showTextMap.put(showText, textList);
                  linkValueMap.put(tableAndAttr, showTextMap);
               }
            });
         });
         if(!CollectionUtils.isEmpty(linkValueMap)){
         if (!CollectionUtils.isEmpty(linkValueMap)) {
            //需要逐个表的值字段,逐个查询
            Map<String/**表格和值属性**/,Map<String/**显示属性**/, Map<String/**值**/,String/**显示的值**/>>> linkCboMap = new HashMap<>();
            linkValueMap.forEach((tableAndAttr,showValueMap)->{
            Map<String/**表格和值属性**/, Map<String/**显示属性**/, Map<String/**值**/, String/**显示的值**/>>> linkCboMap = new HashMap<>();
            linkValueMap.forEach((tableAndAttr, showValueMap) -> {
               String[] split = tableAndAttr.split("#");
               String table = split[0];
               String valueField = split[1].toLowerCase(Locale.ROOT);
               Map<String,Map<String,String>> dataMap = new HashMap<>();
               showValueMap.forEach((showText,valueList)->{
                  Map<String,String> valueOidTextMap = new HashMap<>();
               Map<String, Map<String, String>> dataMap = new HashMap<>();
               showValueMap.forEach((showText, valueList) -> {
                  Map<String, String> valueOidTextMap = new HashMap<>();
                  List<List<String>> valueCollections = VciBaseUtil.switchListForOracleIn(valueList);
                  String sql = "select " + valueField + "," + showText.toLowerCase(Locale.ROOT) +" from " + table + "  where " + showText + " in (%s)";
                  valueCollections.stream().forEach(values->{
                     List<Map<String,String>> dataMapList = commonsMapper.queryByOnlySqlForMap(String.format(sql, VciBaseUtil.toInSql(values.toArray(new String[0]))));
                     List<ClientBusinessObject> cbos=   ChangeMapTOClientBusinessObjects(dataMapList);
                     if(!CollectionUtils.isEmpty(cbos)){
                        valueOidTextMap.putAll(cbos.stream().collect(Collectors.toMap(s->s.getAttributeValue(valueField),t->t.getAttributeValue(showText))));
                  String sql = "select " + valueField + "," + showText.toLowerCase(Locale.ROOT) + " from " + table + "  where " + showText + " in (%s)";
                  valueCollections.stream().forEach(values -> {
                     List<Map<String, String>> dataMapList = commonsMapper.queryByOnlySqlForMap(String.format(sql, VciBaseUtil.toInSql(values.toArray(new String[0]))));
                     DefaultAttrAssimtUtil.mapToLowerCase(dataMapList, true);
                     List<ClientBusinessObject> cbos = ChangeMapTOClientBusinessObjects(dataMapList);
                     if (!CollectionUtils.isEmpty(cbos)) {
                        valueOidTextMap.putAll(cbos.stream().collect(Collectors.toMap(s -> s.getAttributeValue(valueField), t -> t.getAttributeValue(showText))));
                     }
                  });
                  dataMap.put(showText,valueOidTextMap);
                  dataMap.put(showText, valueOidTextMap);
               });
               linkCboMap.put(tableAndAttr,dataMap);
               linkCboMap.put(tableAndAttr, dataMap);
            });
            referAttrVOMap.forEach((attrId,attrVO)->{
            referAttrVOMap.forEach((attrId, attrVO) -> {
               dataList.stream().forEach(cbo -> {
                  String text = cbo.getAttributeValue(attrId);
                  if (StringUtils.isNotBlank(text)) {
@@ -3870,31 +4051,31 @@
                     String valueField = getValueField(referVO);
                     String showText = getTextField(referVO);
                     String tableAndAttr = VciBaseUtil.getTableName(referVO.getReferType()) + "#" + valueField;
                     if(!linkCboMap.containsKey(tableAndAttr)){
                     if (!linkCboMap.containsKey(tableAndAttr)) {
                        String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX);
                        errorMap.put(rowIndex,errorMap.getOrDefault(rowIndex,"") + ";参数属性[" + attrVO.getName() + "]的值在系统中不存在" );
                        errorMap.put(rowIndex, errorMap.getOrDefault(rowIndex, "") + ";参数属性[" + attrVO.getName() + "]的值在系统中不存在");
                     }else{
                     } else {
                        Map<String, Map<String, String>> dataMap = linkCboMap.get(tableAndAttr);
                        if(!dataMap.containsKey(showText)){
                        if (!dataMap.containsKey(showText)) {
                           String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX);
                           errorMap.put(rowIndex,errorMap.getOrDefault(rowIndex,"") + ";参数属性[" + attrVO.getName() + "]的值在系统中不存在" );
                        }else{
                           errorMap.put(rowIndex, errorMap.getOrDefault(rowIndex, "") + ";参数属性[" + attrVO.getName() + "]的值在系统中不存在");
                        } else {
                           Map<String, String> data = dataMap.get(showText);
                           final boolean[] fined = {false};
                           data.forEach((key,value)->{
                              if(value.equalsIgnoreCase(text)){
                           data.forEach((key, value) -> {
                              if (value.equalsIgnoreCase(text)) {
                                 fined[0] = true;
                                 try {
                                    cbo.setAttributeValue(attrId, key);
                                 }catch (Throwable e){
                                 } catch (Throwable e) {
                                 }
                              }
                           });
                           if(!fined[0]){
                           if (!fined[0]) {
                              String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX);
                              errorMap.put(rowIndex,errorMap.getOrDefault(rowIndex,"") + ";参数属性[" + attrVO.getName() + "]的值在系统中不存在" );
                              errorMap.put(rowIndex, errorMap.getOrDefault(rowIndex, "") + ";参数属性[" + attrVO.getName() + "]的值在系统中不存在");
                           }
                        }
                     }
@@ -3908,16 +4089,17 @@
   /**
    * 批量检查企业编码是否存在
    *
    * @param templateVO 模板的显示对象
    * @param cboList 数据的列表
    * @param errorMap 错误的信息
    * @param cboList    数据的列表
    * @param errorMap   错误的信息
    */
   private void batchCheckIdExistOnOrder(CodeClassifyTemplateVO templateVO,List<ClientBusinessObject> cboList,Map<String ,String> errorMap) throws Throwable{
   private void batchCheckIdExistOnOrder(CodeClassifyTemplateVO templateVO, List<ClientBusinessObject> cboList, Map<String, String> errorMap) throws Throwable {
      List<String> existIds = new ArrayList<>();
      String tableName ="";
      String tableName = "";
      try {
         R<BtmTypeVO> r = btmTypeClient.getAllAttributeByBtmId(templateVO.getBtmTypeId());
         if(!r.isSuccess()) {
         if (!r.isSuccess()) {
            throw new Throwable(r.getMsg());
         }
         BtmTypeVO btmTypeVO = r.getData();
@@ -3928,7 +4110,7 @@
         if (StringUtils.isBlank(tableName)) {
            throw new Throwable("根据业务类型未查询到业务类型相关联的表");
         }
      }catch (Throwable e){
      } catch (Throwable e) {
         throw e;
      }
      String finalTableName = tableName;
@@ -3936,33 +4118,34 @@
         Map<String, String> conditionMap = new HashMap<>();
         conditionMap.put("id", QueryOptionConstant.IN + "(" + VciBaseUtil.toInSql(cbos.stream().map(s -> s.getId()).collect(Collectors.toSet()).toArray(new String[0])) + ")");
         StringBuffer sb=new StringBuffer();
         StringBuffer sb = new StringBuffer();
         sb.append(" select id from ");
         sb.append(finalTableName);
         sb.append(" where 1=1 ");
         //sb.append(" where 1 = 1");
         sb.append(" where lastr = 1 and lastv = 1"); //TODO:涉及到已升版的数据也应该排除掉,否则会报重
         sb.append(" and id in (");
         sb.append(VciBaseUtil.toInSql(cbos.stream().map(s -> s.getId()).collect(Collectors.toSet()).toArray(new String[0])));
         sb.append(")");
         List<String> idList= commonsMapper.selectById(sb.toString());
         List<String> idList = commonsMapper.selectById(sb.toString());
         //业务数据如果码值回收会直接删除数据,所以这里直接判断是否存在即可
         existIds.addAll(Optional.ofNullable(idList).orElseGet(() -> new ArrayList<>()).stream().map(s -> s.toLowerCase(Locale.ROOT)).collect(Collectors.toList()));
      });
      if(!CollectionUtils.isEmpty(existIds)){
      if (!CollectionUtils.isEmpty(existIds)) {
         String idFieldName = templateVO.getAttributes().stream().filter(s -> VciQueryWrapperForDO.ID_FIELD.equalsIgnoreCase(s.getId())).findFirst().orElseGet(() -> new CodeClassifyTemplateAttrVO()).getName();
         if(StringUtils.isBlank(idFieldName)){
         if (StringUtils.isBlank(idFieldName)) {
            idFieldName = "企业编码";
         }
         String finalIdFieldName = idFieldName;
         cboList.stream().forEach(cbo->{
         cboList.stream().forEach(cbo -> {
            String id = cbo.getId();
            if(StringUtils.isBlank(id)){
            if (StringUtils.isBlank(id)) {
               id = cbo.getAttributeValue("id");
            }
            if(existIds.contains(id)){
            if (existIds.contains(id)) {
               String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX);
               String msg = errorMap.getOrDefault(rowIndex, "");
               msg+=";" + finalIdFieldName + "的值在系统中已经存在";
               errorMap.put(rowIndex,msg);
               msg += ";" + finalIdFieldName + "的值在系统中已经存在";
               errorMap.put(rowIndex, msg);
            }
         });
      }
@@ -3978,27 +4161,27 @@
    * @return
    * @throws Throwable
    */
   private LinkedList<CodeClassifyTemplateVO> checkSamesTemplate(List<String> titleRowData,  List<SheetDataSet> sheetDataSetList,int shetNumber,Map<String/**路径**/, CodeClassifyVO> pathMap,Map<String,String>errorMap) throws Throwable {
      Map<String,String>pathOidMap =new HashMap<>();
      Map<String,String> templateIdRowIndex=new HashedMap();
      SheetDataSet dataSet=  sheetDataSetList.get(shetNumber);
      LinkedHashMap<String,CodeClassifyTemplateVO> codeClassifyTemplateVOMap=new LinkedHashMap <String,CodeClassifyTemplateVO>();
      for (int i=0; i<titleRowData.size();i++){
         String title= titleRowData.get(i);
         if(title.equals("分类路径")) {
   private LinkedList<CodeClassifyTemplateVO> checkSamesTemplate(List<String> titleRowData, List<SheetDataSet> sheetDataSetList, int shetNumber, Map<String/**路径**/, CodeClassifyVO> pathMap, Map<String, String> errorMap) throws Throwable {
      Map<String, String> pathOidMap = new HashMap<>();
      Map<String, String> templateIdRowIndex = new HashedMap();
      SheetDataSet dataSet = sheetDataSetList.get(shetNumber);
      LinkedHashMap<String, CodeClassifyTemplateVO> codeClassifyTemplateVOMap = new LinkedHashMap<String, CodeClassifyTemplateVO>();
      for (int i = 0; i < titleRowData.size(); i++) {
         String title = titleRowData.get(i);
         if (title.equals("分类路径")) {
            int finalI = i;
            dataSet.getRowData().stream().forEach(sheetRowData -> {
               String Path = sheetRowData.getData().get(finalI);
               String rowIndex=sheetRowData.getRowIndex();
               if(StringUtils.isBlank(Path)){
                  Path= "#current#";
               String rowIndex = sheetRowData.getRowIndex();
               if (StringUtils.isBlank(Path)) {
                  Path = "#current#";
               }
               CodeClassifyTemplateVO newTemplateVO=new CodeClassifyTemplateVO();
               String templateOid="";
               if(pathOidMap.containsKey(Path)){
                  templateOid= pathOidMap.get(Path) ;
                  newTemplateVO=codeClassifyTemplateVOMap.get(templateOid);
               }else{
               CodeClassifyTemplateVO newTemplateVO = new CodeClassifyTemplateVO();
               String templateOid = "";
               if (pathOidMap.containsKey(Path)) {
                  templateOid = pathOidMap.get(Path);
                  newTemplateVO = codeClassifyTemplateVOMap.get(templateOid);
               } else {
                  if (pathMap.containsKey(Path)) {
                     CodeClassifyVO codeClassifyVO = pathMap.get(Path);
                     newTemplateVO = engineService.getUsedTemplateByClassifyOid(codeClassifyVO.getOid());
@@ -4014,54 +4197,55 @@
               }
               pathOidMap.put(Path, templateOid);
               codeClassifyTemplateVOMap.put(templateOid, newTemplateVO);
               templateIdRowIndex.put(templateOid, templateIdRowIndex.getOrDefault(templateOid, "") + "," +rowIndex );
               templateIdRowIndex.put(templateOid, templateIdRowIndex.getOrDefault(templateOid, "") + "," + rowIndex);
            });
            break;
         }
      }
      LinkedList<CodeClassifyTemplateVO> codeClassifyTemplateVOList=new LinkedList<>();
      StringBuffer sb=new StringBuffer();
      codeClassifyTemplateVOMap.keySet().forEach(tempateOid->{
         String templateOidInExcel="";
         String tempateName="";
         CodeClassifyTemplateVO t= codeClassifyTemplateVOMap.get(tempateOid);
      LinkedList<CodeClassifyTemplateVO> codeClassifyTemplateVOList = new LinkedList<>();
      StringBuffer sb = new StringBuffer();
      codeClassifyTemplateVOMap.keySet().forEach(tempateOid -> {
         String templateOidInExcel = "";
         String tempateName = "";
         CodeClassifyTemplateVO t = codeClassifyTemplateVOMap.get(tempateOid);
         codeClassifyTemplateVOList.add(t);
         if(!CollectionUtils.isEmpty(sheetDataSetList)
            && sheetDataSetList.size()>1 && !CollectionUtils.isEmpty(sheetDataSetList.get(sheetDataSetList.size()-1).getColName())){
            List<SheetRowData>  rowData=  sheetDataSetList.get(sheetDataSetList.size()-1).getRowData();
            templateOidInExcel=rowData.get(shetNumber).getData().get(0);
            tempateName=rowData.get(shetNumber).getData().get(2);
         if (!CollectionUtils.isEmpty(sheetDataSetList)
            && sheetDataSetList.size() > 1 && !CollectionUtils.isEmpty(sheetDataSetList.get(sheetDataSetList.size() - 1).getColName())) {
            List<SheetRowData> rowData = sheetDataSetList.get(sheetDataSetList.size() - 1).getRowData();
            templateOidInExcel = rowData.get(shetNumber).getData().get(0);
            tempateName = rowData.get(shetNumber).getData().get(2);
            //templateOidInExcel = sheetDataSetList.get(sheetDataSetList.size()-1).getColName().get(sheetDataSetList.size()-i);
         }
         if(StringUtils.isBlank(templateOidInExcel) || !templateOidInExcel.equalsIgnoreCase(tempateOid)){
            sb.append("模板【"+tempateName+"】中第"+templateIdRowIndex.get(tempateOid)+"行数据不属于当前模板的数据,请核对!");
         if (StringUtils.isBlank(templateOidInExcel) || !templateOidInExcel.equalsIgnoreCase(tempateOid)) {
            sb.append("模板【" + tempateName + "】中第" + templateIdRowIndex.get(tempateOid) + "行数据不属于当前模板的数据,请核对!");
         }
      });
      if(StringUtils.isNotBlank(sb.toString())){
         throw  new Throwable(sb.toString());
      if (StringUtils.isNotBlank(sb.toString())) {
         throw new Throwable(sb.toString());
      }
      if(codeClassifyTemplateVOList.size()>1){
         String message="模板【"+dataSet.getSheetName()+"】根据分类路径判断,分类存在多个模板";
      if (codeClassifyTemplateVOList.size() > 1) {
         String message = "模板【" + dataSet.getSheetName() + "】根据分类路径判断,分类存在多个模板";
         throw  new Throwable(message);
         throw new Throwable(message);
      }
      if(codeClassifyTemplateVOList.size()==0){
         String message="模板【"+dataSet.getSheetName()+"】根据数据分类路径判断,未匹配到对应模板";
         throw  new Throwable(message);
      if (codeClassifyTemplateVOList.size() == 0) {
         String message = "模板【" + dataSet.getSheetName() + "】根据数据分类路径判断,未匹配到对应模板";
         throw new Throwable(message);
      }
      return codeClassifyTemplateVOList ;
      return codeClassifyTemplateVOList;
   }
   /**
    * 从属性上获取参照的内容
    *
    * @param attrVO 属性的信息
    * @return 参照的内容
    */
   private UIFormReferVO getReferVO(CodeClassifyTemplateAttrVO attrVO){
   private UIFormReferVO getReferVO(CodeClassifyTemplateAttrVO attrVO) {
      UIFormReferVO referVO = null;
      if(StringUtils.isNotBlank(attrVO.getReferConfig())){
         referVO = JSONObject.parseObject(attrVO.getReferConfig(),UIFormReferVO.class);
      }else{
      if (StringUtils.isNotBlank(attrVO.getReferConfig())) {
         referVO = JSONObject.parseObject(attrVO.getReferConfig(), UIFormReferVO.class);
      } else {
         referVO = new UIFormReferVO();
         referVO.setReferType(attrVO.getReferBtmId());
         referVO.setValueField(VciQueryWrapperForDO.OID_FIELD);
@@ -4072,20 +4256,21 @@
   /**
    * 获取参照中的值的字段
    *
    * @param referVO 参照的对象
    * @return 默认为Oid,有多个的时候,获取第一个
    */
   private String getValueField(UIFormReferVO referVO){
   private String getValueField(UIFormReferVO referVO) {
      String showText = referVO.getValueField();
      if(StringUtils.isBlank(showText)){
      if (StringUtils.isBlank(showText)) {
         return "oid";
      }
      if(showText.contains(",")){
      if (showText.contains(",")) {
         //防止万一有多个,看看有没有oid
         List<String> strings = VciBaseUtil.str2List(showText);
         if(strings.contains("oid")){
         if (strings.contains("oid")) {
            showText = "oid";
         }else{
         } else {
            showText = strings.get(0);
         }
      }
@@ -4094,20 +4279,21 @@
   /**
    * 获取参照中的显示内容的字段
    *
    * @param referVO 参照的对象
    * @return 默认为name,有多个的时候,获取第一个
    */
   private String getTextField(UIFormReferVO referVO){
   private String getTextField(UIFormReferVO referVO) {
      String showText = referVO.getTextField();
      if(StringUtils.isBlank(showText)){
      if (StringUtils.isBlank(showText)) {
         return "name";
      }
      if(showText.contains(",")){
      if (showText.contains(",")) {
         //防止万一有多个,看看有没有name
         List<String> strings = VciBaseUtil.str2List(showText);
         if(strings.contains("name")){
         if (strings.contains("name")) {
            showText = "name";
         }else{
         } else {
            showText = strings.get(0);
         }
      }
@@ -4116,12 +4302,13 @@
   /**
    * 处理枚举的显示对象
    * @param attrVOS 模板属性
    *
    * @param attrVOS  模板属性
    * @param dataList excel的数据内容
    * @param errorMap 错误信息的映射
    */
   private void batchSwitchEnumAttrOnOrder(Collection<CodeClassifyTemplateAttrVO> attrVOS,List<ClientBusinessObject> dataList,
                                 Map<String,String> errorMap ) {
   private void batchSwitchEnumAttrOnOrder(Collection<CodeClassifyTemplateAttrVO> attrVOS, List<ClientBusinessObject> dataList,
                                 Map<String, String> errorMap) {
      Map<String, CodeClassifyTemplateAttrVO> dateAttrVOMap = attrVOS.stream().filter(
         s -> (StringUtils.isNotBlank(s.getEnumString()) || StringUtils.isNotBlank(s.getEnumId()))
      ).collect(Collectors.toMap(s -> s.getId().toLowerCase(Locale.ROOT), t -> t));
@@ -4129,25 +4316,25 @@
         dateAttrVOMap.forEach((attrId, attrVO) -> {
            dataList.stream().forEach(cbo -> {
               String text = cbo.getAttributeValue(attrId);
               if(StringUtils.isNotBlank(text)){
               if (StringUtils.isNotBlank(text)) {
                  List<KeyValue> valueList = engineService.listComboboxItems(attrVO);
                  boolean fined = false;
                  for (int i = 0; i < valueList.size(); i++) {
                     KeyValue keyValue = valueList.get(i);
                     //if(keyValue.getValue().equalsIgnoreCase(text)){
                     if(keyValue.getValue().equalsIgnoreCase(text)||keyValue.getKey().equalsIgnoreCase(text)){
                     if (keyValue.getValue().equalsIgnoreCase(text) || keyValue.getKey().equalsIgnoreCase(text)) {
                        try {
                           cbo.setAttributeValue(attrId, keyValue.getKey());
                        }catch (Throwable e){
                        } catch (Throwable e) {
                           log.error("设置属性出错");
                        }
                        fined = true;
                        break;
                     }
                  }
                  if(!fined){
                  if (!fined) {
                     String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX);
                     errorMap.put(rowIndex,errorMap.getOrDefault(rowIndex,"") + ";属性[" + attrVO.getName() + "]的值不符合下拉的要求");
                     errorMap.put(rowIndex, errorMap.getOrDefault(rowIndex, "") + ";属性[" + attrVO.getName() + "]的值不符合下拉的要求");
                  }
               }
            });
@@ -4157,20 +4344,21 @@
   /**
    * 批量校验数据的信息
    *
    * @param templateVO 模板的显示对象
    * @param cboList 数据的内容
    * @param cboList    数据的内容
    */
   private void batchCheckRequiredAttrOnOrder(CodeClassifyTemplateVO templateVO,List<ClientBusinessObject> cboList,Map<String,String> errorMap){
   private void batchCheckRequiredAttrOnOrder(CodeClassifyTemplateVO templateVO, List<ClientBusinessObject> cboList, Map<String, String> errorMap) {
      Map<String, CodeClassifyTemplateAttrVO> requiredAttrMap = templateVO.getAttributes().stream().filter(s ->
         VciBaseUtil.getBoolean(s.getRequireFlag()) && StringUtils.isBlank(s.getComponentRule()) && (StringUtils.isBlank(s.getClassifyInvokeLevel())||s.getClassifyInvokeLevel().equals("none"))//不能是组合的和分类注入的
         VciBaseUtil.getBoolean(s.getRequireFlag()) && StringUtils.isBlank(s.getComponentRule()) && (StringUtils.isBlank(s.getClassifyInvokeLevel()) || s.getClassifyInvokeLevel().equals("none"))//不能是组合的和分类注入的
      ).collect(Collectors.toMap(s -> s.getId().toLowerCase(Locale.ROOT), t -> t));
      //与MdmEngineServiceImpl里面的checkRequiredAttrOnOrder 逻辑应该相似
      if(!CollectionUtils.isEmpty(requiredAttrMap)) {
      if (!CollectionUtils.isEmpty(requiredAttrMap)) {
         Set<String> nullRowIndex = cboList.stream().filter(cbo -> requiredAttrMap.keySet().stream().anyMatch(attrId -> StringUtils.isBlank(cbo.getAttributeValue(attrId)))).map(cbo -> cbo.getAttributeValue(IMPORT_ROW_INDEX)).collect(Collectors.toSet());
         if(!CollectionUtils.isEmpty(nullRowIndex)){
         if (!CollectionUtils.isEmpty(nullRowIndex)) {
            String checkAttr = requiredAttrMap.values().stream().map(CodeClassifyTemplateAttrVO::getName).collect(Collectors.joining(","));
            nullRowIndex.stream().forEach(rowIndex->{
               errorMap.put(rowIndex,errorMap.getOrDefault(rowIndex,"") + ";校验规则必填项不通过,如果有必填属性为空,则填【/】代替,有校验的属性为" + checkAttr);
            nullRowIndex.stream().forEach(rowIndex -> {
               errorMap.put(rowIndex, errorMap.getOrDefault(rowIndex, "") + ";校验规则必填项不通过,如果有必填属性为空,则填【/】代替,有校验的属性为" + checkAttr);
            });
         }
      }
@@ -4178,40 +4366,41 @@
   /**
    * 处理分类注入
    * @param attrVOS 模板属性
    * @param dataList excel的数据内容
    *
    * @param attrVOS          模板属性
    * @param dataList         excel的数据内容
    * @param classifyFullInfo 分类的全路径
    */
   private void batchSwitchClassifyAttrOnOrder(Collection<CodeClassifyTemplateAttrVO> attrVOS,List<ClientBusinessObject> dataList,
                                    CodeClassifyFullInfoBO classifyFullInfo,boolean isImPort) {
   private void batchSwitchClassifyAttrOnOrder(Collection<CodeClassifyTemplateAttrVO> attrVOS, List<ClientBusinessObject> dataList,
                                    CodeClassifyFullInfoBO classifyFullInfo, boolean isImPort) {
      Map<String, CodeClassifyTemplateAttrVO> dateAttrVOMap = attrVOS.stream().filter(
         s -> StringUtils.isNotBlank(s.getClassifyInvokeAttr())
      ).collect(Collectors.toMap(s -> s.getId().toLowerCase(Locale.ROOT), t -> t));
      Map<String,CodeClassifyFullInfoBO> classifyFullInfoMap=new HashMap<>();
      classifyFullInfoMap.put(classifyFullInfo.getCurrentClassifyVO().getOid(),classifyFullInfo);
      Map<String, CodeClassifyFullInfoBO> classifyFullInfoMap = new HashMap<>();
      classifyFullInfoMap.put(classifyFullInfo.getCurrentClassifyVO().getOid(), classifyFullInfo);
      if (!CollectionUtils.isEmpty(dateAttrVOMap)) {
         dataList.stream().forEach(cbo -> {
            dateAttrVOMap.forEach((attrId, attrVO) -> {
               //分类注入的编号或者名称,
               //层级包含指定层和最小层
               CodeClassifyVO classifyVO = null;
               if(!CodeLevelTypeEnum.MIN.getValue().equalsIgnoreCase(attrVO.getClassifyInvokeLevel()) && !"min".equalsIgnoreCase(attrVO.getClassifyInvokeLevel())) {
               if (!CodeLevelTypeEnum.MIN.getValue().equalsIgnoreCase(attrVO.getClassifyInvokeLevel()) && !"min".equalsIgnoreCase(attrVO.getClassifyInvokeLevel())) {
                  //指定了层级的
                  //注意,因为查询上级分类出来的层级是倒序的,即顶层节点是最大的值
                  if(isImPort){
                     if(!classifyFullInfoMap.containsKey(cbo.getAttributeValue(CODE_CLASSIFY_OID_FIELD))) {
                  if (isImPort) {
                     if (!classifyFullInfoMap.containsKey(cbo.getAttributeValue(CODE_CLASSIFY_OID_FIELD))) {
                        CodeClassifyFullInfoBO currentClassifyFullInfo = classifyService.getClassifyFullInfo(cbo.getAttributeValue(CODE_CLASSIFY_OID_FIELD));
                        classifyFullInfoMap.put(currentClassifyFullInfo.getCurrentClassifyVO().getOid(), currentClassifyFullInfo);
                     }
                  }
                  CodeClassifyFullInfoBO newClassifyFullInfo= classifyFullInfoMap.get(cbo.getAttributeValue(CODE_CLASSIFY_OID_FIELD));
                  CodeClassifyFullInfoBO newClassifyFullInfo = classifyFullInfoMap.get(cbo.getAttributeValue(CODE_CLASSIFY_OID_FIELD));
                  List<CodeClassifyVO> classifyVOS = newClassifyFullInfo.getParentClassifyVOs().stream().sorted(((o1, o2) -> -o2.getDataLevel().compareTo(o1.getDataLevel()))).collect(Collectors.toList());
                  int level = VciBaseUtil.getInt(attrVO.getClassifyInvokeLevel());
                  if (classifyVOS.size()>=level && level > 0 ) {
                     classifyVO = classifyVOS.get(level-1);
                  if (classifyVOS.size() >= level && level > 0) {
                     classifyVO = classifyVOS.get(level - 1);
                  }
               }else{
               } else {
                  //当前的分类
                  classifyVO = classifyFullInfo.getCurrentClassifyVO();
               }
@@ -4222,7 +4411,7 @@
                  } else {
                     Map<String, String> classifyDataMap = VciBaseUtil.objectToMapString(classifyVO);
                     String value = classifyDataMap.getOrDefault(attrVO.getClassifyInvokeAttr(), "");
                     log.error("================================当前分类注入的value值为:==========================",value);
//                     log.error("================================当前分类注入的value值为:==========================",value);
                     cbo.setAttributeValue(attrId, value);
                  }
               } catch (Throwable e) {
@@ -4232,87 +4421,128 @@
         });
      }
   }
   /**
    * 校验关键属性
    * 校验关键属性,和近义词查询规则
    *
    * @param classifyFullInfo 分类的全部信息
    * @param templateVO 模板的内容,必须包含模板属性
    * @param cboList 批量的数据
    */
    * @param templateVO       模板的内容,必须包含模板属性
    * @param cboList          批量的数据
    * @param isEdit          是否是修改
    * @param errorMap          必须必须必须是线程安全的集合
    * */
   private CodeImportResultVO batchCheckKeyAttrOnOrder(CodeClassifyFullInfoBO classifyFullInfo, CodeClassifyTemplateVO templateVO,
                                          List<ClientBusinessObject> cboList,Map<String,String> errorMap) {
                                          List<ClientBusinessObject> cboList, boolean isEdit, Map<String, String> errorMap/*必须要是线程安全的集合*/) {
      //与MdmEngineServiceImpl里的checkKeyAttrOnOrder相似
      //先获取关键属性的规则,也利用继承的方式
      CodeKeyAttrRepeatVO keyRuleVO = keyRuleService.getRuleByClassifyFullInfo(classifyFullInfo);
      //注意的是keyRuleVO可能为空,表示不使用规则控制
      //获取所有的关键属性
      Map<String/**属性的编号**/, CodeClassifyTemplateAttrVO> ketAttrMap = templateVO.getAttributes().stream().filter(s -> VciBaseUtil.getBoolean(s.getKeyAttrFlag())).collect(Collectors.toMap(s -> s.getId().toLowerCase(Locale.ROOT), t -> t));
      Map<String/**属性的编号**/, CodeClassifyTemplateAttrVO> keyAttrMap = templateVO.getAttributes().stream().filter(s -> VciBaseUtil.getBoolean(s.getKeyAttrFlag())).collect(Collectors.toMap(s -> s.getId().toLowerCase(Locale.ROOT), t -> t));
      boolean trimAll =keyRuleVO ==null?false: VciBaseUtil.getBoolean(keyRuleVO.getIgnoreallspaceflag());
      // TODO:2024-02-01 先获取配置了近义词查询规则的属性,不同于关键属性,设置了近义词查询规则的属性可能是多条不同的近义词查询规则
      Map<String, CodeClassifyTemplateAttrVO> sysonymAttrMaps = templateVO.getAttributes().stream().filter(item -> Func.isNotBlank(item.getSysonymRuleOids())).collect(Collectors.toMap(s -> s.getId().toLowerCase(Locale.ROOT), t -> t));
      // 获取是否有配置近义词查询规则属性
      Map<String, List<CodeSynonym>> codeSynonymMaps = new HashMap<>();
      if (!sysonymAttrMaps.isEmpty()) {
         // 查询近义词规则,存储方式key:属性id,value近义词查询规则列表
         codeSynonymMaps = codeSynonymService.getCodeSynonymByOids(sysonymAttrMaps);
      }
      boolean trimAll = keyRuleVO == null ? false : VciBaseUtil.getBoolean(keyRuleVO.getIgnoreallspaceflag());
      //全部去空的优先级大于去空
      boolean trim =keyRuleVO ==null?false:  VciBaseUtil.getBoolean(keyRuleVO.getIgnorespaceflag());
      boolean ignoreCase = keyRuleVO ==null?false: VciBaseUtil.getBoolean(keyRuleVO.getIgnorecaseflag());
      boolean ignoreWidth = keyRuleVO ==null?false: VciBaseUtil.getBoolean(keyRuleVO.getIgnorewidthflag());
      boolean trim = keyRuleVO == null ? false : VciBaseUtil.getBoolean(keyRuleVO.getIgnorespaceflag());
      boolean ignoreCase = keyRuleVO == null ? false : VciBaseUtil.getBoolean(keyRuleVO.getIgnorecaseflag());
      boolean ignoreWidth = keyRuleVO == null ? false : VciBaseUtil.getBoolean(keyRuleVO.getIgnorewidthflag());
      //1. 我们需要先判断excel导入的内容是否正确
      CodeImportResultVO resultVO = new CodeImportResultVO();
      resultVO.setKeyAttrRuleInfo(String.format(keyRuleVO ==null?"":"查询规则:去除空格--{0},忽略大小写--{1},忽略全半角--{2},忽略全部空格--{3}",
         new String[]{trim?"是":"否",ignoreCase?"是":"否",ignoreWidth?"是":"否",trimAll?"是":"否"}));
      //resultVO.setSelfRepeatRowIndexList(getSelfRepeatRowIndex(ketAttrMap,cboList,keyRuleVO));
      getSelfRepeatRowIndex(ketAttrMap,cboList,keyRuleVO,resultVO);
      if(!CollectionUtils.isEmpty(resultVO.getSelfRepeatRowIndexList())){
      StringBuilder synonymResString = new StringBuilder();
      if (Func.isNotEmpty(codeSynonymMaps)) {
         codeSynonymMaps.keySet().stream().forEach(item -> {
            synonymResString.append(item);
            synonymResString.append(",");
         });
      }
      resultVO.setSynonymRuleInfo(Func.isEmpty(codeSynonymMaps) ? "" : String.format("以下[%s]被设置了近义词查询规则的关键属性,中出现了重复:", synonymResString));
      resultVO.setKeyAttrRuleInfo(keyRuleVO == null ? "" : String.format("查询规则:去除空格--{%s},忽略大小写--{%s},忽略全半角--{%s},忽略全部空格--{%s}"
         , trim ? "是" : "否", ignoreCase ? "是" : "否", ignoreWidth ? "是" : "否", trimAll ? "是" : "否"));
      //resultVO.setSelfRepeatRowIndexList(getSelfRepeatRowIndex(keyAttrMap,cboList,keyRuleVO));
      // 先在表格中查询关键属性和近义词转换后重复的列
      getSelfRepeatRowIndex(keyAttrMap, cboList, keyRuleVO, codeSynonymMaps, resultVO);
      // 再在表格中查询近义词查询规则的列
      //getSelfRepeatSysnomRowIndex(sysonymAttrMaps,cboList,codeSynonymMaps,resultVO);
      if (!CollectionUtils.isEmpty(resultVO.getSelfRepeatRowIndexList())) {
         //我们移除本身重复的数据
         cboList = cboList.stream().filter(s->!resultVO.getSelfRepeatRowIndexList().contains(s.getAttributeValue(IMPORT_ROW_INDEX))).collect(Collectors.toList());
         cboList = cboList.stream().filter(s -> !resultVO.getSelfRepeatRowIndexList().contains(s.getAttributeValue(IMPORT_ROW_INDEX))).collect(Collectors.toList());
      }
      //2.判断关键属性在系统里是否重复
      //因为数据量很大,所以得想办法并行
      //SessionInfo sessionInfo = VciBaseUtil.getCurrentUserSessionInfo();
      Map<String,List<BaseModel>> indexTODataMap=new ConcurrentHashMap<>();
      Map<String, List<BaseModel>> indexTODataMap = new ConcurrentHashMap<>();
      // 查询不需要参与关键属性校验的除自己以外的所有分类oid
      final String isParticipateCheckOids = classifyService.selectLeafByParentClassifyOid(classifyFullInfo.getTopClassifyVO().getOid(), classifyFullInfo.getCurrentClassifyVO().getOid());
      final HttpServletRequest request = org.springblade.core.tool.utils.WebUtil.getRequest();
      List<ClientBusinessObject> repeatDataMap = cboList.parallelStream().filter(cbo -> {
         //每行都得查询.如果其中出现了错误,我们就直接抛出异常,其余的显示
         //VciBaseUtil.setCurrentUserSessionInfo(sessionInfo);
         Map<String, String> conditionMap = new HashMap<>();
         ketAttrMap.forEach((attrId, attrVO) -> {
            String value =cbo.getAttributeValue(attrId.toLowerCase(Locale.ROOT));
            if (value == null) {
               value = "";
            }
            value= value.replace(REQUIRED_CHAR,SPECIAL_CHAR);
            engineService.wrapperKeyAttrConditionMap(value, keyRuleVO, attrId, trim, ignoreCase, ignoreWidth, trimAll, conditionMap);
         });
         if (!CollectionUtils.isEmpty(ketAttrMap)) {
            // 添加不参与关键属性校验的分类oid判断
            if(Func.isNotBlank(isParticipateCheckOids)){
               conditionMap.put("t.codeclsfid",QueryOptionConstant.NOTIN+isParticipateCheckOids);
            }
            CodeTemplateAttrSqlBO sqlBO = engineService.getSqlByTemplateVO(classifyFullInfo.getTopClassifyVO().getBtmTypeId(), templateVO, conditionMap, null);
            List<String> repeatData = commonsMapper.selectList(sqlBO.getSqlId());
            if(!repeatData.isEmpty()){
               final List<Map<String,String>> newDataList = commonsMapper.queryByOnlySqlForMap(sqlBO.getSqlUnPage());
               //List<ClientBusinessObject> newCboList=ChangeMapTOClientBusinessObjects(newDataList);
               List<BaseModel> newCboList = new ArrayList<>();
               newDataList.stream().forEach(stringStringMap -> {
                  BaseModel baseModel=new BaseModel();
                  DefaultAttrAssimtUtil.copplyDefaultAttrAssimt(stringStringMap,baseModel,request);
                  baseModel.setData(stringStringMap);
                  newCboList.add(baseModel);
               });
               // 添加错误值
               String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX);
               errorMap.put(rowIndex, "重复的记录编号为:"+repeatData.stream().collect(Collectors.joining(",")));
               if(!CollectionUtils.isEmpty(newCboList)) {
                  indexTODataMap.put(cbo.getAttributeValue(IMPORT_ROW_INDEX), newCboList);
      final BladeUser user = AuthUtil.getUser();
      // TODO:Thread limit exceeded replacing blocked 异常是这部分代码抛出的
      //  ,所以暂时将parallelStream改成了stream,改成了stream之后发现巨慢
      // customForkJoinPool控制并发度
      final List<ClientBusinessObject> finalCboList = cboList;
      final Map<String, List<CodeSynonym>> finalCodeSynonymMaps = codeSynonymMaps;
      List<ClientBusinessObject> repeatDataMap = (List<ClientBusinessObject>) customForkJoinPool.submit(() -> {
         finalCboList.parallelStream().filter(cbo -> {
            //每行都得查询.如果其中出现了错误,我们就直接抛出异常,其余的显示
            //VciBaseUtil.setCurrentUserSessionInfo(sessionInfo);
            Map<String, String> conditionMap = new HashMap<>();
            keyAttrMap.forEach((attrId, attrVO) -> {
               String value = cbo.getAttributeValue(attrId.toLowerCase(Locale.ROOT));
               if (value == null) {
                  value = "";
               }
               value = value.replace(REQUIRED_CHAR, SPECIAL_CHAR);
               // 关键属性查询条件map获取
               engineService.wrapperKeyAttrConditionMap(value, keyRuleVO, finalCodeSynonymMaps.get(attrId), attrId, trim, ignoreCase, ignoreWidth, trimAll, conditionMap);
            });
            if (!CollectionUtils.isEmpty(keyAttrMap)) {
               // 添加不参与关键属性校验的分类oid判断
               if (Func.isNotBlank(isParticipateCheckOids)) {
                  conditionMap.put("t.codeclsfid", QueryOptionConstant.NOTIN + isParticipateCheckOids);
               }
               //如果是更改则需排除系统本身
               if (isEdit) {
                  conditionMap.put("t.id", QueryOptionConstant.NOTEQUAL + cbo.getId());
               }
               conditionMap.put("t.lastr", "1");
               conditionMap.put("t.lastv", "1");
               CodeTemplateAttrSqlBO sqlBO = engineService.getSqlByTemplateVO(classifyFullInfo.getTopClassifyVO().getBtmTypeId(), templateVO, conditionMap, null);
               List<String> repeatData = commonsMapper.selectList(sqlBO.getSqlId());
               if (!repeatData.isEmpty()) {
                  final List<Map<String, String>> newDataList = commonsMapper.queryByOnlySqlForMap(sqlBO.getSqlUnPage());
                  DefaultAttrAssimtUtil.mapToLowerCase(newDataList, true);
                  //List<ClientBusinessObject> newCboList=ChangeMapTOClientBusinessObjects(newDataList);
                  List<BaseModel> newCboList = new ArrayList<>();
                  newDataList.stream().forEach(stringStringMap -> {
                     BaseModel baseModel = new BaseModel();
                     DefaultAttrAssimtUtil.copplyDefaultAttrAssimt(stringStringMap, baseModel, false, user);
                     baseModel.setData(stringStringMap);
                     newCboList.add(baseModel);
                  });
                  // 添加错误值
                  String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX);
                  log.info("=============关键属性查询重复的============="+JSON.toJSONString(repeatData));
                  errorMap.put(rowIndex, "重复的记录编号为:" + repeatData.stream().collect(Collectors.joining(",")));
                  if (!CollectionUtils.isEmpty(newCboList)) {
                     indexTODataMap.put(cbo.getAttributeValue(IMPORT_ROW_INDEX), newCboList);
                  }
               }
               return !repeatData.isEmpty();
            } else {
               return false;
            }
            return !repeatData.isEmpty();
         }else{
            return false;
         }
      }).collect(Collectors.toList());
      if(!CollectionUtils.isEmpty(repeatDataMap)){
         resultVO.setKeyAttrRepeatRowIndexList(repeatDataMap.stream().map(s->s.getAttributeValue(IMPORT_ROW_INDEX)).collect(Collectors.toSet()));
         }).collect(Collectors.toList());
      }).join();
      if (!CollectionUtils.isEmpty(repeatDataMap)) {
         resultVO.setKeyAttrRepeatRowIndexList(repeatDataMap.stream().map(s -> s.getAttributeValue(IMPORT_ROW_INDEX)).collect(Collectors.toSet()));
      }
      resultVO.setIndexTODataMap(indexTODataMap);
      //resultVO.setSuccess(true);
@@ -4321,28 +4551,29 @@
   /**
    * 检查分类的路径是否存在
    * @param cboList 业务数据
    *
    * @param cboList  业务数据
    * @param errorMap 错误信息
    * @param pathMap 路径和分类的映射
    * @param pathMap  路径和分类的映射
    */
   private void checkClassifyPathInHistory(List<ClientBusinessObject> cboList,
                                 Map<String,String> errorMap,     Map<String/**路径**/,CodeClassifyVO> pathMap,
                                 Map<String, String> errorMap, Map<String/**路径**/, CodeClassifyVO> pathMap,
                                 Map<String/**主键**/, String/**路径**/> childOidPathMap) {
      cboList.parallelStream().forEach(cbo -> {
         String classifyPath = cbo.getAttributeValue(CODE_CLASSIFY_OID_FIELD);
         //如果path为空,则表示是导入当前分类
         if(StringUtils.isBlank(classifyPath)){
         if (StringUtils.isBlank(classifyPath)) {
            classifyPath = "#current#";
         }
         if (!pathMap.containsKey(classifyPath)) {
            String row_index = cbo.getAttributeValue(IMPORT_ROW_INDEX);
            errorMap.put(row_index,errorMap.getOrDefault(row_index,"") + ";分类路径不存在");
            errorMap.put(row_index, errorMap.getOrDefault(row_index, "") + ";分类路径不存在");
         } else {
            //转一下分类的主键
            try {
               String classifyOid = pathMap.get(classifyPath).getOid();
               cbo.setAttributeValueWithNoCheck(CODE_CLASSIFY_OID_FIELD, classifyOid);
               cbo.setAttributeValue(CODE_FULL_PATH_FILED, childOidPathMap.getOrDefault(classifyOid,classifyPath));
               cbo.setAttributeValue(CODE_FULL_PATH_FILED, childOidPathMap.getOrDefault(classifyOid, classifyPath));
            } catch (VciBaseException e) {
               log.error("设置属性的错误", e);
            }
@@ -4352,23 +4583,24 @@
   /**
    * 检查分类以及子分类是否都有编码规则
    * @param classifyVOMap 分类的显示对象映射
    * @param ruleOidMap 规则的主键映射
    *
    * @param classifyVOMap              分类的显示对象映射
    * @param ruleOidMap                 规则的主键映射
    * @param unExistRuleClassifyOidList 不存在编码规则的分类的主键
    */
   private void checkRuleOidInHistory( Map<String/**主键**/,CodeClassifyVO> classifyVOMap,  Map<String/**分类主键**/,String/**规则主键**/> ruleOidMap,
                              List<String> unExistRuleClassifyOidList   ){
      if(!CollectionUtils.isEmpty(classifyVOMap)){
         classifyVOMap.values().parallelStream().forEach(classifyVO->{
            if(StringUtils.isNotBlank(classifyVO.getCodeRuleOid())){
               ruleOidMap.put(classifyVO.getOid(),classifyVO.getCodeRuleOid());
            }else{
   private void checkRuleOidInHistory(Map<String/**主键**/, CodeClassifyVO> classifyVOMap, Map<String/**分类主键**/, String/**规则主键**/> ruleOidMap,
                              List<String> unExistRuleClassifyOidList) {
      if (!CollectionUtils.isEmpty(classifyVOMap)) {
         classifyVOMap.values().parallelStream().forEach(classifyVO -> {
            if (StringUtils.isNotBlank(classifyVO.getCodeRuleOid())) {
               ruleOidMap.put(classifyVO.getOid(), classifyVO.getCodeRuleOid());
            } else {
               //递归找上级
               List<String> ruleOidList = new ArrayList<>();
               recursionRule(classifyVOMap,classifyVO.getParentCodeClassifyOid(),ruleOidList);
               if(!CollectionUtils.isEmpty(ruleOidList)){
                  ruleOidMap.put(classifyVO.getOid(),ruleOidList.get(0));
               }else{
               recursionRule(classifyVOMap, classifyVO.getParentCodeClassifyOid(), ruleOidList);
               if (!CollectionUtils.isEmpty(ruleOidList)) {
                  ruleOidMap.put(classifyVO.getOid(), ruleOidList.get(0));
               } else {
                  unExistRuleClassifyOidList.add(classifyVO.getOid());
               }
            }
@@ -4376,155 +4608,164 @@
      }
      log.info(";;;;");
   }
   /**
    * 递归找编码规则
    *
    * @param classifyVOMap 分类的显示对象映射
    * @param classifyOid 分类的主键
    * @param ruleOidList 规则的主键list
    * @param classifyOid   分类的主键
    * @param ruleOidList   规则的主键list
    */
   private void recursionRule(Map<String, CodeClassifyVO> classifyVOMap,String classifyOid,List<String> ruleOidList){
      if(classifyVOMap.containsKey(classifyOid)){
   private void recursionRule(Map<String, CodeClassifyVO> classifyVOMap, String classifyOid, List<String> ruleOidList) {
      if (classifyVOMap.containsKey(classifyOid)) {
         CodeClassifyVO classifyVO = classifyVOMap.get(classifyOid);
         if(StringUtils.isNotBlank(classifyVO.getCodeRuleOid())){
         if (StringUtils.isNotBlank(classifyVO.getCodeRuleOid())) {
            ruleOidList.add(classifyVO.getCodeRuleOid());
            return;
         }else{
            recursionRule(classifyVOMap,classifyVO.getParentCodeClassifyOid(),ruleOidList);
         } else {
            recursionRule(classifyVOMap, classifyVO.getParentCodeClassifyOid(), ruleOidList);
         }
      }else{
         Map<String, CodeClassifyVO> parentClassifyVOMap=new HashMap<>();
         CodeClassifyVO codeClassifyVO= this.classifyService.getObjectByOid(classifyOid);
         parentClassifyVOMap.put(codeClassifyVO.getOid(),codeClassifyVO);
         recursionRule(parentClassifyVOMap,codeClassifyVO.getOid(),ruleOidList);
      } else {
         Map<String, CodeClassifyVO> parentClassifyVOMap = new HashMap<>();
         CodeClassifyVO codeClassifyVO = this.classifyService.getObjectByOid(classifyOid);
         parentClassifyVOMap.put(codeClassifyVO.getOid(), codeClassifyVO);
         recursionRule(parentClassifyVOMap, codeClassifyVO.getOid(), ruleOidList);
      }
   }
   /**
    * 获取子分类的路径
    *
    * @param classifyFullInfo 分类全部信息
    * @param fullPath 分类的全路径
    * @param fullPath         分类的全路径
    * @return 子分类的路径,key是分类的主键
    */
   private Map<String/**分类的主键**/,String/**分类路径**/> getChildClassifyPathMap(CodeClassifyFullInfoBO classifyFullInfo,String fullPath){
   private Map<String/**分类的主键**/, String/**分类路径**/> getChildClassifyPathMap(CodeClassifyFullInfoBO classifyFullInfo, String fullPath) {
      List<CodeClassifyVO> childPathVOs = classifyService.listChildrenClassify(classifyFullInfo.getCurrentClassifyVO().getOid(), true, VciQueryWrapperForDO.OID_FIELD, true);
      Map<String/**分类的主键**/,String/**分类的主键**/> childOidPathMap = new ConcurrentHashMap<>();
      if(!CollectionUtils.isEmpty(childPathVOs)){
         childPathVOs.parallelStream().forEach(childPath->{
      Map<String/**分类的主键**/, String/**分类的主键**/> childOidPathMap = new ConcurrentHashMap<>();
      if (!CollectionUtils.isEmpty(childPathVOs)) {
         childPathVOs.parallelStream().forEach(childPath -> {
            // String thisClassifyPath = fullPath + "##" + childPath.getPath().replace("#" + classifyFullInfo.getCurrentClassifyVO().getOid() + "#","").replace("#","##");
            List<String> list=Arrays.asList(childPath.getPath().split("#"));
            List<String> newPahtList=  list.stream().sorted(Comparator.comparing(s -> s,Comparator.reverseOrder())).collect(Collectors.toList());
            String thisClassifyPath=StringUtils.join(newPahtList,"##")+fullPath;
            childOidPathMap.put(childPath.getOid(),thisClassifyPath);
            List<String> list = Arrays.asList(childPath.getPath().split("#"));
            List<String> newPahtList = list.stream().sorted(Comparator.comparing(s -> s, Comparator.reverseOrder())).collect(Collectors.toList());
            String thisClassifyPath = StringUtils.join(newPahtList, "##") + fullPath;
            childOidPathMap.put(childPath.getOid(), thisClassifyPath);
         });
      }
      String path=classifyFullInfo.getCurrentClassifyVO().getId();
      String path = classifyFullInfo.getCurrentClassifyVO().getId();
      //根据客户选择的分类路径未id,还是name确定路径拼接
      childOidPathMap.put(classifyFullInfo.getCurrentClassifyVO().getOid(),fullPath);
      childOidPathMap.put(classifyFullInfo.getCurrentClassifyVO().getOid(), fullPath);
      return childOidPathMap;
   }
   /**
    * 获取导入的内容中关键属性重复的行号
    * 获取导入的内容中关键属性近义词转换后重复的行号
    *
    * @param ketAttrMap 关键属性的映射
    * @param dataList 导入的数据
    * @param keyRuleVO 关键属性控制规则
    * @param dataList   导入的数据
    * @param keyRuleVO  关键属性控制规则
    * @return 重复的行号
    */
   private void getSelfRepeatRowIndex(Map<String/**属性的编号**/, CodeClassifyTemplateAttrVO> ketAttrMap,
                              List<ClientBusinessObject> dataList,CodeKeyAttrRepeatVO keyRuleVO,CodeImportResultVO resultVO){
                              List<ClientBusinessObject> dataList, CodeKeyAttrRepeatVO keyRuleVO,/*近义词查询规则*/Map<String, List<CodeSynonym>> codeSynonymMaps, CodeImportResultVO resultVO) {
      Set<String> selfRepeatRowIndexList = new CopyOnWriteArraySet<>();
      Map<String,List<String>> keyAttrOkOidTORepeatOidMap=new HashMap<>();
      boolean trimAll =keyRuleVO ==null?false: VciBaseUtil.getBoolean(keyRuleVO.getIgnoreallspaceflag());
      Map<String, List<String>> keyAttrOkOidTORepeatOidMap = new ConcurrentHashMap<>();
      boolean trimAll = keyRuleVO == null ? false : VciBaseUtil.getBoolean(keyRuleVO.getIgnoreallspaceflag());
      //全部去空的优先级大于去空
      boolean trim =keyRuleVO ==null?false:  VciBaseUtil.getBoolean(keyRuleVO.getIgnorespaceflag());
      boolean ignoreCase = keyRuleVO ==null?false: VciBaseUtil.getBoolean(keyRuleVO.getIgnorecaseflag());
      boolean ignoreWidth = keyRuleVO ==null?false: VciBaseUtil.getBoolean(keyRuleVO.getIgnorewidthflag());
      boolean trim = keyRuleVO == null ? false : VciBaseUtil.getBoolean(keyRuleVO.getIgnorespaceflag());
      boolean ignoreCase = keyRuleVO == null ? false : VciBaseUtil.getBoolean(keyRuleVO.getIgnorecaseflag());
      boolean ignoreWidth = keyRuleVO == null ? false : VciBaseUtil.getBoolean(keyRuleVO.getIgnorewidthflag());
      //必须将属性按照顺序排序好
      List<CodeClassifyTemplateAttrVO> attrVOList = ketAttrMap.values().stream().sorted(((o1, o2) -> o1.getOrderNum().compareTo(o2.getOrderNum()))).collect(Collectors.toList());
      Map<String/**行号**/,String/**关键属性的组合内容**/> rowIndexKeyStringMap = new HashMap<>();
      Map<String/**关键属性的组合内容**/,String/**第一个关键属性的数据oid**/> okOidKeyStringMap = new HashMap<>();
      dataList.parallelStream().forEach(cbo-> {
      Map<String/**行号**/, String/**关键属性的组合内容**/> rowIndexKeyStringMap = new ConcurrentHashMap<>();
      Map<String/**关键属性的组合内容**/, String/**第一个关键属性的数据oid**/> okOidKeyStringMap = new ConcurrentHashMap<>();
      dataList.stream().forEach(cbo -> {
         String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX);
         String oid=cbo.getOid();
         String oid = cbo.getOid();
         StringBuilder sb = new StringBuilder();
         for (int i = 0; i < attrVOList.size(); i++) {
            CodeClassifyTemplateAttrVO attrVO = attrVOList.get(i);
            String attrId = attrVO.getId().toLowerCase(Locale.ROOT);
            String value = cbo.getAttributeValue( attrId);
         // TODO: 2024-02-25改造实现近义词查询规则功能;关键属性重复校验值处理
         attrVOList.stream().forEach(item -> {
            String attrId = item.getId().toLowerCase(Locale.ROOT);
            String value = cbo.getAttributeValue(attrId);
            if (value == null) {
               value = "";
            }
            if(trim){
            if (trim) {
               value = value.trim();
            }
            if(trimAll){
               value = value.replace(" ","");
            if (trimAll) {
               value = value.replace(" ", "");
            }
            if(ignoreCase){
            if (ignoreCase) {
               value = value.toLowerCase(Locale.ROOT);
            }
            if(ignoreWidth){
            if (ignoreWidth) {
               value = VciBaseUtil.toDBC(value);
            }
            value = mdmEngineService.getValueToSynony(codeSynonymMaps.get(attrId), value);
            sb.append(value).append("${ks}");
         }
         });
         String keyString = sb.toString();
         if(rowIndexKeyStringMap.containsValue(keyString) && StringUtils.isNotBlank(keyString)){
         if (rowIndexKeyStringMap.containsValue(keyString) && StringUtils.isNotBlank(keyString)) {
            selfRepeatRowIndexList.add(rowIndex);
            String okOid=okOidKeyStringMap.getOrDefault(keyString,"");
            if(StringUtils.isNotBlank(okOid)){
               List<String>newOidList=new ArrayList<>();
            String okOid = okOidKeyStringMap.getOrDefault(keyString, "");
            if (StringUtils.isNotBlank(okOid)) {
               List<String> newOidList = new ArrayList<>();
               newOidList.add(oid);
               if(keyAttrOkOidTORepeatOidMap.containsKey(okOid)){
               if (keyAttrOkOidTORepeatOidMap.containsKey(okOid)) {
                  List<String> oldOidList = keyAttrOkOidTORepeatOidMap.get(okOid);
                  newOidList.addAll(oldOidList);
               }
               keyAttrOkOidTORepeatOidMap.put(okOid,newOidList);
               keyAttrOkOidTORepeatOidMap.put(okOid, newOidList);
            }
         }else {
            okOidKeyStringMap.put(sb.toString(),oid);
            rowIndexKeyStringMap.put(rowIndex, sb.toString());
         } else {
            okOidKeyStringMap.put(sb.toString(), oid);
            rowIndexKeyStringMap.put(rowIndex, keyString);
         }
      });
      //因为只是关键属性重复,所以我们不能重复的多条选一条来报错
      resultVO.setKeyAttrRepeatRowIndexList(selfRepeatRowIndexList);
//      resultVO.setKeyAttrRepeatRowIndexList(selfRepeatRowIndexList);
      resultVO.setSelfRepeatRowIndexList(selfRepeatRowIndexList);
      resultVO.setKeyAttrOkOidTORepeatOidMap(keyAttrOkOidTORepeatOidMap);
   }
   /**
    * excel的标题上获取字段所在的位置
    * @param titleRowData 标题的内容
    *
    * @param titleRowData  标题的内容
    * @param attrNameIdMap 模板中属性名称和英文的映射
    * @param fieldIndexMap 位置和英文字段的映射
    */
   private void getFieldIndexMap(List<String> titleRowData,Map<String/**名称**/,String/**字段名**/> attrNameIdMap,Map<Integer/**位置**/,String/**英文名字**/> fieldIndexMap){
   private void getFieldIndexMap(List<String> titleRowData, Map<String/**名称**/, String/**字段名**/> attrNameIdMap, Map<Integer/**位置**/, String/**英文名字**/> fieldIndexMap) {
      for (int i = 0; i < titleRowData.size(); i++) {
         String title = titleRowData.get(i);
         String id = attrNameIdMap.getOrDefault(title.replace(KEY_ATTR_CHAR,"").replace(REQUIRED_CHAR
            ,""),"");
         if(com.alibaba.cloud.commons.lang.StringUtils.isBlank(id) && "分类路径".equalsIgnoreCase(title)){
         String id = attrNameIdMap.getOrDefault(title.replace(KEY_ATTR_CHAR, "").replace(REQUIRED_CHAR
            , ""), "");
         if (com.alibaba.cloud.commons.lang.StringUtils.isBlank(id) && "分类路径".equalsIgnoreCase(title)) {
            id = CODE_CLASSIFY_OID_FIELD;
         }
         if(com.alibaba.cloud.commons.lang.StringUtils.isBlank(id) && "码段宽度".equalsIgnoreCase(title)){
         if (com.alibaba.cloud.commons.lang.StringUtils.isBlank(id) && "码段宽度".equalsIgnoreCase(title)) {
            id = CODE_SEC_LENGTH_FIELD;
         }
         if(com.alibaba.cloud.commons.lang.StringUtils.isBlank(id) && "企业编码".equalsIgnoreCase(title)){
         if (com.alibaba.cloud.commons.lang.StringUtils.isBlank(id) && "企业编码".equalsIgnoreCase(title)) {
            id = CODE_FIELD;
         }
         if(com.alibaba.cloud.commons.lang.StringUtils.isNotBlank(id)){
            fieldIndexMap.put(i,id);
         if (com.alibaba.cloud.commons.lang.StringUtils.isNotBlank(id)) {
            fieldIndexMap.put(i, id);
         }
      }
   }
   private List<ClientBusinessObject> ChangeMapTOClientBusinessObjects(List<Map<String,String>> oldDataMap){
      List<ClientBusinessObject> clientBusinessObjectList=new ArrayList<>();
      oldDataMap.stream().forEach(dataMap->{
         ClientBusinessObject clientBusinessObject=new ClientBusinessObject();
         DefaultAttrAssimtUtil.copplyDefaultAttrAssimt(dataMap,clientBusinessObject,null);
         for (String key:dataMap.keySet()){
            Object value= dataMap.getOrDefault(key,"");
            clientBusinessObject.setAttributeValue(key.toLowerCase(Locale.ROOT),value==null?"":value.toString());
   private List<ClientBusinessObject> ChangeMapTOClientBusinessObjects(List<Map<String, String>> oldDataMap) {
      List<ClientBusinessObject> clientBusinessObjectList = new ArrayList<>();
      DefaultAttrAssimtUtil.mapToLowerCase(oldDataMap, true);
      final BladeUser user = AuthUtil.getUser();
      oldDataMap.stream().forEach(dataMap -> {
         ClientBusinessObject clientBusinessObject = new ClientBusinessObject();
         DefaultAttrAssimtUtil.copplyDefaultAttrAssimt(dataMap, clientBusinessObject, false, user);
         for (String key : dataMap.keySet()) {
            Object value = dataMap.getOrDefault(key, "");
            clientBusinessObject.setAttributeValue(key.toLowerCase(Locale.ROOT), value == null ? "" : value.toString());
         }
         clientBusinessObjectList.add(clientBusinessObject);
      });
@@ -4537,72 +4778,72 @@
    * @param pathMap
    * @param errorMap
    */
   private void createExeclClassData(SheetDataSet dataSet,Map<String/**路径**/, CodeClassifyVO> pathMap,Map<String,String>errorMap,List<CodeImprotDataVO> codeClassifyDatas){
   private void createExeclClassData(SheetDataSet dataSet, Map<String/**路径**/, CodeClassifyVO> pathMap, Map<String, String> errorMap, List<CodeImprotDataVO> codeClassifyDatas) {
      Map<String,CodeImprotDataVO> pathDatas=new HashMap<>();
      List<String> titleRowData= dataSet.getColName();
      List<SheetRowData>  rowDataList= dataSet.getRowData();
      LinkedHashMap<String,CodeClassifyTemplateVO> codeClassifyTemplateVOMap=new LinkedHashMap <String,CodeClassifyTemplateVO>();
      LinkedHashMap<String,CodeRuleVO> codeRuleVOVOMap=new LinkedHashMap <String,CodeRuleVO>();
      Map<String, CodeImprotDataVO> pathDatas = new HashMap<>();
      List<String> titleRowData = dataSet.getColName();
      List<SheetRowData> rowDataList = dataSet.getRowData();
      LinkedHashMap<String, CodeClassifyTemplateVO> codeClassifyTemplateVOMap = new LinkedHashMap<String, CodeClassifyTemplateVO>();
      LinkedHashMap<String, CodeRuleVO> codeRuleVOVOMap = new LinkedHashMap<String, CodeRuleVO>();
      for (int i=0;i<titleRowData.size();i++){
         String title= titleRowData.get(i);
         if(title.equals("分类路径")) {
      for (int i = 0; i < titleRowData.size(); i++) {
         String title = titleRowData.get(i);
         if (title.equals("分类路径")) {
            int finalI = i;
            rowDataList.stream().forEach(sheetRowData -> {
               CodeImprotDataVO dataVO=new CodeImprotDataVO();
               CodeImprotDataVO dataVO = new CodeImprotDataVO();
               String Path = sheetRowData.getData().get(finalI);
               String rowIndex=sheetRowData.getRowIndex();
               Map<Integer, String> execlData= sheetRowData.getData();
               CodeClassifyTemplateVO newTemplateVO=new CodeClassifyTemplateVO();
               CodeRuleVO codeRuleVO=new CodeRuleVO();
               if(StringUtils.isEmpty(Path)){
                  Path="#current#";
               String rowIndex = sheetRowData.getRowIndex();
               Map<Integer, String> execlData = sheetRowData.getData();
               CodeClassifyTemplateVO newTemplateVO = new CodeClassifyTemplateVO();
               CodeRuleVO codeRuleVO = new CodeRuleVO();
               if (StringUtils.isEmpty(Path)) {
                  Path = "#current#";
               }
               if(pathMap.containsKey(Path)){
                  CodeClassifyVO codeClassifyVO=pathMap.get(Path);
                  if(codeClassifyTemplateVOMap.containsKey(Path)){
                     newTemplateVO=  codeClassifyTemplateVOMap.get(Path);
                     codeRuleVO=  codeRuleVOVOMap.get(Path);
                     if(newTemplateVO==null||StringUtils.isBlank(newTemplateVO.getOid())){
                        errorMap.put(rowIndex,"第"+rowIndex+"行,分类路径未查询到相应的分类模板");
               if (pathMap.containsKey(Path)) {
                  CodeClassifyVO codeClassifyVO = pathMap.get(Path);
                  if (codeClassifyTemplateVOMap.containsKey(Path)) {
                     newTemplateVO = codeClassifyTemplateVOMap.get(Path);
                     codeRuleVO = codeRuleVOVOMap.get(Path);
                     if (newTemplateVO == null || StringUtils.isBlank(newTemplateVO.getOid())) {
                        errorMap.put(rowIndex, "第" + rowIndex + "行,分类路径未查询到相应的分类模板");
                     }
                     if(codeRuleVO==null||StringUtils.isBlank(codeRuleVO.getOid())){
                        errorMap.put(rowIndex,"第"+rowIndex+"行,分类路径未查询到相应的分类规则");
                     if (codeRuleVO == null || StringUtils.isBlank(codeRuleVO.getOid())) {
                        errorMap.put(rowIndex, "第" + rowIndex + "行,分类路径未查询到相应的分类规则");
                     }
                  }else{
                     newTemplateVO =engineService.getUsedTemplateByClassifyOid(codeClassifyVO.getOid());
                     if(newTemplateVO==null||StringUtils.isBlank(newTemplateVO.getOid())){
                        errorMap.put(rowIndex,"第"+rowIndex+"行,分类路径未查询到相应的分类模板");
                  } else {
                     newTemplateVO = engineService.getUsedTemplateByClassifyOid(codeClassifyVO.getOid());
                     if (newTemplateVO == null || StringUtils.isBlank(newTemplateVO.getOid())) {
                        errorMap.put(rowIndex, "第" + rowIndex + "行,分类路径未查询到相应的分类模板");
                     }
                     codeRuleVO=engineService.getCodeRuleByClassifyOid(codeClassifyVO.getOid());
                     if(codeRuleVO==null||StringUtils.isBlank(codeRuleVO.getOid())){
                        errorMap.put(rowIndex,"第"+rowIndex+"行,分类路径未查询到相应的分类规则");
                     codeRuleVO = engineService.getCodeRuleByClassifyOid(codeClassifyVO.getOid());
                     if (codeRuleVO == null || StringUtils.isBlank(codeRuleVO.getOid())) {
                        errorMap.put(rowIndex, "第" + rowIndex + "行,分类路径未查询到相应的分类规则");
                     }
                  }
                  if(pathMap.containsKey(Path)){
                     dataVO=pathDatas.getOrDefault(Path,dataVO);
                  if (pathMap.containsKey(Path)) {
                     dataVO = pathDatas.getOrDefault(Path, dataVO);
                  }
                  dataVO.setTemplateOid(newTemplateVO==null?"":newTemplateVO.getOid());
                  dataVO.setTemplateOid(newTemplateVO == null ? "" : newTemplateVO.getOid());
                  dataVO.setCodeClassifyTemplateVO(newTemplateVO);
                  dataVO.setCodeClassifyVO(codeClassifyVO);
                  dataVO.setCodeRuleVO(codeRuleVO);
                  dataVO.setRowIndex(rowIndex);
                  dataVO.setCodeClassifyOid(codeClassifyVO.getOid());//设置分类oid
                  dataVO.setCodeRuleOid(codeRuleVO==null?"":codeRuleVO.getOid());
                  createExeclClassData(titleRowData,newTemplateVO,execlData,dataVO);
                  pathDatas.put(Path,dataVO);
                  dataVO.setCodeRuleOid(codeRuleVO == null ? "" : codeRuleVO.getOid());
                  createExeclClassData(titleRowData, newTemplateVO, execlData, dataVO);
                  pathDatas.put(Path, dataVO);
                  codeClassifyTemplateVOMap.put(Path, newTemplateVO);
                  codeRuleVOVOMap.put(Path,codeRuleVO);
               }else{
                  errorMap.put(rowIndex,"第"+rowIndex+"行,分类路径未查询到相应的分类");
                  codeRuleVOVOMap.put(Path, codeRuleVO);
               } else {
                  errorMap.put(rowIndex, "第" + rowIndex + "行,分类路径未查询到相应的分类");
               }
            });
            break;
         }
      }
      List <CodeImprotDataVO> newCodeImprotDataVO= pathDatas.values().stream().collect(Collectors.toList());
      List<CodeImprotDataVO> newCodeImprotDataVO = pathDatas.values().stream().collect(Collectors.toList());
      codeClassifyDatas.addAll(newCodeImprotDataVO);
      log.info("222");
   }
@@ -4613,41 +4854,42 @@
    * @param execlData
    * @param codeImprotDataVO
    */
   private void createExeclClassData(List<String> titleRowData, CodeClassifyTemplateVO newTemplateVO, Map<Integer, String> execlData, CodeImprotDataVO codeImprotDataVO){
   private void createExeclClassData(List<String> titleRowData, CodeClassifyTemplateVO newTemplateVO, Map<Integer, String> execlData, CodeImprotDataVO codeImprotDataVO) {
      //除去默认的属性.还有只有表单显示的字段才导入
      List<CodeClassifyTemplateAttrVO> attrVOS = newTemplateVO.getAttributes().stream().filter(s ->
         !DEFAULT_ATTR_LIST.contains(s.getId()) && VciBaseUtil.getBoolean(s.getFormDisplayFlag())
         !DEFAULT_ATTR_LIST.contains(s.getId()) &&
            ((Func.isNotEmpty(s.getClassifyInvokeAttr()) || Func.isNotEmpty(s.getClassifyInvokeAttrName())) || VciBaseUtil.getBoolean(s.getFormDisplayFlag()))
      ).collect(Collectors.toList());
      Map<String/**中文名称**/, String/**英文名称**/> attrNameIdMap = attrVOS.stream().collect(Collectors.toMap(s -> s.getName(), t -> t.getId()));
      List<String> fields=new ArrayList<>();
      Map<String,String> filedValueMap=new HashMap<>();
      List<String> colNames=new ArrayList<>();
      List<String> fields = new ArrayList<>();
      Map<String, String> filedValueMap = new HashMap<>();
      List<String> colNames = new ArrayList<>();
      for (int i = 0; i < titleRowData.size(); i++) {
         String title = titleRowData.get(i);
         title=title.replace(KEY_ATTR_CHAR,"").replace(REQUIRED_CHAR,"");
         String id = attrNameIdMap.getOrDefault(title,"");
         if(StringUtils.isBlank(id) && "分类路径".equalsIgnoreCase(title)){
         title = title.replace(KEY_ATTR_CHAR, "").replace(REQUIRED_CHAR, "");
         String id = attrNameIdMap.getOrDefault(title, "");
         if (StringUtils.isBlank(id) && "分类路径".equalsIgnoreCase(title)) {
            id = CODE_CLASSIFY_OID_FIELD;
         }
         if(StringUtils.isBlank(id) && "码段宽度".equalsIgnoreCase(title)){
         if (StringUtils.isBlank(id) && "码段宽度".equalsIgnoreCase(title)) {
            id = CODE_SEC_LENGTH_FIELD;
         }
         if(StringUtils.isBlank(id) && "企业编码".equalsIgnoreCase(title)){
         if (StringUtils.isBlank(id) && "企业编码".equalsIgnoreCase(title)) {
            id = CODE_FIELD;
         }
         if(StringUtils.isNotBlank(id)){
         if (StringUtils.isNotBlank(id)) {
            // fieldIndexMap.put(i,id);id
            fields.add(id);
            colNames.add(title);
            String value= StringUtils.isNotBlank(execlData.get(i))?execlData.get(i):"";
            filedValueMap.put(id,value);
            String value = StringUtils.isNotBlank(execlData.get(i)) ? execlData.get(i) : "";
            filedValueMap.put(id, value);
         }
      }
      // filedValueMap.put(CODE_CLASSIFY_OID_FIELD,codeImprotDataVO.getCodeClassifyOid());//将当前分类oid存入字段中
      filedValueMap.put("codeclassifyid",codeImprotDataVO.getCodeClassifyOid());
      filedValueMap.put(IMPORT_ROW_INDEX,codeImprotDataVO.getRowIndex());
      filedValueMap.put("codetemplateoid",newTemplateVO.getOid());
      filedValueMap.put("codeclassifyid", codeImprotDataVO.getCodeClassifyOid());
      filedValueMap.put(IMPORT_ROW_INDEX, codeImprotDataVO.getRowIndex());
      filedValueMap.put("codetemplateoid", newTemplateVO.getOid());
      codeImprotDataVO.setFields(fields);
      codeImprotDataVO.setColNames(colNames);
      codeImprotDataVO.getDatas().add(filedValueMap);
@@ -4655,6 +4897,7 @@
   /**
    * 正确错误数据redis缓存
    *
    * @param uuid
    * @param templateVO
    * @param rowIndexCbo
@@ -4663,26 +4906,26 @@
    * @param errorMap
    * @param isok
    */
   private void createRedisDatas(String uuid,CodeClassifyTemplateVO templateVO,Map<String,ClientBusinessObject> rowIndexCbo, SheetDataSet dataSet, Map<Integer/**列号**/,String/**字段的名称**/> fieldIndexMap,Map<String,String> errorMap,boolean isok){
      List<SheetRowData>  needsheetRowDataList =new ArrayList<>();
      if(errorMap.size()>0) {
   private void createRedisDatas(String uuid, CodeClassifyTemplateVO templateVO, Map<String, ClientBusinessObject> rowIndexCbo, SheetDataSet dataSet, Map<Integer/**列号**/, String/**字段的名称**/> fieldIndexMap, Map<String, String> errorMap, boolean isok) {
      List<SheetRowData> needsheetRowDataList = new ArrayList<>();
      if (errorMap.size() > 0) {
         //要把以上的错误的都抛出后,再继续处理时间和组合规则
         needsheetRowDataList = dataSet.getRowData().stream().filter(cbo -> {
            String rowIndex=cbo.getRowIndex();
            return  isok? !errorMap.containsKey(rowIndex):errorMap.containsKey(rowIndex);
            String rowIndex = cbo.getRowIndex();
            return isok ? !errorMap.containsKey(rowIndex) : errorMap.containsKey(rowIndex);
         }).collect(Collectors.toList());
      }else{
         needsheetRowDataList= dataSet.getRowData();
      } else {
         needsheetRowDataList = dataSet.getRowData();
      }
      Map<String/**中文名称**/, SheetRowData/**英文名称**/> rowIdexDataMap = needsheetRowDataList.stream().collect(Collectors.toMap(s -> s.getRowIndex(), t -> t,(o1, o2)->o2));
      Map<String,CodeImprotDataVO> clsfDataMap=new HashMap<>();
      rowIndexCbo .forEach((rowIndex, cbo) -> {
      Map<String/**中文名称**/, SheetRowData/**英文名称**/> rowIdexDataMap = needsheetRowDataList.stream().collect(Collectors.toMap(s -> s.getRowIndex(), t -> t, (o1, o2) -> o2));
      Map<String, CodeImprotDataVO> clsfDataMap = new HashMap<>();
      rowIndexCbo.forEach((rowIndex, cbo) -> {
         CodeImprotDataVO codeImprotDataVO = new CodeImprotDataVO();
         codeImprotDataVO.setTemplateOid(templateVO.getOid());
         List<Map<String, String>> dataList = new ArrayList<>();
         if(rowIdexDataMap.containsKey(rowIndex)){
            SheetRowData sheetRowData=rowIdexDataMap.get(rowIndex);
         if (rowIdexDataMap.containsKey(rowIndex)) {
            SheetRowData sheetRowData = rowIdexDataMap.get(rowIndex);
            Map<String, String> dataMap = new HashMap<>();
            Map<Integer, String> data = sheetRowData.getData();
            fieldIndexMap.forEach((integer, s) -> {
@@ -4692,57 +4935,57 @@
                  dataMap.put(field, vlues);
               }
            });
            dataMap.put("oid",cbo.getOid());
            dataMap.put("oid", cbo.getOid());
            dataList.add(dataMap);
         }
         if(clsfDataMap.containsKey(templateVO.getOid())){
            codeImprotDataVO=clsfDataMap.get(templateVO.getOid());
         if (clsfDataMap.containsKey(templateVO.getOid())) {
            codeImprotDataVO = clsfDataMap.get(templateVO.getOid());
            dataList.addAll(codeImprotDataVO.getDatas());
         }
         codeImprotDataVO.setColNames(dataSet.getColName());
         codeImprotDataVO.setDatas(dataList);
         clsfDataMap.put(templateVO.getOid(),codeImprotDataVO);
         clsfDataMap.put(templateVO.getOid(), codeImprotDataVO);
      });
      if(!CollectionUtils.isEmpty(clsfDataMap)) {
         Collection codeImprotDataVOS=clsfDataMap.values();
         List<CodeImprotDataVO> codeImprotDataVOList=new ArrayList<>();
      if (!CollectionUtils.isEmpty(clsfDataMap)) {
         Collection codeImprotDataVOS = clsfDataMap.values();
         List<CodeImprotDataVO> codeImprotDataVOList = new ArrayList<>();
         codeImprotDataVOList.addAll(codeImprotDataVOS);
         bladeRedis.set(uuid+"-"+templateVO.getOid(), codeImprotDataVOList);
         bladeRedis.expire(uuid+"-"+templateVO.getOid(),BATCHADD_REDIS_TIME);//redis过期时间
         bladeRedis.set(uuid + "-" + templateVO.getOid(), codeImprotDataVOList);
         bladeRedis.expire(uuid + "-" + templateVO.getOid(), BATCHADD_REDIS_TIME);//redis过期时间
      }
   }
   /******
   /**
    * 根据编码规则缓存数据
    * @param uuid
    * @param codeImprotDataVOs
    * @param errorMap
    * @param isok
    */
   private void createRedisDatas(String uuid, List<CodeImprotDataVO> codeImprotDataVOs, Map<String, String> errorMap, boolean isok){
   private void createRedisDatas(String uuid, List<CodeImprotDataVO> codeImprotDataVOs, Map<String, String> errorMap, boolean isok) {
      codeImprotDataVOs.stream().forEach(codeImprotDataVO -> {
         List<Map<String, String>>  dataLists=new ArrayList<>();
         CodeImprotDataVO newCodeImprotDataVO=new CodeImprotDataVO();
         if(errorMap.size()>0) {
         List<Map<String, String>> dataLists = new ArrayList<>();
         CodeImprotDataVO newCodeImprotDataVO = new CodeImprotDataVO();
         if (errorMap.size() > 0) {
            //要把以上的错误的都抛出后,再继续处理时间和组合规则
            dataLists = codeImprotDataVO.getDatas().stream().filter(cbo -> {
               String rowIndex=cbo.get(IMPORT_ROW_INDEX);
               String msg=StringUtils.isBlank(errorMap.get(rowIndex))?"":errorMap.get(rowIndex);
               cbo.put("errorMsg",msg);
               return  isok? !errorMap.containsKey(rowIndex):errorMap.containsKey(rowIndex);
               String rowIndex = cbo.get(IMPORT_ROW_INDEX);
               String msg = StringUtils.isBlank(errorMap.get(rowIndex)) ? "" : errorMap.get(rowIndex);
               cbo.put("errorMsg", msg);
               return isok ? !errorMap.containsKey(rowIndex) : errorMap.containsKey(rowIndex);
            }).collect(Collectors.toList());
         }else{
            dataLists= codeImprotDataVO.getDatas();
         } else {
            dataLists = codeImprotDataVO.getDatas();
         }
         BeanUtilForVCI.copyPropertiesIgnoreCase(codeImprotDataVO,newCodeImprotDataVO);
         BeanUtilForVCI.copyPropertiesIgnoreCase(codeImprotDataVO, newCodeImprotDataVO);
         newCodeImprotDataVO.setDatas(dataLists);
         List<CodeImprotDataVO> codeImprotDataVOList=new ArrayList<>();
         List<CodeImprotDataVO> codeImprotDataVOList = new ArrayList<>();
         codeImprotDataVOList.add(newCodeImprotDataVO);
         /***update 更改成以规则分组*****/
         String codeRuleOid=codeImprotDataVO.getCodeRuleOid();
         log.info(uuid+"-"+codeRuleOid+":条目数"+codeImprotDataVOList.size());
         if(codeImprotDataVOList.size()>0) {
         String codeRuleOid = codeImprotDataVO.getCodeRuleOid();
         log.info(uuid + "-" + codeRuleOid + ":条目数" + codeImprotDataVOList.size());
         if (codeImprotDataVOList.size() > 0) {
            bladeRedis.set(uuid + "-" + codeRuleOid, codeImprotDataVOList);
            bladeRedis.expire(uuid + "-" + codeRuleOid, BATCHADD_REDIS_TIME);//redis过期时间
@@ -4756,7 +4999,7 @@
      });
   }
   /****
   /**
    * 数据相似项数据校验redis缓存
    * @param codeClassifyOid
    * @param templateVO
@@ -4765,7 +5008,7 @@
    * @param btmtypeid
    * @param dataResembleVOS
    */
   private void bathcResembleQuery(String codeClassifyOid, CodeClassifyTemplateVO templateVO, List<ClientBusinessObject> cboList,Map<String,String>resembleMap,String btmtypeid,List<DataResembleVO> dataResembleVOS){
   private void bathcResembleQuery(String codeClassifyOid, CodeClassifyTemplateVO templateVO, List<ClientBusinessObject> cboList, Map<String, String> resembleMap, String btmtypeid, List<DataResembleVO> dataResembleVOS) {
      CodeClassifyFullInfoBO fullInfoBO = classifyService.getClassifyFullInfo(codeClassifyOid);
      Map<String, String> conditionMap = new HashMap<>();
      CodeResembleRuleVO resembleRuleVO = Optional.ofNullable(engineService.getUseResembleRule(fullInfoBO, fullInfoBO.getCurrentClassifyVO())).orElseGet(() -> new CodeResembleRuleVO());
@@ -4774,34 +5017,34 @@
      if (CollectionUtils.isEmpty(attrVOs)) {
         return;
      }
      Map<String,CodeImprotResembleVO> codeImprotResembleVOMap=new HashMap<>();
      List<CodeImprotResembleVO> codeImprotResembleVOList=new ArrayList<>();
      Map<String,String> rowIndePathMap=new HashMap<>();
      Map<String, CodeImprotResembleVO> codeImprotResembleVOMap = new HashMap<>();
      List<CodeImprotResembleVO> codeImprotResembleVOList = new ArrayList<>();
      Map<String, String> rowIndePathMap = new HashMap<>();
      cboList.stream().forEach(clientBusinessObject -> {
         CodeImprotResembleVO codeImprotResembleVO=new CodeImprotResembleVO();
         CodeImprotResembleVO codeImprotResembleVO = new CodeImprotResembleVO();
         final String[] path = {""};
         List<String> fieldList=new ArrayList<>();
         List<String> rowIndeList=new ArrayList<>();
         List<String> fieldList = new ArrayList<>();
         List<String> rowIndeList = new ArrayList<>();
         String rowIndex = clientBusinessObject.getAttributeValue(IMPORT_ROW_INDEX);
         attrVOs.forEach((attrId, attrVO) -> {
            String value="";
            String value = "";
                /*if (VciQueryWrapperForDO.BASIC_FIELD_MAP.containsKey(attrId)) {
                    value = WebUtil.getStringValueFromObject(WebUtil.getValueFromField(WebUtil.getFieldForObject(attrId, orderDTO.getClass()).getName(), orderDTO));
                }else {*/
            value= clientBusinessObject.getAttributeValue(attrId);
            value = clientBusinessObject.getAttributeValue(attrId);
            // }
            fieldList.add(attrId);
            value=StringUtils.isBlank(value)?"":value;
            path[0] +=value+"#";
            value = StringUtils.isBlank(value) ? "" : value;
            path[0] += value + "#";
            engineService.wrapperResembleConditionMap(value, resembleRuleVO, attrId, conditionMap);
         });
         List<Map<String,String>> dataMap=new ArrayList<>();
         if(codeImprotResembleVOMap.containsKey(path[0])) {
            codeImprotResembleVO=codeImprotResembleVOMap.get(path[0]);
            rowIndeList=codeImprotResembleVO.getRownIndex();
            dataMap=  codeImprotResembleVO.getDataList();
         List<Map<String, String>> dataMap = new ArrayList<>();
         if (codeImprotResembleVOMap.containsKey(path[0])) {
            codeImprotResembleVO = codeImprotResembleVOMap.get(path[0]);
            rowIndeList = codeImprotResembleVO.getRownIndex();
            dataMap = codeImprotResembleVO.getDataList();
            resembleMap.put(rowIndex, "存在相似数据");
         }else{
         } else {
            if (!CollectionUtils.isEmpty(conditionMap)) {
               Map<String, String> andConditionMap = new HashMap<>();
               andConditionMap.put("lastr", "1");
@@ -4810,21 +5053,22 @@
               PageHelper pageHelper = new PageHelper(-1);
               pageHelper.addDefaultDesc("id");
               CodeTemplateAttrSqlBO sqlBO = engineService.getSqlByTemplateVO(btmtypeid, templateVO, conditionMap, pageHelper);
               List<Map<String,String>> dataMapList=commonsMapper.queryByOnlySqlForMap(sqlBO.getSqlUnPage());
               List<ClientBusinessObject> resembleCboList=   ChangeMapTOClientBusinessObjects(dataMapList);
               if(!CollectionUtils.isEmpty(resembleCboList)) {
               List<Map<String, String>> dataMapList = commonsMapper.queryByOnlySqlForMap(sqlBO.getSqlUnPage());
               DefaultAttrAssimtUtil.mapToLowerCase(dataMapList, true);
               List<ClientBusinessObject> resembleCboList = ChangeMapTOClientBusinessObjects(dataMapList);
               if (!CollectionUtils.isEmpty(resembleCboList)) {
                  List<Map<String, String>> finalDataMap = dataMap;
                  resembleCboList.stream().forEach(cbo->{
                     Map<String,String> resembDataMap=new HashMap<>();
                     fieldList.stream().forEach(field->{
                        String value=cbo.getAttributeValue(field);
                        value=StringUtils.isBlank(value)?"":value;
                        resembDataMap.put(field,value);
                  resembleCboList.stream().forEach(cbo -> {
                     Map<String, String> resembDataMap = new HashMap<>();
                     fieldList.stream().forEach(field -> {
                        String value = cbo.getAttributeValue(field);
                        value = StringUtils.isBlank(value) ? "" : value;
                        resembDataMap.put(field, value);
                     });
                     resembDataMap.put("codetemplateoid",templateVO.getOid());
                     resembDataMap.put("id",StringUtils.isBlank(cbo.getAttributeValue("id"))?"":cbo.getAttributeValue("id"));
                     resembDataMap.put("rowIndex","");
                     resembDataMap.put("oid",cbo.getOid());
                     resembDataMap.put("codetemplateoid", templateVO.getOid());
                     resembDataMap.put("id", StringUtils.isBlank(cbo.getAttributeValue("id")) ? "" : cbo.getAttributeValue("id"));
                     resembDataMap.put("rowIndex", "");
                     resembDataMap.put("oid", cbo.getOid());
                     finalDataMap.add(resembDataMap);
                  });
                  resembleMap.put(rowIndex, "存在相似数据");
@@ -4832,36 +5076,36 @@
               }
            }
         }
         rowIndePathMap.put(rowIndex,path[0]);
         rowIndePathMap.put(rowIndex, path[0]);
         rowIndeList.add(rowIndex);
         codeImprotResembleVO.setPath(path[0]);
         codeImprotResembleVO.setRownIndex(rowIndeList);
         codeImprotResembleVO.setConditionMap(conditionMap);
         codeImprotResembleVO.setFields(fieldList);
         codeImprotResembleVO.setDataList(dataMap);
         codeImprotResembleVOMap.put(path[0],codeImprotResembleVO);
         codeImprotResembleVOMap.put(path[0], codeImprotResembleVO);
      });
      Map<String, ClientBusinessObject> cboMap = cboList.stream().filter(cbo -> cbo != null).collect(Collectors.toList()).stream().collect(Collectors.toMap(s -> s.getAttributeValue((IMPORT_ROW_INDEX)), t -> t));
      if(!CollectionUtils.isEmpty(rowIndePathMap)){
      if (!CollectionUtils.isEmpty(rowIndePathMap)) {
         rowIndePathMap.forEach((rowIndex, path) -> {
            if(codeImprotResembleVOMap.containsKey(path)){
               CodeImprotResembleVO codeImprotResembleVO=  codeImprotResembleVOMap.get(path);
               List<String> fieldList=codeImprotResembleVO.getFields();
               List<String> rownIndexList= codeImprotResembleVO.getRownIndex();
            if (codeImprotResembleVOMap.containsKey(path)) {
               CodeImprotResembleVO codeImprotResembleVO = codeImprotResembleVOMap.get(path);
               List<String> fieldList = codeImprotResembleVO.getFields();
               List<String> rownIndexList = codeImprotResembleVO.getRownIndex();
               List<String> newRownIndexList = rownIndexList.stream().filter(cbo -> {
                  return rowIndex!=cbo;
                  return rowIndex != cbo;
               }).collect(Collectors.toList());
               newRownIndexList.stream().forEach(s -> {
                  resembleMap.put(s, "存在相似数据");
               });
               List<Map<String, String>>newDataList=new ArrayList<>();
               DataResembleVO dataResembleVO=new DataResembleVO();
               List<Map<String, String>> newDataList = new ArrayList<>();
               DataResembleVO dataResembleVO = new DataResembleVO();
               dataResembleVO.setOid(cboMap.get(rowIndex).getOid());
               List<ClientBusinessObject> needSaveCboList = cboList.stream().filter(cbo -> {
                  String newRowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX);
                  return rownIndexList.contains(newRowIndex)&&(!newRowIndex.equalsIgnoreCase(rowIndex));
                  return rownIndexList.contains(newRowIndex) && (!newRowIndex.equalsIgnoreCase(rowIndex));
               }).collect(Collectors.toList());
               if(!CollectionUtils.isEmpty(needSaveCboList)) {
               if (!CollectionUtils.isEmpty(needSaveCboList)) {
                  needSaveCboList.stream().forEach(cbo -> {
                     String newRowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX);
                     Map<String, String> resembDataMap = new HashMap<>();
@@ -4870,14 +5114,14 @@
                        value = StringUtils.isBlank(value) ? "" : value;
                        resembDataMap.put(field, value);
                     });
                     resembDataMap.put("codetemplateoid",templateVO.getOid());
                     resembDataMap.put("id",StringUtils.isBlank(cbo.getAttributeValue("id"))?"":cbo.getAttributeValue("id"));
                     resembDataMap.put("codetemplateoid", templateVO.getOid());
                     resembDataMap.put("id", StringUtils.isBlank(cbo.getAttributeValue("id")) ? "" : cbo.getAttributeValue("id"));
                     resembDataMap.put("rowIndex", newRowIndex);
                     resembDataMap.put("oid",cbo.getOid());
                     resembDataMap.put("oid", cbo.getOid());
                     newDataList.add(resembDataMap);
                  });
               }
               List<Map<String, String>>dataList=codeImprotResembleVO.getDataList();
               List<Map<String, String>> dataList = codeImprotResembleVO.getDataList();
               newDataList.addAll(dataList);
               dataResembleVO.setDataList(newDataList);
               dataResembleVOS.add(dataResembleVO);
@@ -4894,7 +5138,7 @@
    * @param fieldIndexMap
    * @param iscContain
    */
   private  void createRedisByCodeClassify(String uuid,CodeClassifyTemplateVO templateVOList,SheetDataSet dataSet, Map<Integer/**列号**/,String/**字段的名称**/> fieldIndexMap,boolean iscContain){
   private void createRedisByCodeClassify(String uuid, CodeClassifyTemplateVO templateVOList, SheetDataSet dataSet, Map<Integer/**列号**/, String/**字段的名称**/> fieldIndexMap, boolean iscContain) {
      List<ColumnVO> columnVOList = new ArrayList<>();
      List<String> outNameList = dataSet.getColName();
      fieldIndexMap.forEach((integer, s) -> {
@@ -4905,47 +5149,50 @@
         columnVOS.setTitle(outName);
         columnVOList.add(columnVOS);
      });
      CodeImportTemplateVO codeImportTemplateVO=new CodeImportTemplateVO();
      CodeImportTemplateVO codeImportTemplateVO = new CodeImportTemplateVO();
      codeImportTemplateVO.setCodeClassifyTemplateVO(templateVOList);
      codeImportTemplateVO.setCloNamesList(columnVOList);
      List<CodeImportTemplateVO> codeImportTemplateVOs= new ArrayList<>();
      List<CodeImportTemplateVO> codeImportTemplateVOs = new ArrayList<>();
      codeImportTemplateVOs.add(codeImportTemplateVO);
      if(codeImportTemplateVOs.size()>0) {
      if (codeImportTemplateVOs.size() > 0) {
         bladeRedis.set(uuid, codeImportTemplateVOs);
         bladeRedis.expire(uuid, BATCHADD_REDIS_TIME);//redis过期时间
      }
   }
   /**
    * 拷贝业务类型到map
    *
    * @param cbo 业务数据
    * @param map map
    */
   public static void copyValueToMapFromCbos(ClientBusinessObject cbo,Map<String,String> map){
      if(cbo!=null){
         copyValueToMapFromBos(cbo,map);
   public static void copyValueToMapFromCbos(ClientBusinessObject cbo, Map<String, String> map) {
      if (cbo != null) {
         copyValueToMapFromBos(cbo, map);
      }
   }
   /**
    * 拷贝业务类型到map
    * @param bo 业务数据
    *
    * @param bo  业务数据
    * @param map map
    */
   public static void copyValueToMapFromBos(ClientBusinessObject bo,Map<String,String> map){
      if(bo!=null ){
   public static void copyValueToMapFromBos(ClientBusinessObject bo, Map<String, String> map) {
      if (bo != null) {
         //先把所有的字段映射找到
         AttributeValue[] newAList = bo.newAttrValList;
         AttributeValue[] hisAList = bo.hisAttrValList;
         if(hisAList!=null&&hisAList.length>0){//
            for(int i = 0 ; i < hisAList.length;i++){
         if (hisAList != null && hisAList.length > 0) {//
            for (int i = 0; i < hisAList.length; i++) {
               AttributeValue av = hisAList[i];
               String attrName = av.attrName.toLowerCase();
               map.put(attrName, av.attrVal);
            }
         }
         if(newAList!=null&&newAList.length>0){//NEW的优先级高些
            for(int i = 0 ; i < newAList.length;i++){
         if (newAList != null && newAList.length > 0) {//NEW的优先级高些
            for (int i = 0; i < newAList.length; i++) {
               AttributeValue av = newAList[i];
               String attrName = av.attrName.toLowerCase();
               map.put(attrName, av.attrVal);
@@ -4959,12 +5206,12 @@
    * @param idList
    * @param btmName
    */
   public void sendApplyGroupcode(List<String> idList,String btmName,String operationType){
      String oids=VciBaseUtil.array2String(idList.toArray(new String[]{}));
      if(operationType.equals(sysIntegrationPushTypeEnum.ACCPET_APPCODE.getValue())) {
         mdmInterJtClient.applyGroupCode(oids,btmName);
      }else if(operationType.equals(sysIntegrationPushTypeEnum.ACCPET_EDITCODE)){
         mdmInterJtClient.receiveEditApply(oids,btmName);
   public void sendApplyGroupcode(List<String> idList, String btmName, String operationType) {
      String oids = VciBaseUtil.array2String(idList.toArray(new String[]{}));
      if (operationType.equals(sysIntegrationPushTypeEnum.ACCPET_APPCODE.getValue())) {
         mdmInterJtClient.applyGroupCode(oids, btmName);
      } else if (operationType.equals(sysIntegrationPushTypeEnum.ACCPET_EDITCODE)) {
         mdmInterJtClient.receiveEditApply(oids, btmName);
      }
   }
@@ -4973,25 +5220,25 @@
    * @return
    */
   @Override
   public String exportGroupCodeExcel(String codeClassifyOid) throws ServiceException {
      VciBaseUtil.alertNotNull(codeClassifyOid,"主题库分类的主键");
   public String exportGroupCodeExcel(String codeClassifyOid) throws VciBaseException {
      VciBaseUtil.alertNotNull(codeClassifyOid, "主题库分类的主键");
      CodeClassifyFullInfoBO classifyFullInfo = classifyService.getClassifyFullInfo(codeClassifyOid);
      CodeClassifyVO codeClassifyVO= classifyFullInfo.getCurrentClassifyVO();
      CodeClassifyVO codeClassifyVO = classifyFullInfo.getCurrentClassifyVO();
      //获取最新的模板
      CodeClassifyTemplateVO templateVO = engineService.getUsedTemplateByClassifyOid(codeClassifyOid);
      LinkedList<String> colName=new LinkedList<>();//列头
      LinkedList<String> fieldList=new LinkedList<>();//列字段
      LinkedList<String> colName = new LinkedList<>();//列头
      LinkedList<String> fieldList = new LinkedList<>();//列字段
      ExecGroupCodePortDataDTO execGroupCodePortDataDTO=new ExecGroupCodePortDataDTO();
      createExportGroupCodeMapConfig(templateVO,execGroupCodePortDataDTO);//组织数据
      if(!CollectionUtils.isEmpty(execGroupCodePortDataDTO.getCodeAttrMapGroupAttrDTOS())){
         throw new ServiceException("集团属性映射未配置");
      ExecGroupCodePortDataDTO execGroupCodePortDataDTO = new ExecGroupCodePortDataDTO();
      createExportGroupCodeMapConfig(templateVO, execGroupCodePortDataDTO);//组织数据
      if (CollectionUtils.isEmpty(execGroupCodePortDataDTO.getCodeAttrMapGroupAttrDTOS())) {
         throw new VciBaseException("集团属性映射未配置");
      }
      fieldList=execGroupCodePortDataDTO.getFieldList();
      List<Map<String,String>>dataList=new ArrayList<>();
      getDatas(classifyFullInfo,templateVO,fieldList,dataList,null);
      fieldList = execGroupCodePortDataDTO.getFieldList();
      List<Map<String, String>> dataList = new ArrayList<>();
      getDatas(classifyFullInfo, templateVO, fieldList, dataList, null);
      execGroupCodePortDataDTO.setDataList(dataList);//放数据
      execGroupCodePortDataDTO.setSheetName(codeClassifyVO.getName()+"集团码导入模板");
      execGroupCodePortDataDTO.setSheetName(codeClassifyVO.getName() + "集团码导入模板");
      String tempFolder = LocalFileUtil.getDefaultTempFolder();
      String excelName = tempFolder + File.separator +
         classifyFullInfo.getCurrentClassifyVO().getId() + "_" + classifyFullInfo.getCurrentClassifyVO().getName() + "_集团码导出模板.xls";
@@ -5001,20 +5248,18 @@
         throw new VciBaseException(LangBaseUtil.getErrorMsg(e), new String[]{excelName}, e);
      }
      LinkedList<String> finalFieldList = fieldList;
      Map<String, CodeClassifyTemplateAttrVO> attrVOMap = templateVO.getAttributes().stream().filter(s-> finalFieldList.contains(s.getId().toLowerCase(Locale.ROOT))).collect(Collectors.toMap(s -> s.getId().toLowerCase(Locale.ROOT), t -> t));
      Map<String, CodeClassifyTemplateAttrVO> attrVOMap = templateVO.getAttributes().stream().filter(s -> finalFieldList.contains(s.getId().toLowerCase(Locale.ROOT))).collect(Collectors.toMap(s -> s.getId().toLowerCase(Locale.ROOT), t -> t));
      List<WriteExcelData> excelDataList = new ArrayList<>();
      Workbook workbook = new HSSFWorkbook();
      List<CodeAndGroupCodeAttrMappingDTO>  codeAndGroupCodeAttrMappingDTOList=   execGroupCodePortDataDTO.getCodeAttrMapGroupAttrDTOS();
      Map<String, CodeAndGroupCodeAttrMappingDTO> jAttrVOMap = codeAndGroupCodeAttrMappingDTOList.stream().filter(s-> finalFieldList.contains(s.getTargetAttrKey().toLowerCase(Locale.ROOT))).collect(Collectors.toMap(s -> s.getTargetAttrKey().toLowerCase(Locale.ROOT), t -> t));
      List<CodeAndGroupCodeAttrMappingDTO> codeAndGroupCodeAttrMappingDTOList = execGroupCodePortDataDTO.getCodeAttrMapGroupAttrDTOS();
      Map<String, CodeAndGroupCodeAttrMappingDTO> jAttrVOMap = codeAndGroupCodeAttrMappingDTOList.stream().filter(s -> finalFieldList.contains(s.getTargetAttrKey().toLowerCase(Locale.ROOT))).collect(Collectors.toMap(s -> s.getTargetAttrKey().toLowerCase(Locale.ROOT), t -> t));
      WriteExcelData codeExcelData = new WriteExcelData(0, 0, "企业编码");
      WriteExcelData groupExcelData = new WriteExcelData(0, 1, "集团码");
      excelDataList.add(codeExcelData);
      excelDataList.add(groupExcelData);
      for (int i = 0; i < fieldList.size(); i++) {
         String attrId=fieldList.get(i);
         if(attrId.equals(CODE_FIELD)||attrId.equals(CODE_GROUP_FIELD)){
         String attrId = fieldList.get(i);
         if (attrId.equals(CODE_FIELD) || attrId.equals(CODE_GROUP_FIELD)) {
            continue;
         }
         if (attrVOMap.containsKey(attrId)) {
@@ -5033,19 +5278,19 @@
      final Integer[] rowIndex = {0};
      dataList.stream().forEach(data -> {
         rowIndex[0]++;
         String id=data.getOrDefault("id", "");
         String id = data.getOrDefault("id", "");
         excelDataList.add(new WriteExcelData(rowIndex[0], 0, id));
         String groupCode=data.getOrDefault("groupcode", "");
         String groupCode = data.getOrDefault("groupcode", "");
         excelDataList.add(new WriteExcelData(rowIndex[0], 1, groupCode));
         List<String> newFieldList = finalFieldList.stream().filter(e -> !e.equals("id") &&!e.equals("groupcode")).collect(Collectors.toList());
         List<String> newFieldList = finalFieldList.stream().filter(e -> !e.equals("id") && !e.equals("groupcode")).collect(Collectors.toList());
         for (int i = 0; i < newFieldList.size(); i++) {
            String attrId = newFieldList.get(i).toLowerCase(Locale.ROOT);
            if(attrId.equals("id")){
            if (attrId.equals("id")) {
            }else if(attrId.equals("groupcode")){
            } else if (attrId.equals("groupcode")) {
            }else{
            } else {
               if (attrVOMap.containsKey(attrId)) {
                  CodeClassifyTemplateAttrVO attrVO = attrVOMap.get(attrId);
                  if (StringUtils.isNotBlank(attrVO.getEnumId()) || StringUtils.isNotBlank(attrVO.getEnumString())) {
@@ -5057,25 +5302,25 @@
                  if (VciQueryWrapperForDO.LC_STATUS_FIELD.equalsIgnoreCase(attrId)) {
                     attrId = VciQueryWrapperForDO.LC_STATUS_FIELD_TEXT.toLowerCase(Locale.ROOT);
                  }
                  excelDataList.add(new WriteExcelData(rowIndex[0], i+2, data.getOrDefault(attrId, "")));
                  excelDataList.add(new WriteExcelData(rowIndex[0], i + 2, data.getOrDefault(attrId, "")));
               }
            }
         }
      });
      WriteExcelOption excelOption = new WriteExcelOption();
      excelOption.addSheetDataList(execGroupCodePortDataDTO.getSheetName(),excelDataList);
      excelOption.addSheetDataList(execGroupCodePortDataDTO.getSheetName(), excelDataList);
      //增加模板的信息导入
      LinkedList<WriteExcelData> tempEDList = new LinkedList<>();
      tempEDList.add(new WriteExcelData(0,0,"模板主键"));
      tempEDList.add(new WriteExcelData(0,1,"模板代号"));
      tempEDList.add(new WriteExcelData(0,2,"模板名称"));
      tempEDList.add(new WriteExcelData(1,0,templateVO.getOid()));
      tempEDList.add(new WriteExcelData(1,1,templateVO.getId()));
      tempEDList.add(new WriteExcelData(1,2,templateVO.getName()));
      excelOption.addSheetDataList("模板信息【请勿删除或移动】",tempEDList);
      tempEDList.add(new WriteExcelData(0, 0, "模板主键"));
      tempEDList.add(new WriteExcelData(0, 1, "模板代号"));
      tempEDList.add(new WriteExcelData(0, 2, "模板名称"));
      tempEDList.add(new WriteExcelData(1, 0, templateVO.getOid()));
      tempEDList.add(new WriteExcelData(1, 1, templateVO.getId()));
      tempEDList.add(new WriteExcelData(1, 2, templateVO.getName()));
      excelOption.addSheetDataList("模板信息【请勿删除或移动】", tempEDList);
      ExcelUtil.writeDataToFile(excelName, excelOption);
      log.info("文件路径"+excelName);
      log.info("文件路径" + excelName);
      return excelName;
   }
@@ -5085,64 +5330,265 @@
    * @param file
    * @return
    */
   public String improtGroupCode(String codeClassifyOid, File file) throws ServiceException {
      VciBaseUtil.alertNotNull(codeClassifyOid,"分类的主键");
   @Override
   @Transactional(rollbackFor = Exception.class)
   public String importGroupCode(String codeClassifyOid, File file) throws Throwable {
      VciBaseUtil.alertNotNull(codeClassifyOid, "分类的主键");
      ReadExcelOption reo = new ReadExcelOption();
      reo.setReadAllSheet(true);
      List<SheetDataSet> sheetDataSetList = ExcelUtil.readDataObjectFromExcel(file,null,reo);
      List<SheetDataSet> sheetDataSetList = ExcelUtil.readDataObjectFromExcel(file, null, reo);
      if (sheetDataSetList.size() > LIMIT + 1) {
         throw new ServiceException("为了保证系统的稳定性,请一次不要导入超过1万条的数据");
      }
      CodeClassifyFullInfoBO classifyFullInfo = classifyService.getClassifyFullInfo(codeClassifyOid);
      CodeClassifyTemplateVO templateVO = new CodeClassifyTemplateVO();
      //除去默认的属性.还有只有表单显示的字段才导入
      List<CodeClassifyTemplateAttrVO> attrVOS = templateVO.getAttributes().stream().filter(s ->!DEFAULT_SYNC_ATTR_LIST.contains(s.getId()) && VciBaseUtil.getBoolean(s.getFormDisplayFlag())
      //获取最新的模板
      CodeClassifyTemplateVO templateVO = engineService.getUsedTemplateByClassifyOid(codeClassifyOid);        //除去默认的属性.还有只有表单显示的字段才导入
      List<CodeClassifyTemplateAttrVO> attrVOS = templateVO.getAttributes().stream().filter(s -> !DEFAULT_SYNC_ATTR_LIST.contains(s.getId()) &&
         ((Func.isNotEmpty(s.getClassifyInvokeAttr()) || Func.isNotEmpty(s.getClassifyInvokeAttrName())) || VciBaseUtil.getBoolean(s.getFormDisplayFlag()))
      ).collect(Collectors.toList());
      ExecGroupCodePortDataDTO execGroupCodePortDataDTO=new ExecGroupCodePortDataDTO();
      createExportGroupCodeMapConfig(templateVO,execGroupCodePortDataDTO);//组织数据
      List<CodeAndGroupCodeAttrMappingDTO> codeAttrMapGroupAttrDTOS=execGroupCodePortDataDTO.getCodeAttrMapGroupAttrDTOS();
      if(!CollectionUtils.isEmpty(codeAttrMapGroupAttrDTOS)){
      ExecGroupCodePortDataDTO execGroupCodePortDataDTO = new ExecGroupCodePortDataDTO();
      createExportGroupCodeMapConfig(templateVO, execGroupCodePortDataDTO);//组织数据
      List<CodeAndGroupCodeAttrMappingDTO> codeAttrMapGroupAttrDTOS = execGroupCodePortDataDTO.getCodeAttrMapGroupAttrDTOS();
      if (CollectionUtils.isEmpty(codeAttrMapGroupAttrDTOS)) {
         throw new ServiceException("集团属性映射未配置");
      }
      Map<String, CodeAndGroupCodeAttrMappingDTO> codeSystemObjectMap = codeAttrMapGroupAttrDTOS.stream().filter(codeAttrMappingDTO -> codeAttrMappingDTO != null && StringUtils.isNotBlank(codeAttrMappingDTO.getSourceAttrName())).collect(Collectors.toList()).stream().collect(Collectors.toMap(s -> s.getSourceAttrName(), t -> t));
      SheetDataSet dataSet= sheetDataSetList.get(0);
      SheetDataSet dataSet = sheetDataSetList.get(0);
      List<String> titleRowData = dataSet.getColName();
      Map<Integer/**列号**/,String/**字段的名称**/> fieldIndexMap = new HashMap<>();
      getGroupCodeFieldIndexMap(titleRowData,codeAttrMapGroupAttrDTOS,fieldIndexMap);
      Map<Integer/**列号**/, String/**字段的名称**/> fieldIndexMap = new HashMap<>();
      getGroupCodeFieldIndexMap(titleRowData, codeAttrMapGroupAttrDTOS, fieldIndexMap);
      //需要判断是否所有的属性都在模板上了
      List<CodeClassifyTemplateAttrVO> unExistAttrVOs = attrVOS.stream().filter(s -> !fieldIndexMap.containsValue(s.getId().toLowerCase(Locale.ROOT))
         && com.alibaba.cloud.commons.lang.StringUtils.isBlank(s.getComponentRule()) && com.alibaba.cloud.commons.lang.StringUtils.isBlank(s.getClassifyInvokeAttr())//组合规则和分类注入确实没给用户导出去
      ).collect(Collectors.toList());
      if(!CollectionUtils.isEmpty(unExistAttrVOs)){
         String message=unExistAttrVOs.stream().map(CodeClassifyTemplateAttrVO::getName).collect(Collectors.joining(SERIAL_UNIT_SPACE));
         throw new VciBaseException("【" + message + "】这些属性在excel中没有找到");
      }
      /**    List<CodeClassifyTemplateAttrVO> unExistAttrVOs = attrVOS.stream().filter(s -> !fieldIndexMap.containsValue(s.getId().toLowerCase(Locale.ROOT))
       && com.alibaba.cloud.commons.lang.StringUtils.isBlank(s.getComponentRule()) && com.alibaba.cloud.commons.lang.StringUtils.isBlank(s.getClassifyInvokeAttr())//组合规则和分类注入确实没给用户导出去
       ).collect(Collectors.toList());
       if(!CollectionUtils.isEmpty(unExistAttrVOs)){
       String message=unExistAttrVOs.stream().map(CodeClassifyTemplateAttrVO::getName).collect(Collectors.joining(SERIAL_UNIT_SPACE));
       throw new VciBaseException("【" + message + "】这些属性在excel中没有找到");
       }**/
      List<ClientBusinessObject> cboList = new ArrayList<>();
      List<SheetRowData> rowDataList = dataSet.getRowData();
      getExportGroupCodeDatas(fieldIndexMap,rowDataList,cboList);//构建数据对象
      List<String> codeList= cboList.stream().map(ClientBusinessObject::getId).collect(Collectors.toList());
      List<Map<String,String>>dataList=new ArrayList<>();
      getDatas(classifyFullInfo,templateVO,execGroupCodePortDataDTO.getFieldList(),dataList,codeList);
      //查询系统中存在
      if(!CollectionUtils.isEmpty(dataList)){
      getExportGroupCodeDatas(fieldIndexMap, rowDataList, cboList);//构建数据对象
      List<String> codeList = cboList.stream().map(ClientBusinessObject::getId).collect(Collectors.toList());
      List<Map<String, String>> dataList = new ArrayList<>();
      Map<String, String> errorMap = new ConcurrentHashMap<>();
      batchSwitchCheckExist(errorMap, cboList, classifyFullInfo, templateVO, execGroupCodePortDataDTO, fieldIndexMap);
      //判断必输项
      batchCheckRequiredAttrOnOrder(templateVO, cboList, errorMap);
      //   //优先校验编码是否存在
      //   batchCheckIdExistOnOrder(templateVO, cboList, errorMap);
      //boolean
      reSwitchBooleanAttrOnOrder(attrVOS, cboList);
      // 枚举的内容需要根据名称转换为枚举的值
      batchSwitchEnumAttrOnOrder(attrVOS, cboList, errorMap);
      batchSwitchReferAttrOnOrder(attrVOS, cboList, errorMap);
      //6.处理分类注入
      batchSwitchClassifyAttrOnOrder(attrVOS, cboList, classifyFullInfo, false);
      //设置默认值
      batchSwitchAttrDefault(attrVOS, cboList);
      //7.处理组合规则
      batchSwitchComponentAttrOnOrder(attrVOS, cboList);
      //4.校验规则
      batchCheckVerifyOnOrder(attrVOS, cboList, errorMap);
      //6.时间的,必须统一为yyyy-MM-dd HH:mm:ss
      batchSwitchDateAttrOnOrder(attrVOS, cboList, errorMap);
      //3.判断关键属性
      CodeImportResultVO keyResultVO = batchCheckKeyAttrOnOrder(classifyFullInfo, templateVO, cboList, true, errorMap);
      Set<String> selfRepeatRowIndexList = keyResultVO.getSelfRepeatRowIndexList();
      Set<String> keyAttrRepeatRowIndexList = keyResultVO.getKeyAttrRepeatRowIndexList();
      if (!CollectionUtils.isEmpty(selfRepeatRowIndexList)) {
         selfRepeatRowIndexList.stream().forEach(rowIndex -> {
            errorMap.put(rowIndex, errorMap.getOrDefault(rowIndex, "") + String.format(";传入的数据中关键属性重复[%s],[%s];", keyResultVO.getKeyAttrRuleInfo(), keyResultVO.getSynonymRuleInfo()));
            // errorMap.put(rowIndex, errorMap.getOrDefault(rowIndex, "") + ";在当前excel文件中关键属性重复");
         });
      }
      return "";
      if (!CollectionUtils.isEmpty(keyAttrRepeatRowIndexList)) {
         keyAttrRepeatRowIndexList.stream().forEach(rowIndex -> {
            errorMap.put(rowIndex, errorMap.getOrDefault(rowIndex, "") + String.format("关键属性与系统中的重复[%s],[%s];", keyResultVO.getKeyAttrRuleInfo(), keyResultVO.getSynonymRuleInfo()));
            // errorMap.put(rowIndex, "关键属性与系统中的重复;" + errorMap.getOrDefault(rowIndex, ""));
         });
      }
      Map<String, List<WriteExcelData>> shetNameMap = new HashMap<>();
      createWriteExcelData(rowDataList, errorMap, new ArrayList<>(), titleRowData, shetNameMap, templateVO);
      String excelFileName = "";
      if (errorMap.size() == 0) {
         try {
            String btmTypeId = classifyFullInfo.getTopClassifyVO().getBtmTypeId();
            List<BaseModel> oldCbos = execGroupCodePortDataDTO.getOldList();
            List<BaseModel> newCbos = new ArrayList<>();
            // 修改版次号
            engineService.updateBatchByBaseModel(btmTypeId, oldCbos);
            List<CodeAllCode> codeAllCodeList = new ArrayList<>();
            final BladeUser user = AuthUtil.getUser();
            cboList.stream().forEach(clientBusinessObject -> {
               BaseModel newBaseModel = new BaseModel();
               DefaultAttrAssimtUtil.copplyDefaultAttrAssimt(clientBusinessObject.getData(), newBaseModel, false, user);
               newCbos.add(newBaseModel);
            });
            // 插入新的数据
            engineService.insertBatchByType(btmTypeId, newCbos);
            codeAllCodeService.saveOrUpdateBatch(execGroupCodePortDataDTO.getCodeAllCodeList());
            engineService.batchSaveSelectChar(templateVO, newCbos);
            // 记录数据更改日志
            saveLogUtil.operateLog("数据更改", false, StringUtil.format("{}\n修改为:\n{}", JSON.toJSONString(oldCbos), JSON.toJSONString(newCbos)));
         } catch (Exception vciError) {
            // 记录数据更改报错时的日志
            saveLogUtil.operateLog("数据更改", true, vciError.toString());
            throw new VciBaseException("数据更改保存出错了", new String[0], vciError);
         }
      } else {
         excelFileName = LocalFileUtil.getDefaultTempFolder() + File.separator + "错误信息.xls";
         WriteExcelOption eo = new WriteExcelOption();
         shetNameMap.forEach((shetName, errorDataList) -> {
            eo.addSheetDataList(shetName, errorDataList);
         });
         try {
            new File(excelFileName).createNewFile();
         } catch (IOException e) {
            throw new VciBaseException(LangBaseUtil.getErrorMsg(e));
         }
         ExcelUtil.writeDataToFile(excelFileName, eo);
      }
      return excelFileName;
   }
   public void batchSwitchCheckExist(Map<String, String> errorMap, List<ClientBusinessObject> cboList, CodeClassifyFullInfoBO classifyFullInfo, CodeClassifyTemplateVO templateVO, ExecGroupCodePortDataDTO execGroupCodePortDataDTO, Map<Integer/**列号**/, String/**字段的名称**/> fieldIndexMap) {
      List<BaseModel> oldBaseModelList = new ArrayList<>();
      List<CodeAllCode> codeAllCodeList = new ArrayList<>();
      final BladeUser user = AuthUtil.getUser();
      cboList.stream().forEach(clientBusinessObject -> {
         String code = clientBusinessObject.getId();
         String rowIndex = clientBusinessObject.getAttributeValue(IMPORT_ROW_INDEX);
         List<Map<String, String>> dataList = new ArrayList<>();
         List<String> fieldList = execGroupCodePortDataDTO.getFieldList();
         getDatas(classifyFullInfo, templateVO, execGroupCodePortDataDTO.getFieldList(), dataList, Arrays.asList(code));
         DefaultAttrAssimtUtil.mapToLowerCase(dataList, true);
         if (!CollectionUtils.isEmpty(dataList)) {
            Map<String, String> newDataMap = new HashMap<>();//将新对象属性暂时存储在Map<>
            newDataMap.putAll(clientBusinessObject.getData());
            Map<String, String> dataMap = dataList.get(0);
            BaseModel oldBaseModel = new BaseModel();
            DefaultAttrAssimtUtil.copplyDefaultAttrAssimt(dataMap, oldBaseModel, false, user);
            String oldOid = oldBaseModel.getOid();
            clientBusinessObject.setCopyFromVersion(oldOid);
            clientBusinessObject.setAttributeValueWithNoCheck("copyfromversion", oldOid);
            String oid = VciBaseUtil.getPk();
            clientBusinessObject.setOid(oid);
            clientBusinessObject.setAttributeValueWithNoCheck("oid", oid);
            clientBusinessObject.setBtmname(oldBaseModel.getBtmname());
            clientBusinessObject.setAttributeValueWithNoCheck("btmname", oldBaseModel.getBtmname());
            clientBusinessObject.setLastR("1");
            clientBusinessObject.setAttributeValueWithNoCheck("lastr", "1");
            clientBusinessObject.setFirstR("1");
            clientBusinessObject.setAttributeValueWithNoCheck("firstr", "1");
            clientBusinessObject.setFirstV("1");
            clientBusinessObject.setAttributeValueWithNoCheck("firstv", "1");
            clientBusinessObject.setLastV("1");
            clientBusinessObject.setAttributeValueWithNoCheck("lastv", "1");
            clientBusinessObject.setRevisionSeq(1);
            clientBusinessObject.setAttributeValueWithNoCheck("revisionseq", "1");
            clientBusinessObject.setVersionSeq(1);
            clientBusinessObject.setAttributeValueWithNoCheck("versionseq", "1");
            clientBusinessObject.setRevisionRule(oldBaseModel.getRevisionRule());
            clientBusinessObject.setAttributeValueWithNoCheck("revisionrule", oldBaseModel.getRevisionRule());
            clientBusinessObject.setVersionRule(oldBaseModel.getRevisionRule());
            clientBusinessObject.setAttributeValueWithNoCheck("versionrule", oldBaseModel.getVersionRule());
            clientBusinessObject.setVersionValue(oldBaseModel.getVersionValue());
            clientBusinessObject.setAttributeValueWithNoCheck("versionvalue", oldBaseModel.getVersionValue());
            clientBusinessObject.setLctid(oldBaseModel.getLctid());
            clientBusinessObject.setAttributeValueWithNoCheck("lctid", oldBaseModel.getLctid());
            clientBusinessObject.setId(oldBaseModel.getId());
            clientBusinessObject.setAttributeValueWithNoCheck("id", oldBaseModel.getId());
            clientBusinessObject.setName(oldBaseModel.getName());
            clientBusinessObject.setAttributeValueWithNoCheck("name", oldBaseModel.getName());
            clientBusinessObject.setLcStatus(CodeDefaultLC.RELEASED.getValue());
            clientBusinessObject.setAttributeValueWithNoCheck("lcstatus", CodeDefaultLC.RELEASED.getValue());
            clientBusinessObject.setDescription("导入集团码");
            clientBusinessObject.setAttributeValueWithNoCheck("description", "导入集团码");
            clientBusinessObject.setOwner("1");
            clientBusinessObject.setAttributeValueWithNoCheck("owner", "1");
            clientBusinessObject.setTenantId(AuthUtil.getTenantId());
            clientBusinessObject.setAttributeValueWithNoCheck("tenant_id", AuthUtil.getTenantId());
            clientBusinessObject.setCreator(oldBaseModel.getCreator());
            clientBusinessObject.setAttributeValueWithNoCheck("creator", oldBaseModel.getCreator());
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            clientBusinessObject.setCreateTime(oldBaseModel.getCreateTime());
            clientBusinessObject.setAttributeValueWithNoCheck("createtime", formatter.format(oldBaseModel.getCreateTime()));
            clientBusinessObject.setLastModifier(AuthUtil.getUserAccount());
            clientBusinessObject.setAttributeValueWithNoCheck("lastmodifier", AuthUtil.getUserAccount());
            clientBusinessObject.setCreateTime(new Date());
            clientBusinessObject.setAttributeValueWithNoCheck("lastmodifytime", formatter.format(new Date()));
            clientBusinessObject.setRevisionValue(String.valueOf(Integer.parseInt(oldBaseModel.getRevisionValue()) + 1));
            clientBusinessObject.setRevisionOid(oldBaseModel.getRevisionOid());
            clientBusinessObject.setAttributeValueWithNoCheck("revisionoid", oldBaseModel.getRevisionOid());
            clientBusinessObject.setAttributeValueWithNoCheck("revisionvalue", String.valueOf(Integer.parseInt(oldBaseModel.getRevisionValue()) + 1));
            clientBusinessObject.setNameOid(oldBaseModel.getNameOid());
            clientBusinessObject.setAttributeValueWithNoCheck("nameoid", oldBaseModel.getNameOid());
            clientBusinessObject.setAttributeValueWithNoCheck(CODE_CLASSIFY_OID_FIELD, oldBaseModel.getData().getOrDefault(CODE_CLASSIFY_OID_FIELD, ""));
            clientBusinessObject.setAttributeValueWithNoCheck(CODE_FULL_PATH_FILED, oldBaseModel.getData().getOrDefault(CODE_FULL_PATH_FILED, ""));
            clientBusinessObject.setAttributeValueWithNoCheck(CODE_TEMPLATE_OID_FIELD, oldBaseModel.getData().getOrDefault(CODE_TEMPLATE_OID_FIELD, ""));
            clientBusinessObject.setTs(new Date());
            clientBusinessObject.setAttributeValueWithNoCheck("ts", formatter.format(new Date()));
            oldBaseModel.setLastV("0");
            oldBaseModel.getData().put("lastv", "0");
            oldBaseModelList.add(oldBaseModel);
            List<CodeAllCode> oldCodeAllCodeList = codeAllCodeService.selectByWrapper(Wrappers.<CodeAllCode>query().lambda().eq(CodeAllCode::getId, code));
            CodeAllCode codeAllCode = new CodeAllCode();
            if (!CollectionUtils.isEmpty(oldCodeAllCodeList)) {
               codeAllCode = oldCodeAllCodeList.get(0);
               codeAllCode.setId(code);
               codeAllCode.setLcStatus(CodeDefaultLC.RELEASED.getValue());
               codeAllCode.setCreateCodeOid(clientBusinessObject.getOid());
               codeAllCode.setCreateCodeBtm(clientBusinessObject.getBtmname());
               codeAllCode.setLastModifyTime(new Date());
               codeAllCode.setLastModifier(AuthUtil.getUserAccount());
               codeAllCodeList.add(codeAllCode);
               if (!oldBaseModel.getLcStatus().equals(CodeDefaultLC.RELEASED.getValue()) || !codeAllCode.getLcStatus().equals(CodeDefaultLC.RELEASED.getValue())) {
                  errorMap.put(rowIndex, "第" + rowIndex + "行,在系统中数据不是发布状态");
               }
            } else {
               errorMap.put(rowIndex, "第" + rowIndex + "行,在系统中未查询到相应的码值数据");
            }
            //除去默认的属性.还有只有表单显示的字段才导入
            List<CodeClassifyTemplateAttrVO> attrVOS = templateVO.getAttributes().stream().filter(s -> !fieldIndexMap.containsValue(s.getId()) &&
               ((Func.isNotEmpty(s.getClassifyInvokeAttr()) || Func.isNotEmpty(s.getClassifyInvokeAttrName())) || VciBaseUtil.getBoolean(s.getFormDisplayFlag()))
            ).collect(Collectors.toList());
            attrVOS.stream().forEach(codeClassifyTemplateAttrVO -> {//将不需要更改的默认字段或者不更改的属性复制到新的版本上
               String arrtibuteKey = codeClassifyTemplateAttrVO.getId();
               Map<String, String> attrDataMap = oldBaseModel.getData();
               if (attrDataMap.containsKey(arrtibuteKey)) {
                  String arrtibuteValue = attrDataMap.get(arrtibuteKey);
                  clientBusinessObject.setAttributeValueWithNoCheck(arrtibuteKey, arrtibuteValue);
               }
            });
         } else {
            errorMap.put(rowIndex, "第" + rowIndex + "行,在系统中未查询到相应的最新版数据");
         }
      });
      execGroupCodePortDataDTO.setOldList(oldBaseModelList);
      execGroupCodePortDataDTO.setCodeAllCodeList(codeAllCodeList);
   }
   /**
    *
    * @param fieldIndexMap
    * @param rowDataList
    * @param cboList
    */
   private void getExportGroupCodeDatas(Map<Integer,String> fieldIndexMap,List<SheetRowData> rowDataList,List<ClientBusinessObject>cboList){
   private void getExportGroupCodeDatas(Map<Integer, String> fieldIndexMap, List<SheetRowData> rowDataList, List<ClientBusinessObject> cboList) {
      rowDataList.stream().forEach(sheetRowData -> {
         sheetRowData.getData().forEach((index,value)->{
            ClientBusinessObject cbo=new ClientBusinessObject();
         String rowIndex = sheetRowData.getRowIndex();
         ClientBusinessObject cbo = new ClientBusinessObject();
         cbo.setAttributeValue(IMPORT_ROW_INDEX, rowIndex);
         sheetRowData.getData().forEach((index, value) -> {
            String field = fieldIndexMap.get(index);
            if (StringUtils.isBlank(field)) {
               throw new VciBaseException("第" + (index + 1) + "列的标题在系统中不存在");
@@ -5155,27 +5601,29 @@
            } catch (VciBaseException e) {
               log.error("设置属性的值错误", e);
            }
            cboList.add(cbo);
         });
         cboList.add(cbo);
      });
   }
   /***
    * 集团导出模板属性映射信息获取
    * @param templateVO
    * @param execGroupCodePortDataDTO
    */
   private void createExportGroupCodeMapConfig(CodeClassifyTemplateVO templateVO,ExecGroupCodePortDataDTO execGroupCodePortDataDTO){
      String classOid=templateVO.getCodeclassifyoid();
      String templateOid=templateVO.getOid();
      R r=mdmInterJtClient.list_mapping(classOid);
      if(r.isSuccess()){
         List<DockingPreAttrMappingVO>dockingPreAttrMappingVOList= (List<DockingPreAttrMappingVO>) r.getData();
         List<CodeAndGroupCodeAttrMappingDTO> codeAttrMapGroupAttrDTOS=new ArrayList<>();
         LinkedList<String> fieldList=new LinkedList<>();
         LinkedList<String> colNameList=new LinkedList<>();
   private void createExportGroupCodeMapConfig(CodeClassifyTemplateVO templateVO, ExecGroupCodePortDataDTO execGroupCodePortDataDTO) {
      String classOid = templateVO.getCodeclassifyoid();
      String templateOid = templateVO.getOid();
      R r = mdmInterJtClient.list_mapping(classOid);
      if (r.isSuccess()) {
         List<DockingPreAttrMappingVO> dockingPreAttrMappingVOList = (List<DockingPreAttrMappingVO>) r.getData();
         List<CodeAndGroupCodeAttrMappingDTO> codeAttrMapGroupAttrDTOS = new ArrayList<>();
         LinkedList<String> fieldList = new LinkedList<>();
         LinkedList<String> colNameList = new LinkedList<>();
         dockingPreAttrMappingVOList.stream().forEach(dockingPreAttrMappingVO -> {
            CodeAndGroupCodeAttrMappingDTO codeAndGroupCodeAttrMappingDTO=new CodeAndGroupCodeAttrMappingDTO();
            if(StringUtils.isNotBlank(dockingPreAttrMappingVO.getTargetAttrId())){
            CodeAndGroupCodeAttrMappingDTO codeAndGroupCodeAttrMappingDTO = new CodeAndGroupCodeAttrMappingDTO();
            // TODO:2024/4/16改成用key值判断
            if (StringUtils.isNotBlank(dockingPreAttrMappingVO.getTargetAttrKey())) {
               codeAndGroupCodeAttrMappingDTO.setDefaultValue(dockingPreAttrMappingVO.getDefaultValue());
               codeAndGroupCodeAttrMappingDTO.setMetaListId(dockingPreAttrMappingVO.getMetaListId());
               codeAndGroupCodeAttrMappingDTO.setSourceAttrKey(dockingPreAttrMappingVO.getSourceAttrKey());
@@ -5200,25 +5648,29 @@
    * @param codeAttrMapGroupAttrDTOS
    * @param fieldIndexMap
    */
   private void getGroupCodeFieldIndexMap(List<String> titleRowData,List<CodeAndGroupCodeAttrMappingDTO> codeAttrMapGroupAttrDTOS,Map<Integer/**列号**/,String/**字段的名称**/> fieldIndexMap){
   private void getGroupCodeFieldIndexMap(List<String> titleRowData, List<CodeAndGroupCodeAttrMappingDTO> codeAttrMapGroupAttrDTOS, Map<Integer/**列号**/, String/**字段的名称**/> fieldIndexMap) {
      Map<String, CodeAndGroupCodeAttrMappingDTO> codeSystemObjectMap = codeAttrMapGroupAttrDTOS.stream().filter(codeAttrMappingDTO -> codeAttrMappingDTO != null && StringUtils.isNotBlank(codeAttrMappingDTO.getSourceAttrName())).collect(Collectors.toList()).stream().collect(Collectors.toMap(s -> s.getSourceAttrName(), t -> t));
      for (int i = 0; i < titleRowData.size(); i++) {
         String title = titleRowData.get(i);
         CodeAndGroupCodeAttrMappingDTO codeAndGroupCodeAttrMappingDTO =codeSystemObjectMap.get(title.replace(KEY_ATTR_CHAR,"").replace(REQUIRED_CHAR,""));
         String id=codeAndGroupCodeAttrMappingDTO.getTargetAttrKey();
         if(com.alibaba.cloud.commons.lang.StringUtils.isBlank(id) && "集团码".equalsIgnoreCase(title)){
         String id = "";
         if ("集团码".equalsIgnoreCase(title)) {
            id = CODE_GROUP_FIELD;
         }
         if(com.alibaba.cloud.commons.lang.StringUtils.isBlank(id) && "企业编码".equalsIgnoreCase(title)){
         if ("企业编码".equalsIgnoreCase(title)) {
            id = CODE_FIELD;
         }
         if(com.alibaba.cloud.commons.lang.StringUtils.isNotBlank(id)){
            fieldIndexMap.put(i,id);
         if (codeSystemObjectMap.containsKey(title)) {
            CodeAndGroupCodeAttrMappingDTO codeAndGroupCodeAttrMappingDTO = codeSystemObjectMap.get(title.replace(KEY_ATTR_CHAR, "").replace(REQUIRED_CHAR, ""));
            id = codeAndGroupCodeAttrMappingDTO.getTargetAttrKey();
         }
         if (com.alibaba.cloud.commons.lang.StringUtils.isNotBlank(id)) {
            fieldIndexMap.put(i, id);
         }
      }
   }
   /***
    * 查询未有集团码的数据
    * @param classifyFullInfo
@@ -5226,30 +5678,30 @@
    * @param selectFieldList
    * @param dataList
    */
   private void getDatas(CodeClassifyFullInfoBO classifyFullInfo,CodeClassifyTemplateVO templateVO,LinkedList<String> selectFieldList,List<Map<String,String>>dataList,List<String> codeList ){
   private void getDatas(CodeClassifyFullInfoBO classifyFullInfo, CodeClassifyTemplateVO templateVO, LinkedList<String> selectFieldList, List<Map<String, String>> dataList, List<String> codeList) {
      //先查询数据
      String btmTypeId = classifyFullInfo.getTopClassifyVO().getBtmTypeId();
      String codeClassifyOid=classifyFullInfo.getCurrentClassifyVO().getOid();
      Map<String, String> conditionMap=new HashMap<>();
      if(conditionMap == null){
      String codeClassifyOid = classifyFullInfo.getCurrentClassifyVO().getOid();
      Map<String, String> conditionMap = new HashMap<>();
      if (conditionMap == null) {
         conditionMap = new HashMap<>();
      }
      if(conditionMap.containsKey(VciQueryWrapperForDO.OID_FIELD)){
         conditionMap.put(VciQueryWrapperForDO.OID_FIELD,QueryOptionConstant.IN + "(" + VciBaseUtil.toInSql(conditionMap.get(VciQueryWrapperForDO.OID_FIELD)) + ")");
      if (conditionMap.containsKey(VciQueryWrapperForDO.OID_FIELD)) {
         conditionMap.put(VciQueryWrapperForDO.OID_FIELD, QueryOptionConstant.IN + "(" + VciBaseUtil.toInSql(conditionMap.get(VciQueryWrapperForDO.OID_FIELD)) + ")");
      }
      if(!CollectionUtils.isEmpty(codeList)){
         conditionMap.put("id_in",VciBaseUtil.array2String(codeList.toArray(new String[]{})));
      if (!CollectionUtils.isEmpty(codeList)) {
         conditionMap.put("id_in", VciBaseUtil.array2String(codeList.toArray(new String[]{})));
      }
      conditionMap.put("codeclsfpath","*" + codeClassifyOid + "*");
      conditionMap.put("codeclsfpath", "*" + codeClassifyOid + "*");
      conditionMap.put("groupcode_null", "null");
      conditionMap.put("lastr", "1");
      conditionMap.put("lastv", "1");
      R<List<BtmTypeVO>> listR = btmTypeClient.selectByIdCollection(Arrays.asList(btmTypeId));
      String tableName = "";
      if(listR.isSuccess() && !listR.getData().isEmpty()){
         tableName = Func.isNotBlank(listR.getData().get(0).getTableName()) ? listR.getData().get(0).getTableName():VciBaseUtil.getTableName(btmTypeId);
      }else{
      if (listR.isSuccess() && !listR.getData().isEmpty()) {
         tableName = Func.isNotBlank(listR.getData().get(0).getTableName()) ? listR.getData().get(0).getTableName() : VciBaseUtil.getTableName(btmTypeId);
      } else {
         tableName = VciBaseUtil.getTableName(btmTypeId);
      }
      PageHelper pageHelper = new PageHelper();
@@ -5258,14 +5710,14 @@
      pageHelper.addDefaultDesc("createTime");
      DataGrid<Map<String, String>> dataGrid = engineService.queryGrid(btmTypeId, templateVO, conditionMap, pageHelper);
      //转换数据
      if(!CollectionUtils.isEmpty(dataGrid.getData())){
      if (!CollectionUtils.isEmpty(dataGrid.getData())) {
         dataList.addAll(dataGrid.getData());
      }
      //封装查询出来的数据
      engineService.wrapperData(dataList, templateVO, selectFieldList,false);
      engineService.wrapperData(dataList, templateVO, selectFieldList, false);
      //modify by weidy@2022-09-27
      //因为在列表和表单的显示的时候,我们的开关类型页面会处理,但是在导出的时候,我们需要将true和false都替换成中文
      engineService.wrapperBoolean(dataList,templateVO);
      log.info("导出模板的数据条目数:"+dataList.size());
      engineService.wrapperBoolean(dataList, templateVO);
      log.info("导出模板的数据条目数:" + dataList.size());
   }
}