forked from erp-dev/erp
148 lines
3.5 KiB
Markdown
148 lines
3.5 KiB
Markdown
# 外部订单产品补图
|
||
|
||
本文档说明“外部印染订单产品补图”的手动命令、共享逻辑与定时任务配置。
|
||
|
||
## 背景
|
||
|
||
系统中有一类 `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. 若未来需要追踪失败明细,可考虑像外部印染同步那样补失败落库;当前版本仅记录日志
|