# 设计师分配弹窗数据同步修复 - 验证指南
## 修复内容总结
### ✅ 修改文件
1. **project-management.html**(第268-282行)
2. **project-management.ts**(第322-347行)
### ✅ 核心修改
#### 1️⃣ HTML 模板 - 添加关键输入参数
```html
```
#### 2️⃣ TypeScript 逻辑 - 移除模拟数据
```typescript
openTeamAssignmentModal(project: Project): void {
this.selectedProject = project;
// ✅ 修改:不再使用模拟数据,让弹窗组件自动加载真实数据
// ❌ 旧代码:this.projectTeams = this.mockProjectTeams;
this.projectTeams = []; // 空数组,让弹窗自动加载
this.currentTeamAssignment = {
primaryTeamId: project.assigneeId || null,
quotationAssignments: [],
crossTeamCollaborators: []
};
this.currentQuotationItems = [];
this.showTeamAssignmentModal = true;
// ✅ 新增:详细的日志输出
console.log('✅ [项目管理] 打开团队分配弹窗:', {
projectId: project.id,
projectTitle: project.title,
currentAssignee: project.assignee
});
}
```
---
## 验证步骤
### 第1步:启动应用并打开项目管理页面
```bash
npm start
```
访问:`http://localhost:4200/admin/project-management`
### 第2步:点击任意项目的"分配设计师"按钮
找到项目列表中的任意项目,点击操作列的"分配设计师"按钮。
### 第3步:检查浏览器控制台日志
打开浏览器开发者工具(F12),查看 Console 面板,应该看到以下日志:
#### ✅ 正确的日志输出
```
✅ [项目管理] 打开团队分配弹窗: {
projectId: "abc123",
projectTitle: "某某项目",
currentAssignee: "张三"
}
🚀 [设计师分配弹窗] 初始化,loadRealData: true
成功加载项目组数据: (3) [{…}, {…}, {…}]
═════════════════════════════════════════════════════════════════════════════
🚀🚀🚀 [项目数据加载] ===== 开始加载所有成员的项目分配 =====
═════════════════════════════════════════════════════════════════════════════
📊 [项目数据加载] 总成员数: 6
📊 [项目数据加载] 成员列表: 张佳乐, 未知设计师, 江集, 李明, 王芳, 赵磊
🔍 [项目数据加载] 目标成员 IDs:
- 张佳乐 (ID: designer-1)
- 未知设计师 (ID: designer-2)
- 江集 (ID: designer-3)
...
✅ [项目数据加载] ProjectTeam 查询成功!
📊 [项目数据加载] 查询结果: 8 条记录
📋 [ProjectTeam 记录详情]
1. Profile: 张佳乐 (designer-1)
Project: 某某项目 (project-1)
状态: 进行中, 阶段: 建模
2. Profile: 张佳乐 (designer-1)
Project: 另一个项目 (project-2)
状态: 进行中, 阶段: 渲染
...
📊 [项目数据加载] 查询阶段完成,开始处理数据...
🔍 [张佳乐] Member ID: designer-1
从 profileIdToProjects 获取到 3 个项目
📋 项目详情:
1. 某某项目 (状态: 进行中, 阶段: 建模)
2. 另一个项目 (状态: 进行中, 阶段: 渲染)
3. 第三个项目 (状态: 进行中, 阶段: 方案深化)
✅ 已设置 currentProjects(所有项目) = 3
🟠 [张佳乐] 3个项目 - 有项目 (工作量:60%, 闲置:0天)
🔍 [未知设计师] Member ID: designer-2
从 profileIdToProjects 获取到 0 个项目
⚠️ 没有找到项目!
✅ 已设置 currentProjects(所有项目) = 0
🟢 [未知设计师] 0个项目 - 空闲 (工作量:0%, 闲置:6天)
✅ [项目数据加载] 所有成员项目数据加载完成
💾 [项目数据加载] 已更新缓存,有效期30秒
```
#### ❌ 如果看到错误日志
```
❌ [项目数据加载] ProjectTeam 查询失败
错误详情: {message: "...", code: ...}
```
**可能原因:**
1. Parse Server 连接失败
2. ProjectTeam 表不存在
3. 权限配置问题
**解决方案:**
- 检查 Parse Server 配置
- 检查数据库表是否存在
- 检查用户权限
---
### 第4步:检查设计师卡片显示
在弹窗中,应该看到:
#### ✅ 正确显示(有项目的设计师)
```
┌─────────────────────────────────────┐
│ 🟠 张佳乐 (组长) │
├─────────────────────────────────────┤
│ 状态: 有项目 │
│ 当前项目: 3个 │
│ 工作量: ████████░░ 60% │
│ 近30天接单: 3单 │
│ 闲置天数: 0天 │
│ │
│ [📅 查看日历] [选择设计师] │
└─────────────────────────────────────┘
```
#### ✅ 正确显示(无项目的设计师)
```
┌─────────────────────────────────────┐
│ 🟢 未知设计师 │
├─────────────────────────────────────┤
│ 状态: 空闲 │
│ 当前项目: 0个 │
│ 工作量: ░░░░░░░░░░ 0% │
│ 近30天接单: 0单 │
│ 闲置天数: 6天 │
│ │
│ [📅 查看日历] [选择设计师] │
└─────────────────────────────────────┘
```
#### ✅ 正确显示(繁忙的设计师)
```
┌─────────────────────────────────────┐
│ 🔴 李明 │
├─────────────────────────────────────┤
│ 状态: 繁忙 │
│ 当前项目: 7个 │
│ 工作量: ██████████ 100% │
│ 近30天接单: 7单 │
│ 闲置天数: 0天 │
│ │
│ [📅 查看日历] [选择设计师] │
└─────────────────────────────────────┘
```
#### ❌ 如果显示错误(所有设计师都是空闲)
```
┌─────────────────────────────────────┐
│ 🟢 张佳乐 (组长) │
├─────────────────────────────────────┤
│ 状态: 空闲 │
│ 当前项目: 0个 ← ❌ 错误! │
│ 工作量: ░░░░░░░░░░ 0% │
│ 近30天接单: 0单 │
│ 闲置天数: 0天 │
└─────────────────────────────────────┘
```
**可能原因:**
1. 没有传递 `projectId` 参数
2. ProjectTeam 表没有数据
3. Project.assignee 字段未设置
---
### 第5步:测试不同状态的设计师
#### 测试场景1:空闲设计师(0个项目)
- **状态颜色**:🟢 绿色
- **状态文本**:"空闲"
- **项目数量**:0个
- **工作量**:0%
- **闲置天数**:根据最后接单日期计算
#### 测试场景2:有项目的设计师(1-5个项目)
- **状态颜色**:🟠 橙色
- **状态文本**:"有项目"
- **项目数量**:1-5个
- **工作量**:20%-100%
- **闲置天数**:0天
#### 测试场景3:繁忙的设计师(>5个项目)
- **状态颜色**:🔴 红色
- **状态文本**:"繁忙"
- **项目数量**:6个及以上
- **工作量**:100%
- **闲置天数**:0天
---
### 第6步:测试日历功能
点击任意设计师卡片的"📅 查看日历"按钮,应该:
1. ✅ 弹出日历面板
2. ✅ 显示该设计师的项目事件
3. ✅ 显示对图日期(review 事件)
4. ✅ 显示项目截止日期(project 事件)
5. ✅ 日历数据与项目数据一致
---
## 对比测试
### 测试A:其他端(设计师端/组长端)
1. 打开设计师端或组长端的项目详情页
2. 点击"分配设计师"按钮
3. 记录设计师的状态和项目数量
### 测试B:项目管理端(修复后)
1. 打开总管理员端的项目管理页
2. 点击"分配设计师"按钮
3. 对比设计师的状态和项目数量
### ✅ 验证标准
| 项目 | 其他端 | 项目管理端 | 结果 |
|------|--------|-----------|------|
| 张佳乐 - 状态 | 🟠 有项目 | 🟠 有项目 | ✅ 一致 |
| 张佳乐 - 项目数 | 3个 | 3个 | ✅ 一致 |
| 张佳乐 - 工作量 | 60% | 60% | ✅ 一致 |
| 未知设计师 - 状态 | 🟢 空闲 | 🟢 空闲 | ✅ 一致 |
| 未知设计师 - 闲置天数 | 6天 | 6天 | ✅ 一致 |
---
## 常见问题排查
### Q1: 所有设计师都显示为空闲状态
**原因:**
- `projectId` 参数未正确传递
- ProjectTeam 表为空且 Project.assignee 未设置
**解决方案:**
1. 检查 HTML 中是否有 `[projectId]="selectedProject?.id || ''"`
2. 检查控制台日志,确认 projectId 不为空
3. 检查数据库中的 ProjectTeam 表和 Project.assignee 字段
### Q2: 控制台报错 "ProjectTeam 查询失败"
**原因:**
- Parse Server 连接问题
- 权限配置问题
**解决方案:**
1. 检查 Parse Server 是否正常运行
2. 检查用户是否有查询 ProjectTeam 的权限
3. 检查 ProjectTeam 表是否存在
### Q3: 项目数量统计不准确
**原因:**
- ProjectTeam 表数据不完整
- 项目状态过滤逻辑问题
**解决方案:**
1. 检查 ProjectTeam 表中的记录是否完整
2. 确认项目的 status 和 currentStage 字段是否正确
3. 查看控制台日志,确认项目是否被过滤
### Q4: 修改后仍显示模拟数据
**原因:**
- 浏览器缓存问题
- 代码未保存或未编译
**解决方案:**
1. 硬刷新浏览器(Ctrl+Shift+R 或 Cmd+Shift+R)
2. 重启开发服务器
3. 清除浏览器缓存
---
## 数据流程验证
### 完整数据流程
```
1. 用户点击"分配设计师"按钮
↓
2. openTeamAssignmentModal(project)
- 设置 selectedProject = project
- 清空 projectTeams 数组
↓
3. 弹窗组件接收输入参数
- [loadRealData]="true"
- [projectId]="project.id"
↓
4. ngOnInit() 自动执行
- 调用 loadRealProjectTeams()
↓
5. 查询 Department 和 Profile 表
- 加载所有项目组和设计师
↓
6. enrichMembersWithProjectAssignments()
- 查询 ProjectTeam 表(优先)
- 或查询 Project.assignee(降级)
↓
7. 为每个设计师统计项目数据
- currentProjects = 实际项目数
- workload = min(100, projects * 20)
- status = idle/reviewing/stagnant
- idleDays = 计算闲置天数
- recentOrders = 近30天接单数
↓
8. 显示设计师卡片
- 状态指示器(绿/橙/红)
- 项目数量
- 工作量进度条
- 接单情况
↓
9. 用户选择设计师并确认
↓
10. 保存分配结果到数据库
```
---
## 预期效果对比
### 修复前 ❌
| 设计师 | 状态 | 项目数 | 工作量 | 接单情况 |
|--------|------|--------|--------|----------|
| 张佳乐 | 🟢 空闲 | 0个 | 0% | 0单 |
| 未知设计师 | 🟢 空闲 | 0个 | 0% | 0单 |
| 江集 | 🟢 空闲 | 0个 | 0% | 0单 |
**问题:所有设计师都显示为空闲状态,无法看到真实的繁忙情况。**
### 修复后 ✅
| 设计师 | 状态 | 项目数 | 工作量 | 接单情况 |
|--------|------|--------|--------|----------|
| 张佳乐 | 🟠 有项目 | 3个 | 60% | 3单 |
| 未知设计师 | 🟢 空闲 | 0个 | 0% | 已闲置6天 |
| 江集 | 🟠 有项目 | 2个 | 40% | 2单 |
| 李明 | 🔴 繁忙 | 7个 | 100% | 7单 |
**效果:显示真实的繁忙情况,方便管理员合理分配任务。**
---
## 技术细节说明
### 为什么需要 projectId?
虽然 `projectId` 在 `enrichMembersWithProjectAssignments()` 中没有直接使用,但它是必需的,原因如下:
1. **未来扩展**:可能需要根据项目类型筛选合适的设计师
2. **空间分配**:如果启用 `loadRealSpaces`,需要 projectId 加载空间数据
3. **上下文信息**:为日志和调试提供项目上下文
4. **一致性**:与其他端保持一致的参数传递方式
### 为什么设置 loadRealSpaces=false?
项目管理端主要用于:
- 查看设计师状态
- 分配设计师到项目
不需要:
- 空间分配功能(这是设计师端和组长端的功能)
- 空间数据加载(减少不必要的查询)
### 数据缓存机制
弹窗组件使用30秒缓存,避免频繁查询:
```typescript
private projectDataCache: Map = new Map();
private lastCacheTime: number = 0;
private CACHE_DURATION = 30000; // 30秒
// 检查缓存
if (now - this.lastCacheTime < this.CACHE_DURATION) {
console.log('⚡ 使用缓存数据,跳过查询');
this.applyProjectDataFromCache(allMembers);
return;
}
```
**注意:** 如果需要强制刷新,关闭弹窗等待30秒后重新打开。
---
## 总结
### ✅ 修复完成
1. **HTML 模板**:添加了 `loadRealData`、`projectId`、`loadRealSpaces`、`enableSpaceAssignment` 参数
2. **TypeScript 逻辑**:移除了模拟数据,让弹窗组件自动加载真实数据
3. **日志输出**:添加了详细的日志,便于调试
### ✅ 预期效果
- 设计师状态显示准确(空闲/有项目/繁忙)
- 项目数量显示正确
- 工作量计算准确
- 接单情况显示真实
- 与其他端数据一致
### ✅ 验证要点
1. 控制台日志正常输出
2. 设计师卡片显示正确
3. 状态颜色正确(绿/橙/红)
4. 与其他端数据一致
如果验证过程中发现任何问题,请参考"常见问题排查"部分。