xiejun
2023-10-18 7f4698c240900277a71bd4acf0014ad2aed71968
Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/service/impl/MdmIOServiceImpl.java
@@ -65,6 +65,7 @@
import java.io.File;
import java.io.IOException;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
@@ -389,9 +390,9 @@
               && (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<>();
@@ -495,7 +496,6 @@
      return text;
   }
   /**
    * 批量申请编码数据
    *
@@ -538,7 +538,6 @@
//      return null;
      return codeImProtRusultVO;
   }
   /***
    * 从顶层批量申请导入方法
@@ -645,7 +644,6 @@
         });
         //都转换完了。需要批量检查
         //如果出错了,我们依然执行有效的数据,无效的数据写回到excel中
         //2.判断必输项。。需要全部的属性,如果是必输,但是表单里面不显示的,只能是分类注入或者组合规则
@@ -719,10 +717,8 @@
         createRedisDatas(uuid + "-ok",codeImprotDataVOS, newErrorMap,true);
      });
      //往物品节点上加模板
      List<String> needRowIndexList=new ArrayList<>();
      CodeImProtRusultVO codeImProtRusultVO = new CodeImProtRusultVO();
      if(errorMap.size()>0) {
@@ -792,6 +788,7 @@
      String uuid=VciBaseUtil.getPk();
      boolean isCreateUUid=false;
      boolean isExport=false;
      long start = System.currentTimeMillis();
      for(int i=0;i<sheetDataSetList.size()-1;i++) {
         if (CollectionUtils.isEmpty(sheetDataSetList) || CollectionUtils.isEmpty(sheetDataSetList.get(i).getRowData())
            || sheetDataSetList.get(i).getRowData().size() < 1) {
@@ -809,7 +806,6 @@
         //     5.3 企业编码的长度,和编码规则的长度要对应上
         //     5.4 获取流水码段的值,去除填充的字符,看流水号是多少,然后将流水号和现在的最大流水号判断,小于就直接录入,大于则修改最大流水号
         //     5.5 存储企业编码到allcode中
         //查询分类和模板
         CodeClassifyFullInfoBO classifyFullInfo = classifyService.getClassifyFullInfo(codeClassifyOid);
@@ -944,7 +940,7 @@
         ruleRowIndexMap.keySet().parallelStream().forEach(ruleOid -> {
            List<String> rowIndexList = ruleRowIndexMap.get(ruleOid);
            List<ClientBusinessObject> thisCbos = cboList.stream().filter(cbo -> rowIndexList.contains(cbo.getAttributeValue(IMPORT_ROW_INDEX)) && !errorMap.containsKey(cbo.getAttributeValue(IMPORT_ROW_INDEX))).collect(Collectors.toList());
//我们需要先查询一下,内容是否已经存在
            //我们需要先查询一下,内容是否已经存在
            if(!CollectionUtils.isEmpty(thisCbos)){
               List<String> existIds = new ArrayList<>();
               VciBaseUtil.switchCollectionForOracleIn(thisCbos).stream().forEach(cbos -> {
@@ -1043,6 +1039,7 @@
               if (!CollectionUtils.isEmpty(thisCbos)) {
                  try {
                     // TODO 多线程流问题
                     productCodeService.productCodeAndSaveData(classifyFullInfo, finalTemplateVO, ruleVOMap.get(ruleOid), null, dataCBOList);
                  } catch (Throwable e) {
                     log.error("批量产生编码的时候出错了", e);
@@ -1061,6 +1058,8 @@
            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";
@@ -1086,6 +1085,7 @@
      return codeImProtRusultVO;
   }
   /*private void converBaseModels(List<ClientBusinessObject> clientBusinessObjects,List<BaseModel>dataCBOList){
      clientBusinessObjects.stream().forEach(clientBusinessObject -> {
         BaseModel baseModel=new BaseModel();
@@ -1099,6 +1099,7 @@
      });
   }*/
   /***
    * 从execl里构建对象
    * @param rowDataList
@@ -1938,7 +1939,8 @@
         && 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 message=unExistAttrVOs.stream().map(CodeClassifyTemplateAttrVO::getName).collect(Collectors.joining(SERIAL_UNIT_SPACE));
         throw new VciBaseException("【" + message + "】这些属性在excel中没有找到");
      }
      List<ClientBusinessObject> cboList = new ArrayList<>();
      String fullPath = getFullPath(classifyFullInfo);
@@ -1954,16 +1956,29 @@
      //都转换完了。需要批量检查
      //如果出错了,我们依然执行有效的数据,无效的数据写回到excel中
      Map<String,String> errorKeyMap=new HashMap<>();
      //1.分类注入
      batchSwitchClassifyAttrOnOrder(attrVOS,cboList,classifyFullInfo,false);
      //boolean
      reSwitchBooleanAttrOnOrder(attrVOS,cboList);
      // cboList.stream().forEach(cbo->{
      //2.校验规则
      batchCheckVerifyOnOrder(attrVOS, cboList,errorMap);
      //3.校验枚举是否正确
      batchSwitchEnumAttrOnOrder(attrVOS,cboList,errorMap);
      //4.时间格式的验证
      //4.时间的,必须统一为yyyy-MM-dd HH:mm:ss
      batchSwitchDateAttrOnOrder(attrVOS,cboList,errorMap);
      //5.处理参照的情况
      batchSwitchReferAttrOnOrder(attrVOS,cboList,errorMap);
      //6设置默认值
      batchSwitchAttrDefault(attrVOS, cboList);
      //2.判断必输项。。需要全部的属性,如果是必输,但是表单里面不显示的,只能是分类注入或者组合规则
      batchCheckRequiredAttrOnOrder(templateVO,cboList,errorMap);
      /**
       * 关键熟悉错误提示
       */
      Map<String,String> errorKeyMap=new HashMap<>();
      //最后弄组合规则
      batchSwitchComponentAttrOnOrder(attrVOS,cboList);
      //3.判断关键属性
      CodeImportResultVO keyResultVO = batchCheckKeyAttrOnOrder(classifyFullInfo, templateVO, cboList);
      Set<String> selfRepeatRowIndexList = keyResultVO.getSelfRepeatRowIndexList();
