bd结算新增 明细数据保存

This commit is contained in:
tianfeng 2025-10-31 10:59:48 +08:00
parent 5878beb0d6
commit d1bca6f78f
6 changed files with 289 additions and 9 deletions

View File

@ -3,6 +3,9 @@ package com.red.circle.other.app.service;
import com.red.circle.common.business.core.enums.ReceiptType;
import com.red.circle.common.business.core.enums.SysOriginPlatformEnum;
import com.red.circle.other.app.dto.clientobject.BdLeaderSalarySettlementCO;
import com.red.circle.other.domain.gateway.user.UserProfileGateway;
import com.red.circle.other.domain.model.user.UserProfile;
import com.red.circle.other.infra.database.mongo.entity.bd.detail.BdLeaderTeamMemberDetail;
import com.red.circle.other.infra.enums.BdSettlementStatus;
import com.red.circle.other.infra.database.mongo.entity.bd.BdLeaderSalaryPolicy;
import com.red.circle.other.infra.database.mongo.entity.bd.BdLeaderSalarySettlementRecord;
@ -11,7 +14,9 @@ import com.red.circle.other.infra.database.mongo.service.bd.BdLeaderSalaryPolicy
import com.red.circle.other.infra.database.mongo.service.bd.BdLeaderSalarySettlementRecordService;
import com.red.circle.other.infra.database.mongo.service.bd.BdSalarySettlementRecordService;
import com.red.circle.other.infra.database.rds.entity.team.BusinessDevelopmentBaseInfo;
import com.red.circle.other.infra.database.rds.entity.team.BusinessDevelopmentTeam;
import com.red.circle.other.infra.database.rds.service.team.BusinessDevelopmentBaseInfoService;
import com.red.circle.other.infra.database.rds.service.team.BusinessDevelopmentTeamService;
import com.red.circle.tool.core.collection.CollectionUtils;
import com.red.circle.tool.core.date.TimestampUtils;
import com.red.circle.tool.core.sequence.IdWorkerUtils;
@ -27,8 +32,7 @@ import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.stream.Collectors;
/**
@ -43,11 +47,13 @@ import java.util.stream.Collectors;
public class BdLeaderSalarySettlementServiceImpl implements BdLeaderSalarySettlementService {
private final BusinessDevelopmentBaseInfoService businessDevelopmentBaseInfoService;
private final BusinessDevelopmentTeamService businessDevelopmentTeamService;
private final BdSalarySettlementRecordService bdSalarySettlementRecordService;
private final BdLeaderSalaryPolicyService bdLeaderSalaryPolicyService;
private final BdLeaderSalarySettlementRecordService bdLeaderSalarySettlementRecordService;
private final UserBankBalanceClient userBankBalanceClient;
private final UserBankRunningWaterClient userBankRunningWaterClient;
private final UserProfileGateway userProfileGateway;
@Override
public void processAllBdLeaderSettlement(Integer billBelong, String billTitle) {
@ -114,15 +120,50 @@ public class BdLeaderSalarySettlementServiceImpl implements BdLeaderSalarySettle
record.setBizNo(bizNo);
record.setStatus(BdSettlementStatus.PENDING);
// 4. 统计所有 BD 的工资总和
// 4. 统计所有 BD 的工资总和并收集成员明细
List<BdLeaderTeamMemberDetail> memberDetails = new ArrayList<>();
BigDecimal totalBdSalary = BigDecimal.ZERO;
for (Long bdUserId : bdUserIds) {
BdSalarySettlementRecord bdRecord = bdSalarySettlementRecordService.getByUserIdAndBillBelong(bdUserId, billBelong);
if (bdRecord != null && bdRecord.getSettlementSalary() != null) {
totalBdSalary = totalBdSalary.add(bdRecord.getSettlementSalary());
if (bdRecord != null) {
// 统计工资
if (bdRecord.getSettlementSalary() != null) {
totalBdSalary = totalBdSalary.add(bdRecord.getSettlementSalary());
}
// 收集成员明细
BdLeaderTeamMemberDetail detail = new BdLeaderTeamMemberDetail();
detail.setBdUserId(bdUserId);
detail.setSalary(bdRecord.getSettlementSalary() != null ?
bdRecord.getSettlementSalary().setScale(2, RoundingMode.DOWN) : BigDecimal.ZERO);
detail.setAgencyCount(bdRecord.getAgencyNumber() != null ? bdRecord.getAgencyNumber() : 0);
memberDetails.add(detail);
}
}
record.setTeamSalaryAmount(totalBdSalary.setScale(2, RoundingMode.DOWN));
// 批量查询 BD 用户信息
if (!CollectionUtils.isEmpty(memberDetails)) {
Set<Long> bdUserIdSet = new HashSet<>(bdUserIds);
Map<Long, UserProfile> userProfileMap = userProfileGateway.mapByUserIds(bdUserIdSet);
for (BdLeaderTeamMemberDetail detail : memberDetails) {
UserProfile userProfile = userProfileMap.get(detail.getBdUserId());
if (userProfile != null) {
detail.setBdUserName(userProfile.getUserNickname());
detail.setBdUserAvatar(userProfile.getUserAvatar());
}
}
// 按工资降序排列
memberDetails.sort((a, b) -> b.getSalary().compareTo(a.getSalary()));
}
record.setMemberDetails(memberDetails);
// 5. 匹配政策并计算工资
calculateLeaderSalary(record);

View File

@ -4,6 +4,9 @@ import com.red.circle.common.business.core.enums.ReceiptType;
import com.red.circle.common.business.core.enums.SysOriginPlatformEnum;
import com.red.circle.other.app.dto.clientobject.BdSalarySettlementCO;
import com.red.circle.other.app.dto.clientobject.BdTeamStatisticsCO;
import com.red.circle.other.domain.gateway.user.UserProfileGateway;
import com.red.circle.other.domain.model.user.UserProfile;
import com.red.circle.other.infra.database.mongo.entity.bd.detail.BdTeamMemberDetail;
import com.red.circle.other.infra.enums.BdPolicyType;
import com.red.circle.other.infra.enums.BdSettlementStatus;
import com.red.circle.other.infra.database.mongo.entity.bd.BdSalaryPolicy;
@ -52,6 +55,7 @@ public class BdSalarySettlementServiceImpl implements BdSalarySettlementService
private final UserBankBalanceClient userBankBalanceClient;
private final UserBankRunningWaterClient userBankRunningWaterClient;
private final InAppPurchaseDetailsClientApi inAppPurchaseDetailsClientApi;
private final UserProfileGateway userProfileGateway;
@Override
@ -107,13 +111,17 @@ public class BdSalarySettlementServiceImpl implements BdSalarySettlementService
// 3. 统计 BD 团队数据
BdTeamStatisticsCO teamStatistics = statisticsBdTeam(bdUserId, billBelong);
// 4. 匹配政策并计算工资
BdSalarySettlementRecord record = calculateSalary(bdUserId, billBelong, billTitle, teamStatistics, bizNo);
// 4. 收集团队成员明细数据
List<BdTeamMemberDetail> memberDetails = collectTeamMemberDetails(bdUserId, billBelong, teamStatistics);
// 5. 保存结算记录
// 5. 匹配政策并计算工资
BdSalarySettlementRecord record = calculateSalary(bdUserId, billBelong, billTitle, teamStatistics, bizNo);
record.setMemberDetails(memberDetails);
// 6. 保存结算记录
bdSalarySettlementRecordService.create(record);
// 6. 如果工资大于 0则发放工资
// 7. 如果工资大于 0则发放工资
if (record.getSettlementSalary() != null && record.getSettlementSalary().compareTo(BigDecimal.ZERO) > 0) {
try {
// 调用钱包服务发放工资
@ -138,6 +146,118 @@ public class BdSalarySettlementServiceImpl implements BdSalarySettlementService
return convertToCO(record);
}
/**
* 收集团队成员明细数据.
*/
private List<BdTeamMemberDetail> collectTeamMemberDetails(Long bdUserId, Integer billBelong,
BdTeamStatisticsCO teamStatistics) {
List<BdTeamMemberDetail> memberDetails = new ArrayList<>();
// 查询 BD 下的所有 Agent 团队
List<BusinessDevelopmentTeam> bdTeams = businessDevelopmentTeamService.listByBdUserId(bdUserId);
if (CollectionUtils.isEmpty(bdTeams)) {
return memberDetails;
}
// 收集所有用户ID
Set<Long> allUserIds = new HashSet<>();
Map<Long, Integer> userHostCountMap = new HashMap<>();
Map<Long, BigDecimal> userSalaryMap = new HashMap<>();
// 遍历每个团队统计每个用户的数据
for (BusinessDevelopmentTeam bdTeam : bdTeams) {
// 查询该团队的成员目标记录
List<com.red.circle.other.infra.database.mongo.entity.team.team.TeamMemberTarget> memberTargets =
teamMemberTargetService.listByBillBelong(bdTeam.getTeamId(), billBelong);
if (CollectionUtils.isEmpty(memberTargets)) {
continue;
}
// 统计每个用户的数据
for (com.red.circle.other.infra.database.mongo.entity.team.team.TeamMemberTarget target : memberTargets) {
Long userId = target.getUserId();
allUserIds.add(userId);
// 统计 Host 数量一个团队 = 1个 Host
userHostCountMap.merge(userId, 1, Integer::sum);
// 统计工资从结算结果中获取
if (target.getSettlementResult() != null && target.getSettlementResult().getTotalSalary() != null) {
BigDecimal salary = target.getSettlementResult().getTotalSalary();
userSalaryMap.merge(userId, salary, BigDecimal::add);
}
}
}
if (CollectionUtils.isEmpty(allUserIds)) {
return memberDetails;
}
// 批量查询用户信息
Map<Long, UserProfile> userProfileMap = userProfileGateway.mapByUserIds(allUserIds);
// 计算结算周期的开始和结束时间
int year = billBelong / 100;
int month = billBelong % 100;
java.time.LocalDateTime startTime = java.time.LocalDateTime.of(year, month, 1, 0, 0, 0);
java.time.LocalDateTime endTime = startTime.plusMonths(1).minusSeconds(1);
// 批量查询用户充值统计
Map<Long, BigDecimal> userRechargeMap = new HashMap<>();
try {
com.red.circle.framework.dto.ResultResponse<List<BatchUserRechargeStatisticsDTO>> response =
inAppPurchaseDetailsClientApi.batchUserRechargeStatistics(
new ArrayList<>(allUserIds),
SysOriginPlatformEnum.LIKEI.name(),
startTime,
endTime
);
if (response != null && response.getStatus() && !CollectionUtils.isEmpty(response.getBody())) {
response.getBody().forEach(dto -> {
if (dto.getTotalAmount() != null) {
userRechargeMap.put(dto.getUserId(), dto.getTotalAmount());
}
});
}
} catch (Exception e) {
log.error("查询用户充值统计失败", e);
}
// 组装成员明细数据
for (Long userId : allUserIds) {
BdTeamMemberDetail detail = new BdTeamMemberDetail();
detail.setUserId(userId);
// 设置用户信息
UserProfile userProfile = userProfileMap.get(userId);
if (userProfile != null) {
detail.setUserName(userProfile.getUserNickname());
detail.setUserAvatar(userProfile.getUserAvatar());
}
// 设置工资
BigDecimal salary = userSalaryMap.getOrDefault(userId, BigDecimal.ZERO);
detail.setSalary(salary.setScale(2, RoundingMode.DOWN));
// 设置充值
BigDecimal recharge = userRechargeMap.getOrDefault(userId, BigDecimal.ZERO);
detail.setRecharge(recharge.setScale(2, RoundingMode.DOWN));
// 设置 Host 数量
detail.setHostCount(userHostCountMap.getOrDefault(userId, 0));
memberDetails.add(detail);
}
// 按工资降序排列
memberDetails.sort((a, b) -> b.getSalary().compareTo(a.getSalary()));
return memberDetails;
}
/**
* 统计 BD 的团队数据.
*/

