Files
junhong_cmp_fiber/docs/commission-search-result.md
huang 8f66ca7bcb
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m14s
文档提交
2026-04-11 11:27:43 +08:00

238 lines
6.7 KiB
Markdown
Raw Permalink 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.
# 差价佣金计算和分配逻辑搜索结果
## 一、差价佣金的计算方式
### 1.1 计算公式
差价佣金 = 下级成本价 - 自己成本价
### 1.2 计算流程
**文件位置**: `internal/service/commission_calculation/service.go:121-225`
```go
func (s *Service) CalculateCostDiffCommission(ctx context.Context, order *model.Order) ([]*model.CommissionRecord, error)
```
**核心逻辑**:
1. **销售端利润计算** (第138-153行)
- 销售利润 = 订单总金额 - 销售成本价
- 如果销售利润 > 0为销售店铺创建一条佣金记录
2. **链式向上计算** (第163-222行)
- 从销售店铺开始,逐级向上遍历代理链
- 对于每一级代理:
- 获取该代理的成本价(从 ShopPackageAllocation 表)
- 计算差价childCostPrice - myCostPrice
- 如果差价 > 0创建佣金记录
3. **链路断裂处理** (第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`
差价佣金在以下情况触发:
1. **订单支付成功**
- 支付状态从 `PaymentStatusPending` (1) 变为 `PaymentStatusPaid` (2)
- 触发点:`WalletPay()` 方法完成后调用 `enqueueCommissionCalculation()`
2. **异步任务处理**
- 任务类型: `commission:calculate`
- 处理器: `CommissionCalculationHandler.HandleCommissionCalculation()`
- 队列: Asynq 异步任务队列
### 2.2 发放流程
**文件位置**: `internal/service/commission_calculation/service.go:74-119`
```go
func (s *Service) CalculateCommission(ctx context.Context, orderID uint) error
```
**步骤**:
1. **检查订单佣金状态** (第81-84行)
- 如果 `commission_status == 2` (已计算),跳过
- 防止重复计算
2. **计算成本价差佣金** (第86-98行)
- 调用 `CalculateCostDiffCommission()` 获取佣金记录列表
- 逐条创建佣金记录到 `tb_commission_record`
- 调用 `creditCommissionInTx()` 入账到代理钱包
3. **触发一次性佣金** (第100-111行)
- 仅非代购订单触发
- 根据订单类型(单卡/设备)调用对应方法
4. **更新订单佣金状态** (第113-115行)
-`commission_status` 更新为 `2` (已计算)
### 2.3 佣金入账
**文件位置**: `internal/service/commission_calculation/service.go:641-687`
```go
func (s *Service) creditCommissionInTx(ctx context.Context, tx *gorm.DB, record *model.CommissionRecord) error
```
**入账步骤**:
1. 获取店铺的分佣钱包 (wallet_type = 'commission')
2. 增加钱包余额
3. 更新佣金记录状态为 `CommissionStatusReleased` (3)
4. 记录入账时间 `released_at`
5. 创建钱包交易记录 (transaction_type = 'commission')
---
## 三、差价佣金与订单状态的关系
### 3.1 订单状态定义
**文件位置**: `internal/model/order.go:106-110`
```go
// 佣金状态常量
const (
CommissionStatusPending = 1 // 待计算
CommissionStatusCalculated = 2 // 已计算
)
```
### 3.2 订单支付状态
**文件位置**: `internal/model/order.go:98-104`
```go
// 支付状态常量
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`
```go
// 佣金记录状态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`
```go
// 任务类型
TaskTypeCommission = "commission:calculate"
// 佣金来源
CommissionSourceCostDiff = "cost_diff" // 成本价差
CommissionSourceOneTime = "one_time" // 一次性佣金
// 佣金状态
CommissionStatusReleased = 3 // 已发放
CommissionStatusInvalid = 4 // 已失效
CommissionStatusPendingReview = 99 // 待人工修正
```