# 差价佣金计算和分配逻辑搜索结果 ## 一、差价佣金的计算方式 ### 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 // 待人工修正 ```