af-mobile-client-vue3 1.2.23 → 1.2.25
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/package.json +1 -1
- package/src/components/core/ImageUploader/index.vue +159 -159
- package/src/components/data/XForm/index.vue +1 -3
- package/src/components/data/XFormGroup/index.vue +172 -133
- package/src/components/data/XFormItem/index.vue +1 -1
- package/src/components/data/XOlMap/utils/wgs84ToGcj02.js +154 -154
- package/src/components/data/XReportGrid/XReportDemo.vue +33 -33
- package/src/components/data/XReportGrid/print.js +184 -184
- package/src/stores/modules/user.ts +2 -2
- package/src/views/component/XCellListView/index.vue +126 -13
- package/src/views/component/XFormGroupView/index.vue +50 -3
- package/src/views/component/XFormView/index.vue +57 -28
- package/src/views/component/XOlMapView/XLocationPicker/index.vue +118 -118
- package/src/views/user/login/LoginForm.vue +2 -14
- package/vite.config.ts +2 -2
- package/src/views/component/XFormView/oldindex.vue +0 -70
package/package.json
CHANGED
|
@@ -1,159 +1,159 @@
|
|
|
1
|
-
<script setup lang="ts">
|
|
2
|
-
import { deleteFile } from '@af-mobile-client-vue3/services/api/common'
|
|
3
|
-
import { mobileUtil } from '@af-mobile-client-vue3/utils/mobileUtil'
|
|
4
|
-
import {
|
|
5
|
-
Button as vanButton,
|
|
6
|
-
Uploader as vanUploader,
|
|
7
|
-
} from 'vant'
|
|
8
|
-
import { ref, watch } from 'vue'
|
|
9
|
-
|
|
10
|
-
const props = defineProps({
|
|
11
|
-
imageList: Array<any>,
|
|
12
|
-
outerIndex: { default: undefined },
|
|
13
|
-
authority: { default: 'user' },
|
|
14
|
-
uploadMode: { default: 'server' },
|
|
15
|
-
attr: { type: Object as () => { addOrEdit?: string }, default: () => ({}) },
|
|
16
|
-
})
|
|
17
|
-
const emit = defineEmits(['updateFileList'])
|
|
18
|
-
|
|
19
|
-
const imageList = ref<Array<any>>(props.imageList ?? [])
|
|
20
|
-
|
|
21
|
-
// 同步 props.imageList 到内部 imageList,保证每次变化都响应
|
|
22
|
-
watch(() => props.imageList, (newVal) => {
|
|
23
|
-
imageList.value = Array.isArray(newVal) ? [...newVal] : []
|
|
24
|
-
}, { immediate: true })
|
|
25
|
-
|
|
26
|
-
// 触发拍照
|
|
27
|
-
function triggerCamera() {
|
|
28
|
-
mobileUtil.execute({
|
|
29
|
-
funcName: 'takePicture',
|
|
30
|
-
param: {},
|
|
31
|
-
callbackFunc: (result: any) => {
|
|
32
|
-
if (result.status === 'success') {
|
|
33
|
-
handlePhotoUpload(result.data)
|
|
34
|
-
}
|
|
35
|
-
},
|
|
36
|
-
})
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
// 处理拍照后的上传
|
|
40
|
-
function getImageMimeType(fileName: string): string {
|
|
41
|
-
const ext = fileName.split('.').pop()?.toLowerCase()
|
|
42
|
-
if (ext === 'jpg' || ext === 'jpeg')
|
|
43
|
-
return 'image/jpeg'
|
|
44
|
-
if (ext === 'png')
|
|
45
|
-
return 'image/png'
|
|
46
|
-
if (ext === 'gif')
|
|
47
|
-
return 'image/gif'
|
|
48
|
-
return 'image/png' // 默认
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
function handlePhotoUpload(photoData: any) {
|
|
52
|
-
// 添加临时预览
|
|
53
|
-
const mimeType = getImageMimeType(photoData.filePath)
|
|
54
|
-
const tempFile = {
|
|
55
|
-
uid: Date.now() + Math.random().toString(36).substr(2, 5),
|
|
56
|
-
name: photoData.filePath.split('/').pop(),
|
|
57
|
-
status: 'uploading',
|
|
58
|
-
message: '上传中...',
|
|
59
|
-
url: `data:${mimeType};base64,${photoData.content}`,
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
if (!imageList.value) {
|
|
63
|
-
imageList.value = [tempFile]
|
|
64
|
-
}
|
|
65
|
-
else {
|
|
66
|
-
imageList.value.push(tempFile)
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
const param = {
|
|
70
|
-
resUploadMode: props.uploadMode,
|
|
71
|
-
pathKey: 'Default',
|
|
72
|
-
formType: 'image',
|
|
73
|
-
useType: 'Default',
|
|
74
|
-
resUploadStock: '1',
|
|
75
|
-
filename: photoData.name,
|
|
76
|
-
filesize: photoData.size,
|
|
77
|
-
f_operator: 'server',
|
|
78
|
-
imgPath: photoData.filePath,
|
|
79
|
-
urlPath: `/api/${import.meta.env.VITE_APP_SYSTEM_NAME}/resource/upload`,
|
|
80
|
-
}
|
|
81
|
-
// 上传到服务器
|
|
82
|
-
mobileUtil.execute({
|
|
83
|
-
funcName: 'uploadResource',
|
|
84
|
-
param,
|
|
85
|
-
callbackFunc: (result: any) => {
|
|
86
|
-
if (result.status === 'success') {
|
|
87
|
-
const index = imageList.value.findIndex(item => item.uid === tempFile.uid)
|
|
88
|
-
if (index !== -1) {
|
|
89
|
-
imageList.value[index].uid = result.data.id
|
|
90
|
-
imageList.value[index].id = result.data.id
|
|
91
|
-
delete imageList.value[index].message
|
|
92
|
-
imageList.value[index].status = 'done'
|
|
93
|
-
imageList.value[index].url = result.data.f_downloadpath
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
else {
|
|
97
|
-
const index = imageList.value.findIndex(item => item.uid === tempFile.uid)
|
|
98
|
-
if (index !== -1) {
|
|
99
|
-
imageList.value[index].status = 'failed'
|
|
100
|
-
imageList.value[index].message = '上传失败'
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
if (props.outerIndex !== undefined)
|
|
105
|
-
emit('updateFileList', imageList.value.filter(item => item.status === 'done'), props.outerIndex)
|
|
106
|
-
else
|
|
107
|
-
emit('updateFileList', imageList.value.filter(item => item.status === 'done'))
|
|
108
|
-
},
|
|
109
|
-
})
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
// 删除图片
|
|
113
|
-
function deleteFileFunction(file: any) {
|
|
114
|
-
if (file.id) {
|
|
115
|
-
deleteFile({ ids: [file.id], f_state: '删除' }).then((res: any) => {
|
|
116
|
-
if (res.msg !== undefined) {
|
|
117
|
-
const targetIndex = imageList.value.findIndex(item => item.id === file.id)
|
|
118
|
-
if (targetIndex !== -1) {
|
|
119
|
-
imageList.value.splice(targetIndex, 1)
|
|
120
|
-
if (props.outerIndex !== undefined)
|
|
121
|
-
emit('updateFileList', imageList.value.filter(item => item.status === 'done'), props.outerIndex)
|
|
122
|
-
else
|
|
123
|
-
emit('updateFileList', imageList.value.filter(item => item.status === 'done'))
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
})
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
</script>
|
|
130
|
-
|
|
131
|
-
<template>
|
|
132
|
-
<div class="uploader-container">
|
|
133
|
-
<van-button
|
|
134
|
-
v-if="props.attr?.addOrEdit !== 'readonly'"
|
|
135
|
-
icon="photograph"
|
|
136
|
-
type="primary"
|
|
137
|
-
@click="triggerCamera"
|
|
138
|
-
>
|
|
139
|
-
拍照
|
|
140
|
-
</van-button>
|
|
141
|
-
|
|
142
|
-
<van-uploader
|
|
143
|
-
v-model="imageList"
|
|
144
|
-
:show-upload="false"
|
|
145
|
-
:deletable="props.attr?.addOrEdit !== 'readonly' && props.authority === 'admin'"
|
|
146
|
-
:multiple="props.authority === 'admin'"
|
|
147
|
-
:preview-image="true"
|
|
148
|
-
:before-delete="props.attr?.addOrEdit !== 'readonly' && props.authority === 'admin' ? deleteFileFunction : undefined"
|
|
149
|
-
/>
|
|
150
|
-
</div>
|
|
151
|
-
</template>
|
|
152
|
-
|
|
153
|
-
<style scoped lang="less">
|
|
154
|
-
.uploader-container {
|
|
155
|
-
display: flex;
|
|
156
|
-
flex-direction: column;
|
|
157
|
-
gap: 16px;
|
|
158
|
-
}
|
|
159
|
-
</style>
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { deleteFile } from '@af-mobile-client-vue3/services/api/common'
|
|
3
|
+
import { mobileUtil } from '@af-mobile-client-vue3/utils/mobileUtil'
|
|
4
|
+
import {
|
|
5
|
+
Button as vanButton,
|
|
6
|
+
Uploader as vanUploader,
|
|
7
|
+
} from 'vant'
|
|
8
|
+
import { ref, watch } from 'vue'
|
|
9
|
+
|
|
10
|
+
const props = defineProps({
|
|
11
|
+
imageList: Array<any>,
|
|
12
|
+
outerIndex: { default: undefined },
|
|
13
|
+
authority: { default: 'user' },
|
|
14
|
+
uploadMode: { default: 'server' },
|
|
15
|
+
attr: { type: Object as () => { addOrEdit?: string }, default: () => ({}) },
|
|
16
|
+
})
|
|
17
|
+
const emit = defineEmits(['updateFileList'])
|
|
18
|
+
|
|
19
|
+
const imageList = ref<Array<any>>(props.imageList ?? [])
|
|
20
|
+
|
|
21
|
+
// 同步 props.imageList 到内部 imageList,保证每次变化都响应
|
|
22
|
+
watch(() => props.imageList, (newVal) => {
|
|
23
|
+
imageList.value = Array.isArray(newVal) ? [...newVal] : []
|
|
24
|
+
}, { immediate: true })
|
|
25
|
+
|
|
26
|
+
// 触发拍照
|
|
27
|
+
function triggerCamera() {
|
|
28
|
+
mobileUtil.execute({
|
|
29
|
+
funcName: 'takePicture',
|
|
30
|
+
param: {},
|
|
31
|
+
callbackFunc: (result: any) => {
|
|
32
|
+
if (result.status === 'success') {
|
|
33
|
+
handlePhotoUpload(result.data)
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
})
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// 处理拍照后的上传
|
|
40
|
+
function getImageMimeType(fileName: string): string {
|
|
41
|
+
const ext = fileName.split('.').pop()?.toLowerCase()
|
|
42
|
+
if (ext === 'jpg' || ext === 'jpeg')
|
|
43
|
+
return 'image/jpeg'
|
|
44
|
+
if (ext === 'png')
|
|
45
|
+
return 'image/png'
|
|
46
|
+
if (ext === 'gif')
|
|
47
|
+
return 'image/gif'
|
|
48
|
+
return 'image/png' // 默认
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function handlePhotoUpload(photoData: any) {
|
|
52
|
+
// 添加临时预览
|
|
53
|
+
const mimeType = getImageMimeType(photoData.filePath)
|
|
54
|
+
const tempFile = {
|
|
55
|
+
uid: Date.now() + Math.random().toString(36).substr(2, 5),
|
|
56
|
+
name: photoData.filePath.split('/').pop(),
|
|
57
|
+
status: 'uploading',
|
|
58
|
+
message: '上传中...',
|
|
59
|
+
url: `data:${mimeType};base64,${photoData.content}`,
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (!imageList.value) {
|
|
63
|
+
imageList.value = [tempFile]
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
imageList.value.push(tempFile)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const param = {
|
|
70
|
+
resUploadMode: props.uploadMode,
|
|
71
|
+
pathKey: 'Default',
|
|
72
|
+
formType: 'image',
|
|
73
|
+
useType: 'Default',
|
|
74
|
+
resUploadStock: '1',
|
|
75
|
+
filename: photoData.name,
|
|
76
|
+
filesize: photoData.size,
|
|
77
|
+
f_operator: 'server',
|
|
78
|
+
imgPath: photoData.filePath,
|
|
79
|
+
urlPath: `/api/${import.meta.env.VITE_APP_SYSTEM_NAME}/resource/upload`,
|
|
80
|
+
}
|
|
81
|
+
// 上传到服务器
|
|
82
|
+
mobileUtil.execute({
|
|
83
|
+
funcName: 'uploadResource',
|
|
84
|
+
param,
|
|
85
|
+
callbackFunc: (result: any) => {
|
|
86
|
+
if (result.status === 'success') {
|
|
87
|
+
const index = imageList.value.findIndex(item => item.uid === tempFile.uid)
|
|
88
|
+
if (index !== -1) {
|
|
89
|
+
imageList.value[index].uid = result.data.id
|
|
90
|
+
imageList.value[index].id = result.data.id
|
|
91
|
+
delete imageList.value[index].message
|
|
92
|
+
imageList.value[index].status = 'done'
|
|
93
|
+
imageList.value[index].url = result.data.f_downloadpath
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
const index = imageList.value.findIndex(item => item.uid === tempFile.uid)
|
|
98
|
+
if (index !== -1) {
|
|
99
|
+
imageList.value[index].status = 'failed'
|
|
100
|
+
imageList.value[index].message = '上传失败'
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (props.outerIndex !== undefined)
|
|
105
|
+
emit('updateFileList', imageList.value.filter(item => item.status === 'done'), props.outerIndex)
|
|
106
|
+
else
|
|
107
|
+
emit('updateFileList', imageList.value.filter(item => item.status === 'done'))
|
|
108
|
+
},
|
|
109
|
+
})
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// 删除图片
|
|
113
|
+
function deleteFileFunction(file: any) {
|
|
114
|
+
if (file.id) {
|
|
115
|
+
deleteFile({ ids: [file.id], f_state: '删除' }).then((res: any) => {
|
|
116
|
+
if (res.msg !== undefined) {
|
|
117
|
+
const targetIndex = imageList.value.findIndex(item => item.id === file.id)
|
|
118
|
+
if (targetIndex !== -1) {
|
|
119
|
+
imageList.value.splice(targetIndex, 1)
|
|
120
|
+
if (props.outerIndex !== undefined)
|
|
121
|
+
emit('updateFileList', imageList.value.filter(item => item.status === 'done'), props.outerIndex)
|
|
122
|
+
else
|
|
123
|
+
emit('updateFileList', imageList.value.filter(item => item.status === 'done'))
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
})
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
</script>
|
|
130
|
+
|
|
131
|
+
<template>
|
|
132
|
+
<div class="uploader-container">
|
|
133
|
+
<van-button
|
|
134
|
+
v-if="props.attr?.addOrEdit !== 'readonly'"
|
|
135
|
+
icon="photograph"
|
|
136
|
+
type="primary"
|
|
137
|
+
@click="triggerCamera"
|
|
138
|
+
>
|
|
139
|
+
拍照
|
|
140
|
+
</van-button>
|
|
141
|
+
|
|
142
|
+
<van-uploader
|
|
143
|
+
v-model="imageList"
|
|
144
|
+
:show-upload="false"
|
|
145
|
+
:deletable="props.attr?.addOrEdit !== 'readonly' && props.authority === 'admin'"
|
|
146
|
+
:multiple="props.authority === 'admin'"
|
|
147
|
+
:preview-image="true"
|
|
148
|
+
:before-delete="props.attr?.addOrEdit !== 'readonly' && props.authority === 'admin' ? deleteFileFunction : undefined"
|
|
149
|
+
/>
|
|
150
|
+
</div>
|
|
151
|
+
</template>
|
|
152
|
+
|
|
153
|
+
<style scoped lang="less">
|
|
154
|
+
.uploader-container {
|
|
155
|
+
display: flex;
|
|
156
|
+
flex-direction: column;
|
|
157
|
+
gap: 16px;
|
|
158
|
+
}
|
|
159
|
+
</style>
|
|
@@ -171,7 +171,7 @@ async function loadFormConfig(): Promise<void> {
|
|
|
171
171
|
getConfigByName(props.configName!, (result) => {
|
|
172
172
|
if (result) {
|
|
173
173
|
// 如果有 paramLogicName,自动请求并赋值
|
|
174
|
-
if (result.paramLogicName && !props.formData) {
|
|
174
|
+
if (result.paramLogicName && (!props.formData || (props.formData && Object.keys(props.formData).length === 0))) {
|
|
175
175
|
let logicParam = props.paramLogicNameParam
|
|
176
176
|
if (typeof logicParam === 'string') {
|
|
177
177
|
try {
|
|
@@ -220,11 +220,9 @@ async function initWithGroupFormItems() {
|
|
|
220
220
|
|
|
221
221
|
// 设置表单配置
|
|
222
222
|
function setupFormConfig(config: GroupFormItems) {
|
|
223
|
-
console.log('>>>> config: ', JSON.stringify(config))
|
|
224
223
|
formConfig.value = config
|
|
225
224
|
myServiceName.value = props.serviceName || ''
|
|
226
225
|
formGroupName.value = config.groupName || 'default'
|
|
227
|
-
console.log('>>>> props.formData: ', props.formData)
|
|
228
226
|
form.value = props.formData || {}
|
|
229
227
|
|
|
230
228
|
// 清理并重新设置验证规则
|
|
@@ -1,133 +1,172 @@
|
|
|
1
|
-
<script setup lang="ts">
|
|
2
|
-
import XForm from '@af-mobile-client-vue3/components/data/XForm/index.vue'
|
|
3
|
-
import { getConfigByName } from '@af-mobile-client-vue3/services/api/common'
|
|
4
|
-
import {
|
|
5
|
-
Button as VanButton,
|
|
6
|
-
Tab as VanTab,
|
|
7
|
-
Tabs as VanTabs,
|
|
8
|
-
} from 'vant'
|
|
9
|
-
import { defineEmits, defineProps, onBeforeMount, ref, watch } from 'vue'
|
|
10
|
-
|
|
11
|
-
const props = withDefaults(defineProps<{
|
|
12
|
-
configName?: string
|
|
13
|
-
serviceName?: string
|
|
14
|
-
groupFormData?: object
|
|
15
|
-
mode?: string
|
|
16
|
-
}>(), {
|
|
17
|
-
configName: '',
|
|
18
|
-
serviceName: undefined,
|
|
19
|
-
groupFormData: () => ({}),
|
|
20
|
-
mode: '查询',
|
|
21
|
-
})
|
|
22
|
-
const emit = defineEmits(['submit'])
|
|
23
|
-
|
|
24
|
-
interface Form {
|
|
25
|
-
configName?: string
|
|
26
|
-
serviceName?: string
|
|
27
|
-
groupFormData?: object
|
|
28
|
-
mode?: string
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
const groupItems = ref([])
|
|
32
|
-
const formData = ref({})
|
|
33
|
-
const submitGroup = ref(false)
|
|
34
|
-
const submitSimple = ref(false)
|
|
35
|
-
const isInit = ref(false)
|
|
36
|
-
const initStatus = ref(false)
|
|
37
|
-
const propsData = ref({})
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import XForm from '@af-mobile-client-vue3/components/data/XForm/index.vue'
|
|
3
|
+
import { getConfigByName } from '@af-mobile-client-vue3/services/api/common'
|
|
4
|
+
import {
|
|
5
|
+
Button as VanButton,
|
|
6
|
+
Tab as VanTab,
|
|
7
|
+
Tabs as VanTabs,
|
|
8
|
+
} from 'vant'
|
|
9
|
+
import { defineEmits, defineProps, onBeforeMount, ref, watch, useSlots, computed } from 'vue'
|
|
10
|
+
|
|
11
|
+
const props = withDefaults(defineProps<{
|
|
12
|
+
configName?: string
|
|
13
|
+
serviceName?: string
|
|
14
|
+
groupFormData?: object
|
|
15
|
+
mode?: string
|
|
16
|
+
}>(), {
|
|
17
|
+
configName: '',
|
|
18
|
+
serviceName: undefined,
|
|
19
|
+
groupFormData: () => ({}),
|
|
20
|
+
mode: '查询',
|
|
21
|
+
})
|
|
22
|
+
const emit = defineEmits(['submit'])
|
|
23
|
+
|
|
24
|
+
interface Form {
|
|
25
|
+
configName?: string
|
|
26
|
+
serviceName?: string
|
|
27
|
+
groupFormData?: object
|
|
28
|
+
mode?: string
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const groupItems = ref([])
|
|
32
|
+
const formData = ref({})
|
|
33
|
+
const submitGroup = ref(false)
|
|
34
|
+
const submitSimple = ref(false)
|
|
35
|
+
const isInit = ref(false)
|
|
36
|
+
const initStatus = ref(false)
|
|
37
|
+
const propsData = ref<Partial<Form>>({})
|
|
38
|
+
|
|
39
|
+
const slots = useSlots()
|
|
40
|
+
const renderableGroupItems = computed(() => {
|
|
41
|
+
return groupItems.value.filter(item => {
|
|
42
|
+
if (item.formGroupType === 'slot') {
|
|
43
|
+
return !!(item.slotName && slots[item.slotName])
|
|
44
|
+
}
|
|
45
|
+
return true
|
|
46
|
+
})
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
// 组件初始化函数
|
|
50
|
+
function init(params: Form) {
|
|
51
|
+
initStatus.value = true
|
|
52
|
+
propsData.value = {
|
|
53
|
+
configName: props.configName,
|
|
54
|
+
serviceName: props.serviceName,
|
|
55
|
+
groupFormData: props.groupFormData,
|
|
56
|
+
mode: props.mode,
|
|
57
|
+
...params,
|
|
58
|
+
}
|
|
59
|
+
formData.value = propsData.value.groupFormData
|
|
60
|
+
getConfigByName(propsData.value.configName, (result) => {
|
|
61
|
+
console.log('result===', result)
|
|
62
|
+
if (result?.groups) {
|
|
63
|
+
groupItems.value = result.groups
|
|
64
|
+
result.groups.forEach((group) => {
|
|
65
|
+
if (!formData.value[group.groupName])
|
|
66
|
+
formData.value[group.groupName] = {}
|
|
67
|
+
if (group.showSubmitBtn)
|
|
68
|
+
submitGroup.value = true
|
|
69
|
+
})
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
submitSimple.value = result.showSubmitBtn
|
|
73
|
+
groupItems.value = [{ ...result }]
|
|
74
|
+
}
|
|
75
|
+
isInit.value = true
|
|
76
|
+
}, propsData.value.serviceName)
|
|
77
|
+
}
|
|
78
|
+
watch(() => props.groupFormData, (_val) => {
|
|
79
|
+
formData.value = { ...formData.value, ...props.groupFormData }
|
|
80
|
+
})
|
|
81
|
+
onBeforeMount(() => {
|
|
82
|
+
if (!initStatus.value)
|
|
83
|
+
init(props)
|
|
84
|
+
})
|
|
85
|
+
interface XFormLike {
|
|
86
|
+
validate: () => Promise<void>
|
|
87
|
+
formGroupName?: string
|
|
88
|
+
form?: any
|
|
89
|
+
getFormData?: () => object
|
|
90
|
+
}
|
|
91
|
+
const xFormListRef = ref<XFormLike[]>([])
|
|
92
|
+
|
|
93
|
+
// 注册表单实例,避免重复
|
|
94
|
+
function setRef(refValue: XFormLike) {
|
|
95
|
+
if (refValue && !xFormListRef.value.includes(refValue)) {
|
|
96
|
+
xFormListRef.value.push(refValue)
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
// 注销表单实例
|
|
100
|
+
function removeRef(refValue: XFormLike) {
|
|
101
|
+
const idx = xFormListRef.value.indexOf(refValue)
|
|
102
|
+
if (idx !== -1) xFormListRef.value.splice(idx, 1)
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
async function submit() {
|
|
106
|
+
for (const res of xFormListRef.value) {
|
|
107
|
+
try {
|
|
108
|
+
await res.validate()
|
|
109
|
+
if (res.formGroupName && res.form) {
|
|
110
|
+
formData.value[res.formGroupName] = res.form
|
|
111
|
+
} else if (typeof res.getFormData === 'function') {
|
|
112
|
+
Object.assign(formData.value, res.getFormData())
|
|
113
|
+
}
|
|
114
|
+
} catch (msg) {
|
|
115
|
+
console.log('error:', msg)
|
|
116
|
+
return
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
console.log('formData.value===', formData.value)
|
|
120
|
+
emit('submit', formData.value)
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
defineExpose({ init, removeRef, xFormListRef })
|
|
124
|
+
</script>
|
|
125
|
+
|
|
126
|
+
<template>
|
|
127
|
+
<div v-if="isInit" id="x-form-group">
|
|
128
|
+
<VanTabs scrollspy sticky>
|
|
129
|
+
<VanTab
|
|
130
|
+
v-for="(item, index) in renderableGroupItems"
|
|
131
|
+
:key="item.groupName ? (item.groupName + index) : index"
|
|
132
|
+
:title="item.describe ? item.describe : item.tableName "
|
|
133
|
+
>
|
|
134
|
+
<div class="x-form-group-item">
|
|
135
|
+
<template v-if="item.formGroupType === 'slot'">
|
|
136
|
+
<slot :name="item.slotName"
|
|
137
|
+
:item="item"
|
|
138
|
+
:form-data="item.groupName ? formData[item.groupName] : formData"
|
|
139
|
+
:set-ref="setRef"
|
|
140
|
+
:remove-ref="removeRef"
|
|
141
|
+
/>
|
|
142
|
+
</template>
|
|
143
|
+
<template v-else>
|
|
144
|
+
<XForm
|
|
145
|
+
ref="xFormListRef"
|
|
146
|
+
:mode="props.mode"
|
|
147
|
+
:group-form-items="item"
|
|
148
|
+
:form-data="item.groupName ? formData[item.groupName] : formData"
|
|
149
|
+
:form-name="item.groupName"
|
|
150
|
+
:service-name="props.serviceName"
|
|
151
|
+
:submit-button="submitSimple"
|
|
152
|
+
@on-submit="submit"
|
|
153
|
+
/>
|
|
154
|
+
</template>
|
|
155
|
+
</div>
|
|
156
|
+
</VanTab>
|
|
157
|
+
</VanTabs>
|
|
158
|
+
<VanButton v-if="submitGroup" round block type="primary" @click="submit">
|
|
159
|
+
提交
|
|
160
|
+
</VanButton>
|
|
161
|
+
</div>
|
|
162
|
+
</template>
|
|
163
|
+
|
|
164
|
+
<style scoped lang="less">
|
|
165
|
+
#x-form-group {
|
|
166
|
+
background-color: rgb(247, 248, 250);
|
|
167
|
+
padding-bottom: 10px;
|
|
168
|
+
.x-form-group-item {
|
|
169
|
+
margin: 20px 0;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
</style>
|
|
@@ -724,7 +724,7 @@ function onTreeSelectFinish(value) {
|
|
|
724
724
|
}
|
|
725
725
|
|
|
726
726
|
function emitFunc(func, data) {
|
|
727
|
-
emits('xFormItemEmitFunc', func, data, data?.model ?
|
|
727
|
+
emits('xFormItemEmitFunc', func, data, data?.model ? form[data.model] : form)
|
|
728
728
|
}
|
|
729
729
|
</script>
|
|
730
730
|
|