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

6.9 KiB
Raw Blame History

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 添加 GINjsonb_path_ops)索引
  • 补齐/更新测试用例,验证过滤行为与撤销记录处理
  • 输出该查询能力的单独说明文档(用途/出入参/示例/性能与索引)
  • Shipment 模块:为 Shipment 增加 area 字段并贯通所有相关 APIcreate/update/返回/文档/测试)
  • Printing/定时任务实现“PlateOrder 图片按 URL 上传到腾讯云图库”的能力(上传函数/按 plate_order_id 批量上传/每日 03:00 定时任务/限速/失败落库)

今日完成

1) BusinessObject 查询能力增强(按已完成节点 + 工艺参数过滤)

api_v1/views/stateflow/business_object.pyBusinessObjectFilterSet 中新增过滤参数:

  • 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_valuecontent_type_str 的配套用法)
  • 过滤语义(排除撤销记录、参数绑定范围)
  • 返回结构(与 BusinessObjectListSerializer 对齐)
  • 性能建议GIN 索引与验证方式)

5) Shipment增加 area 字段并贯通 APIcreate/update/返回/文档/测试)

新增字段:

  • shipment.models.Shipment.areaCharField(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.pycreate_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-pythonTIIA 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_upload03: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.pymock uploader验证包装函数能提取并上传多张图片、entity_id 绑定正确
  • printing/test_tiia_upload_task.pymock 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(便于后续排查与重试)