bd结算新增 明细数据保存
This commit is contained in:
parent
5878beb0d6
commit
d1bca6f78f
@ -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);
|
||||
|
||||
@ -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 的团队数据.
|
||||
*/
|
||||
|
||||
@ -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;
|
||||
|
||||
/**
|
||||
* 创建时间.
|
||||
*/
|
||||
|
||||
@ -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;
|
||||
|
||||
/**
|
||||
* 创建时间.
|
||||
*/
|
||||
|
||||
@ -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;
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user