adtec-core-package 2.8.1 → 2.8.3

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,6 +1,6 @@
1
1
  {
2
2
  "name": "adtec-core-package",
3
- "version": "2.8.1",
3
+ "version": "2.8.3",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "scripts": {
@@ -23,5 +23,8 @@ export default {
23
23
  },
24
24
  fileStatusConfirmation(ids: string[]): Promise<ISysUploadFiles[]> {
25
25
  return request.post(basePath + 'fileStatusConfirmation', ids)
26
+ },
27
+ delSysUploadFiles(ids: string[]): Promise<Record<string, string>> {
28
+ return request.post(basePath + 'delSysUploadFiles', ids)
26
29
  }
27
30
  }
@@ -0,0 +1,478 @@
1
+ <!--创建人 丁盼-->
2
+ <!--说明: 文档上传组件-->
3
+ <!--创建时间: 2024/12/2 下午1:59-->
4
+ <!--修改时间: 2024/12/2 下午1:59-->
5
+ <template>
6
+ <div v-if="!isEdit">
7
+ <el-auto-tool-tip v-if="uploadFilesList?.length">
8
+ <template #tooltipContent>
9
+ <div style="display:flex;flex-direction:column">
10
+ <span
11
+ v-for="item in uploadFilesList"
12
+ :key="item.id"
13
+ style="margin: 0 2px"
14
+ >{{ item.name }}
15
+ </span>
16
+ </div>
17
+ </template>
18
+ <template #content>
19
+ <div style="display:flex;flex-direction:column">
20
+ <div v-for="item in uploadFilesList" :key="item.id"
21
+ class="file-item"
22
+ style="display:flex; align-items:center;overflow: hidden">
23
+ <el-icons :model-value="getIcon(item.name)" style="margin-right: 5px"></el-icons>
24
+ <span class="link-name" @click="fileView(item.id)">{{ item.name }}</span>
25
+ </div>
26
+ </div>
27
+ </template>
28
+ </el-auto-tool-tip>
29
+ <div style="text-align: center;color: var(--el-disabled-text-color)" v-else>
30
+ 暂无附件
31
+ </div>
32
+ </div>
33
+ <el-upload
34
+ v-else
35
+ ref="ref_upload"
36
+ :file-list="uploadFilesList"
37
+ @success="success"
38
+ @remove="remove"
39
+ @preview="preview"
40
+ :auto-upload="autoUpload"
41
+ @error="error"
42
+ v-loading="loading"
43
+ @exceed="exceed"
44
+ @progress="progress"
45
+ :before-upload="beforeUpload"
46
+ drag
47
+ :accept="getAccept"
48
+ :action="'/api/doc/uploadFile/' + business + '/' + businessId + '/' + association"
49
+ multiple
50
+ :limit="limit"
51
+ :headers="uploadHeaders"
52
+ >
53
+ <el-icon class="el-icon--upload">
54
+ <upload-filled />
55
+ </el-icon>
56
+ <div class="el-upload__text">拖动文件或<em>点击上传</em></div>
57
+ <div class="el-upload__tip">最大上传文件大小{{ size }}MB</div>
58
+ <template #file="{ file }">
59
+ <el-flex
60
+ class="file-class"
61
+ @mousemove="mousemove(file.name)"
62
+ @mouseout="mouseout"
63
+ @click="preview(file)"
64
+ height="20px"
65
+ :width="itemWidth"
66
+ >
67
+ <el-flex align="center" justify="flex-start" style="overflow: hidden">
68
+ <el-tooltip class="box-item" :content="file.name" placement="top">
69
+ <el-text truncated style="cursor: pointer">
70
+ <el-icons :model-value="getIcon(file.name)" style="margin-right: 5px"></el-icons>
71
+ {{ file.name }}
72
+ </el-text>
73
+ </el-tooltip>
74
+ </el-flex>
75
+ <el-flex align="center" justify="flex-end" width="50px">
76
+ <el-text v-if="!file?.businessId && file.percentage !== 100"
77
+ >{{ file.percentage }}%
78
+ </el-text>
79
+ <el-icons
80
+ v-if="file?.businessId || file.percentage === 100"
81
+ @click.prevent.stop="fileClick(file)"
82
+ :model-value="file.name === hoverfileName ? 'adtec-close' : 'adtec-success'"
83
+ style="color: var(--el-color-success); font-size: 14px"
84
+ :style="{
85
+ color:
86
+ file.name === hoverfileName ? 'var(--el-color-danger)' : 'var(--el-color-success)',
87
+ }"
88
+ ></el-icons>
89
+ </el-flex>
90
+ </el-flex>
91
+ </template>
92
+ </el-upload>
93
+ </template>
94
+
95
+ <script setup lang="ts">
96
+ import { UploadFilled } from '@element-plus/icons-vue'
97
+ import { computed, onMounted, ref } from 'vue'
98
+ import { ElMessage, ElMessageBox, type UploadFile, type UploadFiles, type UploadUserFile } from 'element-plus'
99
+ import type { ISysUploadFiles } from '../../interface/ISysUploadFiles'
100
+ //@ts-ignore
101
+ import useFileView from '../../hooks/useFileView.ts'
102
+ import documentApi from '../../api/DocumentApi.ts'
103
+ import frameworkUtils from '../../utils/FrameworkUtils.ts'
104
+ import { userInfoStore } from '../../stores/userInfoStore'
105
+
106
+ const { fileView: fileView } = useFileView()
107
+ const uploadHeaders = ref({
108
+ Authorization: ''
109
+ })
110
+ const emit = defineEmits(['success'])
111
+ const userInfo = userInfoStore()
112
+ const ref_upload = ref()
113
+ const deleteFiles = ref<ISysUploadFiles[]>([])
114
+ const hoverfileName = ref('')
115
+ const props = defineProps({
116
+ /**
117
+ * @description 上传文件数量
118
+ * @default 1
119
+ */
120
+ limit: {
121
+ type: Number,
122
+ default: 1
123
+ },
124
+ /**
125
+ * @description 纵向排列
126
+ * @default false
127
+ */
128
+ vertical: {
129
+ type: Boolean,
130
+ default: false
131
+ },
132
+ /**
133
+ * @description 上传文件类型
134
+ * @default ''
135
+ * @type {'images'|'document'|'txt'|'pdf'|'word'|'excel'|'ppt'}
136
+ */
137
+ accept: {
138
+ type: String,
139
+ default: ''
140
+ },
141
+ /**
142
+ * @description 业务类型
143
+ * @default 'default'
144
+ */
145
+ business: {
146
+ type: String,
147
+ default: 'default'
148
+ },
149
+ /**
150
+ * @description 业务id
151
+ * @default ''
152
+ */
153
+ businessId: {
154
+ type: String,
155
+ default: 'default'
156
+ },
157
+ /**
158
+ * 文件列表
159
+ */
160
+ uploadFilesList: {
161
+ type: Array<ISysUploadFiles>,
162
+ default: () => []
163
+ },
164
+ /**
165
+ * @description 是否编辑状态
166
+ * @default 'true'
167
+ * @type {true|false}
168
+ */
169
+ isEdit: {
170
+ type: Boolean,
171
+ default: true
172
+ },
173
+ /**
174
+ * @description 文档上传是否默认关联,默认不关联
175
+ * @default 'false'
176
+ * @type {true|false}
177
+ */
178
+ association: {
179
+ type: Boolean,
180
+ default: false
181
+ },
182
+ size: {
183
+ type: Number,
184
+ default: 50
185
+ },
186
+ //附件宽度
187
+ itemWidth: {
188
+ type: String,
189
+ default: '100%'
190
+ },
191
+ isConfirmDelete: {
192
+ type: Boolean,
193
+ default: true
194
+ },
195
+ overwrite: {
196
+ type: Boolean,
197
+ default: true
198
+ },
199
+ autoUpload: {
200
+ type: Boolean,
201
+ default: true
202
+ },
203
+ showOptMessage: {
204
+ type:Boolean,
205
+ default:true
206
+ }
207
+ })
208
+ const mousemove = (fileName: string) => {
209
+ hoverfileName.value = fileName
210
+ }
211
+ const mouseout = () => {
212
+ hoverfileName.value = ''
213
+ }
214
+ const getAccept = computed(() => {
215
+ if (props.accept === 'images') {
216
+ return '.jpg,.jpeg,.png,.gif,.bmp'
217
+ } else if (props.accept === 'document') {
218
+ return '.txt,.pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx'
219
+ } else if (props.accept === 'txt') {
220
+ return '.txt'
221
+ } else if (props.accept === 'pdf') {
222
+ return '.pdf' // 正确配置,仅允许 pdf
223
+ } else if (props.accept === 'word') {
224
+ return '.doc,.docx'
225
+ } else if (props.accept === 'excel') {
226
+ return '.xls,.xlsx'
227
+ } else if (props.accept === 'ppt') {
228
+ return '.ppt,.pptx'
229
+ } else {
230
+ return undefined
231
+ }
232
+ })
233
+ const getIcon = (fileName: string) => {
234
+ const type: string = fileName.split('.').pop() + ''
235
+ if ('.jpg,.jpeg,.png,.gif,.bmp,.JPG,.JPEG,.PBG,.GIF,.BMP'.includes(type)) {
236
+ return 'adtec-image'
237
+ } else if ('txt'.includes(type)) {
238
+ return 'adtec-text'
239
+ } else if ('pdf'.includes(type)) {
240
+ return 'adtec-pdf'
241
+ } else if ('doc,docx'.includes(type)) {
242
+ return 'adtec-word'
243
+ } else if ('xls,xlsx'.includes(type)) {
244
+ return 'adtec-excel'
245
+ } else if ('ppt,pptx'.includes(type)) {
246
+ return 'adtec-ppt'
247
+ } else {
248
+ return 'adtec-text'
249
+ }
250
+ }
251
+ const success = (response: any, uploadFile: UploadFile, uploadFiles: UploadFiles) => {
252
+ if (response.code === '0') {
253
+ props.uploadFilesList.push(response.data as ISysUploadFiles)
254
+ } else {
255
+ ElMessage.error(response.msg)
256
+ ref_upload.value?.handleRemove(uploadFile)
257
+ }
258
+ for (let i = loadingFiles.value.length - 1; i >= 0; i--) {
259
+ if (loadingFiles.value[i] === uploadFile.name) {
260
+ loadingFiles.value.splice(i, 1)
261
+ }
262
+ }
263
+ if (response.code === '0') {
264
+ props.showOptMessage && ElMessage.success('上传成功')
265
+ emit('success', { files: props.uploadFilesList, deleteFiles: deleteFiles.value })
266
+ }
267
+ loading.value = false
268
+ }
269
+ const loading = defineModel<boolean>('loading')
270
+ const loadingFiles = ref<string[]>([])
271
+ // watch(
272
+ // loadingFiles,
273
+ // (val) => {
274
+ // if (props.autoUpload) {
275
+ // if (val.length > 0) {
276
+ // loading.value = true
277
+ // } else {
278
+ // loading.value = false
279
+ // }
280
+ // }
281
+ // },
282
+ // { deep: true }
283
+ // )
284
+ const beforeUpload = async (file: File) => {
285
+ const f = props.uploadFilesList.find((c) => c.name === file.name)
286
+ if (f) {
287
+ ElMessage.warning(file.name + ',文件已存在')
288
+ return false
289
+ } else if (file.size > props.size * 1024 * 1024) {
290
+ ElMessage.warning('文件大小不能超过' + props.size + 'MB')
291
+ return false
292
+ }
293
+ const acceptSuffixes = getAccept.value
294
+ ?.split(',')
295
+ .map(suffix => suffix.slice(1).toLowerCase())
296
+ const fileSuffix = file.name.split('.').pop()?.toLowerCase()
297
+ if (acceptSuffixes && !acceptSuffixes.includes(fileSuffix ?? '')) {
298
+ ElMessage.error(`文件 ${file.name} 格式不支持,仅允许 ${getAccept.value}!`)
299
+ setTimeout(() => {
300
+ ref_upload.value?.clearFiles(['ready'])
301
+ }, 1)
302
+ return false
303
+ }
304
+ loadingFiles.value.push(file.name)
305
+ return true
306
+ }
307
+ const fileClick = async (file: UploadFile & ISysUploadFiles) => {
308
+ if (file.name === hoverfileName.value) {
309
+ if (file.createBy && userInfo.getUserInfo.userCode !== file.createBy) {
310
+ ElMessage.warning('您没有权限删除此文件!')
311
+ return
312
+ }
313
+ if (!props.isConfirmDelete) {
314
+ const flag = await ElMessageBox.confirm('删除不可恢复!您确定删除此附件?', '提示', {
315
+ confirmButtonText: '确定',
316
+ cancelButtonText: '取消',
317
+ type: 'warning'
318
+ })
319
+ if (!flag) {
320
+ return
321
+ }
322
+ }
323
+ ref_upload.value?.handleRemove(file)
324
+ } else {
325
+ preview(file)
326
+ }
327
+ }
328
+ // 处理覆盖逻辑
329
+ const exceed = async (files: File[], uploadFiles: UploadUserFile[]) => {
330
+ if (props.limit === 1 && props.overwrite && props.uploadFilesList.length >= 1) {
331
+ const existingFile = props.uploadFilesList[0]
332
+ if (!props.isConfirmDelete) {
333
+ const flag = await ElMessageBox.confirm('只允许上传一个附件,是否点击确定覆盖原有附件?', '提示', {
334
+ confirmButtonText: '确定',
335
+ cancelButtonText: '取消',
336
+ type: 'warning'
337
+ })
338
+ if (!flag) {
339
+ return
340
+ }
341
+ try {
342
+ loading.value = true
343
+ await documentApi.delSysUploadFile(existingFile.id).catch(err => {
344
+ frameworkUtils.messageError(err)
345
+ })
346
+ } catch (err) {
347
+ frameworkUtils.messageError(err)
348
+ return
349
+ } finally {
350
+ loading.value = false
351
+ }
352
+ }
353
+ props.uploadFilesList.splice(0, 1)
354
+ ref_upload.value?.clearFiles()
355
+ if (files.length > 0) {
356
+ const canUpload = await beforeUpload(files[0])
357
+ if (canUpload) {
358
+ deleteFiles.value.push(existingFile)
359
+ ref_upload.value?.handleStart(files[0])
360
+ props.autoUpload && ref_upload.value?.submit()
361
+ } else {
362
+ props.uploadFilesList.push(existingFile)
363
+ }
364
+ }
365
+ } else {
366
+ ElMessage.warning(`最多上传${props.limit}个文件,上传文件数量已达到限制`)
367
+ }
368
+ }
369
+ const error = (error: Error, uploadFile: UploadFile, uploadFiles: UploadFiles) => {
370
+ ElMessage.error('上传失败')
371
+ for (let i = loadingFiles.value.length - 1; i >= 0; i--) {
372
+ if (loadingFiles.value[i] === uploadFile.name) {
373
+ loadingFiles.value.splice(i, 1)
374
+ }
375
+ }
376
+ loading.value = false
377
+ }
378
+ const preview = async (uploadFile: UploadFile) => {
379
+ const file = props.uploadFilesList.find((c) => c.name === uploadFile.name)
380
+ if (file) {
381
+ //if ((uploadFile.response as any).code === '0') {
382
+ // const data = (uploadFile.response as any).data as ISysUploadFiles
383
+ fileView(file.id)
384
+ }
385
+ }
386
+ const remove = async (file: UploadFile, isConfirm: boolean = true) => {
387
+ // if ((file.response as any).code === '0') {
388
+ // const data = (file.response as any).data as ISysUploadFiles
389
+ const find = props.uploadFilesList.find((c) => c.name === file.name)
390
+ if (find) {
391
+ try {
392
+ if (!isConfirm && !props.isConfirmDelete) {
393
+ await documentApi.delSysUploadFile(find.id)
394
+ }
395
+ props.uploadFilesList.splice(props.uploadFilesList.indexOf(find), 1)
396
+ deleteFiles.value.push(find)
397
+ } catch (err: any) {
398
+ frameworkUtils.messageError(err)
399
+ }
400
+ }
401
+ // }
402
+ }
403
+ const progress = (event: { percent: number }, file: UploadFile) => {
404
+ loading.value = true
405
+ }
406
+ const confirm = async (autoDelete: boolean=true) => {
407
+ try {
408
+ loading.value = true
409
+ if (props.isConfirmDelete && deleteFiles.value.length > 0 && autoDelete) {
410
+ await documentApi.delSysUploadFiles(deleteFiles.value.map(item => item.id))
411
+ if (!loadingFiles.value?.length) {
412
+ props.showOptMessage && ElMessage.success('操作成功')
413
+ emit('success', { files: props.uploadFilesList, deleteFiles: deleteFiles.value })
414
+ }
415
+ } else if (!loadingFiles.value?.length) {
416
+ props.showOptMessage && ElMessage.success('操作成功')
417
+ emit('success', { files: props.uploadFilesList, deleteFiles: deleteFiles.value })
418
+ }
419
+ if (!props.autoUpload) {
420
+ ref_upload.value?.submit()
421
+ }
422
+ } catch (err: any) {
423
+ frameworkUtils.messageError(err)
424
+ loading.value = false
425
+ } finally {
426
+ if (props.autoUpload) {
427
+ loading.value = false
428
+ }
429
+ }
430
+ }
431
+ onMounted(() => {
432
+ uploadHeaders.value.Authorization = sessionStorage.getItem('Authorization') + ''
433
+ })
434
+ defineExpose({
435
+ remove,
436
+ confirm
437
+ })
438
+ </script>
439
+ <style scoped lang="scss">
440
+ .file-class {
441
+ }
442
+
443
+ .file-class :hover {
444
+ color: var(--el-color-primary);
445
+ }
446
+
447
+ :deep {
448
+ .el-icon--upload {
449
+ margin-bottom: 0;
450
+ }
451
+ }
452
+
453
+ .file-item {
454
+ position: relative;
455
+ padding: 2px 0;
456
+ border-radius: 4px;
457
+ transition: background-color 0.2s ease;
458
+
459
+ &:hover {
460
+ background-color: var(--el-fill-color-light);
461
+
462
+ .delete-icon {
463
+ visibility: visible;
464
+ opacity: 1;
465
+ transform: scale(1);
466
+ }
467
+ }
468
+ }
469
+
470
+ .link-name {
471
+ cursor: pointer;
472
+ }
473
+
474
+ .link-name:hover {
475
+ color: var(--el-color-primary);
476
+ text-decoration: underline;
477
+ }
478
+ </style>
@@ -279,7 +279,7 @@ const beforeUpload = (file: File) => {
279
279
  const fileClick = async (file: UploadFile & ISysUploadFiles) => {
280
280
  if (file.name === hoverfileName.value) {
281
281
  if (file.createBy && userInfo.getUserInfo.userCode !== file.createBy) {
282
- frameworkUtils.messageError('您没有权限删除此文件!')
282
+ ElMessage.warning('您没有权限删除此文件!')
283
283
  return
284
284
  }
285
285
  const flag = await ElMessageBox.confirm('删除不可恢复!您确定删除此附件?', '提示', {