"""补充演示数据 - 只添加项目/提交/成本,不动用户和角色""" from datetime import date, timedelta from database import SessionLocal, engine 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 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(Project).delete() db.commit() print("[1] Cleared old project data") # 获取真实用户 huhaonan = get_user("huhaonan") # 主管/总导演 dengqingrui = get_user("dengqingrui") # 主管/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") # 组员/动画制作 # ── 项目 ── proj_a = Project( name="星际漫游 第一季", project_type=ProjectType.CLIENT_FORMAL, leader_id=huhaonan.id, current_phase=PhaseGroup.PRODUCTION, episode_duration_minutes=5, episode_count=13, estimated_completion_date=date.today() + timedelta(days=60), contract_amount=100000, ) proj_b = Project( name="品牌方 TVC 宣传片", project_type=ProjectType.CLIENT_FORMAL, leader_id=dengqingrui.id, current_phase=PhaseGroup.PRODUCTION, episode_duration_minutes=1, episode_count=3, estimated_completion_date=date.today() + timedelta(days=20), contract_amount=50000, ) proj_c = Project( name="甲方风格测试", project_type=ProjectType.CLIENT_TEST, leader_id=maruoqing.id, current_phase=PhaseGroup.PRE, episode_duration_minutes=1, episode_count=1, ) proj_d = Project( name="AI 短剧原创 S1", project_type=ProjectType.INTERNAL_ORIGINAL, leader_id=weichunli.id, current_phase=PhaseGroup.PRE, episode_duration_minutes=8, episode_count=6, estimated_completion_date=date.today() + timedelta(days=90), ) db.add_all([proj_a, proj_b, proj_c, proj_d]) db.flush() print("[2] Created 4 projects") # ── 内容提交(模拟近 20 天的数据) ── base = date.today() - timedelta(days=20) subs = [] # --- 项目A:星际漫游 --- # 黄溶莹 - 编剧 - 前期方案 for i in range(6): d = base + timedelta(days=i) subs.append(Submission( user_id=huangrongying.id, project_id=proj_a.id, project_phase=PhaseGroup.PRE, work_type=WorkType.PLAN, content_type=ContentType.DESIGN, total_seconds=0, submit_to=SubmitTo.INTERNAL, description=f"第{i+1}集剧本初稿", submit_date=d, )) # 陈保丹 - 组长 - 动画制作 for i in range(12): d = base + timedelta(days=i + 3) secs = 55 + (i % 3) * 20 wt = WorkType.TEST if i < 2 else WorkType.PRODUCTION subs.append(Submission( user_id=chenbaodan.id, project_id=proj_a.id, project_phase=PhaseGroup.PRODUCTION, work_type=wt, content_type=ContentType.ANIMATION, total_seconds=secs, duration_minutes=secs // 60, duration_seconds=secs % 60, submit_to=SubmitTo.INTERNAL, description=f"第1集场景{i+1}动画", submit_date=d, )) # 代晓倩 - 动画制作 for i in range(10): d = base + timedelta(days=i + 2) secs = 40 + (i % 4) * 15 subs.append(Submission( user_id=daixiaoqian.id, project_id=proj_a.id, project_phase=PhaseGroup.PRODUCTION, work_type=WorkType.PRODUCTION, content_type=ContentType.ANIMATION, total_seconds=secs, duration_minutes=secs // 60, duration_seconds=secs % 60, submit_to=SubmitTo.LEADER, description=f"第2集片段{i+1}", submit_date=d, )) # 谭如平 - 动画制作 for i in range(8): d = base + timedelta(days=i + 4) secs = 35 + (i % 3) * 25 wt = WorkType.TEST if i == 0 else WorkType.PRODUCTION subs.append(Submission( user_id=tanruping.id, project_id=proj_a.id, project_phase=PhaseGroup.PRODUCTION, work_type=wt, content_type=ContentType.ANIMATION, total_seconds=secs, duration_minutes=secs // 60, duration_seconds=secs % 60, submit_to=SubmitTo.LEADER, description=f"第3集镜头{i+1}", submit_date=d, )) # 郑奕晴 - 动画制作 for i in range(9): d = base + timedelta(days=i + 3) secs = 45 + (i % 2) * 30 subs.append(Submission( user_id=zhengyiqing.id, project_id=proj_a.id, project_phase=PhaseGroup.PRODUCTION, work_type=WorkType.PRODUCTION, content_type=ContentType.ANIMATION, total_seconds=secs, duration_minutes=secs // 60, duration_seconds=secs % 60, submit_to=SubmitTo.LEADER, description=f"第4集场景动画{i+1}", submit_date=d, )) # 黄雪雯 - 动画制作 for i in range(7): d = base + timedelta(days=i + 5) secs = 30 + (i % 3) * 20 subs.append(Submission( user_id=huangxuewen.id, project_id=proj_a.id, project_phase=PhaseGroup.PRODUCTION, work_type=WorkType.PRODUCTION, content_type=ContentType.ANIMATION, total_seconds=secs, duration_minutes=secs // 60, duration_seconds=secs % 60, submit_to=SubmitTo.LEADER, description=f"第5集片段{i+1}", submit_date=d, )) # 潘梓彦 - 剪辑 - 后期 for i in range(4): d = base + timedelta(days=i + 14) subs.append(Submission( user_id=panziyan.id, project_id=proj_a.id, project_phase=PhaseGroup.POST, work_type=WorkType.PRODUCTION, content_type=ContentType.EDITING, total_seconds=0, submit_to=SubmitTo.PRODUCER, description=f"第{i+1}集粗剪", submit_date=d, )) # 贾浩正 - 剪辑 for i in range(3): d = base + timedelta(days=i + 15) subs.append(Submission( user_id=jiahaozheng.id, project_id=proj_a.id, project_phase=PhaseGroup.POST, work_type=WorkType.PRODUCTION, content_type=ContentType.EDITING, total_seconds=0, submit_to=SubmitTo.PRODUCER, description=f"第{i+5}集粗剪", submit_date=d, )) # --- 项目B:品牌方 TVC --- # 马若情 - AI导演 for i in range(6): d = base + timedelta(days=i + 5) secs = 20 + i * 10 subs.append(Submission( user_id=maruoqing.id, project_id=proj_b.id, project_phase=PhaseGroup.PRODUCTION, work_type=WorkType.PRODUCTION, content_type=ContentType.ANIMATION, total_seconds=secs, duration_minutes=secs // 60, duration_seconds=secs % 60, submit_to=SubmitTo.INTERNAL, description=f"TVC 片段{i+1}", submit_date=d, )) # 刘诗琪 - 动画制作 for i in range(5): d = base + timedelta(days=i + 7) secs = 15 + (i % 3) * 10 subs.append(Submission( user_id=liushiqi.id, project_id=proj_b.id, project_phase=PhaseGroup.PRODUCTION, work_type=WorkType.PRODUCTION, content_type=ContentType.ANIMATION, total_seconds=secs, duration_minutes=secs // 60, duration_seconds=secs % 60, submit_to=SubmitTo.LEADER, description=f"TVC 补充镜头{i+1}", submit_date=d, )) # 王炎森 - 剪辑 for i in range(3): d = base + timedelta(days=i + 13) subs.append(Submission( user_id=wangyansen.id, project_id=proj_b.id, project_phase=PhaseGroup.POST, work_type=WorkType.PRODUCTION, content_type=ContentType.EDITING, total_seconds=0, submit_to=SubmitTo.PRODUCER, description=f"TVC 第{i+1}版剪辑", submit_date=d, )) # --- 项目C:甲方风格测试 --- for i in range(3): d = base + timedelta(days=i + 1) subs.append(Submission( user_id=huangrongying.id, project_id=proj_c.id, project_phase=PhaseGroup.PRE, work_type=WorkType.PLAN, content_type=ContentType.DESIGN, total_seconds=0, submit_to=SubmitTo.INTERNAL, description=f"风格方案{i+1}", submit_date=d, )) for i in range(4): d = base + timedelta(days=i + 4) secs = 10 + i * 5 subs.append(Submission( user_id=daiwei.id, project_id=proj_c.id, project_phase=PhaseGroup.PRODUCTION, work_type=WorkType.TEST, content_type=ContentType.ANIMATION, total_seconds=secs, duration_minutes=secs // 60, duration_seconds=secs % 60, submit_to=SubmitTo.INTERNAL, description=f"风格测试片段{i+1}", submit_date=d, )) # --- 项目D:AI 短剧原创 --- for i in range(5): d = base + timedelta(days=i) subs.append(Submission( user_id=huangrongying.id, project_id=proj_d.id, project_phase=PhaseGroup.PRE, work_type=WorkType.PLAN, content_type=ContentType.DESIGN, total_seconds=0, submit_to=SubmitTo.INTERNAL, description=f"原创剧本第{i+1}集大纲", submit_date=d, )) for i in range(6): d = base + timedelta(days=i + 8) secs = 60 + (i % 3) * 25 subs.append(Submission( user_id=weichunli.id, project_id=proj_d.id, project_phase=PhaseGroup.PRODUCTION, work_type=WorkType.PRODUCTION, content_type=ContentType.ANIMATION, total_seconds=secs, duration_minutes=secs // 60, duration_seconds=secs % 60, submit_to=SubmitTo.INTERNAL, description=f"原创第1集片段{i+1}", submit_date=d, )) for i in range(5): d = base + timedelta(days=i + 10) secs = 50 + (i % 2) * 35 subs.append(Submission( user_id=huangqiuxia.id, project_id=proj_d.id, project_phase=PhaseGroup.PRODUCTION, work_type=WorkType.PRODUCTION, content_type=ContentType.ANIMATION, total_seconds=secs, duration_minutes=secs // 60, duration_seconds=secs % 60, submit_to=SubmitTo.LEADER, description=f"原创第2集动画{i+1}", submit_date=d, )) for i in range(4): d = base + timedelta(days=i + 12) secs = 45 + i * 15 subs.append(Submission( user_id=lijing.id, project_id=proj_d.id, project_phase=PhaseGroup.PRODUCTION, work_type=WorkType.PRODUCTION, content_type=ContentType.ANIMATION, total_seconds=secs, duration_minutes=secs // 60, duration_seconds=secs % 60, submit_to=SubmitTo.LEADER, description=f"原创第3集片段{i+1}", submit_date=d, )) for i in range(3): d = base + timedelta(days=i + 14) secs = 40 + i * 20 subs.append(Submission( user_id=yemeilian.id, project_id=proj_d.id, project_phase=PhaseGroup.PRODUCTION, work_type=WorkType.PRODUCTION, content_type=ContentType.ANIMATION, total_seconds=secs, duration_minutes=secs // 60, duration_seconds=secs % 60, submit_to=SubmitTo.LEADER, description=f"原创第4集动画{i+1}", submit_date=d, )) for i in range(3): d = base + timedelta(days=i + 15) secs = 55 + (i % 2) * 20 subs.append(Submission( user_id=chenxuanying.id, project_id=proj_d.id, project_phase=PhaseGroup.PRODUCTION, work_type=WorkType.PRODUCTION, content_type=ContentType.ANIMATION, total_seconds=secs, duration_minutes=secs // 60, duration_seconds=secs % 60, submit_to=SubmitTo.LEADER, description=f"原创第5集场景{i+1}", submit_date=d, )) 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=date.today().replace(day=1), )) db.add(AIToolCost( tool_name="Runway", subscription_period=SubscriptionPeriod.MONTHLY, amount=600, allocation_type=CostAllocationType.PROJECT, project_id=proj_a.id, recorded_by=qiushaohui.id, record_date=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=date.today().replace(day=1), )) print("[4] Created 3 AI tool costs") # ── 外包成本 ── db.add(OutsourceCost( project_id=proj_a.id, outsource_type=OutsourceType.ANIMATION, episode_start=10, episode_end=13, amount=20000, recorded_by=qiushaohui.id, record_date=date.today() - timedelta(days=5), )) print("[5] Created 1 outsource cost") # ── 固定开支 ── db.add(OverheadCost( cost_type=OverheadCostType.OFFICE_RENT, amount=8000, record_month=date.today().strftime("%Y-%m"), recorded_by=qiushaohui.id, note="办公室月租", )) db.add(OverheadCost( cost_type=OverheadCostType.UTILITIES, amount=500, record_month=date.today().strftime("%Y-%m"), recorded_by=qiushaohui.id, note="水电费", )) print("[6] Created 2 overhead costs") db.commit() print("\n[DONE] Demo data seeded successfully!") print(f" Projects: 4") print(f" Submissions: {len(subs)}") print(f" AI tools: 3, Outsource: 1, Overhead: 2") if __name__ == "__main__": seed_demo()