@agile-team/wl-skills-kit 2.11.1 → 2.11.3

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 (91) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/README.md +38 -21
  3. package/bin/wl-skills.js +27 -3
  4. package/files/.wl-skills/docs/jh-pagination.md +505 -505
  5. package/files/.wl-skills/docs/request.md +940 -940
  6. package/files/.wl-skills/docs/validate-exempt.md +113 -0
  7. package/files/.wl-skills/guides/architecture.md +1 -1
  8. package/files/.wl-skills/skills/_compat/headers/cursor-mdc.txt +1 -1
  9. package/files/.wl-skills/skills/_compat/headers/kiro.txt +1 -1
  10. package/files/.wl-skills/skills/_compat/headers/trae.txt +1 -1
  11. package/files/.wl-skills/skills/core/convention-audit/SKILL.md +3 -3
  12. package/files/.wl-skills/skills/core/spec-doc-parse/SKILL.md +332 -332
  13. package/files/.wl-skills/skills/core/spec-doc-parse/USAGE.md +97 -97
  14. package/files/.wl-skills/skills/sync/permission-sync/USAGE.md +107 -107
  15. package/files/.wl-skills/src/components/global/C_ParentView/index.vue +3 -3
  16. package/files/.wl-skills/src/components/global/C_RightToolbar/index.vue +157 -157
  17. package/files/.wl-skills/src/components/global/C_SvgIcon/index.vue +31 -31
  18. package/files/.wl-skills/src/components/global/C_SvgIcon/svgicon.js +10 -10
  19. package/files/.wl-skills/src/components/global/C_TagStatus/README.md +264 -264
  20. package/files/.wl-skills/src/components/global/C_TagStatus/config.ts +192 -192
  21. package/files/.wl-skills/src/components/global/C_TagStatus/index.vue +106 -106
  22. package/files/.wl-skills/src/components/global/C_TagStatus/types.ts +64 -64
  23. package/files/.wl-skills/src/components/global/C_Tree/README.md +153 -153
  24. package/files/.wl-skills/src/components/global/C_Tree/index.scss +42 -42
  25. package/files/.wl-skills/src/components/global/C_Tree/index.vue +78 -78
  26. package/files/.wl-skills/src/components/global/C_Tree/types.ts +59 -59
  27. package/files/.wl-skills/src/components/local/c_formModal/README.md +235 -235
  28. package/files/.wl-skills/src/components/local/c_formModal/data.ts +95 -95
  29. package/files/.wl-skills/src/components/local/c_formModal/index.scss +8 -8
  30. package/files/.wl-skills/src/components/local/c_formModal/index.vue +107 -107
  31. package/files/.wl-skills/src/components/local/c_formSections/data.ts +175 -175
  32. package/files/.wl-skills/src/components/local/c_formSections/index.scss +280 -280
  33. package/files/.wl-skills/src/components/local/c_formSections/index.vue +429 -429
  34. package/files/.wl-skills/src/components/local/c_listModal/data.ts +41 -41
  35. package/files/.wl-skills/src/components/local/c_listModal/index.vue +136 -136
  36. package/files/.wl-skills/src/components/local/c_spliterTitle/index.scss +25 -25
  37. package/files/.wl-skills/src/components/local/c_spliterTitle/index.vue +21 -21
  38. package/files/.wl-skills/src/components/remote/AGGrid/README.md +530 -530
  39. package/files/.wl-skills/src/components/remote/BaseForm/README.md +508 -508
  40. package/files/.wl-skills/src/components/remote/BaseQuery/README.md +865 -865
  41. package/files/.wl-skills/src/components/remote/BaseTable/README.md +941 -941
  42. package/files/.wl-skills/src/components/remote/BaseToolbar/README.md +496 -496
  43. package/files/.wl-skills/src/types/page.ts +24 -24
  44. package/files/.wl-skills/standards/04-coding-basics.md +39 -1
  45. package/files/.wl-skills/standards/09-typescript.md +26 -3
  46. package/files/.wl-skills/standards/12-base-table.md +56 -4
  47. package/files/.wl-skills/standards/13-platform-components.md +1 -0
  48. package/files/.wl-skills/standards/index.md +2 -2
  49. package/files/.wl-skills/templates/README.md +44 -44
  50. package/files/.wl-skills/templates/produce/aiflow/mmwr-customer-apply-add/api.md +54 -54
  51. package/files/.wl-skills/templates/produce/aiflow/mmwr-customer-apply-add/data.ts +346 -346
  52. package/files/.wl-skills/templates/produce/aiflow/mmwr-customer-apply-add/index.scss +1 -1
  53. package/files/.wl-skills/templates/produce/aiflow/mmwr-customer-apply-add/index.vue +28 -28
  54. package/files/.wl-skills/templates/produce/aiflow/mmwr-customer-apply-add-form/data.ts +115 -115
  55. package/files/.wl-skills/templates/produce/aiflow/mmwr-customer-apply-add-form/index.scss +44 -44
  56. package/files/.wl-skills/templates/produce/aiflow/mmwr-customer-apply-add-form/index.vue +43 -43
  57. package/files/.wl-skills/templates/produce/aiflow/mmwr-customer-apply-change/data.ts +338 -338
  58. package/files/.wl-skills/templates/produce/aiflow/mmwr-customer-apply-change/index.scss +1 -1
  59. package/files/.wl-skills/templates/produce/aiflow/mmwr-customer-apply-change/index.vue +28 -28
  60. package/files/.wl-skills/templates/produce/aiflow/mmwr-customer-apply-change-form/data.ts +115 -115
  61. package/files/.wl-skills/templates/produce/aiflow/mmwr-customer-apply-change-form/index.scss +44 -44
  62. package/files/.wl-skills/templates/produce/aiflow/mmwr-customer-apply-change-form/index.vue +43 -43
  63. package/files/.wl-skills/templates/produce/aiflow/mmwr-customer-archive/api.md +88 -88
  64. package/files/.wl-skills/templates/produce/aiflow/mmwr-customer-archive/data.ts +601 -601
  65. package/files/.wl-skills/templates/produce/aiflow/mmwr-customer-archive/index.scss +1 -1
  66. package/files/.wl-skills/templates/produce/aiflow/mmwr-customer-archive/index.vue +64 -64
  67. package/files/.wl-skills/templates/produce/aiflow/mmwr-customer-detail/api.md +67 -67
  68. package/files/.wl-skills/templates/produce/aiflow/mmwr-customer-detail/data.ts +286 -286
  69. package/files/.wl-skills/templates/produce/aiflow/mmwr-customer-detail/index.scss +139 -139
  70. package/files/.wl-skills/templates/produce/aiflow/mmwr-customer-detail/index.vue +318 -318
  71. package/files/.wl-skills/templates/produce/aiflow/mmwr-temp-customer-archive/api.md +98 -98
  72. package/files/.wl-skills/templates/produce/aiflow/mmwr-temp-customer-archive/data.ts +543 -543
  73. package/files/.wl-skills/templates/produce/aiflow/mmwr-temp-customer-archive/index.scss +1 -1
  74. package/files/.wl-skills/templates/produce/aiflow/mmwr-temp-customer-archive/index.vue +52 -52
  75. package/files/.wl-skills/templates/sale/demo/add-demo/data.ts +518 -518
  76. package/files/.wl-skills/templates/sale/demo/billet-flame-cut-plan/data.ts +524 -524
  77. package/files/.wl-skills/templates/sale/demo/billet-flame-cut-plan/index.scss +154 -154
  78. package/files/.wl-skills/templates/sale/demo/billet-flame-cut-plan/index.vue +117 -117
  79. package/files/.wl-skills/templates/sale/demo/domestic-trade-order/data.ts +308 -308
  80. package/files/.wl-skills/templates/sale/demo/domestic-trade-order/index.scss +99 -99
  81. package/files/.wl-skills/templates/sale/demo/domestic-trade-order/index.vue +77 -77
  82. package/files/.wl-skills/templates/sale/demo/heat-batch-return/data.ts +367 -367
  83. package/files/.wl-skills/templates/sale/demo/heat-batch-return/index.scss +100 -100
  84. package/files/.wl-skills/templates/sale/demo/heat-batch-return/index.vue +170 -170
  85. package/files/.wl-skills/templates/sale/demo/heat-batch-return/meltDialog.vue +320 -320
  86. package/files/.wl-skills/templates/sale/demo/metallurgical-spec/data.ts +824 -824
  87. package/lib/ast-rules.js +395 -12
  88. package/mcp/config.js +46 -46
  89. package/mcp/registry.js +6 -1
  90. package/mcp/tools/projectTools.js +9 -1
  91. package/package.json +2 -2
