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

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 (85) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/README.md +1 -1
  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/guides/architecture.md +1 -1
  7. package/files/.wl-skills/skills/core/convention-audit/SKILL.md +3 -3
  8. package/files/.wl-skills/skills/core/spec-doc-parse/SKILL.md +332 -332
  9. package/files/.wl-skills/skills/core/spec-doc-parse/USAGE.md +97 -97
  10. package/files/.wl-skills/skills/sync/permission-sync/USAGE.md +107 -107
  11. package/files/.wl-skills/src/components/global/C_ParentView/index.vue +3 -3
  12. package/files/.wl-skills/src/components/global/C_RightToolbar/index.vue +157 -157
  13. package/files/.wl-skills/src/components/global/C_SvgIcon/index.vue +31 -31
  14. package/files/.wl-skills/src/components/global/C_SvgIcon/svgicon.js +10 -10
  15. package/files/.wl-skills/src/components/global/C_TagStatus/README.md +264 -264
  16. package/files/.wl-skills/src/components/global/C_TagStatus/config.ts +192 -192
  17. package/files/.wl-skills/src/components/global/C_TagStatus/index.vue +106 -106
  18. package/files/.wl-skills/src/components/global/C_TagStatus/types.ts +64 -64
  19. package/files/.wl-skills/src/components/global/C_Tree/README.md +153 -153
  20. package/files/.wl-skills/src/components/global/C_Tree/index.scss +42 -42
  21. package/files/.wl-skills/src/components/global/C_Tree/index.vue +78 -78
  22. package/files/.wl-skills/src/components/global/C_Tree/types.ts +59 -59
  23. package/files/.wl-skills/src/components/local/c_formModal/README.md +235 -235
  24. package/files/.wl-skills/src/components/local/c_formModal/data.ts +95 -95
  25. package/files/.wl-skills/src/components/local/c_formModal/index.scss +8 -8
  26. package/files/.wl-skills/src/components/local/c_formModal/index.vue +107 -107
  27. package/files/.wl-skills/src/components/local/c_formSections/data.ts +175 -175
  28. package/files/.wl-skills/src/components/local/c_formSections/index.scss +280 -280
  29. package/files/.wl-skills/src/components/local/c_formSections/index.vue +429 -429
  30. package/files/.wl-skills/src/components/local/c_listModal/data.ts +41 -41
  31. package/files/.wl-skills/src/components/local/c_listModal/index.vue +136 -136
  32. package/files/.wl-skills/src/components/local/c_spliterTitle/index.scss +25 -25
  33. package/files/.wl-skills/src/components/local/c_spliterTitle/index.vue +21 -21
  34. package/files/.wl-skills/src/components/remote/AGGrid/README.md +530 -530
  35. package/files/.wl-skills/src/components/remote/BaseForm/README.md +508 -508
  36. package/files/.wl-skills/src/components/remote/BaseQuery/README.md +865 -865
  37. package/files/.wl-skills/src/components/remote/BaseTable/README.md +941 -941
  38. package/files/.wl-skills/src/components/remote/BaseToolbar/README.md +496 -496
  39. package/files/.wl-skills/src/types/page.ts +24 -24
  40. package/files/.wl-skills/standards/04-coding-basics.md +39 -1
  41. package/files/.wl-skills/standards/09-typescript.md +26 -3
  42. package/files/.wl-skills/standards/index.md +2 -2
  43. package/files/.wl-skills/templates/README.md +44 -44
  44. package/files/.wl-skills/templates/produce/aiflow/mmwr-customer-apply-add/api.md +54 -54
  45. package/files/.wl-skills/templates/produce/aiflow/mmwr-customer-apply-add/data.ts +346 -346
  46. package/files/.wl-skills/templates/produce/aiflow/mmwr-customer-apply-add/index.scss +1 -1
  47. package/files/.wl-skills/templates/produce/aiflow/mmwr-customer-apply-add/index.vue +28 -28
  48. package/files/.wl-skills/templates/produce/aiflow/mmwr-customer-apply-add-form/data.ts +115 -115
  49. package/files/.wl-skills/templates/produce/aiflow/mmwr-customer-apply-add-form/index.scss +44 -44
  50. package/files/.wl-skills/templates/produce/aiflow/mmwr-customer-apply-add-form/index.vue +43 -43
  51. package/files/.wl-skills/templates/produce/aiflow/mmwr-customer-apply-change/data.ts +338 -338
  52. package/files/.wl-skills/templates/produce/aiflow/mmwr-customer-apply-change/index.scss +1 -1
  53. package/files/.wl-skills/templates/produce/aiflow/mmwr-customer-apply-change/index.vue +28 -28
  54. package/files/.wl-skills/templates/produce/aiflow/mmwr-customer-apply-change-form/data.ts +115 -115
  55. package/files/.wl-skills/templates/produce/aiflow/mmwr-customer-apply-change-form/index.scss +44 -44
  56. package/files/.wl-skills/templates/produce/aiflow/mmwr-customer-apply-change-form/index.vue +43 -43
  57. package/files/.wl-skills/templates/produce/aiflow/mmwr-customer-archive/api.md +88 -88
  58. package/files/.wl-skills/templates/produce/aiflow/mmwr-customer-archive/data.ts +601 -601
  59. package/files/.wl-skills/templates/produce/aiflow/mmwr-customer-archive/index.scss +1 -1
  60. package/files/.wl-skills/templates/produce/aiflow/mmwr-customer-archive/index.vue +64 -64
  61. package/files/.wl-skills/templates/produce/aiflow/mmwr-customer-detail/api.md +67 -67
  62. package/files/.wl-skills/templates/produce/aiflow/mmwr-customer-detail/data.ts +286 -286
  63. package/files/.wl-skills/templates/produce/aiflow/mmwr-customer-detail/index.scss +139 -139
  64. package/files/.wl-skills/templates/produce/aiflow/mmwr-customer-detail/index.vue +318 -318
  65. package/files/.wl-skills/templates/produce/aiflow/mmwr-temp-customer-archive/api.md +98 -98
  66. package/files/.wl-skills/templates/produce/aiflow/mmwr-temp-customer-archive/data.ts +543 -543
  67. package/files/.wl-skills/templates/produce/aiflow/mmwr-temp-customer-archive/index.scss +1 -1
  68. package/files/.wl-skills/templates/produce/aiflow/mmwr-temp-customer-archive/index.vue +52 -52
  69. package/files/.wl-skills/templates/sale/demo/add-demo/data.ts +518 -518
  70. package/files/.wl-skills/templates/sale/demo/billet-flame-cut-plan/data.ts +524 -524
  71. package/files/.wl-skills/templates/sale/demo/billet-flame-cut-plan/index.scss +154 -154
  72. package/files/.wl-skills/templates/sale/demo/billet-flame-cut-plan/index.vue +117 -117
  73. package/files/.wl-skills/templates/sale/demo/domestic-trade-order/data.ts +308 -308
  74. package/files/.wl-skills/templates/sale/demo/domestic-trade-order/index.scss +99 -99
  75. package/files/.wl-skills/templates/sale/demo/domestic-trade-order/index.vue +77 -77
  76. package/files/.wl-skills/templates/sale/demo/heat-batch-return/data.ts +367 -367
  77. package/files/.wl-skills/templates/sale/demo/heat-batch-return/index.scss +100 -100
  78. package/files/.wl-skills/templates/sale/demo/heat-batch-return/index.vue +170 -170
  79. package/files/.wl-skills/templates/sale/demo/heat-batch-return/meltDialog.vue +320 -320
  80. package/files/.wl-skills/templates/sale/demo/metallurgical-spec/data.ts +824 -824
  81. package/lib/ast-rules.js +304 -9
  82. package/mcp/config.js +46 -46
  83. package/mcp/registry.js +6 -1
  84. package/mcp/tools/projectTools.js +9 -1
  85. package/package.json +2 -2