@@ -2000,20 +2015,6 @@
            errorKeyMap.put(rowIndex,errorMap.getOrDefault(rowIndex,"") + ";关键属性与系统中的重复" );
         });
      }
      //分类注入
      batchSwitchClassifyAttrOnOrder(attrVOS,cboList,classifyFullInfo,false);
      //boolean
      reSwitchBooleanAttrOnOrder(attrVOS,cboList);
      // cboList.stream().forEach(cbo->{
      //4.校验规则
      batchCheckVerifyOnOrder(attrVOS, cboList,errorMap);
      //5.校验枚举是否正确
      batchSwitchEnumAttrOnOrder(attrVOS,cboList,errorMap);
      //6.时间格式的验证
      //6.时间的,必须统一为yyyy-MM-dd HH:mm:ss
      batchSwitchDateAttrOnOrder(attrVOS,cboList,errorMap);
      //7.处理参照的情况
      batchSwitchReferAttrOnOrder(attrVOS,cboList,errorMap);
      //校验属性是否正确错误信息
      if(errorMap.size()>0){
         String[] newMsg = {""};
@@ -2114,10 +2115,7 @@
      }
      //  });
      //设置默认值
      batchSwitchAttrDefault(attrVOS, cboList);
      //最后弄组合规则
      batchSwitchComponentAttrOnOrder(attrVOS,cboList);
      //要把以上的错误的都抛出后,再继续处理时间和组合规则
      List<ClientBusinessObject> needSaveCboList = cboList.stream().filter(cbo -> {
         String rowIndex =cbo.getAttributeValue(IMPORT_ROW_INDEX);
@@ -2133,7 +2131,7 @@
         needSaveCboList.stream().forEach(clientBusinessObject -> {
            BaseModel baseModel=new BaseModel();
            BeanUtil.convert(clientBusinessObject,baseModel);
         //(VciBaseUtil.objectToMapString(clientBusinessObject));
            //(VciBaseUtil.objectToMapString(clientBusinessObject));
            dataCBOList.add(baseModel);
            allNeedSaveCboList.add(baseModel.getOid());
         });
@@ -2329,12 +2327,17 @@
      sb.append(" where 1=1 ");
      sb.append(" and lastr=1 and lastv=1" );
      if(isCodeOrGroupCode) {
         sb.append(" and groupcode in (");
         sb.append(" and ( groupcode in (");
         sb.append(VciBaseUtil.toInSql(codeDataMap.keySet().toArray(new String[0])));
         sb.append(")");
         sb.append(" or id in (");
         sb.append(VciBaseUtil.toInSql(codeDataMap.keySet().toArray(new String[0])));
         sb.append("))");
      }else{
         sb.append(" and id in (");
         sb.append(VciBaseUtil.toInSql(codeDataMap.keySet().toArray(new String[0])));
         sb.append(")");
      }
      sb.append(VciBaseUtil.toInSql(codeDataMap.keySet().toArray(new String[0])));
      sb.append(")");
      List<Map<String,String>> dataMapList=commonsMapper.queryByOnlySqlForMap(sb.toString());
      List<ClientBusinessObject> cboList=   ChangeMapTOClientBusinessObjects(dataMapList);
@@ -2362,6 +2365,7 @@
         String dataStatus=cbo.getLcStatus();
         RowDatas rowData=codeDataMap.get(code);
         String status=rowData.getStatus();
         String lastModifier= rowData.getEditor();
         String operation=rowData.getOperation();
         if (cbo.getTs().compareTo(orderDTO.getTs())==0?false:true) {
            // throw new VciBaseException("数据不是最新的,可能他人已经修改,请刷新后再试");
@@ -2371,20 +2375,20 @@
                throw new VciBaseException("数据不是{0}的状态,不允许修改", new String[]{CodeDefaultLC.EDITING.getText()});
            }*/
         if(operation.equals("update")) {
            //1. 判断必输项
            checkRequiredAttrOnOrder(templateVO, orderDTO, errorMap);
            //2.先注入,再组合,最后校验
            //1.先注入,再组合,最后校验
            switchClassifyLevelOnOrder(templateVO, classifyFullInfo, orderDTO, errorMap);
            //3.处理组合规则。组合规则不能使用编码的属性,因为编码的生成可能是需要属性的
            //2.处理组合规则。组合规则不能使用编码的属性,因为编码的生成可能是需要属性的
            switchComponentAttrOnOrder(templateVO, orderDTO);
            //4.校验规则
            //3.校验规则
            checkVerifyOnOrder(templateVO, orderDTO, errorMap);
            //5.判断关键属性
            checkKeyAttrOnOrder(classifyFullInfo, templateVO, orderDTO, errorMap);
            //6.校验枚举的内容是否正确
            //4.校验枚举的内容是否正确
            checkEnumOnOrder(templateVO, orderDTO, errorMap);
            //7.处理时间格式,在数据库里面不论是字符串还是日期格式,都使用相同的格式存储
            //5.处理时间格式,在数据库里面不论是字符串还是日期格式,都使用相同的格式存储
            switchDateAttrOnOrder(templateVO, orderDTO);
            //6. 判断必输项
            checkRequiredAttrOnOrder(templateVO, orderDTO, errorMap);
            //7.判断关键属性
            checkKeyAttrOnOrder(classifyFullInfo, templateVO, orderDTO, errorMap);
            //默认的内容不能变,所以只需要拷贝自定义的相关属性即可
            copyValueToCBO(classifyFullInfo, cbo, orderDTO, templateVO, true, errorMap);
            //企业码和集团码的不修改
@@ -2392,12 +2396,20 @@
            cbo.setName(orderDTO.getName());
            try {
               cbo.setAttributeValueWithNoCheck("description", orderDTO.getDescription());
               cbo.setAttributeValue("name", orderDTO.getName());
            //   cbo.setAttributeValue("name", orderDTO.getName());
               //  if(finalIsProcess){//在流程中不允许更改
               //     errorMap.put(code,errorMap.getOrDefault(code, errorMap.getOrDefault(code,"")+";数据"+code+"在流程中,不允许更改!"));
               //  }else{
               Date date=new Date();
               cbo.setLcStatus(status);
               cbo.setAttributeValue("lcstatus",status);
               cbo.setLastModifyTime(date);
               cbo.setLastModifier(lastModifier);
               cbo.setLastModifyTime(date);
               cbo.setAttributeValue("lastmodifier",lastModifier);
               cbo.setAttributeValue("lastmodifytime",new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(date));
               cbo.setTs(date);
               cbo.setAttributeValue("ts",new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(date));
               //  }
            } catch (VciBaseException e) {
               e.printStackTrace();
@@ -2424,7 +2436,7 @@
               List<CodeAllCode>newCodeAllCodeList= codeAllCodeService.selectByWrapper(Wrappers.<CodeAllCode>query().lambda().eq(CodeAllCode::getCreateCodeOid, cbo.getOid()));
               log.info("codeCbos size:" + newCodeAllCodeList.size());
               if (!CollectionUtils.isEmpty(newCodeAllCodeList)) {
                  CodeAllCode codeCbo = codeAllCodeList.get(0);
                  CodeAllCode codeCbo = newCodeAllCodeList.get(0);
                  log.info("codeCbos code:" + codeCbo.getId());
                  codeCbo.setLcStatus(CodeDefaultLC.TASK_BACK.getValue());
                  codeAllCodeList.add(codeCbo);
@@ -2489,6 +2501,9 @@
            //是否调用集团接口申请接口
            if(isCodeOrGroupCode){
               List<String> IdList=resultDataObjectDetailDOs.stream().filter(xMLResultDataObjectDetailDO-> com.alibaba.cloud.commons.lang.StringUtils.isNotBlank(xMLResultDataObjectDetailDO.getId())).map(XMLResultDataObjectDetailDO::getId).distinct().collect(Collectors.toList());
               if(!CollectionUtils.isEmpty(IdList)) {
                  this.sendApplyGroupcode(IdList, classifyFullInfo.getTopClassifyVO().getBtmTypeId(),sysIntegrationPushTypeEnum.ACCPET_EDITCODE.getValue());
               }
@@ -2616,7 +2631,21 @@
      //没有限制分类,但是一个模板只可能在一个业务类型里面,所以直接查询这个业务类型即可
      if (!CollectionUtils.isEmpty(conditionMap)) {
         final String[] sql = {"select count(*) from " + VciBaseUtil.getTableName(classifyFullInfo.getTopClassifyVO().getBtmTypeId()) + " t where 1 = 1 "};
         String tableName="";
         R<BtmTypeVO> r = btmTypeClient.getAllAttributeByBtmId(templateVO.getBtmTypeId());
         if(r.isSuccess()) {
            BtmTypeVO btmTypeVO = r.getData();
            if (btmTypeVO != null) {
               tableName = btmTypeVO.getTableName();
            }
         }
         if (StringUtils.isBlank(tableName)) {
            String errormsg="根据业务类型为查询到相关业务表";
            errorMap.put(orderDTO.getId(),errorMap.getOrDefault(orderDTO.getId(),"")+errormsg);
            return;
         }
         final String[] sql = {"select count(*) from " + tableName + " t where 1 = 1 "};
         conditionMap.forEach((key, value) -> {
            if(StringUtils.isBlank(value)||value.equals(QueryOptionConstant.ISNULL)){
               sql[0] += " and " + key + " is null ";
@@ -2726,7 +2755,7 @@
//               if (lifeCycleVO != null) {
//                  cbo.setLcStatus(lifeCycleVO.getStartStatus());
//               } else {
                  cbo.setLcStatus(CodeDefaultLC.EDITING.getValue());
               cbo.setLcStatus(CodeDefaultLC.EDITING.getValue());
//               }
            } else {
               cbo.setLcStatus(CodeDefaultLC.EDITING.getValue());
@@ -2836,6 +2865,9 @@
         ClientBusinessObject sysDataObject= codeSystemObjectMap.get(code);
         if(isCodeOrGroupCode){
            code=sysDataObject.getAttributeValue("GROUPCODE");
            if(StringUtils.isBlank(code)){
               code=sysDataObject.getId();
            }
         }
         CodeOrderDTO orderDTO = new CodeOrderDTO();
         if(codeDataMap.containsKey(code)){
@@ -2844,11 +2876,7 @@
            orderDTO.setCodeClassifyOid(codeClassifyVO.getOid());//分类主键
            orderDTO.setOid(sysDataObject.getOid());//数据oid
            orderDTO.setLcStatus(rowDatas.getStatus());//状态
            if(isCodeOrGroupCode){
               orderDTO.setId(sysDataObject.getId());
            }else{
               orderDTO.setId(code);
            }
            orderDTO.setId(code);
            orderDTO.setTs(sysDataObject.getTs());
            orderDTO.setBtmname(codeClassifyVO.getBtmname());//业务类型
            orderDTO.setDescription("集成调用:更新");//数据描述
@@ -3126,7 +3154,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)) {
@@ -3677,7 +3705,7 @@
    */
   private void batchCheckRequiredAttrOnOrder(CodeClassifyTemplateVO templateVO,List<ClientBusinessObject> cboList,Map<String,String> errorMap){
      Map<String, CodeClassifyTemplateAttrVO> requiredAttrMap = templateVO.getAttributes().stream().filter(s ->
         VciBaseUtil.getBoolean(s.getRequireFlag()) && StringUtils.isBlank(s.getComponentRule()) && StringUtils.isBlank(s.getClassifyInvokeLevel())//不能是组合的和分类注入的
         VciBaseUtil.getBoolean(s.getRequireFlag()) && StringUtils.isBlank(s.getComponentRule()) && (StringUtils.isBlank(s.getClassifyInvokeLevel())||s.getClassifyInvokeLevel().equals("none"))//不能是组合的和分类注入的
      ).collect(Collectors.toMap(s -> s.getId().toLowerCase(Locale.ROOT), t -> t));
      //与MdmEngineServiceImpl里面的checkRequiredAttrOnOrder 逻辑应该相似
      if(!CollectionUtils.isEmpty(requiredAttrMap)) {
@@ -3930,7 +3958,7 @@
    * @return 重复的行号
    */
   private void getSelfRepeatRowIndex(Map<String/**属性的编号**/, CodeClassifyTemplateAttrVO> ketAttrMap,
                                   List<ClientBusinessObject> dataList,CodeKeyAttrRepeatVO keyRuleVO,CodeImportResultVO resultVO){
                              List<ClientBusinessObject> dataList,CodeKeyAttrRepeatVO keyRuleVO,CodeImportResultVO resultVO){
      Set<String> selfRepeatRowIndexList = new CopyOnWriteArraySet<>();
      Map<String,List<String>> keyAttrOkOidTORepeatOidMap=new HashMap<>();
      boolean trimAll =keyRuleVO ==null?false: VciBaseUtil.getBoolean(keyRuleVO.getIgnoreallspaceflag());