@@ -1,496 +1,496 @@
1
- # BaseToolbar 工具栏组件
2
-
3
- > 来源:`@jhlc/common-core` 远程组件
4
-
5
- BaseToolbar 是一个灵活的工具栏组件,用于放置操作按钮,支持左侧和右侧按钮区域、下拉菜单、权限控制、加载状态等功能。
6
-
7
- ## 📦 导入方式
8
-
9
- ```typescript
10
- // 全局注册(已在项目中配置)
11
- // 直接使用 <BaseToolbar /> 即可
12
-
13
- // 类型导入
14
- import type { ActionButtonDesc, ActionType } from "@jhlc/common-core/.wl-skills/src/components/toolbar/type";
15
- ```
16
-
17
- ## 🚀 基本用法
18
-
19
- ```vue
20
- <template>
21
- <BaseToolbar :items="toolbarItems" />
22
- </template>
23
-
24
- <script setup lang="ts">
25
- import { computed } from "vue";
26
-
27
- const toolbarItems = computed(() => [
28
- {
29
- name: "add",
30
- type: "add",
31
- onClick: () => handleAdd()
32
- },
33
- {
34
- name: "delete",
35
- type: "delete",
36
- onClick: () => handleDelete()
37
- }
38
- ]);
39
-
40
- const handleAdd = () => console.log("新增");
41
- const handleDelete = () => console.log("删除");
42
- </script>
43
- ```
44
-
45
- ---
46
-
47
- ## 📋 Props 属性
48
-
49
- | 属性名 | 类型 | 默认值 | 说明 |
50
- | ------------ | --------------------------------- | ----------- | -------------- |
51
- | `items` | `ActionButtonDesc[]` | `[]` | 左侧按钮配置 |
52
- | `rightItems` | `ActionButtonDesc[]` | `[]` | 右侧按钮配置 |
53
- | `size` | `'small' \| 'default' \| 'large'` | `'default'` | 按钮尺寸 |
54
-
55
- ---
56
-
57
- ## 📋 ActionType 按钮类型
58
-
59
- 使用 `type` 属性可以快速设置按钮的图标和样式:
60
-
61
- | 类型 | 说明 | 图标 | 样式 |
62
- | ---------- | -------- | ---------------- | ------- |
63
- | `add` | 新增 | `Plus` | primary |
64
- | `edit` | 编辑 | `Edit` | warning |
65
- | `delete` | 删除 | `Delete` | danger |
66
- | `batchDel` | 批量删除 | `Delete` | danger |
67
- | `import` | 导入 | `Upload` | info |
68
- | `export` | 导出 | `Download` | warning |
69
- | `query` | 查询 | `Search` | primary |
70
- | `reset` | 重置 | `Refresh` | - |
71
- | `print` | 打印 | `Printer` | warning |
72
- | `submit` | 提交 | `CircleCheck` | primary |
73
- | `finish` | 完成 | `CircleCheck` | primary |
74
- | `close` | 关闭 | `CircleClose` | info |
75
- | `cancel` | 取消 | `CircleClose` | info |
76
- | `rollback` | 退回 | `RefreshLeft` | warning |
77
- | `back` | 返回 | `ArrowLeft` | - |
78
- | `copy` | 复制 | `CopyDocument` | - |
79
- | `view` | 查看 | `View` | - |
80
- | `refresh` | 刷新 | `Refresh` | - |
81
- | `save` | 保存 | `Document` | primary |
82
- | `collapse` | 收起 | `DArrowLeft` | - |
83
- | `expand` | 展开 | `DArrowRight` | - |
84
- | `log` | 日志 | `Document` | - |
85
- | `prev` | 上一步 | `ArrowLeftBold` | warning |
86
- | `next` | 下一步 | `ArrowRightBold` | primary |
87
- | `confirm` | 确认 | `Select` | primary |
88
-
89
- ---
90
-
91
- ## 📋 ActionButtonDesc 按钮配置
92
-
93
- ```typescript
94
- interface ActionButtonDesc {
95
- // 按钮唯一标识(必填)
96
- name: string;
97
- // 按钮类型,会自动设置图标和样式
98
- type?: ActionType;
99
- // 自定义标签文本
100
- label?: string;
101
- // 自定义图标
102
- icon?: string;
103
- // 是否禁用
104
- disabled?: boolean | (() => boolean);
105
- // 是否显示
106
- show?: boolean | (() => boolean);
107
- // 加载状态
108
- loading?: boolean | (() => boolean);
109
- // 点击事件
110
- onClick?: () => void | Promise<void>;
111
- // 权限标识
112
- permission?: string;
113
- // 下拉子按钮
114
- children?: ActionButtonDesc[];
115
- // 是否朴素按钮
116
- plain?: boolean;
117
- // 是否自动管理加载状态(点击后自动 loading)
118
- autoLoading?: boolean;
119
- // 自定义渲染
120
- renderNode?: () => VNode;
121
- // 更多样式
122
- style?: any;
123
- // 下拉按钮(当存在 children 时)
124
- split?: boolean;
125
- }
126
- ```
127
-
128
- ---
129
-
130
- ## 💡 使用示例
131
-
132
- ### 基础工具栏
133
-
134
- ```vue
135
- <template>
136
- <BaseToolbar :items="toolbarItems" />
137
- </template>
138
-
139
- <script setup lang="ts">
140
- import { computed } from "vue";
141
-
142
- const toolbarItems = computed(() => [
143
- {
144
- name: "add",
145
- type: "add",
146
- onClick: handleAdd
147
- },
148
- {
149
- name: "edit",
150
- type: "edit",
151
- disabled: () => selectedRows.value.length !== 1,
152
- onClick: handleEdit
153
- },
154
- {
155
- name: "delete",
156
- type: "delete",
157
- disabled: () => selectedRows.value.length === 0,
158
- onClick: handleDelete
159
- }
160
- ]);
161
- </script>
162
- ```
163
-
164
- ### 左右布局
165
-
166
- ```vue
167
- <template>
168
- <BaseToolbar
169
- :items="leftItems"
170
- :rightItems="rightItems"
171
- />
172
- </template>
173
-
174
- <script setup lang="ts">
175
- const leftItems = computed(() => [
176
- { name: "add", type: "add", onClick: handleAdd },
177
- { name: "delete", type: "batchDel", onClick: handleBatchDelete }
178
- ]);
179
-
180
- const rightItems = computed(() => [
181
- { name: "export", type: "export", onClick: handleExport },
182
- { name: "import", type: "import", onClick: handleImport }
183
- ]);
184
- </script>
185
- ```
186
-
187
- ### 自定义图标和标签
188
-
189
- ```vue
190
- <script setup lang="ts">
191
- const toolbarItems = computed(() => [
192
- {
193
- name: "approve",
194
- label: "审批通过",
195
- icon: "Select",
196
- onClick: handleApprove
197
- },
198
- {
199
- name: "reject",
200
- label: "审批退回",
201
- icon: "CloseBold",
202
- onClick: handleReject
203
- }
204
- ]);
205
- </script>
206
- ```
207
-
208
- ### 下拉菜单按钮
209
-
210
- ```vue
211
- <script setup lang="ts">
212
- const toolbarItems = computed(() => [
213
- {
214
- name: "add",
215
- type: "add",
216
- onClick: handleAdd
217
- },
218
- {
219
- name: "more",
220
- label: "更多操作",
221
- icon: "More",
222
- children: [
223
- {
224
- name: "copy",
225
- type: "copy",
226
- label: "复制",
227
- onClick: handleCopy
228
- },
229
- {
230
- name: "export",
231
- type: "export",
232
- label: "导出",
233
- onClick: handleExport
234
- },
235
- {
236
- name: "print",
237
- type: "print",
238
- label: "打印",
239
- onClick: handlePrint
240
- }
241
- ]
242
- }
243
- ]);
244
- </script>
245
- ```
246
-
247
- ### 分裂式下拉按钮
248
-
249
- ```vue
250
- <script setup lang="ts">
251
- const toolbarItems = computed(() => [
252
- {
253
- name: "save",
254
- type: "save",
255
- label: "保存",
256
- split: true, // 分裂式下拉
257
- onClick: handleSave,
258
- children: [
259
- {
260
- name: "saveAndNew",
261
- label: "保存并新增",
262
- onClick: handleSaveAndNew
263
- },
264
- {
265
- name: "saveAndCopy",
266
- label: "保存并复制",
267
- onClick: handleSaveAndCopy
268
- }
269
- ]
270
- }
271
- ]);
272
- </script>
273
- ```
274
-
275
- ### 权限控制
276
-
277
- ```vue
278
- <script setup lang="ts">
279
- const toolbarItems = computed(() => [
280
- {
281
- name: "add",
282
- type: "add",
283
- permission: "sale:order:add", // 需要此权限才显示
284
- onClick: handleAdd
285
- },
286
- {
287
- name: "edit",
288
- type: "edit",
289
- permission: "sale:order:edit",
290
- onClick: handleEdit
291
- },
292
- {
293
- name: "delete",
294
- type: "delete",
295
- permission: "sale:order:delete",
296
- onClick: handleDelete
297
- }
298
- ]);
299
- </script>
300
- ```
301
-
302
- ### 加载状态
303
-
304
- ```vue
305
- <script setup lang="ts">
306
- import { ref } from "vue";
307
-
308
- const saving = ref(false);
309
-
310
- const toolbarItems = computed(() => [
311
- {
312
- name: "save",
313
- type: "save",
314
- loading: () => saving.value, // 响应式加载状态
315
- onClick: async () => {
316
- saving.value = true;
317
- await save();
318
- saving.value = false;
319
- }
320
- },
321
- {
322
- name: "submit",
323
- type: "submit",
324
- autoLoading: true, // 自动管理加载状态
325
- onClick: async () => {
326
- await submit(); // 点击后自动 loading,完成后自动恢复
327
- }
328
- }
329
- ]);
330
- </script>
331
- ```
332
-
333
- ### 动态显示/禁用
334
-
335
- ```vue
336
- <script setup lang="ts">
337
- import { ref } from "vue";
338
-
339
- const selectedRows = ref([]);
340
- const isEditing = ref(false);
341
-
342
- const toolbarItems = computed(() => [
343
- {
344
- name: "add",
345
- type: "add",
346
- show: () => !isEditing.value, // 编辑时隐藏
347
- onClick: handleAdd
348
- },
349
- {
350
- name: "edit",
351
- type: "edit",
352
- show: () => !isEditing.value,
353
- disabled: () => selectedRows.value.length !== 1, // 只选中一条时可用
354
- onClick: handleEdit
355
- },
356
- {
357
- name: "save",
358
- type: "save",
359
- show: () => isEditing.value, // 编辑时显示
360
- onClick: handleSave
361
- },
362
- {
363
- name: "cancel",
364
- type: "cancel",
365
- show: () => isEditing.value,
366
- onClick: handleCancel
367
- }
368
- ]);
369
- </script>
370
- ```
371
-
372
- ### 自定义渲染
373
-
374
- ```vue
375
- <script setup lang="ts">
376
- import { h } from "vue";
377
- import { ElSwitch } from "element-plus";
378
-
379
- const autoRefresh = ref(false);
380
-
381
- const rightItems = computed(() => [
382
- {
383
- name: "autoRefresh",
384
- renderNode: () => h("div", { class: "flex items-center gap-2" }, [
385
- h("span", "自动刷新"),
386
- h(ElSwitch, {
387
- modelValue: autoRefresh.value,
388
- "onUpdate:modelValue": (val) => autoRefresh.value = val
389
- })
390
- ])
391
- },
392
- {
393
- name: "refresh",
394
- type: "refresh",
395
- onClick: handleRefresh
396
- }
397
- ]);
398
- </script>
399
- ```
400
-
401
- ---
402
-
403
- ## 🎨 与其他组件配合
404
-
405
- ### 配合 BaseQuery
406
-
407
- ```vue
408
- <template>
409
- <div class="page">
410
- <BaseQuery
411
- :form="queryParam"
412
- :items="queryItems"
413
- @select="handleSearch"
414
- @reset="handleReset"
415
- />
416
- <BaseToolbar :items="toolbarItems" />
417
- <BaseTable :data="tableData" :columns="columns" />
418
- </div>
419
- </template>
420
- ```
421
-
422
- ### 在 BaseTable 中使用操作列
423
-
424
- ```typescript
425
- // 表格列配置中的操作列
426
- {
427
- name: "",
428
- label: "操作",
429
- width: 150,
430
- actions: [
431
- { name: "edit", type: "edit" },
432
- { name: "delete", type: "delete" }
433
- ]
434
- }
435
- ```
436
-
437
- ---
438
-
439
- ## ⚠️ 注意事项
440
-
441
- 1. **使用 computed 包装按钮配置**
442
-
443
- ```typescript
444
- // ✅ 正确
445
- const toolbarItems = computed(() => [...]);
446
-
447
- // ❌ 避免
448
- const toolbarItems = [...];
449
- ```
450
-
451
- 2. **disabled/show 使用函数形式**
452
-
453
- ```typescript
454
- // ✅ 响应式
455
- disabled: () => selectedRows.value.length === 0
456
-
457
- // ❌ 非响应式(只在初始化时计算一次)
458
- disabled: selectedRows.value.length === 0
459
- ```
460
-
461
- 3. **autoLoading 适用于异步操作**
462
-
463
- ```typescript
464
- {
465
- name: "submit",
466
- autoLoading: true, // 点击后自动 loading
467
- onClick: async () => {
468
- await submitApi(); // 完成后自动恢复
469
- }
470
- }
471
- ```
472
-
473
- 4. **permission 需要后端配合**
474
-
475
- - 权限标识需要与后端菜单权限配置一致
476
-
477
- 5. **下拉按钮的 children 中也可以有权限控制**
478
-
479
- ```typescript
480
- {
481
- name: "more",
482
- label: "更多",
483
- children: [
484
- { name: "export", permission: "sale:order:export" },
485
- { name: "print", permission: "sale:order:print" }
486
- ]
487
- }
488
- ```
489
-
490
- ---
491
-
492
- ## 📚 相关文档
493
-
494
- - [BaseTable 表格组件](../BaseTable/README.md) - 表格操作列按钮
495
- - [BaseQuery 查询组件](../BaseQuery/README.md) - 查询区按钮
496
- - [BaseForm 表单组件](../BaseForm/README.md) - 表单提交按钮
1
+ # BaseToolbar 工具栏组件
2
+
3
+ > 来源:`@jhlc/common-core` 远程组件
4
+
5
+ BaseToolbar 是一个灵活的工具栏组件,用于放置操作按钮,支持左侧和右侧按钮区域、下拉菜单、权限控制、加载状态等功能。
6
+
7
+ ## 📦 导入方式
8
+
9
+ ```typescript
10
+ // 全局注册(已在项目中配置)
11
+ // 直接使用 <BaseToolbar /> 即可
12
+
13
+ // 类型导入
14
+ import type { ActionButtonDesc, ActionType } from "@jhlc/common-core/.wl-skills/src/components/toolbar/type";
15
+ ```
16
+
17
+ ## 🚀 基本用法
18
+
19
+ ```vue
20
+ <template>
21
+ <BaseToolbar :items="toolbarItems" />
22
+ </template>
23
+
24
+ <script setup lang="ts">
25
+ import { computed } from "vue";
26
+
27
+ const toolbarItems = computed(() => [
28
+ {
29
+ name: "add",
30
+ type: "add",
31
+ onClick: () => handleAdd()
32
+ },
33
+ {
34
+ name: "delete",
35
+ type: "delete",
36
+ onClick: () => handleDelete()
37
+ }
38
+ ]);
39
+
40
+ const handleAdd = () => console.log("新增");
41
+ const handleDelete = () => console.log("删除");
42
+ </script>
43
+ ```
44
+
45
+ ---
46
+
47
+ ## 📋 Props 属性
48
+
49
+ | 属性名 | 类型 | 默认值 | 说明 |
50
+ | ------------ | --------------------------------- | ----------- | -------------- |
51
+ | `items` | `ActionButtonDesc[]` | `[]` | 左侧按钮配置 |
52
+ | `rightItems` | `ActionButtonDesc[]` | `[]` | 右侧按钮配置 |
53
+ | `size` | `'small' \| 'default' \| 'large'` | `'default'` | 按钮尺寸 |
54
+
55
+ ---
56
+
57
+ ## 📋 ActionType 按钮类型
58
+
59
+ 使用 `type` 属性可以快速设置按钮的图标和样式:
60
+
61
+ | 类型 | 说明 | 图标 | 样式 |
62
+ | ---------- | -------- | ---------------- | ------- |
63
+ | `add` | 新增 | `Plus` | primary |
64
+ | `edit` | 编辑 | `Edit` | warning |
65
+ | `delete` | 删除 | `Delete` | danger |
66
+ | `batchDel` | 批量删除 | `Delete` | danger |
67
+ | `import` | 导入 | `Upload` | info |
68
+ | `export` | 导出 | `Download` | warning |
69
+ | `query` | 查询 | `Search` | primary |
70
+ | `reset` | 重置 | `Refresh` | - |
71
+ | `print` | 打印 | `Printer` | warning |
72
+ | `submit` | 提交 | `CircleCheck` | primary |
73
+ | `finish` | 完成 | `CircleCheck` | primary |
74
+ | `close` | 关闭 | `CircleClose` | info |
75
+ | `cancel` | 取消 | `CircleClose` | info |
76
+ | `rollback` | 退回 | `RefreshLeft` | warning |
77
+ | `back` | 返回 | `ArrowLeft` | - |
78
+ | `copy` | 复制 | `CopyDocument` | - |
79
+ | `view` | 查看 | `View` | - |
80
+ | `refresh` | 刷新 | `Refresh` | - |
81
+ | `save` | 保存 | `Document` | primary |
82
+ | `collapse` | 收起 | `DArrowLeft` | - |
83
+ | `expand` | 展开 | `DArrowRight` | - |
84
+ | `log` | 日志 | `Document` | - |
85
+ | `prev` | 上一步 | `ArrowLeftBold` | warning |
86
+ | `next` | 下一步 | `ArrowRightBold` | primary |
87
+ | `confirm` | 确认 | `Select` | primary |
88
+
89
+ ---
90
+
91
+ ## 📋 ActionButtonDesc 按钮配置
92
+
93
+ ```typescript
94
+ interface ActionButtonDesc {
95
+ // 按钮唯一标识(必填)
96
+ name: string;
97
+ // 按钮类型,会自动设置图标和样式
98
+ type?: ActionType;
99
+ // 自定义标签文本
100
+ label?: string;
101
+ // 自定义图标
102
+ icon?: string;
103
+ // 是否禁用
104
+ disabled?: boolean | (() => boolean);
105
+ // 是否显示
106
+ show?: boolean | (() => boolean);
107
+ // 加载状态
108
+ loading?: boolean | (() => boolean);
109
+ // 点击事件
110
+ onClick?: () => void | Promise<void>;
111
+ // 权限标识
112
+ permission?: string;
113
+ // 下拉子按钮
114
+ children?: ActionButtonDesc[];
115
+ // 是否朴素按钮
116
+ plain?: boolean;
117
+ // 是否自动管理加载状态(点击后自动 loading)
118
+ autoLoading?: boolean;
119
+ // 自定义渲染
120
+ renderNode?: () => VNode;
121
+ // 更多样式
122
+ style?: any;
123
+ // 下拉按钮(当存在 children 时)
124
+ split?: boolean;
125
+ }
126
+ ```
127
+
128
+ ---
129
+
130
+ ## 💡 使用示例
131
+
132
+ ### 基础工具栏
133
+
134
+ ```vue
135
+ <template>
136
+ <BaseToolbar :items="toolbarItems" />
137
+ </template>
138
+
139
+ <script setup lang="ts">
140
+ import { computed } from "vue";
141
+
142
+ const toolbarItems = computed(() => [
143
+ {
144
+ name: "add",
145
+ type: "add",
146
+ onClick: handleAdd
147
+ },
148
+ {
149
+ name: "edit",
150
+ type: "edit",
151
+ disabled: () => selectedRows.value.length !== 1,
152
+ onClick: handleEdit
153
+ },
154
+ {
155
+ name: "delete",
156
+ type: "delete",
157
+ disabled: () => selectedRows.value.length === 0,
158
+ onClick: handleDelete
159
+ }
160
+ ]);
161
+ </script>
162
+ ```
163
+
164
+ ### 左右布局
165
+
166
+ ```vue
167
+ <template>
168
+ <BaseToolbar
169
+ :items="leftItems"
170
+ :rightItems="rightItems"
171
+ />
172
+ </template>
173
+
174
+ <script setup lang="ts">
175
+ const leftItems = computed(() => [
176
+ { name: "add", type: "add", onClick: handleAdd },
177
+ { name: "delete", type: "batchDel", onClick: handleBatchDelete }
178
+ ]);
179
+
180
+ const rightItems = computed(() => [
181
+ { name: "export", type: "export", onClick: handleExport },
182
+ { name: "import", type: "import", onClick: handleImport }
183
+ ]);
184
+ </script>
185
+ ```
186
+
187
+ ### 自定义图标和标签
188
+
189
+ ```vue
190
+ <script setup lang="ts">
191
+ const toolbarItems = computed(() => [
192
+ {
193
+ name: "approve",
194
+ label: "审批通过",
195
+ icon: "Select",
196
+ onClick: handleApprove
197
+ },
198
+ {
199
+ name: "reject",
200
+ label: "审批退回",
201
+ icon: "CloseBold",
202
+ onClick: handleReject
203
+ }
204
+ ]);
205
+ </script>
206
+ ```
207
+
208
+ ### 下拉菜单按钮
209
+
210
+ ```vue
211
+ <script setup lang="ts">
212
+ const toolbarItems = computed(() => [
213
+ {
214
+ name: "add",
215
+ type: "add",
216
+ onClick: handleAdd
217
+ },
218
+ {
219
+ name: "more",
220
+ label: "更多操作",
221
+ icon: "More",
222
+ children: [
223
+ {
224
+ name: "copy",
225
+ type: "copy",
226
+ label: "复制",
227
+ onClick: handleCopy
228
+ },
229
+ {
230
+ name: "export",
231
+ type: "export",
232
+ label: "导出",
233
+ onClick: handleExport
234
+ },
235
+ {
236
+ name: "print",
237
+ type: "print",
238
+ label: "打印",
239
+ onClick: handlePrint
240
+ }
241
+ ]
242
+ }
243
+ ]);
244
+ </script>
245
+ ```
246
+
247
+ ### 分裂式下拉按钮
248
+
249
+ ```vue
250
+ <script setup lang="ts">
251
+ const toolbarItems = computed(() => [
252
+ {
253
+ name: "save",
254
+ type: "save",
255
+ label: "保存",
256
+ split: true, // 分裂式下拉
257
+ onClick: handleSave,
258
+ children: [
259
+ {
260
+ name: "saveAndNew",
261
+ label: "保存并新增",
262
+ onClick: handleSaveAndNew
263
+ },
264
+ {
265
+ name: "saveAndCopy",
266
+ label: "保存并复制",
267
+ onClick: handleSaveAndCopy
268
+ }
269
+ ]
270
+ }
271
+ ]);
272
+ </script>
273
+ ```
274
+
275
+ ### 权限控制
276
+
277
+ ```vue
278
+ <script setup lang="ts">
279
+ const toolbarItems = computed(() => [
280
+ {
281
+ name: "add",
282
+ type: "add",
283
+ permission: "sale:order:add", // 需要此权限才显示
284
+ onClick: handleAdd
285
+ },
286
+ {
287
+ name: "edit",
288
+ type: "edit",
289
+ permission: "sale:order:edit",
290
+ onClick: handleEdit
291
+ },
292
+ {
293
+ name: "delete",
294
+ type: "delete",
295
+ permission: "sale:order:delete",
296
+ onClick: handleDelete
297
+ }
298
+ ]);
299
+ </script>
300
+ ```
301
+
302
+ ### 加载状态
303
+
304
+ ```vue
305
+ <script setup lang="ts">
306
+ import { ref } from "vue";
307
+
308
+ const saving = ref(false);
309
+
310
+ const toolbarItems = computed(() => [
311
+ {
312
+ name: "save",
313
+ type: "save",
314
+ loading: () => saving.value, // 响应式加载状态
315
+ onClick: async () => {
316
+ saving.value = true;
317
+ await save();
318
+ saving.value = false;
319
+ }
320
+ },
321
+ {
322
+ name: "submit",
323
+ type: "submit",
324
+ autoLoading: true, // 自动管理加载状态
325
+ onClick: async () => {
326
+ await submit(); // 点击后自动 loading,完成后自动恢复
327
+ }
328
+ }
329
+ ]);
330
+ </script>
331
+ ```
332
+
333
+ ### 动态显示/禁用
334
+
335
+ ```vue
336
+ <script setup lang="ts">
337
+ import { ref } from "vue";
338
+
339
+ const selectedRows = ref([]);
340
+ const isEditing = ref(false);
341
+
342
+ const toolbarItems = computed(() => [
343
+ {
344
+ name: "add",
345
+ type: "add",
346
+ show: () => !isEditing.value, // 编辑时隐藏
347
+ onClick: handleAdd
348
+ },
349
+ {
350
+ name: "edit",
351
+ type: "edit",
352
+ show: () => !isEditing.value,
353
+ disabled: () => selectedRows.value.length !== 1, // 只选中一条时可用
354
+ onClick: handleEdit
355
+ },
356
+ {
357
+ name: "save",
358
+ type: "save",
359
+ show: () => isEditing.value, // 编辑时显示
360
+ onClick: handleSave
361
+ },
362
+ {
363
+ name: "cancel",
364
+ type: "cancel",
365
+ show: () => isEditing.value,
366
+ onClick: handleCancel
367
+ }
368
+ ]);
369
+ </script>
370
+ ```
371
+
372
+ ### 自定义渲染
373
+
374
+ ```vue
375
+ <script setup lang="ts">
376
+ import { h } from "vue";
377
+ import { ElSwitch } from "element-plus";
378
+
379
+ const autoRefresh = ref(false);
380
+
381
+ const rightItems = computed(() => [
382
+ {
383
+ name: "autoRefresh",
384
+ renderNode: () => h("div", { class: "flex items-center gap-2" }, [
385
+ h("span", "自动刷新"),
386
+ h(ElSwitch, {
387
+ modelValue: autoRefresh.value,
388
+ "onUpdate:modelValue": (val) => autoRefresh.value = val
389
+ })
390
+ ])
391
+ },
392
+ {
393
+ name: "refresh",
394
+ type: "refresh",
395
+ onClick: handleRefresh
396
+ }
397
+ ]);
398
+ </script>
399
+ ```
400
+
401
+ ---
402
+
403
+ ## 🎨 与其他组件配合
404
+
405
+ ### 配合 BaseQuery
406
+
407
+ ```vue
408
+ <template>
409
+ <div class="page">
410
+ <BaseQuery
411
+ :form="queryParam"
412
+ :items="queryItems"
413
+ @select="handleSearch"
414
+ @reset="handleReset"
415
+ />
416
+ <BaseToolbar :items="toolbarItems" />
417
+ <BaseTable :data="tableData" :columns="columns" />
418
+ </div>
419
+ </template>
420
+ ```
421
+
422
+ ### 在 BaseTable 中使用操作列
423
+
424
+ ```typescript
425
+ // 表格列配置中的操作列
426
+ {
427
+ name: "",
428
+ label: "操作",
429
+ width: 150,
430
+ actions: [
431
+ { name: "edit", type: "edit" },
432
+ { name: "delete", type: "delete" }
433
+ ]
434
+ }
435
+ ```
436
+
437
+ ---
438
+
439
+ ## ⚠️ 注意事项
440
+
441
+ 1. **使用 computed 包装按钮配置**
442
+
443
+ ```typescript
444
+ // ✅ 正确
445
+ const toolbarItems = computed(() => [...]);
446
+
447
+ // ❌ 避免
448
+ const toolbarItems = [...];
449
+ ```
450
+
451
+ 2. **disabled/show 使用函数形式**
452
+
453
+ ```typescript
454
+ // ✅ 响应式
455
+ disabled: () => selectedRows.value.length === 0
456
+
457
+ // ❌ 非响应式(只在初始化时计算一次)
458
+ disabled: selectedRows.value.length === 0
459
+ ```
460
+
461
+ 3. **autoLoading 适用于异步操作**
462
+
463
+ ```typescript
464
+ {
465
+ name: "submit",
466
+ autoLoading: true, // 点击后自动 loading
467
+ onClick: async () => {
468
+ await submitApi(); // 完成后自动恢复
469
+ }
470
+ }
471
+ ```
472
+
473
+ 4. **permission 需要后端配合**
474
+
475
+ - 权限标识需要与后端菜单权限配置一致
476
+
477
+ 5. **下拉按钮的 children 中也可以有权限控制**
478
+
479
+ ```typescript
480
+ {
481
+ name: "more",
482
+ label: "更多",
483
+ children: [
484
+ { name: "export", permission: "sale:order:export" },
485
+ { name: "print", permission: "sale:order:print" }
486
+ ]
487
+ }
488
+ ```
489
+
490
+ ---
491
+
492
+ ## 📚 相关文档
493
+
494
+ - [BaseTable 表格组件](../BaseTable/README.md) - 表格操作列按钮
495
+ - [BaseQuery 查询组件](../BaseQuery/README.md) - 查询区按钮
496
+ - [BaseForm 表单组件](../BaseForm/README.md) - 表单提交按钮