@@ -1,59 +1,59 @@
1
- /**
2
- * C_Tree 组件类型定义(纯树形展示)
3
- */
4
-
5
- /** 树形节点数据 */
6
- export interface TreeNode {
7
- id?: string | number;
8
- label?: string;
9
- children?: TreeNode[];
10
- [key: string]: any;
11
- }
12
-
13
- /** 标签页配置 */
14
- export interface TabConfig {
15
- label: string;
16
- name: string;
17
- }
18
-
19
- /** 树形配置 */
20
- export interface TreeProps {
21
- children?: string;
22
- label?: string;
23
- disabled?: string;
24
- isLeaf?: string;
25
- }
26
-
27
- /** C_Tree 组件 Props */
28
- export interface CTreeProps {
29
- /** Tab 配置数组 */
30
- tabs?: TabConfig[];
31
- /** 树形数据(必填) */
32
- treeData: TreeNode[];
33
- /** 树形配置 */
34
- treeProps?: TreeProps;
35
- /** 默认激活的 tab */
36
- defaultActiveTab?: string;
37
- /** 是否显示搜索框 */
38
- showSearch?: boolean;
39
- /** 搜索框占位符 */
40
- searchPlaceholder?: string;
41
- /** 是否默认展开所有节点 */
42
- defaultExpandAll?: boolean;
43
- /** 是否高亮当前选中节点 */
44
- highlightCurrent?: boolean;
45
- }
46
-
47
- /** C_Tree 组件暴露的方法 */
48
- export interface CTreeExpose {
49
- /** 树形组件实例 */
50
- treeRef: any;
51
- /** 搜索关键词 */
52
- searchKeyword: string;
53
- /** 当前激活的 tab */
54
- activeTab: string;
55
- /** 清空搜索 */
56
- clearSearch: () => void;
57
- /** 切换 tab */
58
- switchTab: (tabName: string) => void;
59
- }
1
+ /**
2
+ * C_Tree 组件类型定义(纯树形展示)
3
+ */
4
+
5
+ /** 树形节点数据 */
6
+ export interface TreeNode {
7
+ id?: string | number;
8
+ label?: string;
9
+ children?: TreeNode[];
10
+ [key: string]: any;
11
+ }
12
+
13
+ /** 标签页配置 */
14
+ export interface TabConfig {
15
+ label: string;
16
+ name: string;
17
+ }
18
+
19
+ /** 树形配置 */
20
+ export interface TreeProps {
21
+ children?: string;
22
+ label?: string;
23
+ disabled?: string;
24
+ isLeaf?: string;
25
+ }
26
+
27
+ /** C_Tree 组件 Props */
28
+ export interface CTreeProps {
29
+ /** Tab 配置数组 */
30
+ tabs?: TabConfig[];
31
+ /** 树形数据(必填) */
32
+ treeData: TreeNode[];
33
+ /** 树形配置 */
34
+ treeProps?: TreeProps;
35
+ /** 默认激活的 tab */
36
+ defaultActiveTab?: string;
37
+ /** 是否显示搜索框 */
38
+ showSearch?: boolean;
39
+ /** 搜索框占位符 */
40
+ searchPlaceholder?: string;
41
+ /** 是否默认展开所有节点 */
42
+ defaultExpandAll?: boolean;
43
+ /** 是否高亮当前选中节点 */
44
+ highlightCurrent?: boolean;
45
+ }
46
+
47
+ /** C_Tree 组件暴露的方法 */
48
+ export interface CTreeExpose {
49
+ /** 树形组件实例 */
50
+ treeRef: any;
51
+ /** 搜索关键词 */
52
+ searchKeyword: string;
53
+ /** 当前激活的 tab */
54
+ activeTab: string;
55
+ /** 清空搜索 */
56
+ clearSearch: () => void;
57
+ /** 切换 tab */
58
+ switchTab: (tabName: string) => void;
59
+ }
@@ -1,235 +1,235 @@
1
- # c_formModal - 通用表单弹窗组件
2
-
3
- > 🎯 支持新增、编辑、详情三种模式的通用业务组件
4
-
5
- ## 📖 组件说明
6
-
7
- 这是一个高度可复用的表单弹窗组件,抽象了常见的 CRUD 场景中的表单交互逻辑。通过配置化的方式,快速实现新增、编辑、查看详情等功能,避免每个页面重复编写相同的弹窗代码。
8
-
9
- ## ✨ 核心特性
10
-
11
- - ✅ **三种模式**:新增(add)、编辑(edit)、详情(view)
12
- - ✅ **配置驱动**:通过 `modalConfig` 对象配置所有行为
13
- - ✅ **自动标题**:根据模式自动生成标题(新增/编辑/查看 + titlePrefix)
14
- - ✅ **智能按钮**:编辑模式显示"取消/确定",详情模式显示"关闭"
15
- - ✅ **表单校验**:继承 `AbstractFormHook`,自动支持表单验证
16
- - ✅ **异步请求**:使用 async/await 扁平化异步代码
17
- - ✅ **类型安全**:完整的 TypeScript 类型定义
18
-
19
- ## 📦 文件结构
20
-
21
- ```
22
- c_formModal/
23
- ├── index.vue # 视图层(模板 + Props 定义)
24
- ├── data.ts # 数据逻辑层(Hook 创建 + 业务逻辑)
25
- ├── index.scss # 样式层
26
- └── README.md # 使用文档
27
- ```
28
-
29
- ## 🚀 快速开始
30
-
31
- ### 1️⃣ 在 data.ts 中配置
32
-
33
- ```typescript
34
- // src/views/your-module/data.ts
35
- import type { BaseFormItemDesc } from "@jhlc/common-core/.wl-skills/src/components/form/common/type";
36
-
37
- export const modalConfig = {
38
- titlePrefix: "内贸订单", // 标题前缀
39
- width: "850px", // 弹窗宽度
40
- columns: 2, // 表单列数
41
- labelWidth: "110px", // 标签宽度
42
- formItems: [
43
- // 表单字段配置
44
- {
45
- name: "foreignTradeOrderNo",
46
- label: "外贸订单号",
47
- required: true,
48
- placeholder: "请输入外贸订单号"
49
- },
50
- {
51
- name: "period",
52
- label: "周期",
53
- required: true,
54
- placeholder: "请选择"
55
- }
56
- // ... 更多字段
57
- ] as BaseFormItemDesc<any>[],
58
- api: {
59
- // API 路径配置
60
- getById: "/api/your-module/getOneById",
61
- save: "/api/your-module/save",
62
- update: "/api/your-module/update"
63
- }
64
- };
65
- ```
66
-
67
- ### 2️⃣ 在 index.vue 中使用
68
-
69
- ```vue
70
- <template>
71
- <div>
72
- <!-- 你的列表页面 -->
73
- <BaseTable :data="list" />
74
-
75
- <!-- 表单弹窗 -->
76
- <c_formModal ref="modalRef" v-bind="modalConfig" @ok="select" />
77
- </div>
78
- </template>
79
-
80
- <script setup lang="ts">
81
- import c_formModal from "@/components/local/c_formModal/index.vue";
82
- import { modalConfig } from "./data";
83
-
84
- const modalRef = ref<InstanceType<typeof c_formModal>>();
85
-
86
- // 新增
87
- function handleAdd() {
88
- modalRef.value?.open();
89
- }
90
-
91
- // 编辑
92
- function handleEdit(id: string) {
93
- modalRef.value?.edit(id);
94
- }
95
-
96
- // 查看详情
97
- function handleView(id: string) {
98
- modalRef.value?.view(id);
99
- }
100
-
101
- // 刷新列表
102
- function select() {
103
- // 重新加载列表数据
104
- }
105
- </script>
106
- ```
107
-
108
- ## 🔧 Props 配置
109
-
110
- | 参数 | 类型 | 必填 | 默认值 | 说明 |
111
- | ------------- | -------------------- | ---- | ------- | ---------------- |
112
- | `formItems` | `BaseFormItemDesc[]` | ✅ | - | 表单字段配置数组 |
113
- | `api` | `ModalApi` | ✅ | - | API 路径配置对象 |
114
- | `width` | `string` | ❌ | `850px` | 弹窗宽度 |
115
- | `columns` | `number` | ❌ | `2` | 表单列数 |
116
- | `labelWidth` | `string` | ❌ | `110px` | 标签宽度 |
117
- | `titlePrefix` | `string` | ❌ | `数据` | 标题前缀 |
118
-
119
- ### ModalApi 类型
120
-
121
- ```typescript
122
- interface ModalApi {
123
- getById: string; // 获取详情接口
124
- save: string; // 新增保存接口
125
- update: string; // 编辑更新接口
126
- }
127
- ```
128
-
129
- ## 📡 事件
130
-
131
- | 事件名 | 参数 | 说明 |
132
- | ------ | ---- | ---------------------------- |
133
- | `ok` | - | 保存成功后触发,用于刷新列表 |
134
-
135
- ## 🎯 暴露方法
136
-
137
- | 方法名 | 参数 | 返回值 | 说明 |
138
- | ------------------ | -------------- | --------------- | -------------------- |
139
- | `open()` | - | `void` | 打开新增弹窗 |
140
- | `edit(id: string)` | `id` - 数据 ID | `Promise<void>` | 打开编辑弹窗 |
141
- | `view(id: string)` | `id` - 数据 ID | `Promise<void>` | 打开详情弹窗(只读) |
142
-
143
- ## 💡 使用场景
144
-
145
- ### 场景 1:标准 CRUD 页面
146
-
147
- 适用于大多数列表页面,包含新增、编辑、删除、查看详情功能。
148
-
149
- ```typescript
150
- // 工具栏按钮
151
- const toolbars = [
152
- { label: "新增", icon: "Plus", onClick: () => modalRef.value?.open() },
153
- {
154
- label: "编辑",
155
- icon: "Edit",
156
- onClick: () => modalRef.value?.edit(selectedId)
157
- },
158
- {
159
- label: "查看",
160
- icon: "View",
161
- onClick: () => modalRef.value?.view(selectedId)
162
- }
163
- ];
164
- ```
165
-
166
- ### 场景 2:审批流程页面
167
-
168
- 详情模式展示数据,编辑模式修改数据。
169
-
170
- ```typescript
171
- // 查看待审批数据
172
- modalRef.value?.view(taskId);
173
-
174
- // 修改后重新提交
175
- modalRef.value?.edit(taskId);
176
- ```
177
-
178
- ### 场景 3:多步骤表单
179
-
180
- 结合其他组件,实现复杂的表单交互。
181
-
182
- ## 📊 性能对比
183
-
184
- | 项目 | 传统方式 | 使用 c_formModal | 节省 |
185
- | ------------------ | -------- | ---------------- | ------------------ |
186
- | **Modal.vue** | 178 行 | **0 行**(删除) | -178 行 |
187
- | **modalConfig** | - | 66 行 | +66 行 |
188
- | **每个页面净节省** | 178 行 | 66 行 | **-112 行 (-63%)** |
189
-
190
- ## 🔍 工作原理
191
-
192
- 1. **配置解析**:通过 `v-bind="modalConfig"` 传递所有配置到组件
193
- 2. **Hook 创建**:`createFormModal()` 工厂函数创建 `AbstractFormHook` 实例
194
- 3. **模式切换**:根据 `mode` 状态(add/edit/view)调整 UI 和行为
195
- 4. **异步请求**:使用 async/await 处理表单保存和数据加载
196
- 5. **事件通知**:操作完成后通过 `emit('ok')` 通知父组件刷新列表
197
-
198
- ## ⚠️ 注意事项
199
-
200
- 1. **API 规范**:后端接口需要遵循统一的响应格式 `{code, message, data}`
201
- 2. **字段类型**:`formItems` 必须是 `BaseFormItemDesc<any>[]` 类型
202
- 3. **ID 参数**:`edit()` 和 `view()` 方法的 `id` 参数会作为查询参数传递给 `getById` 接口
203
- 4. **表单校验**:字段的 `required` 属性会自动生成必填校验规则
204
-
205
- ## 🎨 自定义扩展
206
-
207
- ### 修改样式
208
-
209
- 编辑 [index.scss](index.scss) 文件:
210
-
211
- ```scss
212
- .dialog-footer {
213
- display: flex;
214
- justify-content: flex-end;
215
- padding: 10px; // 添加内边距
216
- }
217
- ```
218
-
219
- ### 扩展功能
220
-
221
- 在 [data.ts](data.ts) 中新增方法:
222
-
223
- ```typescript
224
- export function createFormModal(/* ... */) {
225
- const Page = new (class extends AbstractFormHook {
226
- // 新增自定义方法
227
- async deleteAttachment(id: string) {
228
- await axios.delete(`/api/attachment/${id}`);
229
- }
230
- })();
231
-
232
- return Page.create();
233
- }
234
- ```
235
-
1
+ # c_formModal - 通用表单弹窗组件
2
+
3
+ > 🎯 支持新增、编辑、详情三种模式的通用业务组件
4
+
5
+ ## 📖 组件说明
6
+
7
+ 这是一个高度可复用的表单弹窗组件,抽象了常见的 CRUD 场景中的表单交互逻辑。通过配置化的方式,快速实现新增、编辑、查看详情等功能,避免每个页面重复编写相同的弹窗代码。
8
+
9
+ ## ✨ 核心特性
10
+
11
+ - ✅ **三种模式**:新增(add)、编辑(edit)、详情(view)
12
+ - ✅ **配置驱动**:通过 `modalConfig` 对象配置所有行为
13
+ - ✅ **自动标题**:根据模式自动生成标题(新增/编辑/查看 + titlePrefix)
14
+ - ✅ **智能按钮**:编辑模式显示"取消/确定",详情模式显示"关闭"
15
+ - ✅ **表单校验**:继承 `AbstractFormHook`,自动支持表单验证
16
+ - ✅ **异步请求**:使用 async/await 扁平化异步代码
17
+ - ✅ **类型安全**:完整的 TypeScript 类型定义
18
+
19
+ ## 📦 文件结构
20
+
21
+ ```
22
+ c_formModal/
23
+ ├── index.vue # 视图层(模板 + Props 定义)
24
+ ├── data.ts # 数据逻辑层(Hook 创建 + 业务逻辑)
25
+ ├── index.scss # 样式层
26
+ └── README.md # 使用文档
27
+ ```
28
+
29
+ ## 🚀 快速开始
30
+
31
+ ### 1️⃣ 在 data.ts 中配置
32
+
33
+ ```typescript
34
+ // src/views/your-module/data.ts
35
+ import type { BaseFormItemDesc } from "@jhlc/common-core/.wl-skills/src/components/form/common/type";
36
+
37
+ export const modalConfig = {
38
+ titlePrefix: "内贸订单", // 标题前缀
39
+ width: "850px", // 弹窗宽度
40
+ columns: 2, // 表单列数
41
+ labelWidth: "110px", // 标签宽度
42
+ formItems: [
43
+ // 表单字段配置
44
+ {
45
+ name: "foreignTradeOrderNo",
46
+ label: "外贸订单号",
47
+ required: true,
48
+ placeholder: "请输入外贸订单号"
49
+ },
50
+ {
51
+ name: "period",
52
+ label: "周期",
53
+ required: true,
54
+ placeholder: "请选择"
55
+ }
56
+ // ... 更多字段
57
+ ] as BaseFormItemDesc<any>[],
58
+ api: {
59
+ // API 路径配置
60
+ getById: "/api/your-module/getOneById",
61
+ save: "/api/your-module/save",
62
+ update: "/api/your-module/update"
63
+ }
64
+ };
65
+ ```
66
+
67
+ ### 2️⃣ 在 index.vue 中使用
68
+
69
+ ```vue
70
+ <template>
71
+ <div>
72
+ <!-- 你的列表页面 -->
73
+ <BaseTable :data="list" />
74
+
75
+ <!-- 表单弹窗 -->
76
+ <c_formModal ref="modalRef" v-bind="modalConfig" @ok="select" />
77
+ </div>
78
+ </template>
79
+
80
+ <script setup lang="ts">
81
+ import c_formModal from "@/components/local/c_formModal/index.vue";
82
+ import { modalConfig } from "./data";
83
+
84
+ const modalRef = ref<InstanceType<typeof c_formModal>>();
85
+
86
+ // 新增
87
+ function handleAdd() {
88
+ modalRef.value?.open();
89
+ }
90
+
91
+ // 编辑
92
+ function handleEdit(id: string) {
93
+ modalRef.value?.edit(id);
94
+ }
95
+
96
+ // 查看详情
97
+ function handleView(id: string) {
98
+ modalRef.value?.view(id);
99
+ }
100
+
101
+ // 刷新列表
102
+ function select() {
103
+ // 重新加载列表数据
104
+ }
105
+ </script>
106
+ ```
107
+
108
+ ## 🔧 Props 配置
109
+
110
+ | 参数 | 类型 | 必填 | 默认值 | 说明 |
111
+ | ------------- | -------------------- | ---- | ------- | ---------------- |
112
+ | `formItems` | `BaseFormItemDesc[]` | ✅ | - | 表单字段配置数组 |
113
+ | `api` | `ModalApi` | ✅ | - | API 路径配置对象 |
114
+ | `width` | `string` | ❌ | `850px` | 弹窗宽度 |
115
+ | `columns` | `number` | ❌ | `2` | 表单列数 |
116
+ | `labelWidth` | `string` | ❌ | `110px` | 标签宽度 |
117
+ | `titlePrefix` | `string` | ❌ | `数据` | 标题前缀 |
118
+
119
+ ### ModalApi 类型
120
+
121
+ ```typescript
122
+ interface ModalApi {
123
+ getById: string; // 获取详情接口
124
+ save: string; // 新增保存接口
125
+ update: string; // 编辑更新接口
126
+ }
127
+ ```
128
+
129
+ ## 📡 事件
130
+
131
+ | 事件名 | 参数 | 说明 |
132
+ | ------ | ---- | ---------------------------- |
133
+ | `ok` | - | 保存成功后触发,用于刷新列表 |
134
+
135
+ ## 🎯 暴露方法
136
+
137
+ | 方法名 | 参数 | 返回值 | 说明 |
138
+ | ------------------ | -------------- | --------------- | -------------------- |
139
+ | `open()` | - | `void` | 打开新增弹窗 |
140
+ | `edit(id: string)` | `id` - 数据 ID | `Promise<void>` | 打开编辑弹窗 |
141
+ | `view(id: string)` | `id` - 数据 ID | `Promise<void>` | 打开详情弹窗(只读) |
142
+
143
+ ## 💡 使用场景
144
+
145
+ ### 场景 1:标准 CRUD 页面
146
+
147
+ 适用于大多数列表页面,包含新增、编辑、删除、查看详情功能。
148
+
149
+ ```typescript
150
+ // 工具栏按钮
151
+ const toolbars = [
152
+ { label: "新增", icon: "Plus", onClick: () => modalRef.value?.open() },
153
+ {
154
+ label: "编辑",
155
+ icon: "Edit",
156
+ onClick: () => modalRef.value?.edit(selectedId)
157
+ },
158
+ {
159
+ label: "查看",
160
+ icon: "View",
161
+ onClick: () => modalRef.value?.view(selectedId)
162
+ }
163
+ ];
164
+ ```
165
+
166
+ ### 场景 2:审批流程页面
167
+
168
+ 详情模式展示数据,编辑模式修改数据。
169
+
170
+ ```typescript
171
+ // 查看待审批数据
172
+ modalRef.value?.view(taskId);
173
+
174
+ // 修改后重新提交
175
+ modalRef.value?.edit(taskId);
176
+ ```
177
+
178
+ ### 场景 3:多步骤表单
179
+
180
+ 结合其他组件,实现复杂的表单交互。
181
+
182
+ ## 📊 性能对比
183
+
184
+ | 项目 | 传统方式 | 使用 c_formModal | 节省 |
185
+ | ------------------ | -------- | ---------------- | ------------------ |
186
+ | **Modal.vue** | 178 行 | **0 行**(删除) | -178 行 |
187
+ | **modalConfig** | - | 66 行 | +66 行 |
188
+ | **每个页面净节省** | 178 行 | 66 行 | **-112 行 (-63%)** |
189
+
190
+ ## 🔍 工作原理
191
+
192
+ 1. **配置解析**:通过 `v-bind="modalConfig"` 传递所有配置到组件
193
+ 2. **Hook 创建**:`createFormModal()` 工厂函数创建 `AbstractFormHook` 实例
194
+ 3. **模式切换**:根据 `mode` 状态(add/edit/view)调整 UI 和行为
195
+ 4. **异步请求**:使用 async/await 处理表单保存和数据加载
196
+ 5. **事件通知**:操作完成后通过 `emit('ok')` 通知父组件刷新列表
197
+
198
+ ## ⚠️ 注意事项
199
+
200
+ 1. **API 规范**:后端接口需要遵循统一的响应格式 `{code, message, data}`
201
+ 2. **字段类型**:`formItems` 必须是 `BaseFormItemDesc<any>[]` 类型
202
+ 3. **ID 参数**:`edit()` 和 `view()` 方法的 `id` 参数会作为查询参数传递给 `getById` 接口
203
+ 4. **表单校验**:字段的 `required` 属性会自动生成必填校验规则
204
+
205
+ ## 🎨 自定义扩展
206
+
207
+ ### 修改样式
208
+
209
+ 编辑 [index.scss](index.scss) 文件:
210
+
211
+ ```scss
212
+ .dialog-footer {
213
+ display: flex;
214
+ justify-content: flex-end;
215
+ padding: 10px; // 添加内边距
216
+ }
217
+ ```
218
+
219
+ ### 扩展功能
220
+
221
+ 在 [data.ts](data.ts) 中新增方法:
222
+
223
+ ```typescript
224
+ export function createFormModal(/* ... */) {
225
+ const Page = new (class extends AbstractFormHook {
226
+ // 新增自定义方法
227
+ async deleteAttachment(id: string) {
228
+ await axios.delete(`/api/attachment/${id}`);
229
+ }
230
+ })();
231
+
232
+ return Page.create();
233
+ }
234
+ ```
235
+