af-mobile-client-vue3 1.2.18 → 1.2.19
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/data/XCellList/index.vue +49 -11
- package/src/components/data/XCellListFilter/index.vue +87 -16
- package/src/components/data/XForm/index.vue +67 -28
- package/src/components/data/XFormItem/index.vue +271 -213
- package/src/components/data/XOlMap/index.vue +4 -3
- package/src/components/data/XOlMap/types.ts +2 -0
- package/src/components/data/XReportGrid/XReportDemo.vue +33 -33
- package/src/components/data/XReportGrid/print.js +184 -184
- package/src/utils/queryFormDefaultRangePicker.ts +57 -57
- package/src/views/component/XCellListView/index.vue +126 -127
- package/src/views/component/XFormGroupView/index.vue +4 -7
- package/vite.config.ts +2 -2
package/package.json
CHANGED
|
@@ -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,17 @@ 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
|
+
} else {
|
|
207
|
+
flatFormJson.push(item)
|
|
208
|
+
}
|
|
209
|
+
})
|
|
210
|
+
formQueryList.value = flatFormJson
|
|
211
|
+
console.log('formQueryList', formQueryList.value)
|
|
206
212
|
if (result.buttonState) {
|
|
207
213
|
buttonState.value = result.buttonState
|
|
208
214
|
buttonPermissions.value = result.buttonPermissions
|
|
@@ -252,13 +258,12 @@ function initConditionParams(formItems, isQuery) {
|
|
|
252
258
|
hasDefaults = true
|
|
253
259
|
|
|
254
260
|
// 如果有默认值,则设置到条件参数中并立即执行查询
|
|
255
|
-
queryDefaultParams.value = defaultParams
|
|
256
261
|
isInitQuery.value = isQuery
|
|
257
262
|
if (hasDefaults && isInitQuery.value) {
|
|
258
263
|
// 延迟执行第一次查询,确保组件完全加载
|
|
259
264
|
setTimeout(() => {
|
|
260
265
|
loading.value = true
|
|
261
|
-
onLoad()
|
|
266
|
+
onLoad(defaultParams)
|
|
262
267
|
}, 100)
|
|
263
268
|
}
|
|
264
269
|
}
|
|
@@ -278,7 +283,7 @@ function onRefresh() {
|
|
|
278
283
|
}
|
|
279
284
|
|
|
280
285
|
// 加载数据
|
|
281
|
-
function onLoad() {
|
|
286
|
+
function onLoad(defaultParams = {}) {
|
|
282
287
|
if (refreshing.value) {
|
|
283
288
|
list.value = []
|
|
284
289
|
pageNo.value = 1
|
|
@@ -292,8 +297,7 @@ function onLoad() {
|
|
|
292
297
|
// 确保conditionParams不是undefined
|
|
293
298
|
if (conditionParams.value === undefined)
|
|
294
299
|
conditionParams.value = {}
|
|
295
|
-
const mergedParams = mergeParams(
|
|
296
|
-
|
|
300
|
+
const mergedParams = mergeParams(defaultParams, conditionParams.value)
|
|
297
301
|
// 输出查询条件,便于调试
|
|
298
302
|
console.log('查询条件:', {
|
|
299
303
|
pageNo: pageNo.value,
|
|
@@ -537,6 +541,16 @@ defineExpose({
|
|
|
537
541
|
@search="onRefresh"
|
|
538
542
|
/>
|
|
539
543
|
</VanCol>
|
|
544
|
+
<!-- 新增按钮,放在查询框后、查询条件下拉按钮前 -->
|
|
545
|
+
<VanCol class="add-col" 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)))) )">
|
|
546
|
+
<VanButton
|
|
547
|
+
icon="plus"
|
|
548
|
+
type="primary"
|
|
549
|
+
size="small"
|
|
550
|
+
class="add-action-btn"
|
|
551
|
+
@click="addOption"
|
|
552
|
+
/>
|
|
553
|
+
</VanCol>
|
|
540
554
|
<!-- 右侧动态插槽区域 -->
|
|
541
555
|
<template v-for="(_, name) in slots" :key="name">
|
|
542
556
|
<template v-if="typeof name === 'string' && name.startsWith('search-right-')">
|
|
@@ -558,7 +572,6 @@ defineExpose({
|
|
|
558
572
|
:button-permissions="buttonPermissions"
|
|
559
573
|
:scan-options="scanOptions"
|
|
560
574
|
@on-refresh="onRefresh"
|
|
561
|
-
@add-option="addOption"
|
|
562
575
|
/>
|
|
563
576
|
</VanCol>
|
|
564
577
|
</VanRow>
|
|
@@ -953,6 +966,31 @@ defineExpose({
|
|
|
953
966
|
position: sticky;
|
|
954
967
|
top: 0;
|
|
955
968
|
z-index: 10;
|
|
969
|
+
.add-col {
|
|
970
|
+
display: flex;
|
|
971
|
+
align-items: center;
|
|
972
|
+
margin: 0 4px;
|
|
973
|
+
.add-action-btn {
|
|
974
|
+
width: 40px;
|
|
975
|
+
height: 40px;
|
|
976
|
+
border-radius: 10px;
|
|
977
|
+
background-color: var(--van-background);
|
|
978
|
+
color: #888;
|
|
979
|
+
border: 1px solid rgba(0,0,0,0.06);
|
|
980
|
+
display: flex;
|
|
981
|
+
align-items: center;
|
|
982
|
+
justify-content: center;
|
|
983
|
+
font-size: 22px;
|
|
984
|
+
padding: 0;
|
|
985
|
+
transition: all 0.2s;
|
|
986
|
+
&:hover, &:active {
|
|
987
|
+
opacity: 0.85;
|
|
988
|
+
background-color: rgba(25, 137, 250, 0.08);
|
|
989
|
+
border-color: var(--van-primary-color);
|
|
990
|
+
color: var(--van-primary-color);
|
|
991
|
+
}
|
|
992
|
+
}
|
|
993
|
+
}
|
|
956
994
|
:deep(.van-search) {
|
|
957
995
|
width: 100%;
|
|
958
996
|
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>
|
|
@@ -55,7 +55,7 @@ const props = withDefaults(defineProps<{
|
|
|
55
55
|
})
|
|
56
56
|
const emits = defineEmits(['onSubmit'])
|
|
57
57
|
const userStore = useUserStore()
|
|
58
|
-
const
|
|
58
|
+
const xFormRef = ref<FormInstance>()
|
|
59
59
|
const myFormItems = ref<FormItem[]>([])
|
|
60
60
|
const rules = reactive({})
|
|
61
61
|
const form = ref({})
|
|
@@ -203,21 +203,6 @@ function init(params) {
|
|
|
203
203
|
}
|
|
204
204
|
|
|
205
205
|
function setFormProps(form, item) {
|
|
206
|
-
// 只有在字段未定义时,按类型赋有意义的默认值
|
|
207
|
-
if (form.value[item.model] === undefined) {
|
|
208
|
-
switch (item.rule?.type) {
|
|
209
|
-
case 'number':
|
|
210
|
-
case 'integer':
|
|
211
|
-
case 'float':
|
|
212
|
-
form.value[item.model] = 0
|
|
213
|
-
break
|
|
214
|
-
case 'string':
|
|
215
|
-
form.value[item.model] = ''
|
|
216
|
-
break
|
|
217
|
-
default:
|
|
218
|
-
form.value[item.model] = ''
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
206
|
if (item.rule) {
|
|
222
207
|
rules[item.model] = []
|
|
223
208
|
let defaultValue
|
|
@@ -273,9 +258,9 @@ function getRealKey(key, mustHandleKey = false) {
|
|
|
273
258
|
async function asyncSubmit() {
|
|
274
259
|
return new Promise((resolve, reject) => {
|
|
275
260
|
validate().then(async () => {
|
|
276
|
-
const
|
|
277
|
-
await appendSilenceAddFields(
|
|
278
|
-
const realForm = handleFormKeys(
|
|
261
|
+
const cleanedForm = prepareForm()
|
|
262
|
+
await appendSilenceAddFields(cleanedForm)
|
|
263
|
+
const realForm = handleFormKeys(cleanedForm)
|
|
279
264
|
resolve({
|
|
280
265
|
realForm,
|
|
281
266
|
mode: props.mode,
|
|
@@ -364,21 +349,74 @@ async function appendSilenceAddFields(form) {
|
|
|
364
349
|
|
|
365
350
|
function prepareForm() {
|
|
366
351
|
const formObj = { ...form.value }
|
|
352
|
+
const cleanedForm = {}
|
|
353
|
+
|
|
367
354
|
for (const key of Object.keys(formObj)) {
|
|
368
355
|
const value = formObj[key]
|
|
369
|
-
|
|
370
|
-
|
|
356
|
+
|
|
357
|
+
// 跳过无效值
|
|
358
|
+
if (value === null || value === undefined || value === '') {
|
|
359
|
+
continue
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
// 处理数组
|
|
363
|
+
if (Array.isArray(value)) {
|
|
364
|
+
// 过滤掉空字符串、null、undefined
|
|
365
|
+
const filteredArray = value.filter(item =>
|
|
366
|
+
item !== null && item !== undefined && item !== '',
|
|
367
|
+
)
|
|
368
|
+
// 只有当数组不为空时才添加
|
|
369
|
+
if (filteredArray.length > 0) {
|
|
370
|
+
cleanedForm[key] = filteredArray
|
|
371
|
+
}
|
|
372
|
+
continue
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
// 处理对象
|
|
376
|
+
if (typeof value === 'object' && value !== null) {
|
|
377
|
+
// 检查对象是否为空
|
|
378
|
+
const objectKeys = Object.keys(value)
|
|
379
|
+
if (objectKeys.length === 0) {
|
|
380
|
+
continue
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
// 递归清理对象内部
|
|
384
|
+
const cleanedObject = {}
|
|
385
|
+
let hasValidValue = false
|
|
386
|
+
|
|
387
|
+
for (const objKey of objectKeys) {
|
|
388
|
+
const objValue = value[objKey]
|
|
389
|
+
if (objValue !== null && objValue !== undefined && objValue !== '') {
|
|
390
|
+
cleanedObject[objKey] = objValue
|
|
391
|
+
hasValidValue = true
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
// 只有当对象有有效值时才添加
|
|
396
|
+
if (hasValidValue) {
|
|
397
|
+
cleanedForm[key] = cleanedObject
|
|
398
|
+
}
|
|
399
|
+
continue
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
// 处理基本类型
|
|
403
|
+
if (value !== null && value !== undefined && value !== '') {
|
|
404
|
+
cleanedForm[key] = value
|
|
371
405
|
}
|
|
372
406
|
}
|
|
373
|
-
|
|
407
|
+
|
|
408
|
+
return cleanedForm
|
|
374
409
|
}
|
|
375
410
|
|
|
376
411
|
async function onSubmit() {
|
|
412
|
+
await validate()
|
|
413
|
+
// 清理表单数据
|
|
414
|
+
const cleanedForm = prepareForm()
|
|
377
415
|
if (!props.configName && props.groupFormItems) {
|
|
378
416
|
// 只有单表才可以成功,多表关联或者自定义sql不行
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
417
|
+
await appendSilenceAddFields(cleanedForm)
|
|
418
|
+
const realForm = handleFormKeys(cleanedForm)
|
|
419
|
+
|
|
382
420
|
try {
|
|
383
421
|
addOrModifyEntity(realForm, tableName.value, props.serviceName || import.meta.env.VITE_APP_SYSTEM_NAME).then(() => {
|
|
384
422
|
showSuccessToast('提交成功!!')
|
|
@@ -394,11 +432,12 @@ async function onSubmit() {
|
|
|
394
432
|
}
|
|
395
433
|
}
|
|
396
434
|
else {
|
|
397
|
-
|
|
435
|
+
// 使用清理后的数据
|
|
436
|
+
emits('onSubmit', cleanedForm)
|
|
398
437
|
}
|
|
399
438
|
}
|
|
400
439
|
async function validate() {
|
|
401
|
-
await
|
|
440
|
+
await xFormRef.value?.validate()
|
|
402
441
|
}
|
|
403
442
|
watch(() => props.formData, (_val) => {
|
|
404
443
|
form.value = _val
|
|
@@ -407,7 +446,7 @@ defineExpose({ init, form, formGroupName, validate, asyncSubmit })
|
|
|
407
446
|
</script>
|
|
408
447
|
|
|
409
448
|
<template>
|
|
410
|
-
<VanForm ref="
|
|
449
|
+
<VanForm ref="xFormRef" class="x-form-container" @submit="onSubmit">
|
|
411
450
|
<div class="form-fields-scrollable">
|
|
412
451
|
<VanCellGroup inset>
|
|
413
452
|
<XFormItem
|