ludc
2024-01-24 c327574106f470c72638e9f34c7f8cd26d78a2bf
Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/service/impl/MdmIOServiceImpl.java
@@ -3,7 +3,6 @@
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.toolkit.Wrappers;
import com.google.protobuf.ServiceException;
import com.vci.ubcs.code.applyjtcodeservice.feign.IMdmInterJtClient;
@@ -27,7 +26,6 @@
import com.vci.ubcs.omd.feign.IBtmTypeClient;
import com.vci.ubcs.omd.feign.IWebSecretClient;
import com.vci.ubcs.omd.vo.BtmTypeVO;
import com.vci.ubcs.omd.vo.RevisionRuleVO;
import com.vci.ubcs.starter.bo.WriteExcelData;
import com.vci.ubcs.starter.exception.VciBaseException;
import com.vci.ubcs.starter.poi.bo.ReadExcelOption;
@@ -56,7 +54,6 @@
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.RichTextString;
import org.apache.poi.ss.usermodel.Workbook;
import org.aspectj.apache.bcel.classfile.Code;
import org.springblade.core.redis.cache.BladeRedis;
import org.springblade.core.secure.BladeUser;
import org.springblade.core.secure.utils.AuthUtil;
@@ -70,7 +67,6 @@
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
@@ -87,7 +83,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;
@@ -201,6 +199,11 @@
    * 客户现场excel为老版本,导出的总数限制为65535
    */
   public static final int EXPORT_LIMIT = 65535;
   /**
    * 自定义并发ForkJoinPool
    */
   private static final ForkJoinPool customForkJoinPool = new ForkJoinPool(Runtime.getRuntime().availableProcessors()-1);
   /**
    * 批量申请:选取选中分类下的所有模板关键属性,相似属性,必填属性,写入execl中
@@ -1344,8 +1347,6 @@
               engineService.batchSaveSelectChar(templateVO, dataCBOIdList);
            }
         }
         //long end = System.currentTimeMillis();
         //log.info("=============for执行时间================="+String.valueOf((end-start)/1000));
         String excelFileName="";
         if(isExport&&!CollectionUtils.isEmpty(shetNameMap)) {
            excelFileName = LocalFileUtil.getDefaultTempFolder() + File.separator + "错误信息.xls";
@@ -1359,14 +1360,17 @@
               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.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){
            codeImProtRusultVO.setRedisUuid(uuid);
@@ -2113,10 +2117,18 @@
      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);
      AtomicReference<CodeClassifyTemplateVO> codeClassifyTemplateVO = new AtomicReference<>();
      codeImprotSaveDatVOList.stream().forEach(codeImprotSaveDatVO -> {
         List<SheetRowData> rowDataList = new ArrayList<>();
         List<ClientBusinessObject>cboList=new ArrayList<>();
@@ -2145,16 +2157,16 @@
         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 ->
         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);
         excelToCbo(classifyFullInfo,fieldIndexMap,rowDataList, codeClassifyTemplateVO.get(),cboList,fullPath,!isImprot);
         Map<String,String> errorMap=new ConcurrentHashMap<>();
         Map<String/**路径**/, CodeClassifyVO> pathMap=new HashMap<>() ;
         //校验编码规则和码段是否正确
@@ -2200,7 +2212,7 @@
         //最后弄组合规则
         batchSwitchComponentAttrOnOrder(attrVOS,cboList);
         //3.判断关键属性
         CodeImportResultVO keyResultVO = batchCheckKeyAttrOnOrder(classifyFullInfo, codeClassifyTemplateVO, cboList,false,errorMap);
         CodeImportResultVO keyResultVO = batchCheckKeyAttrOnOrder(classifyFullInfo, codeClassifyTemplateVO.get(), cboList,false,errorMap);
         Set<String> selfRepeatRowIndexList = keyResultVO.getSelfRepeatRowIndexList();
         Set<String> keyAttrRepeatRowIndexList = keyResultVO.getKeyAttrRepeatRowIndexList();
         if(!CollectionUtils.isEmpty(keyAttrRepeatRowIndexList)){
@@ -2231,7 +2243,7 @@
                     dataCBOList.add(baseModel);
                  });
                  try {
                     productCodeService.productCodeAndSaveData(classifyFullInfo, codeClassifyTemplateVO, finalRuleVOMap.get(ruleOid), null, dataCBOList, user);
                     productCodeService.productCodeAndSaveData(classifyFullInfo, codeClassifyTemplateVO.get(), finalRuleVOMap.get(ruleOid), null, dataCBOList, user);
                  } catch (Throwable e) {
                     //success=false;
                     log.error("批量产生编码的时候出错了", e);
@@ -2241,7 +2253,7 @@
                     });
                  }
               }
               engineService.batchSaveSelectChar(codeClassifyTemplateVO, dataCBOList);
               engineService.batchSaveSelectChar(codeClassifyTemplateVO.get(), dataCBOList);
            });
         }else {
            final BladeUser user = AuthUtil.getUser();
@@ -2258,7 +2270,7 @@
                  dataCBOList.add(baseModel);
               });
               try {
                  productCodeService.productCodeAndSaveData(classifyFullInfo, codeClassifyTemplateVO, ruleVO, orderDTO.getSecDTOList(), dataCBOList,user);
                  productCodeService.productCodeAndSaveData(classifyFullInfo, codeClassifyTemplateVO.get(), ruleVO, orderDTO.getSecDTOList(), dataCBOList,user);
               } catch (Exception e) {
                  log.error("批量产生编码的时候出错了", e);
                  needSaveCboList.stream().forEach(cbo -> {
@@ -2267,7 +2279,7 @@
                  });
               }
               //如果是编码生成失败,则直接就失败了,其他的判断出来有错误的我们都统一返回到excel里面
               engineService.batchSaveSelectChar(codeClassifyTemplateVO, dataCBOList);
               engineService.batchSaveSelectChar(codeClassifyTemplateVO.get(), dataCBOList);
            }
         }
         if(errorMap.size()>0) {
@@ -2278,14 +2290,16 @@
            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);
         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 ? "批量历史导入成功" : "批量申请成功");
      }
   }
