"""补充演示数据 - 只添加项目/提交/成本,不动用户和角色 展示场景: 1. 双色进度条(品牌方 TVC 进度>200%) 2. 工时损耗(分镜/剪辑里程碑超期) 3. 秒数损耗(测试提交 + 超产) 4. 四种项目类型 + 五个项目 5. 前期必须结束才有制作提交 6. 内部原创配有风格测试项目 7. owners / 制片 不提交 """ from datetime import date, datetime, timedelta from database import SessionLocal from models import * db = SessionLocal() def get_user(username): u = db.query(User).filter(User.username == username).first() if not u: print(f" [WARN] user '{username}' not found") return u def dt(d): """date → datetime(用于 completed_at)""" return datetime.combine(d, datetime.min.time()) def seed_demo(): # 清除旧的项目相关数据(不动 users 和 roles) db.query(SubmissionHistory).delete() db.query(Submission).delete() db.query(OutsourceCost).delete() db.query(CostOverride).delete() db.query(AIToolCost).delete() db.query(OverheadCost).delete() db.query(ProjectMilestone).delete() db.query(Project).delete() db.commit() print("[1] Cleared old project data") # ── 获取真实用户 ── # owners / 制片:不提交任何东西 huhaonan = get_user("huhaonan") # owner/总导演 dengqingrui = get_user("dengqingrui") # owner/AI导演 qiushaohui = get_user("qiushaohui") # 制片 # 组长:可以提交 chenbaodan = get_user("chenbaodan") # 组长/动画制作 maruoqing = get_user("maruoqing") # 组长/AI导演 weichunli = get_user("weichunli") # 组长/AI导演 panziyan = get_user("panziyan") # 组长/剪辑 # 组员 daixiaoqian = get_user("daixiaoqian") # 动画制作 tanruping = get_user("tanruping") # 动画制作 zhengyiqing = get_user("zhengyiqing") # 动画制作 huangxuewen = get_user("huangxuewen") # 动画制作 liushiqi = get_user("liushiqi") # 动画制作 daiwei = get_user("daiwei") # 动画制作 huangrongying = get_user("huangrongying") # 编剧 jiahaozheng = get_user("jiahaozheng") # 剪辑 wangyansen = get_user("wangyansen") # 剪辑 huangqiuxia = get_user("huangqiuxia") # 动画制作 lijing = get_user("lijing") # 动画制作 yemeilian = get_user("yemeilian") # 动画制作 chenxuanying = get_user("chenxuanying") # 动画制作 today = date.today() # ══════════════════════════════════════════════════════════════ # 项目 1: 品牌方 TVC 宣传片 # 客户正式 | 后期 | target=180s | 创建于 12/8 # 进度>200% → 双色进度条 # 分镜+剪辑超期 → waste_hours # ══════════════════════════════════════════════════════════════ proj_tvc = Project( name="品牌方 TVC 宣传片", project_type=ProjectType.CLIENT_FORMAL, leader_id=maruoqing.id, current_phase=PhaseGroup.POST, episode_duration_minutes=1, episode_count=3, estimated_completion_date=date(2026, 2, 20), contract_amount=50000, created_at=dt(date(2025, 12, 8)), ) # ══════════════════════════════════════════════════════════════ # 项目 2: 星际漫游 第一季 # 客户正式 | 制作中 | target=3900s | 创建于 12/22 # 进度~80% | 分镜微超期 → 少量 waste_hours # ══════════════════════════════════════════════════════════════ proj_star = Project( name="星际漫游 第一季", project_type=ProjectType.CLIENT_FORMAL, leader_id=chenbaodan.id, current_phase=PhaseGroup.PRODUCTION, episode_duration_minutes=5, episode_count=13, estimated_completion_date=date(2026, 3, 30), contract_amount=100000, created_at=dt(date(2025, 12, 22)), ) # ══════════════════════════════════════════════════════════════ # 项目 3: AI 短剧原创 S1 # 内部原创 | 制作中 | target=2880s | 创建于 1/6 # 进度~40% | 无超期 → waste_hours=0 # ══════════════════════════════════════════════════════════════ proj_orig = Project( name="AI 短剧原创 S1", project_type=ProjectType.INTERNAL_ORIGINAL, leader_id=weichunli.id, current_phase=PhaseGroup.PRODUCTION, episode_duration_minutes=8, episode_count=6, estimated_completion_date=date(2026, 4, 30), created_at=dt(date(2026, 1, 6)), ) # ══════════════════════════════════════════════════════════════ # 项目 4: 原创 S1 风格测试 # 内部测试 | 制作 | target=60s | 创建于 1/2 # 内部原创的配套测试项目 | 全 TEST → 高损耗率 # ══════════════════════════════════════════════════════════════ proj_orig_test = Project( name="原创 S1 风格测试", project_type=ProjectType.INTERNAL_TEST, leader_id=weichunli.id, current_phase=PhaseGroup.PRODUCTION, episode_duration_minutes=1, episode_count=1, created_at=dt(date(2026, 1, 2)), ) # ══════════════════════════════════════════════════════════════ # 项目 5: 甲方风格测试 # 客户测试 | 前期 | target=60s | 创建于 1/27 # 早期阶段 | 策划案超期 → waste_hours # ══════════════════════════════════════════════════════════════ proj_client_test = Project( name="甲方风格测试", project_type=ProjectType.CLIENT_TEST, leader_id=maruoqing.id, current_phase=PhaseGroup.PRE, episode_duration_minutes=1, episode_count=1, created_at=dt(date(2026, 1, 27)), ) db.add_all([proj_tvc, proj_star, proj_orig, proj_orig_test, proj_client_test]) db.flush() print("[2] Created 5 projects") # ══════════════════════════════════════════════════════════════ # 里程碑 # ══════════════════════════════════════════════════════════════ milestones = [] # ── 品牌方 TVC 里程碑 ── # 前期 milestones.append(ProjectMilestone( project_id=proj_tvc.id, name="策划案", phase=PhaseGroup.PRE, sort_order=1, estimated_days=2, start_date=date(2025, 12, 8), is_completed=1, completed_at=dt(date(2025, 12, 9)), )) milestones.append(ProjectMilestone( project_id=proj_tvc.id, name="分镜", phase=PhaseGroup.PRE, sort_order=3, estimated_days=2, start_date=date(2025, 12, 10), is_completed=1, completed_at=dt(date(2025, 12, 15)), # 实际3天,超1天→8h )) milestones.append(ProjectMilestone( project_id=proj_tvc.id, name="人设图", phase=PhaseGroup.PRE, sort_order=4, estimated_days=2, start_date=date(2025, 12, 15), is_completed=1, completed_at=dt(date(2025, 12, 16)), )) milestones.append(ProjectMilestone( project_id=proj_tvc.id, name="场景图", phase=PhaseGroup.PRE, sort_order=5, estimated_days=1, start_date=date(2025, 12, 17), is_completed=1, completed_at=dt(date(2025, 12, 17)), )) # 后期 milestones.append(ProjectMilestone( project_id=proj_tvc.id, name="配音", phase=PhaseGroup.POST, sort_order=1, estimated_days=3, start_date=date(2026, 1, 27), is_completed=1, completed_at=dt(date(2026, 1, 29)), )) milestones.append(ProjectMilestone( project_id=proj_tvc.id, name="音效", phase=PhaseGroup.POST, sort_order=2, estimated_days=2, start_date=date(2026, 1, 29), is_completed=1, completed_at=dt(date(2026, 1, 30)), )) milestones.append(ProjectMilestone( project_id=proj_tvc.id, name="修补镜头", phase=PhaseGroup.POST, sort_order=3, estimated_days=2, start_date=date(2026, 1, 27), is_completed=1, completed_at=dt(date(2026, 1, 28)), )) milestones.append(ProjectMilestone( project_id=proj_tvc.id, name="剪辑", phase=PhaseGroup.POST, sort_order=4, estimated_days=3, start_date=date(2026, 2, 3), is_completed=0, # 进行中,多轮反馈导致超期 → waste_hours )) # ── 星际漫游 里程碑 ── # 前期 milestones.append(ProjectMilestone( project_id=proj_star.id, name="策划案", phase=PhaseGroup.PRE, sort_order=1, estimated_days=3, start_date=date(2025, 12, 22), is_completed=1, completed_at=dt(date(2025, 12, 23)), )) milestones.append(ProjectMilestone( project_id=proj_star.id, name="剧本", phase=PhaseGroup.PRE, sort_order=2, estimated_days=5, start_date=date(2025, 12, 24), is_completed=1, completed_at=dt(date(2025, 12, 30)), )) milestones.append(ProjectMilestone( project_id=proj_star.id, name="分镜", phase=PhaseGroup.PRE, sort_order=3, estimated_days=3, start_date=date(2025, 12, 31), is_completed=1, completed_at=dt(date(2026, 1, 7)), # 实际5天,超2天→16h )) milestones.append(ProjectMilestone( project_id=proj_star.id, name="人设图", phase=PhaseGroup.PRE, sort_order=4, estimated_days=2, start_date=date(2026, 1, 8), is_completed=1, completed_at=dt(date(2026, 1, 9)), )) milestones.append(ProjectMilestone( project_id=proj_star.id, name="场景图", phase=PhaseGroup.PRE, sort_order=5, estimated_days=2, start_date=date(2026, 1, 10), is_completed=1, completed_at=dt(date(2026, 1, 13)), )) # 后期(未开始) for name, order in [("配音", 1), ("音效", 2), ("修补镜头", 3), ("剪辑", 4)]: milestones.append(ProjectMilestone( project_id=proj_star.id, name=name, phase=PhaseGroup.POST, sort_order=order, )) # ── AI 短剧原创 里程碑 ──(全部按时) milestones.append(ProjectMilestone( project_id=proj_orig.id, name="策划案", phase=PhaseGroup.PRE, sort_order=1, estimated_days=2, start_date=date(2026, 1, 6), is_completed=1, completed_at=dt(date(2026, 1, 7)), )) milestones.append(ProjectMilestone( project_id=proj_orig.id, name="剧本", phase=PhaseGroup.PRE, sort_order=2, estimated_days=5, start_date=date(2026, 1, 8), is_completed=1, completed_at=dt(date(2026, 1, 14)), )) milestones.append(ProjectMilestone( project_id=proj_orig.id, name="分镜", phase=PhaseGroup.PRE, sort_order=3, estimated_days=3, start_date=date(2026, 1, 15), is_completed=1, completed_at=dt(date(2026, 1, 17)), )) milestones.append(ProjectMilestone( project_id=proj_orig.id, name="人设图", phase=PhaseGroup.PRE, sort_order=4, estimated_days=2, start_date=date(2026, 1, 20), is_completed=1, completed_at=dt(date(2026, 1, 21)), )) milestones.append(ProjectMilestone( project_id=proj_orig.id, name="场景图", phase=PhaseGroup.PRE, sort_order=5, estimated_days=1, start_date=date(2026, 1, 22), is_completed=1, completed_at=dt(date(2026, 1, 22)), )) for name, order in [("配音", 1), ("音效", 2), ("修补镜头", 3), ("剪辑", 4)]: milestones.append(ProjectMilestone( project_id=proj_orig.id, name=name, phase=PhaseGroup.POST, sort_order=order, )) # ── 原创风格测试 里程碑 ── milestones.append(ProjectMilestone( project_id=proj_orig_test.id, name="策划案", phase=PhaseGroup.PRE, sort_order=1, estimated_days=2, start_date=date(2026, 1, 2), is_completed=1, completed_at=dt(date(2026, 1, 3)), )) milestones.append(ProjectMilestone( project_id=proj_orig_test.id, name="人设图", phase=PhaseGroup.PRE, sort_order=4, estimated_days=2, start_date=date(2026, 1, 6), is_completed=1, completed_at=dt(date(2026, 1, 7)), )) milestones.append(ProjectMilestone( project_id=proj_orig_test.id, name="剪辑", phase=PhaseGroup.POST, sort_order=4, )) # ── 甲方风格测试 里程碑 ── milestones.append(ProjectMilestone( project_id=proj_client_test.id, name="策划案", phase=PhaseGroup.PRE, sort_order=1, estimated_days=3, start_date=date(2026, 1, 27), is_completed=0, # 甲方反复修改,至今未定稿 → 超期 → waste_hours )) milestones.append(ProjectMilestone( project_id=proj_client_test.id, name="人设图", phase=PhaseGroup.PRE, sort_order=4, estimated_days=2, start_date=date(2026, 2, 3), is_completed=0, )) milestones.append(ProjectMilestone( project_id=proj_client_test.id, name="剪辑", phase=PhaseGroup.POST, sort_order=4, )) db.add_all(milestones) db.flush() print(f"[2.5] Created {len(milestones)} milestones") # ══════════════════════════════════════════════════════════════ # 内容提交 # ══════════════════════════════════════════════════════════════ subs = [] def add(user, proj, phase, wt, ct, secs, d, desc, hours=None): """快捷添加提交""" subs.append(Submission( user_id=user.id, project_id=proj.id, project_phase=phase, work_type=wt, content_type=ct, total_seconds=secs, duration_minutes=secs // 60 if secs else 0, duration_seconds=secs % 60 if secs else 0, hours_spent=hours, submit_to=SubmitTo.INTERNAL, description=desc, submit_date=d, )) PRE = PhaseGroup.PRE PROD = PhaseGroup.PRODUCTION POST = PhaseGroup.POST PLAN = WorkType.PLAN MFG = WorkType.PRODUCTION TEST = WorkType.TEST # ──────────────────────────────────────────── # 品牌方 TVC 宣传片 (target=180s, 创建 12/8) # 前期: 12/8 - 12/18 # 制作: 12/22 - 1/10 # 后期: 1/27 - now # ──────────────────────────────────────────── # 前期 - 策划案 (12/8-9) add(huangrongying, proj_tvc, PRE, PLAN, ContentType.PLANNING, 0, date(2025, 12, 8), "TVC 策划案初稿", 4) add(huangrongying, proj_tvc, PRE, PLAN, ContentType.PLANNING, 0, date(2025, 12, 9), "TVC 策划案定稿", 3) # 前期 - 分镜 (12/10-15, 比预期多1天) add(daixiaoqian, proj_tvc, PRE, PLAN, ContentType.STORYBOARD, 0, date(2025, 12, 10), "TVC 分镜初稿", 5) add(daixiaoqian, proj_tvc, PRE, PLAN, ContentType.STORYBOARD, 0, date(2025, 12, 11), "TVC 分镜修改", 4) add(daixiaoqian, proj_tvc, PRE, PLAN, ContentType.STORYBOARD, 0, date(2025, 12, 15), "TVC 分镜终稿", 3) # 前期 - 人设图 (12/15-16) add(huangxuewen, proj_tvc, PRE, PLAN, ContentType.CHARACTER_DESIGN, 0, date(2025, 12, 15), "TVC 人设图初稿", 5) add(huangxuewen, proj_tvc, PRE, PLAN, ContentType.CHARACTER_DESIGN, 0, date(2025, 12, 16), "TVC 人设图定稿", 3) # 前期 - 场景图 (12/17) add(huangxuewen, proj_tvc, PRE, PLAN, ContentType.SCENE_DESIGN, 0, date(2025, 12, 17), "TVC 场景图", 4) # 制作 - 马若情 (12/22 - 12/26 第一轮, 1/8-9 修改轮) add(maruoqing, proj_tvc, PROD, TEST, ContentType.ANIMATION, 35, date(2025, 12, 22), "TVC 片段测试", 3) add(maruoqing, proj_tvc, PROD, MFG, ContentType.ANIMATION, 70, date(2025, 12, 23), "TVC 第1集场景1", 4) add(maruoqing, proj_tvc, PROD, MFG, ContentType.ANIMATION, 65, date(2025, 12, 24), "TVC 第1集场景2", 4) add(maruoqing, proj_tvc, PROD, MFG, ContentType.ANIMATION, 75, date(2025, 12, 25), "TVC 第2集场景1", 4) add(maruoqing, proj_tvc, PROD, MFG, ContentType.ANIMATION, 60, date(2025, 12, 26), "TVC 第2-3集", 4) # 甲方反馈后修改 add(maruoqing, proj_tvc, PROD, MFG, ContentType.ANIMATION, 55, date(2026, 1, 8), "TVC 修改-第1集重做", 3) add(maruoqing, proj_tvc, PROD, MFG, ContentType.ANIMATION, 50, date(2026, 1, 9), "TVC 修改-第3集调整", 3) # 后期 - 修补镜头 (秒数,归入制作计算) 1/27-28 add(liushiqi, proj_tvc, POST, MFG, ContentType.SHOT_REPAIR, 25, date(2026, 1, 27), "TVC 修补镜头1", 1.5) add(liushiqi, proj_tvc, POST, MFG, ContentType.SHOT_REPAIR, 30, date(2026, 1, 28), "TVC 修补镜头2", 1.5) # 后期 - 配音 (1/27-29, 每天1集) add(panziyan, proj_tvc, POST, MFG, ContentType.DUBBING, 0, date(2026, 1, 27), "TVC 第1集配音", 4) add(panziyan, proj_tvc, POST, MFG, ContentType.DUBBING, 0, date(2026, 1, 28), "TVC 第2集配音", 4) add(panziyan, proj_tvc, POST, MFG, ContentType.DUBBING, 0, date(2026, 1, 29), "TVC 第3集配音", 3) # 后期 - 音效 (1/29-30) add(panziyan, proj_tvc, POST, MFG, ContentType.SOUND_EFFECTS, 0, date(2026, 1, 29), "TVC 音效设计", 5) add(panziyan, proj_tvc, POST, MFG, ContentType.SOUND_EFFECTS, 0, date(2026, 1, 30), "TVC 音效终混", 3) # 后期 - 剪辑 (2/3-now, 多轮甲方反馈导致超期) add(wangyansen, proj_tvc, POST, MFG, ContentType.EDITING, 0, date(2026, 2, 3), "TVC 第1-2集粗剪", 6) add(wangyansen, proj_tvc, POST, MFG, ContentType.EDITING, 0, date(2026, 2, 4), "TVC 第3集粗剪+精剪", 5) add(wangyansen, proj_tvc, POST, MFG, ContentType.EDITING, 0, date(2026, 2, 10), "TVC 甲方反馈后重剪", 5) add(wangyansen, proj_tvc, POST, MFG, ContentType.EDITING, 0, date(2026, 2, 12), "TVC 第二轮反馈修改", 4) # ──────────────────────────────────────────── # 星际漫游 第一季 (target=3900s, 创建 12/22) # 前期: 12/22 - 1/13 # 制作: 1/14 - now # ──────────────────────────────────────────── # 前期 - 策划案 (12/22-23) add(huangrongying, proj_star, PRE, PLAN, ContentType.PLANNING, 0, date(2025, 12, 22), "星际漫游 世界观策划案", 4) add(huangrongying, proj_star, PRE, PLAN, ContentType.PLANNING, 0, date(2025, 12, 23), "星际漫游 策划案终稿", 3) # 前期 - 剧本 (12/24-30, 5个工作日) for i, d in enumerate([date(2025, 12, 24), date(2025, 12, 25), date(2025, 12, 26), date(2025, 12, 29), date(2025, 12, 30)]): add(huangrongying, proj_star, PRE, PLAN, ContentType.SCRIPT, 0, d, f"第{i*3+1}-{i*3+3}集剧本", 6) # 前期 - 分镜 (12/31-1/7, 比预期多, 导致超期 → 16h waste) for i, d in enumerate([date(2025, 12, 31), date(2026, 1, 2), date(2026, 1, 5), date(2026, 1, 6), date(2026, 1, 7)]): add(daixiaoqian, proj_star, PRE, PLAN, ContentType.STORYBOARD, 0, d, f"第{i+1}批分镜({i*3+1}-{i*3+3}集)", 5) # 前期 - 人设图 (1/8-9) add(huangxuewen, proj_star, PRE, PLAN, ContentType.CHARACTER_DESIGN, 0, date(2026, 1, 8), "主要角色人设图", 5) add(huangxuewen, proj_star, PRE, PLAN, ContentType.CHARACTER_DESIGN, 0, date(2026, 1, 9), "配角人设图", 4) # 前期 - 场景图 (1/10-13) add(huangxuewen, proj_star, PRE, PLAN, ContentType.SCENE_DESIGN, 0, date(2026, 1, 12), "太空站场景图", 5) add(huangxuewen, proj_star, PRE, PLAN, ContentType.SCENE_DESIGN, 0, date(2026, 1, 13), "星球表面场景图", 4) # 制作 - 1/14 起 (~22个工作日到今天) # 3个动画师,不是每天都在这个项目上 # 陈保丹: 14次提交 (2测试 + 12制作) star_anim_dates_chen = [ date(2026, 1, 14), date(2026, 1, 15), date(2026, 1, 16), date(2026, 1, 19), date(2026, 1, 20), date(2026, 1, 22), date(2026, 1, 23), date(2026, 1, 26), date(2026, 1, 28), date(2026, 1, 30), date(2026, 2, 3), date(2026, 2, 5), date(2026, 2, 9), date(2026, 2, 11), ] star_secs_chen = [70, 80, 85, 75, 90, 80, 95, 70, 85, 90, 80, 75, 85, 80] for i, (d, s) in enumerate(zip(star_anim_dates_chen, star_secs_chen)): wt = TEST if i < 2 else MFG add(chenbaodan, proj_star, PROD, wt, ContentType.ANIMATION, s, d, f"第{(i//2)+1}集 场景{(i%4)+1}{'(测试)' if wt == TEST else ''}", 3.5) # 谭如平: 12次提交 (1测试 + 11制作) star_anim_dates_tan = [ date(2026, 1, 15), date(2026, 1, 16), date(2026, 1, 19), date(2026, 1, 21), date(2026, 1, 23), date(2026, 1, 27), date(2026, 1, 29), date(2026, 2, 2), date(2026, 2, 4), date(2026, 2, 6), date(2026, 2, 10), date(2026, 2, 12), ] star_secs_tan = [75, 70, 80, 65, 85, 70, 75, 80, 90, 70, 75, 85] for i, (d, s) in enumerate(zip(star_anim_dates_tan, star_secs_tan)): wt = TEST if i < 1 else MFG add(tanruping, proj_star, PROD, wt, ContentType.ANIMATION, s, d, f"第{(i//2)+3}集 镜头{(i%3)+1}{'(测试)' if wt == TEST else ''}", 3) # 郑奕晴: 11次提交 (1测试 + 10制作) star_anim_dates_zheng = [ date(2026, 1, 16), date(2026, 1, 20), date(2026, 1, 22), date(2026, 1, 26), date(2026, 1, 28), date(2026, 2, 2), date(2026, 2, 4), date(2026, 2, 6), date(2026, 2, 10), date(2026, 2, 12), date(2026, 2, 13), ] star_secs_zheng = [85, 75, 90, 80, 85, 95, 70, 80, 75, 90, 85] for i, (d, s) in enumerate(zip(star_anim_dates_zheng, star_secs_zheng)): wt = TEST if i < 1 else MFG add(zhengyiqing, proj_star, PROD, wt, ContentType.ANIMATION, s, d, f"第{(i//2)+5}集 动画{(i%3)+1}{'(测试)' if wt == TEST else ''}", 3.5) # ──────────────────────────────────────────── # AI 短剧原创 S1 (target=2880s, 创建 1/6) # 前期: 1/6 - 1/22 # 制作: 1/23 - now # ──────────────────────────────────────────── # 前期 - 策划案 (1/6-7) add(huangrongying, proj_orig, PRE, PLAN, ContentType.PLANNING, 0, date(2026, 1, 6), "原创S1 世界观策划案", 4) add(huangrongying, proj_orig, PRE, PLAN, ContentType.PLANNING, 0, date(2026, 1, 7), "原创S1 策划案终稿", 3) # 前期 - 剧本 (1/8-14) for i, d in enumerate([date(2026, 1, 8), date(2026, 1, 9), date(2026, 1, 12), date(2026, 1, 13), date(2026, 1, 14)]): add(huangrongying, proj_orig, PRE, PLAN, ContentType.SCRIPT, 0, d, f"原创S1 第{i+1}集剧本", 6) # 前期 - 分镜 (1/15-17) for i, d in enumerate([date(2026, 1, 15), date(2026, 1, 16), date(2026, 1, 17)]): add(daixiaoqian, proj_orig, PRE, PLAN, ContentType.STORYBOARD, 0, d, f"原创S1 第{i*2+1}-{i*2+2}集分镜", 5) # 前期 - 人设图 (1/20-21) add(huangxuewen, proj_orig, PRE, PLAN, ContentType.CHARACTER_DESIGN, 0, date(2026, 1, 20), "原创S1 主角人设图", 5) add(huangxuewen, proj_orig, PRE, PLAN, ContentType.CHARACTER_DESIGN, 0, date(2026, 1, 21), "原创S1 配角人设图", 4) # 前期 - 场景图 (1/22) add(huangxuewen, proj_orig, PRE, PLAN, ContentType.SCENE_DESIGN, 0, date(2026, 1, 22), "原创S1 场景图", 5) # 制作 - 1/23 起 (~16个工作日到今天) # 魏春丽: 6次, 黄秋霞: 5次, 李静: 4次 orig_dates_wei = [date(2026, 1, 23), date(2026, 1, 26), date(2026, 1, 29), date(2026, 2, 3), date(2026, 2, 6), date(2026, 2, 10)] orig_secs_wei = [80, 90, 75, 85, 95, 80] for i, (d, s) in enumerate(zip(orig_dates_wei, orig_secs_wei)): add(weichunli, proj_orig, PROD, MFG, ContentType.ANIMATION, s, d, f"原创S1 第1集 片段{i+1}", 4) orig_dates_huang = [date(2026, 1, 27), date(2026, 1, 30), date(2026, 2, 4), date(2026, 2, 9), date(2026, 2, 12)] orig_secs_huang = [70, 80, 65, 75, 85] for i, (d, s) in enumerate(zip(orig_dates_huang, orig_secs_huang)): add(huangqiuxia, proj_orig, PROD, MFG, ContentType.ANIMATION, s, d, f"原创S1 第2集 动画{i+1}", 3.5) orig_dates_li = [date(2026, 2, 3), date(2026, 2, 5), date(2026, 2, 10), date(2026, 2, 13)] orig_secs_li = [75, 70, 80, 65] for i, (d, s) in enumerate(zip(orig_dates_li, orig_secs_li)): add(lijing, proj_orig, PROD, MFG, ContentType.ANIMATION, s, d, f"原创S1 第3集 片段{i+1}", 3.5) # ──────────────────────────────────────────── # 原创 S1 风格测试 (target=60s, 创建 1/2) # 前期: 1/2-7, 制作(全测试): 1/8-17 # ──────────────────────────────────────────── # 前期 - 策划案 (1/2-3) add(huangrongying, proj_orig_test, PRE, PLAN, ContentType.PLANNING, 0, date(2026, 1, 2), "原创风格测试 策划案", 3) add(huangrongying, proj_orig_test, PRE, PLAN, ContentType.PLANNING, 0, date(2026, 1, 3), "原创风格测试 策划终稿", 2) # 前期 - 人设图 (1/6-7) add(huangxuewen, proj_orig_test, PRE, PLAN, ContentType.CHARACTER_DESIGN, 0, date(2026, 1, 6), "风格测试 人设图初稿", 4) add(huangxuewen, proj_orig_test, PRE, PLAN, ContentType.CHARACTER_DESIGN, 0, date(2026, 1, 7), "风格测试 人设图定稿", 3) # 制作(测试) - 戴伟全部 TEST test_dates = [date(2026, 1, 8), date(2026, 1, 9), date(2026, 1, 12), date(2026, 1, 14), date(2026, 1, 16)] test_secs = [12, 14, 10, 16, 18] test_descs = ["角色动作测试", "场景氛围测试", "打光方案测试", "运镜方案A", "运镜方案B"] for d, s, desc in zip(test_dates, test_secs, test_descs): add(daiwei, proj_orig_test, PROD, TEST, ContentType.ANIMATION, s, d, f"原创风格测试-{desc}", 2) # ──────────────────────────────────────────── # 甲方风格测试 (target=60s, 创建 1/27) # 前期: 1/27 - now (策划案仍未定稿,甲方反复修改) # ──────────────────────────────────────────── # 前期 - 策划案 (1/27起,至今未完成) add(huangrongying, proj_client_test, PRE, PLAN, ContentType.PLANNING, 0, date(2026, 1, 27), "甲方风格策划案 v1", 4) add(huangrongying, proj_client_test, PRE, PLAN, ContentType.PLANNING, 0, date(2026, 1, 30), "甲方风格策划案 v2(反馈修改)", 3) add(huangrongying, proj_client_test, PRE, PLAN, ContentType.PLANNING, 0, date(2026, 2, 5), "甲方风格策划案 v3(二次反馈)", 3) add(huangrongying, proj_client_test, PRE, PLAN, ContentType.PLANNING, 0, date(2026, 2, 11), "甲方风格策划案 v4(三次反馈)", 3) # 前期 - 人设图 (2/3-5, 边做边等策划案定稿) add(huangxuewen, proj_client_test, PRE, PLAN, ContentType.CHARACTER_DESIGN, 0, date(2026, 2, 3), "甲方风格 人设图初稿", 5) add(huangxuewen, proj_client_test, PRE, PLAN, ContentType.CHARACTER_DESIGN, 0, date(2026, 2, 5), "甲方风格 人设图修改", 4) # 少量测试动画 (2/10-12, 用于给甲方展示方向) add(daiwei, proj_client_test, PROD, TEST, ContentType.ANIMATION, 10, date(2026, 2, 10), "甲方风格测试片段1", 2) add(daiwei, proj_client_test, PROD, TEST, ContentType.ANIMATION, 14, date(2026, 2, 12), "甲方风格测试片段2", 2) db.add_all(subs) print(f"[3] Created {len(subs)} submissions") # ══════════════════════════════════════════════════════════════ # 成本数据 # ══════════════════════════════════════════════════════════════ # AI 工具成本 db.add(AIToolCost( tool_name="Midjourney", subscription_period=SubscriptionPeriod.MONTHLY, amount=200, allocation_type=CostAllocationType.TEAM, recorded_by=qiushaohui.id, record_date=today.replace(day=1), )) db.add(AIToolCost( tool_name="Runway", subscription_period=SubscriptionPeriod.MONTHLY, amount=600, allocation_type=CostAllocationType.PROJECT, project_id=proj_star.id, recorded_by=qiushaohui.id, record_date=today.replace(day=1), )) db.add(AIToolCost( tool_name="ChatGPT Plus", subscription_period=SubscriptionPeriod.MONTHLY, amount=150, allocation_type=CostAllocationType.TEAM, recorded_by=qiushaohui.id, record_date=today.replace(day=1), )) print("[4] Created 3 AI tool costs") # 外包成本 db.add(OutsourceCost( project_id=proj_star.id, outsource_type=OutsourceType.ANIMATION, episode_start=10, episode_end=13, amount=20000, recorded_by=qiushaohui.id, record_date=today - timedelta(days=5), )) print("[5] Created 1 outsource cost") # 固定开支 db.add(OverheadCost( cost_type=OverheadCostType.OFFICE_RENT, amount=8000, record_month=today.strftime("%Y-%m"), recorded_by=qiushaohui.id, note="办公室月租", )) db.add(OverheadCost( cost_type=OverheadCostType.UTILITIES, amount=500, record_month=today.strftime("%Y-%m"), recorded_by=qiushaohui.id, note="水电费", )) print("[6] Created 2 overhead costs") db.commit() # ── 打印统计摘要 ── print(f"\n{'='*55}") print("[DONE] Demo data seeded successfully!") print(f" Projects: 5 | Milestones: {len(milestones)}") print(f" Submissions: {len(subs)}") print(f" AI tools: 3 | Outsource: 1 | Overhead: 2") print(f"\n 预期展示效果:") print(f" · 品牌方 TVC 进度>200% → 蓝红双色进度条") print(f" · 星际漫游/TVC/甲方测试有超期里程碑 → 工时损耗") print(f" · 原创风格测试全测试 → 高 waste_rate") print(f" · 5个项目覆盖4种类型, created_at设为过去日期") print(f" · 前期结束后才有制作提交") print(f" · owners/制片无提交") if __name__ == "__main__": seed_demo()