import { Component, OnInit, signal } from '@angular/core'; import { CommonModule } from '@angular/common'; import { RouterModule } from '@angular/router'; import { FormsModule } from '@angular/forms'; import { MatButtonModule } from '@angular/material/button'; import { MatIconModule } from '@angular/material/icon'; import { MatTableModule } from '@angular/material/table'; import { MatInputModule } from '@angular/material/input'; import { MatSelectModule } from '@angular/material/select'; import { MatPaginatorModule } from '@angular/material/paginator'; import { MatDialogModule, MatDialog } from '@angular/material/dialog'; import { MatSortModule } from '@angular/material/sort'; import { ProjectDialogComponent } from './project-dialog/project-dialog'; interface Project { id: string; name: string; customer: string; status: 'pending' | 'in-progress' | 'completed' | 'on-hold'; designer: string; startDate: string; endDate: string; budget: number; progress: number; } @Component({ selector: 'app-project-management', standalone: true, imports: [ CommonModule, RouterModule, FormsModule, MatButtonModule, MatIconModule, MatTableModule, MatInputModule, MatSelectModule, MatPaginatorModule, MatDialogModule, MatSortModule, ProjectDialogComponent ], templateUrl: './project-management.html', styleUrl: './project-management.scss' }) export class ProjectManagement implements OnInit { projects = signal([]); filteredProjects = signal([]); searchTerm = ''; statusFilter = ''; sortColumn = 'startDate'; sortDirection = 'desc'; pageSize = 10; currentPage = 0; // 状态颜色映射 statusColors: Record = { 'pending': '#FFAA00', 'in-progress': '#165DFF', 'completed': '#00B42A', 'on-hold': '#F53F3F' }; // 状态文本映射 statusTexts: Record = { 'pending': '待开始', 'in-progress': '进行中', 'completed': '已完成', 'on-hold': '暂停中' }; constructor(private dialog: MatDialog) {} ngOnInit(): void { this.loadProjects(); } loadProjects(): void { // 模拟项目数据 this.projects.set([ { id: '1', name: '现代简约风格三居室设计', customer: '王先生', status: 'in-progress', designer: '张设计师', startDate: '2025-09-01', endDate: '2025-10-15', budget: 85000, progress: 65 }, { id: '2', name: '北欧风格两居室设计', customer: '李女士', status: 'completed', designer: '刘设计师', startDate: '2025-08-15', endDate: '2025-09-30', budget: 68000, progress: 100 }, { id: '3', name: '工业风办公室设计', customer: '赵先生', status: 'pending', designer: '王设计师', startDate: '2025-09-15', endDate: '2025-11-05', budget: 120000, progress: 0 }, { id: '4', name: '新中式别墅设计', customer: '钱女士', status: 'on-hold', designer: '张设计师', startDate: '2025-08-20', endDate: '2025-11-20', budget: 250000, progress: 40 }, { id: '5', name: '日式小户型设计', customer: '孙先生', status: 'in-progress', designer: '刘设计师', startDate: '2025-09-05', endDate: '2025-10-20', budget: 55000, progress: 35 }, { id: '6', name: '美式乡村风格设计', customer: '周女士', status: 'in-progress', designer: '王设计师', startDate: '2025-09-08', endDate: '2025-10-30', budget: 75000, progress: 25 }, { id: '7', name: '极简主义公寓设计', customer: '吴先生', status: 'pending', designer: '张设计师', startDate: '2025-09-20', endDate: '2025-11-10', budget: 60000, progress: 0 }, { id: '8', name: '地中海风格别墅设计', customer: '郑女士', status: 'completed', designer: '刘设计师', startDate: '2025-08-01', endDate: '2025-09-15', budget: 180000, progress: 100 }, { id: '9', name: '后现代风格办公室设计', customer: '王总', status: 'in-progress', designer: '王设计师', startDate: '2025-08-25', endDate: '2025-10-15', budget: 95000, progress: 50 }, { id: '10', name: '新古典主义住宅设计', customer: '陈女士', status: 'on-hold', designer: '张设计师', startDate: '2025-08-10', endDate: '2025-11-01', budget: 130000, progress: 30 } ]); this.applyFilters(); } applyFilters(): void { let result = [...this.projects()]; // 搜索过滤 if (this.searchTerm) { const term = this.searchTerm.toLowerCase(); result = result.filter(project => project.name.toLowerCase().includes(term) || project.customer.toLowerCase().includes(term) || project.designer.toLowerCase().includes(term) ); } // 状态过滤 if (this.statusFilter) { result = result.filter(project => project.status === this.statusFilter); } // 排序 result.sort((a, b) => { if (this.sortColumn === 'startDate' || this.sortColumn === 'endDate') { const dateA = new Date(a[this.sortColumn]).getTime(); const dateB = new Date(b[this.sortColumn]).getTime(); return this.sortDirection === 'asc' ? dateA - dateB : dateB - dateA; } else if (this.sortColumn === 'budget' || this.sortColumn === 'progress') { return this.sortDirection === 'asc' ? a[this.sortColumn] - b[this.sortColumn] : b[this.sortColumn] - a[this.sortColumn]; } else { const valueA = a[this.sortColumn as keyof Project]?.toString().toLowerCase() || ''; const valueB = b[this.sortColumn as keyof Project]?.toString().toLowerCase() || ''; return this.sortDirection === 'asc' ? valueA.localeCompare(valueB) : valueB.localeCompare(valueA); } }); this.filteredProjects.set(result); } onSearch(): void { this.applyFilters(); } onStatusFilterChange(): void { this.applyFilters(); } onSort(column: string): void { if (this.sortColumn === column) { this.sortDirection = this.sortDirection === 'asc' ? 'desc' : 'asc'; } else { this.sortColumn = column; this.sortDirection = 'asc'; } this.applyFilters(); } openProjectDialog(project?: Project): void { const dialogRef = this.dialog.open(ProjectDialogComponent, { width: '600px', data: project ? { ...project } : { id: '', name: '', client: '', designer: '', status: 'pending', priority: 'medium', startDate: new Date().toISOString().split('T')[0], endDate: '', budget: 0, progress: 0, description: '', tasks: [] } }); dialogRef.afterClosed().subscribe(result => { if (result) { if (result.id) { // 更新项目 this.updateProject(result); } else { // 创建新项目 this.createProject(result); } } }); } createProject(projectData: Omit): void { const newProject: Project = { ...projectData, id: (this.projects().length + 1).toString() }; this.projects.set([newProject, ...this.projects()]); this.applyFilters(); } updateProject(updatedProject: Project): void { this.projects.set(this.projects().map(project => project.id === updatedProject.id ? updatedProject : project )); this.applyFilters(); } deleteProject(id: string): void { if (confirm('确定要删除这个项目吗?')) { this.projects.set(this.projects().filter(project => project.id !== id)); this.applyFilters(); } } formatCurrency(amount: number): string { return new Intl.NumberFormat('zh-CN', { style: 'currency', currency: 'CNY', minimumFractionDigits: 0 }).format(amount); } get paginatedProjects(): Project[] { const startIndex = this.currentPage * this.pageSize; return this.filteredProjects().slice(startIndex, startIndex + this.pageSize); } get totalPages(): number { return Math.ceil(this.filteredProjects().length / this.pageSize); } onPageChange(page: number): void { this.currentPage = page; } }