qnc-server-tob/app/main/api/internal/service/agentService.go
2025-06-09 22:09:15 +08:00

377 lines
15 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package service
import (
"context"
"qnc-server/app/main/api/internal/config"
"qnc-server/app/main/api/internal/types"
"qnc-server/app/main/model"
"qnc-server/pkg/lzkit/lzUtils"
"github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/logx"
"github.com/zeromicro/go-zero/core/stores/sqlx"
)
type AgentService struct {
config config.Config
AgentModel model.AgentModel
AgentAuditModel model.AgentAuditModel
AgentClosureModel model.AgentClosureModel
AgentCommissionModel model.AgentCommissionModel
AgentCommissionDeductionModel model.AgentCommissionDeductionModel
AgentWalletModel model.AgentWalletModel
AgentLinkModel model.AgentLinkModel
AgentOrderModel model.AgentOrderModel
AgentRewardsModel model.AgentRewardsModel
AgentMembershipConfigModel model.AgentMembershipConfigModel
AgentMembershipRechargeOrderModel model.AgentMembershipRechargeOrderModel
AgentMembershipUserConfigModel model.AgentMembershipUserConfigModel
AgentProductConfigModel model.AgentProductConfigModel
AgentPlatformDeductionModel model.AgentPlatformDeductionModel
AgentActiveStatModel model.AgentActiveStatModel
AgentWithdrawalModel model.AgentWithdrawalModel
AsynqService *AsynqService
}
func NewAgentService(c config.Config, agentModel model.AgentModel, agentAuditModel model.AgentAuditModel,
agentClosureModel model.AgentClosureModel, agentCommissionModel model.AgentCommissionModel,
agentCommissionDeductionModel model.AgentCommissionDeductionModel, agentWalletModel model.AgentWalletModel, agentLinkModel model.AgentLinkModel, agentOrderModel model.AgentOrderModel, agentRewardsModel model.AgentRewardsModel,
agentMembershipConfigModel model.AgentMembershipConfigModel,
agentMembershipRechargeOrderModel model.AgentMembershipRechargeOrderModel,
agentMembershipUserConfigModel model.AgentMembershipUserConfigModel,
agentProductConfigModel model.AgentProductConfigModel, agentPlatformDeductionModel model.AgentPlatformDeductionModel,
agentActiveStatModel model.AgentActiveStatModel, asynqService *AsynqService, agentWithdrawalModel model.AgentWithdrawalModel) *AgentService {
return &AgentService{
config: c,
AgentModel: agentModel,
AgentAuditModel: agentAuditModel,
AgentClosureModel: agentClosureModel,
AgentCommissionModel: agentCommissionModel,
AgentCommissionDeductionModel: agentCommissionDeductionModel,
AgentWalletModel: agentWalletModel,
AgentLinkModel: agentLinkModel,
AgentOrderModel: agentOrderModel,
AgentRewardsModel: agentRewardsModel,
AgentMembershipConfigModel: agentMembershipConfigModel,
AgentMembershipRechargeOrderModel: agentMembershipRechargeOrderModel,
AgentMembershipUserConfigModel: agentMembershipUserConfigModel,
AgentProductConfigModel: agentProductConfigModel,
AgentPlatformDeductionModel: agentPlatformDeductionModel,
AgentActiveStatModel: agentActiveStatModel,
AgentWithdrawalModel: agentWithdrawalModel,
AsynqService: asynqService,
}
}
// AgentProcess 推广单成功
func (l *AgentService) AgentProcess(ctx context.Context, order *model.Order) error {
// 获取是否该订单是代理推广订单
agentOrderModel, err := l.AgentOrderModel.FindOneByOrderId(ctx, order.Id)
if err != nil && !errors.Is(err, model.ErrNotFound) {
return err
}
if errors.Is(err, model.ErrNotFound) || agentOrderModel == nil {
return nil
}
// 事务
transErr := l.AgentWalletModel.Trans(ctx, func(transCtx context.Context, session sqlx.Session) error {
agentID := agentOrderModel.AgentId
agentProductConfigModel, findAgentProductConfigModelErr := l.AgentProductConfigModel.FindOneByProductId(transCtx, order.ProductId)
if findAgentProductConfigModelErr != nil {
return findAgentProductConfigModelErr
}
// 平台底价成本
PlatformCostAmount, platformCostErr := l.PlatformCost(transCtx, agentID, agentProductConfigModel, session)
if platformCostErr != nil {
return platformCostErr
}
// 平台提价成本
PlatformPricingAmount, platformPricingErr := l.PlatformPricing(transCtx, agentID, order.Amount, agentProductConfigModel, session)
if platformPricingErr != nil {
return platformPricingErr
}
// 查找上级
AgentClosureModel, findAgentClosureModelErr := l.AgentClosureModel.FindOneByDescendantIdDepth(transCtx, agentID, 1)
if findAgentClosureModelErr != nil && !errors.Is(findAgentClosureModelErr, model.ErrNotFound) {
return findAgentClosureModelErr
}
var descendantDeductedAmount = 0.00
if AgentClosureModel != nil {
AncestorId := AgentClosureModel.AncestorId
AncestorModel, findAgentModelErr := l.AgentModel.FindOne(transCtx, AncestorId)
if findAgentModelErr != nil != errors.Is(findAgentModelErr, model.ErrNotFound) {
return findAgentModelErr
}
if AgentClosureModel != nil {
AgentMembershipConfigModel, findAgentMembersipConfigModelErr := l.AgentMembershipConfigModel.FindOneByLevelName(ctx, AncestorModel.LevelName)
if findAgentMembersipConfigModelErr != nil {
return findAgentMembersipConfigModelErr
}
// 定价
commissionCost, commissionCostErr := l.CommissionCost(transCtx, agentID, AncestorId, AgentMembershipConfigModel, order.ProductId, session)
if commissionCostErr != nil {
return commissionCostErr
}
// 提价
commissionPricing, commissionPricingErr := l.CommissionPricing(transCtx, agentID, AncestorId, AgentMembershipConfigModel, order.ProductId, order.Amount, session)
if commissionPricingErr != nil {
return commissionPricingErr
}
// 上级克扣的成本
descendantDeductedAmount = commissionCost + commissionPricing
// 佣金
ancestorCommissionReward, ancestorCommissionErr := l.AncestorCommission(transCtx, agentID, AncestorId, session)
if ancestorCommissionErr != nil {
return ancestorCommissionErr
}
// 给上级成本以及佣金
ancestorCommissionAmount := commissionCost + commissionPricing + ancestorCommissionReward
ancestorWallet, findAgentWalletModelErr := l.AgentWalletModel.FindOneByAgentId(transCtx, AncestorId)
if findAgentWalletModelErr != nil {
return findAgentWalletModelErr
}
ancestorWallet.FrozenBalance += ancestorCommissionAmount
ancestorWallet.TotalEarnings += ancestorCommissionAmount
updateErr := l.AgentWalletModel.UpdateWithVersion(transCtx, session, ancestorWallet)
if updateErr != nil {
return updateErr
}
// 发送解冻任务
err := l.AsynqService.SendUnfreezeAgentBalanceTask(AncestorId, order.Id, ancestorCommissionAmount)
if err != nil {
logx.Errorf("创建解冻任务失败: %v, 代理ID: %d, 订单号: %d", err, AncestorId, order.Id)
return err
}
}
}
// 推广人扣除金额 = 平台成本价 + 平台提价成本 + 上级佣金
deductedAmount := PlatformCostAmount + PlatformPricingAmount + descendantDeductedAmount
agentCommissionErr := l.AgentCommission(transCtx, agentID, order, deductedAmount, session)
if agentCommissionErr != nil {
return agentCommissionErr
}
return nil
})
if transErr != nil {
return transErr
}
return nil
}
// AgentCommission 直推报告推广人佣金
func (l *AgentService) AgentCommission(ctx context.Context, agentID int64, order *model.Order, deductedAmount float64, session sqlx.Session) error {
agentWalletModel, findAgentWalletModelErr := l.AgentWalletModel.FindOneByAgentId(ctx, agentID)
if findAgentWalletModelErr != nil {
return findAgentWalletModelErr
}
// 推广人最终获得代理佣金
finalCommission := order.Amount - deductedAmount
// 更新冻结余额而不是直接更新余额
agentWalletModel.FrozenBalance += finalCommission
agentWalletModel.TotalEarnings += finalCommission
agentCommission := model.AgentCommission{
AgentId: agentID,
OrderId: order.Id,
Amount: finalCommission,
ProductId: order.ProductId,
}
_, insertAgentCommissionErr := l.AgentCommissionModel.Insert(ctx, session, &agentCommission)
if insertAgentCommissionErr != nil {
return insertAgentCommissionErr
}
updateAgentWalletErr := l.AgentWalletModel.UpdateWithVersion(ctx, session, agentWalletModel)
if updateAgentWalletErr != nil {
return updateAgentWalletErr
}
// 创建24小时后解冻任务
unfreezePayload := types.UnfreezeAgentBalancePayload{
AgentID: agentID,
OrderID: order.Id,
Amount: finalCommission,
}
// 发送解冻任务
err := l.AsynqService.SendUnfreezeAgentBalanceTask(unfreezePayload.AgentID, unfreezePayload.OrderID, unfreezePayload.Amount)
if err != nil {
logx.Errorf("创建解冻任务失败: %v, 代理ID: %d, 订单号: %d", err, agentID, order.Id)
return err
}
return nil
}
// AncestorCommission 直推报告上级佣金(奖励型)
func (l *AgentService) AncestorCommission(ctx context.Context, descendantId int64, ancestorId int64, session sqlx.Session) (float64, error) {
agentModel, err := l.AgentModel.FindOne(ctx, ancestorId)
if err != nil {
return 0, err
}
agentMembershipConfigModel, err := l.AgentMembershipConfigModel.FindOneByLevelName(ctx, agentModel.LevelName)
if err != nil {
return 0, err
}
if agentMembershipConfigModel.ReportCommission.Valid {
reportCommissionAmount := agentMembershipConfigModel.ReportCommission.Float64
agentRewards := model.AgentRewards{
AgentId: ancestorId,
Amount: reportCommissionAmount,
RelationAgentId: lzUtils.Int64ToNullInt64(descendantId),
Type: model.AgentRewardsTypeDescendantPromotion,
}
_, agentRewardsModelInsetErr := l.AgentRewardsModel.Insert(ctx, session, &agentRewards)
if agentRewardsModelInsetErr != nil {
return 0, agentRewardsModelInsetErr
}
return reportCommissionAmount, nil
}
return 0, nil
}
// PlatformCost 平台底价成本
func (l *AgentService) PlatformCost(ctx context.Context, agentID int64, agentProductConfigModel *model.AgentProductConfig, session sqlx.Session) (float64, error) {
costAgentPlatformDeductionModel := model.AgentPlatformDeduction{
AgentId: agentID,
Amount: agentProductConfigModel.CostPrice,
Type: model.AgentDeductionTypeCost,
}
_, err := l.AgentPlatformDeductionModel.Insert(ctx, session, &costAgentPlatformDeductionModel)
if err != nil {
return 0, err
}
return agentProductConfigModel.CostPrice, nil
}
// PlatformPricing 平台提价成本
func (l *AgentService) PlatformPricing(ctx context.Context, agentID int64, pricing float64, agentProductConfigModel *model.AgentProductConfig, session sqlx.Session) (float64, error) {
// 2. 计算平台提价成本
if pricing > agentProductConfigModel.PricingStandard {
// 超出部分
overpricing := pricing - agentProductConfigModel.PricingStandard
// 收取成本
overpricingCost := overpricing * agentProductConfigModel.OverpricingRatio
pricingAgentPlatformDeductionModel := model.AgentPlatformDeduction{
AgentId: agentID,
Amount: overpricingCost,
Type: model.AgentDeductionTypePricing,
}
_, err := l.AgentPlatformDeductionModel.Insert(ctx, session, &pricingAgentPlatformDeductionModel)
if err != nil {
return 0, err
}
return overpricingCost, nil
}
return 0, nil
}
// CommissionCost 上级底价成本
func (l *AgentService) CommissionCost(ctx context.Context, descendantId int64, AncestorId int64, agentMembershipConfigModel *model.AgentMembershipConfig, productID int64, session sqlx.Session) (float64, error) {
if agentMembershipConfigModel.PriceIncreaseAmount.Valid {
// 拥有则查看该上级设定的成本
agentMembershipUserConfigModel, findAgentMembershipUserConfigModelErr := l.AgentMembershipUserConfigModel.FindOneByAgentIdProductId(ctx, AncestorId, productID)
if findAgentMembershipUserConfigModelErr != nil && !errors.Is(findAgentMembershipUserConfigModelErr, model.ErrNotFound) {
return 0, findAgentMembershipUserConfigModelErr
}
if agentMembershipUserConfigModel != nil {
deductCostAmount := agentMembershipUserConfigModel.PriceIncreaseAmount
agentCommissionDeductionModel := model.AgentCommissionDeduction{
AgentId: AncestorId,
DeductedAgentId: descendantId,
Amount: deductCostAmount,
Type: model.AgentDeductionTypeCost,
ProductId: productID,
}
_, insertAgentCommissionDeductionModelErr := l.AgentCommissionDeductionModel.Insert(ctx, session, &agentCommissionDeductionModel)
if insertAgentCommissionDeductionModelErr != nil {
return 0, insertAgentCommissionDeductionModelErr
}
return deductCostAmount, nil
} else {
return 0, nil
}
}
return 0, nil
}
// CommissionPricing 上级提价成本
func (l *AgentService) CommissionPricing(ctx context.Context, descendantId int64, AncestorId int64, agentMembershipConfigModel *model.AgentMembershipConfig, productID int64, pricing float64, session sqlx.Session) (float64, error) {
//看上级代理等级否有拥有定价标准收益功能
if agentMembershipConfigModel.PriceIncreaseMax.Valid && agentMembershipConfigModel.PriceRatio.Valid {
// 拥有则查看该上级设定的成本
agentMembershipUserConfigModel, findAgentMembershipUserConfigModelErr := l.AgentMembershipUserConfigModel.FindOneByAgentIdProductId(ctx, AncestorId, productID)
if findAgentMembershipUserConfigModelErr != nil {
if errors.Is(findAgentMembershipUserConfigModelErr, model.ErrNotFound) {
// 如果找不到配置直接返回0不计算提价成本
return 0, nil
}
return 0, findAgentMembershipUserConfigModelErr
}
// 确保配置存在且有效
if agentMembershipUserConfigModel == nil {
return 0, nil
}
// 计算是否在范围内
var pricingRange float64
if pricing > agentMembershipUserConfigModel.PriceRangeFrom {
if pricing > agentMembershipUserConfigModel.PriceRangeTo {
pricingRange = agentMembershipUserConfigModel.PriceRangeTo - agentMembershipUserConfigModel.PriceRangeFrom
} else {
pricingRange = pricing - agentMembershipUserConfigModel.PriceRangeFrom
}
}
deductCostAmount := pricingRange * agentMembershipUserConfigModel.PriceRatio
agentCommissionDeductionModel := model.AgentCommissionDeduction{
AgentId: AncestorId,
DeductedAgentId: descendantId,
Amount: deductCostAmount,
Type: model.AgentDeductionTypePricing,
ProductId: productID,
}
_, insertAgentCommissionDeductionModelErr := l.AgentCommissionDeductionModel.Insert(ctx, session, &agentCommissionDeductionModel)
if insertAgentCommissionDeductionModelErr != nil {
return 0, insertAgentCommissionDeductionModelErr
}
return deductCostAmount, nil
}
return 0, nil
}
//func (l *AgentService) UpgradeVip(ctx context.Context, agentID int64, leve string, session sqlx.Session) error {
// agentModel, err := l.AgentModel.FindOne(ctx, agentID)
// if err != nil {
// return err
// }
// if agentModel.LevelName != model.AgentLeveNameNormal {
// return fmt.Errorf("已经是会员")
// }
// return nil
//}