8.0 KiB
差价佣金快速参考指南
快速查询表
1. 关键文件位置
| 功能 | 文件 | 行号 |
|---|---|---|
| 差价佣金计算 | internal/service/commission_calculation/service.go |
121-225 |
| 佣金入账 | internal/service/commission_calculation/service.go |
641-687 |
| 佣金计算触发 | internal/service/order/service.go |
2132-2150 |
| 订单支付完成 | internal/service/order/service.go |
1431-1623 |
| 异步任务处理 | internal/task/commission_calculation.go |
40-62 |
| 订单模型 | internal/model/order.go |
1-138 |
| 佣金记录模型 | internal/model/commission.go |
1-46 |
| 业务文档 | docs/commission-package-model.md |
- |
2. 关键常量
// 任务类型
constants.TaskTypeCommission = "commission:calculate"
// 佣金来源
model.CommissionSourceCostDiff = "cost_diff" // 成本价差
model.CommissionSourceOneTime = "one_time" // 一次性佣金
// 订单佣金状态
model.CommissionStatusPending = 1 // 待计算
model.CommissionStatusCalculated = 2 // 已计算
// 订单支付状态
model.PaymentStatusPending = 1 // 待支付
model.PaymentStatusPaid = 2 // 已支付
model.PaymentStatusCancelled = 3 // 已取消
model.PaymentStatusRefunded = 4 // 已退款
// 佣金记录状态
constants.CommissionStatusReleased = 3 // 已发放
constants.CommissionStatusInvalid = 4 // 已失效
constants.CommissionStatusPendingReview = 99 // 待人工修正
3. 关键数据库表
| 表名 | 用途 | 关键字段 |
|---|---|---|
tb_order |
订单 | commission_status, payment_status, seller_shop_id, seller_cost_price |
tb_commission_record |
佣金记录 | shop_id, order_id, amount, status, released_at |
tb_agent_wallet |
代理钱包 | shop_id, balance, wallet_type |
tb_agent_wallet_transaction |
钱包交易 | agent_wallet_id, transaction_type, amount |
tb_shop_package_allocation |
套餐分配 | shop_id, package_id, cost_price |
常见问题快速查询
Q1: 差价佣金什么时候计算?
A: 订单支付成功后立即入队异步任务,由 Worker 异步计算。
代码位置: internal/service/order/service.go:1621
s.enqueueCommissionCalculation(ctx, orderID)
Q2: 差价佣金的计算公式是什么?
A: 差价佣金 = 下级成本价 - 自己成本价
代码位置: internal/service/commission_calculation/service.go:203
profit := childCostPrice - myCostPrice
Q3: 如何查询某个订单的佣金记录?
A: 查询 tb_commission_record 表,按 order_id 过滤。
SELECT * FROM tb_commission_record
WHERE order_id = ?
ORDER BY created_at DESC;
Q4: 佣金什么时候入账到代理钱包?
A: 佣金记录创建后立即入账,通过 creditCommissionInTx() 方法。
代码位置: internal/service/commission_calculation/service.go:641-687
Q5: 链路断裂是什么意思?
A: 上级代理未分配该套餐,导致佣金链中断。此时创建待审佣金记录(status=99),需平台人工处理。
代码位置: internal/service/commission_calculation/service.go:173-200
Q6: 如何追踪一个订单的佣金计算过程?
A:
- 查询订单:
SELECT * FROM tb_order WHERE id = ? - 检查
commission_status字段(1=待计算, 2=已计算) - 查询佣金记录:
SELECT * FROM tb_commission_record WHERE order_id = ? - 查询钱包交易:
SELECT * FROM tb_agent_wallet_transaction WHERE reference_id = ? AND reference_type = 'commission'
Q7: 代理钱包余额如何更新?
A: 通过 AgentWalletStore.AddBalanceWithTx() 方法,使用乐观锁防并发。
代码位置: internal/service/commission_calculation/service.go:651
s.agentWalletStore.AddBalanceWithTx(ctx, tx, wallet.ID, record.Amount)
Q8: 如何处理佣金计算失败?
A: Asynq 会自动重试,最多重试次数由队列配置决定。如果最终失败,任务会进入死信队列。
代码位置: internal/task/commission_calculation.go:40-62
Q9: 一个订单可能产生多少条佣金记录?
A: 取决于代理链的深度。最多为:销售店铺 + 所有上级店铺。
示例: 4级代理链 → 最多4条佣金记录
Q10: 如何验证佣金计算的正确性?
A:
- 验证总金额:所有佣金记录的
amount之和 = 订单总金额 - 平台成本价 - 验证链路:每条佣金记录的
shop_id应该是代理链中的一个 - 验证状态:所有佣金记录的
status应该是 3(已发放)或 99(待审)
调试技巧
1. 查看订单的佣金计算状态
SELECT
id, order_no, commission_status, payment_status,
seller_shop_id, seller_cost_price, total_amount
FROM tb_order
WHERE id = ?;
2. 查看订单的所有佣金记录
SELECT
id, shop_id, amount, commission_source, status, released_at
FROM tb_commission_record
WHERE order_id = ?
ORDER BY shop_id;
3. 查看代理的钱包余额变化
SELECT
id, shop_id, balance, wallet_type, version
FROM tb_agent_wallet
WHERE shop_id = ?;
4. 查看代理的钱包交易记录
SELECT
id, agent_wallet_id, transaction_type, amount,
balance_before, balance_after, reference_type, reference_id
FROM tb_agent_wallet_transaction
WHERE shop_id = ? AND transaction_type = 'commission'
ORDER BY created_at DESC;
5. 查看待审佣金记录(链路断裂)
SELECT
id, shop_id, order_id, amount, status, remark
FROM tb_commission_record
WHERE status = 99
ORDER BY created_at DESC;
6. 查看异步任务队列状态
# 查看待处理任务
redis-cli LRANGE asynq:queues:default 0 -1
# 查看已完成任务
redis-cli LRANGE asynq:queues:completed 0 -1
# 查看失败任务
redis-cli LRANGE asynq:queues:failed 0 -1
性能优化建议
1. 批量查询优化
避免在循环中逐条查询,使用 IN 子句批量查询:
// ❌ 不好:N+1 查询
for _, shopID := range shopIDs {
allocation, _ := store.GetByShopAndPackage(ctx, shopID, packageID)
}
// ✅ 好:批量查询
allocations, _ := store.GetByShopsAndPackage(ctx, shopIDs, packageID)
2. 事务优化
确保事务范围最小化,避免长事务:
// ✅ 好:事务只包含必要操作
err = s.db.Transaction(func(tx *gorm.DB) error {
// 创建佣金记录
// 更新钱包余额
// 创建交易记录
return nil
})
3. 索引优化
确保以下字段有索引:
tb_order.id,tb_order.commission_status,tb_order.payment_statustb_commission_record.order_id,tb_commission_record.shop_id,tb_commission_record.statustb_agent_wallet.shop_id,tb_agent_wallet.wallet_type
常见错误排查
错误1: 佣金未入账
症状: commission_status = 2 但钱包余额未增加
排查步骤:
- 检查
tb_commission_record中是否有记录 - 检查记录的
status是否为 3(已发放) - 检查
tb_agent_wallet_transaction中是否有对应交易 - 查看应用日志中的错误信息
错误2: 链路断裂
症状: tb_commission_record.status = 99,remark 包含"套餐系列未分配"
排查步骤:
- 检查上级代理是否分配了该套餐
- 检查
tb_shop_package_allocation表中是否有记录 - 平台管理员需要手动分配套餐或修正佣金记录
错误3: 佣金计算失败
症状: 异步任务失败,订单 commission_status 仍为 1
排查步骤:
- 查看应用日志中的错误信息
- 检查订单数据是否完整(
seller_shop_id,seller_cost_price等) - 检查数据库连接是否正常
- 手动重试任务或联系技术支持