- 仪表盘双色进度条(超100%蓝红分段)、工时损耗展示、chart tooltip增强 - 修复 Submissions.vue 延期原因字段始终显示的Bug - 修复 SPA catch-all 路由拦截 API 请求(去尾部斜杠) - seed_demo.py 重写:5项目/4类型/32里程碑/124提交,真实时间线 - 三阶段损耗计算(前期工时/制作秒数/后期工时) - ContentType 扩展为11种,里程碑增强(预估天数/开始日期/超期检测) - 更新 PRD 和项目总结文档 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
423 lines
17 KiB
Markdown
423 lines
17 KiB
Markdown
# AirLabs Project 项目总结文档
|
||
|
||
> 内容组 · 项目制周期 / 成本 / 产出管理系统
|
||
> 更新日期:2026-02-14
|
||
|
||
---
|
||
|
||
## 1. 项目概述
|
||
|
||
### 1.1 定位
|
||
|
||
服务于**以 AI 动画/视觉内容为核心产出的内容团队**(约 30 人以内)的内部管理系统。
|
||
|
||
**核心价值**:以项目为核心,以内容提交为最小记录单位,自动汇总产出、进度、成本与损耗,支持项目完成后统一结算。
|
||
|
||
### 1.2 解决的核心问题
|
||
|
||
- 项目**实际投入成本**不可见
|
||
- 实际产出是否匹配项目目标
|
||
- 测试与损耗占比无法量化
|
||
- 项目超期难以追踪
|
||
- 项目结束后是否盈利
|
||
|
||
### 1.3 覆盖范围(V1)
|
||
|
||
- 内容组、内容类项目、动画/视觉内容生产
|
||
- PC 端 Web 应用(预留响应式,V2 适配移动端)
|
||
- **不包含**:产品研发周期、精细工时、人事绩效、审批验收、移动端专属适配
|
||
|
||
---
|
||
|
||
## 2. 技术架构
|
||
|
||
| 层级 | 技术选型 | 说明 |
|
||
|------|----------|------|
|
||
| 前端 | Vue 3 + Element Plus + Vite | 后台管理 UI |
|
||
| 后端 | Python FastAPI | 高性能 API |
|
||
| 数据库 | MySQL 8.0(阿里云 RDS) | 生产环境;本地开发可回退 SQLite |
|
||
| 图表 | ECharts | 仪表盘可视化 |
|
||
| 认证 | JWT Token | 登录鉴权与权限控制 |
|
||
|
||
### 2.1 部署
|
||
|
||
- **CI/CD**:Gitea Actions 自动构建
|
||
- **镜像**:Docker 构建,推送到华为云 SWR
|
||
- **运行**:K3s 集群,通过 Ingress 暴露服务
|
||
- **前端**:静态构建后由后端统一托管(`/` 路径返回 index.html)
|
||
|
||
### 2.2 目录结构
|
||
|
||
```
|
||
AirLabs Project/
|
||
├── backend/ # FastAPI 后端
|
||
│ ├── main.py # 入口、静态文件托管、角色初始化
|
||
│ ├── models.py # ORM 模型、枚举、权限定义
|
||
│ ├── calculations.py # 成本分摊、三阶段损耗、效率、结算计算引擎
|
||
│ ├── config.py # 配置
|
||
│ ├── database.py # SQLAlchemy 引擎与会话
|
||
│ ├── auth.py # 密码哈希、JWT
|
||
│ ├── schemas.py # Pydantic 模型
|
||
│ └── routers/ # API 路由
|
||
│ ├── auth.py # 登录、me
|
||
│ ├── users.py # 用户 CRUD
|
||
│ ├── projects.py # 项目 CRUD、完成、结算、效率
|
||
│ ├── submissions.py# 内容提交 CRUD、历史
|
||
│ ├── costs.py # AI 工具、外包、人力调整、固定开支
|
||
│ ├── dashboard.py # 仪表盘
|
||
│ └── roles.py # 角色、权限
|
||
├── frontend/ # Vue 3 前端
|
||
│ └── src/
|
||
│ ├── views/ # 页面:Dashboard, Projects, ProjectDetail, Submissions,
|
||
│ │ # Costs, Users, MemberDetail, Roles, Settlement, Login
|
||
│ ├── api/index.js # 接口封装
|
||
│ ├── stores/auth.js# 用户状态
|
||
│ └── router/ # 路由与权限守卫
|
||
├── k8s/ # K8s manifests
|
||
├── .gitea/workflows/ # 部署流程
|
||
└── 人员清单.md # 团队成员与薪资
|
||
```
|
||
|
||
---
|
||
|
||
## 3. 核心数据模型
|
||
|
||
### 3.1 项目(Project)
|
||
|
||
| 字段 | 说明 |
|
||
|------|------|
|
||
| name | 项目名称 |
|
||
| project_type | 客户正式/客户测试/内部原创/内部测试 |
|
||
| status | **制作中 / 已完成 / 废弃** |
|
||
| leader_id | 负责人 |
|
||
| current_phase | 前期/制作/后期 |
|
||
| episode_duration_minutes | 单集正片时长(分钟) |
|
||
| episode_count | 集数 |
|
||
| target_total_seconds | 目标总秒数(计算属性 = 单集×集数×60) |
|
||
| estimated_completion_date | 预估完成日期 |
|
||
| actual_completion_date | 实际完成日期 |
|
||
| contract_amount | 回款金额(客户正式项目) |
|
||
|
||
### 3.2 用户(User)
|
||
|
||
- 姓名、用户名、所属阶段组(前期/制作/后期)
|
||
- 角色、月薪、社保、奖金
|
||
- **日成本** = (月薪+奖金+社保) ÷ 22 个工作日
|
||
|
||
### 3.3 内容提交(Submission)
|
||
|
||
- 提交人、所属项目、项目阶段、工作类型(制作/测试/方案)
|
||
- 内容制作类型(11 种,按阶段分组)
|
||
- 前期:策划案 / 剧本 / 分镜 / 人设图 / 场景图
|
||
- 制作:动画制作
|
||
- 后期:配音 / 音效 / 修补镜头 / 剪辑
|
||
- 其他
|
||
- 产出时长(分钟/秒,换算为 total_seconds)
|
||
- 投入时长(小时,可选)
|
||
- 提交对象(组长/制片/内部/外部)
|
||
- 提交日期
|
||
- **milestone_id**(系统自动关联:根据内容类型匹配同名里程碑)
|
||
- **delay_reason**(延期原因:里程碑超期时必填)
|
||
|
||
### 3.4 项目里程碑(ProjectMilestone)
|
||
|
||
- 所属项目、名称、所属阶段(前期/后期)
|
||
- is_completed(是否完成)、completed_at(完成日期)
|
||
- **estimated_days**(预估工作日)
|
||
- **start_date**(开始日期)
|
||
- actual_days(计算值 = 开始到完成/今天的工作日数,排除周末)
|
||
- is_overdue(计算值 = 实际 > 预估)
|
||
- 默认里程碑:前期 5 个(策划案/剧本/分镜/人设图/场景图)+ 后期 5 个(配音/音效/修补镜头/剪辑/杂项)
|
||
|
||
---
|
||
|
||
## 4. 业务逻辑
|
||
|
||
### 4.1 成本结构
|
||
|
||
| 成本类型 | 计算方式 |
|
||
|----------|----------|
|
||
| **人力成本** | 按提交自动分摊:有秒数按秒数比例,无秒数按条数比例;支持 CostOverride 手动调整 |
|
||
| **AI 工具成本** | 指定项目 / 内容组整体(按产出秒数分摊)/ 手动分摊 |
|
||
| **外包成本** | 按项目直接归属 |
|
||
| **固定开支** | 办公室租金、水电费,按项目产出秒数比例分摊 |
|
||
|
||
### 4.2 损耗(Waste)与亏损(Loss)
|
||
|
||
**概念区分:**
|
||
|
||
- **损耗**:生产效率指标,盈利项目也有
|
||
- **亏损**:财务结果(总成本 > 回款),仅客户正式项目
|
||
|
||
**三阶段损耗计算体系:**
|
||
|
||
| 阶段 | 计算方式 | 损耗指标 |
|
||
|------|----------|----------|
|
||
| **前期** | 工时制 | 里程碑超期天数 × 8h |
|
||
| **制作** | 秒数制 | 测试损耗 + 超产损耗 |
|
||
| **后期** | 工时制 | 里程碑超期天数 × 8h |
|
||
|
||
- **前期损耗**:遍历前期里程碑(策划案/剧本/分镜/人设图/场景图),有预估工期且已完成/超期的,超出天数 × 8h = 损耗工时
|
||
- **制作损耗**:测试损耗(work_type=测试且phase=制作的秒数)+ 超产损耗(制作产出+修补镜头 − 目标秒数的超出部分)
|
||
- **后期损耗**:剪辑等里程碑按工时计算;修补镜头秒数已计入制作损耗;配音/音效不计损耗
|
||
- **废弃项目**:全部产出直接记为损耗,损耗率 100%
|
||
|
||
**秒数损耗率** = (测试损耗 + 超产损耗) ÷ 目标秒数 × 100%
|
||
**工时损耗** = 前期超期工时 + 后期超期工时
|
||
|
||
### 4.3 团队效率(人均基准对比法)
|
||
|
||
- 人均基准 = 目标秒数 ÷ 参与制作人数
|
||
- 超出比例 = (个人提交 − 人均基准) ÷ 人均基准 × 100%
|
||
|
||
### 4.4 进度计算
|
||
|
||
- 完成百分比 = 当前有秒数提交的累计秒数 ÷ 目标总秒数 × 100%
|
||
- 仅统计有产出秒数的提交(制作组 + 后期补拍)
|
||
|
||
---
|
||
|
||
## 5. 权限体系
|
||
|
||
| 角色 | 可见范围 | 典型权限 |
|
||
|------|----------|----------|
|
||
| 超级管理员 | 全量 | 全部 |
|
||
| 主管 | 所有项目 | dashboard, project CRUD+complete, submission, cost, settlement, efficiency |
|
||
| 组长 | 所负责项目 | project view+create, submission, cost, efficiency |
|
||
| 成员 | 本人提交、项目公开信息 | project view, submission |
|
||
|
||
**权限标识**:`dashboard:view`, `project:view/create/edit/delete/complete`, `submission:view/create`, `cost:view/create/delete`, `user:view/manage`, `role:manage`, `settlement:view`, `efficiency:view`
|
||
|
||
---
|
||
|
||
## 6. 前端页面与路由
|
||
|
||
| 路径 | 页面 | 权限 |
|
||
|------|------|------|
|
||
| /login | 登录 | 公开 |
|
||
| /dashboard | 仪表盘 | dashboard:view |
|
||
| /projects | 项目列表 | project:view |
|
||
| /projects/:id | 项目详情、提交、损耗、进度 | project:view |
|
||
| /submissions | 提交记录 | submission:view |
|
||
| /costs | 成本管理(AI/外包/固定开支/人力调整) | cost:view |
|
||
| /users | 用户管理 | user:manage |
|
||
| /users/:id/detail | 成员详情 | user:view |
|
||
| /roles | 角色管理 | role:manage |
|
||
| /settlement/:id | 项目结算 | settlement:view |
|
||
|
||
**项目详情页操作**:编辑、确认完成(制作中→已完成)、标记废弃(制作中→废弃)、查看结算(已完成)
|
||
|
||
---
|
||
|
||
## 7. 废弃项目特性(近期新增)
|
||
|
||
- **状态**:`ProjectStatus.ABANDONED = "废弃"`
|
||
- **含义**:项目中途停止,不再继续制作
|
||
- **损耗**:全部产出记为损耗,损耗率 100%
|
||
- **操作**:
|
||
- 项目详情页「标记废弃」按钮(仅制作中可见)
|
||
- 编辑表单中状态下拉增加「废弃」选项
|
||
- **仪表盘**:废弃项目纳入总损耗统计、成本构成统计、损耗排行
|
||
|
||
---
|
||
|
||
## 8. 人员与团队(来自 人员清单.md)
|
||
|
||
- 22 人:主管 3、组长 4、组员 15、Owner 2
|
||
- 职位涵盖:总导演、AI 导演、制片、动画制作、剪辑、编剧等
|
||
- 薪资与社保已录入,用于人力成本计算
|
||
|
||
---
|
||
|
||
## 9. PRD 与实现对照
|
||
|
||
| PRD 要求 | 实现情况 |
|
||
|----------|----------|
|
||
| 项目管理(创建/编辑/状态/目标) | ✅ |
|
||
| 内容提交表单 | ✅ |
|
||
| 项目详情(进度、提交、损耗) | ✅ |
|
||
| 人力/AI/外包/固定开支成本 | ✅ |
|
||
| 仪表盘 | ✅ |
|
||
| 项目结算、盈亏 | ✅ |
|
||
| 废弃项目 | ✅(PRD 未写,实际补充) |
|
||
| 登录与 4 级权限 | ✅ |
|
||
| 历史修改记录(版本追溯、修改原因) | ⚠️ 部分(有 SubmissionHistory 表与 history 接口,前端展示待完善) |
|
||
| 用户管理(新增/编辑/薪资) | ✅ |
|
||
|
||
---
|
||
|
||
## 10. AI 能力模块(V2 新增)
|
||
|
||
### 10.1 技术架构
|
||
|
||
```
|
||
FastAPI 后端
|
||
├── services/ai_service.py # 豆包模型调用(OpenAI 兼容协议)
|
||
├── services/report_service.py # 报告数据汇总 + AI 摘要
|
||
├── services/feishu_service.py # 飞书自建应用消息推送
|
||
├── services/scheduler_service.py # APScheduler 定时任务
|
||
└── routers/reports.py # 手动触发报告 API
|
||
↓ ↓
|
||
豆包 AI (ARK) 飞书开放平台
|
||
生成报告摘要 私聊推送给管理员
|
||
```
|
||
|
||
### 10.2 功能清单
|
||
|
||
| 功能 | 说明 |
|
||
|------|------|
|
||
| 自动日报 | 每天 20:00,今日提交、项目进展、风险提醒 |
|
||
| 自动周报 | 每周五 20:00,项目进展、团队产出、成本概览 |
|
||
| 自动月报 | 每月1日 10:00,上月完整数据、成本明细、盈亏 |
|
||
| 项目风险预警 | 仪表盘展示,规则引擎检测超期/进度/损耗/停滞 |
|
||
| 手动触发 | POST /api/reports/{daily,weekly,monthly},调试用 |
|
||
| 报告预览 | POST /api/reports/preview/{type},不推送仅预览 |
|
||
|
||
### 10.3 新增依赖
|
||
|
||
| 包 | 用途 |
|
||
|----|------|
|
||
| openai | 豆包 AI 调用(兼容协议) |
|
||
| httpx | 飞书 API 异步请求 |
|
||
| apscheduler | 定时任务调度 |
|
||
| python-dotenv | .env 配置文件 |
|
||
|
||
### 10.4 配置项
|
||
|
||
通过 `backend/.env` 配置:
|
||
- `ARK_API_KEY` — 豆包 API Key
|
||
- `ARK_MODEL` — 模型名称
|
||
- `FEISHU_APP_ID` / `FEISHU_APP_SECRET` — 飞书应用凭证
|
||
- `REPORT_RECEIVERS` — 接收人手机号(逗号分隔)
|
||
|
||
---
|
||
|
||
## 11. PRD 与实现对照(更新)
|
||
|
||
| PRD 要求 | 实现情况 |
|
||
|----------|----------|
|
||
| 项目管理(创建/编辑/状态/目标) | ✅ |
|
||
| 内容提交表单 | ✅ |
|
||
| 项目详情(进度、提交、损耗) | ✅ |
|
||
| 人力/AI/外包/固定开支成本 | ✅ |
|
||
| 仪表盘 | ✅ |
|
||
| 项目结算、盈亏 | ✅ |
|
||
| 废弃项目 | ✅(PRD 未写,实际补充) |
|
||
| 登录与 4 级权限 | ✅ |
|
||
| 历史修改记录 | ⚠️ 部分 |
|
||
| 用户管理 | ✅ |
|
||
| AI 自动报告 + 飞书推送 | ✅ V2 新增 |
|
||
| 项目风险预警 | ✅ V2 新增 |
|
||
| 三阶段损耗计算(前期工时/制作秒数/后期工时) | ✅ V1.1 新增 |
|
||
| 内容类型细化(4→11 种) | ✅ V1.1 新增 |
|
||
| 里程碑管理(预估/实际天数、超期检测) | ✅ V1.1 新增 |
|
||
| 提交自动关联里程碑 + 超期延期原因 | ✅ V1.1 新增 |
|
||
| 仪表盘双色进度条(超产可视化) | ✅ V2.1 新增 |
|
||
| 工时损耗展示(仪表盘+项目进度+tooltip) | ✅ V2.1 新增 |
|
||
| 提交页延期原因条件显示修复 | ✅ V2.1 修复 |
|
||
| 后端 SPA 路由与 API 路由冲突修复 | ✅ V2.1 修复 |
|
||
|
||
---
|
||
|
||
## 12. V1.1 三阶段损耗计算体系(近期新增)
|
||
|
||
### 12.1 背景
|
||
|
||
V1 损耗计算仅用「产出秒数 vs 目标秒数」一种方式,无法覆盖前期(策划/人设等)和后期(剪辑等)无法用秒数衡量的工作,导致这些阶段的损耗无法量化。
|
||
|
||
### 12.2 改动概要
|
||
|
||
| 改动项 | 说明 |
|
||
|--------|------|
|
||
| **内容类型扩展** | 从 4 种(内容制作/设定策划/剪辑后期/其他)扩展为 11 种,按前期/制作/后期分组 |
|
||
| **里程碑增强** | 新增 estimated_days(预估天数)、start_date(开始日期),系统自动计算 actual_days 和 is_overdue |
|
||
| **三阶段损耗** | 前期/后期按工时(天数超期 × 8h),制作保持秒数制(测试 + 超产) |
|
||
| **提交关联里程碑** | 提交时根据 content_type 自动匹配同名里程碑,超期时必须填写延期原因 |
|
||
| **数据库迁移** | 启动时幂等 ALTER TABLE 添加 4 个新字段 + 旧 content_type 值映射 |
|
||
|
||
### 12.3 涉及文件
|
||
|
||
**后端**:
|
||
- `models.py` — ContentType 枚举扩展、ProjectMilestone 新字段、Submission 新字段、CONTENT_PHASE_MAP
|
||
- `schemas.py` — MilestoneOut/Create/Update、SubmissionCreate/Out 新字段、ProjectOut 新增 waste_hours
|
||
- `calculations.py` — 重写 calc_waste_for_project() 三阶段逻辑,新增 _working_days_between()
|
||
- `routers/projects.py` — enrich_project() 用集中损耗函数、_build_milestone_out()、PUT /milestones/{id}
|
||
- `routers/submissions.py` — 自动关联里程碑、超期校验 delay_reason
|
||
- `routers/dashboard.py` — 损耗汇总兼容 waste_hours
|
||
- `main.py` — 启动迁移(ALTER TABLE + ENUM 扩展 + 旧值映射)
|
||
|
||
**前端**:
|
||
- `views/Submissions.vue` — 内容类型分组下拉、自动设置阶段、延期原因字段
|
||
- `views/ProjectDetail.vue` — 里程碑显示预估/实际天数和超期标记、编辑弹窗、损耗拆分展示
|
||
- `views/Settlement.vue` — 损耗分析改为三列分阶段展示
|
||
- `api/index.js` — 新增 updateMilestone 方法
|
||
|
||
### 12.4 旧数据兼容
|
||
|
||
- 旧 content_type 自动迁移:`内容制作→动画制作`、`设定策划→策划案`、`剪辑后期→剪辑`
|
||
- 已有项目自动补充"剪辑"里程碑
|
||
- 无 estimated_days 的里程碑不参与损耗计算
|
||
|
||
---
|
||
|
||
## 13. V2.1 前端增强与路由修复(2026-02-14)
|
||
|
||
### 13.1 仪表盘双色进度条
|
||
|
||
进度超过 100% 的项目(如品牌方 TVC 258.3%),进度条分为蓝色(目标内)和红色(超出部分),直观反映超产程度。百分比数字在超 100% 时变为红色。
|
||
|
||
### 13.2 工时损耗展示
|
||
|
||
- **总损耗卡片**:在总损耗率下方显示工时损耗(如 `工时损耗 192h`)
|
||
- **项目进度条下方**:每个项目显示损耗率 + 工时损耗(如 `损耗 158.3% · 工时48h`)
|
||
- **损耗排行图表 tooltip**:鼠标悬浮显示秒数损耗和工时损耗
|
||
|
||
### 13.3 提交页延期原因修复
|
||
|
||
修复 `Submissions.vue` 中延期原因字段始终显示的 Bug(原条件 `!== undefined` 恒为 true)。改为根据所选项目+内容类型匹配里程碑,仅在里程碑超期时显示红色标签 + 警告 + 必填延期原因。
|
||
|
||
### 13.4 后端路由修复
|
||
|
||
- **catch-all SPA 路由拦截 API 请求**:`main.py` 的 `/{full_path:path}` 会匹配 `/api/*` 路径(因 API 路由注册时带尾部斜杠 `/api/projects/`,而请求不带斜杠 `/api/projects`)。修复:catch-all 对 `api/` 开头路径返回 404 + 所有路由改为无尾部斜杠(`@router.get("")`)+ 前端 API 调用同步去掉尾部斜杠。
|
||
|
||
### 13.5 演示数据(seed_demo.py)
|
||
|
||
重写种子数据,覆盖 5 个项目、4 种类型、32 个里程碑、124 条提交。所有 `created_at` 设为过去日期,前期结束后才有制作提交,owners/制片不提交,生产速率参照真实情况(60-120s/人/天)。
|
||
|
||
### 13.6 涉及文件
|
||
|
||
**后端**:
|
||
- `main.py` — 导入 HTTPException,catch-all 增加 API 路径判断
|
||
- `routers/projects.py` — `@router.get("")` 去尾部斜杠
|
||
- `routers/users.py` — 同上
|
||
- `routers/submissions.py` — 同上
|
||
- `routers/roles.py` — 同上
|
||
- `routers/dashboard.py` — project_summaries 补充 `waste_hours` 字段
|
||
- `seed_demo.py` — 全面重写
|
||
|
||
**前端**:
|
||
- `api/index.js` — 所有 list/create 请求去尾部斜杠
|
||
- `views/Dashboard.vue` — 双色进度条、工时损耗展示、chart tooltip 增强
|
||
- `views/Submissions.vue` — 延期原因计算属性 + 前端校验
|
||
|
||
---
|
||
|
||
## 14. 已知待办 / 待完善
|
||
|
||
- **历史修改记录**:后端已有 `SubmissionHistory`,前端完整展示与 diff 对比可完善
|
||
- **数据导出**:PRD 提到 V2 支持 Excel/PDF,当前未实现
|
||
- **移动端适配**:V2 计划
|
||
- **数据库迁移工具**:当前用 `main.py` startup 里的幂等 ALTER TABLE,大规模重构时建议引入 Alembic
|
||
- **AI 智能问答**:V3 计划,前端聊天页面 + 自然语言查询
|
||
- **按权限分级推送**:V3 计划,不同角色收到不同报告内容
|
||
|
||
---
|
||
|
||
## 15. 默认账号
|
||
|
||
- 首次启动自动创建:`admin` / `admin123`(超级管理员)
|
||
|
||
---
|
||
|
||
*本文档用于项目交接、复盘与后续迭代参考。*
|