af-mobile-client-vue3 1.1.36 → 1.1.38
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 +160 -160
- package/src/components/data/XCellList/index.vue +24 -9
- 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/views/component/XCellListView/index.vue +435 -92
- package/src/views/component/XFormGroupView/index.vue +37 -0
- package/src/views/component/XFormView/index.vue +120 -27
- package/src/views/component/XOlMapView/XLocationPicker/index.vue +118 -118
- package/tsconfig.json +43 -43
- package/vite.config.ts +2 -2
- package/src/views/component/XFormView/oldindex.vue +0 -133
package/package.json
CHANGED
|
@@ -1,160 +1,160 @@
|
|
|
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
|
-
console.log('>>>> uploader 上传111')
|
|
29
|
-
mobileUtil.execute({
|
|
30
|
-
funcName: 'takePicture',
|
|
31
|
-
param: {},
|
|
32
|
-
callbackFunc: (result: any) => {
|
|
33
|
-
if (result.status === 'success') {
|
|
34
|
-
handlePhotoUpload(result.data)
|
|
35
|
-
}
|
|
36
|
-
},
|
|
37
|
-
})
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
// 处理拍照后的上传
|
|
41
|
-
function handlePhotoUpload(photoData: any) {
|
|
42
|
-
const formData = new FormData()
|
|
43
|
-
formData.append('resUploadMode', props.uploadMode)
|
|
44
|
-
formData.append('pathKey', 'Default')
|
|
45
|
-
formData.append('formType', 'image')
|
|
46
|
-
formData.append('useType', 'Default')
|
|
47
|
-
formData.append('resUploadStock', '1')
|
|
48
|
-
formData.append('filename', photoData.name)
|
|
49
|
-
formData.append('filesize', (photoData.size / 1024 / 1024).toFixed(4))
|
|
50
|
-
formData.append('f_operator', 'server')
|
|
51
|
-
formData.append('imgPath', photoData.filePath)
|
|
52
|
-
formData.append('urlPath', `/api/${import.meta.env.VITE_APP_SYSTEM_NAME}/resource/upload`)
|
|
53
|
-
|
|
54
|
-
// 添加临时预览
|
|
55
|
-
const tempFile = {
|
|
56
|
-
uid: Date.now() + Math.random().toString(36).substr(2, 5),
|
|
57
|
-
name: photoData.name,
|
|
58
|
-
status: 'uploading',
|
|
59
|
-
message: '上传中...',
|
|
60
|
-
url: `data:image/png;base64,${photoData.content}`,
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
if (!imageList.value) {
|
|
64
|
-
imageList.value = [tempFile]
|
|
65
|
-
}
|
|
66
|
-
else {
|
|
67
|
-
imageList.value.push(tempFile)
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
const param = {
|
|
71
|
-
resUploadMode: props.uploadMode,
|
|
72
|
-
pathKey: 'Default',
|
|
73
|
-
formType: 'image',
|
|
74
|
-
useType: 'Default',
|
|
75
|
-
resUploadStock: '1',
|
|
76
|
-
filename: photoData.name,
|
|
77
|
-
filesize: photoData.size,
|
|
78
|
-
f_operator: 'server',
|
|
79
|
-
imgPath: photoData.filePath,
|
|
80
|
-
urlPath: `/api/${import.meta.env.VITE_APP_SYSTEM_NAME}/resource/upload`,
|
|
81
|
-
}
|
|
82
|
-
// 上传到服务器
|
|
83
|
-
mobileUtil.execute({
|
|
84
|
-
funcName: 'uploadResource',
|
|
85
|
-
param,
|
|
86
|
-
callbackFunc: (result: any) => {
|
|
87
|
-
if (result.status === 'success') {
|
|
88
|
-
const index = imageList.value.findIndex(item => item.uid === tempFile.uid)
|
|
89
|
-
if (index !== -1) {
|
|
90
|
-
imageList.value[index].uid = result.data.id
|
|
91
|
-
imageList.value[index].id = result.data.id
|
|
92
|
-
delete imageList.value[index].message
|
|
93
|
-
imageList.value[index].status = 'done'
|
|
94
|
-
imageList.value[index].url = result.data.f_downloadpath
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
else {
|
|
98
|
-
const index = imageList.value.findIndex(item => item.uid === tempFile.uid)
|
|
99
|
-
if (index !== -1) {
|
|
100
|
-
imageList.value[index].status = 'failed'
|
|
101
|
-
imageList.value[index].message = '上传失败'
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
if (props.outerIndex !== undefined)
|
|
106
|
-
emit('updateFileList', imageList.value.filter(item => item.status === 'done'), props.outerIndex)
|
|
107
|
-
else
|
|
108
|
-
emit('updateFileList', imageList.value.filter(item => item.status === 'done'))
|
|
109
|
-
},
|
|
110
|
-
})
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
// 删除图片
|
|
114
|
-
function deleteFileFunction(file: any) {
|
|
115
|
-
if (file.id) {
|
|
116
|
-
deleteFile({ ids: [file.id], f_state: '删除' }).then((res: any) => {
|
|
117
|
-
if (res.msg !== undefined) {
|
|
118
|
-
const targetIndex = imageList.value.findIndex(item => item.id === file.id)
|
|
119
|
-
if (targetIndex !== -1) {
|
|
120
|
-
imageList.value.splice(targetIndex, 1)
|
|
121
|
-
if (props.outerIndex !== undefined)
|
|
122
|
-
emit('updateFileList', imageList.value.filter(item => item.status === 'done'), props.outerIndex)
|
|
123
|
-
else
|
|
124
|
-
emit('updateFileList', imageList.value.filter(item => item.status === 'done'))
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
})
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
</script>
|
|
131
|
-
|
|
132
|
-
<template>
|
|
133
|
-
<div class="uploader-container">
|
|
134
|
-
<van-button
|
|
135
|
-
v-if="props.attr?.addOrEdit !== 'readonly'"
|
|
136
|
-
icon="photograph"
|
|
137
|
-
type="primary"
|
|
138
|
-
@click="triggerCamera"
|
|
139
|
-
>
|
|
140
|
-
拍照
|
|
141
|
-
</van-button>
|
|
142
|
-
|
|
143
|
-
<van-uploader
|
|
144
|
-
v-model="imageList"
|
|
145
|
-
:show-upload="false"
|
|
146
|
-
:deletable="props.attr?.addOrEdit !== 'readonly' && props.authority === 'admin'"
|
|
147
|
-
:multiple="props.authority === 'admin'"
|
|
148
|
-
:preview-image="true"
|
|
149
|
-
:before-delete="props.attr?.addOrEdit !== 'readonly' && props.authority === 'admin' ? deleteFileFunction : undefined"
|
|
150
|
-
/>
|
|
151
|
-
</div>
|
|
152
|
-
</template>
|
|
153
|
-
|
|
154
|
-
<style scoped lang="less">
|
|
155
|
-
.uploader-container {
|
|
156
|
-
display: flex;
|
|
157
|
-
flex-direction: column;
|
|
158
|
-
gap: 16px;
|
|
159
|
-
}
|
|
160
|
-
</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
|
+
console.log('>>>> uploader 上传111')
|
|
29
|
+
mobileUtil.execute({
|
|
30
|
+
funcName: 'takePicture',
|
|
31
|
+
param: {},
|
|
32
|
+
callbackFunc: (result: any) => {
|
|
33
|
+
if (result.status === 'success') {
|
|
34
|
+
handlePhotoUpload(result.data)
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
})
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// 处理拍照后的上传
|
|
41
|
+
function handlePhotoUpload(photoData: any) {
|
|
42
|
+
const formData = new FormData()
|
|
43
|
+
formData.append('resUploadMode', props.uploadMode)
|
|
44
|
+
formData.append('pathKey', 'Default')
|
|
45
|
+
formData.append('formType', 'image')
|
|
46
|
+
formData.append('useType', 'Default')
|
|
47
|
+
formData.append('resUploadStock', '1')
|
|
48
|
+
formData.append('filename', photoData.name)
|
|
49
|
+
formData.append('filesize', (photoData.size / 1024 / 1024).toFixed(4))
|
|
50
|
+
formData.append('f_operator', 'server')
|
|
51
|
+
formData.append('imgPath', photoData.filePath)
|
|
52
|
+
formData.append('urlPath', `/api/${import.meta.env.VITE_APP_SYSTEM_NAME}/resource/upload`)
|
|
53
|
+
|
|
54
|
+
// 添加临时预览
|
|
55
|
+
const tempFile = {
|
|
56
|
+
uid: Date.now() + Math.random().toString(36).substr(2, 5),
|
|
57
|
+
name: photoData.name,
|
|
58
|
+
status: 'uploading',
|
|
59
|
+
message: '上传中...',
|
|
60
|
+
url: `data:image/png;base64,${photoData.content}`,
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (!imageList.value) {
|
|
64
|
+
imageList.value = [tempFile]
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
imageList.value.push(tempFile)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const param = {
|
|
71
|
+
resUploadMode: props.uploadMode,
|
|
72
|
+
pathKey: 'Default',
|
|
73
|
+
formType: 'image',
|
|
74
|
+
useType: 'Default',
|
|
75
|
+
resUploadStock: '1',
|
|
76
|
+
filename: photoData.name,
|
|
77
|
+
filesize: photoData.size,
|
|
78
|
+
f_operator: 'server',
|
|
79
|
+
imgPath: photoData.filePath,
|
|
80
|
+
urlPath: `/api/${import.meta.env.VITE_APP_SYSTEM_NAME}/resource/upload`,
|
|
81
|
+
}
|
|
82
|
+
// 上传到服务器
|
|
83
|
+
mobileUtil.execute({
|
|
84
|
+
funcName: 'uploadResource',
|
|
85
|
+
param,
|
|
86
|
+
callbackFunc: (result: any) => {
|
|
87
|
+
if (result.status === 'success') {
|
|
88
|
+
const index = imageList.value.findIndex(item => item.uid === tempFile.uid)
|
|
89
|
+
if (index !== -1) {
|
|
90
|
+
imageList.value[index].uid = result.data.id
|
|
91
|
+
imageList.value[index].id = result.data.id
|
|
92
|
+
delete imageList.value[index].message
|
|
93
|
+
imageList.value[index].status = 'done'
|
|
94
|
+
imageList.value[index].url = result.data.f_downloadpath
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
const index = imageList.value.findIndex(item => item.uid === tempFile.uid)
|
|
99
|
+
if (index !== -1) {
|
|
100
|
+
imageList.value[index].status = 'failed'
|
|
101
|
+
imageList.value[index].message = '上传失败'
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (props.outerIndex !== undefined)
|
|
106
|
+
emit('updateFileList', imageList.value.filter(item => item.status === 'done'), props.outerIndex)
|
|
107
|
+
else
|
|
108
|
+
emit('updateFileList', imageList.value.filter(item => item.status === 'done'))
|
|
109
|
+
},
|
|
110
|
+
})
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// 删除图片
|
|
114
|
+
function deleteFileFunction(file: any) {
|
|
115
|
+
if (file.id) {
|
|
116
|
+
deleteFile({ ids: [file.id], f_state: '删除' }).then((res: any) => {
|
|
117
|
+
if (res.msg !== undefined) {
|
|
118
|
+
const targetIndex = imageList.value.findIndex(item => item.id === file.id)
|
|
119
|
+
if (targetIndex !== -1) {
|
|
120
|
+
imageList.value.splice(targetIndex, 1)
|
|
121
|
+
if (props.outerIndex !== undefined)
|
|
122
|
+
emit('updateFileList', imageList.value.filter(item => item.status === 'done'), props.outerIndex)
|
|
123
|
+
else
|
|
124
|
+
emit('updateFileList', imageList.value.filter(item => item.status === 'done'))
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
})
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
</script>
|
|
131
|
+
|
|
132
|
+
<template>
|
|
133
|
+
<div class="uploader-container">
|
|
134
|
+
<van-button
|
|
135
|
+
v-if="props.attr?.addOrEdit !== 'readonly'"
|
|
136
|
+
icon="photograph"
|
|
137
|
+
type="primary"
|
|
138
|
+
@click="triggerCamera"
|
|
139
|
+
>
|
|
140
|
+
拍照
|
|
141
|
+
</van-button>
|
|
142
|
+
|
|
143
|
+
<van-uploader
|
|
144
|
+
v-model="imageList"
|
|
145
|
+
:show-upload="false"
|
|
146
|
+
:deletable="props.attr?.addOrEdit !== 'readonly' && props.authority === 'admin'"
|
|
147
|
+
:multiple="props.authority === 'admin'"
|
|
148
|
+
:preview-image="true"
|
|
149
|
+
:before-delete="props.attr?.addOrEdit !== 'readonly' && props.authority === 'admin' ? deleteFileFunction : undefined"
|
|
150
|
+
/>
|
|
151
|
+
</div>
|
|
152
|
+
</template>
|
|
153
|
+
|
|
154
|
+
<style scoped lang="less">
|
|
155
|
+
.uploader-container {
|
|
156
|
+
display: flex;
|
|
157
|
+
flex-direction: column;
|
|
158
|
+
gap: 16px;
|
|
159
|
+
}
|
|
160
|
+
</style>
|
|
@@ -351,6 +351,19 @@ function splitArrayAt<T>(array: T[], index: number) {
|
|
|
351
351
|
otherActions.value = array.slice(index)
|
|
352
352
|
}
|
|
353
353
|
|
|
354
|
+
// 新增:动态获取按钮分组
|
|
355
|
+
function getActionGroups(item: any, index: number) {
|
|
356
|
+
// 先过滤出当前行可见的按钮
|
|
357
|
+
const visibleActions = allActions.value.filter(action =>
|
|
358
|
+
evaluateCustomFunction(action.customFunction, item, index),
|
|
359
|
+
)
|
|
360
|
+
// 前3个为主按钮,其余为更多按钮,保持逆序
|
|
361
|
+
return {
|
|
362
|
+
main: visibleActions.slice(0, 3).reverse(),
|
|
363
|
+
more: visibleActions.slice(3).reverse(),
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
|
|
354
367
|
watch(() => searchValue.value, (newVal) => {
|
|
355
368
|
if (newVal === '')
|
|
356
369
|
onRefresh()
|
|
@@ -679,16 +692,16 @@ defineExpose({
|
|
|
679
692
|
<VanRow v-if="allActions.length > 0" gutter="20" class="card_item_bottom">
|
|
680
693
|
<VanCol span="4">
|
|
681
694
|
<VanPopover
|
|
682
|
-
v-if="
|
|
695
|
+
v-if="getActionGroups(item, index).more.length"
|
|
683
696
|
v-model:show="showPopover[index]"
|
|
684
697
|
placement="bottom-start"
|
|
685
|
-
|
|
698
|
+
theme="dark"
|
|
699
|
+
overlay
|
|
700
|
+
:actions="getActionGroups(item, index).more"
|
|
686
701
|
@select="onSelectMenu(item, $event)"
|
|
687
702
|
>
|
|
688
703
|
<template #reference>
|
|
689
|
-
<div
|
|
690
|
-
class="more-button"
|
|
691
|
-
>
|
|
704
|
+
<div class="more-button">
|
|
692
705
|
<span>⋯</span>
|
|
693
706
|
</div>
|
|
694
707
|
</template>
|
|
@@ -698,8 +711,7 @@ defineExpose({
|
|
|
698
711
|
<VanRow justify="end">
|
|
699
712
|
<VanSpace>
|
|
700
713
|
<VanButton
|
|
701
|
-
v-for="button in
|
|
702
|
-
v-show="evaluateCustomFunction(button.customFunction, item, index)"
|
|
714
|
+
v-for="button in getActionGroups(item, index).main"
|
|
703
715
|
:key="button.func"
|
|
704
716
|
type="primary"
|
|
705
717
|
size="small"
|
|
@@ -726,13 +738,16 @@ defineExpose({
|
|
|
726
738
|
|
|
727
739
|
<style scoped lang="less">
|
|
728
740
|
#XCellList {
|
|
729
|
-
height: calc(
|
|
741
|
+
height: calc(100vh - var(--van-nav-bar-height) - 5px);
|
|
742
|
+
display: flex;
|
|
743
|
+
flex-direction: column;
|
|
730
744
|
--van-search-padding: 3px;
|
|
731
745
|
--van-dropdown-menu-title-padding: 3px;
|
|
732
746
|
--van-cell-vertical-padding: 0px;
|
|
733
747
|
.main {
|
|
748
|
+
flex: 1;
|
|
749
|
+
min-height: 0;
|
|
734
750
|
overflow-y: auto;
|
|
735
|
-
height: 100%;
|
|
736
751
|
background-color: var(--van-background);
|
|
737
752
|
padding: var(--van-padding-base) var(--van-padding-sm);
|
|
738
753
|
|