|
|
@@ -0,0 +1,372 @@
|
|
|
+package com.jzg.costsorrule.service.impl;
|
|
|
+
|
|
|
+import com.alibaba.fastjson.JSONArray;
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
+import com.jzg.commons.entity.po.PtlAgreementUndwrtRulesAttr;
|
|
|
+import com.jzg.commons.entity.scheme.po.PtlSchemeRulesAttrLink;
|
|
|
+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.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
|
|
|
+public class RuleServiceImpl implements RuleService {
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 预处理数据
|
|
|
+ * @param attrMap
|
|
|
+ * @param linkVos
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ 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());
|
|
|
+ //boolean 类型的转换
|
|
|
+ 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);
|
|
|
+ }
|
|
|
+ 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");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public boolean verificationRule(Map<String,String> maps, List<RuleAttrLinkVo> linkVos,List<PtlAgreementUndwrtRulesAttr> rulesAttrs, StringBuilder logs) {
|
|
|
+ //预处理数据
|
|
|
+ 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();
|
|
|
+ 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);
|
|
|
+ if(Objects.isNull(attrValue) || Objects.isNull(rulesAttr)){
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (!judgements(attrValue, linkVos.get(i),rulesAttr, logs)) {
|
|
|
+ //返回 费用id 如果需要匹配非车的情况 将返回值返回list 后赛选
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+// log.debug("当前费用因子匹配结束\n");
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+// throw new SystemException("费用因子匹配失败");
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 匹配费用因子
|
|
|
+ * @param value 表单值
|
|
|
+ * @param linkVo 费用因子
|
|
|
+ * @param rulesAttr 规则因子
|
|
|
+ * @param logs 日志
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ 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) {
|
|
|
+ if (rulesAttr.getAttrType().equals(AttrTypeConstant.CHECKBOX.getCode())) {
|
|
|
+ return checkBoxEqual(linkVo, value);
|
|
|
+ } else if (rulesAttr.getAttrType().equals(AttrTypeConstant.INPUTNUMBER.getCode())) {
|
|
|
+ return inputNumberEqual(linkVo, value);
|
|
|
+ } else if (rulesAttr.getAttrType().equals(AttrTypeConstant.INPUTTAG.getCode())) {
|
|
|
+ return inputTagEqual(linkVo, value);
|
|
|
+ } else if (rulesAttr.getAttrType().equals(AttrTypeConstant.SELECT.getCode())) {
|
|
|
+ //截取车牌
|
|
|
+ if (linkVo.getAttrCode().equals("LicenseNo")) {
|
|
|
+ value = value.substring(0, 2);
|
|
|
+ }
|
|
|
+ return selectEqual(linkVo, value);
|
|
|
+ } else if (rulesAttr.getAttrType().equals(AttrTypeConstant.RADIO.getCode())) {
|
|
|
+ return radioEqual(linkVo, value);
|
|
|
+ } else if (rulesAttr.getAttrType().equals(AttrTypeConstant.DATETIME.getCode())){
|
|
|
+ return dateTimeEqual(linkVo, value);
|
|
|
+ }
|
|
|
+
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ private boolean checkBoxEqual(RuleAttrLinkVo linkVo, String value) {
|
|
|
+ String[] split = linkVo.getMin().split(",");
|
|
|
+ for (String sp : split) {
|
|
|
+ if (sp.equals(value)) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ private boolean inputNumberEqual(RuleAttrLinkVo linkVo, String value) {
|
|
|
+ double v = Double.parseDouble(value);
|
|
|
+ //统一处理数值
|
|
|
+ if (OperatorConstant.InputNumber.EQ.getCode().equals(linkVo.getOperator())) {
|
|
|
+ if (Double.parseDouble(linkVo.getMin()) <= v &&
|
|
|
+ Double.parseDouble(linkVo.getMax()) >= v) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ } else if (OperatorConstant.InputNumber.LT.getCode().equals(linkVo.getOperator())) {
|
|
|
+ if (Double.parseDouble(linkVo.getMin()) > v) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ } else if (OperatorConstant.InputNumber.LE.getCode().equals(linkVo.getOperator())) {
|
|
|
+ if (Double.parseDouble(linkVo.getMin()) >= v) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ } else if (OperatorConstant.InputNumber.GT.getCode().equals(linkVo.getOperator())) {
|
|
|
+ if (Double.parseDouble(linkVo.getMax()) < v) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ } else if (OperatorConstant.InputNumber.GE.getCode().equals(linkVo.getOperator())) {
|
|
|
+ if (Double.parseDouble(linkVo.getMax()) <= v) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private boolean inputTagEqual(RuleAttrLinkVo linkVo, String value) {
|
|
|
+ //将值进行分割
|
|
|
+
|
|
|
+ AtomicBoolean returnBool = new AtomicBoolean(false);
|
|
|
+
|
|
|
+ List<String> equalsMap = new ArrayList<>();
|
|
|
+ //字符型评分
|
|
|
+ equalsMap.add("CharacterBasedRating");
|
|
|
+ //交强字符型评分
|
|
|
+ equalsMap.add("JqCharacterBasedRating");
|
|
|
+ //商业字符型评分
|
|
|
+ equalsMap.add("SyCharacterBasedRating");
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ //equest 等于判断
|
|
|
+// if(equalsMap.contains(linkVo.getAttrCode())){
|
|
|
+// boolean b = value.anyMatch(value::equals);
|
|
|
+// returnBool.set(b);
|
|
|
+// }else if((ptlAgreementProductCostsAttrLink.getAttrCode().equals("BrandandModel") || ptlAgreementProductCostsAttrLink.getAttrCode().equals("CarOwnerName"))
|
|
|
+// && ptlAgreementProductCostsAttrLink.getOperator().equals("2")){
|
|
|
+// //处理品牌型号 不包含的情况
|
|
|
+// boolean anyMatch = Arrays.stream(split)
|
|
|
+// .anyMatch(value::contains);
|
|
|
+// returnBool.set(!anyMatch);
|
|
|
+// }else {
|
|
|
+// boolean anyMatch = Arrays.stream(split)
|
|
|
+// .anyMatch(value::contains);
|
|
|
+// returnBool.set(anyMatch);
|
|
|
+// }
|
|
|
+ return returnBool.get();
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private boolean selectEqual(RuleAttrLinkVo linkVo, String value) {
|
|
|
+ if (linkVo.getMin() != null && linkVo.getMin().contains(value)) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ private boolean radioEqual(RuleAttrLinkVo linkVo, String value) {
|
|
|
+ //新能源判断
|
|
|
+// if ("NewEnergy".equals(linkVo.getAttrCode())) {
|
|
|
+// // 是否是新能源车
|
|
|
+// boolean newEnergy = EnergyType.isNewEnergy(value);
|
|
|
+// if (newEnergy && linkVo.getMin().equals("1")) {
|
|
|
+// return true;
|
|
|
+// } else if (!newEnergy && linkVo.getMin().equals("0")) {
|
|
|
+// return true;
|
|
|
+// }
|
|
|
+// } else if (linkVo.getMin().contains(value)) {
|
|
|
+// return true;
|
|
|
+// }
|
|
|
+ return linkVo.getMin().equals(value);
|
|
|
+ }
|
|
|
+
|
|
|
+ public boolean dateTimeEqual(RuleAttrLinkVo linkVo, String value){
|
|
|
+ DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
|
|
+ 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);
|
|
|
+ }
|
|
|
+ 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;
|
|
|
+ }
|
|
|
+ } else if (OperatorConstant.DateTime.LT.getCode().equals(linkVo.getOperator())) {
|
|
|
+ if (v.isBefore(min)) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ } else if (OperatorConstant.DateTime.LE.getCode().equals(linkVo.getOperator())) {
|
|
|
+ if (v.isBefore(min) || v.isEqual(min)) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ } else if (OperatorConstant.DateTime.GT.getCode().equals(linkVo.getOperator())) {
|
|
|
+ if (v.isAfter(max)) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ } else if (OperatorConstant.DateTime.GE.getCode().equals(linkVo.getOperator())) {
|
|
|
+ if (v.isAfter(max) || v.isEqual(max)) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ //region 表单转换成json对象
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void traverseJsonObject(JSONObject jsonObject, HashMap<String,String> attrMap) {
|
|
|
+ if (Objects.isNull(jsonObject)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ // 遍历 JSONObject 的所有键值对
|
|
|
+ for (Map.Entry<String, Object> entry : jsonObject.entrySet()) {
|
|
|
+ String key = entry.getKey();
|
|
|
+ Object value = entry.getValue();
|
|
|
+
|
|
|
+ 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);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果值是嵌套的数组(JSONArray),遍历数组
|
|
|
+ if (value instanceof JSONArray) {
|
|
|
+ System.out.println("Nested JSONArray for key: " + key);
|
|
|
+ traverseJsonArray((JSONArray) value,attrMap);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 处理车主 投保人 被保人信息
|
|
|
+ * @param jsonObject
|
|
|
+ * @param attrMap
|
|
|
+ * @param parentKey
|
|
|
+ */
|
|
|
+ public void traverseJsonObject(JSONObject jsonObject,HashMap<String,String> attrMap,String parentKey) {
|
|
|
+ if (Objects.isNull(jsonObject)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ for (Map.Entry<String, Object> entry : jsonObject.entrySet()) {
|
|
|
+ String key = entry.getKey();
|
|
|
+ Object value = entry.getValue();
|
|
|
+
|
|
|
+ if(!(value instanceof JSONObject) && !(value instanceof JSONArray)){
|
|
|
+ attrMap.put(parentKey.toLowerCase() + key.toLowerCase(),value.toString());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public void traverseJsonArray(JSONArray jsonArray,HashMap<String,String> attrMap) {
|
|
|
+ if (jsonArray == null) {
|
|
|
+ System.out.println("JSONArray is null.");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 遍历 JSONArray 的所有元素
|
|
|
+ for (int i = 0; i < jsonArray.size(); i++) {
|
|
|
+ Object element = jsonArray.get(i);
|
|
|
+
|
|
|
+ // 打印数组元素
|
|
|
+ System.out.println("Array element at index " + i + ": " + element);
|
|
|
+
|
|
|
+ // 如果元素是嵌套的 JSONObject,递归遍历
|
|
|
+ if (element instanceof JSONObject) {
|
|
|
+ System.out.println("Nested JSONObject in array at index: " + i);
|
|
|
+ traverseJsonObject((JSONObject) element,attrMap);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果元素是嵌套的数组(JSONArray),递归遍历
|
|
|
+ if (element instanceof JSONArray) {
|
|
|
+ System.out.println("Nested JSONArray in array at index: " + i);
|
|
|
+ traverseJsonArray((JSONArray) element,attrMap);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //判断是否是车主 投保人 被保人信息
|
|
|
+ public boolean isUserKey(String key){
|
|
|
+ if(key.equals("ownersInfo") || key.equals("policyHolderInfo") || key.equals("insuredPersonInfo")){
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ //endregion
|
|
|
+
|
|
|
+
|
|
|
+ @Override
|
|
|
+ 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->{
|
|
|
+ RuleAttrLinkVo vo = new RuleAttrLinkVo();
|
|
|
+ vo.setMin(value.getMin());
|
|
|
+ vo.setMax(value.getMax());
|
|
|
+ vo.setAttrCode(value.getAttrCode());
|
|
|
+ vo.setOperator(value.getOperator());
|
|
|
+ vo.setMinArray(value.getMinArray().toArray(new String[0]));
|
|
|
+ vos.add(vo);
|
|
|
+ });
|
|
|
+ convertMaps.put(key,vos);
|
|
|
+ }
|
|
|
+ return convertMaps;
|
|
|
+ }
|
|
|
+}
|