Procházet zdrojové kódy

Merge remote-tracking branch 'origin/master'

wanghao před 4 dny
rodič
revize
97e633c6cd

+ 18 - 17
commons/src/main/java/com/jzg/commons/entity/po/PtlAgreementCost.java

@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.annotation.IdType;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
 import com.jzg.commons.core.base.BaseModel;
+import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 
 import java.io.Serial;
@@ -22,39 +23,39 @@ public class PtlAgreementCost extends BaseModel {
 
     @Serial
     private static final long serialVersionUID = -985496146546865007L;
-    @TableId(type = IdType.ASSIGN_ID)
+    @Schema(description = "主键")
     private String id;
-
+    @Schema(description = "协议ID")
     private String ptlAgreementId;
-
+    @Schema(description = "承保规则ID")
     private String coverRuleId;
-
+    @Schema(description = "险种")
     private String productName;
-
+    @Schema(description = "险种ID")
     private String productId;
-
+    @Schema(description = "生效时间")
     private Date effectiveTime;
-
+    @Schema(description = "失效时间")
     private Date failureTime;
-
+    @Schema(description = "优先级")
     private Integer priorityLevel;
-
+    @Schema(description = "审核方式")//:0-自动审核;1-手动审核
     private int auditMethod;
-
+    @Schema(description = "费用描述")
     private String costDescribe;
-
+    @Schema(description = "审核状态")//:0-申请审核;1-审核通过;2-审核未通过
     private Integer approved;
-
+    @Schema(description = "审核描述")
     private String reviewDescription;
-
+    @Schema(description = "是否有效")//:0-生效中;1-已失效
     private int isValid;
-
+    @Schema(description = "是否启用")//:0-启用;1-停用
     private int isEnabled;
-
+    @Schema(description = "费用规则")
     private String costRules;
-
+    @Schema(description = "审核时间")
     private LocalDateTime auditTime;
-
+    @Schema(description = "审核人")
     private String auditPerson;
 
 }

+ 63 - 4
commons/src/main/java/com/jzg/commons/util/comparble/CompatibleUtils.java

@@ -112,6 +112,32 @@ public class CompatibleUtils {
         FIELD_DESCRIPTION_MAP.put("auditPerson", "审核人");
     }
 
+    /** PO 状态字段码值映射(用于操作轨迹 compareResultList 中文展示) */
+    private static final Map<String, String> APPROVED_MAP = new HashMap<>();
+    static {
+        APPROVED_MAP.put("0", "申请审核");
+        APPROVED_MAP.put("1", "审核通过");
+        APPROVED_MAP.put("2", "审核未通过");
+    }
+
+    private static final Map<String, String> AUDIT_METHOD_MAP = new HashMap<>();
+    static {
+        AUDIT_METHOD_MAP.put("0", "自动审核");
+        AUDIT_METHOD_MAP.put("1", "手动审核");
+    }
+
+    private static final Map<String, String> IS_VALID_MAP = new HashMap<>();
+    static {
+        IS_VALID_MAP.put("0", "生效中");
+        IS_VALID_MAP.put("1", "已失效");
+    }
+
+    private static final Map<String, String> IS_ENABLED_MAP = new HashMap<>();
+    static {
+        IS_ENABLED_MAP.put("0", "启用");
+        IS_ENABLED_MAP.put("1", "停用");
+    }
+
     // ============ 字典解析器(由外部注入) ============
     private static DictLabelResolver dictLabelResolver;
 
@@ -418,8 +444,12 @@ public class CompatibleUtils {
                     results.add(buildCompareResult(entityName, key, displayOld, displayNew));
                 }
             } else {
-                String newValue = getValue(newData);
-                String oldValue = getValue(oldData);
+                // 先 getValue 做类型归一化(时间戳、LocalDateTime、BigDecimal...)
+                String rawNew = getValue(newData);
+                String rawOld = getValue(oldData);
+                // 再字典转换(PO 状态 int → 中文描述)
+                String newValue = convertDictValue(key, rawNew != null ? rawNew : newData, attrNameMap, dictLabelMap);
+                String oldValue = convertDictValue(key, rawOld != null ? rawOld : oldData, attrNameMap, dictLabelMap);
                 if (StringUtils.isNotEmpty(newValue) && !Objects.equals(oldValue, newValue)) {
                     String displayOld = (oldValue == null) ? "(空)" : oldValue;
                     results.add(buildCompareResult(entityName, key, displayOld, newValue));
@@ -742,6 +772,18 @@ public class CompatibleUtils {
                 value = new java.math.BigDecimal(value).stripTrailingZeros().toPlainString();
             } catch (NumberFormatException ignored) { }
         }
+        // ★ 时间戳字符串转日期(13位毫秒时间戳,落在合理日期范围)
+        if (value.matches("^\\d{13}$")) {
+            try {
+                long ts = Long.parseLong(value);
+                if (ts >= 946684800000L && ts <= 4102444800000L) {
+                    return LocalDateTime.ofInstant(
+                            java.time.Instant.ofEpochMilli(ts),
+                            java.time.ZoneId.systemDefault()
+                    ).format(DATE_TIME_FORMATTER);
+                }
+            } catch (NumberFormatException ignored) { }
+        }
 
         // 1) 操作符
         if ("operator".equals(fieldKey)) {
@@ -786,8 +828,25 @@ public class CompatibleUtils {
             }
         }
 
-        // 6) 非字典字段直接返回原始值,不做通用字典匹配
-        //    避免数值字段(如 inlet=2)被其他字典的 code 错误匹配
+        // 6) approved → 审核状态
+        if ("approved".equals(fieldKey)) {
+            return APPROVED_MAP.getOrDefault(value, value);
+        }
+        // 7) auditMethod → 审核方式
+        if ("auditMethod".equals(fieldKey)) {
+            return AUDIT_METHOD_MAP.getOrDefault(value, value);
+        }
+        // 8) isValid → 是否有效
+        if ("isValid".equals(fieldKey)) {
+            return IS_VALID_MAP.getOrDefault(value, value);
+        }
+        // 9) isEnabled → 是否启用
+        if ("isEnabled".equals(fieldKey)) {
+            return IS_ENABLED_MAP.getOrDefault(value, value);
+        }
+
+        // 10) 非字典字段直接返回原始值,不做通用字典匹配
+        //     避免数值字段(如 inlet=2)被其他字典的 code 错误匹配
         return value;
     }
 

