diff --git a/backend/routers/projects.py b/backend/routers/projects.py index 8c990da..32f268c 100644 --- a/backend/routers/projects.py +++ b/backend/routers/projects.py @@ -7,7 +7,7 @@ from datetime import datetime from database import get_db from models import ( User, Project, Submission, ProjectType, - ProjectStatus, PhaseGroup, WorkType, + ProjectStatus, PhaseGroup, WorkType, ContentType, ProjectMilestone, DEFAULT_MILESTONES ) from schemas import ( @@ -59,6 +59,13 @@ def enrich_project(p: Project, db: Session) -> ProjectOut: Submission.project_phase == PhaseGroup.PRODUCTION, ).scalar() or 0 + # 修补镜头(后期秒数,归入制作目标对比) + shot_repair_secs = db.query(sa_func.sum(Submission.total_seconds)).filter( + Submission.project_id == p.id, + Submission.content_type == ContentType.SHOT_REPAIR, + Submission.total_seconds > 0, + ).scalar() or 0 + # 后期产出:按内容类型分组 post_rows = db.query( Submission.content_type, @@ -107,6 +114,7 @@ def enrich_project(p: Project, db: Session) -> ProjectOut: "production": { "progress_percent": progress, "submitted_seconds": round(animation_secs, 1), + "shot_repair_seconds": round(shot_repair_secs, 1), "target_seconds": target, "waste": waste_data.get("production_waste", {}), }, diff --git a/backend/routers/submissions.py b/backend/routers/submissions.py index 34548cf..74d24dc 100644 --- a/backend/routers/submissions.py +++ b/backend/routers/submissions.py @@ -88,6 +88,14 @@ def create_submission( if req.hours_spent is None or req.hours_spent <= 0: raise HTTPException(status_code=422, detail="请填写投入时长") + # 产出时长校验:前期内容不需要,中期/后期内容必须 > 0 + PRE_PHASE_TYPES = {'策划案', '大纲/梗概', '概念设计图', '测试片', '剧本', '分镜', '人设图', '场景图', '道具图'} + content_val = req.content_type.value if hasattr(req.content_type, 'value') else req.content_type + if content_val not in PRE_PHASE_TYPES: + total_secs = (req.duration_minutes or 0) * 60 + (req.duration_seconds or 0) + if total_secs <= 0: + raise HTTPException(status_code=422, detail="请填写产出时长") + # 确定集数列表 from models import PROJECT_LEVEL_TYPES content_val = req.content_type.value if hasattr(req.content_type, 'value') else req.content_type @@ -211,6 +219,12 @@ def update_submission( # 重算总秒数 sub.total_seconds = (sub.duration_minutes or 0) * 60 + (sub.duration_seconds or 0) + # 产出时长校验:前期内容不需要,中期/后期内容必须 > 0 + PRE_PHASE_TYPES = {'策划案', '大纲/梗概', '概念设计图', '测试片', '剧本', '分镜', '人设图', '场景图', '道具图'} + content_val = sub.content_type.value if hasattr(sub.content_type, 'value') else sub.content_type + if content_val not in PRE_PHASE_TYPES and sub.total_seconds <= 0: + raise HTTPException(status_code=422, detail="请填写产出时长") + # 保存新数据 new_data = { "project_phase": sub.project_phase.value if hasattr(sub.project_phase, 'value') else sub.project_phase, diff --git a/frontend/src/views/ProjectDetail.vue b/frontend/src/views/ProjectDetail.vue index 9587427..25b0559 100644 --- a/frontend/src/views/ProjectDetail.vue +++ b/frontend/src/views/ProjectDetail.vue @@ -167,6 +167,10 @@ 目标 {{ formatSecs(project.target_total_seconds) }} +