1
0
forked from erp-dev/erp
Files
erpnew/docs/2026-01-16_summary.md

159 lines
7.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 2026-01-16 工作日志
## 背景
需要在 `stateflow` 模块提供一种通用查询能力按“已完成的状态节点state_id+ 工艺参数 key/value”反查相关的 `BusinessObject` 列表。
典型场景:查找所有 **已完成**“画图中”节点且工艺参数“设计师名称”为“AAA”的业务对象并可通过 `content_type/object_id` 追溯到实际业务对象,如 `printing.plateorder`)。
---
## 今日任务
-`GET /api/v1/stateflow/business-objects/` 增加过滤条件:`state_id` + `param_key` + `param_value`
- 增加 PostgreSQL JSONB 查询性能优化:为 `StateLogParameterRecord.parameters` 添加 GIN`jsonb_path_ops`)索引
- 补齐/更新测试用例,验证过滤行为与撤销记录处理
- 输出该查询能力的单独说明文档(用途/出入参/示例/性能与索引)
- Shipment 模块:为 `Shipment` 增加 `area` 字段并贯通所有相关 APIcreate/update/返回/文档/测试)
- Printing/定时任务实现“PlateOrder 图片按 URL 上传到腾讯云图库”的能力(上传函数/按 plate_order_id 批量上传/每日 03:00 定时任务/限速/失败落库)
---
## 今日完成
### 1) BusinessObject 查询能力增强(按已完成节点 + 工艺参数过滤)
`api_v1/views/stateflow/business_object.py``BusinessObjectFilterSet` 中新增过滤参数:
- `state_id`:状态节点 ID表示“已完成该节点”仅匹配 `StateFlowRecord.is_cancelled=False`
- `param_key`:工艺参数 key
- `param_value`:工艺参数 value
典型用法(示例:查 `printing.plateorder` 类型):
- `GET /api/v1/stateflow/business-objects/?content_type_str=printing.plateorder&state_id=<id>&param_key=设计师名称&param_value=AAA&limit=500&offset=0`
实现方式使用 `Exists(OuterRef)` 子查询,避免 join + distinct 的重复行问题,性能更稳定。
### 2) PostgreSQL JSONB 索引优化
新增迁移:`stateflow/migrations/0022_statelogparameterrecord_parameters_gin_index.py`
-`StateLogParameterRecord.parameters` 增加 `GIN(jsonb_path_ops)` 索引
- 主要加速 `parameters__contains={key: value}`(即 `jsonb @> ...`)这类查询
### 3) 测试补齐
`stateflow/tests/test_business_object_crud_and_filters_api.py` 增加用例,覆盖:
- 命中:已完成节点 + 参数匹配
- 不命中:参数值不一致
- 排除:已撤销的 `StateFlowRecord` 不参与匹配
另外,为保证 `stateflow` 测试集可持续运行,恢复了 `stateflow.services.clone_business_object()` 的实现(此前曾临时禁用导致测试失败)。
### 4) 单独说明文档stateflow 查询能力)
新增文档:`docs/stateflow_business_objects_query_by_completed_state_and_param.md`,包含:
- 能力用途/背景(“已完成某节点 + 工艺参数 key/value”反查 `BusinessObject`
- 接口定义与查询参数(`state_id/param_key/param_value``content_type_str` 的配套用法)
- 过滤语义(排除撤销记录、参数绑定范围)
- 返回结构(与 `BusinessObjectListSerializer` 对齐)
- 性能建议GIN 索引与验证方式)
### 5) Shipment增加 area 字段并贯通 APIcreate/update/返回/文档/测试)
新增字段:
- `shipment.models.Shipment.area``CharField(max_length=30, blank=True, default='')`
- 迁移:`shipment/migrations/0008_add_area_to_shipment.py`
接口/序列化器调整:
- `api_v1/views/shipment/serializers.py`
- `ShipmentSerializer`:响应中新增 `area`
- `ShipmentCreateNormalSerializer` / `ShipmentCreateExternalSerializer`:支持写入 `area`
- 新增 `ShipmentUpdateSerializer`用于更新入口PATCH/PUT
- `api_v1/views/shipment/views.py`
- 普通创建与 external 创建:将 `area` 透传并落库
- `ShipmentDetailView`:新增 `PATCH/PUT /api/v1/shipment/shipments/<id>/`,支持更新 `area` 并回显(同时保持 merchant 隔离与 customer 校验)
- `shipment/services.py``create_shipment/create_external_shipment` 支持 `area` 并写入
测试与文档:
- `api_v1/views/shipment/test_api.py`:补齐 create 回显 + PATCH 更新回显用例
- `docs/shipment_api.md`:补齐 `area` 的请求/响应示例与字段说明
### 6) PrintingPlateOrder 图片上传腾讯云图库(函数 + 定时任务 + 限速 + 失败落库)
依赖:
- `pyproject.toml`:加入 `tencentcloud-sdk-python`TIIA SDK
上传函数(基础能力):
- `api_v1/utils/tencentcloud_tiia.py`
- `upload_image_url_to_tencent_tiia(image_url, entity_id)`:调用 TIIA `CreateImage`,通过 URL 上传图片到图库
- 腾讯云凭证/配置改为从 `flower/settings.py` 读取(支持 `.env` 注入)
- `SimpleRateLimiter`:简单限速器,确保不超过 10 次/秒(可由 `TENCENTCLOUD_TIIA_QPS` 配置)
按 PlateOrder 批量上传(包装函数):
- `api_v1/utils/tencentcloud_tiia.py`
- `upload_plate_order_images_to_tencent_tiia(plate_order_id, rate_limiter=...)`
-`PlateOrder.plate_image(JSONField)` 提取所有图片 URL/Path兼容 `url/path/imageUrl/字符串`),逐张上传
- `entity_id` 统一使用 `str(plate_order_id)`
每日定时任务03:00 跑“昨天创建的订单”):
- `printing/tasks.py`
- `upload_yesterday_plate_order_images_to_tencent_tiia`
- 扫描昨天创建的 PlateOrder逐单上传遇错记录失败 ID 并继续
- `flower/settings.py`
- `CELERY_BEAT_SCHEDULE` 新增 `daily_plate_order_tiia_image_upload`03:00
失败记录表(用于可追踪/可重试):
- `printing.models.PlateOrderTiiaUploadFailure`
- 字段:`run_date/plate_order_id/error/details/attempts/last_attempt_at`
- 唯一约束:`(run_date, plate_order_id)`,重复失败会累加 `attempts`
- 迁移:`printing/migrations/0031_plateorder_tiia_upload_failure.py`
- `printing/admin.py`:在 admin 中注册失败记录表,便于排查
测试:
- `api_v1/test_tencentcloud_tiia_plate_order_upload.py`mock uploader验证包装函数能提取并上传多张图片、entity_id 绑定正确
- `printing/test_tiia_upload_task.py`mock uploader + sleep验证“记录失败 ID 但不中断继续执行”
补充配置项settings
- `flower/settings.py`
- `TENCENTCLOUD_SECRET_ID / TENCENTCLOUD_SECRET_KEY / TENCENTCLOUD_TOKEN`
- `TENCENTCLOUD_TIIA_GROUP_ID / TENCENTCLOUD_TIIA_REGION / TENCENTCLOUD_TIIA_ENDPOINT`
- `TENCENTCLOUD_TIIA_PIC_NAME_PREFIX`
- `TENCENTCLOUD_TIIA_QPS`(默认 10用于任务限速
### 7) 临时跑批(一次性全量上传现有 PlateOrder
为支持上线前手工验证/补数据,提供了可直接在 `manage.py shell` 中执行的一次性跑批脚本(遍历全部 `PlateOrder`,逐单上传 `plate_image` 里的所有图片,遇错记录失败 ID 并继续)。
说明:
- `entity_id` 使用 `plate_order_id`
- 通过 `SimpleRateLimiter(qps=10)` 遵守腾讯云限速
- 失败会写入 `PlateOrderTiiaUploadFailure`(便于后续排查与重试)
补充:也提供了正式的 Django management command推荐使用避免手工粘贴脚本
- 全量跑批:
- `uv run python manage.py tiia_upload_plate_order_images --all`
- 跑“昨天创建”的订单(同定时任务口径):
- `uv run python manage.py tiia_upload_plate_order_images --yesterday`
- 跑指定日期(本地时区 YYYY-MM-DD
- `uv run python manage.py tiia_upload_plate_order_images --date 2026-01-15`
- 跑单个订单:
- `uv run python manage.py tiia_upload_plate_order_images --plate-order-id 123`
- 小批量验证(最多处理 N 个):
- `uv run python manage.py tiia_upload_plate_order_images --all --limit 20`