forked from erp-dev/erp
7.7 KiB
7.7 KiB
腾讯云 TIIA 图库(PlateOrder 图片上传 & 搜图)说明
背景与目标
本项目接入腾讯云 TIIA(Image and Video AI)的“图库”能力,用于:
- 将
printing.PlateOrder的图片(通过 ImageUrl)上传到 TIIA 图库(CreateImage) - 通过输入图片(URL 或 Base64)在图库中做相似图检索(SearchImage)
一、配置(settings + .env)
配置集中在 flower/settings.py,建议通过 .env 注入:
TENCENTCLOUD_SECRET_IDTENCENTCLOUD_SECRET_KEYTENCENTCLOUD_TOKEN(可选,STS)TENCENTCLOUD_TIIA_GROUP_ID(当前默认168)TENCENTCLOUD_TIIA_REGION(默认ap-guangzhou)TENCENTCLOUD_TIIA_ENDPOINT(默认tiia.tencentcloudapi.com)TENCENTCLOUD_TIIA_PIC_NAME_PREFIX(默认plate_order)TENCENTCLOUD_TIIA_QPS(默认10,用于限速)
说明:
- 本项目通过
django-environ读取.env(Env.read_env(BASE_DIR / '.env')) - 本项目依赖
tencentcloud-sdk-python;在容器/服务启动方式不同的情况下,请确保运行使用的是同一套依赖环境(推荐uv run ...)。
二、上传到图库(CreateImage)
2.1 基础上传函数(上传单张 ImageUrl)
位置:api_v1/utils/tencentcloud_tiia.py
upload_image_url_to_tencent_tiia(image_url, entity_id, tags=None, custom_content=None)
行为(当前约定):
GroupId固定从 settings 读取EntityId由调用方传入(在 PlateOrder 场景中=str(plate_order_id))PicName自动生成(带TENCENTCLOUD_TIIA_PIC_NAME_PREFIX)ImageUrl使用传入的image_urlCustomContent默认写入完整image_urlTags默认不写入(避免触发“标签值长度过长”)
注意:腾讯云
SearchImage的返回结构默认不包含ImageUrl;如果你希望在搜图结果里拿到可访问 URL,建议依赖CustomContent(前提是腾讯云搜图返回里会回传该字段)。
2.2 PlateOrder 批量上传(读取 plate_image)
位置:api_v1/utils/tencentcloud_tiia.py
upload_plate_order_images_to_tencent_tiia(plate_order_id, rate_limiter=None)
行为:
- 查询
printing.PlateOrder(id=plate_order_id) - 从
plate_image(JSONField)提取所有图片 URL/Path(兼容多种字段名与格式),并标准化为公网可访问 URL - 对每张图片调用
upload_image_url_to_tencent_tiia(...) - 单张失败不抛出,返回每张图片的结果列表(便于落库/排查)
三、定时任务(Celery Beat:每天 03:00 上传“昨天创建的订单”)
3.1 Task 本体
位置:printing/tasks.py
upload_yesterday_plate_order_images_to_tencent_tiia
行为:
- 计算“昨天”的日期范围
[start, end) - 遍历
created_at落在该范围内的所有PlateOrder - 逐单上传
plate_image中所有图片 - 遇错:记录失败并继续处理下一个订单
- 使用
SimpleRateLimiter(qps=TENCENTCLOUD_TIIA_QPS)控制 QPS(默认 10)
3.2 Beat 调度配置
位置:flower/settings.py
CELERY_BEAT_SCHEDULE['daily_plate_order_tiia_image_upload']task = 'printing.tasks.upload_yesterday_plate_order_images_to_tencent_tiia'schedule = crontab(hour=3, minute=0)
说明:
- 仅配置 schedule 不代表一定在跑;需要线上同时运行 celery worker + celery beat。
四、失败记录(可追踪/可重试)
位置:printing/models.py
PlateOrderTiiaUploadFailurerun_date / plate_order_id / error / details / attempts / last_attempt_at- 唯一约束:
(run_date, plate_order_id),同日重复失败会累加attempts
可在 Django Admin 中查看(printing/admin.py 已注册)。
四点五、MDY 开版暂存(MDYPlateOrderStaging)图片上传到图库(CreateImage)
4.5.1 目标数据源与字段(明道云暂存)
数据源:
- 模型:
api_v1.models.MDYPlateOrderStaging - 图片字段:
raw["62d52f4b8d2972284492dd27"](明道云开版主表字段“开版图”,Attachment)
单个附件项的 URL 取值策略(当前约定):
- 优先:
original_file_full_path(你确认的主用字段) - 候补:
DownloadUrl - 不再使用:
preview_url(通常带 token/过期参数,不适合作为长期回显 URL)
4.5.2 Service(上传单条暂存记录)
位置:api_v1/mdy_plate_order_staging_tiia_upload.py
upload_mdy_plate_order_staging_plate_images_to_tencent_tiia(staging, rate_limiter=None, dry_run=False)EntityId:使用staging.mdy_rowid- 每张图调用:
api_v1.utils.tencentcloud_tiia.upload_image_url_to_tencent_tiia(image_url, entity_id, custom_content=image_url) - 限流:
SimpleRateLimiter(qps=settings.TENCENTCLOUD_TIIA_QPS)(默认 10) - 单张失败不影响其它图片,返回
successes/failures明细
4.5.3 定时任务(Celery Beat)
位置:api_v1/tasks.py
- task:
upload_mdy_plate_order_staging_images_to_tencent_tiia(batch_size=200, dry_run=False)- 游标:
api_v1.models.DataSync(table_name=mdy_plate_order_staging_tiia_upload),用last_rowid存储 staging 表自增id - 失败落库:
api_v1.models.MDYPlateOrderStagingTiiaUploadFailure(同日同 rowid 去重,attempts 累加)
- 游标:
Beat 配置位置:flower/settings.py
CELERY_BEAT_SCHEDULE['daily_mdy_plate_order_staging_tiia_image_upload']- 默认:03:20 运行
- kwargs 默认值:
batch_size=500dry_run=False
手动触发(示例):
uv run python manage.py shell -c "from api_v1.tasks import upload_mdy_plate_order_staging_images_to_tencent_tiia; r=upload_mdy_plate_order_staging_images_to_tencent_tiia.delay(batch_size=50, dry_run=True); print(r.id)"
4.5.4 迁移与 Admin
- 迁移:
api_v1/migrations/0010_mdy_plate_order_staging_tiia_upload_failure.py - Admin:
api_v1/admin.py已注册MDYPlateOrderStagingTiiaUploadFailure
五、手动跑批(推荐:management command)
位置:printing/management/commands/tiia_upload_plate_order_images.py
常用:
- 全量跑批:
uv run python manage.py tiia_upload_plate_order_images --all - 跑昨天:
uv run python manage.py tiia_upload_plate_order_images --yesterday - 跑某天:
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 - 小批量验证:
uv run python manage.py tiia_upload_plate_order_images --all --limit 20 - Dry-run:
uv run python manage.py tiia_upload_plate_order_images --all --dry-run
说明:
- 同样遵守
TENCENTCLOUD_TIIA_QPS的限速,并会落库失败记录。
六、搜图 API(简化版:SearchImage)
6.1 接口
POST /api/v1/tiia/search-image/
参数(JSON body):
imageUrl:图片 URL(优先)imageBase64:Base64(可选,若无 imageUrl)limit:可选,1~100(默认腾讯云 10;本项目已透传)offset:可选,>=0matchThreshold:可选,0~100
6.2 返回
- 直接返回腾讯云
SearchImage的原始响应 JSON
6.3 已知限制/注意点
- 腾讯云
SearchImage返回结果通常以EntityId/PicName/Score/Tags/CustomContent为主,不一定直接提供可访问ImageUrl - 如果期望在搜图结果里拿到可访问 URL,请优先依赖上传时写入的
CustomContent
七、排障清单(常见问题)
- SDK 导入失败(
No module named 'tencentcloud'):- 确认使用
uv run python ...(确保解释器与依赖一致)
- 确认使用
- 腾讯云返回“标签值长度过长”:
- 不要默认写入
Tags;本项目已改为默认不写Tags
- 不要默认写入
- 任务未触发:
- 检查是否同时运行 celery worker + celery beat
- 检查
CELERY_BROKER_URL / CELERY_RESULT_BACKEND是否可用