View File

@ -2,6 +2,7 @@ package com.red.circle.other.infra.database.mongo.entity.bd;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.red.circle.other.infra.database.mongo.entity.bd.detail.BdLeaderTeamMemberDetail;
import com.red.circle.other.infra.enums.BdSettlementStatus;
import lombok.Data;
import lombok.experimental.Accessors;
@ -12,6 +13,7 @@ import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.List;
/**
* BD Leader 工资结算记录.
@ -115,6 +117,11 @@ public class BdLeaderSalarySettlementRecord implements Serializable {
*/
private String bizNo;
/**
* 团队成员明细列表BD 维度.
*/
private List<BdLeaderTeamMemberDetail> memberDetails;
/**
* 创建时间.
*/

View File

@ -2,6 +2,7 @@ package com.red.circle.other.infra.database.mongo.entity.bd;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.red.circle.other.infra.database.mongo.entity.bd.detail.BdTeamMemberDetail;
import com.red.circle.other.infra.enums.BdPolicyType;
import com.red.circle.other.infra.enums.BdSettlementStatus;
import lombok.Data;
@ -13,6 +14,7 @@ import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.List;
/**
* BD 工资结算记录.
@ -111,6 +113,11 @@ public class BdSalarySettlementRecord implements Serializable {
*/
private String bizNo;
/**
* 团队成员明细列表Agent 维度.
*/
private List<BdTeamMemberDetail> memberDetails;
/**
* 创建时间.
*/

