管理员中心总览接口完善

This commit is contained in:
tianfeng 2025-11-28 11:57:55 +08:00
parent c0def6600f
commit 3bf88ff06b
5 changed files with 370 additions and 0 deletions

View File

@ -1,7 +1,9 @@
package com.red.circle.other.adapter.app;
import com.red.circle.common.business.dto.cmd.AppExtCommand;
import com.red.circle.other.app.dto.clientobject.BdTeamMemberDetailCO;
import com.red.circle.other.app.dto.clientobject.BdTeamOverviewCO;
import com.red.circle.other.app.dto.clientobject.BdTeamSummaryCO;
import com.red.circle.other.app.dto.cmd.BdTeamMemberDetailQueryCmd;
import com.red.circle.other.app.dto.cmd.BdTeamQueryCmd;
import com.red.circle.other.app.service.BdTeamService;
@ -49,4 +51,15 @@ public class BdTeamRestController {
public BdTeamMemberDetailCO queryMemberDetail(@RequestBody BdTeamMemberDetailQueryCmd cmd) {
return bdTeamService.queryMemberDetail(cmd);
}
/**
* 查询BD团队总览
* <p>
* 返回当前用户在BD_LEADERBDAGENCY三个角色下的汇总数据
* </p>
*/
@PostMapping("/summary")
public BdTeamSummaryCO queryTeamSummary(AppExtCommand cmd) {
return bdTeamService.queryTeamSummary(cmd.getReqUserId());
}
}

View File

