Commit 247f8530 by zhangxingmin

push

parent 8b5993fa
......@@ -91,6 +91,12 @@
<artifactId>yd-insurance-base-feign</artifactId>
<version>${project.version}</version>
</dependency>
<!-- 在 pom.xml 中添加 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
</dependencies>
<build>
......
package com.yd.csf.api.dto;
import com.baomidou.mybatisplus.annotation.TableField;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
* 算法DTO - 公共入参封装
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class AlgorithmDto {
/**
* 转介人业务ID(客户端用户表唯一业务ID)
*/
private String brokerBizId;
/**
* 基本法配置表唯一业务ID(业务员绑定的基本法类型(类型中含多个基本法项目(基本法项目绑定公式)))
*/
private String ruleBizId;
/**
* 基本法项目配置表唯一业务ID
*/
private String ruleItemBizId;
/**
* 公式配置表唯一业务ID
*/
private String formulaBizId;
/**
* 变量表业务ID集合列表
*/
private List<String> variableBizIdList;
/**
* SQL模板表唯一业务ID
*/
private String sqlTemplateBizId;
/**
* SQL模板条件入参参数及参数值对象(通用,用于各种SQL模板计算值入参条件参数值,这边集成大部分SQL模所需的条件参数,SQL模板会去匹配入参sqlTemplateParamDto有符合的就作为条件参数)
*/
private SqlTemplateParamDto sqlTemplateParamDto;
/**
* 需要执行的基本法项目的执行顺序下标值列表(为空就是执行全部项目)
*/
private List<Integer> executionOrderList;
/**
* 需要执行的基本法项目的执行顺序下标值列表是否取反执行(true-取反就是非executionOrderList的列表执行,false-不取反就是executionOrderList的列表执行)
*/
private Boolean isNegateExecutionOrderList;
}
package com.yd.csf.api.dto;
import lombok.Data;
import java.math.BigDecimal;
import java.util.List;
/**
* 算法-基本法计算-返回的对象
*/
@Data
public class AlgorithmResDto {
/**
* 基本法配置表唯一业务ID(基本法类型)
*/
private String ruleBizId;
/**
* 基本法项目配置表唯一业务ID
*/
private String ruleItemBizId;
/**
* 计算值 - sqlAlgorithmResultDtoList集合里面的计算值和值
*/
private BigDecimal calculatedValue;
/**
* 当前变量绑定的SQL模板计算结果集合列表(含计算值,以及计算值的提供者等等)(sql语句返回多个值作为算子计算)
*/
private List<SqlAlgorithmResultDto> sqlAlgorithmResultDtoList;
}
package com.yd.csf.api.dto;
import com.baomidou.mybatisplus.annotation.TableField;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
* 生成业务员(转介人)积分明细表记录入参
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class GenerateAgentDetailFycDto {
/**
* 业务员ID(客户端用户表唯一业务ID,转介人业务ID)
*/
private String agentId;
/**
* 积分来源类型:保单转介费、一级管理奖、二级管理奖、辅导津贴奖、终身推荐奖
*/
private String sourceType;
/**
* 积分提供的保单号
*/
private String policyNo;
/**
* 保单发佣批次ID
*/
private String batchBizId;
/**
* 转介人绑定的基本法列表对应计算值
*/
private List<AlgorithmResDto> algorithmResDtoList;
}
package com.yd.csf.api.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
/**
* 基本法项目出参
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class RuleItemAlgorithmDto {
/**
* 基本法配置表唯一业务ID(基本法类型)
*/
private String ruleBizId;
/**
* 基本法项目配置表唯一业务ID
*/
private String ruleItemBizId;
/**
* 计算值
*/
private BigDecimal calculatedValue;
}
package com.yd.csf.api.dto;
import lombok.Data;
/**
* 执行SQL模板语句,返回的对象封装
*/
@Data
public class SqlAlgorithmResultDto {
/**
* 计算的积分值提供者(业务员-客户端用户业务ID)
*/
private String provider;
/**
* 计算值
*/
private String calculatedValue;
//TODO 后续扩展
}
package com.yd.csf.api.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* SQL模板条件入参参数及参数值对象(通用,用于各种SQL模板计算值入参条件参数值,这边集成大部分SQL模所需的条件参数,SQL模板会去匹配入参sqlTemplateParamDto有符合的就作为条件参数)
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class SqlTemplateParamDto {
/**
* 条件类型表唯一业务ID
*/
private String conditionTypeBizId;
/**
* 保单号
*/
private String policyNo;
/**
* 产品代码
*/
private String productCode;
/**
* 保单绑定转介人业务ID(销售业务员,客户端用户表唯一业务ID)
*/
private String brokerBizId;
}
package com.yd.csf.api.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
* 变量算法出参公共封装DTO
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class VariableAlgorithmDto {
/**
* 变量表唯一业务ID
*/
private String variableBizId;
/**
* 变量编码
*/
private String variableCode;
/**
* 变量名称中文名
*/
private String nameCn;
/**
* 计算值 - sqlAlgorithmResultDtoList集合里面的计算值和值
*/
private String calculatedValue;
/**
* 当前变量绑定的SQL模板计算结果集合列表(含计算值,以及计算值的提供者等等)
*/
private List<SqlAlgorithmResultDto> sqlAlgorithmResultDtoList;
}
package com.yd.csf.api.service;
import com.yd.common.result.Result;
import com.yd.csf.api.dto.GenerateAgentDetailFycDto;
public interface ApiAgentDetailFycService {
Result saveAgentDetailFyc(GenerateAgentDetailFycDto dto);
}
package com.yd.csf.api.service.impl;
import com.yd.common.result.Result;
import com.yd.csf.api.dto.AlgorithmResDto;
import com.yd.csf.api.dto.GenerateAgentDetailFycDto;
import com.yd.csf.api.dto.SqlAlgorithmResultDto;
import com.yd.csf.api.service.ApiAgentDetailFycService;
import com.yd.csf.service.model.AgentAccumulatedFyc;
import com.yd.csf.service.model.AgentDetailFyc;
import com.yd.csf.service.service.IAgentAccumulatedFycService;
import com.yd.csf.service.service.IAgentDetailFycService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
@Slf4j
@Service
public class ApiAgentDetailFycServiceImpl implements ApiAgentDetailFycService {
@Autowired
private IAgentDetailFycService iAgentDetailFycService;
@Autowired
private IAgentAccumulatedFycService iAgentAccumulatedFycService;
/**
* 基本法计算 - 保存积分明细表
* @param dto
* @return
*/
@Override
public Result saveAgentDetailFyc(GenerateAgentDetailFycDto dto) {
List<AlgorithmResDto> algorithmResDtoList = dto.getAlgorithmResDtoList();
List<AgentDetailFyc> agentDetailFycList = new ArrayList<>();
//根据业务员ID查询业务员累计积分表
AgentAccumulatedFyc agentAccumulatedFyc = iAgentAccumulatedFycService.queryOne(dto.getAgentId());
BigDecimal totalFyc = BigDecimal.ZERO;
if (!Objects.isNull(agentAccumulatedFyc)) {
totalFyc = agentAccumulatedFyc.getTotalFyc();
}
if (!CollectionUtils.isEmpty(algorithmResDtoList)) {
for (AlgorithmResDto algorithmResDto : algorithmResDtoList){
if (!CollectionUtils.isEmpty(algorithmResDto.getSqlAlgorithmResultDtoList())) {
for (SqlAlgorithmResultDto sqlAlgorithmResultDto : algorithmResDto.getSqlAlgorithmResultDtoList()) {
AgentDetailFyc agentDetailFyc = new AgentDetailFyc();
//变化前的业务员总FYC积分 -> 查询
agentDetailFyc.setBeforeFyc(totalFyc);
//累加积分值
totalFyc = totalFyc.add(new BigDecimal(sqlAlgorithmResultDto.getCalculatedValue()));
//变化值(-代表减少)
agentDetailFyc.setChangeFyc(sqlAlgorithmResultDto.getCalculatedValue());
//变化后的业务员总FYC积分
agentDetailFyc.setAfterFyc(totalFyc);
//业务员ID(客户端用户表唯一业务ID)获取积分的人
agentDetailFyc.setAgentId(dto.getAgentId());
//积分来源类型 TODO
// agentDetailFyc.setSourceType();
//积分来源基本法项目配置表唯一业务ID
agentDetailFyc.setRuleItemBizId(algorithmResDto.getRuleItemBizId());
//保单发佣批次ID
agentDetailFyc.setBatchBizId(dto.getBatchBizId());
//积分提供保单表唯一业务ID
agentDetailFyc.setPolicyBizId(dto.getPolicyBizId());
//积分提供者(客户端用户表唯一业务ID)
agentDetailFyc.setProvideId(sqlAlgorithmResultDto.getProvider());
agentDetailFycList.add(agentDetailFyc);
}
}else {
AgentDetailFyc agentDetailFyc = new AgentDetailFyc();
//变化前的业务员总FYC积分 -> 查询
agentDetailFyc.setBeforeFyc(totalFyc);
//累加积分值
totalFyc = totalFyc.add(algorithmResDto.getCalculatedValue());
//变化值(-代表减少)
agentDetailFyc.setChangeFyc(algorithmResDto.getCalculatedValue().toString());
//变化后的业务员总FYC积分
agentDetailFyc.setAfterFyc(totalFyc);
//业务员ID(客户端用户表唯一业务ID)获取积分的人
agentDetailFyc.setAgentId(dto.getAgentId());
//积分来源类型 TODO
// agentDetailFyc.setSourceType();
//积分来源基本法项目配置表唯一业务ID
agentDetailFyc.setRuleItemBizId(algorithmResDto.getRuleItemBizId());
//保单发佣批次ID
agentDetailFyc.setBatchBizId(dto.getBatchBizId());
//积分提供保单表唯一业务ID
agentDetailFyc.setPolicyBizId(dto.getPolicyBizId());
//积分提供者(客户端用户表唯一业务ID)
// agentDetailFyc.setProvideId(sqlAlgorithmResultDto.getProvider());
agentDetailFycList.add(agentDetailFyc);
}
}
}
if (!CollectionUtils.isEmpty(agentDetailFycList)) {
//保存积分明细
iAgentDetailFycService.saveOrUpdateBatch(agentDetailFycList);
//更新累计积分表的业务员的累计积分字段值
if (!Objects.isNull(agentAccumulatedFyc)) {
agentAccumulatedFyc.setTotalFyc(totalFyc);
iAgentAccumulatedFycService.saveOrUpdate(agentAccumulatedFyc);
}
}
return Result.success();
}
}
package com.yd.csf.api.utils;
import java.util.*;
import java.util.regex.*;
/**
* 公式解析工具类
*/
public class FormulaParser {
/**
* 从公式字符串中解析出所有变量业务ID
* @param calculationFormulaBizId 公式字符串,如 "(variable_1001 + variable_2123) * variable_4455"
* @return 变量业务ID的集合
*/
public static Set<String> parseVariableBizIds(String calculationFormulaBizId) {
Set<String> variableIds = new HashSet<>();
if (calculationFormulaBizId == null || calculationFormulaBizId.trim().isEmpty()) {
return variableIds;
}
// 正则表达式匹配 variable_ 后面跟着数字的模式
Pattern pattern = Pattern.compile("variable_\\d+");
Matcher matcher = pattern.matcher(calculationFormulaBizId);
while (matcher.find()) {
variableIds.add(matcher.group());
}
return variableIds;
}
/**
* 从公式字符串中解析出所有变量业务ID(返回列表,保持顺序)
* @param calculationFormulaBizId 公式字符串
* @return 变量业务ID的列表(按出现顺序)
*/
public static List<String> parseVariableBizIdsOrdered(String calculationFormulaBizId) {
List<String> variableIds = new ArrayList<>();
if (calculationFormulaBizId == null || calculationFormulaBizId.trim().isEmpty()) {
return variableIds;
}
Pattern pattern = Pattern.compile("variable_\\d+");
Matcher matcher = pattern.matcher(calculationFormulaBizId);
while (matcher.find()) {
variableIds.add(matcher.group());
}
return variableIds;
}
/**
* 从公式字符串中解析出纯数字ID部分
* @param calculationFormulaBizId 公式字符串
* @return 纯数字ID的集合
*/
public static Set<Long> parseVariableNumericIds(String calculationFormulaBizId) {
Set<Long> numericIds = new HashSet<>();
if (calculationFormulaBizId == null || calculationFormulaBizId.trim().isEmpty()) {
return numericIds;
}
// 匹配 variable_ 后面的数字部分
Pattern pattern = Pattern.compile("variable_(\\d+)");
Matcher matcher = pattern.matcher(calculationFormulaBizId);
while (matcher.find()) {
try {
Long numericId = Long.parseLong(matcher.group(1));
numericIds.add(numericId);
} catch (NumberFormatException e) {
// 忽略格式错误的ID
System.err.println("无效的数字ID: " + matcher.group(1));
}
}
return numericIds;
}
/**
* 替换公式中的变量业务ID为实际值
* @param formula 原始公式
* @param variableValues 变量值映射表
* @return 替换后的公式
*/
public static String replaceVariablesWithValues(String formula, Map<String, Double> variableValues) {
if (formula == null || variableValues == null) {
return formula;
}
String result = formula;
for (Map.Entry<String, Double> entry : variableValues.entrySet()) {
String variableId = entry.getKey();
Double value = entry.getValue();
if (value != null) {
// 直接替换变量ID为数值
result = result.replace(variableId, value.toString());
}
}
return result;
}
/**
* 验证公式格式是否正确
* @param formula 公式字符串
* @return 验证结果
*/
public static boolean validateFormulaFormat(String formula) {
if (formula == null || formula.trim().isEmpty()) {
return false;
}
// 基本格式检查:包含变量、运算符和括号
// 这里可以添加更复杂的验证逻辑
String tempFormula = formula.replaceAll("variable_\\d+", "VAR")
.replaceAll("\\s+", "");
// 简单的括号匹配检查
return isBracketBalanced(tempFormula);
}
/**
* 检查括号是否平衡
*/
private static boolean isBracketBalanced(String str) {
Deque<Character> stack = new ArrayDeque<>();
for (char c : str.toCharArray()) {
if (c == '(') {
stack.push(c);
} else if (c == ')') {
if (stack.isEmpty() || stack.pop() != '(') {
return false;
}
}
}
return stack.isEmpty();
}
}
\ No newline at end of file
package com.yd.csf.feign.enums;
/**
* 变量类型枚举
*/
public enum VariableEnum {
FIXED_VALUE("固定值","FIXED_VALUE"),
DYNAMIC_COMPUTATION("动态计算","DYNAMIC_COMPUTATION"),
;
//字典项标签(名称)
private String itemLabel;
//字典项值
private String itemValue;
//构造函数
VariableEnum(String itemLabel, String itemValue) {
this.itemLabel = itemLabel;
this.itemValue = itemValue;
}
public String getItemLabel() {
return itemLabel;
}
public String getItemValue() {
return itemValue;
}
}
package com.yd.csf.service.dto;
import com.baomidou.mybatisplus.annotation.TableField;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class CommissionRuleBindingDto {
/**
* 基本法配置表唯一业务ID
*/
private String ruleBizId;
/**
* 基本法项目配置表唯一业务ID
*/
private String ruleItemBizId;
/**
* 绑定目标类型:AGENT-业务员, TEAM-团队
*/
private String targetType;
/**
* 目标ID,业务员ID或团队ID
*/
private String targetId;
}
package com.yd.csf.service.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class RelObjectConditionDto {
/**
......
......@@ -12,6 +12,11 @@ import lombok.NoArgsConstructor;
public class RuleItemConfigDto {
/**
* 基本法配置表唯一业务ID
*/
private String ruleBizId;
/**
* 基本法项目配置表唯一业务ID
*/
private String ruleItemBizId;
......
......@@ -5,6 +5,8 @@ import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@Builder
@NoArgsConstructor
......@@ -17,6 +19,11 @@ public class VariableDto {
private String variableBizId;
/**
* 变量表唯一业务ID列表
*/
private List<String> variableBizIdList;
/**
* 变量名称中文名
*/
private String nameCn;
......
......@@ -44,10 +44,22 @@ public class AgentDetailFyc implements Serializable {
private String sourceType;
/**
* 积分提供保单表唯一业务ID
* 积分来源基本法项目配置表唯一业务ID
*/
@TableField("policy_biz_id")
private String policyBizId;
@TableField("rule_item_biz_id")
private String ruleItemBizId;
/**
* 保单发佣批次ID
*/
@TableField("batch_bizId")
private String batchBizId;
/**
* 积分提供的保单号
*/
@TableField("policy_no")
private String policyNo;
/**
* 积分提供者(客户端用户表唯一业务ID)
......
......@@ -61,6 +61,12 @@ public class FormulaConfig implements Serializable {
private String calculationFormulaBizId;
/**
* 计算公式(变量表编码组合)
*/
@TableField("calculation_formula_code")
private String calculationFormulaCode;
/**
* 描述
*/
@TableField("description")
......
......@@ -21,6 +21,11 @@ public class Fortune implements Serializable {
private Long id;
/**
* 保单发佣批次ID
*/
private String batchBizId;
/**
* 保单发佣业务id
*/
private String fortuneBizId;
......
......@@ -13,4 +13,5 @@ import com.baomidou.mybatisplus.extension.service.IService;
*/
public interface IAgentAccumulatedFycService extends IService<AgentAccumulatedFyc> {
AgentAccumulatedFyc queryOne(String agentId);
}
package com.yd.csf.service.service;
import com.yd.csf.service.dto.CommissionRuleBindingDto;
import com.yd.csf.service.model.CommissionRuleBinding;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
/**
* <p>
* 基本法绑定表 - 存储基本法与业务员或团队的绑定关系,支持灵活的权限分配 服务类
......@@ -13,4 +16,5 @@ import com.baomidou.mybatisplus.extension.service.IService;
*/
public interface ICommissionRuleBindingService extends IService<CommissionRuleBinding> {
List<CommissionRuleBinding> queryList(CommissionRuleBindingDto dto);
}
......@@ -24,4 +24,6 @@ public interface ICommissionSqlTemplateService extends IService<CommissionSqlTem
ApiCommissionSqlTemplatePageRequest request);
List<CommissionSqlTemplate> queryList(CommissionSqlTemplateDto dto);
CommissionSqlTemplate queryOne(String sqlTemplateBizId);
}
package com.yd.csf.service.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yd.csf.service.model.AgentAccumulatedFyc;
import com.yd.csf.service.dao.AgentAccumulatedFycMapper;
import com.yd.csf.service.service.IAgentAccumulatedFycService;
......@@ -17,4 +18,14 @@ import org.springframework.stereotype.Service;
@Service
public class AgentAccumulatedFycServiceImpl extends ServiceImpl<AgentAccumulatedFycMapper, AgentAccumulatedFyc> implements IAgentAccumulatedFycService {
/**
* 查询单个对象
* @param agentId
* @return
*/
@Override
public AgentAccumulatedFyc queryOne(String agentId) {
return this.getOne(new LambdaQueryWrapper<AgentAccumulatedFyc>().eq(AgentAccumulatedFyc::getAgentId,agentId).last("limit 1"));
}
}
package com.yd.csf.service.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yd.csf.service.dto.CommissionRuleBindingDto;
import com.yd.csf.service.model.CommissionRuleBinding;
import com.yd.csf.service.dao.CommissionRuleBindingMapper;
import com.yd.csf.service.model.CommissionSqlTemplate;
import com.yd.csf.service.service.ICommissionRuleBindingService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.util.List;
/**
* <p>
......@@ -17,4 +24,18 @@ import org.springframework.stereotype.Service;
@Service
public class CommissionRuleBindingServiceImpl extends ServiceImpl<CommissionRuleBindingMapper, CommissionRuleBinding> implements ICommissionRuleBindingService {
/**
* 查询列表
* @param dto
* @return
*/
@Override
public List<CommissionRuleBinding> queryList(CommissionRuleBindingDto dto) {
List<CommissionRuleBinding> list = baseMapper.selectList(new LambdaQueryWrapper<CommissionRuleBinding>()
.eq(StringUtils.isNotBlank(dto.getTargetId()),CommissionRuleBinding::getTargetId,dto.getTargetId())
);
return list;
}
}
......@@ -45,4 +45,14 @@ public class CommissionSqlTemplateServiceImpl extends ServiceImpl<CommissionSqlT
);
return list;
}
/**
* 查询单个对象
* @param sqlTemplateBizId
* @return
*/
@Override
public CommissionSqlTemplate queryOne(String sqlTemplateBizId) {
return this.getOne(new LambdaQueryWrapper<CommissionSqlTemplate>().eq(CommissionSqlTemplate::getSqlTemplateBizId,sqlTemplateBizId));
}
}
......@@ -53,7 +53,9 @@ public class RuleItemConfigServiceImpl extends ServiceImpl<RuleItemConfigMapper,
List<RuleItemConfig> list = baseMapper.selectList(new LambdaQueryWrapper<RuleItemConfig>()
.eq(StringUtils.isNotBlank(dto.getRuleItemBizId()) && !dto.getIsExcludeMy(),RuleItemConfig::getRuleItemBizId,dto.getRuleItemBizId())
.eq(StringUtils.isNotBlank(dto.getItemName()),RuleItemConfig::getItemName,dto.getItemName())
.eq(StringUtils.isNotBlank(dto.getRuleBizId()),RuleItemConfig::getRuleBizId,dto.getRuleBizId())
.ne(dto.getIsExcludeMy(),RuleItemConfig::getRuleItemBizId,dto.getRuleItemBizId())
.orderByAsc(RuleItemConfig::getExecutionOrder)
);
return list;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment