Commit 8c0ecfc3 authored by 刘小敏's avatar 刘小敏

feat(command): 增强修复佣金脚本并移除订单软删除查询

增强 FixMissedCommission 脚本,支持指定订单ID参数, 排除软删除订单,完善日志明细与汇总统计; 同时移除后台订单列表中不必要的 withTrashed 查询, 并更新 .gitignore 忽略规则。
parent 03afae08
...@@ -12,5 +12,4 @@ composer.lock ...@@ -12,5 +12,4 @@ composer.lock
.user.ini .user.ini
/public/uploads /public/uploads
.codebuddy/memory/2025-07-07.md .codebuddy/memory/
.codebuddy/memory/2026-07-08.md
...@@ -51,7 +51,7 @@ class Order extends Common ...@@ -51,7 +51,7 @@ class Order extends Common
return $this->view->fetch(); return $this->view->fetch();
} }
$orders = $this->model->withTrashed()->sheepFilter()->with(['user', 'items', 'address', 'activity_orders']) $orders = $this->model->sheepFilter()->with(['user', 'items', 'address', 'activity_orders'])
->paginate(request()->param('list_rows', 10))->each(function ($order) { ->paginate(request()->param('list_rows', 10))->each(function ($order) {
$order->pay_types = $order->pay_types; $order->pay_types = $order->pay_types;
$order->pay_types_text = $order->pay_types_text; $order->pay_types_text = $order->pay_types_text;
...@@ -80,12 +80,12 @@ class Order extends Common ...@@ -80,12 +80,12 @@ class Order extends Common
// 查询各个状态下的订单数量 // 查询各个状态下的订单数量
$searchStatus = $this->model->searchStatusList(); $searchStatus = $this->model->searchStatusList();
// 所有的数量 // 所有的数量
$result['all'] = $this->model->withTrashed()->sheepFilter(true, function ($filters) { $result['all'] = $this->model->sheepFilter(true, function ($filters) {
unset($filters['status']); unset($filters['status']);
return $filters; return $filters;
})->count(); })->count();
foreach ($searchStatus as $status => $text) { foreach ($searchStatus as $status => $text) {
$result[$status] = $this->model->withTrashed()->sheepFilter(true, function ($filters) use ($status) { $result[$status] = $this->model->sheepFilter(true, function ($filters) use ($status) {
$filters['status'] = $status; $filters['status'] = $status;
return $filters; return $filters;
})->count(); })->count();
......
## FixMissedCommission 脚本完整流程拆解
### 脚本目的
遍历所有已完成的订单,检查分销佣金是否有遗漏,自动补全缺失的分销数据。可重复执行,已有记录不会重复操作。
**执行命令**: `php think shopro:fix-missed-commission`
---
### 整体流程分 4 层
```
外层循环: 分页遍历已完成的订单
└─ 每笔订单: 两步处理
├─ 第一步: 创建分销订单 + 佣金计划(模拟支付成功)
└─ 第二步: 执行佣金拨款结算(模拟订单完成)
```
---
### 第 1 层:分页查询已完成订单(第 96-113 行)
- 每页 100 条(`PAGE_SIZE = 100`
- 查询条件:`status = completed` + `type != score`(排除纯积分商品订单)
- 查询字段:`id, user_id, order_sn, deduct_score`
-`id` 升序排列
- 当某页数据不足 100 条时,说明已是最后一页,退出循环
---
### 第 2 层:每笔订单的前置处理(第 115-133 行)
进入订单循环后,先做 2 件事:
| 步骤 | 内容 |
|------|------|
| ① 查询订单商品 | 查询 `shopro_order_item` 表,条件:`order_id = $orderId` + `refund_status = 0`(未退款) |
| ② 判断商品是否为空 | 没有未退款商品 → 跳过整笔订单 |
---
### 第 3 层 A:积分抵扣修正(第 135-143 行)
这是之前修复的 Bug:`order_item.pay_fee` 不含积分抵扣,需要手动扣减。
| 条件 | 操作 |
|------|------|
| `deduct_score = 0` | 无需修正,跳过 |
| `deduct_score > 0` | `积分抵扣金额 = deduct_score ÷ 100`(100 积分 = 1 元),汇总所有 item 的 `pay_fee` 总额 |
---
### 第 3 层 B:第一步 — 创建分销订单(第 145-216 行)
**目的**:为没有 `commission_order` 记录的商品补建分销订单和佣金计划(模拟"订单支付成功"事件)。
遍历每个 `order_item`,执行以下检查链:
```
商品 item → 检查1: ext.is_commission 标记
→ 是 → 跳过(标记不参与分销)
→ 否 → 检查2: shopro_commission_order 表是否已有记录
→ 有 → 跳过(已存在分佣记录)
→ 无 → 检查3: 积分抵扣修正 pay_fee
→ 按比例分摊:itemScoreDeduction = 积分抵扣金额 × (item.pay_fee / 各item.pay_fee总和)
→ 调整后 pay_fee = 原始 pay_fee - itemScoreDeduction
→ 检查4: OrderService.checkAndSetCommission()
→ 不满足 → 跳过(无分销商/无佣金规则等)
→ 满足 → 步骤4a: createCommissionOrder()
→ 失败 → 跳过
→ 成功 → 步骤4b: runCommissionPlan()
→ 递归向上创建所有上级分销商的佣金奖励(commission_reward)
```
**关键代码调用链**
- `new OrderService($item)` — 传入商品 item,内部会调用 `getGoodsCommissionAmount()` 拿到调整后的 `pay_fee`
- `checkAndSetCommission()` — 检查购买者是否有上级分销商、商品是否有佣金规则等
- `createCommissionOrder()` — 写入 `shopro_commission_order`
- `runCommissionPlan()` — 递归计算各级分销佣金,写入 `shopro_commission_reward`
---
### 第 3 层 C:第二步 — 执行拨款结算(第 221-266 行)
**目的**:对已有 `commission_order` 但佣金状态为"待结算"的记录,执行拨款(模拟"订单完成"事件)。
```
查所有 commission_order(order_id = $orderId)
→ 无 → 跳过第二步
→ 有 → 遍历每条分佣单:
→ 状态 != 待结算 → 跳过(已结算/已取消/已退款)
→ 状态 = 待结算 → RewardService('admin').runCommissionRewardByOrder()
→ 成功 → 写入钱包余额(total_income + 对应金额)
→ 失败 → 记录 warning
```
**关键点**:使用 `RewardService('admin')` 而非正常事件(如 `confirm`/`finish`),因为 `admin` 事件不受 `reward_event` 配置限制,确保一定能拨款。
---
### 第 4 层:统计汇总(第 278-290 行)
循环全部结束后输出汇总:
| 统计项 | 含义 |
|--------|------|
| `totalOrders` | 遍历的已完成订单总数 |
| `totalCreated` | 新创建的分销订单 `commission_order` 数 |
| `totalSettled` | 新执行的拨款结算数 |
| `totalSkipped` | 已结算/已取消跳过的分佣单数 |
---
### 可重复执行的安全性
| 保护机制 | 说明 |
|----------|------|
| `order_item_id` 唯一检查 | 已有 `commission_order` 记录的不重复创建 |
| 状态过滤 | 已结算/已取消/已退款的 `commission_order` 跳过拨款 |
| `is_commission` 标记 | 商品标记不参与分销的不处理 |
| 退款商品过滤 | `refund_status != 0` 的不处理 |
---
### 流程图总结
```
开始
分页查询 shopro_order (status=completed, type!=score)
遍历每笔订单 ──→ 无未退款商品 → 跳过
↓ 有
积分抵扣修正: 按比例从 item.pay_fee 扣减 deduct_score/100
【第一步】遍历 item:
├─ ext.is_commission=false → 跳过
├─ commission_order 已存在 → 跳过
├─ checkAndSetCommission 不满足 → 跳过
└─ ✓ createCommissionOrder → runCommissionPlan → 创建成功
【第二步】遍历 commission_order:
├─ 状态 != 待结算 → 跳过
└─ 待结算 → runCommissionRewardByOrder → 拨款到钱包
下一页 / 结束汇总
```
\ No newline at end of file
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment