1
0
forked from erp-dev/erp

feat: backfill external order image upgrade to beat schedule by 1 hour

This commit is contained in:
2026-03-31 18:10:24 +08:00
parent aff10b8925
commit 72840b7277
12 changed files with 1085 additions and 108 deletions

View File

@@ -0,0 +1,147 @@
# 外部订单产品补图
本文档说明“外部印染订单产品补图”的手动命令、共享逻辑与定时任务配置。
## 背景
系统中有一类 `PrintingJob` 来自外部印染订单,同步后:
- `printing_order.external_order_id` 有值
- `product.image` 为空
- `job.external_raw.YanSe``job.external_product_name` 中包含可用于外部图片接口查询的名称
为了让产品图片逐步补齐,项目提供:
1. 手动 management command
2. 可复用的共享函数
3. 每小时一次的 Celery 定时任务
## 处理规则
补图任务只处理满足以下条件的数据:
1. `printing_order.external_order_id` 非空
2. `product.image` 为空
3. 能从以下字段提取请求名:
- 优先:`external_raw.YanSe`
- 回退:`external_product_name`
并且同一个 `product` 在单次运行中只会处理一次,避免重复请求外部图片接口。
## 共享逻辑
共享逻辑已抽到:
- [api_v1/external_product_image_backfill.py](/home/f/coding/flower/api_v1/external_product_image_backfill.py)
其中:
- `extract_request_name(job)`
- `run_external_product_image_backfill(...)`
management command 与 Celery task 都复用这套逻辑,避免出现双份实现。
## 手动运行
命令位置:
- [api_v1/management/commands/backfill_external_product_images.py](/home/f/coding/flower/api_v1/management/commands/backfill_external_product_images.py)
### 示例
处理指定商户:
```bash
python manage.py backfill_external_product_images --merchant-id 1
```
限制本次最多处理 50 条:
```bash
python manage.py backfill_external_product_images --merchant-id 1 --limit 50
```
只预览、不实际写库:
```bash
python manage.py backfill_external_product_images --merchant-id 1 --dry-run
```
仅处理指定产品:
```bash
python manage.py backfill_external_product_images --product-id 123
```
### 参数
| 参数 | 说明 |
|------|------|
| `--merchant-id` | 仅处理指定商户的产品 |
| `--product-id` | 仅处理指定产品 |
| `--limit` | 最多处理多少条符合条件的产品 |
| `--dry-run` | 仅输出将处理的产品,不实际请求外部 API 或写库 |
## Celery Task
Task 位置:
- [api_v1/tasks.py](/home/f/coding/flower/api_v1/tasks.py)
Task 名称:
- `api_v1.tasks.backfill_external_product_images`
支持参数:
- `merchant_id`
- `product_id`
- `limit`
- `dry_run`
默认建议:
- `limit=500`
- `dry_run=False`
## 定时任务
已接入 `CELERY_BEAT_SCHEDULE`
- key: `backfill_external_product_images_hourly`
- schedule: `crontab(minute=17)`
- kwargs:
- `limit=500`
- `dry_run=False`
也就是说:
- 每小时第 `17` 分钟运行一次
- 采用错峰策略,避免和若干整点/五分钟任务撞在一起
配置位置:
- [flower/settings.py](/home/f/coding/flower/flower/settings.py)
## 输出与结果
无论是 command 还是 task最终都会产出统一统计结果包含
- `scanned`
- `selected`
- `success`
- `failed`
- `skipped_with_image`
- `skipped_without_request_name`
- `skipped_duplicate_product`
Celery task 还会额外带:
- `task_id`
## 风险与建议
1. 这是外部接口依赖任务,若外部图片接口不稳定,`failed` 可能升高
2. 每小时一次已足够,`limit=500` 对“补漏”场景比较合适
3. 如果后续发现积压较多,可以只调大 `limit`,不必提高调度频率
4. 若未来需要追踪失败明细,可考虑像外部印染同步那样补失败落库;当前版本仅记录日志