| 
					
				 | 
			
			
				@@ -1,823 +0,0 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import { Component, OnInit, signal, computed, Inject } from '@angular/core'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import { CommonModule } from '@angular/common'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import { FormsModule } from '@angular/forms'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import { MatButtonModule } from '@angular/material/button'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import { MatCardModule } from '@angular/material/card'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import { MatIconModule } from '@angular/material/icon'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import { MatDialogModule, MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import { MatTabsModule } from '@angular/material/tabs'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import { MatTooltipModule } from '@angular/material/tooltip'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import { MatTableModule } from '@angular/material/table'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import { Asset, AssetType, AssetStatus, AssetAssignment, Employee } from '../../../models/hr.model'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// 资产分配对话框组件 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-@Component({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  selector: 'app-asset-assignment-dialog', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  standalone: true, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  imports: [ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    CommonModule, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    FormsModule, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    MatButtonModule, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    MatIconModule 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  ], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  template: ` 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    <div class="dialog-header"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      <h2>{{ isEdit ? '修改资产分配' : '分配资产' }}</h2> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      <button class="close-btn" (click)="dialogRef.close()"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          <line x1="18" y1="6" x2="6" y2="18"></line> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          <line x1="6" y1="6" x2="18" y2="18"></line> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        </svg> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      </button> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    <div class="dialog-content"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      <div class="info-item"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <label>资产名称:</label> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <span>{{ asset.name }}</span> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      <div class="form-group"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <label>选择员工:</label> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <input  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          type="text"  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          [(ngModel)]="selectedEmployeeName" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          (input)="filterEmployees($event.target.value)" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          placeholder="搜索员工姓名或工号..." 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          class="employee-search" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          [disabled]="isReturning" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        > 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <div class="employee-dropdown" *ngIf="showEmployeeDropdown && !isReturning"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          <div *ngFor="let employee of filteredEmployees"  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-               class="employee-item"  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-               (click)="selectEmployee(employee)"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <span class="employee-name">{{ employee.name }}</span> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <span class="employee-id">{{ employee.employeeId }}</span> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      <div class="form-group" *ngIf="!isReturning"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <label>分配开始日期:</label> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <input type="date" [(ngModel)]="startDate" class="date-input"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      <div class="form-group" *ngIf="!isReturning"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <label>预计归还日期:</label> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <input type="date" [(ngModel)]="endDate" class="date-input"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      <div class="form-group" *ngIf="isReturning"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <label>实际归还日期:</label> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <input type="date" [(ngModel)]="returnDate" class="date-input"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      <div class="form-group"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <label>备注:</label> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <textarea  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          [(ngModel)]="notes"  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          placeholder="请输入备注信息..."  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          rows="3" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          class="notes-input" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ></textarea> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    <div class="dialog-actions"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      <button mat-button (click)="dialogRef.close()">取消</button> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      <button mat-raised-button color="primary" (click)="submit()"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        {{ isReturning ? '确认归还' : '确认分配' }} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      </button> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  `, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  styles: [` 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    .dialog-header { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      display: flex; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      justify-content: space-between; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      align-items: center; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      margin-bottom: 24px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      padding-bottom: 16px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      border-bottom: 1px solid #e5e7eb; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    .close-btn { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      background: none; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      border: none; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      cursor: pointer; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      color: #6b7280; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      padding: 4px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    .dialog-content { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      max-width: 500px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    .info-item { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      display: flex; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      justify-content: space-between; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      margin-bottom: 16px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      padding: 8px 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      border-bottom: 1px solid #f3f4f6; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    .form-group { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      margin-bottom: 20px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      position: relative; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    label { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      display: block; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      margin-bottom: 4px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      font-weight: 500; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      color: #374151; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    .employee-search, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    .date-input { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      width: 100%; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      padding: 8px 12px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      border: 1px solid #e5e7eb; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      border-radius: 6px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      font-size: 14px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    .employee-dropdown { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      position: absolute; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      top: 100%; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      left: 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      right: 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      background-color: white; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      border: 1px solid #e5e7eb; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      border-radius: 6px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      max-height: 200px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      overflow-y: auto; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      z-index: 1000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    .employee-item { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      padding: 10px 12px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      cursor: pointer; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      transition: background-color 0.2s; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      display: flex; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      justify-content: space-between; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      align-items: center; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    .employee-item:hover { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      background-color: #f3f4f6; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    .employee-name { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      font-weight: 500; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      color: #1f2937; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    .employee-id { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      font-size: 12px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      color: #6b7280; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    .notes-input { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      width: 100%; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      padding: 8px 12px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      border: 1px solid #e5e7eb; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      border-radius: 6px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      font-size: 14px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      resize: vertical; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    .dialog-actions { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      display: flex; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      justify-content: flex-end; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      gap: 12px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      margin-top: 24px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  `] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-}) class AssetAssignmentDialog { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  asset: Asset; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  employees: Employee[] = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  filteredEmployees: Employee[] = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  showEmployeeDropdown = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  selectedEmployeeId = ''; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  selectedEmployeeName = ''; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  startDate = new Date().toISOString().split('T')[0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  endDate = ''; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  returnDate = new Date().toISOString().split('T')[0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  notes = ''; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  isEdit = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  isReturning = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  constructor( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    public dialogRef: MatDialogRef<AssetAssignmentDialog>, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    @Inject(MAT_DIALOG_DATA) public data: any 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.asset = data.asset; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.employees = data.employees; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.filteredEmployees = [...this.employees]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.isEdit = data.isEdit || false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.isReturning = data.isReturning || false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (this.isEdit && data.assignment) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      const assignment = data.assignment; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      const employee = this.employees.find(e => e.id === assignment.employeeId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (employee) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.selectedEmployeeId = employee.id; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.selectedEmployeeName = employee.name; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (assignment.startDate) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.startDate = new Date(assignment.startDate).toISOString().split('T')[0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (assignment.endDate) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.endDate = new Date(assignment.endDate).toISOString().split('T')[0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  filterEmployees(query: string) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (!query.trim()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.filteredEmployees = [...this.employees]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      const term = query.toLowerCase(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.filteredEmployees = this.employees.filter(emp =>  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        emp.name.toLowerCase().includes(term) || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        emp.employeeId.toLowerCase().includes(term) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.showEmployeeDropdown = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  selectEmployee(employee: Employee) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.selectedEmployeeId = employee.id; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.selectedEmployeeName = employee.name; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.showEmployeeDropdown = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  submit() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (!this.selectedEmployeeId && !this.isReturning) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      alert('请选择员工'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.dialogRef.close({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      employeeId: this.selectedEmployeeId, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      startDate: this.startDate, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      endDate: this.isReturning ? this.returnDate : this.endDate, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      notes: this.notes 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// 报修对话框组件 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-@Component({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  selector: 'app-asset-repair-dialog', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  standalone: true, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  imports: [ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    CommonModule, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    FormsModule, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    MatButtonModule, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    MatIconModule 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  ], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  template: ` 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    <div class="dialog-header"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      <h2>资产报修</h2> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      <button class="close-btn" (click)="dialogRef.close()"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          <line x1="18" y1="6" x2="6" y2="18"></line> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          <line x1="6" y1="6" x2="18" y2="18"></line> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        </svg> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      </button> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    <div class="dialog-content"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      <div class="info-item"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <label>资产名称:</label> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <span>{{ asset.name }}</span> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      <div class="info-item"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <label>资产类型:</label> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <span>{{ asset.type }}</span> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      <div class="info-item"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <label>序列号:</label> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <span>{{ asset.serialNumber || '无' }}</span> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      <div class="form-group"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <label>故障描述 *:</label> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <textarea  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          [(ngModel)]="problemDescription"  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          placeholder="请详细描述故障情况..."  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          rows="4" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          class="description-input" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          required 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ></textarea> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      <div class="form-group"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <label>期望修复时间:</label> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <input type="date" [(ngModel)]="expectedFixDate" class="date-input"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      <div class="form-group"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <label>联系人:</label> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <input type="text" [(ngModel)]="contactPerson" class="contact-input" placeholder="请输入联系人姓名"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      <div class="form-group"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <label>联系电话:</label> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <input type="text" [(ngModel)]="contactPhone" class="phone-input" placeholder="请输入联系电话"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    <div class="dialog-actions"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      <button mat-button (click)="dialogRef.close()">取消</button> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      <button mat-raised-button color="primary" (click)="submit()" [disabled]="!problemDescription.trim()"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        提交报修申请 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      </button> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  `, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  styles: [` 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    .dialog-header { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      display: flex; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      justify-content: space-between; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      align-items: center; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      margin-bottom: 24px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      padding-bottom: 16px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      border-bottom: 1px solid #e5e7eb; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    .close-btn { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      background: none; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      border: none; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      cursor: pointer; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      color: #6b7280; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      padding: 4px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    .dialog-content { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      max-width: 500px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    .info-item { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      display: flex; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      justify-content: space-between; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      margin-bottom: 16px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      padding: 8px 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      border-bottom: 1px solid #f3f4f6; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    .form-group { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      margin-bottom: 20px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    label { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      display: block; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      margin-bottom: 4px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      font-weight: 500; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      color: #374151; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    .description-input, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    .date-input, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    .contact-input, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    .phone-input { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      width: 100%; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      padding: 8px 12px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      border: 1px solid #e5e7eb; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      border-radius: 6px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      font-size: 14px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    .description-input { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      resize: vertical; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    .dialog-actions { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      display: flex; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      justify-content: flex-end; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      gap: 12px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      margin-top: 24px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  `] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-}) class AssetRepairDialog { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  asset: Asset; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  problemDescription = ''; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  expectedFixDate = new Date().toISOString().split('T')[0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  contactPerson = ''; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  contactPhone = ''; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  constructor( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    public dialogRef: MatDialogRef<AssetRepairDialog>, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    @Inject(MAT_DIALOG_DATA) public data: any 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.asset = data.asset; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  submit() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (!this.problemDescription.trim()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      alert('请填写故障描述'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.dialogRef.close({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      problemDescription: this.problemDescription, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      expectedFixDate: this.expectedFixDate, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      contactPerson: this.contactPerson, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      contactPhone: this.contactPhone 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// 生成模拟资产数据 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-const generateMockAssets = (): Asset[] => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  const assets: Asset[] = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  const types: AssetType[] = ['电脑', '外设', '软件账号', '域名', '其他']; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  const statuses: AssetStatus[] = ['空闲', '占用', '故障', '报修中']; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  const departments = ['设计部', '客户服务部', '财务部', '人力资源部']; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  const computerModels = ['MacBook Pro', 'Dell XPS', 'HP EliteBook', 'Lenovo ThinkPad', 'Surface Laptop']; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  const peripheralTypes = ['显示器', '键盘', '鼠标', '打印机', '扫描仪', '投影仪']; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  const softwareTypes = ['Adobe Creative Cloud', 'AutoCAD', 'Office 365', '渲染农场账号', '素材库账号']; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  const otherAssets = ['办公桌', '办公椅', '服务器', '网络设备', '空调']; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  for (let i = 1; i <= 30; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    const type = types[Math.floor(Math.random() * types.length)]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    const status = statuses[Math.floor(Math.random() * statuses.length)]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    const purchaseDate = new Date(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    purchaseDate.setMonth(purchaseDate.getMonth() - Math.floor(Math.random() * 36)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    let name = ''; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    let serialNumber = `SN${Math.floor(Math.random() * 1000000)}`; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    switch (type) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      case '电脑': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        name = `${computerModels[Math.floor(Math.random() * computerModels.length)]} ${2020 + Math.floor(Math.random() * 4)}`; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      case '外设': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        name = peripheralTypes[Math.floor(Math.random() * peripheralTypes.length)]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      case '软件账号': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        name = softwareTypes[Math.floor(Math.random() * softwareTypes.length)]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        serialNumber = '无'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      case '域名': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        name = `example-${i}.com`; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        serialNumber = '无'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      case '其他': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        name = otherAssets[Math.floor(Math.random() * otherAssets.length)]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    const value = Math.floor(Math.random() * 10000) + 500; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    const assignedTo = status === '占用' ? `emp-${Math.floor(Math.random() * 10) + 1}` : undefined; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    const assignedToName = assignedTo ? `员工${Math.floor(Math.random() * 20) + 1}` : undefined; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // 随机设置保修截止日期 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    const warrantyExpiry = new Date(purchaseDate); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    warrantyExpiry.setFullYear(warrantyExpiry.getFullYear() + (Math.random() > 0.5 ? 1 : 2)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    assets.push({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      id: `asset-${i}`, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      name, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      type, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      status, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      purchaseDate, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      value, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      assignedTo, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      assignedToName, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      department: departments[Math.floor(Math.random() * departments.length)], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      description: `这是一台${name},用于日常办公和项目开发。`, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      serialNumber, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      warrantyExpiry 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  return assets; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// 生成模拟员工数据 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-const generateMockEmployees = (): Employee[] => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  const employees: Employee[] = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  const departments = ['设计部', '客户服务部', '财务部', '人力资源部']; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  const positions = ['设计师', '客服专员', '财务专员', '人事专员', '经理', '助理']; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  const names = ['张三', '李四', '王五', '赵六', '钱七', '孙八', '周九', '吴十']; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  for (let i = 1; i <= 20; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    employees.push({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      id: `emp-${i}`, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      name: names[i % names.length] + i, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      department: departments[Math.floor(Math.random() * departments.length)], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      position: positions[Math.floor(Math.random() * positions.length)], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      employeeId: `EMP2023${String(i).padStart(3, '0')}`, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      phone: `138${Math.floor(Math.random() * 100000000)}`, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      email: `employee${i}@example.com`, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      gender: i % 2 === 0 ? '女' : '男', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      birthDate: new Date(1980 + Math.floor(Math.random() * 20), Math.floor(Math.random() * 12), Math.floor(Math.random() * 28) + 1), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      hireDate: new Date(2020 + Math.floor(Math.random() * 3), Math.floor(Math.random() * 12), Math.floor(Math.random() * 28) + 1), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      status: '在职' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  return employees; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// 生成模拟资产分配记录 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-const generateMockAssignments = (): AssetAssignment[] => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  const assignments: AssetAssignment[] = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  for (let i = 1; i <= 15; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    const startDate = new Date(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    startDate.setMonth(startDate.getMonth() - Math.floor(Math.random() * 6)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    const endDate = Math.random() > 0.5 ? new Date(startDate) : undefined; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (endDate) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      endDate.setMonth(endDate.getMonth() + Math.floor(Math.random() * 3) + 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    assignments.push({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      id: `assignment-${i}`, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      assetId: `asset-${Math.floor(Math.random() * 20) + 1}`, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      employeeId: `emp-${Math.floor(Math.random() * 15) + 1}`, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      startDate, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      endDate, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      status: endDate ? '已归还' : '进行中' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  return assignments; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// 主组件 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-@Component({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  selector: 'app-assets-stats', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  standalone: true, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  imports: [ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    CommonModule, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    FormsModule, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    MatButtonModule, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    MatCardModule, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    MatIconModule, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    MatDialogModule, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    MatTabsModule, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    MatTooltipModule, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    MatTableModule 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  ], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  templateUrl: './assets-stats.html', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  styleUrl: './assets-stats.scss' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-}) export class AssetsStats implements OnInit { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  // 暴露Math对象给模板使用 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  readonly Math = Math; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  // 数据 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  assets = signal<Asset[]>([]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  employees = signal<Employee[]>([]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  assignments = signal<AssetAssignment[]>([]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  selectedView = signal<'grid' | 'list'>('grid'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  searchTerm = signal(''); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  typeFilter = signal<AssetType | ''>(''); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  statusFilter = signal<AssetStatus | ''>(''); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  departmentFilter = signal(''); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  // 计算属性 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  filteredAssets = computed(() => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    let filtered = this.assets(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // 按搜索词筛选 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (this.searchTerm()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      const term = this.searchTerm().toLowerCase(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      filtered = filtered.filter(asset =>  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        asset.name.toLowerCase().includes(term) || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        (asset.serialNumber && asset.serialNumber.toLowerCase().includes(term)) || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        (asset.department && asset.department.toLowerCase().includes(term)) || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        (asset.assignedToName && asset.assignedToName.toLowerCase().includes(term)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // 按类型筛选 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (this.typeFilter()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      filtered = filtered.filter(asset => asset.type === this.typeFilter()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // 按状态筛选 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (this.statusFilter()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      filtered = filtered.filter(asset => asset.status === this.statusFilter()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // 按部门筛选 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (this.departmentFilter()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      filtered = filtered.filter(asset => asset.department === this.departmentFilter()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return filtered; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  // 资产统计 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  assetStats = computed(() => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    const total = this.assets().length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    const occupied = this.assets().filter(a => a.status === '占用').length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    const idle = this.assets().filter(a => a.status === '空闲').length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    const faulty = this.assets().filter(a => a.status === '故障').length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    const repairing = this.assets().filter(a => a.status === '报修中').length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    const totalValue = this.assets().reduce((sum, asset) => sum + asset.value, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // 按类型统计 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    const typeStats = new Map<AssetType, { count: number, value: number }>(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.assets().forEach(asset => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      const current = typeStats.get(asset.type) || { count: 0, value: 0 }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      current.count++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      current.value += asset.value; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      typeStats.set(asset.type, current); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // 转换为数组格式以便在模板中使用 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    const typeStatsArray = Array.from(typeStats.entries()).map(([key, value]) => ({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      type: key, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      ...value 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    })); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // 按部门统计 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    const departmentStats = new Map<string, { count: number, value: number }>(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.assets().forEach(asset => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      const department = asset.department || '未知部门'; // 提供默认值 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      const current = departmentStats.get(department) || { count: 0, value: 0 }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      current.count++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      current.value += asset.value; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      departmentStats.set(department, current); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // 转换为数组格式以便在模板中使用 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    const departmentStatsArray = Array.from(departmentStats.entries()).map(([key, value]) => ({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      department: key, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      ...value 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    })); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // 使用时长统计(模拟数据) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    const usageStats = [ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      { type: '电脑', avgHours: Math.floor(Math.random() * 40) + 100 }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      { type: '外设', avgHours: Math.floor(Math.random() * 30) + 80 }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      { type: '软件账号', avgHours: Math.floor(Math.random() * 50) + 120 }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      { type: '域名', avgHours: Math.floor(Math.random() * 20) + 60 }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      { type: '其他', avgHours: Math.floor(Math.random() * 20) + 40 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    ]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      total, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      occupied, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      idle, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      faulty, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      repairing, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      totalValue, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      typeStats, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      typeStatsArray, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      departmentStats, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      departmentStatsArray, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      usageStats 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  // 获取资产类型列表 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  assetTypes = computed(() => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return Array.from(new Set(this.assets().map(asset => asset.type))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  // 获取部门列表 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  departments = computed(() => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return Array.from(new Set(this.assets().map(asset => asset.department))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  constructor(private dialog: MatDialog) {} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  ngOnInit() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // 加载模拟数据 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.assets.set(generateMockAssets()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.employees.set(generateMockEmployees()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.assignments.set(generateMockAssignments()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  // 切换视图(网格/列表) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  switchView(view: 'grid' | 'list') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.selectedView.set(view); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  // 格式化日期 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  formatDate(date: Date): string { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (!date) return ''; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    const d = new Date(date); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  // 格式化金额 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  formatCurrency(amount: number): string { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return new Intl.NumberFormat('zh-CN', { style: 'currency', currency: 'CNY' }).format(amount); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  // 获取状态样式类 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  getStatusClass(status: string): string { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    switch (status) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      case '空闲': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return 'status-idle'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      case '占用': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return 'status-occupied'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      case '故障': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return 'status-faulty'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      case '报修中': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return 'status-repairing'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      default: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return ''; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  // 获取类型图标 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  getTypeIcon(type: AssetType): string { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    switch (type) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      case '电脑': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return 'laptop'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      case '外设': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return 'devices'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      case '软件账号': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return 'cloud'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      case '域名': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return 'link'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      case '其他': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return 'category'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      default: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return 'help'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  // 打开资产分配对话框 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  openAssignmentDialog(asset: Asset, isReturning: boolean = false) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    let assignment: AssetAssignment | undefined; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (isReturning) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      assignment = this.assignments().find(a => a.assetId === asset.id && a.status === '进行中'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    const dialogRef = this.dialog.open(AssetAssignmentDialog, { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      width: '500px', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      maxWidth: '90vw', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      disableClose: true, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      data: { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        asset, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        employees: this.employees(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        isEdit: !!assignment, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        isReturning, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        assignment 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    dialogRef.afterClosed().subscribe(result => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (result) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (isReturning && assignment) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // 更新归还信息 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          this.assignments.update(assignments =>  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            assignments.map(a =>  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              a.id === assignment!.id ? { ...a, endDate: result.endDate, status: '已归还' } : a 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-           
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // 更新资产状态为空闲 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          this.assets.update(assets =>  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            assets.map(a =>  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              a.id === asset.id ? { ...a, status: '空闲', assignedTo: undefined, assignedToName: undefined } : a 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // 创建新分配记录 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          const newAssignment: AssetAssignment = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            id: `assignment-${Date.now()}`, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            assetId: asset.id, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            employeeId: result.employeeId, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            startDate: new Date(result.startDate), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            endDate: result.endDate ? new Date(result.endDate) : undefined, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            status: '进行中' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-           
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          this.assignments.update(assignments => [newAssignment, ...assignments]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-           
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // 更新资产状态为占用 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          const employee = this.employees().find(e => e.id === result.employeeId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          this.assets.update(assets =>  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            assets.map(a =>  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              a.id === asset.id ? { ...a, status: '占用', assignedTo: result.employeeId, assignedToName: employee?.name } : a 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        alert(isReturning ? '资产归还成功' : '资产分配成功'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  // 打开报修对话框 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  openRepairDialog(asset: Asset) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    const dialogRef = this.dialog.open(AssetRepairDialog, { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      width: '500px', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      maxWidth: '90vw', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      disableClose: true, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      data: { asset } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    dialogRef.afterClosed().subscribe(result => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (result) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // 更新资产状态为报修中 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.assets.update(assets =>  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          assets.map(a =>  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            a.id === asset.id ? { ...a, status: '报修中' } : a 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        alert('报修申请已提交'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  // 导出资产台账 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  exportAssetLedger() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    alert('资产台账导出功能待实现'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  // 重置筛选条件 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  resetFilters() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.searchTerm.set(''); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.typeFilter.set(''); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.statusFilter.set(''); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.departmentFilter.set(''); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  // 获取资产使用情况 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  getAssetUsage(assetId: string): AssetAssignment | undefined { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return this.assignments().find(a => a.assetId === assetId && a.status === '进行中'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  // 获取员工姓名 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  getEmployeeName(employeeId: string): string { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    const employee = this.employees().find(e => e.id === employeeId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return employee ? employee.name : '未知员工'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-} 
			 |