Commit 3848bb2f by zhangxingmin

push

parent 93ff6104
package com.yd.csf.service.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* <p>
* 业务员累计积分表 - 存储业务员的累计FYC积分和当前等级信息 前端控制器
* </p>
*
* @author zxm
* @since 2026-04-16
*/
@RestController
@RequestMapping("/agentAccumulatedFyc")
public class AgentAccumulatedFycController {
}
package com.yd.csf.service.dao;
import com.yd.csf.service.model.AgentAccumulatedFyc;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* <p>
* 业务员累计积分表 - 存储业务员的累计FYC积分和当前等级信息 Mapper 接口
* </p>
*
* @author zxm
* @since 2026-04-16
*/
public interface AgentAccumulatedFycMapper extends BaseMapper<AgentAccumulatedFyc> {
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yd.csf.service.dao.AgentAccumulatedFycMapper">
</mapper>
package com.yd.csf.service.model;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import lombok.Getter;
import lombok.Setter;
/**
* <p>
* 业务员累计积分表 - 存储业务员的累计FYC积分和当前等级信息
* </p>
*
* @author zxm
* @since 2026-04-16
*/
@Getter
@Setter
@TableName("agent_accumulated_fyc")
public class AgentAccumulatedFyc implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 业务员ID(会员唯一业务ID)
*/
@TableField("agent_id")
private String agentId;
/**
* 未生效累计积分(不限业务场景)
*/
@TableField("no_effect")
private BigDecimal noEffect;
/**
* 已生效累计积分(不限业务场景)
*/
@TableField("effect")
private BigDecimal effect;
/**
* 累计积分 = 未生效累计积分 + 已生效累计积分
*/
@TableField("total_fyc")
private BigDecimal totalFyc;
/**
* 已生效累计首期佣金积分值(佣金场景)
*/
@TableField("first_commission")
private BigDecimal firstCommission;
/**
* 未生效累计首期佣金积分值(佣金场景)
*/
@TableField("no_first_commission")
private BigDecimal noFirstCommission;
/**
* 已生效累计非首期佣金积分值(佣金场景)
*/
@TableField("ryc")
private BigDecimal ryc;
/**
* 未生效累计非首期佣金积分值(佣金场景)
*/
@TableField("no_ryc")
private BigDecimal noRyc;
/**
* 晋升职级累计积分 = 已生效累计积分 - 已生效累计非首期佣金积分值
*/
@TableField("promotion")
private BigDecimal promotion;
/**
* 当前等级,业务员当前的会员等级编码(会员等级配置表等级编码)
*/
@TableField("current_grade_code")
private String currentGradeCode;
/**
* 最后计算日期,记录最后一次计算累计FYC的日期
*/
@TableField("last_calc_date")
private LocalDateTime lastCalcDate;
/**
* 状态(0:停用 1:启用)
*/
@TableField("status")
private Byte status;
/**
* 所属租户唯一业务ID(冗余)
*/
@TableField("tenant_biz_id")
private String tenantBizId;
/**
* 所属项目唯一业务ID(冗余)
*/
@TableField("project_biz_id")
private String projectBizId;
/**
* 通用备注
*/
@TableField("remark")
private String remark;
/**
* 删除标识: 0-正常, 1-删除
*/
@TableField("is_deleted")
private Boolean isDeleted;
/**
* 创建人ID
*/
@TableField("creator_id")
private String creatorId;
/**
* 更新人ID
*/
@TableField("updater_id")
private String updaterId;
/**
* 创建时间
*/
@TableField("create_time")
private LocalDateTime createTime;
/**
* 更新时间
*/
@TableField("update_time")
private LocalDateTime updateTime;
}
package com.yd.csf.service.service;
import com.yd.csf.service.model.AgentAccumulatedFyc;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* <p>
* 业务员累计积分表 - 存储业务员的累计FYC积分和当前等级信息 服务类
* </p>
*
* @author zxm
* @since 2026-04-16
*/
public interface IAgentAccumulatedFycService extends IService<AgentAccumulatedFyc> {
}
package com.yd.csf.service.service.impl;
import com.yd.csf.service.model.AgentAccumulatedFyc;
import com.yd.csf.service.dao.AgentAccumulatedFycMapper;
import com.yd.csf.service.service.IAgentAccumulatedFycService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
* <p>
* 业务员累计积分表 - 存储业务员的累计FYC积分和当前等级信息 服务实现类
* </p>
*
* @author zxm
* @since 2026-04-16
*/
@Service
public class AgentAccumulatedFycServiceImpl extends ServiceImpl<AgentAccumulatedFycMapper, AgentAccumulatedFyc> implements IAgentAccumulatedFycService {
}
...@@ -7,23 +7,20 @@ import com.yd.csf.api.dto.AlgorithmCollectResDto; ...@@ -7,23 +7,20 @@ import com.yd.csf.api.dto.AlgorithmCollectResDto;
import com.yd.csf.api.dto.AlgorithmResDto; import com.yd.csf.api.dto.AlgorithmResDto;
import com.yd.csf.api.service.ApiExpectedFortuneService; import com.yd.csf.api.service.ApiExpectedFortuneService;
import com.yd.csf.api.service.XxlJobService; import com.yd.csf.api.service.XxlJobService;
import com.yd.csf.feign.enums.FycSourceTypeEnum;
import com.yd.csf.feign.enums.OprSourceEnum;
import com.yd.csf.feign.request.expectedfortune.ApiGenerateExpectedFortuneRequest; import com.yd.csf.feign.request.expectedfortune.ApiGenerateExpectedFortuneRequest;
import com.yd.csf.feign.response.expectedfortune.ApiGenerateExpectedFortuneResponse; import com.yd.csf.feign.response.expectedfortune.ApiGenerateExpectedFortuneResponse;
import com.yd.csf.service.model.CalmTask; import com.yd.csf.service.model.*;
import com.yd.csf.service.model.Policy; import com.yd.csf.service.service.*;
import com.yd.csf.service.model.PolicyFollow;
import com.yd.csf.service.service.ICalmTaskService;
import com.yd.csf.service.service.PolicyFollowService;
import com.yd.csf.service.service.PolicyService;
import com.yd.feign.config.FeignTokenInterceptor; import com.yd.feign.config.FeignTokenInterceptor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils; import org.springframework.beans.BeanUtils;
import org.springframework.scheduling.annotation.Async; import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes; import org.springframework.web.context.request.ServletRequestAttributes;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal; import java.math.BigDecimal;
...@@ -44,11 +41,15 @@ public class ApiExpectedFortuneAsyncService { ...@@ -44,11 +41,15 @@ public class ApiExpectedFortuneAsyncService {
@Resource @Resource
private PolicyFollowService policyFollowService; private PolicyFollowService policyFollowService;
@Resource @Resource
private PolicyService policyService;
@Resource
private ICalmTaskService iCalmTaskService; private ICalmTaskService iCalmTaskService;
@Resource @Resource
private XxlJobService xxlJobService; private XxlJobService xxlJobService;
@Resource
private IAgentAccumulatedFycService iAgentAccumulatedFycService;
@Resource
private IAgentDetailFycService iAgentDetailFycService;
@Resource
private IAgentAccumulatedFycLogService iAgentAccumulatedFycLogService;
/** /**
* 异步处理-执行预计发拥数据 * 异步处理-执行预计发拥数据
...@@ -80,21 +81,6 @@ public class ApiExpectedFortuneAsyncService { ...@@ -80,21 +81,6 @@ public class ApiExpectedFortuneAsyncService {
} }
} }
// /**
// * 异步处理-构建冷静期定时任务
// * @param collectResDtos
// */
// @Async("commonAsyncExecutor")
// public void buildCalmDateTask(List<AlgorithmCollectResDto> collectResDtos,String policyNo){
// //collectResDtos要分组,分组条件是clientUserBizId,sumCalculatedValue和commissionName需要分组统计计算,拿到分组后的创建新的List<AlgorithmCollectResDto>返回
//
// }
/**
* 异步处理-构建冷静期定时任务
* @param collectResDtos 原始计算结果收集列表
* @param policyNo 保单号
*/
@Async("commonAsyncExecutor") @Async("commonAsyncExecutor")
public void buildCalmDateTask(List<AlgorithmCollectResDto> collectResDtos, String policyNo) { public void buildCalmDateTask(List<AlgorithmCollectResDto> collectResDtos, String policyNo) {
if (CollectionUtils.isEmpty(collectResDtos)) { if (CollectionUtils.isEmpty(collectResDtos)) {
...@@ -102,113 +88,239 @@ public class ApiExpectedFortuneAsyncService { ...@@ -102,113 +88,239 @@ public class ApiExpectedFortuneAsyncService {
return; return;
} }
//新单跟进对象 // 新单跟进对象
PolicyFollow policyFollow = policyFollowService.queryOneByPolicyNo(policyNo); PolicyFollow policyFollow = policyFollowService.queryOneByPolicyNo(policyNo);
//保单对象 if (policyFollow == null) {
// Policy policy = policyService.queryOne(policyNo); log.warn("未找到保单跟进记录,policyNo: {}", policyNo);
return;
}
// 按 clientUserBizId 分组,计算每个用户的 sumCalculatedValue 和 commissionName // 过滤掉 calculatedValue 为 0 的项,并收集所有有效的 AlgorithmResDto,返回新的List<AlgorithmCollectResDto>
Map<String, AlgorithmCollectResDto> groupedMap = collectResDtos.stream() List<AlgorithmCollectResDto> filteredCollectResDtos = collectResDtos.stream()
.filter(dto -> StringUtils.isNotBlank(dto.getClientUserBizId())) .map(dto -> {
.collect(Collectors.toMap( List<AlgorithmResDto> originalList = dto.getAlgorithmResDtoList();
AlgorithmCollectResDto::getClientUserBizId, if (CollectionUtils.isEmpty(originalList)) {
Function.identity(), return null;
(existing, replacement) -> { }
// 合并:累加 sumCalculatedValue,合并 commissionName List<AlgorithmResDto> validList = originalList.stream()
BigDecimal sum1 = existing.getSumCalculatedValue() != null ? existing.getSumCalculatedValue() : BigDecimal.ZERO; .filter(res -> res.getCalculatedValue() != null
BigDecimal sum2 = calculateSumFromResList(replacement.getAlgorithmResDtoList()); && res.getCalculatedValue().compareTo(BigDecimal.ZERO) != 0)
existing.setSumCalculatedValue(sum1.add(sum2)); .collect(Collectors.toList());
if (validList.isEmpty()) {
return null;
}
// 创建新对象
AlgorithmCollectResDto newDto = new AlgorithmCollectResDto();
BeanUtils.copyProperties(dto, newDto);
newDto.setAlgorithmResDtoList(validList);
return newDto;
})
.filter(Objects::nonNull)
.collect(Collectors.toList());
String commission1 = existing.getCommissionName() != null ? existing.getCommissionName() : ""; if (CollectionUtils.isEmpty(filteredCollectResDtos)) {
String commission2 = buildCommissionName(replacement.getAlgorithmResDtoList()); log.info("过滤后无有效发佣数据,policyNo: {}", policyNo);
existing.setCommissionName(mergeCommissionNames(commission1, commission2)); return;
return existing;
} }
));
// 构造calmTask列表返回 //去重获取转介人业务ID列表
List<CalmTask> resultList = groupedMap.values().stream().map(dto -> { List<String> clientUserBizIdList = filteredCollectResDtos
//计算合计值 .stream()
BigDecimal totalSum = dto.getSumCalculatedValue(); .map(AlgorithmCollectResDto::getClientUserBizId)
if (totalSum == null || (totalSum != null && totalSum.compareTo(BigDecimal.ZERO) == 0)) { .distinct()
//计算合计值为空或者0,直接返回null,不构造此CalmTask对象。 .collect(Collectors.toList());
return null; //查询转介人对应累计积分
List<AgentAccumulatedFyc> accumulatedFycList = new ArrayList<>();
if (CollectionUtils.isNotEmpty(clientUserBizIdList)) {
accumulatedFycList = iAgentAccumulatedFycService.queryList(clientUserBizIdList);
}
//循环,构建同保单号多个转介人多个期数多个佣金项目的冷静期定时任务记录和积分明细记录
for (AlgorithmCollectResDto resDto : filteredCollectResDtos) {
if (CollectionUtils.isEmpty(resDto.getAlgorithmResDtoList())) {
continue;
}
List<AgentAccumulatedFyc> filterList = accumulatedFycList
.stream()
.filter(dto -> dto.getAgentId().equals(resDto.getClientUserBizId()))
.collect(Collectors.toList());
AgentAccumulatedFyc agentAccumulatedFyc = null;
if (CollectionUtils.isNotEmpty(filterList)) {
agentAccumulatedFyc = filterList.get(0);
} }
for (AlgorithmResDto algorithmResDto : resDto.getAlgorithmResDtoList()) {
CalmTask calmTask = new CalmTask(); CalmTask calmTask = new CalmTask();
calmTask.setBrokerBizId(dto.getClientUserBizId()); //保单号
calmTask.setBrokerName(dto.getClientUserName()); calmTask.setPolicyNo(policyNo);
//当前保单转介人累计FYC(当前保单转介人基本法计算积分合值) //新单跟进唯一业务ID
calmTask.setTotalFyc(totalSum); calmTask.setPolicyBizId(policyFollow.getPolicyBizId());
calmTask.setCommissionName(dto.getCommissionName()); //执行时间(定时任务执行时间) = 积分解冻时间
//执行状态->未执行 calmTask.setExecutionTime(resDto.getThawingTime());
calmTask.setExecutionStatus("0");
calmTask.setCalmTaskBizId(RandomStringGenerator.generateBizId16(CommonEnum.UID_TYPE_CALM_TASK.getCode()));
//冷静期天数 //冷静期天数
calmTask.setCoolingOffDays(policyFollow.getCoolingOffDays()); calmTask.setCoolingOffDays(policyFollow.getCoolingOffDays());
//保单冷静期定时任务表唯一业务ID
calmTask.setCalmTaskBizId(RandomStringGenerator.generateBizId16(CommonEnum.UID_TYPE_CALM_TASK.getCode()));
//执行状态(0-未执行,1-执行中,2-已执行,3-执行异常)
//0-未执行
calmTask.setExecutionStatus("0");
//转介人名称
calmTask.setBrokerName(resDto.getClientUserName());
//转介人业务id
calmTask.setBrokerBizId(resDto.getClientUserBizId());
//佣金项目
calmTask.setCommissionName(algorithmResDto.getItemName());
//发佣期数
calmTask.setFortunePeriod(resDto.getFortunePeriod());
//佣金值(积分值)
calmTask.setFyc(algorithmResDto.getCalculatedValue());
//冷静期结束日期 //冷静期结束日期
calmTask.setCoolingOffEndDate(policyFollow.getCoolingOffEndDate()); calmTask.setCoolingOffEndDate(policyFollow.getCoolingOffEndDate());
//执行时间(定时任务执行时间) //业务员积分明细表唯一业务ID
calmTask.setExecutionTime(policyFollow.getCoolingOffEndDate().toInstant() String detailFycBizId = RandomStringGenerator.generateBizId16(CommonEnum.UID_TYPE_AGENT_DETAIL_FYC.getCode());
.atZone(ZoneId.of("Asia/Shanghai")) calmTask.setDetailFycBizId(detailFycBizId);
.toLocalDateTime()); iCalmTaskService.saveOrUpdate(calmTask);
//新单跟进唯一业务ID
calmTask.setPolicyBizId(policyFollow.getPolicyBizId()); //新增积分明细
//保单号 addAgentDetailFyc(resDto,policyNo,algorithmResDto,detailFycBizId,agentAccumulatedFyc);
calmTask.setPolicyNo(policyNo);
return calmTask;
}).collect(Collectors.toList());
iCalmTaskService.saveOrUpdateBatch(resultList);
log.info("完成基本法分组计算,policyNo: {}, 分组后用户数: {}", policyNo, resultList.size());
// 构建冷静期定时任务逻辑
//创建XXL-Job定时任务 //创建XXL-Job定时任务
if (CollectionUtils.isNotEmpty(resultList)) { xxlJobService.addScheduleJob(calmTask.getCalmTaskBizId(),"冷静期定时发送任务-","calmSendJobHandler",Date.from(resDto.getThawingTime().atZone(ZoneId.systemDefault()).toInstant()));
//循环创建定时任务(多个冷静期的定时任务)
for (CalmTask calmTask : resultList) {
xxlJobService.addScheduleJob(calmTask.getCalmTaskBizId(),"冷静期定时发送任务-","calmSendJobHandler",calmTask.getCoolingOffEndDate());
} }
} }
//更新积分总表的值
updateAgentAccumulatedFyc(accumulatedFycList,filteredCollectResDtos);
} }
/** /**
* 从 AlgorithmResDto 列表中计算所有 calculatedValue 的总和 * 新增积分明细
* @param resDto
* @param policyNo
* @param algorithmResDto
* @param detailFycBizId
* @param agentAccumulatedFyc
*/ */
private BigDecimal calculateSumFromResList(List<AlgorithmResDto> resDtoList) { public void addAgentDetailFyc(AlgorithmCollectResDto resDto,
if (CollectionUtils.isEmpty(resDtoList)) { String policyNo,
return BigDecimal.ZERO; AlgorithmResDto algorithmResDto,
} String detailFycBizId,
return resDtoList.stream() AgentAccumulatedFyc agentAccumulatedFyc) {
.map(AlgorithmResDto::getCalculatedValue) //新增积分明细
.filter(Objects::nonNull) AgentDetailFyc agentDetailFyc = new AgentDetailFyc();
.reduce(BigDecimal.ZERO, BigDecimal::add); //积分来源类型
agentDetailFyc.setSourceType(FycSourceTypeEnum.CALM_TASK.getItemValue());
//业务员ID
agentDetailFyc.setAgentId(resDto.getClientUserBizId());
//积分提供的保单号
agentDetailFyc.setPolicyNo(policyNo);
//积分来源基本法项目配置表唯一业务ID
agentDetailFyc.setRuleItemBizId(algorithmResDto.getRuleItemBizId());
//业务员积分明细表唯一业务ID
agentDetailFyc.setDetailFycBizId(detailFycBizId);
//状态(0:停用(冻结) 1:启用(生效))
//冻结
agentDetailFyc.setStatus(0);
//积分解冻时间
agentDetailFyc.setThawingTime(resDto.getThawingTime());
//变化前的业务员总FYC积分(已生效+未生效)
agentDetailFyc.setBeforeFyc(agentAccumulatedFyc != null ? agentAccumulatedFyc.getTotalFyc() : BigDecimal.ZERO);
//变化值(-代表减少)
agentDetailFyc.setChangeFyc(algorithmResDto.getCalculatedValue().toString());
//变化后的业务员总FYC积分
agentDetailFyc.setAfterFyc(agentDetailFyc.getBeforeFyc().add(algorithmResDto.getCalculatedValue()));
iAgentDetailFycService.saveOrUpdate(agentDetailFyc);
} }
/** /**
* 从 AlgorithmResDto 列表中构建去重后的佣金项目名称(分号拼接) * 更新积分总表的值
* @param accumulatedFycList
* @param filteredCollectResDtos
*/ */
private String buildCommissionName(List<AlgorithmResDto> resDtoList) { public void updateAgentAccumulatedFyc(List<AgentAccumulatedFyc> accumulatedFycList,
if (CollectionUtils.isEmpty(resDtoList)) { List<AlgorithmCollectResDto> filteredCollectResDtos) {
return ""; //更新积分总表的值,更新这个accumulatedFycList的每个对象里面的:未生效累计积分(不限业务场景)、累计积分 = 未生效累计积分 + 已生效累计积分、未生效累计首期佣金积分值(佣金场景)、未生效累计非首期佣金积分值(佣金场景)
// 将查询到的累计积分列表转为 Map(便于更新)
Map<String, AgentAccumulatedFyc> fycMap = accumulatedFycList.stream()
.collect(Collectors.toMap(
AgentAccumulatedFyc::getAgentId,
Function.identity(),
(v1, v2) -> v1
));
// 构建每个转介人本次的积分增量 Map
// 未生效累计积分增量
Map<String, BigDecimal> noEffectDeltaMap = new HashMap<>();
// 未生效首期佣金增量
Map<String, BigDecimal> noFirstCommissionDeltaMap = new HashMap<>();
// 未生效非首期佣金增量
Map<String, BigDecimal> noRycDeltaMap = new HashMap<>();
for (AlgorithmCollectResDto resDto : filteredCollectResDtos) {
String agentId = resDto.getClientUserBizId();
Integer fortunePeriod = resDto.getFortunePeriod();
for (AlgorithmResDto algorithmResDto : resDto.getAlgorithmResDtoList()) {
BigDecimal val = algorithmResDto.getCalculatedValue();
if (val == null) continue;
// 累加 noEffect 增量
noEffectDeltaMap.merge(agentId, val, BigDecimal::add);
// 根据期数判断佣金类型
if (fortunePeriod != null && fortunePeriod == 1) {
noFirstCommissionDeltaMap.merge(agentId, val, BigDecimal::add);
} else {
noRycDeltaMap.merge(agentId, val, BigDecimal::add);
}
} }
return resDtoList.stream()
.map(AlgorithmResDto::getItemName)
.filter(StringUtils::isNotBlank)
.distinct()
.collect(Collectors.joining(";"));
} }
/** // 更新或新建累计积分记录
* 合并两个佣金名称字符串(去重后用分号拼接) List<AgentAccumulatedFyc> toUpdateList = new ArrayList<>();
*/ for (String agentId : noEffectDeltaMap.keySet()) {
private String mergeCommissionNames(String name1, String name2) { BigDecimal noEffectDelta = noEffectDeltaMap.get(agentId);
Set<String> nameSet = new LinkedHashSet<>(); BigDecimal noFirstDelta = noFirstCommissionDeltaMap.getOrDefault(agentId, BigDecimal.ZERO);
if (StringUtils.isNotBlank(name1)) { BigDecimal noRycDelta = noRycDeltaMap.getOrDefault(agentId, BigDecimal.ZERO);
nameSet.addAll(Arrays.asList(name1.split(";")));
AgentAccumulatedFyc fyc = fycMap.get(agentId);
if (fyc == null) {
continue;
} }
if (StringUtils.isNotBlank(name2)) { // 应用增量
nameSet.addAll(Arrays.asList(name2.split(";"))); //未生效累计积分(不限业务场景)
fyc.setNoEffect(fyc.getNoEffect().add(noEffectDelta));
//未生效累计首期佣金积分值(佣金场景)
fyc.setNoFirstCommission(fyc.getNoFirstCommission().add(noFirstDelta));
//未生效累计非首期佣金积分值(佣金场景)
fyc.setNoRyc(fyc.getNoRyc().add(noRycDelta));
//累计积分 = 未生效累计积分 + 已生效累计积分
fyc.setTotalFyc(fyc.getNoEffect().add(fyc.getEffect()));
toUpdateList.add(fyc);
} }
return String.join(";", nameSet);
// 批量保存
if (CollectionUtils.isNotEmpty(toUpdateList)) {
iAgentAccumulatedFycService.saveOrUpdateBatch(toUpdateList);
log.info("更新业务员累计积分完成,涉及人数: {}", toUpdateList.size());
//批量新增积分总表日志表
List<AgentAccumulatedFycLog> saveLogList = toUpdateList.stream().map(dto -> {
AgentAccumulatedFycLog log = new AgentAccumulatedFycLog();
BeanUtils.copyProperties(dto,log);
log.setId(null);
log.setFycBizId(dto.getFycBizId());
log.setFycLogBizId(RandomStringGenerator.generateBizId16(CommonEnum.UID_TYPE_AGENT_ACCUMULATED_FYC_LOG.getCode()));
//操作来源枚举-冻结
log.setSourceType(OprSourceEnum.CALM_TASK_FREEZE.getItemValue());
return log;
}).collect(Collectors.toList());
iAgentAccumulatedFycLogService.saveOrUpdateBatch(saveLogList);
} }
}
} }
\ No newline at end of file
package com.yd.csf.api.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* <p>
* 业务员累计积分表操作日志记录表(每次主表(累计积分表)的操作变化记录) 前端控制器
* </p>
*
* @author zxm
* @since 2026-04-17
*/
@RestController
@RequestMapping("/agentAccumulatedFycLog")
public class AgentAccumulatedFycLogController {
}
package com.yd.csf.api.dto; package com.yd.csf.api.dto;
import lombok.Data; import lombok.Data;
import java.math.BigDecimal; import java.time.LocalDateTime;
import java.util.List; import java.util.List;
/** /**
...@@ -21,14 +21,24 @@ public class AlgorithmCollectResDto { ...@@ -21,14 +21,24 @@ public class AlgorithmCollectResDto {
private String clientUserName; private String clientUserName;
/** /**
* 计算值-当前用户的基本法合计值(客户端用户业务ID分组后统计组内的algorithmResDtoList的里面的calculatedValue合计值) * 发佣期数(1=第一年; 2=第二年; 3=第三年; 4=第四年; 5=第五年)
*/ */
private BigDecimal sumCalculatedValue; private Integer fortunePeriod;
/** /**
* 计算值-佣金项目(去重algorithmResDtoList的itemName通过分号拼接的 * 积分解冻时间(受发佣期数影响,第一年就是冷静期结束日期,第二年冷静期结束日期+1年,以此类推
*/ */
private String commissionName; private LocalDateTime thawingTime;
// /**
// * 计算值-当前用户的基本法合计值(客户端用户业务ID分组后统计组内的algorithmResDtoList的里面的calculatedValue合计值)
// */
// private BigDecimal sumCalculatedValue;
//
// /**
// * 计算值-佣金项目(去重algorithmResDtoList的itemName通过分号拼接的)
// */
// private String commissionName;
/** /**
* 算法-基本法计算-返回的列表(当前客户端用户绑定的多个基本法类型的计算值列表) * 算法-基本法计算-返回的列表(当前客户端用户绑定的多个基本法类型的计算值列表)
......
...@@ -3,11 +3,20 @@ package com.yd.csf.api.handler; ...@@ -3,11 +3,20 @@ package com.yd.csf.api.handler;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.xxl.job.core.context.XxlJobHelper; import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob; import com.xxl.job.core.handler.annotation.XxlJob;
import com.yd.csf.service.service.ICalmTaskService; import com.yd.common.enums.CommonEnum;
import com.yd.common.utils.RandomStringGenerator;
import com.yd.csf.api.service.ApiAgentDetailFycService;
import com.yd.csf.feign.enums.FycSourceTypeEnum;
import com.yd.csf.feign.enums.OprSourceEnum;
import com.yd.csf.service.model.*;
import com.yd.csf.service.service.*;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.Objects; import java.util.Objects;
...@@ -19,34 +28,104 @@ import java.util.Objects; ...@@ -19,34 +28,104 @@ import java.util.Objects;
@Slf4j @Slf4j
public class CalmSendJobHandler { public class CalmSendJobHandler {
@Autowired @Resource
private ICalmTaskService iCalmTaskService; private ICalmTaskService iCalmTaskService;
@Resource
private IAgentDetailFycService iAgentDetailFycService;
@Resource
private IAgentAccumulatedFycService iAgentAccumulatedFycService;
@Resource
private IAgentAccumulatedFycLogService iAgentAccumulatedFycLogService;
/** /**
* XXL-Job任务执行入口方法 * XXL-Job任务执行入口方法
*/ */
@XxlJob("calmSendJobHandler") @XxlJob("calmSendJobHandler")
public void execute() throws Exception { public void execute() throws Exception {
// //主任务发送时间 //主任务发送时间
// LocalDateTime taskSendTime = LocalDateTime.now(); LocalDateTime taskSendTime = LocalDateTime.now();
// // 从XXL-Job参数中获取任务ID // 从XXL-Job参数中获取任务ID
// String param = XxlJobHelper.getJobParam(); String param = XxlJobHelper.getJobParam();
// // 记录任务开始日志 // 记录任务开始日志
// log.info("开始冷静期定时发送任务,参数: {}", param); log.info("开始冷静期定时发送任务,参数: {}", param);
//
// // 解析任务参数(参数为冷静期定时任务业务ID) // 解析任务参数(参数为冷静期定时任务业务ID)
// String taskBizId = param; String taskBizId = param;
// // 根据冷静期定时任务业务ID查询冷静期定时任务信息 // 根据冷静期定时任务业务ID查询冷静期定时任务信息
// EmailTask emailTask = iCalmTaskService.queryOne(taskBizId); CalmTask calmTask = iCalmTaskService.queryOne(taskBizId);
// log.info("根据邮件任务业务ID查询邮件任务信息: {}: " + JSON.toJSONString(emailTask)); log.info("根据冷静期定时发送任务业务ID查询冷静期定时任务信息: {}: " + JSON.toJSONString(calmTask));
//
// // 检查邮件任务是否存在 // 检查冷静期定时任务是否存在
// if (Objects.isNull(emailTask)) { if (Objects.isNull(calmTask)) {
// // 记录错误并返回 // 记录错误并返回
// XxlJobHelper.log("邮件任务不存在: " + taskBizId); XxlJobHelper.log("冷静期定时发送任务不存在: " + taskBizId);
// XxlJobHelper.handleFail("邮件任务不存在"); XxlJobHelper.handleFail("冷静期定时发送任务不存在");
// return; return;
// } }
//更新保单冷静期定时任务对象字段
//执行状态: 2-已执行
calmTask.setExecutionStatus("2");
iCalmTaskService.saveOrUpdate(calmTask);
//更新保单冷静期定时任务对应的积分明细对象字段
//查询积分明细
AgentDetailFyc agentDetailFyc = iAgentDetailFycService.queryOne(calmTask.getDetailFycBizId());
if (agentDetailFyc != null) {
//状态:生效
agentDetailFyc.setStatus(1);
iAgentDetailFycService.saveOrUpdate(agentDetailFyc);
}
//更新积分总表的字段(此时积分都已经生效)
//查询积分总表对象 弄好了,差一个每月1号晋升职级定时任务未开发,还有个基本法要根据保单生效日所在月对应的积分总表操作日志记录表来找出对应月的最大职级(晋升职级累计积分)(少个积分总表操作日志记录表)
AgentAccumulatedFyc agentAccumulatedFyc = iAgentAccumulatedFycService.queryOne(calmTask.getBrokerBizId());
if (agentAccumulatedFyc != null) {
//未生效累计积分(不限业务场景)= 未生效累计积分(不限业务场景) - 增量积分
BigDecimal noEffect = agentAccumulatedFyc.getNoEffect().subtract(calmTask.getFyc());
agentAccumulatedFyc.setNoEffect(noEffect.compareTo(BigDecimal.ZERO) < 0 ? BigDecimal.ZERO : noEffect);
//已生效累计积分(不限业务场景) = 已生效累计积分(不限业务场景) + 增量积分
BigDecimal effect = agentAccumulatedFyc.getEffect().add(calmTask.getFyc());
agentAccumulatedFyc.setEffect(effect);
//累计积分 = 未生效累计积分 + 已生效累计积分
agentAccumulatedFyc.setTotalFyc(agentAccumulatedFyc.getNoEffect().add(agentAccumulatedFyc.getEffect()));
if (calmTask.getFortunePeriod() == 1) {
//首期
//已生效累计首期佣金积分值(佣金场景) = 已生效累计首期佣金积分值(佣金场景) + 增量积分
BigDecimal firstCommission = agentAccumulatedFyc.getFirstCommission().add(calmTask.getFyc());
agentAccumulatedFyc.setFirstCommission(firstCommission);
//未生效累计首期佣金积分值(佣金场景)= 未生效累计首期佣金积分值(佣金场景)- 增量积分
BigDecimal noFirstCommission = agentAccumulatedFyc.getNoFirstCommission().subtract(calmTask.getFyc());
agentAccumulatedFyc.setNoFirstCommission(noFirstCommission.compareTo(BigDecimal.ZERO) < 0 ? BigDecimal.ZERO : noFirstCommission);
}else {
//非首期
//已生效累计非首期佣金积分值(佣金场景) = 已生效累计非首期佣金积分值(佣金场景) + 增量积分
BigDecimal ryc = agentAccumulatedFyc.getRyc().add(calmTask.getFyc());
agentAccumulatedFyc.setRyc(ryc);
//未生效累计非首期佣金积分值(佣金场景)= 未生效累计非首期佣金积分值(佣金场景)- 增量积分
BigDecimal noRyc = agentAccumulatedFyc.getNoRyc().subtract(calmTask.getFyc());
agentAccumulatedFyc.setNoRyc(noRyc.compareTo(BigDecimal.ZERO) < 0 ? BigDecimal.ZERO : noRyc);
} }
//晋升职级累计积分 = 已生效累计积分 - 已生效累计非首期佣金积分值
BigDecimal promotion = agentAccumulatedFyc.getEffect().subtract(agentAccumulatedFyc.getRyc());
agentAccumulatedFyc.setPromotion(promotion.compareTo(BigDecimal.ZERO) < 0 ? BigDecimal.ZERO : promotion);
//最后计算日期,记录最后一次计算累计FYC的日期
agentAccumulatedFyc.setLastCalcDate(LocalDateTime.now());
iAgentAccumulatedFycService.saveOrUpdate(agentAccumulatedFyc);
//新增积分总表日志表
AgentAccumulatedFycLog log = new AgentAccumulatedFycLog();
BeanUtils.copyProperties(agentAccumulatedFyc,log);
log.setId(null);
log.setFycBizId(agentAccumulatedFyc.getFycBizId());
log.setFycLogBizId(RandomStringGenerator.generateBizId16(CommonEnum.UID_TYPE_AGENT_ACCUMULATED_FYC_LOG.getCode()));
//操作来源枚举-解冻
log.setSourceType(OprSourceEnum.CALM_TASK_FREEZE.getItemValue());
iAgentAccumulatedFycLogService.saveOrUpdate(log);
}
}
} }
\ No newline at end of file
...@@ -2,6 +2,7 @@ package com.yd.csf.api.service; ...@@ -2,6 +2,7 @@ package com.yd.csf.api.service;
import com.yd.common.result.Result; import com.yd.common.result.Result;
import com.yd.csf.api.dto.GenerateAgentDetailFycDto; import com.yd.csf.api.dto.GenerateAgentDetailFycDto;
import com.yd.csf.service.model.AgentDetailFyc;
public interface ApiAgentDetailFycService { public interface ApiAgentDetailFycService {
......
...@@ -532,6 +532,12 @@ public class ApiExpectedFortuneServiceImpl implements ApiExpectedFortuneService ...@@ -532,6 +532,12 @@ public class ApiExpectedFortuneServiceImpl implements ApiExpectedFortuneService
throw new BusinessException("保单的供款年期不存在"); throw new BusinessException("保单的供款年期不存在");
} }
// 冷静期结束日期 Date 转换为 LocalDateTime
LocalDateTime baseThawingTime = brokerDto.getCoolingOffEndDate()
.toInstant()
.atZone(ZoneId.systemDefault())
.toLocalDateTime();
List<CommissionRuleBinding> commissionRuleBindingList = brokerRelUserIdList(brokerDto); List<CommissionRuleBinding> commissionRuleBindingList = brokerRelUserIdList(brokerDto);
log.info("同步处理-> 遍历保单转介人列表信息 -> 调用基本法算出预计发佣列表->commissionRuleBindingList:{}",JSON.toJSONString(commissionRuleBindingList)); log.info("同步处理-> 遍历保单转介人列表信息 -> 调用基本法算出预计发佣列表->commissionRuleBindingList:{}",JSON.toJSONString(commissionRuleBindingList));
for (int i = 1; i <= paymentTerm; i++) { for (int i = 1; i <= paymentTerm; i++) {
...@@ -544,6 +550,12 @@ public class ApiExpectedFortuneServiceImpl implements ApiExpectedFortuneService ...@@ -544,6 +550,12 @@ public class ApiExpectedFortuneServiceImpl implements ApiExpectedFortuneService
AlgorithmCollectResDto resDto = new AlgorithmCollectResDto(); AlgorithmCollectResDto resDto = new AlgorithmCollectResDto();
resDto.setClientUserBizId(brokerDto.getBrokerBizId()); resDto.setClientUserBizId(brokerDto.getBrokerBizId());
resDto.setClientUserName(brokerDto.getBrokerName()); resDto.setClientUserName(brokerDto.getBrokerName());
//发佣期数
resDto.setFortunePeriod(i);
// 根据期数增加年份(第一年 +0,第二年 +1,以此类推)
LocalDateTime actualThawingTime = baseThawingTime.plusYears(resDto.getFortunePeriod() - 1);
//积分解冻时间(受发佣期数影响,第一年就是冷静期结束日期,第二年冷静期结束日期+1年,以此类推)
resDto.setThawingTime(actualThawingTime);
resDto.setAlgorithmResDtoList(result.getData()); resDto.setAlgorithmResDtoList(result.getData());
collectResDtos.add(resDto); collectResDtos.add(resDto);
...@@ -557,9 +569,13 @@ public class ApiExpectedFortuneServiceImpl implements ApiExpectedFortuneService ...@@ -557,9 +569,13 @@ public class ApiExpectedFortuneServiceImpl implements ApiExpectedFortuneService
.build()); .build());
//收集计算非销售佣金的转介人 //收集计算非销售佣金的转介人
AlgorithmCollectResDto resDto1 = new AlgorithmCollectResDto(); AlgorithmCollectResDto resDto1 = new AlgorithmCollectResDto();
resDto.setClientUserBizId(binding.getTargetId()); resDto1.setClientUserBizId(binding.getTargetId());
resDto.setClientUserName(binding.getTargetName()); resDto1.setClientUserName(binding.getTargetName());
resDto.setAlgorithmResDtoList(result1.getData()); //发佣期数
resDto1.setFortunePeriod(i);
//积分解冻时间(受发佣期数影响,第一年就是冷静期结束日期,第二年冷静期结束日期+1年,以此类推)
resDto1.setThawingTime(actualThawingTime);
resDto1.setAlgorithmResDtoList(result1.getData());
collectResDtos.add(resDto1); collectResDtos.add(resDto1);
} }
......
package com.yd.csf.feign.enums;
/**
* 积分来源枚举
*/
public enum FycSourceTypeEnum {
CALM_TASK("冷静期定时计算","CALM_TASK"),
;
//字典项标签(名称)
private String itemLabel;
//字典项值
private String itemValue;
//构造函数
FycSourceTypeEnum(String itemLabel, String itemValue) {
this.itemLabel = itemLabel;
this.itemValue = itemValue;
}
public String getItemLabel() {
return itemLabel;
}
public String getItemValue() {
return itemValue;
}
}
package com.yd.csf.feign.enums;
/**
* 操作来源枚举
*/
public enum OprSourceEnum {
CALM_TASK_FREEZE("冷静期定时计算-冻结","CALM_TASK_FREEZE"),
CALM_TASK_DEFROST("冷静期定时计算-解冻","CALM_TASK_DEFROST"),
;
//字典项标签(名称)
private String itemLabel;
//字典项值
private String itemValue;
//构造函数
OprSourceEnum(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.dao;
import com.yd.csf.service.model.AgentAccumulatedFycLog;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* <p>
* 业务员累计积分表操作日志记录表(每次主表(累计积分表)的操作变化记录) Mapper 接口
* </p>
*
* @author zxm
* @since 2026-04-17
*/
public interface AgentAccumulatedFycLogMapper extends BaseMapper<AgentAccumulatedFycLog> {
}
...@@ -55,9 +55,9 @@ public class QueryPolicyAndBrokerDto { ...@@ -55,9 +55,9 @@ public class QueryPolicyAndBrokerDto {
private LocalDate effectiveDate; private LocalDate effectiveDate;
/** /**
* 冷静期到期日 * 冷静期结束日期
*/ */
private LocalDate coolingOffEndDate; private Date coolingOffEndDate;
/** /**
* 期交保费 * 期交保费
......
package com.yd.csf.service.model; package com.yd.csf.service.model;
import com.baomidou.mybatisplus.annotation.*; import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
...@@ -14,7 +17,7 @@ import java.time.LocalDateTime; ...@@ -14,7 +17,7 @@ import java.time.LocalDateTime;
* </p> * </p>
* *
* @author zxm * @author zxm
* @since 2025-10-15 * @since 2026-04-16
*/ */
@Getter @Getter
@Setter @Setter
...@@ -30,18 +33,66 @@ public class AgentAccumulatedFyc implements Serializable { ...@@ -30,18 +33,66 @@ public class AgentAccumulatedFyc implements Serializable {
private Long id; private Long id;
/** /**
* 业务员ID(客户端用户表唯一业务ID) * 业务员累计积分表唯一业务ID
*/
@TableField("fyc_biz_id")
private String fycBizId;
/**
* 业务员ID(会员唯一业务ID)
*/ */
@TableField("agent_id") @TableField("agent_id")
private String agentId; private String agentId;
/** /**
* 累计FYC,业务员历史累计的FYC总额 * 未生效累计积分(不限业务场景)
*/
@TableField("no_effect")
private BigDecimal noEffect;
/**
* 已生效累计积分(不限业务场景)
*/
@TableField("effect")
private BigDecimal effect;
/**
* 累计积分 = 未生效累计积分 + 已生效累计积分
*/ */
@TableField("total_fyc") @TableField("total_fyc")
private BigDecimal totalFyc; private BigDecimal totalFyc;
/** /**
* 已生效累计首期佣金积分值(佣金场景)
*/
@TableField("first_commission")
private BigDecimal firstCommission;
/**
* 未生效累计首期佣金积分值(佣金场景)
*/
@TableField("no_first_commission")
private BigDecimal noFirstCommission;
/**
* 已生效累计非首期佣金积分值(佣金场景)
*/
@TableField("ryc")
private BigDecimal ryc;
/**
* 未生效累计非首期佣金积分值(佣金场景)
*/
@TableField("no_ryc")
private BigDecimal noRyc;
/**
* 晋升职级累计积分 = 已生效累计积分 - 已生效累计非首期佣金积分值
*/
@TableField("promotion")
private BigDecimal promotion;
/**
* 当前等级,业务员当前的会员等级编码(会员等级配置表等级编码) * 当前等级,业务员当前的会员等级编码(会员等级配置表等级编码)
*/ */
@TableField("current_grade_code") @TableField("current_grade_code")
...@@ -86,13 +137,13 @@ public class AgentAccumulatedFyc implements Serializable { ...@@ -86,13 +137,13 @@ public class AgentAccumulatedFyc implements Serializable {
/** /**
* 创建人ID * 创建人ID
*/ */
@TableField(value = "creator_id", fill = FieldFill.INSERT) @TableField("creator_id")
private String creatorId; private String creatorId;
/** /**
* 更新人ID * 更新人ID
*/ */
@TableField(value = "updater_id", fill = FieldFill.UPDATE) @TableField("updater_id")
private String updaterId; private String updaterId;
/** /**
......
package com.yd.csf.service.model;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import lombok.Getter;
import lombok.Setter;
/**
* <p>
* 业务员累计积分表操作日志记录表(每次主表(累计积分表)的操作变化记录)
* </p>
*
* @author zxm
* @since 2026-04-17
*/
@Getter
@Setter
@TableName("agent_accumulated_fyc_log")
public class AgentAccumulatedFycLog implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 业务员累计积分表操作日志记录表唯一业务ID
*/
@TableField("fyc_log_biz_id")
private String fycLogBizId;
/**
* 业务员累计积分表唯一业务ID(关联业务员累计积分表)
*/
@TableField("fyc_biz_id")
private String fycBizId;
/**
* 操作来源
*/
@TableField("source_type")
private String sourceType;
/**
* 业务员ID(会员唯一业务ID)
*/
@TableField("agent_id")
private String agentId;
/**
* 未生效累计积分(不限业务场景)
*/
@TableField("no_effect")
private BigDecimal noEffect;
/**
* 已生效累计积分(不限业务场景)
*/
@TableField("effect")
private BigDecimal effect;
/**
* 累计积分 = 未生效累计积分 + 已生效累计积分
*/
@TableField("total_fyc")
private BigDecimal totalFyc;
/**
* 已生效累计首期佣金积分值(佣金场景)
*/
@TableField("first_commission")
private BigDecimal firstCommission;
/**
* 未生效累计首期佣金积分值(佣金场景)
*/
@TableField("no_first_commission")
private BigDecimal noFirstCommission;
/**
* 已生效累计非首期佣金积分值(佣金场景)
*/
@TableField("ryc")
private BigDecimal ryc;
/**
* 未生效累计非首期佣金积分值(佣金场景)
*/
@TableField("no_ryc")
private BigDecimal noRyc;
/**
* 晋升职级累计积分 = 已生效累计积分 - 已生效累计非首期佣金积分值
*/
@TableField("promotion")
private BigDecimal promotion;
/**
* 当前等级,业务员当前的会员等级编码(会员等级配置表等级编码)
*/
@TableField("current_grade_code")
private String currentGradeCode;
/**
* 最后计算日期,记录最后一次计算累计FYC的日期
*/
@TableField("last_calc_date")
private LocalDateTime lastCalcDate;
/**
* 状态(0:停用 1:启用)
*/
@TableField("status")
private Integer status;
/**
* 所属租户唯一业务ID(冗余)
*/
@TableField("tenant_biz_id")
private String tenantBizId;
/**
* 所属项目唯一业务ID(冗余)
*/
@TableField("project_biz_id")
private String projectBizId;
/**
* 通用备注
*/
@TableField("remark")
private String remark;
/**
* 删除标识: 0-正常, 1-删除
*/
@TableField("is_deleted")
private Integer isDeleted;
/**
* 创建人ID
*/
@TableField("creator_id")
private String creatorId;
/**
* 更新人ID
*/
@TableField("updater_id")
private String updaterId;
/**
* 创建时间
*/
@TableField("create_time")
private LocalDateTime createTime;
/**
* 更新时间
*/
@TableField("update_time")
private LocalDateTime updateTime;
}
...@@ -30,13 +30,19 @@ public class AgentDetailFyc implements Serializable { ...@@ -30,13 +30,19 @@ public class AgentDetailFyc implements Serializable {
private Long id; private Long id;
/** /**
* 业务员ID(客户端用户表唯一业务ID) * 业务员积分明细表唯一业务ID
*/
@TableField("detail_fyc_biz_id")
private String detailFycBizId;
/**
* 业务员ID(客户端用户表唯一业务ID,积分接收者)
*/ */
@TableField("agent_id") @TableField("agent_id")
private String agentId; private String agentId;
/** /**
* 积分来源类型:保单转介费、一级管理奖、二级管理奖、辅导津贴奖、终身推荐奖 * 积分来源类型:销售佣金、一级管理佣金、二级管理佣金、辅导津贴佣金、终身推荐佣金、冷静期定时计算
*/ */
@TableField("source_type") @TableField("source_type")
private String sourceType; private String sourceType;
...@@ -84,7 +90,13 @@ public class AgentDetailFyc implements Serializable { ...@@ -84,7 +90,13 @@ public class AgentDetailFyc implements Serializable {
private String changeFyc; private String changeFyc;
/** /**
* 状态(0:停用 1:启用) * 积分解冻时间
*/
@TableField("thawing_time")
private LocalDateTime thawingTime;
/**
* 状态(0:停用(冻结) 1:启用(生效))
*/ */
@TableField("status") @TableField("status")
private Integer status; private Integer status;
......
...@@ -40,6 +40,12 @@ public class CalmTask implements Serializable { ...@@ -40,6 +40,12 @@ public class CalmTask implements Serializable {
private String calmTaskBizId; private String calmTaskBizId;
/** /**
* 业务员积分明细表唯一业务ID
*/
@TableField("detail_fyc_biz_id")
private String detailFycBizId;
/**
* 新单跟进唯一业务ID * 新单跟进唯一业务ID
*/ */
@TableField("policy_biz_id") @TableField("policy_biz_id")
...@@ -58,6 +64,12 @@ public class CalmTask implements Serializable { ...@@ -58,6 +64,12 @@ public class CalmTask implements Serializable {
private String commissionName; private String commissionName;
/** /**
* 发佣期数(1=第一年; 2=第二年; 3=第三年; 4=第四年; 5=第五年)
*/
@TableField("fortune_period")
private Integer fortunePeriod;
/**
* 转介人业务id * 转介人业务id
*/ */
@TableField("broker_biz_id") @TableField("broker_biz_id")
...@@ -70,10 +82,10 @@ public class CalmTask implements Serializable { ...@@ -70,10 +82,10 @@ public class CalmTask implements Serializable {
private String brokerName; private String brokerName;
/** /**
* 当前保单转介人累计FYC(当前保单转介人基本法计算积分合值) * 佣金值(积分值)
*/ */
@TableField("total_fyc") @TableField("fyc")
private BigDecimal totalFyc; private BigDecimal fyc;
/** /**
* 冷静期结束日期 * 冷静期结束日期
...@@ -88,7 +100,7 @@ public class CalmTask implements Serializable { ...@@ -88,7 +100,7 @@ public class CalmTask implements Serializable {
private Integer coolingOffDays; private Integer coolingOffDays;
/** /**
* 执行时间(定时任务执行时间) * 执行时间(定时任务执行时间) = 积分解冻时间(冷静期结束日期 + 期数年份)
*/ */
@TableField("execution_time") @TableField("execution_time")
private LocalDateTime executionTime; private LocalDateTime executionTime;
......
...@@ -60,6 +60,18 @@ public class MemberGradeConfig implements Serializable { ...@@ -60,6 +60,18 @@ public class MemberGradeConfig implements Serializable {
private BigDecimal integralRatio; private BigDecimal integralRatio;
/** /**
* 最小积分值(包含最小值)
*/
@TableField("min_value")
private BigDecimal minValue;
/**
* 最大积分值(不包含最大值)
*/
@TableField("max_value")
private BigDecimal maxValue;
/**
* 等级描述 * 等级描述
*/ */
@TableField("description") @TableField("description")
......
package com.yd.csf.service.service;
import com.yd.csf.service.model.AgentAccumulatedFycLog;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* <p>
* 业务员累计积分表操作日志记录表(每次主表(累计积分表)的操作变化记录) 服务类
* </p>
*
* @author zxm
* @since 2026-04-17
*/
public interface IAgentAccumulatedFycLogService extends IService<AgentAccumulatedFycLog> {
}
...@@ -3,6 +3,8 @@ package com.yd.csf.service.service; ...@@ -3,6 +3,8 @@ package com.yd.csf.service.service;
import com.yd.csf.service.model.AgentAccumulatedFyc; import com.yd.csf.service.model.AgentAccumulatedFyc;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
/** /**
* <p> * <p>
* 业务员累计积分表 - 存储业务员的累计FYC积分和当前等级信息 服务类 * 业务员累计积分表 - 存储业务员的累计FYC积分和当前等级信息 服务类
...@@ -14,4 +16,6 @@ import com.baomidou.mybatisplus.extension.service.IService; ...@@ -14,4 +16,6 @@ import com.baomidou.mybatisplus.extension.service.IService;
public interface IAgentAccumulatedFycService extends IService<AgentAccumulatedFyc> { public interface IAgentAccumulatedFycService extends IService<AgentAccumulatedFyc> {
AgentAccumulatedFyc queryOne(String agentId); AgentAccumulatedFyc queryOne(String agentId);
List<AgentAccumulatedFyc> queryList(List<String> agentIdList);
} }
...@@ -13,4 +13,5 @@ import com.baomidou.mybatisplus.extension.service.IService; ...@@ -13,4 +13,5 @@ import com.baomidou.mybatisplus.extension.service.IService;
*/ */
public interface IAgentDetailFycService extends IService<AgentDetailFyc> { public interface IAgentDetailFycService extends IService<AgentDetailFyc> {
AgentDetailFyc queryOne(String detailFycBizId);
} }
...@@ -3,6 +3,8 @@ package com.yd.csf.service.service; ...@@ -3,6 +3,8 @@ package com.yd.csf.service.service;
import com.yd.csf.service.model.MemberGradeConfig; import com.yd.csf.service.model.MemberGradeConfig;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import java.math.BigDecimal;
/** /**
* <p> * <p>
* 会员等级配置表 服务类 * 会员等级配置表 服务类
...@@ -13,4 +15,5 @@ import com.baomidou.mybatisplus.extension.service.IService; ...@@ -13,4 +15,5 @@ import com.baomidou.mybatisplus.extension.service.IService;
*/ */
public interface IMemberGradeConfigService extends IService<MemberGradeConfig> { public interface IMemberGradeConfigService extends IService<MemberGradeConfig> {
MemberGradeConfig queryOne(BigDecimal fycValue);
} }
package com.yd.csf.service.service.impl;
import com.yd.csf.service.model.AgentAccumulatedFycLog;
import com.yd.csf.service.dao.AgentAccumulatedFycLogMapper;
import com.yd.csf.service.service.IAgentAccumulatedFycLogService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
* <p>
* 业务员累计积分表操作日志记录表(每次主表(累计积分表)的操作变化记录) 服务实现类
* </p>
*
* @author zxm
* @since 2026-04-17
*/
@Service
public class AgentAccumulatedFycLogServiceImpl extends ServiceImpl<AgentAccumulatedFycLogMapper, AgentAccumulatedFycLog> implements IAgentAccumulatedFycLogService {
}
...@@ -5,8 +5,11 @@ import com.yd.csf.service.model.AgentAccumulatedFyc; ...@@ -5,8 +5,11 @@ import com.yd.csf.service.model.AgentAccumulatedFyc;
import com.yd.csf.service.dao.AgentAccumulatedFycMapper; import com.yd.csf.service.dao.AgentAccumulatedFycMapper;
import com.yd.csf.service.service.IAgentAccumulatedFycService; import com.yd.csf.service.service.IAgentAccumulatedFycService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.List;
/** /**
* <p> * <p>
* 业务员累计积分表 - 存储业务员的累计FYC积分和当前等级信息 服务实现类 * 业务员累计积分表 - 存储业务员的累计FYC积分和当前等级信息 服务实现类
...@@ -25,7 +28,14 @@ public class AgentAccumulatedFycServiceImpl extends ServiceImpl<AgentAccumulated ...@@ -25,7 +28,14 @@ public class AgentAccumulatedFycServiceImpl extends ServiceImpl<AgentAccumulated
*/ */
@Override @Override
public AgentAccumulatedFyc queryOne(String agentId) { public AgentAccumulatedFyc queryOne(String agentId) {
return this.getOne(new LambdaQueryWrapper<AgentAccumulatedFyc>().eq(AgentAccumulatedFyc::getAgentId,agentId).last("limit 1")); return this.getOne(new LambdaQueryWrapper<AgentAccumulatedFyc>()
.eq(AgentAccumulatedFyc::getAgentId,agentId).last("limit 1"));
}
@Override
public List<AgentAccumulatedFyc> queryList(List<String> agentIdList) {
return this.baseMapper.selectList(new LambdaQueryWrapper<AgentAccumulatedFyc>()
.in(CollectionUtils.isNotEmpty(agentIdList),AgentAccumulatedFyc::getAgentId,agentIdList));
} }
} }
package com.yd.csf.service.service.impl; package com.yd.csf.service.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yd.csf.service.model.AgentDetailFyc; import com.yd.csf.service.model.AgentDetailFyc;
import com.yd.csf.service.dao.AgentDetailFycMapper; import com.yd.csf.service.dao.AgentDetailFycMapper;
import com.yd.csf.service.service.IAgentDetailFycService; import com.yd.csf.service.service.IAgentDetailFycService;
...@@ -17,4 +18,9 @@ import org.springframework.stereotype.Service; ...@@ -17,4 +18,9 @@ import org.springframework.stereotype.Service;
@Service @Service
public class AgentDetailFycServiceImpl extends ServiceImpl<AgentDetailFycMapper, AgentDetailFyc> implements IAgentDetailFycService { public class AgentDetailFycServiceImpl extends ServiceImpl<AgentDetailFycMapper, AgentDetailFyc> implements IAgentDetailFycService {
@Override
public AgentDetailFyc queryOne(String detailFycBizId) {
return this.baseMapper.selectOne(new LambdaQueryWrapper<AgentDetailFyc>()
.eq(AgentDetailFyc::getDetailFycBizId,detailFycBizId).last(" limit 1 "));
}
} }
package com.yd.csf.service.service.impl; package com.yd.csf.service.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yd.csf.service.model.CalmTask; import com.yd.csf.service.model.CalmTask;
import com.yd.csf.service.dao.CalmTaskMapper; import com.yd.csf.service.dao.CalmTaskMapper;
import com.yd.csf.service.service.ICalmTaskService; import com.yd.csf.service.service.ICalmTaskService;
...@@ -24,6 +25,7 @@ public class CalmTaskServiceImpl extends ServiceImpl<CalmTaskMapper, CalmTask> i ...@@ -24,6 +25,7 @@ public class CalmTaskServiceImpl extends ServiceImpl<CalmTaskMapper, CalmTask> i
*/ */
@Override @Override
public CalmTask queryOne(String calmTaskBizId) { public CalmTask queryOne(String calmTaskBizId) {
return null; return this.baseMapper.selectOne(new LambdaQueryWrapper<CalmTask>()
.eq(CalmTask::getCalmTaskBizId,calmTaskBizId).last(" limit 1 "));
} }
} }
package com.yd.csf.service.service.impl; package com.yd.csf.service.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yd.csf.service.model.MemberGradeConfig; import com.yd.csf.service.model.MemberGradeConfig;
import com.yd.csf.service.dao.MemberGradeConfigMapper; import com.yd.csf.service.dao.MemberGradeConfigMapper;
import com.yd.csf.service.service.IMemberGradeConfigService; import com.yd.csf.service.service.IMemberGradeConfigService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.math.BigDecimal;
/** /**
* <p> * <p>
* 会员等级配置表 服务实现类 * 会员等级配置表 服务实现类
...@@ -17,4 +20,21 @@ import org.springframework.stereotype.Service; ...@@ -17,4 +20,21 @@ import org.springframework.stereotype.Service;
@Service @Service
public class MemberGradeConfigServiceImpl extends ServiceImpl<MemberGradeConfigMapper, MemberGradeConfig> implements IMemberGradeConfigService { public class MemberGradeConfigServiceImpl extends ServiceImpl<MemberGradeConfigMapper, MemberGradeConfig> implements IMemberGradeConfigService {
/**
* 根据积分查询范围内的等级
* @param fycValue
* @return
*/
@Override
public MemberGradeConfig queryOne(BigDecimal fycValue) {
LambdaQueryWrapper<MemberGradeConfig> wrapper = new LambdaQueryWrapper<>();
wrapper.le(MemberGradeConfig::getMinValue, fycValue) // min_value <= fycValue
.and(w -> w.isNull(MemberGradeConfig::getMaxValue) // max_value IS NULL
.or()
.gt(MemberGradeConfig::getMaxValue, fycValue) // 或 fycValue < max_value
)
.eq(MemberGradeConfig::getStatus, 1)
.last(" limit 1");
return getOne(wrapper);
}
} }
...@@ -21,7 +21,7 @@ public class MyBatisPlusCodeGenerator { ...@@ -21,7 +21,7 @@ public class MyBatisPlusCodeGenerator {
}) })
.strategyConfig(builder -> { .strategyConfig(builder -> {
builder.addInclude( builder.addInclude(
"calm_task" "agent_accumulated_fyc_log"
) )
.entityBuilder() .entityBuilder()
......
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yd.csf.service.dao.AgentAccumulatedFycLogMapper">
</mapper>
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