View File

@ -0,0 +1,50 @@
package com.red.circle.other.infra.database.mongo.entity.bd.detail;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* BD Leader 团队成员明细BD 维度.
*
* @author AI Assistant
* @since 2025-10-31
*/
@Data
@Accessors(chain = true)
public class BdLeaderTeamMemberDetail implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* BD 用户 ID.
*/
@JsonSerialize(using = ToStringSerializer.class)
private Long bdUserId;
/**
* BD 用户名称.
*/
private String bdUserName;
/**
* BD 用户头像.
*/
private String bdUserAvatar;
/**
* 工资金额美元.
*/
private BigDecimal salary;
/**
* Agency 数量.
*/
private Integer agencyCount;
}

View File

@ -0,0 +1,55 @@
package com.red.circle.other.infra.database.mongo.entity.bd.detail;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* BD 团队成员明细Agent 维度.
*
* @author AI Assistant
* @since 2025-10-31
*/
@Data
@Accessors(chain = true)
public class BdTeamMemberDetail implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 用户 ID.
*/
@JsonSerialize(using = ToStringSerializer.class)
private Long userId;
/**
* 用户名称.
*/
private String userName;
/**
* 用户头像.
*/
private String userAvatar;
/**
* 工资金额美元.
*/
private BigDecimal salary;
/**
* 充值金额美元.
*/
private BigDecimal recharge;
/**
* Host 数量.
*/
private Integer hostCount;
}