@ebiz/designer-components 0.0.37 → 0.0.39
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.
- package/dist/designer-components.css +1 -1
- package/dist/index.mjs +5022 -4936
- package/package.json +1 -1
- package/src/components/senior/EbizSData/index.vue +16 -1
- package/src/components/senior/EbizSDialog/index.vue +29 -220
- package/src/components/senior/EbizSForm/README.md +158 -0
- package/src/components/senior/EbizSForm/index.vue +326 -41
- package/src/index.js +2 -2
- package/src/router/index.js +2 -2
- package/src/views/EbizSForm/index.vue +360 -0
- package/src/views/EbizSFormDemo.vue +100 -6
package/package.json
CHANGED
@@ -79,7 +79,22 @@ const refreshing = ref(false)
|
|
79
79
|
const total = ref(0)
|
80
80
|
const pageSizeOptions = ref([10, 20, 50, 100])
|
81
81
|
|
82
|
-
const data = ref([
|
82
|
+
const data = ref([
|
83
|
+
{
|
84
|
+
id: 1,
|
85
|
+
name: '张三',
|
86
|
+
age: 18,
|
87
|
+
gender: '男',
|
88
|
+
address: '北京市海淀区'
|
89
|
+
},
|
90
|
+
{
|
91
|
+
id: 2,
|
92
|
+
name: '李四',
|
93
|
+
age: 20,
|
94
|
+
gender: '女',
|
95
|
+
address: '北京市朝阳区'
|
96
|
+
}
|
97
|
+
]);
|
83
98
|
|
84
99
|
const props = defineProps({
|
85
100
|
showPageHeader: {
|
@@ -334,93 +334,25 @@ const callApi = async (config = props.apiConfig) => {
|
|
334
334
|
try {
|
335
335
|
apiLoading.value = true
|
336
336
|
|
337
|
-
//
|
338
|
-
const
|
337
|
+
// 准备请求参数
|
338
|
+
const fetchParams = { ...localFormData.value }
|
339
339
|
|
340
|
-
//
|
341
|
-
if (
|
342
|
-
|
343
|
-
if (!apiConfig.data) {
|
344
|
-
apiConfig.data = { ...localFormData.value }
|
345
|
-
}
|
346
|
-
// 如果有data字段且是对象,合并表单数据
|
347
|
-
else if (typeof apiConfig.data === 'object' && apiConfig.data !== null) {
|
348
|
-
// 深拷贝表单数据,避免引用问题
|
349
|
-
const formDataCopy = {}
|
350
|
-
Object.keys(localFormData.value).forEach(key => {
|
351
|
-
// 处理表单中的引用类型数据
|
352
|
-
if (typeof localFormData.value[key] === 'object' && localFormData.value[key] !== null) {
|
353
|
-
formDataCopy[key] = Array.isArray(localFormData.value[key])
|
354
|
-
? [...localFormData.value[key]]
|
355
|
-
: { ...localFormData.value[key] }
|
356
|
-
} else {
|
357
|
-
formDataCopy[key] = localFormData.value[key]
|
358
|
-
}
|
359
|
-
})
|
360
|
-
|
361
|
-
apiConfig.data = { ...apiConfig.data, ...formDataCopy }
|
362
|
-
}
|
363
|
-
}
|
364
|
-
|
365
|
-
// 添加默认的content-type头
|
366
|
-
if (!apiConfig.headers) {
|
367
|
-
apiConfig.headers = {}
|
368
|
-
}
|
369
|
-
|
370
|
-
if (!apiConfig.headers['Content-Type']) {
|
371
|
-
apiConfig.headers['Content-Type'] = 'application/json'
|
372
|
-
}
|
373
|
-
|
374
|
-
// 设置默认的请求方法
|
375
|
-
if (!apiConfig.method) {
|
376
|
-
// 根据弹窗类型设置默认方法
|
377
|
-
switch (props.dialogType) {
|
378
|
-
case 'add':
|
379
|
-
apiConfig.method = 'post'
|
380
|
-
break
|
381
|
-
case 'edit':
|
382
|
-
apiConfig.method = 'put'
|
383
|
-
break
|
384
|
-
case 'delete':
|
385
|
-
apiConfig.method = 'delete'
|
386
|
-
break
|
387
|
-
default:
|
388
|
-
apiConfig.method = 'post'
|
389
|
-
}
|
390
|
-
}
|
391
|
-
|
392
|
-
// 如果是URL形式的API配置
|
393
|
-
if (typeof apiConfig === 'string') {
|
394
|
-
apiConfig = { url: apiConfig, method: 'post' }
|
395
|
-
}
|
396
|
-
|
397
|
-
// 添加自定义请求拦截器
|
398
|
-
let requestTransformer = null
|
399
|
-
if (apiConfig.transformRequest) {
|
400
|
-
requestTransformer = apiConfig.transformRequest
|
401
|
-
delete apiConfig.transformRequest
|
340
|
+
// 如果有ID,添加到请求参数中
|
341
|
+
if (currentId.value) {
|
342
|
+
fetchParams.id = currentId.value
|
402
343
|
}
|
403
344
|
|
404
|
-
//
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
// 处理请求数据
|
412
|
-
if (requestTransformer && typeof requestTransformer === 'function') {
|
413
|
-
apiConfig.data = requestTransformer(apiConfig.data)
|
345
|
+
// 合并当前参数到请求参数
|
346
|
+
if (currentParams.value && Object.keys(currentParams.value).length > 0) {
|
347
|
+
Object.keys(currentParams.value).forEach(key => {
|
348
|
+
if (key !== 'formData') { // 避免重复添加表单数据
|
349
|
+
fetchParams[key] = currentParams.value[key]
|
350
|
+
}
|
351
|
+
})
|
414
352
|
}
|
415
353
|
|
416
|
-
// 调用dataService进行API
|
417
|
-
const response = await dataService.fetch(
|
418
|
-
|
419
|
-
// 处理响应数据
|
420
|
-
let transformedResponse = response
|
421
|
-
if (responseTransformer && typeof responseTransformer === 'function') {
|
422
|
-
transformedResponse = responseTransformer(response)
|
423
|
-
}
|
354
|
+
// 调用dataService进行API请求,直接使用config
|
355
|
+
const response = await dataService.fetch(fetchParams, config)
|
424
356
|
|
425
357
|
// 显示成功消息
|
426
358
|
if (props.showResultMessage) {
|
@@ -435,14 +367,14 @@ const callApi = async (config = props.apiConfig) => {
|
|
435
367
|
}
|
436
368
|
|
437
369
|
// 触发成功事件
|
438
|
-
emit('api-success',
|
370
|
+
emit('api-success', response)
|
439
371
|
|
440
372
|
// 如果设置了成功后关闭,则关闭弹窗
|
441
373
|
if (props.closeOnSuccess) {
|
442
374
|
dialogVisible.value = false
|
443
375
|
}
|
444
376
|
|
445
|
-
return
|
377
|
+
return response
|
446
378
|
} catch (error) {
|
447
379
|
// 错误处理和错误消息展示
|
448
380
|
const errorMessage = getErrorMessage(error, props.dialogType)
|
@@ -481,62 +413,8 @@ const handleDialogConfirm = async (e) => {
|
|
481
413
|
|
482
414
|
// 校验成功,执行提交操作
|
483
415
|
if (validateResult === true) {
|
484
|
-
//
|
485
|
-
|
486
|
-
|
487
|
-
// 对于编辑模式,确保请求中包含ID
|
488
|
-
if (props.dialogType === 'edit' && currentId.value) {
|
489
|
-
// 替换URL中的ID参数,支持{id}和:id两种格式
|
490
|
-
if (apiConfig.url) {
|
491
|
-
apiConfig.url = apiConfig.url.replace(/\{id\}/g, currentId.value).replace(/:id/g, currentId.value)
|
492
|
-
}
|
493
|
-
|
494
|
-
// 准备请求参数
|
495
|
-
if (!apiConfig.params) {
|
496
|
-
apiConfig.params = {}
|
497
|
-
}
|
498
|
-
|
499
|
-
// 如果有params参数且没有id,添加id
|
500
|
-
if (!apiConfig.params.id && currentId.value) {
|
501
|
-
apiConfig.params.id = currentId.value
|
502
|
-
}
|
503
|
-
|
504
|
-
// 准备请求数据
|
505
|
-
if (!apiConfig.data) {
|
506
|
-
apiConfig.data = {}
|
507
|
-
}
|
508
|
-
|
509
|
-
// 确保请求体中有ID
|
510
|
-
if (!apiConfig.data.id && currentId.value) {
|
511
|
-
apiConfig.data.id = currentId.value
|
512
|
-
}
|
513
|
-
|
514
|
-
// 合并当前参数中的非表单数据
|
515
|
-
if (currentParams.value && Object.keys(currentParams.value).length > 0) {
|
516
|
-
// 过滤掉id和formData,避免重复
|
517
|
-
const { id: _id, formData: _formData, ...otherParams } = currentParams.value
|
518
|
-
apiConfig.params = { ...apiConfig.params, ...otherParams }
|
519
|
-
}
|
520
|
-
|
521
|
-
await callApi(apiConfig)
|
522
|
-
} else {
|
523
|
-
// 克隆API配置,确保添加操作有正确的data字段
|
524
|
-
const addApiConfig = { ...props.apiConfig }
|
525
|
-
|
526
|
-
// 合并当前参数中的非表单数据
|
527
|
-
if (currentParams.value && Object.keys(currentParams.value).length > 0) {
|
528
|
-
// 过滤掉id和formData,避免重复
|
529
|
-
const { id: _id, formData: _formData, ...otherParams } = currentParams.value
|
530
|
-
|
531
|
-
if (!addApiConfig.params) {
|
532
|
-
addApiConfig.params = {}
|
533
|
-
}
|
534
|
-
|
535
|
-
addApiConfig.params = { ...addApiConfig.params, ...otherParams }
|
536
|
-
}
|
537
|
-
|
538
|
-
await callApi(addApiConfig)
|
539
|
-
}
|
416
|
+
// 直接调用callApi传入props.apiConfig
|
417
|
+
await callApi(props.apiConfig)
|
540
418
|
} else {
|
541
419
|
// 校验失败,显示第一个错误信息
|
542
420
|
const firstError = validateResult[Object.keys(validateResult)[0]]?.[0]?.message || '表单校验失败'
|
@@ -557,51 +435,8 @@ const handleDialogConfirm = async (e) => {
|
|
557
435
|
// 显示加载状态
|
558
436
|
apiLoading.value = true
|
559
437
|
|
560
|
-
// 克隆API配置,避免修改原始配置
|
561
|
-
const deleteApiConfig = { ...props.apiConfig }
|
562
|
-
|
563
|
-
// 对于删除操作,确保包含ID
|
564
|
-
if (currentId.value) {
|
565
|
-
// 替换URL中的ID参数
|
566
|
-
if (deleteApiConfig.url) {
|
567
|
-
deleteApiConfig.url = deleteApiConfig.url.replace(/\{id\}/g, currentId.value).replace(/:id/g, currentId.value)
|
568
|
-
}
|
569
|
-
|
570
|
-
// 准备请求参数
|
571
|
-
if (!deleteApiConfig.params) {
|
572
|
-
deleteApiConfig.params = {}
|
573
|
-
}
|
574
|
-
|
575
|
-
// 如果有params参数且没有id,添加id
|
576
|
-
if (!deleteApiConfig.params.id && currentId.value) {
|
577
|
-
deleteApiConfig.params.id = currentId.value
|
578
|
-
}
|
579
|
-
|
580
|
-
// 准备请求数据
|
581
|
-
if (!deleteApiConfig.data) {
|
582
|
-
deleteApiConfig.data = {}
|
583
|
-
}
|
584
|
-
|
585
|
-
// 确保请求体中有ID
|
586
|
-
if (!deleteApiConfig.data.id && currentId.value) {
|
587
|
-
deleteApiConfig.data.id = currentId.value
|
588
|
-
}
|
589
|
-
}
|
590
|
-
|
591
|
-
// 合并当前参数
|
592
|
-
if (currentParams.value && Object.keys(currentParams.value).length > 0) {
|
593
|
-
// 过滤掉id和formData,避免重复
|
594
|
-
const { id: _id, formData: _formData, ...otherParams } = currentParams.value
|
595
|
-
|
596
|
-
if (!deleteApiConfig.params) {
|
597
|
-
deleteApiConfig.params = {}
|
598
|
-
}
|
599
|
-
|
600
|
-
deleteApiConfig.params = { ...deleteApiConfig.params, ...otherParams }
|
601
|
-
}
|
602
|
-
|
603
438
|
// 删除操作直接调用API
|
604
|
-
await callApi(
|
439
|
+
await callApi(props.apiConfig)
|
605
440
|
} catch (error) {
|
606
441
|
// API调用过程中的错误
|
607
442
|
MessagePlugin.error(`删除失败: ${error.message || '未知错误'}`)
|
@@ -621,19 +456,8 @@ const handleDialogConfirm = async (e) => {
|
|
621
456
|
// 显示加载状态
|
622
457
|
apiLoading.value = true
|
623
458
|
|
624
|
-
//
|
625
|
-
|
626
|
-
|
627
|
-
// 合并当前参数
|
628
|
-
if (currentParams.value && Object.keys(currentParams.value).length > 0) {
|
629
|
-
if (!normalApiConfig.params) {
|
630
|
-
normalApiConfig.params = {}
|
631
|
-
}
|
632
|
-
|
633
|
-
normalApiConfig.params = { ...normalApiConfig.params, ...currentParams.value }
|
634
|
-
}
|
635
|
-
|
636
|
-
await callApi(normalApiConfig)
|
459
|
+
// 直接调用API,不修改apiConfig
|
460
|
+
await callApi(props.apiConfig)
|
637
461
|
} catch (error) {
|
638
462
|
// API调用过程中的错误
|
639
463
|
MessagePlugin.error(`操作失败: ${error.message || '未知错误'}`)
|
@@ -682,35 +506,20 @@ const loadDetailData = async (id) => {
|
|
682
506
|
// 显示加载状态
|
683
507
|
apiLoading.value = true
|
684
508
|
|
685
|
-
//
|
686
|
-
const
|
687
|
-
...props.detailApiConfig
|
688
|
-
}
|
689
|
-
|
690
|
-
// 替换URL中的ID参数,支持{id}和:id两种格式
|
691
|
-
if (requestConfig.url) {
|
692
|
-
requestConfig.url = requestConfig.url.replace(/\{id\}/g, id).replace(/:id/g, id)
|
693
|
-
}
|
694
|
-
|
695
|
-
// 处理请求参数
|
696
|
-
if (!requestConfig.params) {
|
697
|
-
requestConfig.params = {}
|
698
|
-
}
|
509
|
+
// 准备请求参数
|
510
|
+
const fetchParams = { id }
|
699
511
|
|
700
|
-
//
|
701
|
-
if (!requestConfig.params.id && id) {
|
702
|
-
requestConfig.params.id = id
|
703
|
-
}
|
704
|
-
|
705
|
-
// 合并当前参数
|
512
|
+
// 合并当前参数到请求参数
|
706
513
|
if (currentParams.value && Object.keys(currentParams.value).length > 0) {
|
707
514
|
// 过滤掉id和formData,避免重复
|
708
515
|
const { id: _id, formData: _formData, ...otherParams } = currentParams.value
|
709
|
-
|
516
|
+
Object.keys(otherParams).forEach(key => {
|
517
|
+
fetchParams[key] = otherParams[key]
|
518
|
+
})
|
710
519
|
}
|
711
520
|
|
712
|
-
// 调用dataService进行API
|
713
|
-
const response = await dataService.fetch(
|
521
|
+
// 调用dataService进行API请求,直接使用detailApiConfig
|
522
|
+
const response = await dataService.fetch(fetchParams, props.detailApiConfig)
|
714
523
|
|
715
524
|
// 获取详情数据
|
716
525
|
const detailData = response.data || response
|
@@ -0,0 +1,158 @@
|
|
1
|
+
# EbizSForm 高级表单组件
|
2
|
+
|
3
|
+
EbizSForm是一个基于TDesign Form封装的高级表单组件,提供了丰富的表单功能,包括本地表单数据管理、表单验证、API提交和详情数据加载等。
|
4
|
+
|
5
|
+
## 主要特性
|
6
|
+
|
7
|
+
1. **本地表单数据管理**:通过`localFormData`管理表单数据,实现数据的双向绑定
|
8
|
+
2. **详情接口支持**:通过`detailApiConfig`配置详情API,支持加载表单详情数据
|
9
|
+
3. **API调用机制**:使用`dataService.fetch(params, apiConfig)`方式调用API,符合系统规范
|
10
|
+
4. **表单验证**:支持完整的表单验证功能,并与API调用无缝衔接
|
11
|
+
5. **丰富的方法支持**:提供`openForm`、`loadDetailData`、`setFormData`等丰富的方法
|
12
|
+
|
13
|
+
## 基本用法
|
14
|
+
|
15
|
+
```vue
|
16
|
+
<template>
|
17
|
+
<EbizSForm
|
18
|
+
ref="formRef"
|
19
|
+
:data="formData"
|
20
|
+
:rules="formRules"
|
21
|
+
:api-config="apiConfig"
|
22
|
+
:detail-api-config="detailApiConfig"
|
23
|
+
@success="handleSuccess"
|
24
|
+
@error="handleError"
|
25
|
+
@detail-loaded="handleDetailLoaded"
|
26
|
+
>
|
27
|
+
<EbizSFormItem label="用户名" name="username" type="input" />
|
28
|
+
<EbizSFormItem label="密码" name="password" type="input" />
|
29
|
+
</EbizSForm>
|
30
|
+
</template>
|
31
|
+
|
32
|
+
<script setup>
|
33
|
+
import { ref, reactive } from 'vue';
|
34
|
+
import { EbizSForm, EbizSFormItem } from '@ebiz/designer-components';
|
35
|
+
|
36
|
+
const formRef = ref(null);
|
37
|
+
const formData = reactive({
|
38
|
+
username: '',
|
39
|
+
password: ''
|
40
|
+
});
|
41
|
+
|
42
|
+
const formRules = {
|
43
|
+
username: [
|
44
|
+
{ required: true, message: '请输入用户名', trigger: 'blur' }
|
45
|
+
],
|
46
|
+
password: [
|
47
|
+
{ required: true, message: '请输入密码', trigger: 'blur' }
|
48
|
+
]
|
49
|
+
};
|
50
|
+
|
51
|
+
// API配置
|
52
|
+
const apiConfig = {
|
53
|
+
key: 'userSubmit',
|
54
|
+
apiId: 'user.submit',
|
55
|
+
apiType: '3'
|
56
|
+
};
|
57
|
+
|
58
|
+
// 详情API配置
|
59
|
+
const detailApiConfig = {
|
60
|
+
key: 'userDetail',
|
61
|
+
apiId: 'user.detail',
|
62
|
+
apiType: '1'
|
63
|
+
};
|
64
|
+
|
65
|
+
// 加载详情数据
|
66
|
+
const loadDetail = (id) => {
|
67
|
+
formRef.value.loadDetailData(id);
|
68
|
+
};
|
69
|
+
|
70
|
+
// 事件处理
|
71
|
+
const handleSuccess = (response) => {
|
72
|
+
console.log('提交成功:', response);
|
73
|
+
};
|
74
|
+
|
75
|
+
const handleError = (error) => {
|
76
|
+
console.error('提交失败:', error);
|
77
|
+
};
|
78
|
+
|
79
|
+
const handleDetailLoaded = (data) => {
|
80
|
+
console.log('详情数据加载成功:', data);
|
81
|
+
};
|
82
|
+
</script>
|
83
|
+
```
|
84
|
+
|
85
|
+
## Props
|
86
|
+
|
87
|
+
| 属性名 | 类型 | 默认值 | 说明 |
|
88
|
+
| ----------------- | --------- | --------- | ----------------------------------- |
|
89
|
+
| data | Object | {} | 表单数据对象 |
|
90
|
+
| labelAlign | String | 'right' | 标签对齐方式:'left'/'right'/'top' |
|
91
|
+
| layout | String | 'vertical'| 表单布局方式:'vertical'/'inline' |
|
92
|
+
| labelWidth | String | '100px' | 标签宽度 |
|
93
|
+
| rules | Object | {} | 表单验证规则 |
|
94
|
+
| apiConfig | Object | null | API配置,用于表单提交 |
|
95
|
+
| detailApiConfig | Object | null | 详情API配置,用于加载表单数据 |
|
96
|
+
| resetOnSuccess | Boolean | false | 提交成功后是否重置表单 |
|
97
|
+
| showResultMessage | Boolean | true | 是否显示结果消息 |
|
98
|
+
|
99
|
+
## 事件
|
100
|
+
|
101
|
+
| 事件名 | 说明 | 参数 |
|
102
|
+
| ------------ | ----------------------- | ------------------------------ |
|
103
|
+
| submit | 表单提交时触发 | formData: 表单数据对象 |
|
104
|
+
| success | API调用成功时触发 | response: 成功响应数据 |
|
105
|
+
| error | API调用失败时触发 | error: 错误信息 |
|
106
|
+
| reset | 表单重置时触发 | context: 重置上下文 |
|
107
|
+
| validate | 表单验证时触发 | result: 验证结果 |
|
108
|
+
| detail-loaded| 详情数据加载成功时触发 | data: 详情数据 |
|
109
|
+
| detail-error | 详情数据加载失败时触发 | error: 错误信息 |
|
110
|
+
|
111
|
+
## 方法
|
112
|
+
|
113
|
+
通过ref可以调用组件实例的以下方法:
|
114
|
+
|
115
|
+
| 方法名 | 说明 | 参数 |
|
116
|
+
| -------------- | ------------------------ | ------------------------------ |
|
117
|
+
| submit | 提交表单 | 无 |
|
118
|
+
| reset | 重置表单 | 无 |
|
119
|
+
| validate | 验证表单 | 无 |
|
120
|
+
| validateFields | 验证指定字段 | fields: 字段名或字段名数组 |
|
121
|
+
| clearValidate | 清除验证结果 | fields: 字段名或字段名数组,可选 |
|
122
|
+
| openForm | 打开表单并设置参数 | params: 参数对象 |
|
123
|
+
| loadDetailData | 加载详情数据 | id: 记录ID |
|
124
|
+
| setFormData | 设置表单数据 | data: 要设置的数据对象 |
|
125
|
+
| getFormData | 获取表单数据 | 无 |
|
126
|
+
| clearFormData | 清空表单数据 | 无 |
|
127
|
+
|
128
|
+
## API配置对象说明
|
129
|
+
|
130
|
+
apiConfig和detailApiConfig的格式如下:
|
131
|
+
|
132
|
+
```javascript
|
133
|
+
{
|
134
|
+
key: 'apiKey', // API的键名
|
135
|
+
apiId: 'module.api', // API的标识ID
|
136
|
+
apiType: '3' // API类型,对应dataService中的类型
|
137
|
+
}
|
138
|
+
```
|
139
|
+
|
140
|
+
apiType常用值:
|
141
|
+
- '0': 列表查询
|
142
|
+
- '1': 详情查询
|
143
|
+
- '3': 数据新增
|
144
|
+
- '5': 数据修改
|
145
|
+
- '7': 数据删除
|
146
|
+
|
147
|
+
## 与EbizSDialog组件的比较
|
148
|
+
|
149
|
+
EbizSForm与EbizSDialog组件有相似的API调用和表单数据处理机制,两者都:
|
150
|
+
|
151
|
+
1. 使用本地表单数据管理(localFormData)
|
152
|
+
2. 支持详情数据加载(detailApiConfig)
|
153
|
+
3. 采用相同的API调用方式(dataService.fetch)
|
154
|
+
4. 不修改apiConfig对象
|
155
|
+
|
156
|
+
选择使用哪个组件取决于具体的场景需求:
|
157
|
+
- 如果需要在页面上直接显示表单,使用EbizSForm
|
158
|
+
- 如果需要在弹窗中显示表单,使用EbizSDialog
|