|
|
@@ -0,0 +1,396 @@
|
|
|
+# 项目阶段截止时间功能实施指南
|
|
|
+
|
|
|
+## ✅ 已完成的实施内容
|
|
|
+
|
|
|
+### 1. 前端类型定义 ✅
|
|
|
+
|
|
|
+**文件位置**: `src/app/models/project-phase.model.ts`
|
|
|
+
|
|
|
+包含内容:
|
|
|
+- `PhaseInfo` - 单个阶段信息接口
|
|
|
+- `PhaseDeadlines` - 阶段截止时间集合接口
|
|
|
+- `ProjectData` - Project.data字段类型定义
|
|
|
+- `PHASE_INFO` - 阶段常量配置(建模/软装/渲染/后期)
|
|
|
+- `PHASE_STATUS_INFO` - 阶段状态信息
|
|
|
+- `PHASE_PRIORITY_INFO` - 优先级信息
|
|
|
+- 工具函数:
|
|
|
+ - `generateDefaultPhaseDeadlines()` - 生成默认阶段截止时间
|
|
|
+ - `isPhaseDelayed()` - 检查阶段是否延期
|
|
|
+ - `getPhaseDaysRemaining()` - 获取阶段剩余天数
|
|
|
+ - `getPhaseProgress()` - 获取阶段进度百分比
|
|
|
+
|
|
|
+### 2. 项目时间轴组件更新 ✅
|
|
|
+
|
|
|
+**文件位置**:
|
|
|
+- `src/app/pages/team-leader/project-timeline/project-timeline.ts`
|
|
|
+- `src/app/pages/team-leader/project-timeline/project-timeline.html`
|
|
|
+
|
|
|
+更新内容:
|
|
|
+- ✅ 导入阶段类型定义和工具函数
|
|
|
+- ✅ 扩展 `ProjectTimeline` 接口添加 `phaseDeadlines` 字段
|
|
|
+- ✅ 添加 `TimelineEvent` 接口支持多种事件类型
|
|
|
+- ✅ 新增 `getProjectEvents()` 方法统一获取所有事件(含阶段截止)
|
|
|
+- ✅ 新增阶段相关工具方法:
|
|
|
+ - `getPhaseLabel()` - 获取阶段标签
|
|
|
+ - `getPhaseIcon()` - 获取阶段图标
|
|
|
+ - `getPhaseColor()` - 获取阶段颜色
|
|
|
+- ✅ 模板更新:
|
|
|
+ - 使用统一的事件标记循环显示所有事件
|
|
|
+ - 图例添加阶段截止时间说明(🎨建模/🪑软装/🖼️渲染/✨后期)
|
|
|
+
|
|
|
+### 3. Dashboard组件数据传递 ✅
|
|
|
+
|
|
|
+**文件位置**: `src/app/pages/team-leader/dashboard/dashboard.ts`
|
|
|
+
|
|
|
+更新内容:
|
|
|
+- ✅ `convertToProjectTimeline()` 方法中读取 `project.data.phaseDeadlines`
|
|
|
+- ✅ 将阶段截止时间数据传递给时间轴组件
|
|
|
+
|
|
|
+### 4. Cloud Code数据迁移脚本 ✅
|
|
|
+
|
|
|
+**文件位置**: `cloud/jobs/migrate-project-phase-deadlines.js`
|
|
|
+
|
|
|
+功能:
|
|
|
+- ✅ `migrateProjectPhaseDeadlines` - 批量为现有项目添加阶段截止时间
|
|
|
+ - 支持干跑模式(`dryRun: true`)
|
|
|
+ - 支持批量处理(`batchSize: 100`)
|
|
|
+ - 根据项目deadline反推各阶段时间
|
|
|
+ - 详细的进度和统计信息
|
|
|
+- ✅ `testProjectPhaseDeadlines` - 测试单个项目的阶段时间生成
|
|
|
+
|
|
|
+### 5. Cloud Code工具函数 ✅
|
|
|
+
|
|
|
+**文件位置**: `cloud/utils/project-phase-utils.js`
|
|
|
+
|
|
|
+功能:
|
|
|
+- ✅ `generatePhaseDeadlines()` - 生成阶段截止时间
|
|
|
+- ✅ `getCompanyPhaseDurations()` - 获取公司级默认工期配置
|
|
|
+- ✅ `updatePhaseStatus()` - 更新阶段状态
|
|
|
+- ✅ `getCurrentPhase()` - 获取当前阶段
|
|
|
+- ✅ `isPhaseDelayed()` - 检查是否延期
|
|
|
+- ✅ `getPhaseDaysRemaining()` - 获取剩余天数
|
|
|
+
|
|
|
+Cloud Function:
|
|
|
+- ✅ `generateProjectPhaseDeadlines` - 生成阶段截止时间
|
|
|
+- ✅ `updateProjectPhaseStatus` - 更新阶段状态
|
|
|
+
|
|
|
+### 6. 设计方案文档 ✅
|
|
|
+
|
|
|
+**文件位置**: `docs/schema/project-phase-deadlines-design.md`
|
|
|
+
|
|
|
+包含完整的:
|
|
|
+- 数据结构设计
|
|
|
+- JSON示例
|
|
|
+- 前后端代码示例
|
|
|
+- 可视化建议
|
|
|
+- 实施步骤
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 🚀 如何使用
|
|
|
+
|
|
|
+### 前端使用示例
|
|
|
+
|
|
|
+#### 1. 在组件中使用类型定义
|
|
|
+
|
|
|
+```typescript
|
|
|
+import { PhaseDeadlines, PHASE_INFO, generateDefaultPhaseDeadlines } from '../models/project-phase.model';
|
|
|
+
|
|
|
+// 生成默认阶段截止时间
|
|
|
+const phaseDeadlines = generateDefaultPhaseDeadlines(new Date());
|
|
|
+
|
|
|
+// 访问阶段信息
|
|
|
+const modelingPhase = phaseDeadlines.modeling;
|
|
|
+console.log('建模截止时间:', modelingPhase?.deadline);
|
|
|
+
|
|
|
+// 使用常量获取阶段信息
|
|
|
+const phaseConfig = PHASE_INFO.modeling;
|
|
|
+console.log('建模阶段:', phaseConfig.label, phaseConfig.icon, phaseConfig.color);
|
|
|
+```
|
|
|
+
|
|
|
+#### 2. 在项目时间轴中展示
|
|
|
+
|
|
|
+时间轴组件已自动支持阶段截止时间展示,只需确保传入的项目数据包含 `phaseDeadlines` 字段:
|
|
|
+
|
|
|
+```typescript
|
|
|
+const projectData: ProjectTimeline = {
|
|
|
+ projectId: 'xxx',
|
|
|
+ projectName: '李总现代简约全案',
|
|
|
+ // ... 其他字段
|
|
|
+ phaseDeadlines: {
|
|
|
+ modeling: {
|
|
|
+ deadline: new Date('2024-12-08'),
|
|
|
+ status: 'in_progress',
|
|
|
+ estimatedDays: 7
|
|
|
+ },
|
|
|
+ // ... 其他阶段
|
|
|
+ }
|
|
|
+};
|
|
|
+```
|
|
|
+
|
|
|
+### Cloud Code使用示例
|
|
|
+
|
|
|
+#### 1. 数据迁移(为现有项目添加阶段时间)
|
|
|
+
|
|
|
+```javascript
|
|
|
+// 干跑模式(只计算不保存)
|
|
|
+Parse.Cloud.startJob('migrateProjectPhaseDeadlines', {
|
|
|
+ dryRun: true,
|
|
|
+ batchSize: 50
|
|
|
+});
|
|
|
+
|
|
|
+// 正式迁移
|
|
|
+Parse.Cloud.startJob('migrateProjectPhaseDeadlines', {
|
|
|
+ dryRun: false,
|
|
|
+ batchSize: 100
|
|
|
+});
|
|
|
+```
|
|
|
+
|
|
|
+#### 2. 创建项目时生成阶段截止时间
|
|
|
+
|
|
|
+```javascript
|
|
|
+// 在afterSave钩子中自动生成
|
|
|
+Parse.Cloud.afterSave("Project", async (request) => {
|
|
|
+ const project = request.object;
|
|
|
+
|
|
|
+ // 检查是否是新项目且有deadline
|
|
|
+ if (project.existed() || !project.get("deadline")) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ const data = project.get("data") || {};
|
|
|
+
|
|
|
+ // 如果已经有phaseDeadlines,跳过
|
|
|
+ if (data.phaseDeadlines) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 生成阶段截止时间
|
|
|
+ const { generatePhaseDeadlines } = require('./utils/project-phase-utils');
|
|
|
+ const phaseDeadlines = generatePhaseDeadlines(
|
|
|
+ project.get("createdAt"),
|
|
|
+ project.get("deadline")
|
|
|
+ );
|
|
|
+
|
|
|
+ data.phaseDeadlines = phaseDeadlines;
|
|
|
+ project.set("data", data);
|
|
|
+
|
|
|
+ await project.save(null, { useMasterKey: true });
|
|
|
+});
|
|
|
+```
|
|
|
+
|
|
|
+#### 3. 更新阶段状态
|
|
|
+
|
|
|
+```javascript
|
|
|
+// 方式1:使用Cloud Function
|
|
|
+await Parse.Cloud.run('updateProjectPhaseStatus', {
|
|
|
+ projectId: 'xxx',
|
|
|
+ phaseName: 'modeling',
|
|
|
+ status: 'completed',
|
|
|
+ additionalData: {
|
|
|
+ completedAt: new Date(),
|
|
|
+ notes: '建模阶段已完成'
|
|
|
+ }
|
|
|
+});
|
|
|
+
|
|
|
+// 方式2:直接使用工具函数
|
|
|
+const { updatePhaseStatus } = require('./utils/project-phase-utils');
|
|
|
+await updatePhaseStatus('projectId', 'modeling', 'completed', {
|
|
|
+ completedAt: new Date()
|
|
|
+});
|
|
|
+```
|
|
|
+
|
|
|
+#### 4. 设置公司默认工期
|
|
|
+
|
|
|
+```javascript
|
|
|
+// 在Company.data中添加配置
|
|
|
+const company = await new Parse.Query("Company").get(companyId);
|
|
|
+const data = company.get("data") || {};
|
|
|
+
|
|
|
+data.phaseDefaultDurations = {
|
|
|
+ modeling: 8, // 建模8天
|
|
|
+ softDecor: 5, // 软装5天
|
|
|
+ rendering: 7, // 渲染7天
|
|
|
+ postProcessing: 4 // 后期4天
|
|
|
+};
|
|
|
+
|
|
|
+company.set("data", data);
|
|
|
+await company.save(null, { useMasterKey: true });
|
|
|
+```
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 📊 数据结构说明
|
|
|
+
|
|
|
+### Project.data.phaseDeadlines 字段结构
|
|
|
+
|
|
|
+```json
|
|
|
+{
|
|
|
+ "phaseDeadlines": {
|
|
|
+ "modeling": {
|
|
|
+ "startDate": "2024-12-01T00:00:00.000Z",
|
|
|
+ "deadline": "2024-12-08T23:59:59.999Z",
|
|
|
+ "estimatedDays": 7,
|
|
|
+ "status": "in_progress",
|
|
|
+ "completedAt": "2024-12-07T18:30:00.000Z",
|
|
|
+ "assignee": {
|
|
|
+ "__type": "Pointer",
|
|
|
+ "className": "Profile",
|
|
|
+ "objectId": "prof001"
|
|
|
+ },
|
|
|
+ "priority": "high",
|
|
|
+ "notes": "客户要求加急"
|
|
|
+ },
|
|
|
+ "softDecor": {
|
|
|
+ "deadline": "2024-12-13T23:59:59.999Z",
|
|
|
+ "estimatedDays": 4,
|
|
|
+ "status": "not_started",
|
|
|
+ "priority": "medium"
|
|
|
+ },
|
|
|
+ "rendering": {
|
|
|
+ "deadline": "2024-12-20T23:59:59.999Z",
|
|
|
+ "estimatedDays": 6,
|
|
|
+ "status": "not_started",
|
|
|
+ "priority": "high"
|
|
|
+ },
|
|
|
+ "postProcessing": {
|
|
|
+ "deadline": "2024-12-24T23:59:59.999Z",
|
|
|
+ "estimatedDays": 3,
|
|
|
+ "status": "not_started",
|
|
|
+ "priority": "medium"
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+### 字段说明
|
|
|
+
|
|
|
+| 字段 | 类型 | 必填 | 说明 |
|
|
|
+|------|------|------|------|
|
|
|
+| startDate | Date | 否 | 阶段开始时间 |
|
|
|
+| deadline | Date | 是 | 阶段截止时间 |
|
|
|
+| estimatedDays | Number | 否 | 预计工期(天数) |
|
|
|
+| status | String | 否 | 阶段状态 (not_started/in_progress/completed/delayed) |
|
|
|
+| completedAt | Date | 否 | 实际完成时间 |
|
|
|
+| assignee | Pointer | 否 | 负责人 |
|
|
|
+| priority | String | 否 | 优先级 (low/medium/high/urgent) |
|
|
|
+| notes | String | 否 | 备注信息 |
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 🎨 可视化效果
|
|
|
+
|
|
|
+### 阶段图标和颜色
|
|
|
+
|
|
|
+- 🎨 **建模** - 蓝色 (#2196F3)
|
|
|
+- 🪑 **软装** - 紫色 (#9C27B0)
|
|
|
+- 🖼️ **渲染** - 橙色 (#FF9800)
|
|
|
+- ✨ **后期** - 绿色 (#4CAF50)
|
|
|
+
|
|
|
+### 时间轴展示
|
|
|
+
|
|
|
+- 项目条形图按紧急程度显示颜色
|
|
|
+- 阶段截止时间在时间轴上显示为彩色标记
|
|
|
+- 悬停显示详细信息(阶段名称、截止时间)
|
|
|
+- 只显示今日线之后的未来事件
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 🧪 测试建议
|
|
|
+
|
|
|
+### 1. 单元测试
|
|
|
+
|
|
|
+```typescript
|
|
|
+describe('PhaseDeadlines', () => {
|
|
|
+ it('should generate default phase deadlines', () => {
|
|
|
+ const startDate = new Date('2024-12-01');
|
|
|
+ const phaseDeadlines = generateDefaultPhaseDeadlines(startDate);
|
|
|
+
|
|
|
+ expect(phaseDeadlines.modeling).toBeDefined();
|
|
|
+ expect(phaseDeadlines.softDecor).toBeDefined();
|
|
|
+ expect(phaseDeadlines.rendering).toBeDefined();
|
|
|
+ expect(phaseDeadlines.postProcessing).toBeDefined();
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should check if phase is delayed', () => {
|
|
|
+ const pastPhase: PhaseInfo = {
|
|
|
+ deadline: new Date('2024-01-01'),
|
|
|
+ status: 'in_progress'
|
|
|
+ };
|
|
|
+ expect(isPhaseDelayed(pastPhase)).toBe(true);
|
|
|
+
|
|
|
+ const futurePhase: PhaseInfo = {
|
|
|
+ deadline: new Date('2025-12-31'),
|
|
|
+ status: 'in_progress'
|
|
|
+ };
|
|
|
+ expect(isPhaseDelayed(futurePhase)).toBe(false);
|
|
|
+ });
|
|
|
+});
|
|
|
+```
|
|
|
+
|
|
|
+### 2. E2E测试
|
|
|
+
|
|
|
+1. 创建新项目,验证自动生成阶段截止时间
|
|
|
+2. 切换到时间轴视图,验证阶段标记显示
|
|
|
+3. 悬停阶段标记,验证工具提示信息
|
|
|
+4. 更新阶段状态,验证UI更新
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 📋 待办事项
|
|
|
+
|
|
|
+### 已完成 ✅
|
|
|
+- [x] 创建前端类型定义文件
|
|
|
+- [x] 更新项目时间轴组件
|
|
|
+- [x] 创建数据迁移脚本
|
|
|
+- [x] 创建工具函数
|
|
|
+- [x] 编写使用文档
|
|
|
+
|
|
|
+### 可选增强功能 🔮
|
|
|
+- [ ] 添加阶段管理界面(手动调整截止时间)
|
|
|
+- [ ] 阶段延期自动提醒功能
|
|
|
+- [ ] 阶段进度追踪报表
|
|
|
+- [ ] 支持自定义阶段(不限于4个阶段)
|
|
|
+- [ ] 阶段依赖关系管理
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 🐛 故障排查
|
|
|
+
|
|
|
+### 问题1:时间轴没有显示阶段标记
|
|
|
+
|
|
|
+**原因**:项目数据中没有 `phaseDeadlines` 字段
|
|
|
+
|
|
|
+**解决方案**:
|
|
|
+1. 运行数据迁移脚本为现有项目添加数据
|
|
|
+2. 或手动为项目添加 `phaseDeadlines` 数据
|
|
|
+
|
|
|
+### 问题2:阶段时间计算不正确
|
|
|
+
|
|
|
+**原因**:项目没有 `deadline` 字段
|
|
|
+
|
|
|
+**解决方案**:
|
|
|
+确保所有项目都设置了 `deadline` 字段
|
|
|
+
|
|
|
+### 问题3:时间轴性能问题
|
|
|
+
|
|
|
+**原因**:项目数量过多
|
|
|
+
|
|
|
+**解决方案**:
|
|
|
+1. 使用筛选功能减少显示的项目数量
|
|
|
+2. 考虑添加分页或虚拟滚动
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 📞 技术支持
|
|
|
+
|
|
|
+如有问题,请参考:
|
|
|
+1. 设计方案文档:`docs/schema/project-phase-deadlines-design.md`
|
|
|
+2. schemas.md数据范式文档:`rules/schemas.md`
|
|
|
+3. 代码注释和类型定义
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+**最后更新**: 2024年11月6日
|
|
|
+**版本**: 1.0.0
|
|
|
+
|