@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,508 +1,508 @@
1
- # BaseForm 表单组件
2
-
3
- > 来源:`@jhlc/common-core` 远程组件
4
-
5
- BaseForm 是一个功能强大的表单组件,支持多列布局、数据验证、逻辑数据类型、自定义组件等功能。适用于新增、编辑场景。
6
-
7
- ## 📦 导入方式
8
-
9
- ```typescript
10
- // 全局注册(已在项目中配置)
11
- // 直接使用 <BaseForm /> 即可
12
-
13
- // 类型导入
14
- import type { BaseFormItemDesc } from "@jhlc/common-core/.wl-skills/src/components/form/common/type";
15
- ```
16
-
17
- ## 🚀 基本用法
18
-
19
- ```vue
20
- <template>
21
- <BaseForm
22
- ref="formRef"
23
- :form="form"
24
- :items="formItems"
25
- :columns="2"
26
- label-width="100px"
27
- />
28
- </template>
29
-
30
- <script setup lang="ts">
31
- import { ref, reactive, computed } from "vue";
32
-
33
- const formRef = ref();
34
- const form = reactive({
35
- userName: "",
36
- phone: "",
37
- userType: ""
38
- });
39
-
40
- const formItems = computed(() => [
41
- {
42
- name: "userName",
43
- label: "用户名",
44
- required: true,
45
- placeholder: "请输入用户名"
46
- },
47
- {
48
- name: "phone",
49
- label: "手机号",
50
- placeholder: "请输入手机号"
51
- },
52
- {
53
- name: "userType",
54
- label: "用户类型",
55
- logicType: "dict",
56
- logicValue: "USER_TYPE"
57
- }
58
- ]);
59
- </script>
60
- ```
61
-
62
- ---
63
-
64
- ## 📋 Props 属性
65
-
66
- | 属性名 | 类型 | 默认值 | 说明 |
67
- | ------------ | ------------------------------ | --------- | ---------------- |
68
- | `form` | `Object` | - | 表单数据对象 |
69
- | `items` | `BaseFormItemDesc[]` | `[]` | 表单项配置数组 |
70
- | `columns` | `number` | - | 列数 |
71
- | `labelWidth` | `string` | - | 标签宽度 |
72
- | `size` | `'default' \| 'large' \| 'small'` | - | 表单尺寸 |
73
- | `disabled` | `boolean` | `false` | 是否禁用 |
74
- | `isViewer` | `boolean` | `false` | 是否查看模式 |
75
- | `noForm` | `boolean` | `false` | 不使用 form 包裹 |
76
- | `style` | `string \| Object` | - | 自定义样式 |
77
- | `classnames` | `Array \| string` | - | 自定义类名 |
78
-
79
- ---
80
-
81
- ## 📋 Expose 方法 (通过 ref 调用)
82
-
83
- | 方法名 | 参数 | 返回值 | 说明 |
84
- | ----------------- | --------------------------- | ------ | -------------- |
85
- | `validate` | `cb: (valid: boolean) => void` | - | 验证表单 |
86
- | `setDefaultValue` | - | - | 设置默认值 |
87
- | `reset` | - | - | 重置表单 |
88
- | `resetFields` | - | - | 重置表单字段 |
89
-
90
- ---
91
-
92
- ## 📋 表单项配置 BaseFormItemDesc
93
-
94
- ### 基础属性
95
-
96
- ```typescript
97
- interface BaseFormItemDesc<T = any> {
98
- // 字段名(绑定 form 对象的属性名)
99
- name?: string;
100
- // 标签文本
101
- label?: string;
102
- // 标签宽度
103
- labelWidth?: string;
104
- // 显示冒号
105
- showColon?: boolean;
106
- // 占位提示
107
- placeholder?: string;
108
- // 栅格数(24 格布局)
109
- span?: number;
110
- // 是否禁用
111
- disabled?: boolean | ((form: T) => boolean);
112
- // 是否可清空
113
- clearable?: boolean;
114
- // 是否显示
115
- show?: boolean | ((form: T) => boolean);
116
- }
117
- ```
118
-
119
- ### 校验规则
120
-
121
- ```typescript
122
- {
123
- name: "userName",
124
- label: "用户名",
125
- // 必填
126
- required: true,
127
- // 或使用函数动态判断
128
- required: (form) => form.userType === "admin",
129
- // 校验提示
130
- message: "请输入用户名",
131
- // 自定义校验规则
132
- rules: [
133
- { required: true, message: "请输入用户名", trigger: "blur" },
134
- { min: 2, max: 20, message: "长度在 2 到 20 个字符", trigger: "blur" },
135
- {
136
- pattern: /^[a-zA-Z0-9_]+$/,
137
- message: "只能包含字母、数字和下划线",
138
- trigger: "blur"
139
- },
140
- {
141
- validator: (rule, value, callback) => {
142
- if (value === "admin") {
143
- callback(new Error("不能使用 admin 作为用户名"));
144
- } else {
145
- callback();
146
- }
147
- },
148
- trigger: "blur"
149
- }
150
- ]
151
- }
152
- ```
153
-
154
- ### 逻辑数据类型
155
-
156
- 组件会根据 `logicType` 自动选择合适的表单控件:
157
-
158
- ```typescript
159
- {
160
- name: "status",
161
- label: "状态",
162
- // 字典类型 - 自动渲染为下拉选择
163
- logicType: "dict",
164
- logicValue: "ORDER_STATUS"
165
- }
166
-
167
- {
168
- name: "createTime",
169
- label: "创建时间",
170
- // 日期类型 - 自动渲染为日期选择器
171
- logicType: "date"
172
- }
173
-
174
- {
175
- name: "createDatetime",
176
- label: "创建时间",
177
- // 日期时间类型
178
- logicType: "datetime"
179
- }
180
-
181
- {
182
- name: "amount",
183
- label: "金额",
184
- // 数字类型 - 自动渲染为数字输入框
185
- logicType: "number"
186
- }
187
-
188
- {
189
- name: "isActive",
190
- label: "是否启用",
191
- // 布尔类型 - 自动渲染为开关
192
- logicType: "boolean"
193
- }
194
-
195
- {
196
- name: "userId",
197
- label: "负责人",
198
- // 用户类型 - 自动渲染为用户选择器
199
- logicType: "user"
200
- }
201
-
202
- {
203
- name: "deptId",
204
- label: "部门",
205
- // 部门类型 - 自动渲染为部门选择器
206
- logicType: "dept"
207
- }
208
-
209
- {
210
- name: "remark",
211
- label: "备注",
212
- // 多行文本
213
- logicType: "textarea"
214
- }
215
- ```
216
-
217
- ### 默认值配置
218
-
219
- ```typescript
220
- {
221
- name: "createTime",
222
- label: "创建时间",
223
- logicType: "date",
224
- // 支持多种默认值类型
225
- defaultValue: "currentDay" // 当天
226
- // defaultValue: "currentMonth" // 当月
227
- // defaultValue: "currentYear" // 当年
228
- }
229
-
230
- // 日期范围默认值
231
- {
232
- type: "range",
233
- name: "dateRange",
234
- startName: "startDate",
235
- endName: "endDate",
236
- logicType: "date",
237
- defaultValue: "recentDay7" // 最近 7 天
238
- // defaultValue: "recentDay30" // 最近 30 天
239
- // defaultValue: "rangeDayCurrentMonth1ToToday" // 当月1号到今天
240
- }
241
- ```
242
-
243
- **支持的默认值类型:**
244
-
245
- | 值 | 说明 |
246
- | ------------------------------- | ----------------------- |
247
- | `currentDay` | 当天 (2024-09-22) |
248
- | `currentMonth` | 当月 (2024-09) |
249
- | `currentYear` | 当年 (2024) |
250
- | `currentDept` | 当前部门 |
251
- | `recentDay3` | 最近 3 天 |
252
- | `recentDay7` | 最近 7 天 |
253
- | `recentDay30` | 最近 30 天 |
254
- | `rangeDatetimeToday` | 当天 0 点到 23 点 |
255
- | `rangeDayCurrentMonth1ToToday` | 当月 1 号到今天 |
256
- | `rangeDayCurrentMonth1ToLastDay`| 当月 1 号到月末 |
257
-
258
- ### 范围输入
259
-
260
- ```typescript
261
- {
262
- type: "range",
263
- label: "日期范围",
264
- startName: "startDate",
265
- endName: "endDate",
266
- logicType: "date",
267
- rangeSeparator: "至",
268
- // 自定义起止表单项
269
- startFormItem: {
270
- placeholder: "开始日期"
271
- },
272
- endFormItem: {
273
- placeholder: "结束日期"
274
- }
275
- }
276
- ```
277
-
278
- ### 自定义组件
279
-
280
- ```typescript
281
- import { h } from "vue";
282
-
283
- // 方式一:使用 component
284
- {
285
- name: "color",
286
- label: "颜色",
287
- component: (form) => ({
288
- tag: "el-color-picker",
289
- props: { showAlpha: true }
290
- })
291
- }
292
-
293
- // 方式二:使用 componentVNode
294
- {
295
- name: "custom",
296
- label: "自定义",
297
- componentVNode: (form) => {
298
- return h("div", { class: "custom-component" }, [
299
- h("span", form.custom),
300
- h("el-button", { onClick: () => {} }, "选择")
301
- ]);
302
- }
303
- }
304
-
305
- // 方式三:自定义属性
306
- {
307
- name: "amount",
308
- label: "金额",
309
- logicType: "number",
310
- customProps: (form) => ({
311
- min: 0,
312
- max: 10000,
313
- precision: 2,
314
- step: 100
315
- })
316
- }
317
- ```
318
-
319
- ---
320
-
321
- ## 💡 完整示例
322
-
323
- ### 基础表单
324
-
325
- ```vue
326
- <template>
327
- <el-card>
328
- <BaseForm
329
- ref="formRef"
330
- :form="form"
331
- :items="formItems"
332
- :columns="2"
333
- label-width="100px"
334
- />
335
- <div class="form-footer">
336
- <el-button type="primary" @click="handleSubmit">提交</el-button>
337
- <el-button @click="handleReset">重置</el-button>
338
- </div>
339
- </el-card>
340
- </template>
341
-
342
- <script setup lang="ts">
343
- import { ref, reactive, computed } from "vue";
344
- import type { BaseFormItemDesc } from "@jhlc/common-core/.wl-skills/src/components/form/common/type";
345
-
346
- const formRef = ref();
347
-
348
- const form = reactive({
349
- orderNo: "",
350
- customerName: "",
351
- amount: 0,
352
- orderDate: "",
353
- status: "",
354
- remark: ""
355
- });
356
-
357
- const formItems = computed<BaseFormItemDesc[]>(() => [
358
- {
359
- name: "orderNo",
360
- label: "订单号",
361
- required: true,
362
- placeholder: "请输入订单号"
363
- },
364
- {
365
- name: "customerName",
366
- label: "客户名称",
367
- required: true,
368
- placeholder: "请输入客户名称"
369
- },
370
- {
371
- name: "amount",
372
- label: "订单金额",
373
- logicType: "number",
374
- required: true,
375
- customProps: () => ({
376
- min: 0,
377
- precision: 2
378
- })
379
- },
380
- {
381
- name: "orderDate",
382
- label: "订单日期",
383
- logicType: "date",
384
- required: true
385
- },
386
- {
387
- name: "status",
388
- label: "订单状态",
389
- logicType: "dict",
390
- logicValue: "ORDER_STATUS"
391
- },
392
- {
393
- name: "remark",
394
- label: "备注",
395
- logicType: "textarea",
396
- span: 24
397
- }
398
- ]);
399
-
400
- const handleSubmit = () => {
401
- formRef.value?.validate((valid) => {
402
- if (valid) {
403
- console.log("表单数据:", form);
404
- // 提交逻辑
405
- }
406
- });
407
- };
408
-
409
- const handleReset = () => {
410
- formRef.value?.resetFields();
411
- };
412
- </script>
413
- ```
414
-
415
- ### 动态表单
416
-
417
- ```vue
418
- <template>
419
- <BaseForm
420
- ref="formRef"
421
- :form="form"
422
- :items="dynamicItems"
423
- :columns="2"
424
- label-width="100px"
425
- />
426
- </template>
427
-
428
- <script setup lang="ts">
429
- import { ref, reactive, computed } from "vue";
430
-
431
- const form = reactive({
432
- type: "person",
433
- name: "",
434
- idCard: "",
435
- companyName: "",
436
- businessLicense: ""
437
- });
438
-
439
- const dynamicItems = computed(() => {
440
- const baseItems = [
441
- {
442
- name: "type",
443
- label: "类型",
444
- logicType: "dict",
445
- logicValue: "CUSTOMER_TYPE"
446
- }
447
- ];
448
-
449
- // 根据类型动态显示不同字段
450
- if (form.type === "person") {
451
- return [
452
- ...baseItems,
453
- { name: "name", label: "姓名", required: true },
454
- { name: "idCard", label: "身份证号", required: true }
455
- ];
456
- } else {
457
- return [
458
- ...baseItems,
459
- { name: "companyName", label: "公司名称", required: true },
460
- { name: "businessLicense", label: "营业执照", required: true }
461
- ];
462
- }
463
- });
464
- </script>
465
- ```
466
-
467
- ---
468
-
469
- ## ⚠️ 注意事项
470
-
471
- 1. **字段名使用 `name` 而非 `prop`**
472
-
473
- ```typescript
474
- // ✅ 正确
475
- { name: "userName", label: "用户名" }
476
-
477
- // ❌ 错误
478
- { prop: "userName", label: "用户名" }
479
- ```
480
-
481
- 2. **logicType 会自动选择组件**
482
-
483
- - 不需要手动指定 `type: "select"`
484
- - 设置 `logicType: "dict"` 即可
485
-
486
- 3. **范围类型需要设置 startName 和 endName**
487
-
488
- ```typescript
489
- {
490
- type: "range",
491
- startName: "startDate",
492
- endName: "endDate",
493
- logicType: "date"
494
- }
495
- ```
496
-
497
- 4. **使用 computed 包装 items 实现响应式**
498
-
499
- ```typescript
500
- const formItems = computed(() => [...]);
501
- ```
502
-
503
- ---
504
-
505
- ## 📚 相关文档
506
-
507
- - [BaseQuery 查询组件](../BaseQuery/README.md)
508
- - [BaseTable 表格组件](../BaseTable/README.md)
1
+ # BaseForm 表单组件
2
+
3
+ > 来源:`@jhlc/common-core` 远程组件
4
+
5
+ BaseForm 是一个功能强大的表单组件,支持多列布局、数据验证、逻辑数据类型、自定义组件等功能。适用于新增、编辑场景。
6
+
7
+ ## 📦 导入方式
8
+
9
+ ```typescript
10
+ // 全局注册(已在项目中配置)
11
+ // 直接使用 <BaseForm /> 即可
12
+
13
+ // 类型导入
14
+ import type { BaseFormItemDesc } from "@jhlc/common-core/.wl-skills/src/components/form/common/type";
15
+ ```
16
+
17
+ ## 🚀 基本用法
18
+
19
+ ```vue
20
+ <template>
21
+ <BaseForm
22
+ ref="formRef"
23
+ :form="form"
24
+ :items="formItems"
25
+ :columns="2"
26
+ label-width="100px"
27
+ />
28
+ </template>
29
+
30
+ <script setup lang="ts">
31
+ import { ref, reactive, computed } from "vue";
32
+
33
+ const formRef = ref();
34
+ const form = reactive({
35
+ userName: "",
36
+ phone: "",
37
+ userType: ""
38
+ });
39
+
40
+ const formItems = computed(() => [
41
+ {
42
+ name: "userName",
43
+ label: "用户名",
44
+ required: true,
45
+ placeholder: "请输入用户名"
46
+ },
47
+ {
48
+ name: "phone",
49
+ label: "手机号",
50
+ placeholder: "请输入手机号"
51
+ },
52
+ {
53
+ name: "userType",
54
+ label: "用户类型",
55
+ logicType: "dict",
56
+ logicValue: "USER_TYPE"
57
+ }
58
+ ]);
59
+ </script>
60
+ ```
61
+
62
+ ---
63
+
64
+ ## 📋 Props 属性
65
+
66
+ | 属性名 | 类型 | 默认值 | 说明 |
67
+ | ------------ | ------------------------------ | --------- | ---------------- |
68
+ | `form` | `Object` | - | 表单数据对象 |
69
+ | `items` | `BaseFormItemDesc[]` | `[]` | 表单项配置数组 |
70
+ | `columns` | `number` | - | 列数 |
71
+ | `labelWidth` | `string` | - | 标签宽度 |
72
+ | `size` | `'default' \| 'large' \| 'small'` | - | 表单尺寸 |
73
+ | `disabled` | `boolean` | `false` | 是否禁用 |
74
+ | `isViewer` | `boolean` | `false` | 是否查看模式 |
75
+ | `noForm` | `boolean` | `false` | 不使用 form 包裹 |
76
+ | `style` | `string \| Object` | - | 自定义样式 |
77
+ | `classnames` | `Array \| string` | - | 自定义类名 |
78
+
79
+ ---
80
+
81
+ ## 📋 Expose 方法 (通过 ref 调用)
82
+
83
+ | 方法名 | 参数 | 返回值 | 说明 |
84
+ | ----------------- | --------------------------- | ------ | -------------- |
85
+ | `validate` | `cb: (valid: boolean) => void` | - | 验证表单 |
86
+ | `setDefaultValue` | - | - | 设置默认值 |
87
+ | `reset` | - | - | 重置表单 |
88
+ | `resetFields` | - | - | 重置表单字段 |
89
+
90
+ ---
91
+
92
+ ## 📋 表单项配置 BaseFormItemDesc
93
+
94
+ ### 基础属性
95
+
96
+ ```typescript
97
+ interface BaseFormItemDesc<T = any> {
98
+ // 字段名(绑定 form 对象的属性名)
99
+ name?: string;
100
+ // 标签文本
101
+ label?: string;
102
+ // 标签宽度
103
+ labelWidth?: string;
104
+ // 显示冒号
105
+ showColon?: boolean;
106
+ // 占位提示
107
+ placeholder?: string;
108
+ // 栅格数(24 格布局)
109
+ span?: number;
110
+ // 是否禁用
111
+ disabled?: boolean | ((form: T) => boolean);
112
+ // 是否可清空
113
+ clearable?: boolean;
114
+ // 是否显示
115
+ show?: boolean | ((form: T) => boolean);
116
+ }
117
+ ```
118
+
119
+ ### 校验规则
120
+
121
+ ```typescript
122
+ {
123
+ name: "userName",
124
+ label: "用户名",
125
+ // 必填
126
+ required: true,
127
+ // 或使用函数动态判断
128
+ required: (form) => form.userType === "admin",
129
+ // 校验提示
130
+ message: "请输入用户名",
131
+ // 自定义校验规则
132
+ rules: [
133
+ { required: true, message: "请输入用户名", trigger: "blur" },
134
+ { min: 2, max: 20, message: "长度在 2 到 20 个字符", trigger: "blur" },
135
+ {
136
+ pattern: /^[a-zA-Z0-9_]+$/,
137
+ message: "只能包含字母、数字和下划线",
138
+ trigger: "blur"
139
+ },
140
+ {
141
+ validator: (rule, value, callback) => {
142
+ if (value === "admin") {
143
+ callback(new Error("不能使用 admin 作为用户名"));
144
+ } else {
145
+ callback();
146
+ }
147
+ },
148
+ trigger: "blur"
149
+ }
150
+ ]
151
+ }
152
+ ```
153
+
154
+ ### 逻辑数据类型
155
+
156
+ 组件会根据 `logicType` 自动选择合适的表单控件:
157
+
158
+ ```typescript
159
+ {
160
+ name: "status",
161
+ label: "状态",
162
+ // 字典类型 - 自动渲染为下拉选择
163
+ logicType: "dict",
164
+ logicValue: "ORDER_STATUS"
165
+ }
166
+
167
+ {
168
+ name: "createTime",
169
+ label: "创建时间",
170
+ // 日期类型 - 自动渲染为日期选择器
171
+ logicType: "date"
172
+ }
173
+
174
+ {
175
+ name: "createDatetime",
176
+ label: "创建时间",
177
+ // 日期时间类型
178
+ logicType: "datetime"
179
+ }
180
+
181
+ {
182
+ name: "amount",
183
+ label: "金额",
184
+ // 数字类型 - 自动渲染为数字输入框
185
+ logicType: "number"
186
+ }
187
+
188
+ {
189
+ name: "isActive",
190
+ label: "是否启用",
191
+ // 布尔类型 - 自动渲染为开关
192
+ logicType: "boolean"
193
+ }
194
+
195
+ {
196
+ name: "userId",
197
+ label: "负责人",
198
+ // 用户类型 - 自动渲染为用户选择器
199
+ logicType: "user"
200
+ }
201
+
202
+ {
203
+ name: "deptId",
204
+ label: "部门",
205
+ // 部门类型 - 自动渲染为部门选择器
206
+ logicType: "dept"
207
+ }
208
+
209
+ {
210
+ name: "remark",
211
+ label: "备注",
212
+ // 多行文本
213
+ logicType: "textarea"
214
+ }
215
+ ```
216
+
217
+ ### 默认值配置
218
+
219
+ ```typescript
220
+ {
221
+ name: "createTime",
222
+ label: "创建时间",
223
+ logicType: "date",
224
+ // 支持多种默认值类型
225
+ defaultValue: "currentDay" // 当天
226
+ // defaultValue: "currentMonth" // 当月
227
+ // defaultValue: "currentYear" // 当年
228
+ }
229
+
230
+ // 日期范围默认值
231
+ {
232
+ type: "range",
233
+ name: "dateRange",
234
+ startName: "startDate",
235
+ endName: "endDate",
236
+ logicType: "date",
237
+ defaultValue: "recentDay7" // 最近 7 天
238
+ // defaultValue: "recentDay30" // 最近 30 天
239
+ // defaultValue: "rangeDayCurrentMonth1ToToday" // 当月1号到今天
240
+ }
241
+ ```
242
+
243
+ **支持的默认值类型:**
244
+
245
+ | 值 | 说明 |
246
+ | ------------------------------- | ----------------------- |
247
+ | `currentDay` | 当天 (2024-09-22) |
248
+ | `currentMonth` | 当月 (2024-09) |
249
+ | `currentYear` | 当年 (2024) |
250
+ | `currentDept` | 当前部门 |
251
+ | `recentDay3` | 最近 3 天 |
252
+ | `recentDay7` | 最近 7 天 |
253
+ | `recentDay30` | 最近 30 天 |
254
+ | `rangeDatetimeToday` | 当天 0 点到 23 点 |
255
+ | `rangeDayCurrentMonth1ToToday` | 当月 1 号到今天 |
256
+ | `rangeDayCurrentMonth1ToLastDay`| 当月 1 号到月末 |
257
+
258
+ ### 范围输入
259
+
260
+ ```typescript
261
+ {
262
+ type: "range",
263
+ label: "日期范围",
264
+ startName: "startDate",
265
+ endName: "endDate",
266
+ logicType: "date",
267
+ rangeSeparator: "至",
268
+ // 自定义起止表单项
269
+ startFormItem: {
270
+ placeholder: "开始日期"
271
+ },
272
+ endFormItem: {
273
+ placeholder: "结束日期"
274
+ }
275
+ }
276
+ ```
277
+
278
+ ### 自定义组件
279
+
280
+ ```typescript
281
+ import { h } from "vue";
282
+
283
+ // 方式一:使用 component
284
+ {
285
+ name: "color",
286
+ label: "颜色",
287
+ component: (form) => ({
288
+ tag: "el-color-picker",
289
+ props: { showAlpha: true }
290
+ })
291
+ }
292
+
293
+ // 方式二:使用 componentVNode
294
+ {
295
+ name: "custom",
296
+ label: "自定义",
297
+ componentVNode: (form) => {
298
+ return h("div", { class: "custom-component" }, [
299
+ h("span", form.custom),
300
+ h("el-button", { onClick: () => {} }, "选择")
301
+ ]);
302
+ }
303
+ }
304
+
305
+ // 方式三:自定义属性
306
+ {
307
+ name: "amount",
308
+ label: "金额",
309
+ logicType: "number",
310
+ customProps: (form) => ({
311
+ min: 0,
312
+ max: 10000,
313
+ precision: 2,
314
+ step: 100
315
+ })
316
+ }
317
+ ```
318
+
319
+ ---
320
+
321
+ ## 💡 完整示例
322
+
323
+ ### 基础表单
324
+
325
+ ```vue
326
+ <template>
327
+ <el-card>
328
+ <BaseForm
329
+ ref="formRef"
330
+ :form="form"
331
+ :items="formItems"
332
+ :columns="2"
333
+ label-width="100px"
334
+ />
335
+ <div class="form-footer">
336
+ <el-button type="primary" @click="handleSubmit">提交</el-button>
337
+ <el-button @click="handleReset">重置</el-button>
338
+ </div>
339
+ </el-card>
340
+ </template>
341
+
342
+ <script setup lang="ts">
343
+ import { ref, reactive, computed } from "vue";
344
+ import type { BaseFormItemDesc } from "@jhlc/common-core/.wl-skills/src/components/form/common/type";
345
+
346
+ const formRef = ref();
347
+
348
+ const form = reactive({
349
+ orderNo: "",
350
+ customerName: "",
351
+ amount: 0,
352
+ orderDate: "",
353
+ status: "",
354
+ remark: ""
355
+ });
356
+
357
+ const formItems = computed<BaseFormItemDesc[]>(() => [
358
+ {
359
+ name: "orderNo",
360
+ label: "订单号",
361
+ required: true,
362
+ placeholder: "请输入订单号"
363
+ },
364
+ {
365
+ name: "customerName",
366
+ label: "客户名称",
367
+ required: true,
368
+ placeholder: "请输入客户名称"
369
+ },
370
+ {
371
+ name: "amount",
372
+ label: "订单金额",
373
+ logicType: "number",
374
+ required: true,
375
+ customProps: () => ({
376
+ min: 0,
377
+ precision: 2
378
+ })
379
+ },
380
+ {
381
+ name: "orderDate",
382
+ label: "订单日期",
383
+ logicType: "date",
384
+ required: true
385
+ },
386
+ {
387
+ name: "status",
388
+ label: "订单状态",
389
+ logicType: "dict",
390
+ logicValue: "ORDER_STATUS"
391
+ },
392
+ {
393
+ name: "remark",
394
+ label: "备注",
395
+ logicType: "textarea",
396
+ span: 24
397
+ }
398
+ ]);
399
+
400
+ const handleSubmit = () => {
401
+ formRef.value?.validate((valid) => {
402
+ if (valid) {
403
+ console.log("表单数据:", form);
404
+ // 提交逻辑
405
+ }
406
+ });
407
+ };
408
+
409
+ const handleReset = () => {
410
+ formRef.value?.resetFields();
411
+ };
412
+ </script>
413
+ ```
414
+
415
+ ### 动态表单
416
+
417
+ ```vue
418
+ <template>
419
+ <BaseForm
420
+ ref="formRef"
421
+ :form="form"
422
+ :items="dynamicItems"
423
+ :columns="2"
424
+ label-width="100px"
425
+ />
426
+ </template>
427
+
428
+ <script setup lang="ts">
429
+ import { ref, reactive, computed } from "vue";
430
+
431
+ const form = reactive({
432
+ type: "person",
433
+ name: "",
434
+ idCard: "",
435
+ companyName: "",
436
+ businessLicense: ""
437
+ });
438
+
439
+ const dynamicItems = computed(() => {
440
+ const baseItems = [
441
+ {
442
+ name: "type",
443
+ label: "类型",
444
+ logicType: "dict",
445
+ logicValue: "CUSTOMER_TYPE"
446
+ }
447
+ ];
448
+
449
+ // 根据类型动态显示不同字段
450
+ if (form.type === "person") {
451
+ return [
452
+ ...baseItems,
453
+ { name: "name", label: "姓名", required: true },
454
+ { name: "idCard", label: "身份证号", required: true }
455
+ ];
456
+ } else {
457
+ return [
458
+ ...baseItems,
459
+ { name: "companyName", label: "公司名称", required: true },
460
+ { name: "businessLicense", label: "营业执照", required: true }
461
+ ];
462
+ }
463
+ });
464
+ </script>
465
+ ```
466
+
467
+ ---
468
+
469
+ ## ⚠️ 注意事项
470
+
471
+ 1. **字段名使用 `name` 而非 `prop`**
472
+
473
+ ```typescript
474
+ // ✅ 正确
475
+ { name: "userName", label: "用户名" }
476
+
477
+ // ❌ 错误
478
+ { prop: "userName", label: "用户名" }
479
+ ```
480
+
481
+ 2. **logicType 会自动选择组件**
482
+
483
+ - 不需要手动指定 `type: "select"`
484
+ - 设置 `logicType: "dict"` 即可
485
+
486
+ 3. **范围类型需要设置 startName 和 endName**
487
+
488
+ ```typescript
489
+ {
490
+ type: "range",
491
+ startName: "startDate",
492
+ endName: "endDate",
493
+ logicType: "date"
494
+ }
495
+ ```
496
+
497
+ 4. **使用 computed 包装 items 实现响应式**
498
+
499
+ ```typescript
500
+ const formItems = computed(() => [...]);
501
+ ```
502
+
503
+ ---
504
+
505
+ ## 📚 相关文档
506
+
507
+ - [BaseQuery 查询组件](../BaseQuery/README.md)
508
+ - [BaseTable 表格组件](../BaseTable/README.md)