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 CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "af-mobile-client-vue3",
3
3
  "type": "module",
4
- "version": "1.1.36",
4
+ "version": "1.1.38",
5
5
  "description": "Vue + Vite component lib",
6
6
  "license": "MIT",
7
7
  "engines": {
@@ -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="otherActions && otherActions.length !== 0 && otherActions.some(action => evaluateCustomFunction(action.customFunction, item, index))"
695
+ v-if="getActionGroups(item, index).more.length"
683
696
  v-model:show="showPopover[index]"
684
697
  placement="bottom-start"
685
- :actions="otherActions.filter(action => evaluateCustomFunction(action.customFunction, item, index))"
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 reversedMainActions"
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(94vh - var(--van-nav-bar-height) - 5px);
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