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