Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/algorithm/CustomRomanSerialAlgorithmExample.java
@@ -1,45 +1,166 @@
package com.vci.ubcs.code.algorithm;
import com.alibaba.nacos.common.utils.StringUtils;
import com.alibaba.nacos.common.utils.CollectionUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.vci.ubcs.code.annotation.MdmSerialAlgorithm;
import com.vci.ubcs.code.annotation.MdmSerialAlgorithmMethod;
import com.vci.ubcs.code.dto.CodeCustomSerialDTO;
import com.vci.ubcs.code.entity.CodeAllCode;
import com.vci.ubcs.code.enumpack.CodeBZOperationTypeEnum;
import com.vci.ubcs.code.service.ICodeAllCodeService;
import com.vci.ubcs.code.vo.pagemodel.CodeBasicSecVO;
import com.vci.ubcs.starter.exception.VciBaseException;
import com.vci.ubcs.starter.web.util.VciBaseUtil;
import io.reactivex.internal.util.LinkedArrayList;
import net.logstash.logback.encoder.org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import javax.management.StringValueExp;
import java.util.*;
import java.util.stream.Collectors;
import static com.vci.ubcs.code.constant.MdmEngineConstant.*;
/****
 * 自定义罗马流水算法自定义类
 */
@MdmSerialAlgorithm(text = "自定义罗马流水",serialType="custom_serial_roman",description = "自定义罗马流水算法")
@Component
public class CustomRomanSerialAlgorithmExample {
   /**
    * 编码规则的服务
    */
   @Autowired
   private ICodeAllCodeService codeAllCodeService;
   /***
    * 操作类型
    */
   @Value("${bzApply.operationType:operationType}")
   private String operationType;
   /***
    * 是否系列
    */
   @Value("${bzApply.isSeries:isSeries}")
   private String isSeries;
   /***
    * 是否变更系列
    */
   @Value("${bzApply.isEditSeries:isEditSeries}")
   private String isEditSeries;
   /***
    * 源标准号
    */
   @Value("${bzApply.oldCode:oldCode}")
   private String oldCode;
   /***
    *发布时间
    */
   @Value("${bzApply.releaseTime:releaseTime}")
   private String releaseTime;
   /***
    * 控制是否写入值的码段名称
    */
   @Value("${bzApply.yearSecName:年代号}")
   private String yearSecName;
   /**
    * 生成罗马流水号的方法
    * @return 流水号的信息
    */
   @MdmSerialAlgorithmMethod
   public String serialGenerate(CodeCustomSerialDTO codeCustomSerialDTO){
      //
      codeCustomSerialDTO.getSerialUnitString();
      CodeBasicSecVO secVO= codeCustomSerialDTO.getSerialCodeCodeBasicSec();
      String currentFlowValue=codeCustomSerialDTO.getCurrentFlowValue();
//      boolean isSeriesValue=false;
      boolean isCrete=false;//是否成产罗马顺序号
      String romanValue="";
      List<CodeBasicSecVO> codeBasicSecVOList= codeCustomSerialDTO.getCodeBasicSecVOList();
      int yearSecValue=0;//年代号
      List<String> secValueList=codeCustomSerialDTO.getSecValueList();
      String serialUnitString=codeCustomSerialDTO.getSerialUnitString();
      //源标准类型
      boolean isSeriesValue=codeCustomSerialDTO.getBaseModel().getData().containsKey(isSeries)&&StringUtils.isNotBlank(codeCustomSerialDTO.getBaseModel().getData().get(isSeries))&&codeCustomSerialDTO.getBaseModel().getData().get(isEditSeries).equals("true")?true:false;
      //是否变更系列
      boolean isEditSeriesValue=codeCustomSerialDTO.getBaseModel().getData().containsKey(isEditSeries)&&StringUtils.isNotBlank(codeCustomSerialDTO.getBaseModel().getData().get(isEditSeries))&&codeCustomSerialDTO.getBaseModel().getData().get(isEditSeries).equals("true")?true:false;
      //如果标修订为标准,原有表准系列号不变,则比较年代号,如果年代号跨年(次年1月后则为跨年)
      String operationTypeValue=codeCustomSerialDTO.getBaseModel().getData().containsKey(operationType)&&StringUtils.isNotBlank(codeCustomSerialDTO.getBaseModel().getData().get(operationType))?codeCustomSerialDTO.getBaseModel().getData().get(operationType):"";
      //发布时间
      String releaseTimeValue=codeCustomSerialDTO.getBaseModel().getData().containsKey(releaseTime)&&StringUtils.isNotBlank(codeCustomSerialDTO.getBaseModel().getData().get(releaseTime))?codeCustomSerialDTO.getBaseModel().getData().get(releaseTime):"";
      if(operationTypeValue.equals(CodeBZOperationTypeEnum.CODE_BZ_AMENDMENT.getValue())){//如果是修订
         //源标准号
         String oldCodeValue=codeCustomSerialDTO.getBaseModel().getData().containsKey(oldCode)&&StringUtils.isNotBlank(codeCustomSerialDTO.getBaseModel().getData().get(oldCode))?codeCustomSerialDTO.getBaseModel().getData().get(oldCode):"";
         if(StringUtils.isNotBlank(oldCodeValue)){
            //还需要修改allCode的生命周期
            QueryWrapper<CodeAllCode> allCodeWrapper = new QueryWrapper<>();
            allCodeWrapper.in("id", VciBaseUtil.str2List(oldCodeValue));
            List<CodeAllCode>codeAllcodeList=codeAllCodeService.selectByWrapper(allCodeWrapper);
            if(!CollectionUtils.isEmpty(codeAllcodeList)){
               String codeDelimit=codeAllcodeList.get(0).getCodeDelimit();
               String[] secValues= StringUtils.splitByWholeSeparatorPreserveAllTokens(codeDelimit,SERIAL_VALUE_SPACE);
               int yearIndex=0;
               if((!isSeriesValue&&!isEditSeriesValue)||(isSeriesValue&&isSeriesValue)){//如果是标准修订为标准,或者系列修订为系列时候,则判断年代号
                  for (int i=0;i<codeBasicSecVOList.size();i++){
                     CodeBasicSecVO codeBasicSecVO=codeBasicSecVOList.get(i);
                     if(codeBasicSecVO.getName().equals(yearSecName)){
                        yearSecValue=Integer.parseInt((secValues[i]));
                        yearIndex=i;
                     }
                  }
                  //则获取年代号比较,如果年代号跨年则需要不需要增加罗马流水,直接改年代号,如果不跨年则增加流水
                  if(StringUtils.isNotBlank(releaseTimeValue)){//发布时间
                   String[] yearMoths=   StringUtils.splitByWholeSeparatorPreserveAllTokens(releaseTimeValue,"-");
                   String[] serialUnitStrings=StringUtils.splitByWholeSeparatorPreserveAllTokens(serialUnitString,SERIAL_UNIT_SPACE);
                   List<String>serialUnitStringList=new ArrayList<>();
                   serialUnitStringList= Arrays.asList(serialUnitStrings);
                   int newYear=0;
                     int month=0;
                    if(yearMoths.length>2){
                       String year=yearMoths[0];
                       if(year.length()>String.valueOf(yearSecValue).length()){//有时候发布时间的年长度大于码段的长度,则需要截取后2位
                          newYear= Integer.parseInt(year.substring(2));
                       }else {
                          newYear=Integer.parseInt(year);
                       }
                       month=Integer.parseInt(yearMoths[1]);
                    }
                    if(newYear>yearSecValue&&month>1){
                       secValueList.set(yearIndex,String.valueOf(newYear));
                       serialUnitStringList.set(yearIndex, String.valueOf(newYear));
                       codeCustomSerialDTO.setSecValueList(secValueList);
                       String newSerialUnitString = serialUnitStringList.size() == 0 ? EMPTY_SERIAL_UNIT : serialUnitStringList.stream().collect(Collectors.joining(SERIAL_UNIT_SPACE));
                       codeCustomSerialDTO.setSerialUnitString(newSerialUnitString);
                    }else{
                       isCrete=true;
                    }
                  }
               }
            }
         }
      Double newThisSerialValue = 0d;
      if(StringUtils.isBlank(currentFlowValue)){
         //第一个编码
         newThisSerialValue = VciBaseUtil.getDouble(secVO.getSerialStart());
      }else {
         //流水号肯定是数字
         //将罗马流水转为数字流水
         int arabicValue=VciBaseUtil.convertRomanToArabic(currentFlowValue);
         newThisSerialValue = (double)(arabicValue + secVO.getSerialStep()) ;
      }
      //要看是否超过最大的流水值
      if (newThisSerialValue >= secVO.getCodeFillLimit()) {
         throw new VciBaseException("流水号已经超过允许的最大流水值{0}", new String[]{secVO.getCodeFillLimit().toString()});
      if(isCrete){
         CodeBasicSecVO secVO= codeCustomSerialDTO.getSerialCodeCodeBasicSec();
         String currentFlowValue=codeCustomSerialDTO.getCurrentFlowValue();
         Double newThisSerialValue = 0d;
         if(StringUtils.isBlank(currentFlowValue)){
            //第一个编码
            newThisSerialValue = VciBaseUtil.getDouble(secVO.getSerialStart());
         }else {
            //流水号肯定是数字
            //将罗马流水转为数字流水
            int arabicValue=VciBaseUtil.convertRomanToArabic(currentFlowValue);
            newThisSerialValue = (double)(arabicValue + secVO.getSerialStep()) ;
         }
         //要看是否超过最大的流水值
         if (newThisSerialValue >= secVO.getCodeFillLimit()) {
            throw new VciBaseException("流水号已经超过允许的最大流水值{0}", new String[]{secVO.getCodeFillLimit().toString()});
         }
         //将数字流水转为罗马流水
         romanValue=VciBaseUtil.convertArabicToRoman(newThisSerialValue.intValue());
      }
      //将数字流水转为罗马流水
      String romanValue=VciBaseUtil.convertArabicToRoman(newThisSerialValue.intValue());
      return romanValue;
   }