| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168 |
- 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<WorkOrder[]>([]);
- loading = signal(true);
- expandedId = signal<string | null>(null);
- showConfirmDialog = signal(false);
- selectedOrder = signal<WorkOrder | null>(null);
- confirmAction = signal<'resolve' | 'close'>('resolve');
- confirmLoading = signal(false);
- successMessage = signal('');
- filters = signal<FilterOption[]>([
- { 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);
- }
- }
|