af-mobile-client-vue3 1.3.50 → 1.3.51

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.3.50",
4
+ "version": "1.3.51",
5
5
  "packageManager": "pnpm@10.13.1",
6
6
  "description": "Vue + Vite component lib",
7
7
  "engines": {
@@ -1,6 +1,6 @@
1
1
  <script setup lang="ts">
2
2
  import cameraIcon from '@af-mobile-client-vue3/assets/img/component/camera.png'
3
- import { deleteFile } from '@af-mobile-client-vue3/services/api/common'
3
+ import { deleteFile, upload } from '@af-mobile-client-vue3/services/api/common'
4
4
  import { mobileUtil } from '@af-mobile-client-vue3/utils/mobileUtil'
5
5
  import {
6
6
  ActionSheet,
@@ -20,6 +20,103 @@ const emit = defineEmits(['updateFileList', 'updateAllFileList'])
20
20
 
21
21
  const imageList = ref<Array<any>>(props.imageList ?? [])
22
22
 
23
+ // 浏览器模式:隐藏的文件输入(选择 / 拍照)
24
+ const fileInputRef = ref<HTMLInputElement | undefined>()
25
+ const cameraInputRef = ref<HTMLInputElement | undefined>()
26
+
27
+ function openBrowserFilePicker() {
28
+ if (fileInputRef.value) {
29
+ fileInputRef.value.value = ''
30
+ fileInputRef.value.click()
31
+ }
32
+ }
33
+
34
+ function openBrowserCameraPicker() {
35
+ if (cameraInputRef.value) {
36
+ cameraInputRef.value.value = ''
37
+ cameraInputRef.value.click()
38
+ }
39
+ }
40
+
41
+ function emitUpdatesAfterChange() {
42
+ // 新增:对外抛出完整与ID列表
43
+ (emit as any)('updateAllFileList', imageList.value.filter(item => item.status === 'done').map(item => item))
44
+ const doneIds = Object.values(imageList.value)
45
+ .filter(item => item.status === 'done')
46
+ .map(item => item.id)
47
+ if (props.outerIndex !== undefined) {
48
+ (emit as any)('updateFileList', doneIds, props.outerIndex)
49
+ }
50
+ else {
51
+ (emit as any)('updateFileList', doneIds)
52
+ }
53
+ }
54
+
55
+ function createTempUploadingItem(name: string, previewUrl: string) {
56
+ const temp = {
57
+ uid: Date.now() + Math.random().toString(36).substr(2, 5),
58
+ name,
59
+ status: 'uploading',
60
+ message: '上传中...',
61
+ url: previewUrl,
62
+ }
63
+ if (!imageList.value)
64
+ imageList.value = [temp]
65
+ else imageList.value.push(temp)
66
+ return temp
67
+ }
68
+
69
+ function uploadFileViaHttp(file: File, previewUrl: string, temp: any) {
70
+ const formData = new FormData()
71
+ formData.append('avatar', file)
72
+ formData.append('resUploadMode', props.uploadMode)
73
+ formData.append('pathKey', 'Default')
74
+ formData.append('formType', 'image')
75
+ formData.append('useType', 'Default')
76
+ formData.append('resUploadStock', '1')
77
+ formData.append('filename', file.name)
78
+ formData.append('filesize', (file.size / 1024 / 1024).toFixed(4))
79
+ formData.append('f_operator', 'server')
80
+
81
+ upload(formData, import.meta.env.VITE_APP_SYSTEM_NAME, { 'Content-Type': 'multipart/form-data' }).then((res: any) => {
82
+ const index = imageList.value.findIndex(item => item.uid === temp.uid)
83
+ if (res?.data?.id) {
84
+ if (index !== -1) {
85
+ imageList.value[index].uid = res.data.id
86
+ imageList.value[index].id = res.data.id
87
+ delete imageList.value[index].message
88
+ imageList.value[index].status = 'done'
89
+ imageList.value[index].url = res.data.f_downloadpath
90
+ }
91
+ }
92
+ else {
93
+ if (index !== -1) {
94
+ imageList.value[index].status = 'failed'
95
+ imageList.value[index].message = '上传失败'
96
+ }
97
+ }
98
+ emitUpdatesAfterChange()
99
+ })
100
+ }
101
+
102
+ function handleBrowserFiles(files: FileList | null) {
103
+ if (!files || files.length === 0)
104
+ return
105
+ const max = props.attr?.acceptCount ?? Number.POSITIVE_INFINITY
106
+ for (let i = 0; i < files.length; i++) {
107
+ if (imageList.value.length >= max)
108
+ break
109
+ const file = files[i]
110
+ const reader = new FileReader()
111
+ reader.onload = (e: any) => {
112
+ const previewUrl = e.target?.result as string
113
+ const temp = createTempUploadingItem(file.name, previewUrl)
114
+ uploadFileViaHttp(file, previewUrl, temp)
115
+ }
116
+ reader.readAsDataURL(file)
117
+ }
118
+ }
119
+
23
120
  // 触发拍照
24
121
  function triggerCamera() {
25
122
  mobileUtil.execute({
@@ -29,6 +126,10 @@ function triggerCamera() {
29
126
  if (result.status === 'success') {
30
127
  handlePhotoUpload(result.data)
31
128
  }
129
+ else {
130
+ // 浏览器模式:调起相机输入
131
+ openBrowserCameraPicker()
132
+ }
32
133
  },
33
134
  })
34
135
  }
@@ -185,6 +286,10 @@ function handleActionSelect(option: any) {
185
286
  handlePhotoUpload(photo)
186
287
  })
187
288
  }
