fix(extract): 实体提取改异步(worker+轮询),根治 502 + 刷新丢 loading + 重复扣费

问题:进资产页点"提取人物/场景"——同步死等豆包思考模型(数十秒)→ 撞网关超时
502;"提取中"loading 是纯前端内存态,刷新即丢;且无幂等,刷新后重点会重复扣费。

改动(对齐全站异步三件套:出图/三视图/故事板同款):
- 后端 submit_extract_entities:Web 只建 RESERVED 任务 + 预留额度秒回(不再 502);
  已有在途提取则复用,绝不二次预扣(防刷新后重点 / 并发重复扣费)。
- 后端 run_extract_entities_task(Celery worker):流式调豆包 + 解析 + 落库 + 扣费;
  失败退费并把可读错误记进 task.error_message。
- 新增 AITask.Type.entity_extraction(迁移 0011)+ extract-status 端点(轮询进度/成败)。
- 前端 runExtract 改提交+轮询;进资产页自动认领在途提取,刷新后 loading 自己回来。

验收:完整 Django 套件 149/149 全绿(含新增 4 测:异步落库+计费一次 / content空
回退 reasoning / 在途防重复扣费 / 状态端点成败透出);tsc + vite build 全绿;
makemigrations --check 无遗漏。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
seaislee1209
2026-06-22 23:15:11 +08:00
co-authored by Claude Opus 4.8
parent 71af0ae166
commit c8cb6d3d51
8 changed files with 304 additions and 86 deletions
@@ -0,0 +1,31 @@
# 实体提取改异步:新增 AITask 任务类型 entity_extraction(供在途查询/计费区分,与 script_optimization 分开)。
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("ai", "0010_modelconfig_is_default"),
]
operations = [
migrations.AlterField(
model_name="aitask",
name="task_type",
field=models.CharField(
choices=[
("script_generation", "Script Generation"),
("script_optimization", "Script Optimization"),
("entity_extraction", "Entity Extraction"),
("product_image", "Product Image"),
("person_image", "Person Image"),
("scene_image", "Scene Image"),
("storyboard", "Storyboard"),
("video_segment", "Video Segment"),
("voiceover", "Voiceover"),
("export", "Export"),
],
max_length=48,
),
),
]