# 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  
**状态**: ✅ 示例完成


