xto-fronted 0.4.71 → 0.4.73

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. package/dist/assets/404-CrBiLyvr.js +1 -0
  2. package/dist/assets/404-Cw_4ZCL6.css +1 -0
  3. package/dist/assets/_plugin-vue_export-helper-DlAUqK2U.js +1 -0
  4. package/dist/assets/index-9XqWtCGs.js +1 -0
  5. package/dist/assets/index-BBGKF0l-.js +1 -0
  6. package/dist/assets/index-BRR97dc6.js +1 -0
  7. package/dist/assets/index-BlRslYYI.css +1 -0
  8. package/dist/assets/index-BudArKxR.css +1 -0
  9. package/dist/assets/index-CFhWBbxk.css +1 -0
  10. package/dist/assets/index-CRJFI4iz.js +2 -0
  11. package/dist/assets/index-CmknWHK0.js +1 -0
  12. package/dist/assets/index-D7epoF1g.js +1 -0
  13. package/dist/assets/index-D9XBi20Y.css +1 -0
  14. package/dist/assets/index-DkkuYBgT.css +1 -0
  15. package/dist/assets/index-O9wpAB3Q.js +1 -0
  16. package/dist/assets/index-_aYxnqzF.css +1 -0
  17. package/dist/assets/index-rfC7s9zA.js +1 -0
  18. package/dist/assets/index-vfvEFrCH.css +1 -0
  19. package/dist/assets/vendor-42ANG6Sg.js +6 -0
  20. package/dist/assets/vue-vendor-D8SAgT8u.js +29 -0
  21. package/dist/assets/xto-base-BD3OH0V6.js +1 -0
  22. package/dist/assets/xto-base-CojW9IFO.css +1 -0
  23. package/dist/assets/xto-business--V1F5Gwb.css +1 -0
  24. package/dist/assets/xto-core-Boim7B0B.js +1 -0
  25. package/dist/assets/xto-data-CnAQAQH2.css +1 -0
  26. package/dist/assets/xto-data-DuG2QJrr.js +1 -0
  27. package/dist/assets/xto-feedback-C-ESp-Y1.css +1 -0
  28. package/dist/assets/xto-feedback-XZPSQcJN.js +1 -0
  29. package/dist/assets/xto-form-BmTGLIm_.js +1 -0
  30. package/dist/assets/xto-form-CrsyAjyr.css +1 -0
  31. package/dist/assets/xto-layout-D1stVnJI.css +1 -0
  32. package/dist/assets/xto-navigation-BRzSCpAw.css +1 -0
  33. package/dist/assets/xto-navigation-nPmjRi-J.js +1 -0
  34. package/dist/index.html +28 -0
  35. package/package.json +90 -87
  36. package/src/App.vue +30 -1
  37. package/src/assets/styles/_root.scss +141 -97
  38. package/src/assets/styles/_variables.scss +44 -19
  39. package/src/assets/styles/index.scss +267 -42
  40. package/src/components/Layout/Sidebar.vue +29 -10
  41. package/src/views/dashboard/index.vue +417 -155
  42. package/src/views/error/403.vue +251 -56
  43. package/src/views/error/404.vue +253 -56
  44. package/src/views/login/index.vue +586 -194
  45. package/src/views/system/menu/index.vue +403 -94
  46. package/src/views/system/role/index.vue +348 -69
  47. package/src/views/system/user/index.vue +402 -73
  48. package/dist/App.vue.d.ts +0 -2
  49. package/dist/api/auth.d.ts +0 -8
  50. package/dist/api/system.d.ts +0 -16
  51. package/dist/api/user.d.ts +0 -13
  52. package/dist/components/Layout/Footer.vue.d.ts +0 -2
  53. package/dist/components/Layout/Header.vue.d.ts +0 -5
  54. package/dist/components/Layout/MixTopMenu.vue.d.ts +0 -5
  55. package/dist/components/Layout/Sidebar.vue.d.ts +0 -11
  56. package/dist/components/Layout/SidebarMenuItem.vue.d.ts +0 -5
  57. package/dist/components/Layout/Tabs.vue.d.ts +0 -2
  58. package/dist/components/Layout/TopMenu.vue.d.ts +0 -5
  59. package/dist/components/Layout/index.vue.d.ts +0 -2
  60. package/dist/composables/useApp.d.ts +0 -29
  61. package/dist/composables/useAuth.d.ts +0 -6
  62. package/dist/composables/useForm.d.ts +0 -20
  63. package/dist/composables/useTable.d.ts +0 -29
  64. package/dist/directives/permission.d.ts +0 -4
  65. package/dist/enums/index.d.ts +0 -32
  66. package/dist/index-BgbSp2mz.js +0 -372
  67. package/dist/index-By874kXD.js +0 -142
  68. package/dist/index-COz0Cbj7.js +0 -345
  69. package/dist/index-CgbSCzIp.js +0 -3159
  70. package/dist/index-CzOd0mGb.js +0 -475
  71. package/dist/index.d.ts +0 -54
  72. package/dist/index.es.js +0 -91
  73. package/dist/index.umd.js +0 -1
  74. package/dist/main.d.ts +0 -0
  75. package/dist/router/dynamicRoutes.d.ts +0 -30
  76. package/dist/router/guards.d.ts +0 -17
  77. package/dist/router/index.d.ts +0 -6
  78. package/dist/router/layoutRoute.d.ts +0 -18
  79. package/dist/router/staticRoutes.d.ts +0 -2
  80. package/dist/stores/app.d.ts +0 -93
  81. package/dist/stores/auth.d.ts +0 -41
  82. package/dist/stores/index.d.ts +0 -9
  83. package/dist/stores/menu.d.ts +0 -77
  84. package/dist/stores/user.d.ts +0 -92
  85. package/dist/style.css +0 -1
  86. package/dist/utils/auth.d.ts +0 -27
  87. package/dist/utils/config.d.ts +0 -30
  88. package/dist/utils/permission.d.ts +0 -18
  89. package/dist/utils/request.d.ts +0 -24
  90. package/dist/utils/storage.d.ts +0 -24
  91. package/dist/views/dashboard/index.vue.d.ts +0 -2
  92. package/dist/views/error/403.vue.d.ts +0 -2
  93. package/dist/views/error/404.vue.d.ts +0 -2
  94. package/dist/views/login/index.vue.d.ts +0 -4
  95. package/dist/views/system/menu/index.vue.d.ts +0 -4
  96. package/dist/views/system/role/index.vue.d.ts +0 -4
  97. package/dist/views/system/user/index.vue.d.ts +0 -4
