# Dashboard组件集成真实数据示例 ## 一、在Dashboard中注入服务 ```typescript:src/app/pages/team-leader/dashboard/dashboard.ts import { ProjectDataService } from '../services/project-data.service'; import { DashboardDataService } from '../services/dashboard-data.service'; import { DesignerService } from '../services/designer.service'; export class Dashboard implements OnInit { // ... 现有代码 ... constructor( private router: Router, private projectService: ProjectService, // 保留现有 private designerService: DesignerService, // 已存在 private projectDataService: ProjectDataService, // 新增 private dashboardDataService: DashboardDataService // 新增 ) {} } ``` ## 二、替换loadProjects方法 ```typescript // 原方法(使用模拟数据) async loadProjects() { // 模拟数据... } // 新方法(使用真实数据) async loadProjects() { try { console.log('📊 开始加载项目数据...'); // 方案1: 使用ProjectDataService(推荐) this.projects = await this.projectDataService.getProjects(); // 方案2: 使用DesignerService的getProjects(已存在) // this.projects = await this.designerService.getProjects(); // 应用筛选 this.applyFilters(); // 更新甘特图 setTimeout(() => { this.updateGanttDesigner(); this.updateWorkloadGantt(); }, 0); console.log(`✅ 成功加载 ${this.projects.length} 个项目`); } catch (error) { console.error('❌ 加载项目失败:', error); // 降级方案:使用模拟数据 this.projects = this.getMockProjects(); this.applyFilters(); } } ``` ## 三、加载设计师数据 ```typescript async loadDesigners() { try { console.log('👥 开始加载设计师数据...'); // 获取真实设计师列表 this.realDesigners = await this.designerService.getDesigners(); // 提取设计师名称(用于筛选器) this.designers = ['all', ...this.realDesigners.map(d => d.name)]; console.log(`✅ 成功加载 ${this.realDesigners.length} 个设计师`); } catch (error) { console.error('❌ 加载设计师失败:', error); this.designers = ['all']; } } ``` ## 四、加载KPI数据 ```typescript async loadKPIData() { try { console.log('📈 开始加载KPI数据...'); const kpi = await this.dashboardDataService.getKPIStats(); // 更新KPI卡片数据(如果有) this.totalProjects = kpi.totalProjects; this.inProgressProjects = kpi.inProgressProjects; this.completedProjects = kpi.completedProjects; this.overdueProjects = kpi.overdueProjects; this.dueSoonProjects = kpi.dueSoonProjects; // 更新设计师统计 this.totalDesigners = kpi.totalDesigners; this.availableDesigners = kpi.availableDesigners; this.busyDesigners = kpi.busyDesigners; this.overloadedDesigners = kpi.overloadedDesigners; console.log('✅ KPI数据加载成功'); } catch (error) { console.error('❌ 加载KPI失败:', error); } } ``` ## 五、加载待办任务 ```typescript async loadTodoTasks() { try { console.log('📝 开始加载待办任务...'); this.todoTasks = await this.dashboardDataService.getTodoTasks(); console.log(`✅ 成功加载 ${this.todoTasks.length} 个待办任务`); } catch (error) { console.error('❌ 加载待办任务失败:', error); this.todoTasks = []; } } ``` ## 六、更新ngOnInit方法 ```typescript async ngOnInit() { // 加载所有数据 await Promise.all([ this.loadProjects(), // 加载项目 this.loadDesigners(), // 加载设计师 this.loadKPIData(), // 加载KPI this.loadTodoTasks() // 加载待办 ]); // 初始化图表 setTimeout(() => { this.updateGanttDesigner(); this.updateWorkloadGantt(); }, 100); } ``` ## 七、分配项目功能 ```typescript async onAssignProject(project: any, designerId: string) { try { console.log(`📌 分配项目 "${project.name}" 给设计师 ${designerId}`); const success = await this.projectDataService.assignProject( project.id, designerId ); if (success) { // 重新加载项目列表 await this.loadProjects(); // 关闭智能推荐弹窗 this.showSmartMatch = false; console.log('✅ 项目分配成功'); // TODO: 显示成功提示 } else { console.error('❌ 项目分配失败'); // TODO: 显示错误提示 } } catch (error) { console.error('❌ 分配项目异常:', error); } } ``` ## 八、更新项目状态 ```typescript async onUpdateProjectStatus(projectId: string, newStatus: string) { try { console.log(`📝 更新项目状态: ${newStatus}`); const success = await this.projectDataService.updateProject( projectId, { status: newStatus } ); if (success) { // 重新加载项目列表 await this.loadProjects(); console.log('✅ 状态更新成功'); } } catch (error) { console.error('❌ 更新状态失败:', error); } } ``` ## 九、更新项目阶段 ```typescript async onUpdateProjectStage(projectId: string, newStage: string) { try { console.log(`📝 更新项目阶段: ${newStage}`); const success = await this.projectDataService.updateProjectStage( projectId, newStage ); if (success) { // 重新加载项目列表 await this.loadProjects(); console.log('✅ 阶段更新成功'); } } catch (error) { console.error('❌ 更新阶段失败:', error); } } ``` ## 十、智能推荐功能 ```typescript async onSmartRecommend(project: any) { try { console.log(`🤖 为项目 "${project.name}" 推荐设计师...`); // 调用智能推荐 this.recommendations = await this.designerService.getRecommendedDesigners(project); // 显示推荐弹窗 this.selectedProject = project; this.showSmartMatch = true; console.log(`✅ 推荐完成,共 ${this.recommendations.length} 个推荐`); } catch (error) { console.error('❌ 智能推荐失败:', error); this.recommendations = []; } } ``` ## 十一、完整的初始化流程 ```typescript async ngOnInit() { console.log('🚀 Dashboard初始化开始...'); try { // 第1步:加载基础数据 await this.loadDesigners(); // 第2步:加载项目数据 await this.loadProjects(); // 第3步:加载统计数据 await this.loadKPIData(); // 第4步:加载待办任务 await this.loadTodoTasks(); // 第5步:初始化图表 setTimeout(() => { this.updateGanttDesigner(); this.updateWorkloadGantt(); }, 100); console.log('✅ Dashboard初始化完成'); } catch (error) { console.error('❌ Dashboard初始化失败:', error); } } ``` ## 十二、错误处理和降级策略 ```typescript async loadProjects() { try { // 尝试加载真实数据 this.projects = await this.projectDataService.getProjects(); if (this.projects.length === 0) { console.warn('⚠️ 数据库中没有项目数据'); // 可选:提示用户创建项目 } } catch (error) { console.error('❌ 加载项目失败,使用模拟数据:', error); // 降级方案:使用模拟数据 this.projects = this.getMockProjects(); } finally { // 无论成功失败都要应用筛选 this.applyFilters(); } } ``` ## 十三、数据刷新机制 ```typescript // 手动刷新 async refreshData() { console.log('🔄 刷新数据...'); await Promise.all([ this.loadProjects(), this.loadKPIData(), this.loadTodoTasks() ]); console.log('✅ 数据刷新完成'); } // 定时自动刷新(可选) private refreshInterval: any; ngOnInit() { // ... 初始加载 ... // 每5分钟自动刷新一次 this.refreshInterval = setInterval(() => { this.refreshData(); }, 5 * 60 * 1000); } ngOnDestroy() { // 清理定时器 if (this.refreshInterval) { clearInterval(this.refreshInterval); } // ... 其他清理 ... } ``` ## 十四、测试步骤 ### 14.1 前置条件 1. 确保 `localStorage.setItem('company', 'your-company-id')` 已设置 2. 确保数据库中有对应公司的数据 ### 14.2 测试流程 1. 打开浏览器控制台 2. 访问组长端Dashboard 3. 观察控制台日志: ``` 🚀 Dashboard初始化开始... 🏢 ProjectDataService初始化,当前公司ID: xxx 🏢 DashboardDataService初始化,当前公司ID: xxx 🏢 DesignerService初始化,当前公司ID: xxx ✅ ProjectDataService: FmodeParse 初始化成功 ✅ DashboardDataService: FmodeParse 初始化成功 ✅ DesignerService: FmodeParse 初始化成功 👥 开始加载设计师数据... ✅ 获取到 3 个设计师 ✅ 成功加载 3 个设计师 📊 开始加载项目数据... ✅ 查询到 10 个项目 ✅ 成功加载 10 个项目 📈 开始加载KPI数据... ✅ KPI数据加载成功 📝 开始加载待办任务... ✅ 成功加载 5 个待办任务 ✅ Dashboard初始化完成 ``` 4. 检查页面数据是否正确显示 ### 14.3 功能测试 - [ ] 项目列表正确显示 - [ ] 筛选功能正常工作 - [ ] 搜索功能正常工作 - [ ] KPI卡片显示正确数据 - [ ] 甘特图正确渲染 - [ ] 分配项目功能正常 - [ ] 智能推荐功能正常 ## 十五、常见问题排查 ### Q1: 控制台显示 "Parse未初始化" **解决**: ```typescript // 检查FmodeParse是否正确安装 npm list fmode-ng // 检查导入是否正确 import { FmodeParse } from 'fmode-ng/parse'; ``` ### Q2: 查询不到数据 **解决**: ```typescript // 检查公司ID console.log('Company ID:', localStorage.getItem('company')); // 手动查询测试 const Parse = FmodeParse.with("nova"); const query = new Parse.Query('Project'); query.equalTo('company', 'your-company-id'); const projects = await query.find(); console.log('Projects:', projects); ``` ### Q3: 数据格式不匹配 **解决**: ```typescript // 检查transformProject方法 const transformed = this.projectDataService['transformProject'](parseObject); console.log('Transformed:', transformed); ``` ## 十六、总结 ### 16.1 集成要点 1. ✅ 注入3个数据服务 2. ✅ 替换loadProjects方法 3. ✅ 添加loadKPIData方法 4. ✅ 添加loadTodoTasks方法 5. ✅ 更新ngOnInit方法 6. ✅ 实现分配/更新功能 7. ✅ 添加错误处理和降级 8. ✅ 实现数据刷新机制 ### 16.2 使用流程 ``` 用户打开Dashboard ↓ ngOnInit触发 ↓ 并行加载:设计师、项目、KPI、待办 ↓ 数据转换为前端格式 ↓ 应用筛选和排序 ↓ 渲染图表和列表 ↓ 用户操作(分配、更新、搜索) ↓ 调用对应服务方法 ↓ 重新加载数据 ↓ 更新UI ``` ### 16.3 下一步 - [ ] 在Dashboard.ts中实际应用这些方法 - [ ] 测试所有功能 - [ ] 优化加载性能 - [ ] 添加加载状态提示 - [ ] 添加操作成功/失败提示 --- **文档版本**: v1.0 **最后更新**: 2025-10-22 16:30 **状态**: ✅ 示例完成