289
+ else {
290
+ // 浏览器模式:打开文件选择
291
+ openBrowserFilePicker()
292
+ }
188
293
  },
189
294
  })
190
295
  }
@@ -193,6 +298,24 @@ function handleActionSelect(option: any) {
193
298
 
194
299
  <template>
195
300
  <div class="uploader-container">
301
+ <!-- 浏览器模式隐藏输入:文件选择 -->
302
+ <input
303
+ ref="fileInputRef"
304
+ type="file"
305
+ multiple
306
+ accept="image/*"
307
+ style="display:none"
308
+ @change="(e:any) => handleBrowserFiles(e.target.files)"
309
+ >
310
+ <!-- 浏览器模式隐藏输入:拍照(相机) -->
311
+ <input
312
+ ref="cameraInputRef"
313
+ type="file"
314
+ accept="image/*"
315
+ capture="environment"
316
+ style="display:none"
317
+ @change="(e:any) => handleBrowserFiles(e.target.files)"
318
+ >
196
319
  <div
197
320
  v-if="props.mode !== '预览' && (imageList.length < props.attr?.acceptCount && props.attr?.addOrEdit !== 'readonly')"
198
321
  class="custom-upload-area"
@@ -3,10 +3,13 @@ import XForm from '@af-mobile-client-vue3/components/data/XForm/index.vue'
3
3
  import NormalDataLayout from '@af-mobile-client-vue3/components/layout/NormalDataLayout/index.vue'
4
4
  import { ref } from 'vue'
5
5
 
6
- const configName = ref('AddConstructionForm')
7
- const serviceName = ref('af-linepatrol')
6
+ const configName = ref('sealCheckInForm')
7
+ const serviceName = ref('af-safecheck')
8
8
 
9
9
  const formGroupAddConstruction = ref(null)
10
+ function submit(s) {
11
+ console.log('>>>> ss: ', JSON.stringify(s))
12
+ }
10
13
  </script>
11
14
 
12
15
  <template>
@@ -17,6 +20,7 @@ const formGroupAddConstruction = ref(null)
17
20
  mode="新增"
18
21
  :config-name="configName"
19
22
  :service-name="serviceName"
23
+ @on-submit="submit"
20
24
  />
21
25
  </template>
22
26
  </NormalDataLayout>