377 lines
15 KiB
Go
377 lines
15 KiB
Go
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
|
||
//}
|