@ -0,0 +1,289 @@
package com.red.circle.other.app.command.bd.query;
import com.alibaba.fastjson.JSON;
import com.red.circle.component.redis.service.RedisService;
import com.red.circle.other.app.convertor.user.UserProfileAppConvertor;
import com.red.circle.other.app.dto.clientobject.BdTeamMemberCO;
import com.red.circle.other.app.dto.clientobject.BdTeamSummaryCO;
import com.red.circle.other.domain.gateway.user.UserProfileGateway;
import com.red.circle.other.infra.database.mongo.dto.team.TeamBillMemberTarget;
import com.red.circle.other.infra.database.mongo.entity.team.team.TeamBillCycle;
import com.red.circle.other.infra.database.mongo.entity.team.team.TeamMemberTarget;
import com.red.circle.other.infra.database.mongo.entity.team.team.TeamPolicyManager;
import com.red.circle.other.infra.database.mongo.entity.team.team.TeamProfile;
import com.red.circle.other.infra.database.mongo.service.team.TeamBillCycleUtils;
import com.red.circle.other.infra.database.mongo.service.team.team.TeamBillCycleService;
import com.red.circle.other.infra.database.mongo.service.team.team.TeamMemberTargetService;
import com.red.circle.other.infra.database.mongo.service.team.team.TeamPolicyManagerService;
import com.red.circle.other.infra.database.mongo.service.team.team.TeamProfileService;
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.entity.team.RoomBdLead;
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.other.infra.database.rds.service.team.RoomBdLeadService;
import com.red.circle.other.inner.enums.team.TeamBillCycleStatus;
import com.red.circle.other.inner.model.dto.user.UserProfileDTO;
import com.red.circle.tool.core.collection.CollectionUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
/**
* BD团队总览查询执行器
*/
@Slf4j
@Component
@RequiredArgsConstructor
public class BdTeamSummaryQryExe {
private final BusinessDevelopmentTeamService businessDevelopmentTeamService;
private final BusinessDevelopmentBaseInfoService businessDevelopmentBaseInfoService;
private final TeamBillCycleService teamBillCycleService;
private final TeamProfileService teamProfileService;
private final TeamMemberTargetService teamMemberTargetService;
private final TeamPolicyManagerService teamPolicyManagerService;
private final UserProfileGateway userProfileGateway;
private final UserProfileAppConvertor userProfileAppConvertor;
private final RoomBdLeadService roomBdLeadService;
private final RedisService redisService;
/**
* 执行查询
*/
public BdTeamSummaryCO execute(Long userId) {
// 缓存查询
String cacheKey = "bdteam:summary:" + userId;
BdTeamSummaryCO cached = redisService.getStringToObject(cacheKey, BdTeamSummaryCO.class);
if (cached != null) {
return cached;
}
// 查询数据
BdTeamSummaryCO result = queryTeamSummary(userId);
// 缓存结果2分钟
redisService.setString(cacheKey, JSON.toJSONString(result), 2, TimeUnit.MINUTES);
return result;
}
/**
* 查询团队总览
*/
private BdTeamSummaryCO queryTeamSummary(Long userId) {
BdTeamSummaryCO summary = new BdTeamSummaryCO();
// 获取当前账单周期
Integer currentBillBelong = TeamBillCycleUtils.getCalcBillBelong();
// 查询三个角色的数据
BdTeamSummaryCO.TeamSummaryItem bdLeaderTeams = queryBdLeaderSummary(userId, currentBillBelong);
BdTeamSummaryCO.TeamSummaryItem bdTeams = queryBdSummary(userId, currentBillBelong);
BdTeamSummaryCO.TeamSummaryItem agencyTeams = queryAgencySummary(userId, currentBillBelong);
summary.setBdLeaderTeams(bdLeaderTeams);
summary.setBdTeams(bdTeams);
summary.setAgencyTeams(agencyTeams);
// Team earnings this period = BD Teams totalIncome
summary.setTeamEarningsThisPeriod(bdTeams.getTotalIncome());
return summary;
}
/**
* 查询 BD Leader 汇总
*/
private BdTeamSummaryCO.TeamSummaryItem queryBdLeaderSummary(Long bdLeaderUserId, Integer currentBillBelong) {
BdTeamSummaryCO.TeamSummaryItem item = new BdTeamSummaryCO.TeamSummaryItem();
// 查询该 Leader 下的所有 BD
List<BusinessDevelopmentBaseInfo> bdList =
businessDevelopmentBaseInfoService.listBdByLeadUserId(bdLeaderUserId);
if (CollectionUtils.isEmpty(bdList)) {
item.setCount(0);
item.setTotalIncome(BigDecimal.ZERO);
return item;
}
// 过滤BD Leader
Set<Long> bdIdSet = bdList.stream()
.map(BusinessDevelopmentBaseInfo::getUserId)
.collect(Collectors.toSet());
List<RoomBdLead> roomBdLeads = roomBdLeadService.listByUserIds(bdIdSet);
if (CollectionUtils.isEmpty(roomBdLeads)) {
item.setCount(0);
item.setTotalIncome(BigDecimal.ZERO);
return item;
}
List<Long> bdLeaderIdList = roomBdLeads.stream()
.map(RoomBdLead::getUserId)
.toList();
bdList = bdList.stream()
.filter(e -> !e.getUserId().equals(bdLeaderUserId))
.filter(e -> bdLeaderIdList.contains(e.getUserId()))
.collect(Collectors.toList());
item.setCount(bdList.size());
// 汇总所有 BD 的收入
BigDecimal totalIncome = BigDecimal.ZERO;
for (BusinessDevelopmentBaseInfo bdInfo : bdList) {
List<BusinessDevelopmentTeam> bdTeamList =
businessDevelopmentTeamService.listByUserId(bdInfo.getUserId());
if (CollectionUtils.isNotEmpty(bdTeamList)) {
BigDecimal bdIncome = calculateBdTotalIncome(bdTeamList, currentBillBelong);
totalIncome = totalIncome.add(bdIncome);
}
}
item.setTotalIncome(totalIncome);
return item;
}
/**
* 查询 BD 汇总
*/
private BdTeamSummaryCO.TeamSummaryItem queryBdSummary(Long bdUserId, Integer currentBillBelong) {
BdTeamSummaryCO.TeamSummaryItem item = new BdTeamSummaryCO.TeamSummaryItem();
// 查询该用户下的所有 Agency 团队
List<BusinessDevelopmentTeam> bdTeamList = businessDevelopmentTeamService.listByUserId(bdUserId);
if (CollectionUtils.isEmpty(bdTeamList)) {
item.setCount(0);
item.setTotalIncome(BigDecimal.ZERO);
return item;
}
item.setCount(bdTeamList.size());
// 计算总收入
BigDecimal totalIncome = calculateBdTotalIncome(bdTeamList, currentBillBelong);
item.setTotalIncome(totalIncome);
return item;
}
/**
* 查询 Agency 汇总
*/
private BdTeamSummaryCO.TeamSummaryItem queryAgencySummary(Long agencyUserId, Integer currentBillBelong) {
BdTeamSummaryCO.TeamSummaryItem item = new BdTeamSummaryCO.TeamSummaryItem();
// 查询该用户的所有团队
List<BusinessDevelopmentTeam> bdTeamList = businessDevelopmentTeamService.listByUserId(agencyUserId);
if (CollectionUtils.isEmpty(bdTeamList)) {
item.setCount(0);
item.setTotalIncome(BigDecimal.ZERO);
return item;
}
item.setCount(bdTeamList.size());
// 获取团队ID集合
Set<Long> teamIdSet = bdTeamList.stream()
.map(BusinessDevelopmentTeam::getTeamId)
.collect(Collectors.toSet());
// 查询账单数据
Map<Long, TeamBillCycle> billCycleMap = teamBillCycleService.mapByTeamIds2(
teamIdSet, currentBillBelong, TeamBillCycleStatus.UNPAID);
Map<Long, List<TeamMemberTarget>> memberTargetMap =
teamMemberTargetService.mapMemberBillTarget(teamIdSet, currentBillBelong);
// 查询区域政策
Map<String, TeamPolicyManager> policyManagerMap = teamPolicyManagerService.mapRegionRelease(
billCycleMap.values().stream()
.map(TeamBillCycle::getRegion)
.collect(Collectors.toSet()));
// 计算总收入
BigDecimal totalIncome = BigDecimal.ZERO;
for (BusinessDevelopmentTeam bdTeam : bdTeamList) {
BigDecimal teamIncome = getTeamTotalSalary(
billCycleMap, memberTargetMap, policyManagerMap, bdTeam.getTeamId());
totalIncome = totalIncome.add(teamIncome);
}
item.setTotalIncome(totalIncome);
return item;
}
/**
* 计算 BD 的总收入汇总其所有 Agency 团队的收入
*/
private BigDecimal calculateBdTotalIncome(List<BusinessDevelopmentTeam> bdTeamList, Integer currentBillBelong) {
// 1. 获取所有团队ID
Set<Long> teamIdSet = bdTeamList.stream()
.map(BusinessDevelopmentTeam::getTeamId)
.collect(Collectors.toSet());
// 2. 查询账单周期
Map<Long, TeamBillCycle> billCycleMap = teamBillCycleService.mapByTeamIds2(
teamIdSet, currentBillBelong, TeamBillCycleStatus.UNPAID);
// 3. 查询成员目标
Map<Long, List<TeamMemberTarget>> memberTargetMap =
teamMemberTargetService.mapMemberBillTarget(teamIdSet, currentBillBelong);
// 4. 查询区域政策
Map<String, TeamPolicyManager> policyManagerMap = teamPolicyManagerService.mapRegionRelease(
billCycleMap.values().stream()
.map(TeamBillCycle::getRegion)
.collect(Collectors.toSet()));
// 5. 计算每个团队的收入并汇总
BigDecimal totalIncome = BigDecimal.ZERO;
for (BusinessDevelopmentTeam bdTeam : bdTeamList) {
Long teamId = bdTeam.getTeamId();
BigDecimal teamIncome = getTeamTotalSalary(billCycleMap, memberTargetMap, policyManagerMap, teamId);
totalIncome = totalIncome.add(teamIncome);
}
return totalIncome;
}
/**
* 计算单个团队的总收入
*/
private BigDecimal getTeamTotalSalary(
Map<Long, TeamBillCycle> billCycleMap,
Map<Long, List<TeamMemberTarget>> teamMemberTargetMap,
Map<String, TeamPolicyManager> policyManagerMap,
Long teamId) {
TeamBillCycle billCycle = billCycleMap.get(teamId);
if (billCycle == null) {
return BigDecimal.ZERO;
}
List<TeamMemberTarget> targetList = teamMemberTargetMap.get(teamId);
List<TeamBillMemberTarget> memberTargets = TeamBillCycleUtils.calculatorPolicyTarget(
targetList, policyManagerMap.get(billCycle.getRegion()));
return ownTotalSalary(memberTargets);
}
/**
* 汇总成员工资
*/
private BigDecimal ownTotalSalary(List<TeamBillMemberTarget> teamBillMemberTargets) {
return teamBillMemberTargets.stream()
.map(TeamBillMemberTarget::getTotalSalary)
.reduce(BigDecimal.ZERO, BigDecimal::add)
.setScale(2, RoundingMode.DOWN);
}
}

