总管理员端的项目管理中,点击"分配设计师"按钮后,设计师的繁忙情况和接单情况没有显示,与其他端看到的数据不一致。
name - 项目组名称leader - 组长 (Pointer → Profile)type - 类型 ('project' = 项目组)company - 所属公司data.description - 项目组描述name - 设计师姓名department - 所属项目组 (String, departmentId)data.avatar - 头像data.skills - 技能列表data.status - 初始状态 (通常为空,由项目数据计算)data.workload - 初始工作量 (通常为空,由项目数据计算)data.currentProjects - 初始项目数 (通常为空,由项目数据计算)设计师分配弹窗在 enrichMembersWithProjectAssignments() 方法中动态加载项目数据:
// 查询 ProjectTeam 表
const teamQuery = new Parse.Query('ProjectTeam');
teamQuery.matchesQuery('project', companyProjectQuery);
teamQuery.include('project');
teamQuery.include('profile');
字段说明:
project - 关联的项目 (Pointer → Project)profile - 关联的设计师 (Pointer → Profile)role - 项目角色isDeleted - 是否删除聚合逻辑:
ProjectTeam 记录profile.id 分组统计项目数量如果 ProjectTeam 表为空,使用 Project 表的 assignee 字段:
const projectQuery = new Parse.Query('Project');
projectQuery.equalTo('company', companyId);
projectQuery.include('assignee');
字段说明:
assignee - 项目负责人 (Pointer → Profile)status - 项目状态currentStage / stage - 项目阶段createdAt - 创建时间title / name - 项目名称设计师的状态根据项目数量自动计算:
// 第808-818行
if (member.currentProjects === 0) {
member.status = 'idle'; // 🟢 绿色 - 空闲
} else if (member.currentProjects >= 1 && member.currentProjects <= 5) {
member.status = 'reviewing'; // 🟠 橙色 - 有项目
} else {
member.status = 'stagnant'; // 🔴 红色 - 繁忙 (超过5个项目)
}
关键指标:
currentProjects - 当前项目总数(所有状态的项目)workload - 工作量 = Math.min(100, currentProjects * 20)idleDays - 闲置天数(如果有项目则为0)recentOrders - 近30天接单数lastOrderDate - 最后接单日期status - 状态 (idle/reviewing/stagnant)查看 project-management.ts 第322-340行:
openTeamAssignmentModal(project: Project): void {
this.selectedProject = project;
// ❌ 使用的是模拟数据
this.projectTeams = this.mockProjectTeams;
// ❌ 没有传递 loadRealData 参数
// ❌ 没有传递 projectId 参数
this.showTeamAssignmentModal = true;
}
查看 project-management.html 第268-278行:
<app-designer-team-assignment-modal
[visible]="showTeamAssignmentModal"
[projectTeams]="projectTeams"
[selectedTeamId]="currentTeamAssignment.primaryTeamId"
[selectedDesigners]="currentTeamAssignment.quotationAssignments"
[crossTeamCollaborators]="currentTeamAssignment.crossTeamCollaborators"
[quotationItems]="currentQuotationItems"
[calendarViewMode]="'month'"
❌ 缺少:[loadRealData]="true"
❌ 缺少:[projectId]="selectedProject.id"
(close)="closeTeamAssignmentModal()"
(confirm)="confirmTeamAssignment($event)"
></app-designer-team-assignment-modal>
<app-designer-team-assignment-modal
[visible]="showTeamAssignmentModal"
[loadRealData]="true" ← ✅ 启用真实数据加载
[projectId]="currentProjectId" ← ✅ 传递项目ID
[loadRealSpaces]="true" ← ✅ 加载真实空间数据
[enableSpaceAssignment]="true" ← ✅ 启用空间分配
(close)="closeTeamAssignmentModal()"
(confirm)="confirmTeamAssignment($event)"
></app-designer-team-assignment-modal>
| 参数 | 类型 | 默认值 | 作用 |
|---|---|---|---|
loadRealData |
boolean | true | 是否从数据库加载真实的项目组和成员数据 |
projectId |
string | '' | 项目ID,用于查询项目相关数据 |
loadRealSpaces |
boolean | true | 是否自动加载项目的空间数据 |
enableSpaceAssignment |
boolean | false | 是否启用空间分配功能 |
打开弹窗
↓
loadRealData = undefined (默认 true)
↓
调用 loadRealProjectTeams()
↓
✅ 从 Department/Profile 表加载设计师基础信息
↓
❌ projectId 未传递 (空字符串)
↓
❌ enrichMembersWithProjectAssignments() 方法中
查询 ProjectTeam 时没有项目上下文
↓
❌ 无法统计设计师的项目数量
↓
❌ currentProjects = 0 (默认值)
↓
❌ status = 'idle' (默认值)
↓
❌ workload = 0 (默认值)
↓
显示:所有设计师都是"空闲"状态 ❌
打开弹窗
↓
[loadRealData]="true"
[projectId]="currentProjectId"
↓
调用 loadRealProjectTeams()
↓
✅ 从 Department/Profile 表加载设计师基础信息
↓
✅ enrichMembersWithProjectAssignments()
↓
✅ 查询 ProjectTeam 表(或 Project 表)
按公司ID查询所有项目
↓
✅ 为每个设计师统计项目数量
currentProjects = 实际项目数
↓
✅ 根据项目数量计算状态
0个项目 → idle (绿色)
1-5个项目 → reviewing (橙色)
>5个项目 → stagnant (红色)
↓
✅ 计算工作量
workload = Math.min(100, currentProjects * 20)
↓
✅ 计算闲置天数
有项目 → idleDays = 0
无项目 → 根据 lastOrderDate 计算
↓
显示:设计师真实的繁忙情况 ✅
<!-- project-management.html -->
<app-designer-team-assignment-modal
[visible]="showTeamAssignmentModal"
[loadRealData]="true" ← ✅ 添加
[projectId]="selectedProject?.id || ''" ← ✅ 添加
[loadRealSpaces]="true" ← ✅ 添加(可选)
[enableSpaceAssignment]="false" ← ✅ 添加(可选)
[projectTeams]="projectTeams"
[selectedTeamId]="currentTeamAssignment.primaryTeamId"
[selectedDesigners]="currentTeamAssignment.quotationAssignments"
[crossTeamCollaborators]="currentTeamAssignment.crossTeamCollaborators"
[quotationItems]="currentQuotationItems"
[calendarViewMode]="'month'"
(close)="closeTeamAssignmentModal()"
(confirm)="confirmTeamAssignment($event)"
></app-designer-team-assignment-modal>
// project-management.ts
openTeamAssignmentModal(project: Project): void {
this.selectedProject = project;
// ✅ 不再使用模拟数据,让弹窗组件自动加载
// ❌ this.projectTeams = this.mockProjectTeams;
this.projectTeams = []; // 让弹窗组件自动加载真实数据
// 初始化当前团队分配信息
this.currentTeamAssignment = {
primaryTeamId: project.assigneeId || null,
quotationAssignments: [],
crossTeamCollaborators: []
};
// TODO: 从Parse Server加载报价项数据
this.currentQuotationItems = [];
this.showTeamAssignmentModal = true;
console.log('✅ 打开团队分配弹窗:', project.id, project.title);
}
控制台应该输出:
🚀 [设计师分配弹窗] 初始化,loadRealData: true
🔄 [设计师分配弹窗] 弹窗打开,重新加载项目数据...
✅ [项目数据加载] ProjectTeam 查询成功!
📊 [项目数据加载] 查询结果: X 条记录
🔍 [张佳乐] Member ID: designer-1
从 profileIdToProjects 获取到 3 个项目
✅ 已设置 currentProjects(所有项目) = 3
🟠 [张佳乐] 3个项目 - 有项目 (工作量:60%, 闲置:0天)
状态指示器:
项目数量:显示实际项目数,例如 "当前项目: 3个"
工作量进度条:根据项目数量计算,例如 60%
闲置天数:有项目时为0天,无项目时显示实际天数
系统会自动启用降级方案,从 Project.assignee 字段查询:
// 降级方案:查询 Project 表
const projectQuery = new Parse.Query('Project');
projectQuery.equalTo('company', companyId);
projectQuery.include('assignee');
const allProjects = await projectQuery.find();
const projects = allProjects.filter(p => {
const assignee = p.get('assignee');
return assignee && profileIds.has(assignee.id);
});
注意事项:
Project.assignee 字段已正确设置currentProjects - 每次打开弹窗时动态查询workload - 根据项目数量计算status - 根据项目数量判断idleDays - 根据最后接单日期计算recentOrders - 统计近30天项目项目管理端调用设计师分配弹窗时,没有传递 projectId 参数,导致弹窗无法查询设计师的项目数据,所有设计师都显示为默认的空闲状态。
在 project-management.html 中添加 [projectId]="selectedProject?.id || ''" 输入属性,让弹窗组件能够查询真实的项目数据。
loadRealData="true" - 启用真实数据加载(默认已是true)projectId="项目ID" - 关键! 必须传递,用于查询项目数据传递 projectId
↓
查询 ProjectTeam/Project 表
↓
统计每个设计师的项目数量
↓
计算状态 (idle/reviewing/stagnant)
↓
显示繁忙情况和接单情况