Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/service/impl/MdmProductCodeServiceImpl.java
@@ -1,5 +1,6 @@
package com.vci.ubcs.code.service.impl;
import com.alibaba.fastjson.JSON;
import com.vci.ubcs.code.algorithm.CustomSerialEnum;
import com.vci.ubcs.code.annotation.MdmSerialAlgorithm;
import com.vci.ubcs.code.annotation.MdmSerialAlgorithmMethod;
@@ -50,6 +51,7 @@
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
@@ -116,7 +118,7 @@
            //VciBaseUtil.setCurrentUserSessionInfo(sessionInfo);
            String code = cbo.getId();
            List<String> serialUnitList = new CopyOnWriteArrayList<>();
            String seclenghStr=cbo.getData().get(CODE_SEC_LENGTH_FIELD);
            //String seclenghStr=cbo.getData().get(CODE_SEC_LENGTH_FIELD);
            String[] secLengths = cbo.getData().get(CODE_SEC_LENGTH_FIELD).split("#");
            cbo.getData().remove(CODE_SEC_LENGTH_FIELD);//将此key除去
            cbo.getData().remove(IMPORT_ROW_INDEX);//将此key除去
@@ -135,11 +137,11 @@
                  //最后
                  thisSecValue =  seclenghStr.contains("#")?code.substring(VciBaseUtil.getInt(secLengths[i-1]),code.length()):code;
               }else {*/
                  int start = 0;
                  for (int j = 0; j < i; j++) {
                     start += VciBaseUtil.getInt(secLengths[j]);
                  }
                  thisSecValue = code.substring(start,start+VciBaseUtil.getInt(secLengths[i]));
               int start = 0;
               for (int j = 0; j < i; j++) {
                  start += VciBaseUtil.getInt(secLengths[j]);
               }
               thisSecValue = code.substring(start,start+VciBaseUtil.getInt(secLengths[i]));
               //   }
               if(VciBaseUtil.getBoolean(secVO.getSerialDependFlag())){
                  serialUnitList.add(thisSecValue);
@@ -153,7 +155,7 @@
            List<String> serialUnFileStringList = new ArrayList<>();
            AtomicReference<String> newSerialUnitString = new AtomicReference<>("");
            if(!CollectionUtils.isEmpty(serialValueMap)){
               AtomicInteger index= new AtomicInteger();
               AtomicInteger index = new AtomicInteger();
               serialValueMap.forEach((secOid,secValue)->{
                  //要看是不是补位的
                  CodeBasicSecVO secVO = secVOMap.get(secOid);
@@ -174,7 +176,7 @@
                  if(OsCodeFillTypeEnum.NONE.getValue().equalsIgnoreCase(secVO.getCodeFillType())){
                     //不补码
                     //把所有不是数字的去掉,因为可能会是老数据,新规则
                     //   serialDb = VciBaseUtil.getDouble(killUnNumberChar(subSecValue));
                     //serialDb = VciBaseUtil.getDouble(killUnNumberChar(subSecValue));
                     //serialDb = killUnNumberChar(subSecValue);
                     serialDb=subSecValue;
                  }else {
@@ -182,21 +184,24 @@
                     serialDb = killFillChar(subSecValue,secVO.getCodeFillSeparator(),
                        OsCodeFillTypeEnum.LEFT.getValue().equalsIgnoreCase(secVO.getCodeFillType()));
                  }
                  Double newSerialDb= CustomSerialEnum.getDoubleCustomSerialValue(serialDb,secVO.getCustomCodeSerialType());
                  HashMap<String, String> thisUnitMaxMap = maxSerialMap.getOrDefault(serialUnitString, new HashMap<>());
                  Double maxValue=newSerialDb;
                  if(thisUnitMaxMap.containsKey(secOid)){
                     String    newMaxValue=  thisUnitMaxMap.getOrDefault(secOid,"");
                     maxValue=StringUtils.isBlank(newMaxValue)?-1:VciBaseUtil.getDouble(newMaxValue);
                     if(maxValue<newSerialDb){
                        maxValue=newSerialDb;
                  Double newSerialDb = CustomSerialEnum.getDoubleCustomSerialValue(serialDb,secVO.getCustomCodeSerialType());
                  //TODO: 20240822需要这块代码是同步性的,maxSerialMap这儿会因为线程受影响,修改后测试多次总数为5000条一次导入耗费时间为3分30秒左右
                  synchronized(this) {
                     HashMap<String, String> thisUnitMaxMap = maxSerialMap.getOrDefault(serialUnitString, new HashMap<>());
                     Double maxValue=newSerialDb;
                     if(thisUnitMaxMap.containsKey(secOid)){
                        String newMaxValue = thisUnitMaxMap.getOrDefault(secOid,"");
                        maxValue = StringUtils.isBlank(newMaxValue)?-1:VciBaseUtil.getDouble(newMaxValue);
                        if(maxValue < newSerialDb){
                           maxValue = newSerialDb;
                        }
                     }
                     String newMaxValue=CustomSerialEnum.getStringCustomSerialValue(maxValue,secVO.getCustomCodeSerialType());
                     serialDb=CustomSerialEnum.getStringCustomSerialValue(newSerialDb,secVO.getCustomCodeSerialType());
                     thisUnitMaxMap.put(secOid,newMaxValue);
                     maxSerialMap.put(serialUnitString,thisUnitMaxMap);
                     serialUnFileStringList.add(String.valueOf(serialDb));
                  }
                  String newMaxValue=CustomSerialEnum.getStringCustomSerialValue(maxValue,secVO.getCustomCodeSerialType());
                  serialDb=CustomSerialEnum.getStringCustomSerialValue(newSerialDb,secVO.getCustomCodeSerialType());
                  thisUnitMaxMap.put(secOid,newMaxValue);
                  maxSerialMap.put(serialUnitString,thisUnitMaxMap);
                  serialUnFileStringList.add(String.valueOf(serialDb));
               });
            }
            CodeAllCode allCodeDO = new CodeAllCode();
@@ -272,7 +277,6 @@
                  allCodeWrapper.in("id", QueryOptionConstant.IN + "(" +
                     VciBaseUtil.toInSql(codeDOs.stream().map(s->s.getId()).collect(Collectors.toList()).toArray(new String[0])) + ")");
                  List<CodeAllCode> existCodes = codeAllCodeService.selectByWrapper(allCodeWrapper);
                  if(!CollectionUtils.isEmpty(existCodes)){
                     existCodes.stream().forEach(existCode->{
@@ -360,7 +364,11 @@
         List<CodeBasicSecVO> attrSecVOList = new ArrayList<>();
         for (int i = 0; i < secVOList.size(); i++) {
            CodeBasicSecVO secVO = secVOList.get(i);
            switchSecValue(secVO, secValueMap, classifyFullInfoBO, serialSecVOList, attrSecVOList, serialUnitList, secValueList);
            try{
               switchSecValue(secVO, secValueMap, classifyFullInfoBO, serialSecVOList, attrSecVOList, serialUnitList, secValueList);
            }catch (Exception e){
               throw new ServiceException("码值转换时出现错误,原因:"+e.getMessage());
            }
         }
         //处理属性码段和流水码段
         Map<String/**流水码段的主键**/, Map<String/**流水依据**/, String>> lastMaxSerialValueMap = new HashMap<>();
@@ -423,7 +431,7 @@
            .collectingAndThen(
               Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(CodeAllCode::getId))),
               ArrayList::new));
         if( distinctCodeAllCOdes.size() != allCodeDOList.size() ){
         if(distinctCodeAllCOdes.size() != allCodeDOList.size() ){
            throw new ServiceException("编码数据重复,无法保存,请注意!");
         }
         QueryWrapper<CodeAllCode> wrapper = new QueryWrapper<>();
@@ -438,16 +446,22 @@
         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.setLastModifier(Func.isNotEmpty(user) ? user.getAccount():AuthUtil.getUserAccount());
            for (int i = 0; i < allCodeDOList.size(); i++) {
               if(codeAllCode.getId().equals(allCodeDOList.get(i).getId())){
                  codeAllCode.setCreateCodeOid(allCodeDOList.get(i).getCreateCodeOid());
                  codeAllCode.setLcStatus(allCodeDOList.get(i).getLcStatus());
                  allCodeDOList.remove(i);
               }
            }
            /*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);
@@ -502,8 +516,6 @@
         });
      }
   }
   /**
    * 转换流水码段的值
@@ -616,8 +628,6 @@
         }
      }
   }
   /**
    * 转换流水码段的值
@@ -812,6 +822,10 @@
         case CODE_CLASSIFY_SEC:
            //分类码段的,也是从前端选择了码值即可,不论码值的长度是多少
            CodeClassifyValue codeClassifyValueDO= codeClassifyValueMapper.selectById(secValue);
            //当码值为空或#NaN?时即表示作为空字符串进行拼接
            if(Func.isBlank(codeClassifyValueDO.getId()) || codeClassifyValueDO.getId().equals("#NaN?")){
               codeClassifyValueDO.setId("");
            }
            if(codeClassifyValueDO!=null) {
               secValue = joinPreffixAndSuffix(secVO, codeClassifyValueDO.getId());
            }
@@ -882,7 +896,7 @@
         case CODE_VARIABLE_SEC:
            //可变码段,是在页面上输入内容
            if (secValue.length() > VciBaseUtil.getInt(secVO.getCodeSecLength())) {
               throw new VciBaseException("【{0}】这个码段是可变码段,但是现在输入的码值的长度({1})超过了规定的长度{2}", new String[]{secVO.getName(), String.valueOf(secValue.length()), secVO.getCodeSecLength()});
               throw new ServiceException(String.format("【{%s}】这个码段是可变码段,但是现在输入的码值的长度({%s})超过了规定的长度{%s}", secVO.getName(), secValue.length(), secVO.getCodeSecLength()));
            }
            OsCodeFillTypeEnum fillTypeEnum = OsCodeFillTypeEnum.forValue(secVO.getCodeFillType());
            secValue = fillString(VciBaseUtil.getInt(secVO.getCodeSecLength()), fillTypeEnum, secValue, secVO.getCodeFillSeparator());
@@ -1213,7 +1227,7 @@
         for (int j = 0; j < serialSecVOList.size(); j++) {
            CodeBasicSecVO secVO = serialSecVOList.get(j);
            if(lastMaxSerialValueMap.containsKey(secVO.getOid())){//此为最后需要存入流水依赖的最大流水
               Map<String/**流水依据**/, String> serialValueMap=   lastMaxSerialValueMap.get(secVO.getOid());
               Map<String/**流水依据**/, String> serialValueMap = lastMaxSerialValueMap.get(secVO.getOid());
               serialValueMap.forEach((maxSerialUnitString,serialValue)->{
                  if(StringUtils.isNotBlank(serialValue)){
                     serialUnitString.set(maxSerialUnitString);
@@ -1263,14 +1277,21 @@
         codeAllCode.setLastModifyTime(new Date());
         codeAllCode.setLastModifier(AuthUtil.getUserId().toString());
         Iterator<CodeAllCode> iterator = allCodeDOList.iterator();
         while (iterator.hasNext()){
         for (int i = 0; i < allCodeDOList.size(); i++) {
            if(codeAllCode.getId().equals(allCodeDOList.get(i).getId())){
               codeAllCode.setCreateCodeOid(allCodeDOList.get(i).getCreateCodeOid());
               codeAllCode.setLcStatus(allCodeDOList.get(i).getLcStatus());
               allCodeDOList.remove(i);
            }
         }
         /*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);
@@ -1279,7 +1300,6 @@
      mdmEngineService.insertBatchByType(dataCBOList.get(0).getBtmname(),dataCBOList);
      return codeList;
   }
   /**
    * 转换码值的内容
@@ -1310,6 +1330,9 @@
         case CODE_CLASSIFY_SEC:
            //分类码段的,也是从前端选择了码值即可,不论码值的长度是多少
            CodeClassifyValue codeClassifyValueDO= codeClassifyValueMapper.selectById(secValue);
            if(Func.isBlank(codeClassifyValueDO.getId()) || codeClassifyValueDO.getId().equals("#NaN?")){
               codeClassifyValueDO.setId("");
            }
            if(codeClassifyValueDO!=null) {
               secValue = joinPreffixAndSuffix(secVO, codeClassifyValueDO.getId());
            }