All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m14s
6.7 KiB
6.7 KiB
差价佣金计算和分配逻辑搜索结果
一、差价佣金的计算方式
1.1 计算公式
差价佣金 = 下级成本价 - 自己成本价
1.2 计算流程
文件位置: internal/service/commission_calculation/service.go:121-225
func (s *Service) CalculateCostDiffCommission(ctx context.Context, order *model.Order) ([]*model.CommissionRecord, error)
核心逻辑:
-
销售端利润计算 (第138-153行)
- 销售利润 = 订单总金额 - 销售成本价
- 如果销售利润 > 0,为销售店铺创建一条佣金记录
-
链式向上计算 (第163-222行)
- 从销售店铺开始,逐级向上遍历代理链
- 对于每一级代理:
- 获取该代理的成本价(从 ShopPackageAllocation 表)
- 计算差价:childCostPrice - myCostPrice
- 如果差价 > 0,创建佣金记录
-
链路断裂处理 (第173-200行)
- 如果上级代理未分配该套餐,创建待审佣金记录(status=99)
- 记录备注:套餐系列未分配给该代理,需人工核查
1.3 示例
平台基础成本价: 100元
↓
分配给代理A,成本价: 120元
├─ A的利润: 120 - 100 = 20元
↓
分配给代理A1,成本价: 130元
├─ A1的利润: 130 - 120 = 10元
├─ A的差价佣金: 130 - 120 = 10元
↓
A1销售给客户,售价: 200元
├─ A1的销售利润: 200 - 130 = 70元
├─ A的差价佣金: 130 - 120 = 10元
├─ 平台收入: 120元
二、差价佣金的发放条件
2.1 触发条件
文件位置: internal/service/order/service.go:1621 和 internal/task/commission_calculation.go
差价佣金在以下情况触发:
-
订单支付成功
- 支付状态从
PaymentStatusPending(1) 变为PaymentStatusPaid(2) - 触发点:
WalletPay()方法完成后调用enqueueCommissionCalculation()
- 支付状态从
-
异步任务处理
- 任务类型:
commission:calculate - 处理器:
CommissionCalculationHandler.HandleCommissionCalculation() - 队列: Asynq 异步任务队列
- 任务类型:
2.2 发放流程
文件位置: internal/service/commission_calculation/service.go:74-119
func (s *Service) CalculateCommission(ctx context.Context, orderID uint) error
步骤:
-
检查订单佣金状态 (第81-84行)
- 如果
commission_status == 2(已计算),跳过 - 防止重复计算
- 如果
-
计算成本价差佣金 (第86-98行)
- 调用
CalculateCostDiffCommission()获取佣金记录列表 - 逐条创建佣金记录到
tb_commission_record表 - 调用
creditCommissionInTx()入账到代理钱包
- 调用
-
触发一次性佣金 (第100-111行)
- 仅非代购订单触发
- 根据订单类型(单卡/设备)调用对应方法
-
更新订单佣金状态 (第113-115行)
- 将
commission_status更新为2(已计算)
- 将
2.3 佣金入账
文件位置: internal/service/commission_calculation/service.go:641-687
func (s *Service) creditCommissionInTx(ctx context.Context, tx *gorm.DB, record *model.CommissionRecord) error
入账步骤:
- 获取店铺的分佣钱包 (wallet_type = 'commission')
- 增加钱包余额
- 更新佣金记录状态为
CommissionStatusReleased(3) - 记录入账时间
released_at - 创建钱包交易记录 (transaction_type = 'commission')
三、差价佣金与订单状态的关系
3.1 订单状态定义
文件位置: internal/model/order.go:106-110
// 佣金状态常量
const (
CommissionStatusPending = 1 // 待计算
CommissionStatusCalculated = 2 // 已计算
)
3.2 订单支付状态
文件位置: internal/model/order.go:98-104
// 支付状态常量
const (
PaymentStatusPending = 1 // 待支付
PaymentStatusPaid = 2 // 已支付
PaymentStatusCancelled = 3 // 已取消
PaymentStatusRefunded = 4 // 已退款
)
3.3 状态转换关系
订单创建
↓
commission_status = 1 (待计算)
payment_status = 1 (待支付)
↓
用户支付
↓
payment_status = 2 (已支付)
↓
触发佣金计算任务
↓
异步处理:CalculateCommission()
↓
commission_status = 2 (已计算)
佣金入账到代理钱包
3.4 佣金记录状态
文件位置: internal/model/commission.go:40-46 和 pkg/constants/iot.go:180-187
// 佣金记录状态(tb_commission_record.status)
const (
CommissionStatusReleased = 3 // 已发放
CommissionStatusInvalid = 4 // 已失效
CommissionStatusPendingReview = 99 // 待人工修正(链路断裂)
)
// 代理钱包交易状态(tb_agent_wallet_transaction.status)
const (
CommissionStatusFrozen = 1 // 已冻结
CommissionStatusUnfreezing = 2 // 解冻中
CommissionStatusReleased = 3 // 已发放
CommissionStatusInvalid = 4 // 已失效
CommissionStatusPendingReview = 99 // 待人工修正
)
3.5 关键字段
订单表 (tb_order):
commission_status: 佣金计算状态commission_config_version: 佣金配置版本快照seller_shop_id: 销售店铺ID(用于成本价差佣金)seller_cost_price: 销售成本价(用于计算利润)series_id: 系列ID(用于查询分配配置)
佣金记录表 (tb_commission_record):
shop_id: 佣金归属店铺order_id: 关联订单commission_source: 佣金来源 (cost_diff/one_time)amount: 佣金金额status: 佣金状态released_at: 入账时间balance_after: 入账后钱包余额
四、关键代码位置总结
| 功能 | 文件位置 | 方法 |
|---|---|---|
| 差价佣金计算 | internal/service/commission_calculation/service.go |
CalculateCostDiffCommission() |
| 佣金入账 | internal/service/commission_calculation/service.go |
creditCommissionInTx() |
| 佣金计算触发 | internal/service/order/service.go |
enqueueCommissionCalculation() |
| 异步任务处理 | internal/task/commission_calculation.go |
HandleCommissionCalculation() |
| 订单支付完成 | internal/service/order/service.go |
WalletPay() |
| 模型定义 | internal/model/commission.go |
CommissionRecord |
| 模型定义 | internal/model/order.go |
Order |
| 业务文档 | docs/commission-package-model.md |
完整的佣金业务模型说明 |
五、相关常量
文件位置: pkg/constants/constants.go 和 pkg/constants/iot.go
// 任务类型
TaskTypeCommission = "commission:calculate"
// 佣金来源
CommissionSourceCostDiff = "cost_diff" // 成本价差
CommissionSourceOneTime = "one_time" // 一次性佣金
// 佣金状态
CommissionStatusReleased = 3 // 已发放
CommissionStatusInvalid = 4 // 已失效
CommissionStatusPendingReview = 99 // 待人工修正