zhangxp
2023-06-05 ac9f1681a2aa83c04272a266d289101a5cbed862
Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/service/impl/MdmIOServiceImpl.java
@@ -1,381 +1,611 @@
package com.vci.ubcs.code.service.impl;
import com.alibaba.nacos.common.utils.StringUtils;
import com.vci.ubcs.code.bo.CodeClassifyFullInfoBO;
import com.vci.ubcs.code.dto.CodeOrderDTO;
import com.vci.ubcs.code.service.ICodeClassifyService;
import com.vci.ubcs.code.service.MdmEngineService;
import com.vci.ubcs.code.service.MdmIOService;
import com.vci.ubcs.code.vo.pagemodel.*;
import com.vci.ubcs.code.vo.webserviceModel.attrmap.DataObjectVO;
import com.vci.ubcs.code.vo.webserviceModel.attrmap.RowDatas;
import com.vci.ubcs.code.vo.webserviceModel.result.xml.XMLResultDataObjectDetailDO;
import com.vci.ubcs.starter.bo.WriteExcelData;
import com.vci.ubcs.starter.exception.VciBaseException;
import com.vci.ubcs.starter.poi.bo.ReadExcelOption;
import com.vci.ubcs.starter.poi.bo.SheetDataSet;
import com.vci.ubcs.starter.poi.bo.SheetRowData;
import com.vci.ubcs.starter.poi.bo.WriteExcelOption;
import com.vci.ubcs.starter.poi.util.ExcelUtil;
import com.vci.ubcs.starter.util.LocalFileUtil;
import com.vci.ubcs.starter.web.enumpck.VciFieldTypeEnum;
import com.vci.ubcs.starter.web.pagemodel.DataGrid;
import com.vci.ubcs.starter.web.pagemodel.KeyValue;
import com.vci.ubcs.starter.web.util.VciBaseUtil;
import com.vci.ubcs.starter.web.util.VciDateUtil;
import lombok.AllArgsConstructor;
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.RichTextString;
import org.apache.poi.ss.usermodel.Workbook;
import org.springblade.core.redis.cache.BladeRedis;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import java.io.File;
import java.util.*;
import java.util.stream.Collectors;
import static com.alibaba.druid.util.FnvHash.Constants.LIMIT;
import static com.vci.ubcs.code.constant.MdmEngineConstant.*;
import static com.vci.ubcs.starter.poi.util.ExcelUtil.KEY_ATTR_CHAR;
import static com.vci.ubcs.starter.poi.util.ExcelUtil.REQUIRED_CHAR;
@AllArgsConstructor
@Service
public class MdmIOServiceImpl implements MdmIOService {
//
// /**
//  * 主题库分类的服务
//  */
// @Resource
// private ICodeClassifyService classifyService;
//
// /**
//  * 模板的服务
//  */
// @Resource
// private CodeClstemplateServiceImpl templateService;
//
// /**
//  * 主数据引擎的服务
//  */
// @Resource
// private MdmEngineService engineService;
//
// /**
//  * 生成导入的文件
//  *
//  * @param codeClassifyOid 分类的主键
//  * @param isHistory 是否历史数据导入
//  * @return excel的文件地址
//  */
// @Override
// public String createImportExcel(String codeClassifyOid, boolean isHistory) {
//    List<CodeClstemplateVO> templateVOList=new ArrayList<>();
//
//    VciBaseUtil.alertNotNull("导出模板","导出的配置",codeClassifyOid,"主题库分类的主键");
//
//    CodeClassifyVO codeClassifyVO = classifyService.getObjectByOid(codeClassifyOid);
//
//    if(isHistory){
//       templateVOList= templateService.childTemplates(codeClassifyOid);
//    }else{
//       //找模板
//       CodeClstemplateVO templateVO = engineService.getUsedTemplateByClassifyOid(codeClassifyOid);
//       templateVOList.add(templateVO);
   /**
    * 主题库分类的服务
    */
   @Resource
   private ICodeClassifyService classifyService;
   /**
    * 模板的服务
    */
   @Resource
   private CodeClstemplateServiceImpl templateService;
   /**
    * 主数据引擎的服务
    */
   @Resource
   private MdmEngineService engineService;
   private final BladeRedis bladeRedis;
   /**
    * 生成导入的文件
    *
    * @param codeClassifyOid 分类的主键
    * @param isHistory 是否历史数据导入
    * @return excel的文件地址
    */
   @Override
   public String createImportExcel(String codeClassifyOid, boolean isHistory) {
      List<CodeClassifyTemplateVO> templateVOList=new ArrayList<>();
      VciBaseUtil.alertNotNull("导出模板","导出的配置",codeClassifyOid,"主题库分类的主键");
      CodeClassifyVO codeClassifyVO = classifyService.getObjectByOid(codeClassifyOid);
      if(isHistory){
         templateVOList= templateService.childTemplates(codeClassifyOid);
      }else{
         //找模板
         CodeClassifyTemplateVO templateVO = engineService.getUsedTemplateByClassifyOid(codeClassifyOid);
         templateVOList.add(templateVO);
      }
      WriteExcelOption eo = new WriteExcelOption();
      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);
         CodeClassifyTemplateVO codeClassifyTemplateVO = new CodeClassifyTemplateVO();
         BeanUtils.copyProperties(templateVO,codeClassifyTemplateVO);
         //组合格式的不导入,
         // 枚举的提供序列的选择
         //时间全部统一为yyyy-MM-dd HH:mm:ss
         //参照的自行输入名称
         //分类注入的不用,都是导入后自动处理的
         //编码,状态等字段不导入
         List<CodeClassifyTemplateAttrVO> templateAttrVOS = codeClassifyTemplateVO.getAttributes().stream().filter(s ->
            !DEFAULT_ATTR_LIST.contains(s.getId())
               && StringUtils.isBlank(s.getComponentRule())
               && StringUtils.isBlank(s.getClassifyInvokeAttr())
               && (isHistory || VciBaseUtil.getBoolean(s.getFormDisplayFlag()))
         ).collect(Collectors.toList());
         if(CollectionUtils.isEmpty(templateAttrVOS)){
            throw new VciBaseException("模板没有配置任何【表单显示】为【是】的属性");
         }
         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():"企业编码"));
         }
         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);
            if(StringUtils.isNotBlank(attrVO.getCodeDateFormat())
               || VciFieldTypeEnum.VTDateTime.name().equalsIgnoreCase(attrVO.getAttributeDataType())
               || VciFieldTypeEnum.VTDate.name().equalsIgnoreCase(attrVO.getAttributeDataType())
               ||VciFieldTypeEnum.VTTime.name().equalsIgnoreCase(attrVO.getAttributeDataType())){
               excelData.setDateFormat(VciDateUtil.DateTimeFormat);
            }
            if(text instanceof RichTextString){
               excelData.setFontColor(String.valueOf(HSSFColor.HSSFColorPredefined.RED.getIndex()));
            }
            excelDataList.add(excelData);
            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->{
                     enumValueList.add(kv.getValue());
                  });
               }
               //默认加1万条
               WriteExcelData ed = new WriteExcelData(1,colIndex,"");
               ed.setRowTo(100);
               ed.setColTo(colIndex);
               ed.setValidation(true);
               ed.setValidationDataList(enumValueList);
               ed.setValidationErrorMsg("请在序列中选择正确的值");
               excelDataList.add(ed);
            }
            if(VciFieldTypeEnum.VTBoolean.name().equalsIgnoreCase(attrVO.getAttributeDataType())){
               List<String> booleanList = new ArrayList<>();
               booleanList.add("是");
               booleanList.add("否");
               //默认加1万条
               WriteExcelData ed = new WriteExcelData(1,colIndex,"");
               ed.setRowTo(100);
               ed.setColTo(colIndex);
               ed.setValidation(true);
               ed.setValidationDataList(booleanList);
               ed.setValidationErrorMsg("请在序列中选择正确的值");
               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()));
      }
      String excelName = LocalFileUtil.getDefaultTempFolder() + File.separator + codeClassifyVO.getName() + (isHistory?"_历史数据导入模板.xls": "_导入模板.xls");
      eo.addSheetDataList(templateVOList.size()+"模板信息【请勿删除或移动】",tempEDList);
      ExcelUtil.writeDataToFile(excelName,eo);
      return excelName;
   }
   /**
    * 导出的时候封装必输和关键属性
    * @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())) {
            value += REQUIRED_CHAR;
         }
         if(VciBaseUtil.getBoolean(attrVO.getKeyAttrFlag())){
            value += KEY_ATTR_CHAR;
         }
         RichTextString ts = new HSSFRichTextString(value);
         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();
            font.setColor(HSSFColor.HSSFColorPredefined.BLUE.getIndex());
            ts.applyFont(font);
         }
         return ts;
      }
      return text;
   }
   /**
    * 批量申请编码数据
    *
    * @param orderDTO 编码申请信息,必须包含分类主键和码段的信息
    * @param file     excel文件的信息
    * @return  有错误信息的excel的文件
    */
   @Override
   public CodeImProtRusultVO batchImportCode(CodeOrderDTO orderDTO, File file) {
      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){
         throw new VciBaseException("没有读取到任何的数据");
      }
      if(sheetDataSetList.size()>LIMIT+1){
         throw new VciBaseException("为了保证系统的稳定性,请一次不要导入超过1万条的数据");
      }
      //先找到每一行的标题,然后根据标题来获取对应的属性
      SheetDataSet dataSet = sheetDataSetList.get(0);
      //找第一行,为了找标题
      CodeClassifyTemplateVO templateVO = engineService.getUsedTemplateByClassifyOid(orderDTO.getCodeClassifyOid());
      //校验模板是不是最新的
      checkTemplateSync(sheetDataSetList,templateVO,0);
      //先不用管属性是否都存在,先转换一下数据
      Map<String,String> errorMap = new HashMap<>();
      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)) {
//       codeImProtRusultVO.setFilePath(filePath);
//    }
//
//    WriteExcelOption eo = new WriteExcelOption();
//    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++){
//       CodeClstemplateVO  templateVO=templateVOList.get(j);
//       CodeClassifyTemplateVO codeClassifyTemplateVO = new CodeClassifyTemplateVO();
//       BeanUtils.copyProperties(templateVO,codeClassifyTemplateVO);
//       //组合格式的不导入,
//       // 枚举的提供序列的选择
//       //时间全部统一为yyyy-MM-dd HH:mm:ss
//       //参照的自行输入名称
//       //分类注入的不用,都是导入后自动处理的
//       //编码,状态等字段不导入
//       List<CodeClassifyTemplateAttrVO> templateAttrVOS = codeClassifyTemplateVO.getAttributes().stream().filter(s ->
//          !DEFAULT_ATTR_LIST.contains(s.getId())
//             && StringUtils.isBlank(s.getComponentRule())
//             && StringUtils.isBlank(s.getClassifyInvokeAttr())
//             && (isHistory || VciBaseUtil.getBoolean(s.getFormDisplayFlag()))
//       ).collect(Collectors.toList());
//
//       if(CollectionUtils.isEmpty(templateAttrVOS)){
//          throw new VciBaseException("模板没有配置任何【表单显示】为【是】的属性");
//       }
//       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():"企业编码"));
//       }
//       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);
//          if(StringUtils.isNotBlank(attrVO.getCodeDateFormat())
//             || VciFieldTypeEnum.VTDateTime.name().equalsIgnoreCase(attrVO.getAttributeDataType())
//             || VciFieldTypeEnum.VTDate.name().equalsIgnoreCase(attrVO.getAttributeDataType())
//             ||VciFieldTypeEnum.VTTime.name().equalsIgnoreCase(attrVO.getAttributeDataType())){
//             excelData.setDateFormat(VciDateUtil.DateTimeFormat);
//          }
//          if(text instanceof RichTextString){
//             excelData.setFontColor(String.valueOf(HSSFColor.HSSFColorPredefined.RED.getIndex()));
//          }
//          excelDataList.add(excelData);
//          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->{
//                   enumValueList.add(kv.getValue());
//                });
//             }
//             //默认加1万条
//             WriteExcelData ed = new WriteExcelData(1,colIndex,"");
//             ed.setRowTo(100);
//             ed.setColTo(colIndex);
//             ed.setValidation(true);
//             ed.setValidationDataList(enumValueList);
//             ed.setValidationErrorMsg("请在序列中选择正确的值");
//             excelDataList.add(ed);
//          }
//          if(VciFieldTypeEnum.VTBoolean.name().equalsIgnoreCase(attrVO.getAttributeDataType())){
//             List<String> booleanList = new ArrayList<>();
//
//             booleanList.add("是");
//             booleanList.add("否");
//             //默认加1万条
//             WriteExcelData ed = new WriteExcelData(1,colIndex,"");
//             ed.setRowTo(100);
//             ed.setColTo(colIndex);
//             ed.setValidation(true);
//             ed.setValidationDataList(booleanList);
//             ed.setValidationErrorMsg("请在序列中选择正确的值");
//             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()));
//    if(StringUtils.isNotBlank(redisUUid)){
//       codeImProtRusultVO.setRedisUuid(redisUUid);
//    }
//    String excelName = LocalFileUtil.getDefaultTempFolder() + File.separator + codeClassifyVO.getName() + (isHistory?"_历史数据导入模板.xls": "_导入模板.xls");
//    eo.addSheetDataList(templateVOList.size()+"模板信息【请勿删除或移动】",tempEDList);
//    ExcelUtil.writeDataToFile(excelName,eo);
//    return excelName;
// }
      return null;
//    return codeImProtRusultVO;
   }
   /**
    * 校验模板是否为同步的
    * @param sheetDataSetList excel里的内容
    * @param templateVO 模板的信息
    */
   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);
         //templateOidInExcel = sheetDataSetList.get(sheetDataSetList.size()-1).getColName().get(sheetDataSetList.size()-i);
      }
       /* 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(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文件里有【模板信息-请勿移动或删除】的工作表,且确保每次导入都是先下载的导入模板后添加的数据");
      }
   }
   /***
    * 批量处理申请数据
    * @param orderDTO
    * @param templateVO
    * @param dataSet
    * @return
    */
   private String batchImportCodes(CodeOrderDTO orderDTO,CodeClassifyTemplateVO templateVO,SheetDataSet dataSet,Map<String,String> errorMap,boolean isEnumType){
      List<String> codeList=new ArrayList<>();
//    CodeClassifyFullInfoBO classifyFullInfo = classifyService.getClassifyFullInfo(orderDTO.getCodeClassifyOid());
      //规则的主键需要去获取
//    CodeRuleVO ruleVO = engineService.getCodeRuleByClassifyFullInfo(classifyFullInfo);
//    //1.判断规则中除了流水码段,是否有其他码段
//    engineService.checkSecValueOnOrder(ruleVO,orderDTO);
//    List<SheetRowData> rowDataList = dataSet.getRowData();
//
// /**
//  * 导出的时候封装必输和关键属性
//  * @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())) {
//          value += REQUIRED_CHAR;
//    //除去默认的属性.还有只有表单显示的字段才导入
//    List<CodeClassifyTemplateAttrVO> attrVOS = templateVO.getAttributes().stream().filter(s ->
//       !DEFAULT_ATTR_LIST.contains(s.getId()) && VciBaseUtil.getBoolean(s.getFormdisplayflag())
//    ).collect(Collectors.toList());
//    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);
//
//    //需要判断是否所有的属性都在模板上了
//    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)){
//       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);
//
//    //都转换完了。需要批量检查
//    //如果出错了,我们依然执行有效的数据,无效的数据写回到excel中
//    //2.判断必输项。。需要全部的属性,如果是必输,但是表单里面不显示的,只能是分类注入或者组合规则
//    batchCheckRequiredAttrOnOrder(templateVO,cboList,errorMap);
//    //3.判断关键属性
//    CodeImportResultVO keyResultVO = batchCheckKeyAttrOnOrder(classifyFullInfo, templateVO, cboList);
//    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(keyAttrRepeatRowIndexList)){
//       keyAttrRepeatRowIndexList.stream().forEach(rowIndex->{
//          errorMap.put(rowIndex,errorMap.getOrDefault(rowIndex,"") + ";关键属性与系统中的重复" );
//       });
//    }
//    //分类注入
//    batchSwitchClassifyAttrOnOrder(attrVOS,cboList,classifyFullInfo,false);
//    //boolean
//    reSwitchBooleanAttrOnOrder(attrVOS,cboList);
//    //4.校验规则
//    batchCheckVerifyOnOrder(attrVOS, cboList,errorMap);
//    if(isEnumType) {//是否需要校验枚举/参照
//       //5.校验枚举是否正确
//       batchSwitchEnumAttrOnOrder(attrVOS, cboList, errorMap);
//       //7.处理参照的情况
//       batchSwitchReferAttrOnOrder(attrVOS,cboList,errorMap);
//    }
//    //6.时间格式的验证
//    //6.时间的,必须统一为yyyy-MM-dd HH:mm:ss
//    batchSwitchDateAttrOnOrder(attrVOS,cboList,errorMap);
//    //最后弄组合规则
//    batchSwitchComponentAttrOnOrder(attrVOS,cboList);
//    String uuid=redisService.getUUIDEveryDay();
//    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);
//    }
//    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)) {
//          redisService.setCacheList(uuid + "-resemble-data", dataResembleVOS);
//          createRedisDatas(uuid + "-resemble",templateVO, rowIndexCboMap, dataSet, fieldIndexMap, resembleMap, false);
//       }
//       if(VciBaseUtil.getBoolean(attrVO.getKeyAttrFlag())){
//          value += KEY_ATTR_CHAR;
//    }
//    //排除错误的,剩下正确的
//    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;
//    }
//    createRedisByCodeClassify(uuid + "-class",templateVO,dataSet,fieldIndexMap,false);
//    if(newErrorMap.size()>0) {
//       createRedisDatas(uuid + "-ok",templateVO, rowIndexCboMap, dataSet, fieldIndexMap, newErrorMap,true);
//    }else {
//       uuid="";
//       //要把以上的错误的都抛出后,再继续处理时间和组合规则
//       needSaveCboList = cboList.stream().filter(cbo -> {
//          String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX);
//          return !newErrorMap.containsKey(rowIndex);
//       }).collect(Collectors.toList());
//       if (!CollectionUtils.isEmpty(needSaveCboList)) {
//          //9.我们处理业务数据
//          //生成编码的内容
//          codeList = productCodeService.productCodeAndSaveData(classifyFullInfo, templateVO, ruleVO, orderDTO.getSecDTOList(), needSaveCboList);
//          //如果是编码生成失败,则直接就失败了,其他的判断出来有错误的我们都统一返回到excel里面
//          engineService.batchSaveSelectChar(templateVO, needSaveCboList);
//       }
//       RichTextString ts = new HSSFRichTextString(value);
//       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();
//          font.setColor(HSSFColor.HSSFColorPredefined.BLUE.getIndex());
//          ts.applyFont(font);
//       }
//       return ts;
//    }
//    return text;
// }
//
//
// /**
//  * 批量申请编码数据
//  *
//  * @param orderDTO 编码申请信息,必须包含分类主键和码段的信息
//  * @param file     excel文件的信息
//  * @return  有错误信息的excel的文件
//  */
// @Override
// public CodeImProtRusultVO batchImportCode(CodeOrderDTO orderDTO, File file) {
//    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){
//       throw new VciBaseException("没有读取到任何的数据");
//    if(!isCreateUUid){
//       return uuid="";
//    }
//    if(sheetDataSetList.size()>LIMIT+1){
//       throw new VciBaseException("为了保证系统的稳定性,请一次不要导入超过1万条的数据");
//    }
//    //先找到每一行的标题,然后根据标题来获取对应的属性
//    SheetDataSet dataSet = sheetDataSetList.get(0);
//    //找第一行,为了找标题
//    CodeClstemplateVO templateVO = engineService.getUsedTemplateByClassifyOid(orderDTO.getCodeClassifyOid());
//
//    //校验模板是不是最新的
//    checkTemplateSync(sheetDataSetList,templateVO,0);
//    //先不用管属性是否都存在,先转换一下数据
//    Map<String,String> errorMap = new HashMap<>();
//    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)) {
////        codeImProtRusultVO.setFilePath(filePath);
////     }
////     if(StringUtils.isNotBlank(redisUUid)){
////        codeImProtRusultVO.setRedisUuid(redisUUid);
////     }
//    return null;
////     return codeImProtRusultVO;
// }
//
// /**
//  * 校验模板是否为同步的
//  * @param sheetDataSetList excel里的内容
//  * @param templateVO 模板的信息
//  */
// private void checkTemplateSync(List<SheetDataSet> sheetDataSetList,CodeClstemplateVO 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);
//       //templateOidInExcel = sheetDataSetList.get(sheetDataSetList.size()-1).getColName().get(sheetDataSetList.size()-i);
//    }
//       /* 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(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文件里有【模板信息-请勿移动或删除】的工作表,且确保每次导入都是先下载的导入模板后添加的数据");
//    }
//
// }
//
//
// /***
//  * 批量处理申请数据
//  * @param orderDTO
//  * @param templateVO
//  * @param dataSet
//  * @return
//  */
// private String batchImportCodes(CodeOrderDTO orderDTO,CodeClstemplateVO templateVO,SheetDataSet dataSet,Map<String,String> errorMap,boolean isEnumType){
//    List<String> codeList=new ArrayList<>();
////     CodeClassifyFullInfoBO classifyFullInfo = classifyService.getClassifyFullInfo(orderDTO.getCodeClassifyOid());
//    //规则的主键需要去获取
////     CodeRuleVO ruleVO = engineService.getCodeRuleByClassifyFullInfo(classifyFullInfo);
////     //1.判断规则中除了流水码段,是否有其他码段
////     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())
////     ).collect(Collectors.toList());
////     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);
////
////     //需要判断是否所有的属性都在模板上了
////     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)){
////        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);
////
////     //都转换完了。需要批量检查
////     //如果出错了,我们依然执行有效的数据,无效的数据写回到excel中
////     //2.判断必输项。。需要全部的属性,如果是必输,但是表单里面不显示的,只能是分类注入或者组合规则
////     batchCheckRequiredAttrOnOrder(templateVO,cboList,errorMap);
////     //3.判断关键属性
////     CodeImportResultVO keyResultVO = batchCheckKeyAttrOnOrder(classifyFullInfo, templateVO, cboList);
////     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(keyAttrRepeatRowIndexList)){
////        keyAttrRepeatRowIndexList.stream().forEach(rowIndex->{
////           errorMap.put(rowIndex,errorMap.getOrDefault(rowIndex,"") + ";关键属性与系统中的重复" );
////        });
////     }
////     //分类注入
////     batchSwitchClassifyAttrOnOrder(attrVOS,cboList,classifyFullInfo,false);
////     //boolean
////     reSwitchBooleanAttrOnOrder(attrVOS,cboList);
////     //4.校验规则
////     batchCheckVerifyOnOrder(attrVOS, cboList,errorMap);
////     if(isEnumType) {//是否需要校验枚举/参照
////        //5.校验枚举是否正确
////        batchSwitchEnumAttrOnOrder(attrVOS, cboList, errorMap);
////        //7.处理参照的情况
////        batchSwitchReferAttrOnOrder(attrVOS,cboList,errorMap);
////     }
////     //6.时间格式的验证
////     //6.时间的,必须统一为yyyy-MM-dd HH:mm:ss
////     batchSwitchDateAttrOnOrder(attrVOS,cboList,errorMap);
////     //最后弄组合规则
////     batchSwitchComponentAttrOnOrder(attrVOS,cboList);
////     String uuid=redisService.getUUIDEveryDay();
////     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);
////     }
////     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)) {
////           redisService.setCacheList(uuid + "-resemble-data", dataResembleVOS);
////           createRedisDatas(uuid + "-resemble",templateVO, rowIndexCboMap, dataSet, fieldIndexMap, resembleMap, false);
////        }
////     }
////     //排除错误的,剩下正确的
////     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;
////     }
////     createRedisByCodeClassify(uuid + "-class",templateVO,dataSet,fieldIndexMap,false);
////     if(newErrorMap.size()>0) {
////        createRedisDatas(uuid + "-ok",templateVO, rowIndexCboMap, dataSet, fieldIndexMap, newErrorMap,true);
////     }else {
////        uuid="";
////        //要把以上的错误的都抛出后,再继续处理时间和组合规则
////        needSaveCboList = cboList.stream().filter(cbo -> {
////           String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX);
////           return !newErrorMap.containsKey(rowIndex);
////        }).collect(Collectors.toList());
////        if (!CollectionUtils.isEmpty(needSaveCboList)) {
////           //9.我们处理业务数据
////           //生成编码的内容
////           codeList = productCodeService.productCodeAndSaveData(classifyFullInfo, templateVO, ruleVO, orderDTO.getSecDTOList(), needSaveCboList);
////           //如果是编码生成失败,则直接就失败了,其他的判断出来有错误的我们都统一返回到excel里面
////           engineService.batchSaveSelectChar(templateVO, needSaveCboList);
////        }
////     }
////     if(!isCreateUUid){
////        return uuid="";
////     }
////     return uuid;
//    return null;
// }
//    return uuid;
      return null;
   }
   @Override
   public List<CodeImportTemplateVO> gridclassifys(String redisOid) {
      List<CodeImportTemplateVO> codeImportTemplateVOs=new ArrayList<>();
      VciBaseUtil.alertNotNull(redisOid,"分类",redisOid,"分类缓存主键");
      List<CodeImportTemplateVO> redisServiceCacheObjects=bladeRedis.lRange(redisOid,0,-1);
      if(redisServiceCacheObjects!=null){
         codeImportTemplateVOs=  redisServiceCacheObjects;
      }
      return codeImportTemplateVOs;
   }
   /***
    * 从缓存里获取到需要导入的相关数据
    * @param codeClssifyOid
    * @param redisOid
    * @return
    */
   @Override
   public DataGrid<Map<String, String>> gridDatas(String codeClssifyOid, String redisOid) {
      VciBaseUtil.alertNotNull(redisOid,"导入相似数据",redisOid,"数据缓存主键");
      List<CodeImprotDataVO> codeImprotDataVOs = bladeRedis.lRange(redisOid+"-"+codeClssifyOid,0,-1);
//    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);
            }
         }
      }
      DataGrid<Map<String, String>> dataGrid = new DataGrid<>();
      List<Map<String, String>> dataList = new ArrayList<>();
      if(codeImprotDataVO!=null){
         dataList= codeImprotDataVO.getDatas();
      }
      dataGrid.setData(dataList);
      if (!CollectionUtils.isEmpty(dataList)) {
         dataGrid.setTotal(dataList.size());
      }
      return dataGrid;
   }
   /**
    *
    * @param oid
    * @param redisOid
    * @return
    */
   @Override
   public DataGrid<Map<String,String>> gridRowResemble(String oid,String redisOid){
      VciBaseUtil.alertNotNull(redisOid,"导入相似数据",redisOid,"数据缓存主键");
      List<DataResembleVO> codeImprotDataVOs = bladeRedis.lRange(redisOid,0,-1);;
      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();
         }
      }
      dataGrid.setData(dataList);
      if (!CollectionUtils.isEmpty(dataList)) {
         dataGrid.setTotal(dataList.size());
      }
      return dataGrid;
   }
   /**
    * 集成批量申请数据
    * @param orderDTO 分类的主键
    * @param dataObjectVO 数据信息
    * @param resultDataObjectDetailDOs 错误信息
    * @return 有错误信息的excel
    */
   @Override
   public void batchSyncApplyCode(CodeOrderDTO orderDTO, DataObjectVO dataObjectVO, LinkedList<XMLResultDataObjectDetailDO> resultDataObjectDetailDOs) {
      Map<String,String> errorMap=new HashMap<>();
      VciBaseUtil.alertNotNull(orderDTO,"编码申请相关的数据",orderDTO.getCodeClassifyOid(),"主题库分类主键");
      CodeClassifyFullInfoBO classifyFullInfo = classifyService.getClassifyFullInfo(orderDTO.getCodeClassifyOid());
      //规则的主键需要去获取
      CodeRuleVO ruleVO = engineService.getCodeRuleByClassifyFullInfo(classifyFullInfo);
      //1.判断规则中除了流水码段,是否有其他码段
      //engineService.checkSecValueOnOrder(ruleVO,orderDTO);
      //查询分类和模板
      //先找到每一行的标题,然后根据标题来获取对应的属性
      List<RowDatas> rowDataList = dataObjectVO.getRowData();
      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())
      ).collect(Collectors.toList());
      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);
      //需要判断是否所有的属性都在模板上了
      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)){
         throw new VciBaseException("【" + unExistAttrVOs.stream().map(CodeClassifyTemplateAttrVO::getName) + "】这些属性在excel中没有找到");
      }
      String fullPath = getFullPath(classifyFullInfo);
      // List<CodeClassifyProcessTempVO> codeClassifyProcessTempVOS=codeClassifyProcessTempService.listProcessTemplate(templateVO.getOid(),"code_cls_flow_use_order");
      boolean isProcess=false;
      //注释掉此处下面所有都按照不判断流程存储状态了
      /** if(!CollectionUtils.isEmpty(codeClassifyProcessTempVOS)){
       isProcess=true;
       }***/
      //List<ClientBusinessObject> cboList = new ArrayList<>();
      //Map<String,String> codeOidToSystemOidMap=new HashMap<>();//存储编码数据和集成系统数据oid对照映射
      //excelToCbo(classifyFullInfo,titleRowData,fieldIndexMap,rowDataList,templateVO,cboList,fullPath,isProcess,"create",errorMap,codeOidToSystemOidMap);
      //都转换完了。需要批量检查
      //如果出错了,我们依然执行有效的数据,无效的数据写回到excel中
      //2.判断必输项。。需要全部的属性,如果是必输,但是表单里面不显示的,只能是分类注入或者组合规则
   }
   @Override
   public void batchSyncEditDatas(CodeClassifyVO codeClassifyVO, DataObjectVO dataObjectVO, LinkedList<XMLResultDataObjectDetailDO> resultDataObjectDetailDOs) {
   }
   /**
    * 获取分类的全路径
    * @param classifyFullInfo 分类的全部信息
    * @return 全路径
    */
   private String getFullPath(CodeClassifyFullInfoBO classifyFullInfo){
      String fullPath = "";
      if(!CollectionUtils.isEmpty(classifyFullInfo.getParentClassifyVOs())){
         fullPath = classifyFullInfo.getParentClassifyVOs().stream().sorted(((o1, o2) -> o1.getDataLevel().compareTo(o2.getDataLevel())))
            .map(CodeClassifyVO::getOid).collect(Collectors.joining("##"));
      }else{
         fullPath = classifyFullInfo.getCurrentClassifyVO().getOid();
      }
      return fullPath;
   }
   /**
    * excel的标题上获取字段所在的位置
    * @param titleRowData 标题的内容
    * @param attrNameIdMap 模板中属性名称和英文的映射
    * @param 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)){
            id = CODE_CLASSIFY_OID_FIELD;
         }
         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)){
            id = CODE_FIELD;
         }
         if(com.alibaba.cloud.commons.lang.StringUtils.isNotBlank(id)){
            fieldIndexMap.put(i,id);
         }
      }
   }
}