xiejun
2023-08-12 4187374bbae66190e7eca6f42cc5e61cfae1637f
Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/service/impl/MdmIOServiceImpl.java
@@ -6,9 +6,9 @@
import com.vci.ubcs.code.bo.AttributeValue;
import com.vci.ubcs.code.bo.CodeClassifyFullInfoBO;
import com.vci.ubcs.code.bo.CodeTemplateAttrSqlBO;
import com.vci.ubcs.code.dto.CodeExportAttrDTO;
import com.vci.ubcs.code.dto.CodeOrderDTO;
import com.vci.ubcs.code.entity.CodeAllCode;
import com.vci.ubcs.code.entity.CodeClassify;
import com.vci.ubcs.code.enumpack.CodeDefaultLC;
import com.vci.ubcs.code.enumpack.CodeLevelTypeEnum;
import com.vci.ubcs.code.lifecycle.CodeAllCodeLC;
@@ -20,6 +20,7 @@
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.file.util.VciZipUtil;
import com.vci.ubcs.omd.feign.IBtmTypeClient;
import com.vci.ubcs.omd.feign.IWebSecretClient;
import com.vci.ubcs.omd.vo.BtmTypeVO;
@@ -33,7 +34,6 @@
import com.vci.ubcs.starter.revision.model.BaseModel;
import com.vci.ubcs.starter.util.DefaultAttrAssimtUtil;
import com.vci.ubcs.starter.util.LocalFileUtil;
import com.vci.ubcs.starter.util.MdmBtmTypeConstant;
import com.vci.ubcs.starter.web.constant.QueryOptionConstant;
import com.vci.ubcs.starter.web.enumpck.BooleanEnum;
import com.vci.ubcs.starter.web.enumpck.UserSecretEnum;
@@ -41,7 +41,6 @@
import com.vci.ubcs.starter.web.pagemodel.*;
import com.vci.ubcs.starter.web.toolmodel.DateConverter;
import com.vci.ubcs.starter.web.util.*;
import lombok.AllArgsConstructor;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.map.HashedMap;
@@ -67,6 +66,7 @@
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;
import static com.alibaba.druid.util.FnvHash.Constants.LIMIT;
@@ -153,11 +153,18 @@
    */
   @Autowired
   private IBtmTypeClient btmTypeClient;
   /***
    * 密级服务
    */
   @Resource
   private IWebSecretClient secretService;
   /**
    * 导出的十万条
    */
   public static final int EXPORT_LIMIT = 100000;
   /**
    * 批量申请:选取选中分类下的所有模板关键属性,相似属性,必填属性,写入execl中
    *
@@ -180,38 +187,40 @@
         //参照的自行输入名称
         //分类注入的不用,都是导入后自动处理的
         //编码,状态等字段不导入
         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)){
            throw new VciBaseException("模板没有配置任何【表单显示】为【是】的属性");
         }
         templateAttrVOS.stream().forEach(codetemplateAttr ->{
            String field=codetemplateAttr.getId();
            String name=codetemplateAttr.getName();
            CodeClassifyTemplateAttrVO codeBaseAttributeDTO=new CodeClassifyTemplateAttrVO();
            boolean res=(StringUtils.isNotBlank(codetemplateAttr.getAttributeGroup())&& codetemplateAttr.getAttributeGroup().equals(BATCHADD_EXCEPORT_ATTR_TYPE))//基本属性字段显示
               ||(StringUtils.isNotBlank(codetemplateAttr.getKeyAttrFlag())&&Boolean.parseBoolean(codetemplateAttr.getKeyAttrFlag()))//关键属性的存入
               ||(StringUtils.isNotBlank(codetemplateAttr.getSameRepeatAttrFlag())&&Boolean.parseBoolean(codetemplateAttr.getSameRepeatAttrFlag())) //相似属性的存入
               ||(StringUtils.isNotBlank(codetemplateAttr.getRequireFlag())&&Boolean.parseBoolean(codetemplateAttr.getRequireFlag()));
            if(allFieldToOutNameMap.containsKey(name)){//如果存在的话则需要根据具体的去赋值
               codeBaseAttributeDTO=  allFieldToOutNameMap.get(name);
               if(StringUtils.isNotBlank(codetemplateAttr.getKeyAttrFlag())&&Boolean.parseBoolean(codetemplateAttr.getKeyAttrFlag())){
                  codeBaseAttributeDTO.setKeyAttrFlag(codetemplateAttr.getKeyAttrFlag());//属性关键属性
               }
               if(StringUtils.isNotBlank(codetemplateAttr.getRequireFlag())&&Boolean.parseBoolean(codetemplateAttr.getRequireFlag())){
                  codeBaseAttributeDTO.setRequireFlag(codetemplateAttr.getRequireFlag());//属性必填项
               }
               if(StringUtils.isNotBlank(codetemplateAttr.getSameRepeatAttrFlag())&&Boolean.parseBoolean(codetemplateAttr.getSameRepeatAttrFlag())){
                  codeBaseAttributeDTO.setSameRepeatAttrFlag(codetemplateAttr.getSameRepeatAttrFlag());//属性相似属性
               }
            }else if(res){
               allFieldToOutNameMap.put(name,codetemplateAttr);
         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)){
               throw new VciBaseException("模板没有配置任何【表单显示】为【是】的属性");
            }
         });
            templateAttrVOS.stream().forEach(codetemplateAttr -> {
               String field = codetemplateAttr.getId();
               String name = codetemplateAttr.getName();
               CodeClassifyTemplateAttrVO codeBaseAttributeDTO = new CodeClassifyTemplateAttrVO();
               boolean res = (StringUtils.isNotBlank(codetemplateAttr.getAttributeGroup()) && codetemplateAttr.getAttributeGroup().equals(BATCHADD_EXCEPORT_ATTR_TYPE))//基本属性字段显示
                  || (StringUtils.isNotBlank(codetemplateAttr.getKeyAttrFlag()) && Boolean.parseBoolean(codetemplateAttr.getKeyAttrFlag()))//关键属性的存入
                  || (StringUtils.isNotBlank(codetemplateAttr.getSameRepeatAttrFlag()) && Boolean.parseBoolean(codetemplateAttr.getSameRepeatAttrFlag())) //相似属性的存入
                  || (StringUtils.isNotBlank(codetemplateAttr.getRequireFlag()) && Boolean.parseBoolean(codetemplateAttr.getRequireFlag()));
               if (allFieldToOutNameMap.containsKey(name)) {//如果存在的话则需要根据具体的去赋值
                  codeBaseAttributeDTO = allFieldToOutNameMap.get(name);
                  if (StringUtils.isNotBlank(codetemplateAttr.getKeyAttrFlag()) && Boolean.parseBoolean(codetemplateAttr.getKeyAttrFlag())) {
                     codeBaseAttributeDTO.setKeyAttrFlag(codetemplateAttr.getKeyAttrFlag());//属性关键属性
                  }
                  if (StringUtils.isNotBlank(codetemplateAttr.getRequireFlag()) && Boolean.parseBoolean(codetemplateAttr.getRequireFlag())) {
                     codeBaseAttributeDTO.setRequireFlag(codetemplateAttr.getRequireFlag());//属性必填项
                  }
                  if (StringUtils.isNotBlank(codetemplateAttr.getSameRepeatAttrFlag()) && Boolean.parseBoolean(codetemplateAttr.getSameRepeatAttrFlag())) {
                     codeBaseAttributeDTO.setSameRepeatAttrFlag(codetemplateAttr.getSameRepeatAttrFlag());//属性相似属性
                  }
               } else if (res) {
                  allFieldToOutNameMap.put(name, codetemplateAttr);
               }
            });
         }
      });
      //整理好所有模板需要写入execl的属性信息
      Workbook workbook = new HSSFWorkbook();
@@ -360,16 +369,23 @@
         //参照的自行输入名称
         //分类注入的不用,都是导入后自动处理的
         //编码,状态等字段不导入
         List<CodeClassifyTemplateAttrVO> templateAttrVOS = codeClassifyTemplateVO.getAttributes().stream().filter(s ->
         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())
               && StringUtils.isBlank(s.getClassifyInvokeAttr())
               && (isHistory || VciBaseUtil.getBoolean(s.getFormDisplayFlag()))
         ).collect(Collectors.toList());
         if(CollectionUtils.isEmpty(templateAttrVOS)){
            throw new VciBaseException("模板没有配置任何【表单显示】为【是】的属性");
         }
            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();
@@ -672,7 +688,7 @@
         //相似校验
         Map<String,String>resembleMap=new HashMap<>();
         List<DataResembleVO> dataResembleVOS=new ArrayList<>();
         String btmtypeid= classifyFullInfo.getTopClassifyVO().getBtmtypeid();
         String btmtypeid= classifyFullInfo.getTopClassifyVO().getBtmTypeId();
         bathcResembleQuery(codeClassifyOid,templateVO,needSaveCboList,resembleMap,btmtypeid,dataResembleVOS);
         if(resembleMap.size()>0) {
            if(!CollectionUtils.isEmpty(dataResembleVOS)) {
@@ -972,7 +988,7 @@
         //相似校验
         Map<String, String> resembleMap = new HashMap<>();
         List<DataResembleVO> dataResembleVOS = new ArrayList<>();
         String btmtypeid = classifyFullInfo.getTopClassifyVO().getBtmtypeid();
         String btmtypeid = classifyFullInfo.getTopClassifyVO().getBtmTypeId();
         bathcResembleQuery(templateVO.getCodeclassifyoid(), templateVO, needSaveCboList, resembleMap, btmtypeid, dataResembleVOS);
         if (resembleMap.size() > 0) {
            if (!CollectionUtils.isEmpty(dataResembleVOS)) {
@@ -1312,7 +1328,7 @@
      //相似校验
      Map<String,String>resembleMap=new HashMap<>();
      List<DataResembleVO> dataResembleVOS=new ArrayList<>();
      String btmtypeid= classifyFullInfo.getTopClassifyVO().getBtmtypeid();
      String btmtypeid= classifyFullInfo.getTopClassifyVO().getBtmTypeId();
      bathcResembleQuery(orderDTO.getCodeClassifyOid(),templateVO,needSaveCboList,resembleMap,btmtypeid,dataResembleVOS);
      if(resembleMap.size()>0) {
         isCreateUUid=true;
@@ -1376,8 +1392,7 @@
   public List<CodeImportTemplateVO> gridclassifys(String redisOid) {
      List<CodeImportTemplateVO> codeImportTemplateVOs=new ArrayList<>();
      VciBaseUtil.alertNotNull(redisOid,"分类",redisOid,"分类缓存主键");
      List<CodeImportTemplateVO> redisServiceCacheObjects=bladeRedis.lRange(redisOid,0,-1);
      List<CodeImportTemplateVO> redisServiceCacheObjects=bladeRedis.get(redisOid);
      if(redisServiceCacheObjects!=null){
         codeImportTemplateVOs=  redisServiceCacheObjects;
      }
@@ -1393,7 +1408,7 @@
   @Override
   public DataGrid<Map<String, String>> gridDatas(String codeClssifyOid, String redisOid) {
      VciBaseUtil.alertNotNull(redisOid,"导入相似数据",redisOid,"数据缓存主键");
      List<CodeImprotDataVO> codeImprotDataVOs = bladeRedis.lRange(redisOid+"-"+codeClssifyOid,0,-1);
      List<CodeImprotDataVO> codeImprotDataVOs = bladeRedis.get(redisOid+"-"+codeClssifyOid);
//      redisService.getCacheList(redisOid+"-"+codeClssifyOid);
      CodeImprotDataVO codeImprotDataVO=new CodeImprotDataVO();
      if(!CollectionUtils.isEmpty(codeImprotDataVOs)){
@@ -1427,7 +1442,7 @@
   @Override
   public DataGrid<Map<String,String>> gridRowResemble(String oid,String redisOid){
      VciBaseUtil.alertNotNull(redisOid,"导入相似数据",redisOid,"数据缓存主键");
      List<DataResembleVO> codeImprotDataVOs = bladeRedis.lRange(redisOid,0,-1);;
      List<DataResembleVO> codeImprotDataVOs = bladeRedis.get(redisOid);;
      DataGrid<Map<String, String>> dataGrid = new DataGrid<>();
      List<Map<String, String>> dataList = new ArrayList<>();
@@ -1446,10 +1461,221 @@
      return dataGrid;
   }
   /**
    * 导出主题库的数据
    *
    * @param exportAttrDTO 导出相关的配置,必须要有主题库分类的主键
    * @return 导出的excel的文件
    */
   @Override
   public String exportCode(CodeExportAttrDTO exportAttrDTO) {
      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){
         conditionMap = new HashMap<>();
      }
      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.setSort(exportAttrDTO.getSort());
      pageHelper.setOrder(exportAttrDTO.getOrder());
      pageHelper.addDefaultDesc("createTime");
      conditionMap.put("codeclsfpath","*" + exportAttrDTO.getCodeClassifyOid() + "*");
      conditionMap.put("lastr", "1");
      conditionMap.put("lastv", "1");
      String countSql = "select count(*) from " + VciBaseUtil.getTableName(btmTypeId) +" where 1=1" +
         " and lastr = '1'" +
         " and lastv='1'" +
         " 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()){
         //从多少页到多少页的查询方式,
         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(countSql);
         }
      }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());
      }
      //参照让平台直接查询就行
      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)))
      ).collect(Collectors.toList());
      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){
         //分组来执行
         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++) {
            indexList.add(i);
         }
         Map<String, String> finalConditionMap = conditionMap;
         //并行查询看看
         SessionInfo sessionInfo = VciBaseUtil.getCurrentUserSessionInfo();
         indexList.stream().forEach(index->{
            //线程的方式,所以需要设置当前用户
            VciBaseUtil.setCurrentUserSessionInfo(sessionInfo);
            PageHelper thisPage = new PageHelper(EXPORT_LIMIT);
            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);
         });
      }else{
         pageHelper.setLimit(total);
         pageHelper.setPage(1);
         selectDataAndExportExcelName(btmTypeId,conditionMap,pageHelper,finalSelectFieldList,
            classifyFullInfo,templateVO,exportAttrDTO,
            excelNameList,tempFolder,1);
      }
      if(excelNameList.size() ==0){
         throw new VciBaseException("没有数据可以被导出");
      }
      if(excelNameList.size() == 1){
         return excelNameList.get(0);
      }
      //是多个,我们需要打成压缩包
      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);
      File[] files = file.listFiles();
      for (int i = 0; i < files.length; i++) {
         LocalFileUtil.deleteTempFile(files[i],false);
      }
      LocalFileUtil.deleteTempFile(file,true);
      return zipFileName;
   }
   /**
    * 查询数据并导出到excel
    * @param btmTypeId 业务类型
    * @param conditionMap 查询条件
    * @param pageHelper 分页
    * @param selectFieldList 查询的字段
    * @param classifyFullInfo 分类的全部信息
    * @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())){
         return;
      }
      //转换数据
      List<Map<String, String>> dataMap = dataGrid.getData();
      //封装查询出来的数据
      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));
      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()));
      }
      List<Integer> indexList = attrIdIndexMap.keySet().stream().sorted().collect(Collectors.toList());
      String excelName = tempFolder + File.separator +
         classifyFullInfo.getCurrentClassifyVO().getId() + "_" + classifyFullInfo.getCurrentClassifyVO().getName() + "_导出_" + excelIndex + ".xls";
      try {
         new File(excelName).createNewFile();
      } catch (Throwable e) {
         throw new VciBaseException(LangBaseUtil.getErrorMsg(e), new String[]{excelName}, e);
      }
      excelNameList.add(excelName);
      List<WriteExcelData> excelDataList = new ArrayList<>();
      Workbook workbook = new HSSFWorkbook();
      for (int i = 0; i < indexList.size(); i++) {
         String attrId = attrIdIndexMap.get(indexList.get(i)).toLowerCase(Locale.ROOT);
         if (attrVOMap.containsKey(attrId)) {
            CodeClassifyTemplateAttrVO attrVO = attrVOMap.get(attrId);
            Object text = attrVO.getName();
            text = exportKeyAndRequired(workbook,attrVO,text);
            WriteExcelData excelData = new WriteExcelData(0, i, text);
            if(text instanceof RichTextString){
               excelData.setFontColor(String.valueOf(HSSFColor.HSSFColorPredefined.RED.getIndex()));
            }
            excelDataList.add(excelData);
         }
      }
      final Integer[] rowIndex = {0};
      Map<Integer, String> finalAttrIdIndexMap = attrIdIndexMap;
      dataMap.stream().forEach(data -> {
         rowIndex[0]++;
         for (int i = 0; i < indexList.size(); i++) {
            Integer index = indexList.get(i);
            String attrId = finalAttrIdIndexMap.get(index).toLowerCase(Locale.ROOT);
            if (attrVOMap.containsKey(attrId)) {
               CodeClassifyTemplateAttrVO attrVO = attrVOMap.get(attrId);
               if (StringUtils.isNotBlank(attrVO.getEnumId()) || StringUtils.isNotBlank(attrVO.getEnumString())) {
                  attrId = attrId + "Text";
               }
               if (StringUtils.isNotBlank(attrVO.getReferBtmId()) || StringUtils.isNotBlank(attrVO.getReferConfig())) {
                  attrId = attrId + "name";
               }
               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, "")));
            }
         }
      });
      WriteExcelOption excelOption = new WriteExcelOption(excelDataList);
      ExcelUtil.writeDataToFile(excelName, excelOption);
   }
   @Override
   public R batchImportData(List<CodeImprotSaveDatVO> codeImprotSaveDatVOList, String classifyAttr, boolean isImprot) {
      boolean success=true;
      WriteExcelOption eo = new WriteExcelOption();
      AtomicBoolean success= new AtomicBoolean(true);
      codeImprotSaveDatVOList.stream().forEach(codeImprotSaveDatVO -> {
         List<SheetRowData> rowDataList = new ArrayList<>();
         List<ClientBusinessObject>cboList=new ArrayList<>();
@@ -1566,7 +1792,7 @@
                     log.error("批量产生编码的时候出错了", e);
                     thisCbos.stream().forEach(cbo -> {
                        String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX);
                        errorMap.put(rowIndex, errorMap.getOrDefault(rowIndex, "") + ";系统错误,存储数据的时候出错了");
                        errorMap.put(rowIndex, errorMap.getOrDefault(rowIndex, "") + ";系统错误,存储数据的时候出错了:"+e.getMessage());
                     });
                  }
               }
@@ -1588,14 +1814,34 @@
               try {
                  productCodeService.productCodeAndSaveData(classifyFullInfo, codeClassifyTemplateVO, ruleVO, orderDTO.getSecDTOList(), dataCBOList);
               } catch (Exception e) {
                  e.printStackTrace();
                  log.error("批量产生编码的时候出错了", e);
                  needSaveCboList.stream().forEach(cbo -> {
                     String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX);
                     errorMap.put(rowIndex, errorMap.getOrDefault(rowIndex, "") + ";系统错误,存储数据的时候出错了:"+e.getMessage());
                  });
               }
               //如果是编码生成失败,则直接就失败了,其他的判断出来有错误的我们都统一返回到excel里面
               engineService.batchSaveSelectChar(codeClassifyTemplateVO, dataCBOList);
            }
         }
         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));
            });
            eo.addSheetDataList(codeClassifyTemplateVO.getName() + "导入模板", excelDataList);
         }
      });
      return  R.success(isImprot?"批量历史导入成功":"批量申请成功");
      if(!success.get()){
         String excelName = LocalFileUtil.getDefaultTempFolder() + File.separator + (isImprot?"批量历史错误信息.xls":"批量申请错误信息.xls");
         ExcelUtil.writeDataToFile(excelName,eo);
         return  R.fail(excelName);
      }else {
         return R.success(isImprot ? "批量历史导入成功" : "批量申请成功");
      }
   }
   /***
@@ -1825,7 +2071,7 @@
            });
            //关键熟悉更改
            if (!CollectionUtils.isEmpty(editBoList)) {
               engineService.updateBatchByBaseModel(classifyFullInfo.getTopClassifyVO().getBtmtypeid(),editBoList);//保存数据
               engineService.updateBatchByBaseModel(classifyFullInfo.getTopClassifyVO().getBtmTypeId(),editBoList);//保存数据
            }
            errorMap.putAll(errorKeyMap);
         }
@@ -1860,7 +2106,7 @@
            //如果是编码生成失败,则直接就失败了,其他的判断出来有错误的我们都统一返回到excel里面
            engineService.batchSaveSelectChar(templateVO, dataCBOList);
            // if(!isProcess){
            needSaveCboList.stream().forEach(needSaveCbo->{
            dataCBOList.stream().forEach(needSaveCbo->{
               XMLResultDataObjectDetailDO resultDataObjectDetailDO=new XMLResultDataObjectDetailDO();
               resultDataObjectDetailDO.setCode(needSaveCbo.getId());
               String oid=needSaveCbo.getOid();
@@ -1947,7 +2193,7 @@
      String tableName ="";
      try {
         R<BtmTypeVO> r = btmTypeClient.getAllAttributeByBtmId(templateVO.getBtmTypeId());
         if(r.getCode()!=200) {
         if(!r.isSuccess()) {
            throw new Throwable(r.getMsg());
         }
         BtmTypeVO btmTypeVO = r.getData();
@@ -2121,7 +2367,7 @@
      }else {
         //存储数据
         try {
            engineService.updateBatchByBaseModel(classifyFullInfo.getTopClassifyVO().getBtmtypeid(),updateList);
            engineService.updateBatchByBaseModel(classifyFullInfo.getTopClassifyVO().getBtmTypeId(),updateList);
            codeAllCodeService.saveBatch(codeAllCodeList);
            if(deleteList.size()>0) {
               commonsMapper.deleteByTaleAndOid(tableName, VciBaseUtil.array2String(deleteList.toArray(new String[]{})));
@@ -2248,7 +2494,7 @@
      //没有限制分类,但是一个模板只可能在一个业务类型里面,所以直接查询这个业务类型即可
      if (!CollectionUtils.isEmpty(conditionMap)) {
         final String[] sql = {"select count(*) from " + VciBaseUtil.getTableName(classifyFullInfo.getTopClassifyVO().getBtmtypeid()) + " where 1 = 1 "};
         final String[] sql = {"select count(*) from " + VciBaseUtil.getTableName(classifyFullInfo.getTopClassifyVO().getBtmTypeId()) + " where 1 = 1 "};
         conditionMap.forEach((key, value) -> {
            sql[0] += " and " + key + " = " + value;
         });
@@ -2588,7 +2834,7 @@
         String oid=rowData.getOid();
         String rowNumber=rowData.getRowIndex();
         ClientBusinessObject cbo = new ClientBusinessObject();
         DefaultAttrAssimtUtil.addDefaultAttrAssimt(cbo, classifyFullInfo.getTopClassifyVO().getBtmtypeid());
         DefaultAttrAssimtUtil.addDefaultAttrAssimt(cbo, classifyFullInfo.getTopClassifyVO().getBtmTypeId());
         rowData.getData().forEach((index,value)->{
            String field = fieldIndexMap.get(index);
            if(StringUtils.isBlank(field)){
@@ -2693,7 +2939,7 @@
      String fullPath = getFullPath(classifyFullInfo);
      codeImprotDataVO.getDatas().stream().forEach(rowData -> {
         ClientBusinessObject cbo=new ClientBusinessObject();
         DefaultAttrAssimtUtil.addDefaultAttrAssimt(cbo, classifyFullInfo.getTopClassifyVO().getBtmtypeid());
         DefaultAttrAssimtUtil.addDefaultAttrAssimt(cbo, classifyFullInfo.getTopClassifyVO().getBtmTypeId());
         rowData.forEach((field,value)->{
            try {
               cbo.setAttributeValueWithNoCheck(field,value);
@@ -2716,6 +2962,7 @@
                  Integer userSecret = VciBaseUtil.getCurrentUserSecret();
                  cbo.setAttributeValue(SECRET_FIELD,String.valueOf((userSecret==null || userSecret ==0)? UserSecretEnum.NONE.getValue():userSecret));
               }
               cbo.setLcStatus(CodeDefaultLC.EDITING.getValue());
            }else{
               //此时还没有转换路径
               //cbo.setAttributeValue(CODE_FULL_PATH_FILED, childOidPathMap.getOrDefault(rowData.getData().getOrDefault(CODE_CLASSIFY_OID_FIELD,""),fullPath));
@@ -2745,7 +2992,7 @@
                     String fullPath,boolean newCode){
      rowDataList.stream().forEach(rowData -> {
         ClientBusinessObject cbo=new ClientBusinessObject();
          DefaultAttrAssimtUtil.addDefaultAttrAssimt(cbo, classifyFullInfo.getTopClassifyVO().getBtmtypeid());
          DefaultAttrAssimtUtil.addDefaultAttrAssimt(cbo, classifyFullInfo.getTopClassifyVO().getBtmTypeId());
         rowData.getData().forEach((index,value)->{
            String field = fieldIndexMap.get(index);
            if (StringUtils.isBlank(field)) {
@@ -2772,6 +3019,7 @@
                  Integer userSecret = VciBaseUtil.getCurrentUserSecret();
                  cbo.setAttributeValue(SECRET_FIELD,String.valueOf((userSecret==null || userSecret ==0)? UserSecretEnum.NONE.getValue():userSecret));
               }
               cbo.setLcStatus(CodeDefaultLC.EDITING.getValue());
            }else{
               //此时还没有转换路径
               //cbo.setAttributeValue(CODE_FULL_PATH_FILED, childOidPathMap.getOrDefault(rowData.getData().getOrDefault(CODE_CLASSIFY_OID_FIELD,""),fullPath));
@@ -3053,7 +3301,7 @@
      String tableName ="";
      try {
         R<BtmTypeVO> r = btmTypeClient.getAllAttributeByBtmId(templateVO.getBtmTypeId());
         if(r.getCode()!=200) {
         if(!r.isSuccess()) {
            throw new Throwable(r.getMsg());
         }
         BtmTypeVO btmTypeVO = r.getData();
@@ -3409,7 +3657,7 @@
            engineService.wrapperKeyAttrConditionMap(value, keyRuleVO, attrId, trim, ignoreCase, ignoreWidth, trimAll, conditionMap);
         });
         if (!CollectionUtils.isEmpty(ketAttrMap)) {
            CodeTemplateAttrSqlBO sqlBO = engineService.getSqlByTemplateVO(classifyFullInfo.getTopClassifyVO().getBtmtypeid(), templateVO, conditionMap, null);
            CodeTemplateAttrSqlBO sqlBO = engineService.getSqlByTemplateVO(classifyFullInfo.getTopClassifyVO().getBtmTypeId(), templateVO, conditionMap, null);
            boolean isKeyCheck= commonsMapper.queryCountBySql(sqlBO.getSqlCount()) > 0;
            if(isKeyCheck){
               List<Map<String,String>> newDataList=  commonsMapper.queryByOnlySqlForMap(sqlBO.getSqlUnPage());
@@ -3478,12 +3726,12 @@
                              List<String> unExistRuleClassifyOidList   ){
      if(!CollectionUtils.isEmpty(classifyVOMap)){
         classifyVOMap.values().parallelStream().forEach(classifyVO->{
            if(StringUtils.isNotBlank(classifyVO.getCoderuleoid())){
               ruleOidMap.put(classifyVO.getOid(),classifyVO.getCoderuleoid());
            if(StringUtils.isNotBlank(classifyVO.getCodeRuleOid())){
               ruleOidMap.put(classifyVO.getOid(),classifyVO.getCodeRuleOid());
            }else{
               //递归找上级
               List<String> ruleOidList = new ArrayList<>();
               recursionRule(classifyVOMap,classifyVO.getParentcodeclassifyoid(),ruleOidList);
               recursionRule(classifyVOMap,classifyVO.getParentCodeClassifyOid(),ruleOidList);
               if(!CollectionUtils.isEmpty(ruleOidList)){
                  ruleOidMap.put(classifyVO.getOid(),ruleOidList.get(0));
               }else{
@@ -3503,11 +3751,11 @@
   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())){
            ruleOidList.add(classifyVO.getCoderuleoid());
         if(StringUtils.isNotBlank(classifyVO.getCodeRuleOid())){
            ruleOidList.add(classifyVO.getCodeRuleOid());
            return;
         }else{
            recursionRule(classifyVOMap,classifyVO.getParentcodeclassifyoid(),ruleOidList);
            recursionRule(classifyVOMap,classifyVO.getParentCodeClassifyOid(),ruleOidList);
         }
      }else{
         Map<String, CodeClassifyVO> parentClassifyVOMap=new HashMap<>();
@@ -3617,13 +3865,15 @@
      }
   }
   private List<ClientBusinessObject> ChangeMapTOClientBusinessObjects(List<Map<String,String>> oldDataMap){
      List<ClientBusinessObject> clientBusinessObjectList=new CopyOnWriteArrayList<>();
      oldDataMap.parallelStream().forEach(dataMap->{
      List<ClientBusinessObject> clientBusinessObjectList=new ArrayList<>();
      oldDataMap.stream().forEach(dataMap->{
         ClientBusinessObject clientBusinessObject=new ClientBusinessObject();
         DefaultAttrAssimtUtil.copplyDefaultAttrAssimt(dataMap,clientBusinessObject);
         dataMap.forEach((key,value)->{
            clientBusinessObject.setAttributeValue(key,value);
         });
         for (String key:dataMap.keySet()){
            Object value= dataMap.getOrDefault(key,"");
            clientBusinessObject.setAttributeValue(key,value.toString());
         }
         clientBusinessObjectList.add(clientBusinessObject);
      });
      return clientBusinessObjectList;
   }
@@ -4048,4 +4298,5 @@
         }
      }
   }
}