将 dashboard.ts 中的逻辑拆分到7个独立子组件中,大幅简化了主组件的代码量和复杂度。
位置: components/dashboard-metrics/
功能:
接口:
@Input() overdueCount: number
@Input() dueSoonCount: number
@Input() pendingApprovalCount: number
@Input() pendingAssignmentCount: number
@Input() overloadedDesignersCount: number
@Input() averageWorkloadRate: number
@Output() filterStatus: EventEmitter<string>
位置: components/dashboard-filter-bar/
功能:
接口:
@Input() projects: Project[]
@Input() designers: string[]
@Input() corePhases: any[]
@Input() searchTerm: string
@Input() selectedType: 'all' | 'soft' | 'hard'
// ... 其他筛选状态
@Output() filterChange: EventEmitter<FilterState>
@Output() viewProject: EventEmitter<string>
位置: components/project-kanban/
功能:
接口:
@Input() corePhases: any[]
@Input() projects: Project[]
@Output() viewProject: EventEmitter<{projectId, phaseId}>
@Output() openSmartMatch: EventEmitter<Project>
@Output() assignProject: EventEmitter<string>
@Output() reviewProject: EventEmitter<{projectId, rating}>
位置: components/todo-section/
功能:
接口:
@Input() todoTasksFromIssues: TodoTaskFromIssue[]
@Input() urgentEvents: UrgentEvent[]
@Input() loadingTodoTasks: boolean
@Input() loadingUrgentEvents: boolean
@Output() refresh: EventEmitter<void>
@Output() navigateToIssue: EventEmitter<TodoTaskFromIssue>
@Output() markAsRead: EventEmitter<TodoTaskFromIssue>
@Output() confirmEventOnTime: EventEmitter<UrgentEvent>
@Output() resolveUrgentEvent: EventEmitter<UrgentEvent>
@Output() createTodoFromEvent: EventEmitter<UrgentEvent>
位置: components/workload-gantt/
功能:
接口:
@Input() designerWorkloadMap: Map<string, any[]>
@Input() realDesigners: any[]
@Input() filteredProjects: Project[]
@Output() employeeClick: EventEmitter<string>
位置: components/smart-match-modal/
功能:
接口:
@Input() visible: boolean
@Input() selectedProject: Project | null
@Input() recommendations: any[]
@Output() close: EventEmitter<void>
@Output() assign: EventEmitter<string>
位置: components/dashboard-alerts/
功能:
接口:
@Input() showAlert: boolean
@Input() overdueProjects: Project[]
@Input() urgentPinnedProjects: Project[]
@Output() viewAllOverdue: EventEmitter<void>
@Output() closeAlert: EventEmitter<void>
@Output() filterStatus: EventEmitter<string>
删除/迁移的方法:
updateWorkloadGantt() → WorkloadGanttComponent(~300行)filterUrgentEventsByTag() → TodoSectionComponentprecalculateTagCaches() → TodoSectionComponentupdateFilteredUrgentEvents() → TodoSectionComponentfilterProjects(), filterByUrgency() 等筛选方法 → DashboardFilterBarComponentmapStageToCorePhase() → ProjectKanbanComponentgetProjectsByStage() → ProjectKanbanComponentsetGanttScale(), setGanttMode() → 已废弃getUrgencyLabel(), formatRelativeTime() 等辅助方法 → 各子组件删除的属性:
ganttChart, workloadGanttChart → 迁移到子组件@ViewChild 引用 → 迁移到子组件urgentEventsCache → 迁移到 TodoSectionComponentfilteredUrgentEventsList → 迁移到 TodoSectionComponenturgentEventTagFilter → 迁移到 TodoSectionComponentganttScale, ganttMode → 已废弃简化的方法:
applyFilters() → 保留核心逻辑,删除冗余更新ngOnDestroy() → 删除 echarts 清理逻辑ngOnInit() → 删除 updateWorkloadGantt 调用| 文件 | 重构前 | 重构后 | 减少 |
|---|---|---|---|
| dashboard.ts | ~2600行 | ~1900行 | -700行 |
Dashboard (父组件)
↓ Props
[子组件1] [子组件2] [子组件3] ...
↑ Events
Dashboard (父组件处理事件)
Input 输入: 父组件 → 子组件传递数据
Output 输出: 子组件 → 父组件触发事件
优点:
所有子组件使用 ChangeDetectionStrategy.OnPush,减少不必要的变更检测
TodoSectionComponent 预计算标签筛选结果,实现 O(1) 切换
子组件独立打包,支持按需加载
每个子组件应独立测试:
// 示例:DashboardMetricsComponent 测试
it('should emit filterStatus when card clicked', () => {
const spy = spyOn(component.filterStatus, 'emit');
component.onFilterStatus('overdue');
expect(spy).toHaveBeenCalledWith('overdue');
});
测试父子组件通信:
it('should update filtered projects when filter changes', () => {
const filterState = { searchTerm: 'test', ... };
filterBar.filterChange.emit(filterState);
expect(dashboard.filteredProjects.length).toBe(expected);
});
<!-- 统计指标 -->
<app-dashboard-metrics
[overdueCount]="overdueProjects.length"
[dueSoonCount]="dueSoonProjects.length"
[overloadedDesignersCount]="overloadedDesignersCount"
(filterStatus)="filterByStatus($event)">
</app-dashboard-metrics>
<!-- 筛选条件栏 -->
<app-dashboard-filter-bar
[projects]="projects"
[designers]="designers"
[(searchTerm)]="searchTerm"
[(selectedStatus)]="selectedStatus"
(filterChange)="onFilterChange($event)"
(viewProject)="viewProjectDetails($event)">
</app-dashboard-filter-bar>
<!-- 项目看板 -->
<app-project-kanban
[corePhases]="corePhases"
[projects]="filteredProjects"
(viewProject)="viewProjectDetailsByPhase($event.projectId, $event.phaseId)"
(openSmartMatch)="openSmartMatch($event)"
(reviewProject)="reviewProjectQuality($event)">
</app-project-kanban>
<!-- 待办任务 -->
<app-todo-section
[todoTasksFromIssues]="todoTasksFromIssues"
[urgentEvents]="urgentEvents"
(refresh)="refreshTodoTasks()"
(navigateToIssue)="navigateToIssue($event)"
(resolveUrgentEvent)="resolveUrgentEvent($event)">
</app-todo-section>
<!-- 工作负载甘特图 -->
<app-workload-gantt
[designerWorkloadMap]="designerWorkloadMap"
[realDesigners]="realDesigners"
(employeeClick)="onEmployeeClick($event)">
</app-workload-gantt>
重构完成日期: 2024-11-21 负责人: AI Assistant 审核状态: ✅ 待人工审核