import { Component, OnInit, inject, signal, computed } from '@angular/core'; import { CommonModule } from '@angular/common'; import { RouterModule } from '@angular/router'; import { FormsModule } from '@angular/forms'; import { FaIconComponent } from '@fortawesome/angular-fontawesome'; import { faTicket, faFilter, faCircleCheck, faClock, faXmark, faPlus, faChevronDown, faChevronUp, faTriangleExclamation } from '@fortawesome/free-solid-svg-icons'; import { PageHeaderComponent } from '../../../shared/components/page-header/page-header.component'; import { StatCardComponent } from '../../../shared/components/stat-card/stat-card.component'; import { DataTableComponent } from '../../../shared/components/data-table/data-table.component'; import { FilterBarComponent, FilterOption } from '../../../shared/components/filter-bar/filter-bar.component'; import { ConfirmDialogComponent } from '../../../shared/components/confirm-dialog/confirm-dialog.component'; import { MessageStripComponent } from '../../../shared/components/message-strip/message-strip.component'; import { EmptyStateComponent } from '../../../shared/components/empty-state/empty-state.component'; import { MockDataService } from '../../../core/services/mock-data.service'; import { WorkOrder } from '../../../core/models'; @Component({ selector: 'app-work-orders', standalone: true, imports: [ CommonModule, RouterModule, FormsModule, FaIconComponent, PageHeaderComponent, StatCardComponent, DataTableComponent, FilterBarComponent, ConfirmDialogComponent, MessageStripComponent, EmptyStateComponent ], templateUrl: './work-orders.component.html' }) export class WorkOrdersComponent implements OnInit { private mockData = inject(MockDataService); readonly faTicket = faTicket; readonly faCircleCheck = faCircleCheck; readonly faClock = faClock; readonly faXmark = faXmark; readonly faChevronDown = faChevronDown; readonly faChevronUp = faChevronUp; readonly faTriangleExclamation = faTriangleExclamation; workOrders = signal([]); loading = signal(true); expandedId = signal(null); showConfirmDialog = signal(false); selectedOrder = signal(null); confirmAction = signal<'resolve' | 'close'>('resolve'); confirmLoading = signal(false); successMessage = signal(''); filters = signal([ { key: 'priority', label: '优先级', type: 'select', options: [ { label: '全部', value: '' }, { label: '高', value: 'high' }, { label: '中', value: 'medium' }, { label: '低', value: 'low' } ], value: '' }, { key: 'status', label: '状态', type: 'select', options: [ { label: '全部', value: '' }, { label: '待处理', value: 'open' }, { label: '处理中', value: 'in_progress' }, { label: '已解决', value: 'resolved' }, { label: '已关闭', value: 'closed' } ], value: '' } ]); activeFilterCount = computed(() => this.filters().filter(f => f.value !== '').length); filteredOrders = computed(() => { let orders = this.workOrders(); const pf = this.filters()[0].value; const sf = this.filters()[1].value; if (pf) orders = orders.filter(o => o.priority === pf); if (sf) orders = orders.filter(o => o.status === sf); return orders; }); openCount = computed(() => this.workOrders().filter(o => o.status === 'open').length); inProgressCount = computed(() => this.workOrders().filter(o => o.status === 'in_progress').length); resolvedCount = computed(() => this.workOrders().filter(o => o.status === 'resolved').length); tableColumns = [ { key: 'title', label: '工单标题', sortable: true }, { key: 'groupName', label: '群名称', sortable: true }, { key: 'assignedToName', label: '负责人', sortable: true }, { key: 'priority', label: '优先级', template: 'status' as const }, { key: 'status', label: '状态', template: 'status' as const }, { key: 'deadline', label: '截止日期', sortable: true }, { key: 'createdAt', label: '创建时间', sortable: true } ]; ngOnInit(): void { this.loadData(); } loadData(): void { this.loading.set(true); this.workOrders.set([]); this.loading.set(false); } toggleExpand(id: string): void { this.expandedId.update(curr => curr === id ? null : id); } onFilterChange(filters: FilterOption[]): void { this.filters.set(filters); } onApply(): void {} onReset(): void { this.filters.update(fs => fs.map(f => ({ ...f, value: '' }))); } onRowClick(order: WorkOrder): void { this.toggleExpand(order.id); } openResolveDialog(order: WorkOrder): void { this.selectedOrder.set(order); this.confirmAction.set('resolve'); this.showConfirmDialog.set(true); } openCloseDialog(order: WorkOrder): void { this.selectedOrder.set(order); this.confirmAction.set('close'); this.showConfirmDialog.set(true); } onConfirm(): void { const order = this.selectedOrder(); if (!order) return; this.confirmLoading.set(true); setTimeout(() => { this.workOrders.update(orders => { const next = orders.map(o => { if (o.id === order.id) { const newStatus = this.confirmAction() === 'resolve' ? 'resolved' as const : 'closed' as const; return { ...o, status: newStatus, resolvedAt: new Date(), resolution: this.confirmAction() === 'resolve' ? '已处理完成' : '已关闭工单', resolutionLog: [...o.resolutionLog, `[${new Date().toLocaleString('zh-CN')}] ${this.confirmAction() === 'resolve' ? '已解决' : '已关闭'}`] }; } return o; }); this.mockData.saveWorkOrders(next); return next; }); this.confirmLoading.set(false); this.showConfirmDialog.set(false); this.selectedOrder.set(null); this.successMessage.set(`工单「${order.title}」已${this.confirmAction() === 'resolve' ? '解决' : '关闭'}`); setTimeout(() => this.successMessage.set(''), 3000); }, 500); } onCancel(): void { this.showConfirmDialog.set(false); this.selectedOrder.set(null); } }