@@ -2740,7 +2754,7 @@
      //cboOidMap.put("id", QueryOptionConstant.IN + "(" + VciBaseUtil.toInSql(codeDataMap.keySet().toArray(new String[0])) + ")");
      String tableName ="";
      try {
         R<BtmTypeVO> r = btmTypeClient.getAllAttributeByBtmId(templateVO.getBtmTypeId());
         R<BtmTypeVO> r = btmTypeClient.getAllAttributeByBtmId(classifyFullInfo.getTopClassifyVO().getBtmTypeId());
         if(!r.isSuccess()) {
            throw new Throwable(r.getMsg());
         }
@@ -2838,7 +2852,17 @@
            cbo.setDescription(StringUtils.isBlank(orderDTO.getDescription())?"":orderDTO.getDescription());
            cbo.setName(orderDTO.getName());
            try {
               cbo.setAttributeValueWithNoCheck("description", orderDTO.getDescription());
               //主要处理大小写问题,将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+"在流程中,不允许更改!"));
@@ -2901,7 +2925,7 @@
               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);
@@ -2939,7 +2963,7 @@
            engineService.updateBatchByBaseModel(classifyFullInfo.getTopClassifyVO().getBtmTypeId(),updateList);
            codeAllCodeService.saveOrUpdateBatch(codeAllCodeList);
            if(deleteList.size()>0) {
               commonsMapper.deleteByTaleAndOid(tableName, VciBaseUtil.array2String(deleteList.toArray(new String[]{})));
               commonsMapper.deleteByTaleAndOid(tableName, VciBaseUtil.toInSql(deleteList.toArray(new String[]{})));
            }
            //是否调用集团接口申请接口
            if(isCodeOrGroupCode){
@@ -4383,56 +4407,60 @@
      // 查询不需要参与关键属性校验的除自己以外的所有分类oid
      final String isParticipateCheckOids = classifyService.selectLeafByParentClassifyOid(classifyFullInfo.getTopClassifyVO().getOid(), classifyFullInfo.getCurrentClassifyVO().getOid());
      final BladeUser user = AuthUtil.getUser();
      //cboList = new CopyOnWriteArrayList<>(cboList);
      // TODO:Thread limit exceeded replacing blocked 异常是这部分代码抛出的,所以暂时将parallelStream改成了stream
      List<ClientBusinessObject> repeatDataMap = cboList.stream().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);
            }
            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);
               errorMap.put(rowIndex, "重复的记录编号为:"+repeatData.stream().collect(Collectors.joining(",")));
               if(!CollectionUtils.isEmpty(newCboList)) {
                  indexTODataMap.put(cbo.getAttributeValue(IMPORT_ROW_INDEX), newCboList);
      // TODO:Thread limit exceeded replacing blocked 异常是这部分代码抛出的
      //  ,所以暂时将parallelStream改成了stream,改成了stream之后发现巨慢
      // customForkJoinPool控制并发度
      List<ClientBusinessObject> finalCboList = cboList;
      List<ClientBusinessObject> repeatDataMap = (List<ClientBusinessObject>) customForkJoinPool.submit(()->{
         finalCboList.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);
               }
               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);
                  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());
         }).collect(Collectors.toList());
      }).join();
      if(!CollectionUtils.isEmpty(repeatDataMap)){
         resultVO.setKeyAttrRepeatRowIndexList(repeatDataMap.stream().map(s->s.getAttributeValue(IMPORT_ROW_INDEX)).collect(Collectors.toSet()));
      }