feat: add seed_demo.py with demo data using real team members
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
e751418540
commit
0dbe00a8b4
Binary file not shown.
362
backend/seed_demo.py
Normal file
362
backend/seed_demo.py
Normal file
@ -0,0 +1,362 @@
|
||||
"""补充演示数据 - 只添加项目/提交/成本,不动用户和角色"""
|
||||
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()
|
||||
Loading…
x
Reference in New Issue
Block a user