af-mobile-client-vue3 1.2.18 → 1.2.20
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/XCellList/index.vue +51 -11
- package/src/components/data/XCellListFilter/index.vue +87 -16
- package/src/components/data/XForm/index.vue +75 -30
- package/src/components/data/XFormItem/index.vue +303 -215
- package/src/components/data/XOlMap/index.vue +4 -3
- package/src/components/data/XOlMap/types.ts +2 -0
- package/src/components/data/XOlMap/utils/wgs84ToGcj02.js +154 -154
- package/src/utils/queryFormDefaultRangePicker.ts +57 -57
- package/src/views/component/XCellListView/index.vue +21 -56
- package/src/views/component/XFormGroupView/index.vue +2 -42
- package/src/views/component/XFormView/index.vue +14 -0
- package/src/views/component/XFormView/oldindex.vue +70 -0
- package/src/views/component/XOlMapView/XLocationPicker/index.vue +118 -118
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>
|
|
@@ -131,9 +131,6 @@ const isLastPage = ref(false)
|
|
|
131
131
|
// 条件参数(查询框)
|
|
132
132
|
const conditionParams = ref(undefined)
|
|
133
133
|
|
|
134
|
-
// 查询参数(配置自带的默认值)
|
|
135
|
-
const queryDefaultParams = ref({})
|
|
136
|
-
|
|
137
134
|
// 主要按钮的状态
|
|
138
135
|
const buttonState = ref(undefined)
|
|
139
136
|
|
|
@@ -201,8 +198,18 @@ function initComponent() {
|
|
|
201
198
|
}
|
|
202
199
|
}
|
|
203
200
|
configContent.value = result
|
|
204
|
-
|
|
205
|
-
|
|
201
|
+
// 扁平化 type=group 的 groupItems,保持顺序
|
|
202
|
+
const flatFormJson = []
|
|
203
|
+
result.formJson.forEach((item) => {
|
|
204
|
+
if (item.type === 'group' && Array.isArray(item.groupItems)) {
|
|
205
|
+
flatFormJson.push(...item.groupItems)
|
|
206
|
+
}
|
|
207
|
+
else {
|
|
208
|
+
flatFormJson.push(item)
|
|
209
|
+
}
|
|
210
|
+
})
|
|
211
|
+
formQueryList.value = flatFormJson
|
|
212
|
+
console.log('formQueryList', formQueryList.value)
|
|
206
213
|
if (result.buttonState) {
|
|
207
214
|
buttonState.value = result.buttonState
|
|
208
215
|
buttonPermissions.value = result.buttonPermissions
|
|
@@ -252,13 +259,12 @@ function initConditionParams(formItems, isQuery) {
|
|
|
252
259
|
hasDefaults = true
|
|
253
260
|
|
|
254
261
|
// 如果有默认值,则设置到条件参数中并立即执行查询
|
|
255
|
-
queryDefaultParams.value = defaultParams
|
|
256
262
|
isInitQuery.value = isQuery
|
|
257
263
|
if (hasDefaults && isInitQuery.value) {
|
|
258
264
|
// 延迟执行第一次查询,确保组件完全加载
|
|
259
265
|
setTimeout(() => {
|
|
260
266
|
loading.value = true
|
|
261
|
-
onLoad()
|
|
267
|
+
onLoad(defaultParams)
|
|
262
268
|
}, 100)
|
|
263
269
|
}
|
|
264
270
|
}
|
|
@@ -278,7 +284,7 @@ function onRefresh() {
|
|
|
278
284
|
}
|
|
279
285
|
|
|
280
286
|
// 加载数据
|
|
281
|
-
function onLoad() {
|
|
287
|
+
function onLoad(defaultParams = {}) {
|
|
282
288
|
if (refreshing.value) {
|
|
283
289
|
list.value = []
|
|
284
290
|
pageNo.value = 1
|
|
@@ -292,8 +298,7 @@ function onLoad() {
|
|
|
292
298
|
// 确保conditionParams不是undefined
|
|
293
299
|
if (conditionParams.value === undefined)
|
|
294
300
|
conditionParams.value = {}
|
|
295
|
-
const mergedParams = mergeParams(
|
|
296
|
-
|
|
301
|
+
const mergedParams = mergeParams(defaultParams, conditionParams.value)
|
|
297
302
|
// 输出查询条件,便于调试
|
|
298
303
|
console.log('查询条件:', {
|
|
299
304
|
pageNo: pageNo.value,
|
|
@@ -537,6 +542,16 @@ defineExpose({
|
|
|
537
542
|
@search="onRefresh"
|
|
538
543
|
/>
|
|
539
544
|
</VanCol>
|
|
545
|
+
<!-- 新增按钮,放在查询框后、查询条件下拉按钮前 -->
|
|
546
|
+
<VanCol v-if="buttonState?.add && buttonState.add === true && (filterButtonPermissions('add').state === false || ((filterButtonPermissions('add').state === true && userState.f.resources.f_role_name.includes((filterButtonPermissions('add').roleStr)))))" class="add-col">
|
|
547
|
+
<VanButton
|
|
548
|
+
icon="plus"
|
|
549
|
+
type="primary"
|
|
550
|
+
size="small"
|
|
551
|
+
class="add-action-btn"
|
|
552
|
+
@click="addOption"
|
|
553
|
+
/>
|
|
554
|
+
</VanCol>
|
|
540
555
|
<!-- 右侧动态插槽区域 -->
|
|
541
556
|
<template v-for="(_, name) in slots" :key="name">
|
|
542
557
|
<template v-if="typeof name === 'string' && name.startsWith('search-right-')">
|
|
@@ -558,7 +573,6 @@ defineExpose({
|
|
|
558
573
|
:button-permissions="buttonPermissions"
|
|
559
574
|
:scan-options="scanOptions"
|
|
560
575
|
@on-refresh="onRefresh"
|
|
561
|
-
@add-option="addOption"
|
|
562
576
|
/>
|
|
563
577
|
</VanCol>
|
|
564
578
|
</VanRow>
|
|
@@ -953,6 +967,32 @@ defineExpose({
|
|
|
953
967
|
position: sticky;
|
|
954
968
|
top: 0;
|
|
955
969
|
z-index: 10;
|
|
970
|
+
.add-col {
|
|
971
|
+
display: flex;
|
|
972
|
+
align-items: center;
|
|
973
|
+
margin: 0 4px;
|
|
974
|
+
.add-action-btn {
|
|
975
|
+
width: 40px;
|
|
976
|
+
height: 40px;
|
|
977
|
+
border-radius: 10px;
|
|
978
|
+
background-color: var(--van-background);
|
|
979
|
+
color: #888;
|
|
980
|
+
border: 1px solid rgba(0, 0, 0, 0.06);
|
|
981
|
+
display: flex;
|
|
982
|
+
align-items: center;
|
|
983
|
+
justify-content: center;
|
|
984
|
+
font-size: 22px;
|
|
985
|
+
padding: 0;
|
|
986
|
+
transition: all 0.2s;
|
|
987
|
+
&:hover,
|
|
988
|
+
&:active {
|
|
989
|
+
opacity: 0.85;
|
|
990
|
+
background-color: rgba(25, 137, 250, 0.08);
|
|
991
|
+
border-color: var(--van-primary-color);
|
|
992
|
+
color: var(--van-primary-color);
|
|
993
|
+
}
|
|
994
|
+
}
|
|
995
|
+
}
|
|
956
996
|
:deep(.van-search) {
|
|
957
997
|
width: 100%;
|
|
958
998
|
padding: var(--van-search-padding);
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
Icon as VanIcon,
|
|
13
13
|
Row as VanRow,
|
|
14
14
|
} from 'vant'
|
|
15
|
-
import { computed, defineEmits, defineModel, defineProps, onMounted, ref } from 'vue'
|
|
15
|
+
import { computed, defineEmits, defineModel, defineProps, nextTick, onMounted, ref } from 'vue'
|
|
16
16
|
import QrScanner from './QrScanner/index.vue'
|
|
17
17
|
import VpnRecognition from './VpnRecognition/index.vue'
|
|
18
18
|
|
|
@@ -91,6 +91,9 @@ const colFieldNames = {
|
|
|
91
91
|
// 查询条件参数 !!!!!建议最后点击确认的时候完成这个的整理
|
|
92
92
|
const conditionParams = ref({})
|
|
93
93
|
|
|
94
|
+
// 用于存储每个 XFormItem 的 ref
|
|
95
|
+
const formItemRefs = ref([])
|
|
96
|
+
|
|
94
97
|
// 视图模式 - 当前选中的扫描模式
|
|
95
98
|
const scanType = ref(getDefaultScanType())
|
|
96
99
|
|
|
@@ -234,6 +237,15 @@ function resetOption() {
|
|
|
234
237
|
Object.keys(conditionParams.value).forEach((key) => {
|
|
235
238
|
conditionParams.value[key] = undefined
|
|
236
239
|
})
|
|
240
|
+
// 关键:调用所有 XFormItem 的 reset 方法
|
|
241
|
+
nextTick(() => {
|
|
242
|
+
formItemRefs.value.forEach((refItem) => {
|
|
243
|
+
if (refItem && typeof refItem.reset === 'function') {
|
|
244
|
+
refItem.reset()
|
|
245
|
+
}
|
|
246
|
+
})
|
|
247
|
+
})
|
|
248
|
+
console.log('conditionParams.value重置', conditionParams.value)
|
|
237
249
|
}
|
|
238
250
|
function checkOrderOption() {
|
|
239
251
|
let isCheck = true
|
|
@@ -251,22 +263,81 @@ function checkOrderOption() {
|
|
|
251
263
|
}
|
|
252
264
|
return isCheck
|
|
253
265
|
}
|
|
266
|
+
// 清理查询条件参数,删除无效内容
|
|
267
|
+
function cleanConditionParams(params) {
|
|
268
|
+
const cleanedParams = {}
|
|
269
|
+
|
|
270
|
+
for (const key of Object.keys(params)) {
|
|
271
|
+
const value = params[key]
|
|
272
|
+
|
|
273
|
+
// 跳过无效值
|
|
274
|
+
if (value === null || value === undefined || value === '') {
|
|
275
|
+
continue
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
// 处理数组
|
|
279
|
+
if (Array.isArray(value)) {
|
|
280
|
+
// 过滤掉空字符串、null、undefined
|
|
281
|
+
const filteredArray = value.filter(item =>
|
|
282
|
+
item !== null && item !== undefined && item !== '',
|
|
283
|
+
)
|
|
284
|
+
// 只有当数组不为空时才添加
|
|
285
|
+
if (filteredArray.length > 0) {
|
|
286
|
+
cleanedParams[key] = filteredArray
|
|
287
|
+
}
|
|
288
|
+
continue
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// 处理对象
|
|
292
|
+
if (typeof value === 'object' && value !== null) {
|
|
293
|
+
// 检查对象是否为空
|
|
294
|
+
const objectKeys = Object.keys(value)
|
|
295
|
+
if (objectKeys.length === 0) {
|
|
296
|
+
continue
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
// 递归清理对象内部
|
|
300
|
+
const cleanedObject = {}
|
|
301
|
+
let hasValidValue = false
|
|
302
|
+
|
|
303
|
+
for (const objKey of objectKeys) {
|
|
304
|
+
const objValue = value[objKey]
|
|
305
|
+
if (objValue !== null && objValue !== undefined && objValue !== '') {
|
|
306
|
+
cleanedObject[objKey] = objValue
|
|
307
|
+
hasValidValue = true
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
// 只有当对象有有效值时才添加
|
|
312
|
+
if (hasValidValue) {
|
|
313
|
+
cleanedParams[key] = cleanedObject
|
|
314
|
+
}
|
|
315
|
+
continue
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
// 处理基本类型
|
|
319
|
+
if (value !== null && value !== undefined && value !== '') {
|
|
320
|
+
cleanedParams[key] = value
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
return cleanedParams
|
|
325
|
+
}
|
|
326
|
+
|
|
254
327
|
// 确认筛选条件
|
|
255
328
|
function confirmOption() {
|
|
256
329
|
const isCheck = checkOrderOption()
|
|
257
330
|
if (isCheck) {
|
|
258
|
-
|
|
259
|
-
|
|
331
|
+
// 清理查询条件参数
|
|
332
|
+
const cleanedParams = cleanConditionParams(conditionParams.value)
|
|
333
|
+
|
|
334
|
+
const isEmptyObject = Object.keys(cleanedParams).length === 0
|
|
335
|
+
emit('update:conditionParams', isEmptyObject ? undefined : cleanedParams)
|
|
260
336
|
emit('onRefresh', {})
|
|
261
337
|
listFilterMenu.value.close(false)
|
|
262
338
|
}
|
|
263
339
|
}
|
|
264
340
|
|
|
265
|
-
// 新增按钮
|
|
266
|
-
function addOption() {
|
|
267
|
-
emit('addOption')
|
|
268
|
-
}
|
|
269
|
-
|
|
270
341
|
// 处理筛选菜单显示
|
|
271
342
|
function handleFilterMenuChange(value: boolean) {
|
|
272
343
|
filterMenuShow.value = value
|
|
@@ -387,20 +458,20 @@ function filterButtonPermissions(btn) {
|
|
|
387
458
|
</div>
|
|
388
459
|
</VanCol> -->
|
|
389
460
|
</VanRow>
|
|
390
|
-
<XFormItem
|
|
461
|
+
<XFormItem
|
|
462
|
+
ref="formItemRefs"
|
|
463
|
+
v-model="conditionParams[item.model]"
|
|
464
|
+
:form="conditionParams"
|
|
465
|
+
:attr="item"
|
|
466
|
+
:service-name="props.serviceName"
|
|
467
|
+
:show-label="false"
|
|
468
|
+
/>
|
|
391
469
|
</template>
|
|
392
470
|
</div>
|
|
393
471
|
<div class="operations-panel">
|
|
394
472
|
<VanButton type="default" @click="resetOption">
|
|
395
473
|
重置
|
|
396
474
|
</VanButton>
|
|
397
|
-
<VanButton
|
|
398
|
-
v-if="props.buttonState.add && props.buttonState.add === true && (filterButtonPermissions('add').state === false || ((filterButtonPermissions('add').state === true && userState.f.resources.f_role_name.includes((filterButtonPermissions('add').roleStr)))))"
|
|
399
|
-
type="primary"
|
|
400
|
-
@click="addOption"
|
|
401
|
-
>
|
|
402
|
-
新增
|
|
403
|
-
</VanButton>
|
|
404
475
|
<VanButton type="primary" @click="confirmOption">
|
|
405
476
|
查询
|
|
406
477
|
</VanButton>
|