agilebuilder-ui 1.0.71-tmp7 → 1.0.72

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.
@@ -0,0 +1,484 @@
1
+ <template>
2
+ <div>
3
+ <FileUploadComponent
4
+ ref="fileUploadRef"
5
+ :disabled="disabled"
6
+ :systemCode="systemCode"
7
+ :accept="accept"
8
+ :multiple="multiple"
9
+ :limitFileSize="limitFileSize"
10
+ :fileList="fileListResult"
11
+ :beforeRemove="beforeRemove"
12
+ :onRemove="onRemove"
13
+ :beforeDownload="beforeDownload"
14
+ :baseURL="baseURLVal"
15
+ @chooseFile="pickBrowserFiles"
16
+ @remove="removeFile"
17
+ />
18
+ <template v-if="openCameraOrChoosePhoto && openCameraOrChoosePhoto === 'openCamera'">
19
+ <!-- 由于直接打开capture相机属性的设置为空或者不是user/environment其中的任意一项时会打开的本地捕获音频 麦克风-->
20
+ <!-- 所有使用 template 可查看 https://w3c.github.io/html-media-capture/#introduction -->
21
+ <input
22
+ v-if="multiple && !disabled"
23
+ ref="fileRef"
24
+ type="file"
25
+ multiple="multiple"
26
+ :capture="'environment'"
27
+ name="file"
28
+ :accept="myAccept"
29
+ style="display: none"
30
+ @change="uploadFiles"
31
+ />
32
+ <input
33
+ v-else-if="!disabled"
34
+ ref="fileRef"
35
+ type="file"
36
+ :capture="'environment'"
37
+ name="file"
38
+ style="display: none"
39
+ :accept="myAccept"
40
+ @change="uploadFiles"
41
+ />
42
+ </template>
43
+ <template v-else>
44
+ <input
45
+ v-if="multiple && !disabled"
46
+ ref="fileRef"
47
+ type="file"
48
+ multiple="multiple"
49
+ name="file"
50
+ :accept="myAccept"
51
+ style="display: none"
52
+ @change="uploadFiles"
53
+ />
54
+ <input
55
+ v-else-if="!disabled"
56
+ ref="fileRef"
57
+ type="file"
58
+ name="file"
59
+ style="display: none"
60
+ :accept="myAccept"
61
+ @change="uploadFiles"
62
+ />
63
+ </template>
64
+ <el-drawer v-model="fileTypeFlag" direction="btt" @close="fileTypeFlag = false">
65
+ <div><el-button
66
+ link
67
+ @click="confirmFileType('image')"
68
+ >
69
+ {{ $t('fsUpload.image') }}
70
+ </el-button></div>
71
+ <div>
72
+ <el-button
73
+ link
74
+ @click="confirmFileType('video')"
75
+ >
76
+ {{ $t('fsUpload.video') }}
77
+ </el-button></div>
78
+ </el-drawer>
79
+ </div>
80
+ </template>
81
+
82
+ <script lang="ts" setup>
83
+ import { ref, defineEmits } from 'vue'
84
+ import { getSystemFrontendUrl, getReplaceUrlDomain, formatFileName } from '../../../../src/utils/common-util'
85
+ import { getToken, getCookieCache } from '../../../../src/utils/auth.js' // 获得token
86
+ import Compressor from 'compressorjs'
87
+ import { ElMessage } from 'element-plus'
88
+ import { useI18n } from 'vue-i18n'
89
+ import FileUploadComponent from './file-upload-component.vue'
90
+
91
+ const props = defineProps({
92
+ openFsUpload: {
93
+ type: Object,
94
+ default: true
95
+ },
96
+ entity: {
97
+ type: Object,
98
+ default: () => {
99
+ return null
100
+ }
101
+ },
102
+ fileInfo: {
103
+ type: Object,
104
+ default: () => ({})
105
+ },
106
+ systemCode: {
107
+ type: String,
108
+ default: ''
109
+ },
110
+ displayType: {
111
+ type: String,
112
+ default: 'input'
113
+ },
114
+ // 是否禁止编辑,为true只能下载,不能删除和上传
115
+ disabled: {
116
+ type: Boolean,
117
+ default: false
118
+ },
119
+ accept: {
120
+ type: String,
121
+ default: ''
122
+ },
123
+ multiple: {
124
+ type: Boolean,
125
+ default: false
126
+ },
127
+ limit: {
128
+ type: Number,
129
+ default: 1
130
+ },
131
+ // 文件大小限制,单位是M,默认是30M
132
+ limitFileSize: {
133
+ type: Number,
134
+ default: 30
135
+ },
136
+ placeholder: {
137
+ type: String,
138
+ default: '拖拽文件 或 点击上传'
139
+ },
140
+ action: {
141
+ type: String,
142
+ default: ''
143
+ },
144
+ headers: {
145
+ type: Object,
146
+ default: () => ({ Authorization: null })
147
+ },
148
+ // 已上传文件列表
149
+ fileList: {
150
+ type: Array,
151
+ default: () => []
152
+ },
153
+ onSuccess: {
154
+ type: Function,
155
+ default: () => {}
156
+ },
157
+ beforeRemove: {
158
+ type: Function,
159
+ default: () => {}
160
+ },
161
+ onRemove: {
162
+ type: Function,
163
+ default: () => {}
164
+ },
165
+ beforeDownload: {
166
+ type: Function,
167
+ default: () => {}
168
+ },
169
+ pageContext: {
170
+ type: Object,
171
+ default: () => ({})
172
+ },
173
+ configure: {
174
+ type: Object,
175
+ default: () => ({})
176
+ },
177
+ // 组件id,在表单或列表中应该唯一,一般传字段名即可
178
+ componentId: {
179
+ type: String,
180
+ default: function () {
181
+ return 'file-upload'
182
+ }
183
+ },
184
+ // 组件名称,一般是字段label
185
+ componentName: {
186
+ type: String,
187
+ default: function () {
188
+ return 'file-upload'
189
+ }
190
+ },
191
+ options: {
192
+ type: Object,
193
+ default: null
194
+ },
195
+ // 列表编码
196
+ listCode: {
197
+ type: String,
198
+ default: null
199
+ },
200
+ // 打开相机和相册选项,默认是都可以打开
201
+ openCameraOrChoosePhoto: {
202
+ type: String,
203
+ default: 'openCameraAndChoosePhoto'
204
+ },
205
+ beforeUpload: {
206
+ type: Function,
207
+ default: () => {}
208
+ }
209
+ })
210
+
211
+ const fileListResult = ref(props.fileList)
212
+
213
+ let baseURL = window.$vueApp.config.globalProperties.baseURL
214
+ if (props.options) {
215
+ baseURL = props.options.backendUrl
216
+ }
217
+ if (!baseURL) {
218
+ baseURL = window.$vueApp.config.globalProperties.baseURL
219
+ }
220
+ const baseURLVal = ref(baseURL)
221
+
222
+ const baseAPI = window.$vueApp.config.globalProperties.baseAPI
223
+ const defaultAction = ref<string>('')
224
+
225
+ if (props.action) {
226
+ defaultAction.value = props.action
227
+ } else {
228
+ let tempAction = baseAPI + '/component/super-form/uploads'
229
+ if (props.multiple) {
230
+ tempAction = baseAPI + '/component/super-form/batch-uploads'
231
+ }
232
+ defaultAction.value = tempAction
233
+ }
234
+
235
+ defaultAction.value = getReplaceUrlDomain(defaultAction.value)
236
+
237
+ let myAccept = ref(props.accept ? props.accept : '')
238
+ let tempFileList = ref([])
239
+ let isUploading = ref(false)
240
+ let isFile = ref(false)
241
+ const fileRef = ref(null)
242
+ const fileTypeFlag = ref(false)
243
+ const emits = defineEmits(['remove', 'uploadend'])
244
+ const { t } = useI18n()
245
+ const fileUploadRef = ref(null)
246
+
247
+ function isImg(file) {
248
+ const fileName = file.name
249
+ if (fileName) {
250
+ return (
251
+ fileName.indexOf('jpg') !== -1 ||
252
+ fileName.indexOf('JPG') !== -1 ||
253
+ fileName.indexOf('png') !== -1 ||
254
+ fileName.indexOf('PNG') !== -1
255
+ )
256
+ }
257
+ return false
258
+ }
259
+
260
+ function removeFile(param) {
261
+ console.log('removeFile----param=', param)
262
+ const file = param.file
263
+ if(file){
264
+ emits('remove', { rmFiles: [file], serverFiles: fileListResult.value, index: param.index })
265
+ }
266
+ }
267
+ function pickBrowserFiles() {
268
+ if (props.openCameraOrChoosePhoto && props.openCameraOrChoosePhoto === 'openCamera') {
269
+ // 只打开相机
270
+ myAccept.value = 'image/*'
271
+ setTimeout(() => {
272
+ fileRef.value.click()
273
+ })
274
+ } else {
275
+ // 相机和文件都可以选
276
+ myAccept.value = '*'
277
+ fileTypeFlag.value = true
278
+ }
279
+ }
280
+
281
+ function confirmFileType(fileType: string) {
282
+ myAccept.value = ''
283
+ if (fileType && fileType === 'image') {
284
+ myAccept.value = 'image/*'
285
+ } else if (fileType && fileType === 'video') {
286
+ myAccept.value = 'video/*'
287
+ }
288
+ setTimeout(() => {
289
+ fileTypeFlag.value = false
290
+ fileRef.value.click()
291
+ })
292
+
293
+ console.log('Action chosen:', fileType)
294
+ }
295
+
296
+ async function uploadBrowserFile() {
297
+ const param = new FormData()
298
+ const fileNames = []
299
+ const selectFiles = []
300
+ let limitFileSize = props.limitFileSize
301
+ if (limitFileSize === undefined) {
302
+ // 默认是30M
303
+ limitFileSize = 30
304
+ }
305
+ let isCanUpload = false
306
+ const files = fileRef.value.files
307
+ for (let i = 0; i < files.length; i++) {
308
+ const newFile = files[i]
309
+ isCanUpload = validateCanUploadFile(newFile, limitFileSize)
310
+ if (isCanUpload) {
311
+ fileNames.push(newFile.name)
312
+ } else {
313
+ break
314
+ }
315
+ }
316
+ console.error('isCanUpload=', isCanUpload)
317
+ if (isCanUpload) {
318
+ for (let i = 0; i < files.length; i++) {
319
+ const fileObj = files[i]
320
+ console.error('fileObj.name=', fileObj.name, 'fileNames=', fileNames)
321
+ if (fileNames.indexOf(fileObj.name) >= 0) {
322
+ selectFiles.push(fileObj)
323
+ }
324
+ if (props.beforeUpload && typeof props.beforeUpload === 'function') {
325
+ const isMobile = true
326
+ // eslint-disable-next-line no-useless-call
327
+ isCanUpload = props.beforeUpload({fileObj, files:selectFiles, isMobile, pageContext: props.pageContext, configureObj: props.configure})
328
+ }
329
+ }
330
+ }
331
+ if (isCanUpload !== undefined && !isCanUpload) {
332
+ // 不能提交文件
333
+ return
334
+ }
335
+ if (!selectFiles || selectFiles.length === 0) {
336
+ console.error('未选择任何文件')
337
+ return
338
+ }
339
+ let uploadFiles = []
340
+ try {
341
+ uploadFiles = await compressionImg(selectFiles)
342
+ } catch (error) {
343
+ console.error('压缩图片失败', error)
344
+ uploadFiles = selectFiles
345
+ }
346
+ if (props.multiple) {
347
+ for (let i = 0; i < uploadFiles.length; i++) {
348
+ // param.append('files['+i+']', uploadFiles[i])
349
+ param.append('files', uploadFiles[i])
350
+ // param.append('files[]', uploadFiles[i])
351
+ }
352
+ // param.append('files', uploadFiles)
353
+ // 批量上传接口有这个参数,单文件上传没有该参数
354
+ param.append('limitFileSize', limitFileSize)
355
+ } else {
356
+ param.append('file', uploadFiles[0])
357
+ }
358
+ param.append('systemCode', props.systemCode)
359
+
360
+ console.log('上传文件111-----defaultAction.value=',defaultAction.value, 'param=', param, 'uploadFiles=', uploadFiles)
361
+ window.$vueApp.config.globalProperties.$http
362
+ .post(defaultAction.value, param, { headers: { 'Content-Type': 'multipart/form-data', Authorization: getToken() } })
363
+ .then((result) => {
364
+ // result:批量上传时返回的是集合,单选上传时返回的是对象
365
+ console.log('上传后返回值==result=', result)
366
+ if (result) {
367
+ if (props.multiple) {
368
+ if (result.length > 0) {
369
+ // this.tempFileList.push(...result)
370
+ uploadComplete(result)
371
+ } else {
372
+ console.error('多选时上传后返回值异常')
373
+ }
374
+ } else {
375
+ // this.tempFileList.push(result)
376
+ uploadComplete(result)
377
+ }
378
+ } else {
379
+ console.error('上传后返回值异常')
380
+ }
381
+ })
382
+ .catch(() => {
383
+ isUploading.value = false
384
+ })
385
+ }
386
+ function validateCanUploadFile(file, limitFileSize) {
387
+ let isCanUpload = true
388
+ console.log('上传文件--验证文件大小--file.size=', file.size, '文件线状大小,单位是M,limitFileSize=', limitFileSize)
389
+ if (file.size > limitFileSize * 1024 * 1024) {
390
+ // 超过最大限制
391
+ ElMessage({
392
+ showClose: true,
393
+ type: 'warning',
394
+ message: t('fileUpload.exceedFileSize', { fileName: file.name, fileSize: limitFileSize })
395
+ })
396
+ // 返回false停止上传
397
+ isCanUpload = false
398
+ }
399
+ return isCanUpload
400
+ }
401
+ // 所有文件上传完毕后
402
+ function uploadComplete(result) {
403
+ console.log('uploadComplete=开始')
404
+ if(!fileListResult.value){
405
+ fileListResult.value = []
406
+ }
407
+ if (props.multiple) {
408
+ console.log(
409
+ 'uploadComplete====fileListResult.value111=',
410
+ JSON.stringify(fileListResult.value),
411
+ 'result=',
412
+ result
413
+ )
414
+ fileListResult.value = fileListResult.value.concat(result)
415
+ console.log('uploadComplete====fileListResult.value222=', fileListResult.value)
416
+ } else {
417
+ // 单选时将已选文件移除,然后再替换为新上传的文件
418
+ console.log('uploadComplete====fileListResult.value333=', JSON.stringify(fileListResult.value))
419
+ const rmFiles = JSON.parse(JSON.stringify(fileListResult.value))
420
+ fileListResult.value.push(result)
421
+ emits('remove', { rmFiles, serverFiles: fileListResult.value, index: 0 })
422
+ console.log('uploadComplete====fileListResult.value444=', fileListResult.value)
423
+ }
424
+ console.log('uploadComplete====fileListResult.value555=', fileListResult.value)
425
+
426
+ fileRef.value.value = null
427
+ isUploading.value = false
428
+ fileUploadRef.value.changeFileList(fileListResult.value)
429
+ // 表示上传完成
430
+ emits('uploadend', fileListResult.value)
431
+ console.log('uploadComplete====上传完成=')
432
+ }
433
+ function uploadFiles() {
434
+ uploadBrowserFiles()
435
+ }
436
+ function uploadBrowserFiles() {
437
+ console.log('uploadBrowserFiles=====上传开始=')
438
+ const files = fileRef.value.files
439
+ if (files && files.length > 0) {
440
+ isUploading.value = true
441
+ uploadBrowserFile()
442
+ } else {
443
+ uploadNoNewFiles()
444
+ }
445
+ }
446
+
447
+ // 文件上传时,无需要走后台上传时的处理
448
+ function uploadNoNewFiles() {
449
+ fileRef.value.value = null
450
+
451
+ // 表示上传完成
452
+ emits('uploadend', fileListResult.value)
453
+ }
454
+
455
+ function compressionImg(selectFiles) {
456
+ const uploadFilesPromises = []
457
+ for (let i = 0; i < selectFiles.length; i++) {
458
+ uploadFilesPromises.push(
459
+ new Promise((resolve, reject) => {
460
+ console.log(`压缩前 size ${selectFiles[i].size / 1024 / 1024} MB`)
461
+ // eslint-disable-next-line no-new
462
+ new Compressor(selectFiles[i], {
463
+ quality: 0.7,
464
+ success(result) {
465
+ console.log(`压缩后 size ${result.size / 1024 / 1024} MB`)
466
+ resolve(
467
+ new File([result], selectFiles[i].name, {
468
+ type: result.type,
469
+ lastModified: Date.now()
470
+ })
471
+ )
472
+ },
473
+ error(err) {
474
+ reject(err)
475
+ }
476
+ })
477
+ })
478
+ )
479
+ }
480
+ return Promise.all(uploadFilesPromises)
481
+ }
482
+ </script>
483
+
484
+ <style lang="scss" scoped></style>
@@ -0,0 +1,127 @@
1
+ <template>
2
+ <el-upload action="#" list-type="picture-card" :file-list="fileListResult" :auto-upload="false" :disabled="true">
3
+ <template #tip>
4
+ <el-text size="small" style="padding: 10px;font-weight: 600"> {{ accept }} {{limitFileSize?$t('imatrixUIMessage.uploadFileTip',{fileSize: limitFileSize}): ''}}</el-text>
5
+ </template>
6
+ <template #trigger>
7
+ <el-icon @click="chooseFile"><Plus /></el-icon>
8
+ </template>
9
+
10
+ <template #file="{ file }">
11
+ <div style="width: 100%;" >
12
+ <div v-if="!isImg(file)" class="el-upload-list__item-thumbnail" >
13
+ <div class="file-name-container" >
14
+ {{file.name}}
15
+ </div></div>
16
+ <img v-else class="el-upload-list__item-thumbnail" :src="getPreviewSrc(file.name, file.serverPath)" alt="" />
17
+ <fs-preview-new :disabled="disabled" :file-list="fileListResult" :file="file" :system-code="systemCode" :before-remove="beforeRemove" :on-remove="onRemove" :before-download="beforeDownload" @remove="removeFile"/>
18
+
19
+ </div>
20
+ </template>
21
+ </el-upload>
22
+ </template>
23
+
24
+ <script lang="ts" setup>
25
+ import { ref,defineEmits } from 'vue'
26
+ import { Plus } from '@element-plus/icons-vue'
27
+ import fsPreviewNew from '../fs-preview-new.vue'
28
+
29
+ import { isImage } from '../../../../src/utils/util'
30
+ import { getToken } from '../../../../src/utils/auth'
31
+ import { getReplaceUrlDomain, isPlateSys } from '../../../../src/utils/common-util'
32
+
33
+ const props = defineProps({
34
+ systemCode: {
35
+ type: String,
36
+ default: ''
37
+ },
38
+ disabled: {
39
+ type: Boolean,
40
+ default: false
41
+ },
42
+ fileList: {
43
+ type: Array<{ showName: string; serverPath: string }>,
44
+ default: () => []
45
+ },
46
+ beforeRemove: {
47
+ type: Function,
48
+ default: () => {}
49
+ },
50
+ onRemove: {
51
+ type: Function,
52
+ default: () => {}
53
+ },
54
+ beforeDownload: {
55
+ type: Function,
56
+ default: () => {}
57
+ },
58
+ accept: {
59
+ type: String,
60
+ default: ''
61
+ },
62
+ limitFileSize: {
63
+ type: Number,
64
+ default: 30
65
+ },
66
+ baseURL: {
67
+ type: String,
68
+ default: ''
69
+ }
70
+ })
71
+
72
+ //拖动定义的方法
73
+ const emits = defineEmits(['chooseFile', 'remove']);
74
+
75
+ const dialogImageUrl = ref('')
76
+ const dialogVisible = ref(false)
77
+ const disabled = ref(false)
78
+
79
+ let baseURL = props.baseURL
80
+
81
+ const baseAPI = window.$vueApp.config.globalProperties.baseAPI
82
+
83
+ const fileListResult = ref(props.fileList)
84
+ console.log('file-upload-component---fileListResult=', fileListResult.value)
85
+ function changeFileList(fileList: any) {
86
+ fileListResult.value = fileList
87
+ }
88
+ const chooseFile = ()=>{
89
+ console.log('点击选择文件按钮---')
90
+ emits('chooseFile')
91
+ }
92
+ const isImg = (file: Object) =>{
93
+ return isImage(file.name)
94
+ }
95
+
96
+ function getPreviewSrc(showName: string, serverPath: string) {
97
+ showName = formatName(showName)
98
+ const token = getToken()
99
+ let url = baseURL + '/common/super-form/downloads?jwt=' + token
100
+ if (isPlateSys(props.systemCode)) {
101
+ url = baseAPI + '/component/super-form/downloads?jwt=' + token
102
+ }
103
+ url = getReplaceUrlDomain(url)
104
+ return url + '&showName=' + encodeURI(showName) + '&serverPath=' + serverPath
105
+ }
106
+ const formatName = (showName: string) => {
107
+ if (showName) {
108
+ showName = showName.replace('#', '~~').replace('?', '~$').replace('&', '$')
109
+ }
110
+ return showName
111
+ }
112
+
113
+ function removeFile(param){
114
+ emits('remove', param)
115
+ }
116
+
117
+ defineExpose({changeFileList})
118
+
119
+ </script>
120
+ <style scoped>
121
+ .file-name-container {
122
+ display: flex;
123
+ align-items: center; /* 垂直居中 */
124
+ justify-content: center; /* 水平居中,如需要 */
125
+ height: 100px; /* 容器高度 */
126
+ }
127
+ </style>