模特库标签分页与全能创作收口:藏长视频、选择器分页

角色库导入打标签并支持筛选;模特库与全能创作角色/商品选择改为每页 20 条分页。临时限制成片 ≤60 秒,过滤对话里的超长时长选项,并收拢本地全能创作与后台用户相关修复。
This commit is contained in:
Azmat@qq.com
2026-09-21 16:24:37 +08:00
parent 690eb3d843
commit 0bd1db6bf9
48 changed files with 3386 additions and 896 deletions
+17 -9
View File
@@ -400,11 +400,13 @@ def _auto_pick_product_continuation(conversation: CreationConversation, request_
_STEP_CONTINUE_INSTRUCTIONS = {
"strategy": (
"用户已确认创作策略。现在只调用 write_plan 写方案卡(含完整 video_prompt 存档);"
"用户已确认创作策略。现在只调用 write_plan 写方案卡并存档 video_prompt;"
"超过 60 秒时只写紧凑章节稿(章节结构 + 每个 30 秒段关键镜头 + 交接状态),不要写制作级长文。"
"不要再写策略,不要调用 write_prompt,不要出片。"
),
"plan": (
"用户已确认视频方案。补齐完整 video_prompt 后直接调用 write_prompt 整理后台出片指令并给出积分确认卡;"
"用户已确认视频方案。调用 write_prompt 整理后台出片指令并给出积分确认卡;"
"超过 60 秒时长优先沿用方案里已存的 video_prompt,只补简短全片规则,不要重写成短片密度的制作长文。"
"不要重写策略/方案,也不要直接出片。"
),
"prompt": (
@@ -419,12 +421,12 @@ _STEP_REVISE_INSTRUCTIONS = {
"写完即停,不要同轮 write_plan / write_prompt。"
),
"plan": (
"用户要求修改视频方案。根据反馈只重新调用 write_plan 写一版修订方案"
"(含完整 video_prompt 存档);写完即停,不要同轮 write_prompt 或出片。"
"用户要求修改视频方案。根据反馈只重新调用 write_plan 写一版修订方案并更新 video_prompt;"
"超过 60 秒时仍写紧凑章节稿,不要写制作级长文。写完即停,不要同轮 write_prompt 或出片。"
),
"prompt": (
"用户要求修改出片细节。根据反馈只重新调用 write_prompt 整理一版修订指令;"
"完成后给出积分确认卡,不要直接出片。"
"长视频不要把逐镜再扩写成短片密度。完成后给出积分确认卡,不要直接出片。"
),
}
@@ -1147,9 +1149,15 @@ def _free_video_task_queryset(team):
)
def _not_omni_create_q() -> Q:
"""「不是全能创作」。同样不能写成 exclude(request_payload__feature="omni_create")——
JSON 键缺失时比较结果是 NULLexclude 会把没写 feature 的历史任务一起筛没。"""
return Q(request_payload__feature__isnull=True) | ~Q(request_payload__feature="omni_create")
def _free_video_list_queryset(team, *, include_replace=False):
"""正常任务流隐藏已从资产库删除的成品,但保留生成中/失败及无落库资产的历史任务。"""
from .video_replace import video_replace_q
from .video_replace import not_video_replace_q, video_replace_q
video_assets = Asset.objects.filter(origin_task_id=OuterRef("pk"), asset_type=Asset.Type.VIDEO)
active_video_assets = video_assets.filter(is_deleted=False, purged_at__isnull=True)
@@ -1168,13 +1176,13 @@ def _free_video_list_queryset(team, *, include_replace=False):
if include_replace:
return qs.filter(video_replace_q())
# 全能创作也走 FREE_VIDEO 任务类型,但不能出现在自由生成任务流里。
return qs.exclude(video_replace_q()).exclude(request_payload__feature="omni_create")
return qs.filter(not_video_replace_q()).filter(_not_omni_create_q())
def _free_video_trash_queryset(team):
return (
AITask.objects.filter(team=team, task_type=AITask.Type.FREE_VIDEO, is_deleted=True, purged_at__isnull=True)
.exclude(request_payload__feature="omni_create")
.filter(_not_omni_create_q())
.select_related("model_config")
.prefetch_related("generated_assets", "generated_assets__files")
)
@@ -1875,7 +1883,7 @@ class CreationConversationViewSet(TeamScopedViewSetMixin, ModelViewSet):
@action(detail=True, methods=["post"], url_path="merge-video-segments")
def merge_video_segments(self, request, pk=None):
"""用户确认后才合并多段成片;未点击前不下载视频、更不调用 ffmpeg"""
"""合并多段成片(兼容旧前端手动触发;正常流程在分段全成功后由平台自动合并)"""
conversation = self.get_object()
message_id = str(request.data.get("message_id") or "").strip()
message = conversation.messages.filter(id=message_id).first() if message_id else None