+ 74 - 110
tenant/costsorrule/src/main/java/com/jzg/costsorrule/service/impl/RuleServiceImpl.java

@@ -3,21 +3,17 @@ package com.jzg.costsorrule.service.impl;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.jzg.commons.entity.agreement.dispatch.dto.PtlAgreementDispatchRulesAttrLink;
-import com.jzg.commons.entity.agreement.dispatch.vo.ValidateDispatchRuleVo;
 import com.jzg.commons.entity.po.PtlAgreementUndwrtRulesAttr;
 import com.jzg.commons.entity.scheme.po.PtlSchemeRulesAttrLink;
-import com.jzg.costsorrule.client.QuoteClient;
 import com.jzg.costsorrule.constants.AttrTypeConstant;
 import com.jzg.costsorrule.constants.OperatorConstant;
 import com.jzg.costsorrule.model.RuleAttrLinkVo;
 import com.jzg.costsorrule.service.RuleService;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 import java.time.LocalDateTime;
 import java.time.format.DateTimeFormatter;
 import java.util.*;
-import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.stream.Collectors;
 
 @Service
@@ -28,52 +24,51 @@ public class RuleServiceImpl implements RuleService {
 
     /**
      * 预处理数据
+     *
      * @param attrMap
      * @param linkVos
      * @return
      */
-    private void dealData(Map<String,String> attrMap, List<RuleAttrLinkVo> linkVos){
+    private void dealData(Map<String, String> attrMap, List<RuleAttrLinkVo> linkVos) {
         //需要截取的字符串
-        Set<String> idNumbers = Set.of("OwnersInfoIdentifyNumber", "ApplicantIDNumber", "InsuredIDNumber","LicenseNo")
-                .stream().map(String::toLowerCase).collect(Collectors.toSet());
+        Set<String> idNumbers = Set.of("OwnersInfoIdentifyNumber", "ApplicantIDNumber", "InsuredIDNumber", "LicenseNo").stream().map(String::toLowerCase).collect(Collectors.toSet());
         //boolean 类型的转换
-        Set<String> inputTags = Set.of("NewEnergyMark")
-                .stream().map(String::toLowerCase).collect(Collectors.toSet());
-        linkVos.forEach(vo->{
-            if(idNumbers.contains(vo.getAttrCode())){
+        Set<String> inputTags = Set.of("NewEnergyMark").stream().map(String::toLowerCase).collect(Collectors.toSet());
+        linkVos.forEach(vo -> {
+            if (idNumbers.contains(vo.getAttrCode())) {
                 String value = attrMap.get(vo.getAttrCode().toLowerCase());
                 String substring = value.substring(0, vo.getMin().length());
-                attrMap.put(vo.getAttrCode(),substring);
+                attrMap.put(vo.getAttrCode(), substring);
             }
-            if(inputTags.contains(vo.getAttrCode())){
+            if (inputTags.contains(vo.getAttrCode())) {
                 String value = attrMap.get(vo.getAttrCode().toLowerCase());
-                if("false".equals(value)){
-                    attrMap.put(vo.getAttrCode(),"0");
-                }else if("true".equals(value)){
-                    attrMap.put(vo.getAttrCode(),"1");
+                if ("false".equals(value)) {
+                    attrMap.put(vo.getAttrCode(), "0");
+                } else if ("true".equals(value)) {
+                    attrMap.put(vo.getAttrCode(), "1");
                 }
             }
         });
         //处理险种ProductCode-InsruanceProduct 不匹配的情况
-        attrMap.put("insruanceproduct",attrMap.get("productcode"));
+        attrMap.put("insruanceproduct", attrMap.get("productcode"));
 
 
     }
 
     @Override
-    public boolean verificationRule(Map<String,String> maps, List<RuleAttrLinkVo> linkVos,List<PtlAgreementUndwrtRulesAttr> rulesAttrs, StringBuilder logs) {
+    public boolean verificationRule(Map<String, String> maps, List<RuleAttrLinkVo> linkVos, List<PtlAgreementUndwrtRulesAttr> rulesAttrs, StringBuilder logs) {
         //预处理数据
-        dealData(maps,linkVos);
+        dealData(maps, linkVos);
         //匹配费用因子
         for (int i = 0; i < linkVos.size(); i++) {
             //判断是否匹配
 //            logs.append("费用id:" + agreementProductCosts.get(i).getId() + "\n");
 //            logs.append("费用因子描述:" + agreementProductCosts.get(i).getCostsDescription() + "\n");
 //            String attrCode = linkVos.get(i).getAttrCode();
-            if(linkVos.get(i).getAttrCode() != null) {
+            if (linkVos.get(i).getAttrCode() != null) {
                 String attrValue = maps.get(linkVos.get(i).getAttrCode().toLowerCase());
                 int finalI = i;
-                PtlAgreementUndwrtRulesAttr rulesAttr = rulesAttrs.stream().filter(value -> value.getAttrCode().toLowerCase().equals(linkVos.get(finalI).getAttrCode().toLowerCase())).findFirst().orElse(null);
+                PtlAgreementUndwrtRulesAttr rulesAttr = rulesAttrs.stream().filter(value -> value.getAttrCode().equalsIgnoreCase(linkVos.get(finalI).getAttrCode())).findFirst().orElse(null);
                 if (Objects.isNull(attrValue) || Objects.isNull(rulesAttr)) {
                     return false;
                 }
@@ -90,25 +85,21 @@ public class RuleServiceImpl implements RuleService {
 
     /**
      * 匹配费用因子
+     *
      * @param value     表单值
      * @param linkVo    费用因子
      * @param rulesAttr 规则因子
      * @param logs      日志
      * @return
      */
-    private boolean judgements(String value,
-                               RuleAttrLinkVo linkVo,
-                               PtlAgreementUndwrtRulesAttr rulesAttr,
-                               StringBuilder logs) {
+    private boolean judgements(String value, RuleAttrLinkVo linkVo, PtlAgreementUndwrtRulesAttr rulesAttr, StringBuilder logs) {
 
         boolean useFlag = attrEqual(value, linkVo, rulesAttr);
         return useFlag;
     }
 
 
-
-
-    private boolean attrEqual(String value,RuleAttrLinkVo linkVo,PtlAgreementUndwrtRulesAttr rulesAttr) {
+    private boolean attrEqual(String value, RuleAttrLinkVo linkVo, PtlAgreementUndwrtRulesAttr rulesAttr) {
         if (rulesAttr.getAttrType().equals(AttrTypeConstant.CHECKBOX.getCode())) {
             return checkBoxEqual(linkVo, value);
         } else if (rulesAttr.getAttrType().equals(AttrTypeConstant.INPUTNUMBER.getCode())) {
@@ -119,7 +110,7 @@ public class RuleServiceImpl implements RuleService {
             return selectEqual(linkVo, value);
         } else if (rulesAttr.getAttrType().equals(AttrTypeConstant.RADIO.getCode())) {
             return radioEqual(linkVo, value);
-        } else if (rulesAttr.getAttrType().equals(AttrTypeConstant.DATETIME.getCode())){
+        } else if (rulesAttr.getAttrType().equals(AttrTypeConstant.DATETIME.getCode())) {
             return dateTimeEqual(linkVo, value);
         }
 
@@ -131,11 +122,10 @@ public class RuleServiceImpl implements RuleService {
         if (min == null || min.isEmpty()) {
             return false;
         }
-        boolean contains = Arrays.stream(min.split(","))
-                .anyMatch(sp -> sp.trim().equals(value.trim()));
+        boolean contains = Arrays.stream(min.split(",")).anyMatch(sp -> sp.trim().equals(value.trim()));
         // "1"(EQ):在列表中匹配;"6"(NE):不在列表中匹配
         boolean isEqgate = OperatorConstant.InputNumber.EQ.getCode().equals(linkVo.getOperator());
-        return isEqgate ? contains : !contains;
+        return isEqgate == contains;
     }
 
     private boolean inputNumberEqual(RuleAttrLinkVo linkVo, String value) {
@@ -144,29 +134,17 @@ public class RuleServiceImpl implements RuleService {
         double max = linkVo.getMax() != null ? Double.parseDouble(linkVo.getMax()) : Double.MAX_VALUE;
         //统一处理数值
         if (OperatorConstant.InputNumber.EQ.getCode().equals(linkVo.getOperator())) {
-            if (min <= v && max >= v) {
-                return true;
-            }
+            return min <= v && max >= v;
         } else if (OperatorConstant.InputNumber.LT.getCode().equals(linkVo.getOperator())) {
-            if (min > v) {
-                return true;
-            }
+            return min > v;
         } else if (OperatorConstant.InputNumber.LE.getCode().equals(linkVo.getOperator())) {
-            if (min >= v) {
-                return true;
-            }
+            return min >= v;
         } else if (OperatorConstant.InputNumber.GT.getCode().equals(linkVo.getOperator())) {
-            if (max < v) {
-                return true;
-            }
+            return max < v;
         } else if (OperatorConstant.InputNumber.GE.getCode().equals(linkVo.getOperator())) {
-            if (max <= v) {
-                return true;
-            }
+            return max <= v;
         } else if (OperatorConstant.InputNumber.NE.getCode().equals(linkVo.getOperator())) {// 不包含:不在 [min, max] 区间内
-            if (min > v || max < v) {
-                return true;
-            }
+            return min > v || max < v;
         }
         return false;
     }
@@ -178,8 +156,7 @@ public class RuleServiceImpl implements RuleService {
             return false;
         }
         String[] split = min.split(",");
-        List<String> equalsMap = Arrays.asList(
-                "CharacterBasedRating", "JqCharacterBasedRating", "SyCharacterBasedRating");
+        List<String> equalsMap = Arrays.asList("CharacterBasedRating", "JqCharacterBasedRating", "SyCharacterBasedRating");
         boolean matched;
         if (equalsMap.contains(linkVo.getAttrCode())) {
             matched = Arrays.stream(split).anyMatch(value::equals);
@@ -187,7 +164,7 @@ public class RuleServiceImpl implements RuleService {
             matched = Arrays.stream(split).anyMatch(value::contains);
         }
         boolean isEqgate = OperatorConstant.InputNumber.EQ.getCode().equals(linkVo.getOperator());
-        return isEqgate ? matched : !matched;
+        return isEqgate == matched;
     }
 
 
@@ -198,7 +175,7 @@ public class RuleServiceImpl implements RuleService {
         }
         boolean contains = min.contains(value);
         boolean isEqgate = OperatorConstant.InputNumber.EQ.getCode().equals(linkVo.getOperator());
-        return isEqgate ? contains : !contains;
+        return isEqgate == contains;
     }
 
     private boolean radioEqual(RuleAttrLinkVo linkVo, String value) {
@@ -206,9 +183,11 @@ public class RuleServiceImpl implements RuleService {
             //判断如果value 是 boolean值 则将min进行转换为bool
             boolean minValue = Boolean.valueOf(linkVo.getMin());
             boolean valueBool = Boolean.valueOf(value);
-            if (linkVo.getMin().equals("5") || linkVo.getMin().equals("6")) {
-                minValue = linkVo.getMin().equals("5") ? false : true;
-                valueBool = value.equals("5") ? false : true;
+            if (linkVo.getMin() != null) {
+                if (linkVo.getMin().equals("5") || linkVo.getMin().equals("6")) {
+                    minValue = !linkVo.getMin().equals("5");
+                    valueBool = !value.equals("5");
+                }
             }
             if (linkVo.getOperator().equals(OperatorConstant.InputNumber.EQ.getCode())) {
                 return minValue == valueBool;
@@ -216,48 +195,36 @@ public class RuleServiceImpl implements RuleService {
                 return !(minValue == valueBool);
             }
         }
-        return linkVo.getOperator().equals(OperatorConstant.InputNumber.EQ.getCode()) ? linkVo.getMin().contains(value) : !linkVo.getMin().contains(value);
+        return linkVo.getOperator().equals(OperatorConstant.InputNumber.EQ.getCode()) == linkVo.getMin().contains(value);
     }
 
-    public boolean dateTimeEqual(RuleAttrLinkVo linkVo, String value){
+    public boolean dateTimeEqual(RuleAttrLinkVo linkVo, String value) {
         DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
-        if(Objects.isNull(value) || value.equals("")){
+        if (Objects.isNull(value) || value.equals("")) {
             return false;
         }
-        LocalDateTime v = LocalDateTime.parse(value,formatter);
-        LocalDateTime min = null,max = null;
-        if(!Objects.isNull(linkVo.getMin())){
-            min = LocalDateTime.parse(linkVo.getMin(),formatter);
+        LocalDateTime v = LocalDateTime.parse(value, formatter);
+        LocalDateTime min = null, max = null;
+        if (!Objects.isNull(linkVo.getMin())) {
+            min = LocalDateTime.parse(linkVo.getMin(), formatter);
         }
-        if(!Objects.isNull(linkVo.getMax())){
-            max = LocalDateTime.parse(linkVo.getMax(),formatter);
+        if (!Objects.isNull(linkVo.getMax())) {
+            max = LocalDateTime.parse(linkVo.getMax(), formatter);
         }
 
         //统一处理数值
         if (OperatorConstant.DateTime.EQ.getCode().equals(linkVo.getOperator())) {
-            if (v.isAfter(min) && v.isBefore(max)) {
-                return true;
-            }
+            return v.isAfter(min) && v.isBefore(max);
         } else if (OperatorConstant.DateTime.LT.getCode().equals(linkVo.getOperator())) {
-            if (v.isBefore(min)) {
-                return true;
-            }
+            return v.isBefore(min);
         } else if (OperatorConstant.DateTime.LE.getCode().equals(linkVo.getOperator())) {
-            if (v.isBefore(min) || v.isEqual(min)) {
-                return true;
-            }
+            return v.isBefore(min) || v.isEqual(min);
         } else if (OperatorConstant.DateTime.GT.getCode().equals(linkVo.getOperator())) {
-            if (v.isAfter(max)) {
-                return true;
-            }
+            return v.isAfter(max);
         } else if (OperatorConstant.DateTime.GE.getCode().equals(linkVo.getOperator())) {
-            if (v.isAfter(max) || v.isEqual(max)) {
-                return true;
-            }
+            return v.isAfter(max) || v.isEqual(max);
         } else if (OperatorConstant.DateTime.NE.getCode().equals(linkVo.getOperator())) {
-            if (!(v.isAfter(min) && v.isBefore(max))) {
-                return true;
-            }
+            return !(v.isAfter(min) && v.isBefore(max));
         }
         return false;
     }
@@ -266,7 +233,7 @@ public class RuleServiceImpl implements RuleService {
     //region  表单转换成json对象
 
     @Override
-    public void traverseJsonObject(JSONObject jsonObject, HashMap<String,String> attrMap) {
+    public void traverseJsonObject(JSONObject jsonObject, HashMap<String, String> attrMap) {
         if (Objects.isNull(jsonObject)) {
             return;
         }
@@ -275,24 +242,23 @@ public class RuleServiceImpl implements RuleService {
             String key = entry.getKey();
             Object value = entry.getValue();
 
-            if(!(value instanceof JSONObject) && !(value instanceof JSONArray)){
-                attrMap.put(key.toLowerCase(),value.toString());
+            if (!(value instanceof JSONObject) && !(value instanceof JSONArray)) {
+                attrMap.put(key.toLowerCase(), value.toString());
             }
 
             // 如果值是嵌套的 JSONObject,递归遍历
             if (value instanceof JSONObject) {
-                if(isUserKey(key))
-                {
-                    traverseJsonObject((JSONObject) value,attrMap,key);
-                }else{
-                    traverseJsonObject((JSONObject) value,attrMap);
+                if (isUserKey(key)) {
+                    traverseJsonObject((JSONObject) value, attrMap, key);
+                } else {
+                    traverseJsonObject((JSONObject) value, attrMap);
                 }
             }
 
             // 如果值是嵌套的数组(JSONArray),遍历数组
             if (value instanceof JSONArray) {
                 System.out.println("Nested JSONArray for key: " + key);
-                traverseJsonArray((JSONArray) value,attrMap);
+                traverseJsonArray((JSONArray) value, attrMap);
             }
         }
 
@@ -304,11 +270,12 @@ public class RuleServiceImpl implements RuleService {
 
     /**
      * 处理车主 投保人 被保人信息
+     *
      * @param jsonObject
      * @param attrMap
      * @param parentKey
      */
-    public void traverseJsonObject(JSONObject jsonObject,HashMap<String,String> attrMap,String parentKey) {
+    public void traverseJsonObject(JSONObject jsonObject, HashMap<String, String> attrMap, String parentKey) {
         if (Objects.isNull(jsonObject)) {
             return;
         }
@@ -316,13 +283,13 @@ public class RuleServiceImpl implements RuleService {
             String key = entry.getKey();
             Object value = entry.getValue();
 
-            if(!(value instanceof JSONObject) && !(value instanceof JSONArray)){
-                attrMap.put(parentKey.toLowerCase() + key.toLowerCase(),value.toString());
+            if (!(value instanceof JSONObject) && !(value instanceof JSONArray)) {
+                attrMap.put(parentKey.toLowerCase() + key.toLowerCase(), value.toString());
             }
         }
     }
 
-    public void traverseJsonArray(JSONArray jsonArray,HashMap<String,String> attrMap) {
+    public void traverseJsonArray(JSONArray jsonArray, HashMap<String, String> attrMap) {
         if (jsonArray == null) {
             System.out.println("JSONArray is null.");
             return;
@@ -338,37 +305,34 @@ public class RuleServiceImpl implements RuleService {
             // 如果元素是嵌套的 JSONObject,递归遍历
             if (element instanceof JSONObject) {
                 System.out.println("Nested JSONObject in array at index: " + i);
-                traverseJsonObject((JSONObject) element,attrMap);
+                traverseJsonObject((JSONObject) element, attrMap);
             }
 
             // 如果元素是嵌套的数组(JSONArray),递归遍历
             if (element instanceof JSONArray) {
                 System.out.println("Nested JSONArray in array at index: " + i);
-                traverseJsonArray((JSONArray) element,attrMap);
+                traverseJsonArray((JSONArray) element, attrMap);
             }
         }
     }
 
     //判断是否是车主 投保人 被保人信息
-    public boolean isUserKey(String key){
-        if(key.equals("ownersInfo") || key.equals("policyHolderInfo") || key.equals("insuredPersonInfo")){
-            return true;
-        }
-        return false;
+    public boolean isUserKey(String key) {
+        return key.equals("ownersInfo") || key.equals("policyHolderInfo") || key.equals("insuredPersonInfo");
     }
 
     //endregion
 
 
     @Override
-    public Map<String, List<RuleAttrLinkVo>> convertSchemeRule(Map<String, List<PtlSchemeRulesAttrLink>> schemeRules){
+    public Map<String, List<RuleAttrLinkVo>> convertSchemeRule(Map<String, List<PtlSchemeRulesAttrLink>> schemeRules) {
         Map<String, List<RuleAttrLinkVo>> convertMaps = new HashMap<>();
         for (Map.Entry<String, List<PtlSchemeRulesAttrLink>> entry : schemeRules.entrySet()) {
             String key = entry.getKey();
             List<RuleAttrLinkVo> vos = new ArrayList<>();
             List<PtlSchemeRulesAttrLink> values = entry.getValue();
 
-            values.forEach(value->{
+            values.forEach(value -> {
                 RuleAttrLinkVo vo = new RuleAttrLinkVo();
                 vo.setMin(value.getMin());
                 vo.setMax(value.getMax());
@@ -377,7 +341,7 @@ public class RuleServiceImpl implements RuleService {
                 vo.setMinArray(value.getMinArray().toArray(new String[0]));
                 vos.add(vo);
             });
-            convertMaps.put(key,vos);
+            convertMaps.put(key, vos);
         }
         return convertMaps;
     }
@@ -390,7 +354,7 @@ public class RuleServiceImpl implements RuleService {
             List<RuleAttrLinkVo> vos = new ArrayList<>();
             List<PtlAgreementDispatchRulesAttrLink> values = entry.getValue();
 
-            values.forEach(value->{
+            values.forEach(value -> {
                 RuleAttrLinkVo vo = new RuleAttrLinkVo();
                 vo.setMin(value.getMin());
                 vo.setMax(value.getMax());
@@ -399,7 +363,7 @@ public class RuleServiceImpl implements RuleService {
                 vo.setMinArray(value.getMinArray().toArray(new String[0]));
                 vos.add(vo);
             });
-            convertMaps.put(key,vos);
+            convertMaps.put(key, vos);
         }
         return convertMaps;
     }

+ 25 - 4
tenant/insurance/quotation-dadi/src/main/java/com/jzg/quotation/dadi/crawler/build/DaDiCrawlerQuoteResultVoBuild.java

@@ -205,15 +205,16 @@ public class DaDiCrawlerQuoteResultVoBuild {
         int sumPayment = daDiQuoteResponse.getInsurancePlan().getTax().getSumPayment();
         quoteResultsVo.getCosts().setVvTax(String.valueOf(sumPayment));
         int niPremium = 0;
-        //设置非车保费
+
+        //设置非车保费:优先取保险计划的 wealthAccPremium,取不到(为0)时兜底取保险责任项(jointSalesSolutionItems)的 defaultValue 之和
         if (daDiQuoteResponse.getInsurancePlan().getAccidentInsure() != null && daDiQuoteResponse.getInsurancePlan().getAccidentInsure().size() > 0) {
-            niPremium = daDiQuoteResponse.getInsurancePlan().getAccidentInsure().get(0).getWealthAccPremium();
+            niPremium = calcNonVehiclePremium(daDiQuoteResponse.getInsurancePlan().getAccidentInsure());
             quoteResultsVo.getCosts().setNiPremium(String.valueOf(niPremium));
         } else if (daDiQuoteResponse.getInsurancePlan().getHealthInsurance() != null && daDiQuoteResponse.getInsurancePlan().getHealthInsurance().size() > 0) {
-            niPremium = daDiQuoteResponse.getInsurancePlan().getHealthInsurance().get(0).getWealthAccPremium();
+            niPremium = calcNonVehiclePremium(daDiQuoteResponse.getInsurancePlan().getHealthInsurance());
             quoteResultsVo.getCosts().setNiPremium(String.valueOf(niPremium));
         } else if (daDiQuoteResponse.getInsurancePlan().getPropertyInsurance() != null && daDiQuoteResponse.getInsurancePlan().getPropertyInsurance().size() > 0) {
-            niPremium = daDiQuoteResponse.getInsurancePlan().getPropertyInsurance().get(0).getWealthAccPremium();
+            niPremium = calcNonVehiclePremium(daDiQuoteResponse.getInsurancePlan().getPropertyInsurance());
             quoteResultsVo.getCosts().setNiPremium(String.valueOf(niPremium));
         }
 
@@ -227,4 +228,24 @@ public class DaDiCrawlerQuoteResultVoBuild {
         quoteResultsVo.getCosts().setSumPremium(String.valueOf(sumPremium));
     }
 
+    /**
+     * 计算非车险(联合销售/驾意险)保费
+     * 优先取保险计划的 wealthAccPremium,取不到(为0)时兜底取保险责任项(jointSalesSolutionItems)的 defaultValue 之和
+     */
+    private static int calcNonVehiclePremium(List<DaDiQuoteResponse.InsurancePlanDTO.AccidentInsureDTO> insuranceList) {
+        if (insuranceList == null || insuranceList.isEmpty()) {
+            return 0;
+        }
+        int premium = insuranceList.get(0).getWealthAccPremium();
+        if (premium <= 0) {
+            premium = insuranceList.stream()
+                    .filter(Objects::nonNull)
+                    .filter(item -> item.getJointSalesSolutionItems() != null)
+                    .flatMap(item -> item.getJointSalesSolutionItems().stream())
+                    .mapToInt(DaDiQuoteResponse.InsurancePlanDTO.AccidentInsureDTO.JointSalesSolutionItemsDTO::getDefaultValue)
+                    .sum();
+        }
+        return premium;
+    }
+
 }

+ 68 - 13
tenant/insurance/quotation-taiping/src/main/java/com/jzg/quotation/taiping/crawler/entity/request/TaiPingCrawlerPremiumCalculateRequest.java

@@ -116,7 +116,8 @@ public class TaiPingCrawlerPremiumCalculateRequest {
         Optional.ofNullable(quoteVo.getCiRiskInfoVo()).ifPresent(ciRiskInfoVo -> {
             this.pfItemKind0801DtoList = List.of(PfItemKind0801DtoListDTO.getCiKindInfo());
         });
-        this.pfItemKind0802DtoList = PfItemKind0802DtoListDTO.buildKindList(quoteVo.getKindInfoVo(),carActualValue,Integer.parseInt(quoteVo.getCarInfoVo().getSeatCount()));
+        boolean isNewEnergy = !quoteVo.getCarInfoVo().getEnergyTypeCode().equals("0") && !quoteVo.getCarInfoVo().getEnergyTypeCode().equals("4");
+        this.pfItemKind0802DtoList = PfItemKind0802DtoListDTO.buildKindList(quoteVo.getKindInfoVo(),carActualValue,Integer.parseInt(quoteVo.getCarInfoVo().getSeatCount()),isNewEnergy);
         this.clauseList0801 = new ArrayList<>();
         this.clauseList0802 = new ArrayList<>();
         this.orderNo = orderNo;
@@ -144,12 +145,14 @@ public class TaiPingCrawlerPremiumCalculateRequest {
         // 驾意险
         this.fcProductList = new ArrayList<>();
         this.cjcSaleInfoDto = new Object();
-        this.fCsaleinfoDto = new FCsaleinfoDTO(record, parameters,taiPingCrawlerFindSolutionCodeData,orderNo);
+        if (quoteVo.getAccidentalDrivings()!=null && !quoteVo.getAccidentalDrivings().isEmpty()) {
+            this.fCsaleinfoDto = new FCsaleinfoDTO(record, parameters,taiPingCrawlerFindSolutionCodeData,orderNo);
+        }
         this.businessType = "Proposal";
         this.optType = "N";
         this.personInd = "C";
         this.productType = "1";
-        this.isMatchClause = true;
+//        this.isMatchClause = true;
     }
 
     @NoArgsConstructor
@@ -2106,7 +2109,7 @@ public class TaiPingCrawlerPremiumCalculateRequest {
         @JsonProperty("serviceTimes")
         private String serviceTimes;
 
-        public static List<PfItemKind0802DtoListDTO> buildKindList(List<KindInfoVo> kindInfoVoList,String actualValue,Integer seatCount) {
+        public static List<PfItemKind0802DtoListDTO> buildKindList(List<KindInfoVo> kindInfoVoList,String actualValue,Integer seatCount,boolean isNewEnergy) {
             List<PfItemKind0802DtoListDTO> kindList = new ArrayList<>();
             for (KindInfoVo kindInfoVo : kindInfoVoList) {
                 PfItemKind0802DtoListDTO kind = new PfItemKind0802DtoListDTO();
@@ -2115,6 +2118,7 @@ public class TaiPingCrawlerPremiumCalculateRequest {
                 if (kindCodeEnum.getKindInd().equals("1")) {
                     kind.setRiskCode("0802");
                 }
+                kind.setKindName(kindInfoVo.getKindName());
                 kind.setKindInd(kindCodeEnum.getKindInd());
                 kind.setKindCode(kindCode);
                 kind.setShortRate(100);
@@ -2123,17 +2127,27 @@ public class TaiPingCrawlerPremiumCalculateRequest {
                 kind.setRelatedInd("0");
                 kind.setRelatedFlagFG2020("0");
                 kind.setRelatedFlagFG2020Type(false);
-                kind.setValueType("");
+                kind.setValueType(null);
                 kind.setClauseType(false);
                 kind.setNoChange(true);
+                kind.setShareModel("0");
                 kind.setSumInsured(kindInfoVo.getAmount());
                 kind.setUnitInsured(kindInfoVo.getAmount());
+                if (kindInfoVo.getDeductibleRate().equals("0")) {
+                    kind.setDeductible("0");
+                }
                 // 车损险
                 if (kindCodeEnum.getKindCode().equals("0301200") || kindCodeEnum.getKindCode().equals("0401200")) {
                     kind.setSumInsured(actualValue);
                     kind.setMax(actualValue);
-                    kind.setDisplayNo(0);
-                    kind.setSrcIndex(0);
+                    if (kindCodeEnum.getKindCode().equals("0301200")) {
+                        kind.setDisplayNo(0);
+                        kind.setSrcIndex(0);
+                    }
+                    if (kindCodeEnum.getKindCode().equals("0401200")) {
+                        kind.setDisplayNo(1);
+                        kind.setSrcIndex(1);
+                    }
                     kind.setDeductible("0");
                     kind.setDeductibleRate("");
                     kind.setRelatedFlagFG2020("1");
@@ -2142,25 +2156,66 @@ public class TaiPingCrawlerPremiumCalculateRequest {
                 // 三者险
                 if (kindCodeEnum.getKindCode().equals("0301600") || kindCodeEnum.getKindCode().equals("0401600")) {
                     kind.setSumInsured(kindInfoVo.getAmount());
-                    kind.setDisplayNo(2);
-                    kind.setSrcIndex(2);
+                    kind.setDisplayNo(0);
+                    kind.setSrcIndex(0);
+                }
+                // 医保外三者
+                if (kindCodeEnum.getKindCode().equals("0301002") && !isNewEnergy) {
+                    kind.setDisplayNo(1);
+                    kind.setSrcIndex(1);
                 }
-                // 司机
+                if (kindCodeEnum.getKindCode().equals("0301002") && isNewEnergy) {
+                    kind.setDisplayNo(4);
+                    kind.setSrcIndex(4);
+                }
+                // 机动车车上人员责任保险(司机)
                 if (kindCodeEnum.getKindCode().equals("0301701") || kindCodeEnum.getKindCode().equals("0401701") || kindCodeEnum.getKindCode().equals("0301011")) {
                     kind.setQuantity(1);
                     kind.setUnitInsured(kindInfoVo.getUnitAmount());
                     kind.setSumInsured(kindInfoVo.getAmount());
-                    kind.setDisplayNo(4);
-                    kind.setSrcIndex(4);
+                    kind.setDisplayNo(2);
+                    kind.setSrcIndex(2);
+                }
+                // 医保外司机
+                if (kindCodeEnum.getKindCode().equals("0301011") && !isNewEnergy) {
+                    kind.setDisplayNo(3);
+                    kind.setSrcIndex(3);
                 }
-                // 乘客
+                if (kindCodeEnum.getKindCode().equals("0301011") && isNewEnergy) {
+                    kind.setDisplayNo(5);
+                    kind.setSrcIndex(5);
+                }
+                // 机动车车上人员责任保险(乘客)
                 if (kindCodeEnum.getKindCode().equals("0301702") || kindCodeEnum.getKindCode().equals("0401702") || kindCodeEnum.getKindCode().equals("0301012")) {
                     kind.setQuantity(seatCount - 1);
                     kind.setUnitInsured(kindInfoVo.getUnitAmount());
                     kind.setSumInsured(String.valueOf(new BigDecimal(kindInfoVo.getUnitAmount()).multiply(new BigDecimal(seatCount - 1))));
+                    kind.setDisplayNo(4);
+                    kind.setSrcIndex(4);
+                    if (isNewEnergy) {
+                        kind.setSrcIndex(3);
+                        kind.setDisplayNo(3);
+                    }
+                }
+                // 医保外乘客
+                if (kindCodeEnum.getKindCode().equals("0301012") && !isNewEnergy) {
+                    kind.setSrcIndex(5);
+                    kind.setDisplayNo(5);
+                }
+                if (kindCodeEnum.getKindCode().equals("0301012") && isNewEnergy) {
                     kind.setDisplayNo(6);
                     kind.setSrcIndex(6);
                 }
+                // 车身划痕
+                if (kindCodeEnum.getKindCode().equals("0301210")) {
+                    kind.setSrcIndex(1);
+                    kind.setDisplayNo(1);
+                }
+                // 附加电网故障损失险
+                if (kindCodeEnum.getKindCode().equals("0401201")) {
+                    kind.setDisplayNo(4);
+                    kind.setSrcIndex(4);
+                }
                 // 绝对免赔率
                 if (kindCodeEnum.getKindCode().equals("0301008") || kindCodeEnum.getKindCode().equals("0301009") || kindCodeEnum.getKindCode().equals("0301010")) {
                     kind.setDeductible(kindInfoVo.getDeductibleRate());

+ 1 - 1
tenant/insurance/quotation-taiping/src/main/java/com/jzg/quotation/taiping/crawler/service/impl/TaipingCrawlerRequestImpl.java

@@ -538,7 +538,7 @@ public class TaipingCrawlerRequestImpl implements TaipingCrawlerRequest {
             // 人工核保
             underwritingResultsVo.setUnderwritingResult("人工核保");
             underwritingResultsVo.setUnderwritingStatus(InsOrderStatusEnum.STAFF_PROCESS);
-        } else if ("2".equals(jqUnderWriteInd) || "2".equals(syUnderWriteInd)) {
+        } else if ("2".equals(jqUnderWriteInd) || "2".equals(syUnderWriteInd) || "0".equals(jqUnderWriteInd) || "0".equals(syUnderWriteInd)) {
             // 核保失败
             underwritingResultsVo.setUnderwritingStatus(InsOrderStatusEnum.AUDIT_FAIL);
             underwritingResultsVo.setUnderwritingResult("核保失败");

+ 6 - 6
tenant/insurance/quotation-yongcheng/src/main/java/com/jzg/quotation/yongcheng/api/entity/request/QuoteRequest.java

@@ -1670,7 +1670,7 @@ public class QuoteRequest {
             @JacksonXmlProperty(localName = "CMassCarMrk")
             private String CMassCarMrk;
 
-            public Applicant(CustomerInfoVo ownerInfo, CustomerInfoVo policyHolderInfo,YcApiConfigurationProperties ycApiConfigurationProperties) {
+            public Applicant(CustomerInfoVo ownerInfo, CustomerInfoVo policyHolderInfo,CustomerInfoVo insuredPersonInfo, YcApiConfigurationProperties ycApiConfigurationProperties) {
 
                 //投保人类型: 0:法人 1:个人(中国籍) 2: 个人(非中国籍)
                 String property = policyHolderInfo.getProperty();
@@ -1724,7 +1724,7 @@ public class QuoteRequest {
                 if(StringUtils.isNotEmpty(this.getCCntrNme())){
                     this.setCCntrNme(policyHolderInfo.getName());
                 }
-                this.setCRelCde(ownerInfo.getName().equals(policyHolderInfo.getName()) ? "601005" : "601008");
+                this.setCRelCde(insuredPersonInfo.getName().equals(policyHolderInfo.getName()) ? "601005" : "601008");
                 this.setTCertfClsValiDate(policyHolderInfo.getIdentifyValidEndDate());
             }
 
@@ -1980,7 +1980,7 @@ public class QuoteRequest {
             @JacksonXmlProperty(localName = "CTrdCde")
             private String CTrdCde;
 
-            public Insured(CustomerInfoVo ownerInfo, CustomerInfoVo insuredPersonInfo) {
+            public Insured(CustomerInfoVo ownerInfo, CustomerInfoVo policyHolderInfo, CustomerInfoVo insuredPersonInfo) {
 
                 //被保人类型: 0:法人 1:个人(中国籍) 2: 个人(非中国籍)
                 String property = insuredPersonInfo.getProperty();
@@ -2017,7 +2017,7 @@ public class QuoteRequest {
                 this.setCCounty(insuredPersonInfo.getCountyCode());
                 this.setTCertfClsValiDate(insuredPersonInfo.getIdentifyValidEndDate());
 //                insured.setCCntrNme(insuredPersonInfo.getName());
-                this.setCRelCdes(ownerInfo.getName().equals(insuredPersonInfo.getName()) ? "601005" : "601008");
+                this.setCRelCdes(policyHolderInfo.getName().equals(insuredPersonInfo.getName()) ? "601005" : "601008");
 
             }
         }
@@ -2258,14 +2258,14 @@ public class QuoteRequest {
          * 投保人信息
          * 代码:applicant
          */
-        Condition.Applicant applicant = new Condition.Applicant(ownerInfo,policyHolderInfo,ycApiConfigurationProperties);
+        Condition.Applicant applicant = new Condition.Applicant(ownerInfo,policyHolderInfo,insuredPersonInfo,ycApiConfigurationProperties);
         condition.setApplicant(applicant);
 
         /**
          * 被保人信息
          * 代码:insured
          */
-        Condition.Insured insured = new Condition.Insured(ownerInfo, insuredPersonInfo);
+        Condition.Insured insured = new Condition.Insured(ownerInfo, policyHolderInfo, insuredPersonInfo);
         condition.setInsured(insured);
 
         /**

+ 4 - 4
tenant/insurance/quotation-zhongmei/src/main/java/com/jzg/quotation/zhongmei/crawler/entity/Request/ZmCrawlerQuotedPriceRequest.java

@@ -690,7 +690,7 @@ public class ZmCrawlerQuotedPriceRequest extends BaseRequest {
                 private Integer analogyPriceTax;
 
                 @JsonProperty("approvedLoad")
-                private Integer approvedLoad;
+                private double approvedLoad;
 
                 @JsonProperty("approvedPassengersCapacity")
                 private Integer approvedPassengersCapacity;
@@ -825,7 +825,7 @@ public class ZmCrawlerQuotedPriceRequest extends BaseRequest {
                 private String series;
 
                 public SimpleStadarCarDTO(ZmCrawlerModelQueryResponse.FullCarDataDTO.FullCarData fullCarData,CarInfoVo carInfo){
-                    this.approvedLoad = fullCarData.getApprovedLoad();
+                    this.approvedLoad = fullCarData.getApprovedLoad() * 1000;
                     this.approvedPassengersCapacity = fullCarData.getApprovedPassengersCapacity();
                     this.brand = fullCarData.getModelName();
                     this.carType = fullCarData.getCarType();
@@ -869,7 +869,7 @@ public class ZmCrawlerQuotedPriceRequest extends BaseRequest {
                 private String modelName;
 
                 @JsonProperty("approvedLoad")
-                private Integer approvedLoad;
+                private double approvedLoad;
 
                 @JsonProperty("approvedPassengersCapacity")
                 private Integer approvedPassengersCapacity;
@@ -939,7 +939,7 @@ public class ZmCrawlerQuotedPriceRequest extends BaseRequest {
 
                 public ModelDetailsDTO(ZmCrawlerModelQueryResponse.FullCarDataDTO fullCarDataDTO) {
                     ZmCrawlerModelQueryResponse.FullCarDataDTO.FullCarData fullCarData = fullCarDataDTO.getFullCarData();
-                    this.approvedLoad = fullCarData.getApprovedLoad();
+                    this.approvedLoad = fullCarData.getApprovedLoad()*1000;
                     this.approvedPassengersCapacity = fullCarData.getApprovedPassengersCapacity();
                     this.brand = fullCarData.getModelName();
                     this.carAlias = fullCarData.getModelName();

+ 1 - 1
tenant/insurance/quotation-zhongmei/src/main/java/com/jzg/quotation/zhongmei/crawler/entity/Response/ZmCrawlerModelQueryResponse.java

@@ -78,7 +78,7 @@ public class ZmCrawlerModelQueryResponse extends BaseResponse {
 
             private Integer analogyPrice;
             private Integer analogyPriceTax;
-            private Integer approvedLoad;
+            private double approvedLoad;
             private Integer approvedPassengersCapacity;
             private String brand;
             private String brandCode;

+ 26 - 0
tenant/organization/src/main/java/com/jzg/organization/service/impl/PtlAgreementCostServiceImpl.java

@@ -357,6 +357,7 @@ public class PtlAgreementCostServiceImpl extends ServiceImpl<PtlAgreementCostMap
                 if (ptlAgreementCost.getApproved() == 1 || ptlAgreementCost.getApproved() == 2) {
                     throw new SystemException("该条费用已审核,请勿重复操作");
                 }
+                PtlAgreementCost beforeCost = JSONUtil.toBean(JSONUtil.toJsonStr(ptlAgreementCost), PtlAgreementCost.class);
                 if (ptlAgreementCost.getApproved() == 0) {
                     StateResult stateResult = isSuccessful ?
                             costStateListener.auditSuccess(ptlAgreementCost) :
@@ -371,6 +372,31 @@ public class PtlAgreementCostServiceImpl extends ServiceImpl<PtlAgreementCostMap
                         baseMapper.updateById(ptlAgreementCost);
                     }
                 }
+                // 插入操作轨迹表记录
+                OperatorTrajectory operatorTrajectory = new OperatorTrajectory();
+                operatorTrajectory.setId(IdGenerate.nextId());
+                operatorTrajectory.setModuleName("代办事项/报价费用审核");
+                operatorTrajectory.setServiceTag(
+                        "com.jzg.organization.service.impl.PtlAgreementCostServiceImpl.audit()");
+                operatorTrajectory.setEntityName(
+                        "com.jzg.commons.entity.po.PtlAgreementCost");
+                operatorTrajectory.setPrimaryValue(String.join(",", costReviewParam.getIds()));
+                operatorTrajectory.setOperatorType(Crud.U.getCode());
+                Map<String, Object> beforeWrapper = new HashMap<>();
+                beforeWrapper.put("ptlAgreementCost", beforeCost);
+                operatorTrajectory.setBeforeJson(JSONUtil.toJsonStr(beforeWrapper));
+
+                Map<String, Object> afterWrapper = new HashMap<>();
+                afterWrapper.put("ptlAgreementCost", ptlAgreementCost);
+                operatorTrajectory.setAfterJson(JSONUtil.toJsonStr(afterWrapper));
+                operatorTrajectory.setOperationContent("报价费用审核");
+                operatorTrajectory.setSystemCode(baseController.getSystemCode());
+                String userTokenString = baseController.getUserTokenString();
+                JSONObject userInfo = JSONObject.parseObject(userTokenString);
+                operatorTrajectory.setCreateBy(userInfo.getString("username"));
+                operatorTrajectory.setCreateByName(userInfo.getString("name"));
+                operatorTrajectory.setCreateTime(LocalDateTime.now());
+                operatorTrajectoryService.save(operatorTrajectory);
             }
             if (isSuccessful) {
                 return HttpResult.ok("审核成功", costReviewParam.isAutomatic() ? nextDataID() : null);