340 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			340 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package service
 | 
						|
 | 
						|
import (
 | 
						|
	"context"
 | 
						|
	"tydata-server/app/user/cmd/api/internal/config"
 | 
						|
	"tydata-server/app/user/model"
 | 
						|
	"tydata-server/pkg/lzkit/lzUtils"
 | 
						|
 | 
						|
	"github.com/pkg/errors"
 | 
						|
	"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
 | 
						|
}
 | 
						|
 | 
						|
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, 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,
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// 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.Balance += ancestorCommissionAmount
 | 
						|
				ancestorWallet.TotalEarnings += ancestorCommissionAmount
 | 
						|
				updateErr := l.AgentWalletModel.UpdateWithVersion(transCtx, session, ancestorWallet)
 | 
						|
				if updateErr != nil {
 | 
						|
					return updateErr
 | 
						|
				}
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		// 推广人扣除金额 = 平台成本价 + 平台提价成本 + 上级佣金
 | 
						|
		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.Balance += 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
 | 
						|
	}
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
// AncestorCommission 直推报告上级佣金(奖励型)
 | 
						|
func (l *AgentService) AncestorCommission(ctx context.Context, descendantId int64, ancestorId int64, session sqlx.Session) (float64, error) {
 | 
						|
	agentModel, err := l.AgentModel.FindOneByUserId(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 {
 | 
						|
			return 0, findAgentMembershipUserConfigModelErr
 | 
						|
		}
 | 
						|
 | 
						|
		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
 | 
						|
	}
 | 
						|
	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 {
 | 
						|
			return 0, findAgentMembershipUserConfigModelErr
 | 
						|
		}
 | 
						|
 | 
						|
		// 计算是否在范围内
 | 
						|
		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
 | 
						|
//}
 |