View File

@ -2,8 +2,10 @@ package com.red.circle.other.app.service;
import com.red.circle.other.app.command.bd.query.BdTeamMemberDetailQryExe;
import com.red.circle.other.app.command.bd.query.BdTeamQryExe;
import com.red.circle.other.app.command.bd.query.BdTeamSummaryQryExe;
import com.red.circle.other.app.dto.clientobject.BdTeamMemberDetailCO;
import com.red.circle.other.app.dto.clientobject.BdTeamOverviewCO;
import com.red.circle.other.app.dto.clientobject.BdTeamSummaryCO;
import com.red.circle.other.app.dto.cmd.BdTeamMemberDetailQueryCmd;
import com.red.circle.other.app.dto.cmd.BdTeamQueryCmd;
import lombok.RequiredArgsConstructor;
@ -20,6 +22,7 @@ public class BdTeamServiceImpl implements BdTeamService {
private final BdTeamQryExe bdTeamQryExe;
private final BdTeamMemberDetailQryExe bdTeamMemberDetailQryExe;
private final BdTeamSummaryQryExe bdTeamSummaryQryExe;
@Override
public BdTeamOverviewCO queryTeamOverview(BdTeamQueryCmd cmd) {
@ -30,4 +33,9 @@ public class BdTeamServiceImpl implements BdTeamService {
public BdTeamMemberDetailCO queryMemberDetail(BdTeamMemberDetailQueryCmd cmd) {
return bdTeamMemberDetailQryExe.execute(cmd);
}
@Override
public BdTeamSummaryCO queryTeamSummary(Long userId) {
return bdTeamSummaryQryExe.execute(userId);
}
}

View File

@ -0,0 +1,48 @@
package com.red.circle.other.app.dto.clientobject;
import lombok.Data;
import java.math.BigDecimal;
/**
* BD团队总览
*/
@Data
public class BdTeamSummaryCO {
/**
* 本期团队收入My BD Teams totalIncome
*/
private BigDecimal teamEarningsThisPeriod;
/**
* My BD Leader Teams 信息
*/
private TeamSummaryItem bdLeaderTeams;
/**
* My BD Teams 信息
*/
private TeamSummaryItem bdTeams;
/**
* My Agency Teams 信息
*/
private TeamSummaryItem agencyTeams;
/**
* 团队汇总项
*/
@Data
public static class TeamSummaryItem {
/**
* 团队数量
*/
private Integer count;
/**
* 总收入
*/
private BigDecimal totalIncome;
}
}

View File

@ -2,6 +2,7 @@ package com.red.circle.other.app.service;
import com.red.circle.other.app.dto.clientobject.BdTeamMemberDetailCO;
import com.red.circle.other.app.dto.clientobject.BdTeamOverviewCO;
import com.red.circle.other.app.dto.clientobject.BdTeamSummaryCO;
import com.red.circle.other.app.dto.cmd.BdTeamMemberDetailQueryCmd;
import com.red.circle.other.app.dto.cmd.BdTeamQueryCmd;
@ -33,4 +34,15 @@ public interface BdTeamService {
* @return 成员详情
*/
BdTeamMemberDetailCO queryMemberDetail(BdTeamMemberDetailQueryCmd cmd);
/**
* 查询BD团队总览
* <p>
* 返回当前用户在BD_LEADERBDAGENCY三个角色下的汇总数据
* </p>
*
* @param userId 用户ID
* @return 团队总览
*/
BdTeamSummaryCO queryTeamSummary(Long userId);
}