@@ -1,7 +1,7 @@
1
1
  <script setup lang="ts">
2
2
  import { ref, reactive, computed, onMounted } from 'vue'
3
3
  import { Form, FormItem, Input, Select, Switch } from '@xto/form'
4
- import { Tag, Card, Pagination } from '@xto/data'
4
+ import { Tag, Pagination } from '@xto/data'
5
5
  import { Modal, Message, Popconfirm } from '@xto/feedback'
6
6
  import { Space, Button } from '@xto/base'
7
7
  import { Status, StatusOptions } from '@/enums'
@@ -155,8 +155,8 @@ onMounted(() => {
155
155
  <template>
156
156
  <div class="user-page">
157
157
  <!-- 搜索栏 -->
158
- <Card class="search-card">
159
- <Form :model="searchForm" inline>
158
+ <div class="search-section">
159
+ <Form :model="searchForm" inline class="search-form">
160
160
  <FormItem label="关键词">
161
161
  <Input
162
162
  v-model="searchForm.keyword"
@@ -175,69 +175,158 @@ onMounted(() => {
175
175
  </FormItem>
176
176
  <FormItem>
177
177
  <Space>
178
- <Button type="primary" @click="handleSearch">搜索</Button>
179
- <Button @click="handleReset">重置</Button>
178
+ <Button type="primary" @click="handleSearch">
179
+ <template #icon>
180
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
181
+ <circle cx="11" cy="11" r="8"/>
182
+ <path d="M21 21l-4.35-4.35"/>
183
+ </svg>
184
+ </template>
185
+ 搜索
186
+ </Button>
187
+ <Button @click="handleReset">
188
+ <template #icon>
189
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
190
+ <path d="M3 12a9 9 0 109-9 9.75 9.75 0 00-6.74 2.74L3 8"/>
191
+ <path d="M3 3v5h5"/>
192
+ </svg>
193
+ </template>
194
+ 重置
195
+ </Button>
180
196
  </Space>
181
197
  </FormItem>
182
198
  </Form>
183
- </Card>
199
+ </div>
184
200
 
185
201
  <!-- 表格 -->
186
- <Card class="table-card">
202
+ <div class="table-section">
187
203
  <!-- 工具栏 -->
188
- <div class="toolbar">
189
- <Button type="primary" @click="handleAdd">新增用户</Button>
204
+ <div class="table-toolbar">
205
+ <div class="toolbar-left">
206
+ <Button type="primary" @click="handleAdd">
207
+ <template #icon>
208
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
209
+ <line x1="12" y1="5" x2="12" y2="19"/>
210
+ <line x1="5" y1="12" x2="19" y2="12"/>
211
+ </svg>
212
+ </template>
213
+ 新增用户
214
+ </Button>
215
+ </div>
216
+ <div class="toolbar-right">
217
+ <span class="table-count">共 {{ total }} 条数据</span>
218
+ </div>
190
219
  </div>
191
220
 
192
221
  <!-- 表格 -->
193
- <table class="data-table">
194
- <thead>
195
- <tr>
196
- <th>ID</th>
197
- <th>用户名</th>
198
- <th>昵称</th>
199
- <th>邮箱</th>
200
- <th>手机号</th>
201
- <th>角色</th>
202
- <th>状态</th>
203
- <th>创建时间</th>
204
- <th>操作</th>
205
- </tr>
206
- </thead>
207
- <tbody>
208
- <tr v-if="loading">
209
- <td colspan="9" class="loading-cell">加载中...</td>
210
- </tr>
211
- <tr v-else-if="userList.length === 0">
212
- <td colspan="9" class="empty-cell">暂无数据</td>
213
- </tr>
214
- <tr v-else v-for="row in userList" :key="row.id">
215
- <td>{{ row.id }}</td>
216
- <td>{{ row.username }}</td>
217
- <td>{{ row.nickname }}</td>
218
- <td>{{ row.email }}</td>
219
- <td>{{ row.phone }}</td>
220
- <td>
221
- <Tag v-for="role in row.roles" :key="role" size="small">{{ role }}</Tag>
222
- </td>
223
- <td>
224
- <Switch
225
- :model-value="row.status === Status.ENABLED"
226
- @update:model-value="row.status = $event ? Status.ENABLED : Status.DISABLED; handleStatusChange(row)"
227
- />
228
- </td>
229
- <td>{{ row.createTime }}</td>
230
- <td>
231
- <Space>
232
- <Button type="primary" link size="small" @click="handleEdit(row)">编辑</Button>
233
- <Popconfirm title="确定删除该用户吗?" @confirm="handleDelete(row.id)">
234
- <Button type="danger" link size="small">删除</Button>
235
- </Popconfirm>
236
- </Space>
237
- </td>
238
- </tr>
239
- </tbody>
240
- </table>
222
+ <div class="table-wrapper">
223
+ <table class="data-table">
224
+ <thead>
225
+ <tr>
226
+ <th class="col-id">ID</th>
227
+ <th class="col-user">用户信息</th>
228
+ <th class="col-contact">联系方式</th>
229
+ <th class="col-roles">角色</th>
230
+ <th class="col-status">状态</th>
231
+ <th class="col-time">创建时间</th>
232
+ <th class="col-actions">操作</th>
233
+ </tr>
234
+ </thead>
235
+ <tbody>
236
+ <tr v-if="loading">
237
+ <td colspan="7" class="loading-cell">
238
+ <div class="loading-content">
239
+ <div class="loading-spinner"></div>
240
+ <span>加载中...</span>
241
+ </div>
242
+ </td>
243
+ </tr>
244
+ <tr v-else-if="userList.length === 0">
245
+ <td colspan="7" class="empty-cell">
246
+ <div class="empty-content">
247
+ <svg viewBox="0 0 64 41" fill="none">
248
+ <g transform="translate(0 1)">
249
+ <ellipse fill="#f5f5f5" cx="32" cy="33" rx="32" ry="7"/>
250
+ <g stroke="var(--color-text-placeholder)" stroke-width="2">
251
+ <path d="M55 12.76L44.854 1.258C44.367.474 43.656 0 42.907 0H21.093c-.749 0-1.46.474-1.947 1.257L9 12.761V22h46v-9.24z"/>
252
+ <path d="M41.613 15.931c0-1.605.994-2.93 2.227-2.931H55v18.137C55 33.26 53.68 35 52.05 35H11.95C10.32 35 9 33.259 9 31.137V13h11.16c1.233 0 2.227 1.323 2.227 2.928v.022c0 1.605 1.005 2.901 2.237 2.901h14.752c1.232 0 2.237-1.308 2.237-2.913v-.007z" fill="var(--color-fill)"/>
253
+ </g>
254
+ </g>
255
+ </svg>
256
+ <span>暂无数据</span>
257
+ </div>
258
+ </td>
259
+ </tr>
260
+ <tr v-else v-for="row in userList" :key="row.id" class="data-row">
261
+ <td class="col-id">
262
+ <span class="id-badge">{{ row.id }}</span>
263
+ </td>
264
+ <td class="col-user">
265
+ <div class="user-info">
266
+ <div class="user-avatar">{{ row.nickname.charAt(0) }}</div>
267
+ <div class="user-detail">
268
+ <span class="user-nickname">{{ row.nickname }}</span>
269
+ <span class="user-username">@{{ row.username }}</span>
270
+ </div>
271
+ </div>
272
+ </td>
273
+ <td class="col-contact">
274
+ <div class="contact-info">
275
+ <span class="contact-email">{{ row.email }}</span>
276
+ <span class="contact-phone">{{ row.phone }}</span>
277
+ </div>
278
+ </td>
279
+ <td class="col-roles">
280
+ <div class="role-tags">
281
+ <Tag v-for="role in row.roles" :key="role" size="small" :type="role === 'admin' ? 'primary' : 'info'">
282
+ {{ role }}
283
+ </Tag>
284
+ </div>
285
+ </td>
286
+ <td class="col-status">
287
+ <div class="status-switch">
288
+ <Switch
289
+ :model-value="row.status === Status.ENABLED"
290
+ @update:model-value="row.status = $event ? Status.ENABLED : Status.DISABLED; handleStatusChange(row)"
291
+ />
292
+ <span class="status-text" :class="{ enabled: row.status === Status.ENABLED }">
293
+ {{ row.status === Status.ENABLED ? '已启用' : '已禁用' }}
294
+ </span>
295
+ </div>
296
+ </td>
297
+ <td class="col-time">
298
+ <span class="time-text">{{ row.createTime }}</span>
299
+ </td>
300
+ <td class="col-actions">
301
+ <Space class="action-buttons">
302
+ <Button type="primary" link size="small" @click="handleEdit(row)">
303
+ <template #icon>
304
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
305
+ <path d="M11 4H4a2 2 0 00-2 2v14a2 2 0 002 2h14a2 2 0 002-2v-7"/>
306
+ <path d="M18.5 2.5a2.121 2.121 0 013 3L12 15l-4 1 1-4 9.5-9.5z"/>
307
+ </svg>
308
+ </template>
309
+ 编辑
310
+ </Button>
311
+ <Popconfirm title="确定删除该用户吗?" @confirm="handleDelete(row.id)">
312
+ <Button type="danger" link size="small">
313
+ <template #icon>
314
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
315
+ <polyline points="3,6 5,6 21,6"/>
316
+ <path d="M19 6v14a2 2 0 01-2 2H7a2 2 0 01-2-2V6m3 0V4a2 2 0 012-2h4a2 2 0 012 2v2"/>
317
+ <line x1="10" y1="11" x2="10" y2="17"/>
318
+ <line x1="14" y1="11" x2="14" y2="17"/>
319
+ </svg>
320
+ </template>
321
+ 删除
322
+ </Button>
323
+ </Popconfirm>
324
+ </Space>
325
+ </td>
326
+ </tr>
327
+ </tbody>
328
+ </table>
329
+ </div>
241
330
 
242
331
  <!-- 分页 -->
243
332
  <div class="pagination-wrapper">
@@ -251,11 +340,11 @@ onMounted(() => {
251
340
  @size-change="getUserList"
252
341
  />
253
342
  </div>
254
- </Card>
343
+ </div>
255
344
 
256
345
  <!-- 编辑弹窗 -->
257
- <Modal v-model="modalVisible" :title="modalTitle" width="500px">
258
- <Form ref="formRef" :model="formData" :rules="rules" label-width="80px">
346
+ <Modal v-model="modalVisible" :title="modalTitle" width="520px" class="user-modal">
347
+ <Form ref="formRef" :model="formData" :rules="rules" label-width="80px" class="user-form">
259
348
  <FormItem label="用户名" prop="username">
260
349
  <Input v-model="formData.username" placeholder="请输入用户名" />
261
350
  </FormItem>
@@ -269,7 +358,10 @@ onMounted(() => {
269
358
  <Input v-model="formData.phone" placeholder="请输入手机号" />
270
359
  </FormItem>
271
360
  <FormItem label="状态">
272
- <Switch v-model="formData.status" :active-value="Status.ENABLED" :inactive-value="Status.DISABLED" />
361
+ <div class="status-field">
362
+ <Switch v-model="formData.status" :active-value="Status.ENABLED" :inactive-value="Status.DISABLED" />
363
+ <span class="status-label">{{ formData.status === Status.ENABLED ? '启用' : '禁用' }}</span>
364
+ </div>
273
365
  </FormItem>
274
366
  </Form>
275
367
  <template #footer>
@@ -284,44 +376,281 @@ onMounted(() => {
284
376
 
285
377
  <style lang="scss" scoped>
286
378
  .user-page {
287
- padding: 20px;
379
+ padding: 24px;
380
+ background: var(--bg-color-page);
381
+ min-height: 100%;
382
+ }
383
+
384
+ // 搜索区域
385
+ .search-section {
386
+ background: var(--bg-color);
387
+ border-radius: var(--border-radius-large);
388
+ padding: 20px 24px;
389
+ margin-bottom: 16px;
390
+ box-shadow: var(--box-shadow-card);
391
+
392
+ .search-form {
393
+ display: flex;
394
+ flex-wrap: wrap;
395
+ gap: 16px;
396
+
397
+ :deep(.x-form-item) {
398
+ margin-bottom: 0;
399
+ }
400
+
401
+ :deep(.x-input),
402
+ :deep(.x-select) {
403
+ width: 200px;
404
+ }
405
+ }
406
+ }
407
+
408
+ // 表格区域
409
+ .table-section {
410
+ background: var(--bg-color);
411
+ border-radius: var(--border-radius-large);
412
+ box-shadow: var(--box-shadow-card);
413
+ overflow: hidden;
414
+ }
288
415
 
289
- .search-card {
290
- margin-bottom: 20px;
416
+ .table-toolbar {
417
+ display: flex;
418
+ justify-content: space-between;
419
+ align-items: center;
420
+ padding: 16px 24px;
421
+ border-bottom: 1px solid var(--color-border-lighter);
422
+
423
+ .toolbar-left {
424
+ display: flex;
425
+ gap: 12px;
291
426
  }
292
427
 
293
- .toolbar {
294
- margin-bottom: 15px;
428
+ .table-count {
429
+ font-size: 14px;
430
+ color: var(--color-text-secondary);
295
431
  }
296
432
  }
297
433
 
434
+ .table-wrapper {
435
+ overflow-x: auto;
436
+ }
437
+
438
+ // 表格样式
298
439
  .data-table {
299
440
  width: 100%;
300
441
  border-collapse: collapse;
301
442
 
302
443
  th, td {
303
- padding: 12px;
444
+ padding: 14px 16px;
304
445
  text-align: left;
305
446
  border-bottom: 1px solid var(--color-border-lighter);
306
447
  }
307
448
 
308
449
  th {
450
+ font-size: 14px;
309
451
  font-weight: 500;
310
- color: var(--color-text-regular);
311
- background-color: var(--color-fill-light);
452
+ color: var(--color-text-secondary);
453
+ background: var(--color-fill-light);
454
+ white-space: nowrap;
455
+ }
456
+
457
+ .data-row {
458
+ transition: background-color 0.2s;
459
+
460
+ &:hover {
461
+ background: var(--color-primary-light-6);
462
+ }
463
+ }
464
+
465
+ td {
466
+ vertical-align: middle;
312
467
  }
313
468
 
314
469
  .loading-cell,
315
470
  .empty-cell {
316
- text-align: center;
317
- color: var(--color-text-secondary);
318
- padding: 40px;
471
+ padding: 60px 20px;
472
+ }
473
+
474
+ .loading-content,
475
+ .empty-content {
476
+ display: flex;
477
+ flex-direction: column;
478
+ align-items: center;
479
+ gap: 16px;
480
+ color: var(--color-text-placeholder);
481
+
482
+ svg {
483
+ width: 64px;
484
+ height: 41px;
485
+ }
486
+ }
487
+
488
+ .loading-spinner {
489
+ width: 32px;
490
+ height: 32px;
491
+ border: 3px solid var(--color-border-lighter);
492
+ border-top-color: var(--color-primary);
493
+ border-radius: 50%;
494
+ animation: spin 0.8s linear infinite;
319
495
  }
320
496
  }
321
497
 
498
+ @keyframes spin {
499
+ to { transform: rotate(360deg); }
500
+ }
501
+
502
+ // 列样式
503
+ .col-id {
504
+ width: 80px;
505
+ }
506
+
507
+ .id-badge {
508
+ display: inline-block;
509
+ min-width: 32px;
510
+ padding: 4px 10px;
511
+ background: var(--color-fill);
512
+ border-radius: 12px;
513
+ font-size: 12px;
514
+ font-weight: 500;
515
+ color: var(--color-text-secondary);
516
+ text-align: center;
517
+ }
518
+
519
+ .col-user {
520
+ min-width: 180px;
521
+ }
522
+
523
+ .user-info {
524
+ display: flex;
525
+ align-items: center;
526
+ gap: 12px;
527
+ }
528
+
529
+ .user-avatar {
530
+ width: 40px;
531
+ height: 40px;
532
+ display: flex;
533
+ align-items: center;
534
+ justify-content: center;
535
+ background: linear-gradient(135deg, var(--color-primary) 0%, var(--color-primary-light-1) 100%);
536
+ border-radius: 50%;
537
+ font-size: 16px;
538
+ font-weight: 500;
539
+ color: #fff;
540
+ flex-shrink: 0;
541
+ }
542
+
543
+ .user-detail {
544
+ display: flex;
545
+ flex-direction: column;
546
+ gap: 2px;
547
+ }
548
+
549
+ .user-nickname {
550
+ font-size: 14px;
551
+ font-weight: 500;
552
+ color: var(--color-text-primary);
553
+ }
554
+
555
+ .user-username {
556
+ font-size: 12px;
557
+ color: var(--color-text-placeholder);
558
+ }
559
+
560
+ .col-contact {
561
+ min-width: 180px;
562
+ }
563
+
564
+ .contact-info {
565
+ display: flex;
566
+ flex-direction: column;
567
+ gap: 4px;
568
+ }
569
+
570
+ .contact-email,
571
+ .contact-phone {
572
+ font-size: 13px;
573
+ color: var(--color-text-regular);
574
+ }
575
+
576
+ .contact-phone {
577
+ color: var(--color-text-secondary);
578
+ }
579
+
580
+ .col-roles {
581
+ min-width: 100px;
582
+ }
583
+
584
+ .role-tags {
585
+ display: flex;
586
+ gap: 6px;
587
+ }
588
+
589
+ .col-status {
590
+ min-width: 120px;
591
+ }
592
+
593
+ .status-switch {
594
+ display: flex;
595
+ align-items: center;
596
+ gap: 8px;
597
+ }
598
+
599
+ .status-text {
600
+ font-size: 13px;
601
+ color: var(--color-text-secondary);
602
+
603
+ &.enabled {
604
+ color: var(--color-success);
605
+ }
606
+ }
607
+
608
+ .col-time {
609
+ min-width: 160px;
610
+ }
611
+
612
+ .time-text {
613
+ font-size: 13px;
614
+ color: var(--color-text-secondary);
615
+ }
616
+
617
+ .col-actions {
618
+ min-width: 140px;
619
+ }
620
+
621
+ .action-buttons {
622
+ :deep(.x-button) {
623
+ padding: 4px 8px;
624
+
625
+ svg {
626
+ width: 14px;
627
+ height: 14px;
628
+ margin-right: 4px;
629
+ }
630
+ }
631
+ }
632
+
633
+ // 分页
322
634
  .pagination-wrapper {
323
635
  display: flex;
324
636
  justify-content: flex-end;
325
- margin-top: 20px;
637
+ padding: 16px 24px;
638
+ border-top: 1px solid var(--color-border-lighter);
639
+ }
640
+
641
+ // 弹窗表单
642
+ .user-form {
643
+ padding: 16px 0;
644
+
645
+ .status-field {
646
+ display: flex;
647
+ align-items: center;
648
+ gap: 12px;
649
+ }
650
+
651
+ .status-label {
652
+ font-size: 14px;
653
+ color: var(--color-text-secondary);
654
+ }
326
655
  }
327
656
  </style>
package/dist/App.vue.d.ts DELETED
@@ -1,2 +0,0 @@
1
- declare const _default: import('vue').DefineComponent<{}, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, HTMLDivElement>;
2
- export default _default;
@@ -1,8 +0,0 @@
1
- import { LoginParams, LoginResult, UserInfo } from '../types/api';
2
- export declare function login(data: LoginParams): Promise<LoginResult>;
3
- export declare function logout(): Promise<unknown>;
4
- export declare function getUserInfo(): Promise<UserInfo>;
5
- export declare function refreshToken(refreshToken: string): Promise<{
6
- token: string;
7
- expireTime: number;
8
- }>;
@@ -1,16 +0,0 @@
1
- import { PageParams, PageResponse } from '../utils/request';
2
- import { RoleInfo, MenuItem } from '../types/api';
3
- export declare function getRoleList(params: PageParams & {
4
- status?: number;
5
- keyword?: string;
6
- }): Promise<PageResponse<RoleInfo>>;
7
- export declare function getRoleDetail(id: string | number): Promise<RoleInfo>;
8
- export declare function createRole(data: Partial<RoleInfo>): Promise<RoleInfo>;
9
- export declare function updateRole(id: string | number, data: Partial<RoleInfo>): Promise<RoleInfo>;
10
- export declare function deleteRole(id: string | number): Promise<unknown>;
11
- export declare function updateRoleStatus(id: string | number, status: number): Promise<unknown>;
12
- export declare function getMenuList(): Promise<MenuItem[]>;
13
- export declare function getMenuTree(appId?: string): Promise<MenuItem[]>;
14
- export declare function createMenu(data: Partial<MenuItem>): Promise<MenuItem>;
15
- export declare function updateMenu(id: string | number, data: Partial<MenuItem>): Promise<MenuItem>;
16
- export declare function deleteMenu(id: string | number): Promise<unknown>;
@@ -1,13 +0,0 @@
1
- import { PageParams, PageResponse } from '../utils/request';
2
- import { UserInfo } from '../types/api';
3
- export declare function getUserList(params: PageParams & {
4
- status?: number;
5
- keyword?: string;
6
- }): Promise<PageResponse<UserInfo>>;
7
- export declare function getUserDetail(id: string | number): Promise<UserInfo>;
8
- export declare function createUser(data: Partial<UserInfo>): Promise<UserInfo>;
9
- export declare function updateUser(id: string | number, data: Partial<UserInfo>): Promise<UserInfo>;
10
- export declare function deleteUser(id: string | number): Promise<unknown>;
11
- export declare function batchDeleteUsers(ids: (string | number)[]): Promise<unknown>;
12
- export declare function updateUserStatus(id: string | number, status: number): Promise<unknown>;
13
- export declare function resetPassword(id: string | number): Promise<unknown>;
@@ -1,2 +0,0 @@
1
- declare const _default: import('vue').DefineComponent<{}, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, HTMLDivElement>;
2
- export default _default;
@@ -1,5 +0,0 @@
1
- declare const _default: import('vue').DefineComponent<{}, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {
2
- searchRef: HTMLDivElement;
3
- dropdownRef: HTMLDivElement;
4
- }, HTMLDivElement>;
5
- export default _default;
@@ -1,5 +0,0 @@
1
- declare const _default: import('vue').DefineComponent<{}, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {
2
- searchRef: HTMLDivElement;
3
- dropdownRef: HTMLDivElement;
4
- }, HTMLDivElement>;
5
- export default _default;
@@ -1,11 +0,0 @@
1
- type __VLS_Props = {
2
- menuList?: any[];
3
- showLogo?: boolean;
4
- showUser?: boolean;
5
- };
6
- declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
7
- menuList: any[];
8
- showLogo: boolean;
9
- showUser: boolean;
10
- }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, HTMLDivElement>;
11
- export default _default;
@@ -1,5 +0,0 @@
1
- type __VLS_Props = {
2
- menu: any;
3
- };
4
- declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
5
- export default _default;
@@ -1,2 +0,0 @@
1
- declare const _default: import('vue').DefineComponent<{}, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, HTMLDivElement>;
2
- export default _default;
@@ -1,5 +0,0 @@
1
- declare const _default: import('vue').DefineComponent<{}, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {
2
- searchRef: HTMLDivElement;
3
- dropdownRef: HTMLDivElement;
4
- }, HTMLDivElement>;
5
- export default _default;
@@ -1,2 +0,0 @@
1
- declare const _default: import('vue').DefineComponent<{}, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, any>;
2
- export default _default;