v2.0
This commit is contained in:
@@ -0,0 +1,200 @@
|
||||
package agent
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"qnc-server/app/user/cmd/api/internal/svc"
|
||||
"qnc-server/app/user/cmd/api/internal/types"
|
||||
"qnc-server/common/ctxdata"
|
||||
"qnc-server/common/xerr"
|
||||
"qnc-server/pkg/lzkit/crypto"
|
||||
|
||||
"github.com/Masterminds/squirrel"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type GetAgentSubordinateContributionDetailLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewGetAgentSubordinateContributionDetailLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetAgentSubordinateContributionDetailLogic {
|
||||
return &GetAgentSubordinateContributionDetailLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *GetAgentSubordinateContributionDetailLogic) GetAgentSubordinateContributionDetail(req *types.GetAgentSubordinateContributionDetailReq) (resp *types.GetAgentSubordinateContributionDetailResp, err error) {
|
||||
userID, err := ctxdata.GetUidFromCtx(l.ctx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取代理下级贡献详情, 获取用户ID%v", err)
|
||||
}
|
||||
|
||||
// 获取当前代理信息
|
||||
agentModel, err := l.svcCtx.AgentModel.FindOneByUserId(l.ctx, userID)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取代理下级贡献详情, 获取代理信息%v", err)
|
||||
}
|
||||
|
||||
// 获取下级代理信息
|
||||
subordinateAgent, err := l.svcCtx.AgentModel.FindOne(l.ctx, req.SubordinateID)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取代理下级贡献详情, 获取下级代理信息%v", err)
|
||||
}
|
||||
|
||||
// 验证是否是当前代理的下级
|
||||
closureBuilder := l.svcCtx.AgentClosureModel.SelectBuilder().Where(squirrel.Eq{
|
||||
"ancestor_id": agentModel.Id,
|
||||
"descendant_id": req.SubordinateID,
|
||||
})
|
||||
closureList, err := l.svcCtx.AgentClosureModel.FindAll(l.ctx, closureBuilder, "create_time DESC")
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取代理下级贡献详情, 验证代理关系%v", err)
|
||||
}
|
||||
if len(closureList) == 0 {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取代理下级贡献详情, 非法的代理关系")
|
||||
}
|
||||
closure := closureList[0]
|
||||
|
||||
// 获取佣金扣除记录
|
||||
deductionBuilder := l.svcCtx.AgentCommissionDeductionModel.SelectBuilder().Where(squirrel.Eq{
|
||||
"agent_id": agentModel.Id,
|
||||
"deducted_agent_id": req.SubordinateID,
|
||||
})
|
||||
deductionList, err := l.svcCtx.AgentCommissionDeductionModel.FindAll(l.ctx, deductionBuilder, "create_time DESC")
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取代理下级贡献详情, 获取佣金扣除记录%v", err)
|
||||
}
|
||||
|
||||
// 获取奖励记录
|
||||
rewardsBuilder := l.svcCtx.AgentRewardsModel.SelectBuilder().Where(squirrel.Eq{
|
||||
"agent_id": agentModel.Id,
|
||||
"relation_agent_id": req.SubordinateID,
|
||||
})
|
||||
rewards, err := l.svcCtx.AgentRewardsModel.FindAll(l.ctx, rewardsBuilder, "create_time DESC")
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取代理下级贡献详情, 获取奖励记录%v", err)
|
||||
}
|
||||
|
||||
// 计算总贡献
|
||||
var totalContribution float64
|
||||
for _, v := range deductionList {
|
||||
totalContribution += v.Amount
|
||||
}
|
||||
// 加上奖励金额
|
||||
for _, v := range rewards {
|
||||
totalContribution += v.Amount
|
||||
}
|
||||
|
||||
// 获取佣金记录
|
||||
commissionBuilder := l.svcCtx.AgentCommissionModel.SelectBuilder().Where(squirrel.Eq{
|
||||
"agent_id": req.SubordinateID,
|
||||
})
|
||||
commissionList, err := l.svcCtx.AgentCommissionModel.FindAll(l.ctx, commissionBuilder, "create_time DESC")
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取代理下级贡献详情, 获取佣金记录%v", err)
|
||||
}
|
||||
|
||||
// 计算总收益和总单量
|
||||
var totalEarnings float64
|
||||
for _, v := range commissionList {
|
||||
totalEarnings += v.Amount
|
||||
}
|
||||
|
||||
// 初始化统计数据
|
||||
stats := types.AgentSubordinateContributionStats{
|
||||
CostCount: 0,
|
||||
CostAmount: 0,
|
||||
PricingCount: 0,
|
||||
PricingAmount: 0,
|
||||
DescendantPromotionCount: 0,
|
||||
DescendantPromotionAmount: 0,
|
||||
DescendantUpgradeVipCount: 0,
|
||||
DescendantUpgradeVipAmount: 0,
|
||||
DescendantUpgradeSvipCount: 0,
|
||||
DescendantUpgradeSvipAmount: 0,
|
||||
DescendantStayActiveCount: 0,
|
||||
DescendantStayActiveAmount: 0,
|
||||
DescendantNewActiveCount: 0,
|
||||
DescendantNewActiveAmount: 0,
|
||||
DescendantWithdrawCount: 0,
|
||||
DescendantWithdrawAmount: 0,
|
||||
}
|
||||
|
||||
// 统计佣金扣除记录
|
||||
for _, v := range deductionList {
|
||||
switch v.Type {
|
||||
case "cost":
|
||||
stats.CostCount++
|
||||
stats.CostAmount += v.Amount
|
||||
case "pricing":
|
||||
stats.PricingCount++
|
||||
stats.PricingAmount += v.Amount
|
||||
}
|
||||
}
|
||||
|
||||
// 统计奖励记录
|
||||
for _, v := range rewards {
|
||||
switch v.Type {
|
||||
case "descendant_promotion":
|
||||
stats.DescendantPromotionCount++
|
||||
stats.DescendantPromotionAmount += v.Amount
|
||||
case "descendant_upgrade_vip":
|
||||
stats.DescendantUpgradeVipCount++
|
||||
stats.DescendantUpgradeVipAmount += v.Amount
|
||||
case "descendant_upgrade_svip":
|
||||
stats.DescendantUpgradeSvipCount++
|
||||
stats.DescendantUpgradeSvipAmount += v.Amount
|
||||
case "descendant_stay_active":
|
||||
stats.DescendantStayActiveCount++
|
||||
stats.DescendantStayActiveAmount += v.Amount
|
||||
case "descendant_new_active":
|
||||
stats.DescendantNewActiveCount++
|
||||
stats.DescendantNewActiveAmount += v.Amount
|
||||
case "descendant_withdraw":
|
||||
stats.DescendantWithdrawCount++
|
||||
stats.DescendantWithdrawAmount += v.Amount
|
||||
}
|
||||
}
|
||||
|
||||
// 解密手机号
|
||||
secretKey := l.svcCtx.Config.Encrypt.SecretKey
|
||||
mobile, err := crypto.DecryptMobile(subordinateAgent.Mobile, secretKey)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取代理下级贡献详情, 解密手机号失败: %v", err)
|
||||
}
|
||||
|
||||
// 获取合并后的分页列表
|
||||
unionDetails, total, err := l.svcCtx.AgentClosureModel.FindUnionPageListByPageWithTotal(l.ctx, agentModel.Id, req.SubordinateID, req.Page, req.PageSize)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取代理下级贡献详情, 获取分页列表%v", err)
|
||||
}
|
||||
|
||||
// 转换为响应类型
|
||||
detailList := make([]types.AgentSubordinateContributionDetail, 0, len(unionDetails))
|
||||
for _, v := range unionDetails {
|
||||
detail := types.AgentSubordinateContributionDetail{
|
||||
ID: v.Id,
|
||||
CreateTime: v.CreateTime,
|
||||
Amount: v.Amount,
|
||||
Type: v.Type,
|
||||
}
|
||||
detailList = append(detailList, detail)
|
||||
}
|
||||
|
||||
return &types.GetAgentSubordinateContributionDetailResp{
|
||||
Mobile: maskPhone(mobile),
|
||||
Total: total,
|
||||
CreateTime: closure.CreateTime.Format("2006-01-02 15:04:05"),
|
||||
TotalEarnings: totalEarnings,
|
||||
TotalContribution: totalContribution,
|
||||
TotalOrders: int64(len(commissionList)),
|
||||
LevelName: subordinateAgent.LevelName,
|
||||
List: detailList,
|
||||
Stats: stats,
|
||||
}, nil
|
||||
}
|
||||
@@ -0,0 +1,173 @@
|
||||
package agent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"qnc-server/app/user/cmd/api/internal/svc"
|
||||
"qnc-server/app/user/cmd/api/internal/types"
|
||||
"qnc-server/app/user/model"
|
||||
"qnc-server/common/ctxdata"
|
||||
"qnc-server/common/xerr"
|
||||
"qnc-server/pkg/lzkit/crypto"
|
||||
|
||||
"github.com/Masterminds/squirrel"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
"github.com/zeromicro/go-zero/core/mr"
|
||||
)
|
||||
|
||||
type GetAgentSubordinateListLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewGetAgentSubordinateListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetAgentSubordinateListLogic {
|
||||
return &GetAgentSubordinateListLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *GetAgentSubordinateListLogic) GetAgentSubordinateList(req *types.GetAgentSubordinateListReq) (resp *types.GetAgentSubordinateListResp, err error) {
|
||||
userID, err := ctxdata.GetUidFromCtx(l.ctx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取代理下级列表, 获取用户ID%v", err)
|
||||
}
|
||||
agentModel, err := l.svcCtx.AgentModel.FindOneByUserId(l.ctx, userID)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取代理下级列表, 获取代理信息%v", err)
|
||||
}
|
||||
agentID := agentModel.Id
|
||||
|
||||
builder := l.svcCtx.AgentClosureModel.SelectBuilder().Where(squirrel.Eq{
|
||||
"ancestor_id": agentID,
|
||||
})
|
||||
agentClosureModelList, total, err := l.svcCtx.AgentClosureModel.FindPageListByPageWithTotal(l.ctx, builder, req.Page, req.PageSize, "create_time DESC")
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取代理下级列表, 获取代理关系%v", err)
|
||||
}
|
||||
|
||||
// 构建ID到CreateTime的映射
|
||||
createTimeMap := make(map[int64]time.Time)
|
||||
descendantIDs := make([]int64, 0)
|
||||
for _, v := range agentClosureModelList {
|
||||
descendantIDs = append(descendantIDs, v.DescendantId)
|
||||
createTimeMap[v.DescendantId] = v.CreateTime
|
||||
}
|
||||
|
||||
// 并发查询代理信息
|
||||
agentMap := make(map[int64]*model.Agent)
|
||||
var descendantList []types.AgentSubordinateList
|
||||
err = mr.Finish(func() error {
|
||||
return mr.MapReduceVoid(func(source chan<- interface{}) {
|
||||
for _, id := range descendantIDs {
|
||||
source <- id
|
||||
}
|
||||
}, func(item interface{}, writer mr.Writer[interface{}], cancel func(error)) {
|
||||
id := item.(int64)
|
||||
agent, err := l.svcCtx.AgentModel.FindOne(l.ctx, id)
|
||||
if err != nil {
|
||||
cancel(err)
|
||||
return
|
||||
}
|
||||
writer.Write(agent)
|
||||
}, func(pipe <-chan interface{}, cancel func(error)) {
|
||||
for item := range pipe {
|
||||
agent := item.(*model.Agent)
|
||||
agentMap[agent.Id] = agent
|
||||
}
|
||||
})
|
||||
}, func() error {
|
||||
// 并发查询佣金扣除信息
|
||||
deductionBuilder := l.svcCtx.AgentCommissionDeductionModel.SelectBuilder().
|
||||
Where(squirrel.Eq{"agent_id": agentID}).
|
||||
Where(squirrel.Eq{"deducted_agent_id": descendantIDs})
|
||||
deductionList, err := l.svcCtx.AgentCommissionDeductionModel.FindAll(l.ctx, deductionBuilder, "")
|
||||
if err != nil {
|
||||
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取代理下级列表, 获取代理佣金扣除信息%v", err)
|
||||
}
|
||||
deductionMap := make(map[int64]float64)
|
||||
for _, v := range deductionList {
|
||||
deductionMap[v.DeductedAgentId] += v.Amount
|
||||
}
|
||||
|
||||
// 并发查询奖励信息
|
||||
rewardsBuilder := l.svcCtx.AgentRewardsModel.SelectBuilder().
|
||||
Where(squirrel.Eq{"agent_id": agentID}).
|
||||
Where(squirrel.Eq{"relation_agent_id": descendantIDs})
|
||||
rewardsList, err := l.svcCtx.AgentRewardsModel.FindAll(l.ctx, rewardsBuilder, "")
|
||||
if err != nil {
|
||||
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取代理下级列表, 获取代理奖励信息%v", err)
|
||||
}
|
||||
rewardsMap := make(map[int64]float64)
|
||||
for _, v := range rewardsList {
|
||||
if v.RelationAgentId.Valid {
|
||||
rewardsMap[v.RelationAgentId.Int64] += v.Amount
|
||||
}
|
||||
}
|
||||
|
||||
// 并发查询佣金信息
|
||||
commissionBuilder := l.svcCtx.AgentCommissionModel.SelectBuilder().
|
||||
Where(squirrel.Eq{"agent_id": descendantIDs})
|
||||
commissionList, err := l.svcCtx.AgentCommissionModel.FindAll(l.ctx, commissionBuilder, "")
|
||||
if err != nil {
|
||||
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取代理下级列表, 获取代理佣金信息%v", err)
|
||||
}
|
||||
commissionMap := make(map[int64]float64)
|
||||
orderCountMap := make(map[int64]int64)
|
||||
for _, v := range commissionList {
|
||||
commissionMap[v.AgentId] += v.Amount
|
||||
orderCountMap[v.AgentId]++
|
||||
}
|
||||
|
||||
// 构建返回结果
|
||||
secretKey := l.svcCtx.Config.Encrypt.SecretKey
|
||||
descendantList = make([]types.AgentSubordinateList, 0, len(descendantIDs))
|
||||
for _, id := range descendantIDs {
|
||||
agent, exists := agentMap[id]
|
||||
if !exists {
|
||||
continue
|
||||
}
|
||||
|
||||
mobile, err := crypto.DecryptMobile(agent.Mobile, secretKey)
|
||||
if err != nil {
|
||||
return errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取代理信息, 解密手机号失败: %v", err)
|
||||
}
|
||||
|
||||
subordinate := types.AgentSubordinateList{
|
||||
ID: id,
|
||||
Mobile: maskPhone(mobile),
|
||||
LevelName: agent.LevelName,
|
||||
CreateTime: createTimeMap[id].Format("2006-01-02 15:04:05"),
|
||||
TotalContribution: deductionMap[id] + rewardsMap[id],
|
||||
TotalEarnings: commissionMap[id],
|
||||
TotalOrders: orderCountMap[id],
|
||||
}
|
||||
descendantList = append(descendantList, subordinate)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &types.GetAgentSubordinateListResp{
|
||||
Total: total,
|
||||
List: descendantList,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// 手机号脱敏
|
||||
func maskPhone(phone string) string {
|
||||
length := len(phone)
|
||||
if length < 8 {
|
||||
return phone // 如果长度太短,可能不是手机号,不处理
|
||||
}
|
||||
// 保留前3位和后4位
|
||||
return phone[:3] + strings.Repeat("*", length-7) + phone[length-4:]
|
||||
}
|
||||
Reference in New Issue
Block a user