assets.html 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. <div class="assets-container">
  2. <header class="page-header">
  3. <h1>花名册与档案库</h1>
  4. <p class="page-description">管理员工全维度信息,包括基本信息、合同管理和证件管理</p>
  5. </header>
  6. <!-- 顶部操作栏 -->
  7. <div class="action-bar">
  8. <div class="action-buttons">
  9. <button mat-raised-button color="primary" class="add-btn" (click)="openAddEmployeeDialog()">
  10. <mat-icon>add</mat-icon>
  11. 新增员工
  12. </button>
  13. <div class="batch-actions" [class.hidden]="selectedEmployees().length === 0">
  14. <button mat-button color="warn" (click)="batchDelete()" class="batch-btn">
  15. <mat-icon>delete</mat-icon>
  16. 批量删除
  17. </button>
  18. <div class="export-dropdown">
  19. <button mat-button class="batch-btn" [matMenuTriggerFor]="exportMenu">
  20. <mat-icon>file_download</mat-icon>
  21. 导出
  22. <mat-icon>expand_more</mat-icon>
  23. </button>
  24. <mat-menu #exportMenu="matMenu">
  25. <button mat-menu-item (click)="exportData('excel')">
  26. <mat-icon>insert_drive_file</mat-icon>
  27. Excel
  28. </button>
  29. <button mat-menu-item (click)="exportData('pdf')">
  30. <mat-icon>picture_as_pdf</mat-icon>
  31. PDF
  32. </button>
  33. </mat-menu>
  34. </div>
  35. </div>
  36. </div>
  37. <div class="search-filters">
  38. <div class="search-container">
  39. <mat-icon class="search-icon">search</mat-icon>
  40. <input
  41. matInput
  42. placeholder="搜索员工姓名、工号、手机号或邮箱..."
  43. [value]="searchTerm()"
  44. (input)="searchTerm.set($event.target.value)"
  45. (keyup.enter)="applyFilters()"
  46. class="search-input"
  47. >
  48. <button mat-icon-button *ngIf="searchTerm()" (click)="searchTerm.set('')" class="clear-search">
  49. <mat-icon>close</mat-icon>
  50. </button>
  51. </div>
  52. <div class="filter-container">
  53. <mat-select placeholder="部门" [value]="departmentFilter()" (selectionChange)="departmentFilter.set($event.value); applyFilters()">
  54. <mat-option value="">全部部门</mat-option>
  55. <mat-option *ngFor="let dept of departments" [value]="dept.name">{{ dept.name }}</mat-option>
  56. </mat-select>
  57. </div>
  58. <div class="filter-container">
  59. <mat-select placeholder="状态" [value]="statusFilter()" (selectionChange)="statusFilter.set($event.value); applyFilters()">
  60. <mat-option value="">全部状态</mat-option>
  61. <mat-option *ngFor="let status of statuses" [value]="status">{{ status }}</mat-option>
  62. </mat-select>
  63. </div>
  64. <button mat-raised-button (click)="applyFilters()" class="filter-btn">
  65. <mat-icon>filter_list</mat-icon>
  66. 筛选
  67. </button>
  68. </div>
  69. </div>
  70. <!-- 数据表格 -->
  71. <div class="table-container">
  72. <table mat-table [dataSource]="filteredEmployees()" class="employee-table">
  73. <!-- 复选框列 -->
  74. <ng-container matColumnDef="select">
  75. <th mat-header-cell *matHeaderCellDef>
  76. <mat-checkbox
  77. [checked]="isAllSelected()"
  78. (change)="toggleSelectAll()"
  79. [indeterminate]="selectedEmployees().length > 0 && selectedEmployees().length < filteredEmployees().length"
  80. ></mat-checkbox>
  81. </th>
  82. <td mat-cell *matCellDef="let employee">
  83. <mat-checkbox
  84. [checked]="selectedEmployees().includes(employee.id)"
  85. (change)="toggleEmployeeSelection(employee.id)"
  86. ></mat-checkbox>
  87. </td>
  88. </ng-container>
  89. <!-- 姓名列 -->
  90. <ng-container matColumnDef="name">
  91. <th mat-header-cell *matHeaderCellDef class="name-column">姓名</th>
  92. <td mat-cell *matCellDef="let employee" class="name-column">
  93. <div class="employee-info">
  94. <img [src]="employee.avatar" alt="员工头像" class="employee-avatar">
  95. <span class="employee-name">{{ employee.name }}</span>
  96. </div>
  97. </td>
  98. </ng-container>
  99. <!-- 工号列 -->
  100. <ng-container matColumnDef="employeeId">
  101. <th mat-header-cell *matHeaderCellDef>工号</th>
  102. <td mat-cell *matCellDef="let employee">{{ employee.employeeId }}</td>
  103. </ng-container>
  104. <!-- 部门列 -->
  105. <ng-container matColumnDef="department">
  106. <th mat-header-cell *matHeaderCellDef>部门</th>
  107. <td mat-cell *matCellDef="let employee">{{ employee.department }}</td>
  108. </ng-container>
  109. <!-- 岗位列 -->
  110. <ng-container matColumnDef="position">
  111. <th mat-header-cell *matHeaderCellDef>岗位</th>
  112. <td mat-cell *matCellDef="let employee">{{ employee.position }}</td>
  113. </ng-container>
  114. <!-- 手机号列 -->
  115. <ng-container matColumnDef="phone">
  116. <th mat-header-cell *matHeaderCellDef>手机号</th>
  117. <td mat-cell *matCellDef="let employee">{{ employee.phone }}</td>
  118. </ng-container>
  119. <!-- 邮箱列 -->
  120. <ng-container matColumnDef="email">
  121. <th mat-header-cell *matHeaderCellDef>邮箱</th>
  122. <td mat-cell *matCellDef="let employee">{{ employee.email }}</td>
  123. </ng-container>
  124. <!-- 入职日期列 -->
  125. <ng-container matColumnDef="hireDate">
  126. <th mat-header-cell *matHeaderCellDef>入职日期</th>
  127. <td mat-cell *matCellDef="let employee">{{ formatDate(employee.hireDate) }}</td>
  128. </ng-container>
  129. <!-- 状态列 -->
  130. <ng-container matColumnDef="status">
  131. <th mat-header-cell *matHeaderCellDef>状态</th>
  132. <td mat-cell *matCellDef="let employee">
  133. <mat-select [value]="employee.status" (selectionChange)="changeEmployeeStatus(employee, $event.value)" class="status-select">
  134. <mat-option *ngFor="let status of statuses" [value]="status">{{ status }}</mat-option>
  135. </mat-select>
  136. </td>
  137. </ng-container>
  138. <!-- 合同列 -->
  139. <ng-container matColumnDef="contract">
  140. <th mat-header-cell *matHeaderCellDef>合同</th>
  141. <td mat-cell *matCellDef="let employee">
  142. <div *ngIf="employee.contract" class="contract-info">
  143. <div class="contract-date">{{ formatDate(employee.contract.startDate) }} - {{ formatDate(employee.contract.endDate) }}</div>
  144. <div *ngIf="employee.contract.isExpiringSoon" class="expiring-soon" matTooltip="合同即将到期">
  145. ⚠️ 即将到期
  146. </div>
  147. <button mat-icon-button class="contract-btn" matTooltip="查看合同">
  148. <mat-icon>description</mat-icon>
  149. </button>
  150. </div>
  151. <div *ngIf="!employee.contract" class="no-contract">
  152. 无合同信息
  153. </div>
  154. </td>
  155. </ng-container>
  156. <!-- 操作列 -->
  157. <ng-container matColumnDef="actions">
  158. <th mat-header-cell *matHeaderCellDef>操作</th>
  159. <td mat-cell *matCellDef="let employee" class="actions-column">
  160. <div class="action-buttons">
  161. <button mat-icon-button class="edit-btn" matTooltip="编辑" (click)="editEmployee(employee)">
  162. <mat-icon>edit</mat-icon>
  163. </button>
  164. <button mat-icon-button class="delete-btn" matTooltip="删除" (click)="deleteEmployee(employee.id)">
  165. <mat-icon>delete</mat-icon>
  166. </button>
  167. <button mat-icon-button class="view-btn" matTooltip="查看详情">
  168. <mat-icon>visibility</mat-icon>
  169. </button>
  170. </div>
  171. </td>
  172. </ng-container>
  173. <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
  174. <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
  175. <!-- 空数据状态 -->
  176. <tr class="mat-row" *matNoDataRow>
  177. <td class="mat-cell empty-state" [attr.colspan]="displayedColumns.length">
  178. <div class="empty-icon">
  179. <mat-icon>search_off</mat-icon>
  180. </div>
  181. <p>没有找到符合条件的员工</p>
  182. <button mat-button (click)="searchTerm.set(''); departmentFilter.set(''); statusFilter.set(''); applyFilters()">
  183. 清除筛选条件
  184. </button>
  185. </td>
  186. </tr>
  187. </table>
  188. </div>
  189. <!-- 分页组件 -->
  190. <div class="pagination">
  191. <div class="pagination-info">
  192. 共 {{ filteredEmployees().length }} 条记录,当前显示第 {{ pageIndex * pageSize + 1 }} -
  193. {{ Math.min((pageIndex + 1) * pageSize, filteredEmployees().length) }} 条
  194. </div>
  195. <mat-paginator
  196. [length]="filteredEmployees().length"
  197. [pageSize]="pageSize"
  198. [pageSizeOptions]="[10, 20, 50]"
  199. [pageIndex]="pageIndex"
  200. (page)="onPageChange($event)"
  201. showFirstLastButtons
  202. ></mat-paginator>
  203. </div>
  204. </div>