Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/service/impl/MdmProductCodeServiceImpl.java
@@ -31,6 +31,8 @@
import com.vci.ubcs.starter.web.util.VciDateUtil;
import lombok.extern.slf4j.Slf4j;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.utils.Func;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
@@ -86,22 +88,20 @@
      /*****
       * 保证并发的时候,最大流水号都对的,但是这种加锁有弊端
       *
       */
      if(dataCBOList.stream().anyMatch(cbo-> StringUtils.isNotBlank(cbo.getId()))
//         && StringUtils.isNotBlank(cbo.getAttributeValue(CODE_SEC_LENGTH_FIELD))
         ){
         // && StringUtils.isNotBlank(cbo.getAttributeValue(CODE_SEC_LENGTH_FIELD))
      ){
         //是历史数据导入
         //历史数据执行的时候,这个系统会很卡
         //主要是为了录入最大流水号和allcode
//         SessionInfo sessionInfo = VciBaseUtil.getCurrentUserSessionInfo();
         //SessionInfo sessionInfo = VciBaseUtil.getCurrentUserSessionInfo();
         List<CodeAllCode> allCodeDOList = new ArrayList<>();
         Map<String/**流水依据**/, Map<String/**码段的主键**/,Double/**最大流水号**/>> maxSerialMap = new HashMap<>();
         // TODO 多线程流引发的问题已修改
         dataCBOList.parallelStream().forEach(cbo->{
            log.info("code:----->"+cbo.getId());
//            VciBaseUtil.setCurrentUserSessionInfo(sessionInfo);
            //VciBaseUtil.setCurrentUserSessionInfo(sessionInfo);
            String code = cbo.getId();
            List<String> serialUnitList = new ArrayList<>();
            String seclenghStr=cbo.getData().get(CODE_SEC_LENGTH_FIELD);
@@ -126,7 +126,7 @@
                     start += VciBaseUtil.getInt(secLengths[j]);
                  }
                  thisSecValue = code.substring(start,start+VciBaseUtil.getInt(secLengths[i]));
            //   }
               //   }
               if(VciBaseUtil.getBoolean(secVO.getSerialDependFlag())){
                  serialUnitList.add(thisSecValue);
               }
@@ -141,23 +141,26 @@
                  //要看是不是补位的
                  CodeBasicSecVO secVO = secVOMap.get(secOid);
                  Double serialDb = null;
                  // 截取掉前后缀之后的码段
                  String subSecValue = killPriffixSuffix(secValue, secVO.getPrefixCode(), secVO.getSuffixCode());
                  if(OsCodeFillTypeEnum.NONE.getValue().equalsIgnoreCase(secVO.getCodeFillType())){
                     //不补码
                     //把所有不是数字的去掉,因为可能会是老数据,新规则
                     serialDb = VciBaseUtil.getDouble(killUnNumberChar(secValue));
                     serialDb = VciBaseUtil.getDouble(killUnNumberChar(subSecValue));
                  }else {
                     //左右填充的,我们需要
                     serialDb = VciBaseUtil.getDouble(killUnNumberChar(killFillChar(secValue,secVO.getCodeFillSeparator(),
                     serialDb = VciBaseUtil.getDouble(killUnNumberChar(killFillChar(subSecValue,secVO.getCodeFillSeparator(),
                        OsCodeFillTypeEnum.LEFT.getValue().equalsIgnoreCase(secVO.getCodeFillType()))));
                  }
                  Map<String, Double> thisUnitMaxMap = maxSerialMap.getOrDefault(serialUnitString, new HashMap<>());
                  Double maxValue=serialDb;
                  if(thisUnitMaxMap.containsKey(secOid)){
                     Double maxValue=  thisUnitMaxMap.getOrDefault(secOid,new Double(-1));
                     if(maxValue>serialDb){
                        serialDb=maxValue;
                     maxValue=  thisUnitMaxMap.getOrDefault(secOid,new Double(-1));
                     if(maxValue<serialDb){
                        maxValue=serialDb;
                     }
                  }
                  thisUnitMaxMap.put(secOid,serialDb);
                  thisUnitMaxMap.put(secOid,maxValue);
                  maxSerialMap.put(serialUnitString,thisUnitMaxMap);
                  serialUnFileStringList.add(String.valueOf(serialDb));
               });
@@ -171,7 +174,8 @@
            allCodeDO.setCreateCodeBtm(cbo.getBtmname());
            allCodeDO.setCreateCodeOid(cbo.getOid());
            allCodeDO.setSerialUnit(serialUnitString);
            allCodeDO.setUnFillSerial(serialUnFileStringList.stream().collect(Collectors.joining(SERIAL_VALUE_SPACE)));
            String unFillSerial =serialUnFileStringList.size()==1?serialUnFileStringList.get(0)+ SERIAL_VALUE_SPACE:serialUnFileStringList.stream().collect(Collectors.joining(SERIAL_VALUE_SPACE));
            allCodeDO.setUnFillSerial(unFillSerial);
            allCodeDO.setLcStatus(cbo.getLcStatus());
            allCodeDOList.add(allCodeDO);
         });
@@ -273,12 +277,34 @@
               if( distinctCodeAllCOdes.size() != addCodeDOs.size() ){
                  throw new VciBaseException("编码数据重复,无法保存,请注意!");
               }
               QueryWrapper<CodeAllCode> wrapper = new QueryWrapper<>();
               wrapper.eq("CREATECODEBTM",addCodeDOs.get(0).getCreateCodeBtm());
               wrapper.in("ID",addCodeDOs.stream().map(CodeAllCode::getId).collect(Collectors.toList()));
               List<CodeAllCode> codeAllCodes = codeAllCodeService.selectByWrapper(wrapper);
               List<CodeAllCode> takeBack = codeAllCodes.stream().filter(e -> e.getLcStatus().equals("TakeBack")).collect(Collectors.toList());
               if(codeAllCodes.size()>takeBack.size()){
                  throw new ServiceException("生成编码数据ID已有历史记录,请确认如下生成的ID数据:"+ addCodeDOs.stream().map(CodeAllCode::getId).collect(Collectors.toList()));
               }
               for (CodeAllCode codeAllCode : takeBack) {
                  codeAllCode.setTs(new Date());
                  codeAllCode.setLastModifyTime(new Date());
                  codeAllCode.setLastModifier(AuthUtil.getUserId().toString());
                  Iterator<CodeAllCode> iterator = addCodeDOs.iterator();
                  while (iterator.hasNext()){
                     CodeAllCode next = iterator.next();
                     if(codeAllCode.getId().equals(next.getId())){
                        codeAllCode.setCreateCodeOid(next.getCreateCodeOid());
                        codeAllCode.setLcStatus(next.getLcStatus());
                        iterator.remove();
                     }
                  }
               }
               if(takeBack.size()>0){
                  codeAllCodeService.updateBatchById(takeBack);
               }
               codeAllCodeService.saveBatch(addCodeDOs);
            }
            mdmEngineService.insertBatchByType(dataCBOList.get(0).getBtmname(),dataCBOList);
            if(mdmEngineService.selectIdsCounts(dataCBOList.get(0).getBtmname(),dataCBOList.stream().map(BaseModel::getId).collect(Collectors.toList()))>0){
               throw new ServiceException("生成编码数据ID已有历史记录请确认!!");
            }
         }
         return codeList;
      }else {
@@ -357,13 +383,35 @@
         if( distinctCodeAllCOdes.size() != allCodeDOList.size() ){
            throw new ServiceException("编码数据重复,无法保存,请注意!");
         }
         if(mdmEngineService.selectIdsCounts(dataCBOList.get(0).getBtmname(),dataCBOList.stream().map(BaseModel::getId).collect(Collectors.toList()))>0){
            throw new ServiceException("生成编码数据ID已有历史记录请确认!!");
         QueryWrapper<CodeAllCode> wrapper = new QueryWrapper<>();
         wrapper.eq("CREATECODEBTM",allCodeDOList.get(0).getCreateCodeBtm());
         wrapper.in("ID",allCodeDOList.stream().map(CodeAllCode::getId).collect(Collectors.toList()));
         List<CodeAllCode> codeAllCodes = codeAllCodeService.selectByWrapper(wrapper);
         List<CodeAllCode> takeBack = codeAllCodes.stream().filter(e -> e.getLcStatus().equals("TakeBack")).collect(Collectors.toList());
         if(codeAllCodes.size()>takeBack.size()){
            throw new ServiceException("生成编码数据ID已有历史记录,请确认如下生成的ID数据:"+ allCodeDOList.stream().map(CodeAllCode::getId).collect(Collectors.toList()));
         }
         for (CodeAllCode codeAllCode : takeBack) {
            codeAllCode.setTs(new Date());
            codeAllCode.setLastModifyTime(new Date());
            codeAllCode.setLastModifier(AuthUtil.getUserId().toString());
            Iterator<CodeAllCode> iterator = allCodeDOList.iterator();
            while (iterator.hasNext()){
               CodeAllCode next = iterator.next();
               if(codeAllCode.getId().equals(next.getId())){
                  codeAllCode.setCreateCodeOid(next.getCreateCodeOid());
                  codeAllCode.setLcStatus(next.getLcStatus());
                  iterator.remove();
               }
            }
         }
         if(takeBack.size()>0){
            codeAllCodeService.updateBatchById(takeBack);
         }
         codeAllCodeService.saveBatch(allCodeDOList);
//         iCodeWupinService.saveBatch(dataCBOList);
         mdmEngineService.insertBatchByType(dataCBOList.get(0).getBtmname(),dataCBOList);
//         batchCBO.getCreateCbos().stream().filter(s -> StringUtils.equalsIgnoreCase("codeallcode",s.getBtmName())).forEach(s -> {
//            s.setLcStatus(statusMap.get(s.getOid()));
//            try {
@@ -373,10 +421,11 @@
//            }
//         });
      }
//      WebUtil.setPersistence(true);
//      boService.persistenceBatch(batchCBO);
      // WebUtil.setPersistence(true);
      // boService.persistenceBatch(batchCBO);
      return codeList;
   }
   /**
    * 转换属性码段的值
    * @param attrSecVOList 属性码段的显示对象
@@ -405,7 +454,8 @@
            for (int j = 0; j < thisSecValueList.size(); j++) {
               String secValue = thisSecValueList.get(j);
               if (secValue.equalsIgnoreCase("${attr_" + attrSevVO.getOid() + "}")) {
                  thisSecValueList.set(j, value);
                  // TODO: 属性码段生成码值后,拼接前后缀
                  thisSecValueList.set(j, joinPreffixAndSuffix(attrSevVO,value));
               }
            }
            if (attrSevIsSerialDepend) {
@@ -413,14 +463,13 @@
               for (int j = 0; j < serialUnitList.size(); j++) {
                  String secValue = serialUnitList.get(j);
                  if (secValue.equalsIgnoreCase("${attr_" + attrSevVO.getOid() + "}")) {
                     serialUnitList.set(j, value);
                     serialUnitList.set(j, joinPreffixAndSuffix(attrSevVO,value));
                  }
               }
            }
         });
      }
   }
   /**
    * 转换流水码段的值
@@ -490,7 +539,8 @@
            for (int z = 0; z < thisSecValueList.size(); z++) {
               String secValue = thisSecValueList.get(z);
               if (secValue.equalsIgnoreCase("${" + secVO.getOid() + "}")) {
                  thisSecValueList.set(z, serialString);
                  // TODO: 流水生成码值后拼接前后缀
                  thisSecValueList.set(z, joinPreffixAndSuffix(secVO, serialString));
               }
            }
            Map<String, Double> unitSerialMap = lastMaxSerialValueMap.getOrDefault(secVO.getOid(), new HashMap<>());
@@ -518,18 +568,19 @@
      String secValue = secValueMap.getOrDefault(secVO.getOid(), "");
      switch (secType) {
         case CODE_FIXED_SEC:
            secValue = joinPreffixAndSuffix(secVO, secValue);
            //固定码段的,直接用码值,不论码值的长度是多少,因为可变长度和固定长度是控制在码段管理里面的码值定义的
            break;
         case CODE_DATE_SEC:
            //时间码段,需要将当前时间依据时间格式进行转换.
            //时间码段不涉及到是否补位
            secValue = VciDateUtil.date2Str(new Date(), secVO.getCodeDateFormatStr());
            secValue =joinPreffixAndSuffix(secVO, VciDateUtil.date2Str(new Date(), secVO.getCodeDateFormatStr()));
            break;
         case CODE_CLASSIFY_SEC:
            //分类码段的,也是从前端选择了码值即可,不论码值的长度是多少
            CodeClassifyValue codeClassifyValueDO= codeClassifyValueMapper.selectById(secValue);
            if(codeClassifyValueDO!=null) {
               secValue = codeClassifyValueDO.getId();
               secValue = joinPreffixAndSuffix(secVO, codeClassifyValueDO.getId());
            }
            break;
         case CODE_LEVEL_SEC:
@@ -582,10 +633,12 @@
                  secValue = secValue.substring(secValue.length() - secVO.getValueCutLength());
               }
            }
            secValue = joinPreffixAndSuffix(secVO,secValue);
            break;
         case CODE_REFER_SEC:
            //引用的在页面上已经选择了,所以直接使用前端上传递的值
            //引用就是参照,可能是其他的分类(业务类型)下的数据,所以只在页面上选择
            secValue = joinPreffixAndSuffix(secVO,secValue);
            break;
         case CODE_ATTR_SEC:
            //属性与引用的区别是,属性是当前数据里的属性,而引用可能是引用其他的分类的(业务类型)
@@ -600,6 +653,7 @@
            }
            OsCodeFillTypeEnum fillTypeEnum = OsCodeFillTypeEnum.forValue(secVO.getCodeFillType());
            secValue = fillString(VciBaseUtil.getInt(secVO.getCodeSecLength()), fillTypeEnum, secValue, secVO.getCodeFillSeparator());
            secValue = joinPreffixAndSuffix(secVO,secValue);
            break;
         case CODE_SERIAL_SEC:
            //流水码段
@@ -612,6 +666,27 @@
         serialUnitList.add(secValue);
      }
      secValueList.add(secValue);
   }
   /**
    * 拼接前后缀
    * @param secVO
    * @param secValue
    * @return
    */
   private String joinPreffixAndSuffix(CodeBasicSecVO secVO, String secValue){
      StringBuilder joinSecValue = new StringBuilder();
      // 拼接前缀
      if (Func.isNotEmpty(secVO.getPrefixCode())) {
         joinSecValue = joinSecValue.append(secVO.getPrefixCode());
      }
      // 在中间拼接值
      joinSecValue.append(secValue);
      // 拼接后缀
      if(Func.isNotEmpty(secVO.getSuffixCode())){
         joinSecValue = joinSecValue.append(secVO.getSuffixCode());
      }
      return joinSecValue.toString();
   }
   /**
@@ -664,9 +739,6 @@
      allCodeDO.setLcStatus(cbo.getLcStatus());
      allCodeDOList.add(allCodeDO);
   }
   /**
    * 保存流水的信息
@@ -735,6 +807,23 @@
   }
   /**
    * 去掉前后缀
    * @param secValue 字符
    * @param priffix 前缀
    * @param suffix 后缀
    * @return 替换后的值
    */
   private String killPriffixSuffix(String secValue, String priffix,String suffix){
      if (priffix != null && secValue.startsWith(priffix)) {
         secValue = secValue.substring(priffix.length());
      }
      if (suffix != null && secValue.endsWith(suffix)) {
         secValue = secValue.substring(0, secValue.length() - suffix.length());
      }
      return secValue;
   }
   /**
    * 去除补位字符
    * @param s 字符
    * @param fillString 补位字符
@@ -744,12 +833,14 @@
   private String killFillChar(String s, String fillString,boolean left){
      Integer index = 0;
      String value = s;
      if(left){
         for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if((new String(new char[]{c})).equalsIgnoreCase(fillString)){
               index = i;
            if(!(new String(new char[]{c})).equalsIgnoreCase(fillString)){
               break;
            }
            index = i;
         }
         if(index >0){
            value = value.substring(index);
@@ -758,9 +849,10 @@
         //从右往左找
         for (int i = s.length()-1; i >=0; i++) {
            char c = s.charAt(i);
            if((new String(new char[]{c})).equalsIgnoreCase(fillString)){
               index = i;
            if(!(new String(new char[]{c})).equalsIgnoreCase(fillString)){
               break;
            }
            index = i;
         }
         if(index >0){
            value = value.substring(0,index);
@@ -828,4 +920,5 @@
//      WebUtil.copyValueToMapFromCbos(cbo,dataMap);
      return formulaService.getValueByFormula(map,rule);
   }
}