adtec-core-package 2.9.4 → 2.9.6

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.9.4",
3
+ "version": "2.9.6",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "scripts": {
@@ -6,29 +6,27 @@
6
6
  <div v-if="!isEdit">
7
7
  <el-auto-tool-tip v-if="uploadFilesList?.length">
8
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>
9
+ <div style="display: flex; flex-direction: column">
10
+ <span v-for="item in uploadFilesList" :key="item.id" style="margin: 0 2px"
11
+ >{{ item.name }}
12
+ </span>
16
13
  </div>
17
14
  </template>
18
15
  <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">
16
+ <div style="display: flex; flex-direction: column">
17
+ <div
18
+ v-for="item in uploadFilesList"
19
+ :key="item.id"
20
+ class="file-item"
21
+ style="display: flex; align-items: center; overflow: hidden"
22
+ >
23
23
  <el-icons :model-value="getIcon(item.name)" style="margin-right: 5px"></el-icons>
24
24
  <span class="link-name" @click="fileView(item.id)">{{ item.name }}</span>
25
25
  </div>
26
26
  </div>
27
27
  </template>
28
28
  </el-auto-tool-tip>
29
- <div style="text-align: center;color: var(--el-disabled-text-color)" v-else>
30
- 暂无附件
31
- </div>
29
+ <div style="text-align: center; color: var(--el-disabled-text-color)" v-else>暂无附件</div>
32
30
  </div>
33
31
  <el-upload
34
32
  v-else
@@ -46,7 +44,15 @@
46
44
  :before-upload="beforeUpload"
47
45
  drag
48
46
  :accept="getAccept"
49
- :action="'/api/doc/uploadFile/' + business + '/' + businessId + '/' + association+(watermarkCode ? '?watermarkCode=' + watermarkCode : '')"
47
+ :action="
48
+ '/api/doc/uploadFile/' +
49
+ business +
50
+ '/' +
51
+ businessId +
52
+ '/' +
53
+ association +
54
+ (watermarkCode ? '?watermarkCode=' + watermarkCode : '')
55
+ "
50
56
  multiple
51
57
  :limit="limit"
52
58
  :headers="uploadHeaders"
@@ -75,7 +81,7 @@
75
81
  </el-flex>
76
82
  <el-flex align="center" justify="flex-end" width="50px">
77
83
  <el-text v-if="!file?.businessId && file.percentage !== 100"
78
- >{{ file.percentage }}%
84
+ >{{ file.percentage }}%
79
85
  </el-text>
80
86
  <el-icons
81
87
  v-if="file?.businessId || file.percentage === 100"
@@ -96,17 +102,24 @@
96
102
  <script setup lang="ts">
97
103
  import { UploadFilled } from '@element-plus/icons-vue'
98
104
  import { computed, onMounted, ref } from 'vue'
99
- import { ElMessage, ElMessageBox, type UploadFile, type UploadFiles, type UploadUserFile } from 'element-plus'
105
+ import {
106
+ ElMessage,
107
+ ElMessageBox,
108
+ type UploadFile,
109
+ type UploadFiles,
110
+ type UploadUserFile,
111
+ } from 'element-plus'
100
112
  import type { ISysUploadFiles } from '../../interface/ISysUploadFiles'
101
113
  //@ts-ignore
102
114
  import useFileView from '../../hooks/useFileView.ts'
103
115
  import documentApi from '../../api/DocumentApi.ts'
104
116
  import frameworkUtils from '../../utils/FrameworkUtils.ts'
105
117
  import { userInfoStore } from '../../stores/userInfoStore'
118
+ import { getAcceptString } from '../../utils/uploadAccept.ts'
106
119
 
107
120
  const { fileView: fileView } = useFileView()
108
121
  const uploadHeaders = ref({
109
- Authorization: ''
122
+ Authorization: '',
110
123
  })
111
124
  const emit = defineEmits(['success'])
112
125
  const userInfo = userInfoStore()
@@ -121,7 +134,7 @@ const props = defineProps({
121
134
  */
122
135
  limit: {
123
136
  type: Number,
124
- default: 1
137
+ default: 1,
125
138
  },
126
139
  /**
127
140
  * @description 纵向排列
@@ -129,7 +142,7 @@ const props = defineProps({
129
142
  */
130
143
  vertical: {
131
144
  type: Boolean,
132
- default: false
145
+ default: false,
133
146
  },
134
147
  /**
135
148
  * @description 上传文件类型
@@ -138,7 +151,7 @@ const props = defineProps({
138
151
  */
139
152
  accept: {
140
153
  type: String,
141
- default: ''
154
+ default: '',
142
155
  },
143
156
  /**
144
157
  * @description 业务类型
@@ -146,7 +159,7 @@ const props = defineProps({
146
159
  */
147
160
  business: {
148
161
  type: String,
149
- default: 'default'
162
+ default: 'default',
150
163
  },
151
164
  /**
152
165
  * @description 业务id
@@ -154,7 +167,7 @@ const props = defineProps({
154
167
  */
155
168
  businessId: {
156
169
  type: String,
157
- default: 'default'
170
+ default: 'default',
158
171
  },
159
172
  /**
160
173
  * @description 是否编辑状态
@@ -163,7 +176,7 @@ const props = defineProps({
163
176
  */
164
177
  isEdit: {
165
178
  type: Boolean,
166
- default: true
179
+ default: true,
167
180
  },
168
181
  /**
169
182
  * @description 文档上传是否默认关联,默认不关联
@@ -172,37 +185,37 @@ const props = defineProps({
172
185
  */
173
186
  association: {
174
187
  type: Boolean,
175
- default: false
188
+ default: false,
176
189
  },
177
190
  size: {
178
191
  type: Number,
179
- default: 50
192
+ default: 50,
180
193
  },
181
194
  //附件宽度
182
195
  itemWidth: {
183
196
  type: String,
184
- default: '100%'
197
+ default: '100%',
185
198
  },
186
199
  isConfirmDelete: {
187
200
  type: Boolean,
188
- default: true
201
+ default: true,
189
202
  },
190
203
  overwrite: {
191
204
  type: Boolean,
192
- default: true
205
+ default: true,
193
206
  },
194
207
  autoUpload: {
195
208
  type: Boolean,
196
- default: true
209
+ default: true,
197
210
  },
198
211
  showOptMessage: {
199
212
  type: Boolean,
200
- default: true
213
+ default: true,
201
214
  },
202
215
  watermarkCode: {
203
216
  type: String,
204
- default: () => undefined
205
- }
217
+ default: () => undefined,
218
+ },
206
219
  })
207
220
  /**
208
221
  * 文件列表
@@ -214,25 +227,7 @@ const mousemove = (fileName: string) => {
214
227
  const mouseout = () => {
215
228
  hoverfileName.value = ''
216
229
  }
217
- const getAccept = computed(() => {
218
- if (props.accept === 'images') {
219
- return '.jpg,.jpeg,.png,.gif,.bmp'
220
- } else if (props.accept === 'document') {
221
- return '.txt,.pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx'
222
- } else if (props.accept === 'txt') {
223
- return '.txt'
224
- } else if (props.accept === 'pdf') {
225
- return '.pdf' // 正确配置,仅允许 pdf
226
- } else if (props.accept === 'word') {
227
- return '.doc,.docx'
228
- } else if (props.accept === 'excel') {
229
- return '.xls,.xlsx'
230
- } else if (props.accept === 'ppt') {
231
- return '.ppt,.pptx'
232
- } else {
233
- return undefined
234
- }
235
- })
230
+ const getAccept = computed(() => getAcceptString(props.accept))
236
231
  const getIcon = (fileName: string) => {
237
232
  const type: string = fileName.split('.').pop() + ''
238
233
  if ('.jpg,.jpeg,.png,.gif,.bmp,.JPG,.JPEG,.PBG,.GIF,.BMP'.includes(type)) {
@@ -272,7 +267,7 @@ const success = (response: any, uploadFile: UploadFile, uploadFiles: UploadFiles
272
267
  const loading = defineModel<boolean>('loading')
273
268
  const loadingFiles = ref<string[]>([])
274
269
  const hasPendingFiles = computed(() => {
275
- return fileList.value.some(file => {
270
+ return fileList.value.some((file) => {
276
271
  return file.status !== 'success' && file.status !== 'error'
277
272
  })
278
273
  })
@@ -298,9 +293,7 @@ const beforeUpload = async (file: File) => {
298
293
  ElMessage.warning('文件大小不能超过' + props.size + 'MB')
299
294
  return false
300
295
  }
301
- const acceptSuffixes = getAccept.value
302
- ?.split(',')
303
- .map(suffix => suffix.slice(1).toLowerCase())
296
+ const acceptSuffixes = getAccept.value?.split(',').map((suffix) => suffix.slice(1).toLowerCase())
304
297
  const fileSuffix = file.name.split('.').pop()?.toLowerCase()
305
298
  if (acceptSuffixes && !acceptSuffixes.includes(fileSuffix ?? '')) {
306
299
  ElMessage.error(`文件 ${file.name} 格式不支持,仅允许 ${getAccept.value}!`)
@@ -322,7 +315,7 @@ const fileClick = async (file: UploadFile & ISysUploadFiles) => {
322
315
  const flag = await ElMessageBox.confirm('删除不可恢复!您确定删除此附件?', '提示', {
323
316
  confirmButtonText: '确定',
324
317
  cancelButtonText: '取消',
325
- type: 'warning'
318
+ type: 'warning',
326
319
  })
327
320
  if (!flag) {
328
321
  return
@@ -341,17 +334,21 @@ const exceed = async (files: File[], uploadFiles: UploadUserFile[]) => {
341
334
  if (props.limit === 1 && props.overwrite && uploadFilesList.value.length >= 1) {
342
335
  const existingFile = uploadFilesList.value[0]
343
336
  if (!props.isConfirmDelete) {
344
- const flag = await ElMessageBox.confirm('只允许上传一个附件,是否点击确定覆盖原有附件?', '提示', {
345
- confirmButtonText: '确定',
346
- cancelButtonText: '取消',
347
- type: 'warning'
348
- })
337
+ const flag = await ElMessageBox.confirm(
338
+ '只允许上传一个附件,是否点击确定覆盖原有附件?',
339
+ '提示',
340
+ {
341
+ confirmButtonText: '确定',
342
+ cancelButtonText: '取消',
343
+ type: 'warning',
344
+ },
345
+ )
349
346
  if (!flag) {
350
347
  return
351
348
  }
352
349
  try {
353
350
  loading.value = true
354
- await documentApi.delSysUploadFile(existingFile.id).catch(err => {
351
+ await documentApi.delSysUploadFile(existingFile.id).catch((err) => {
355
352
  frameworkUtils.messageError(err)
356
353
  })
357
354
  } catch (err) {
@@ -418,7 +415,7 @@ const confirm = async (autoDelete: boolean = true) => {
418
415
  try {
419
416
  loading.value = true
420
417
  if (props.isConfirmDelete && deleteFiles.value.length > 0 && autoDelete) {
421
- await documentApi.delSysUploadFiles(deleteFiles.value.map(item => item.id))
418
+ await documentApi.delSysUploadFiles(deleteFiles.value.map((item) => item.id))
422
419
  }
423
420
  if (!props.autoUpload) {
424
421
  //此处判断是否存在需要上传的文件
@@ -443,7 +440,7 @@ onMounted(() => {
443
440
  })
444
441
  defineExpose({
445
442
  remove,
446
- confirm
443
+ confirm,
447
444
  })
448
445
  </script>
449
446
  <style scoped lang="scss">
@@ -111,6 +111,7 @@ import useFileView from '../../hooks/useFileView.ts'
111
111
  import documentApi from '../../api/DocumentApi.ts'
112
112
  import frameworkUtils from '../../utils/FrameworkUtils.ts'
113
113
  import { userInfoStore } from '../../stores/userInfoStore'
114
+ import { getAcceptString } from '../../utils/uploadAccept.ts'
114
115
 
115
116
  const { fileView: fileView } = useFileView()
116
117
  const uploadHeaders = ref({
@@ -206,25 +207,7 @@ const mousemove = (fileName: string) => {
206
207
  const mouseout = () => {
207
208
  hoverfileName.value = ''
208
209
  }
209
- const getAccept = computed(() => {
210
- if (props.accept === 'images') {
211
- return '.jpg,.jpeg,.png,.gif,.bmp'
212
- } else if (props.accept === 'document') {
213
- return '.txt,.pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx'
214
- } else if (props.accept === 'txt') {
215
- return '.txt'
216
- } else if (props.accept === 'pdf') {
217
- return '.pdf' // 正确配置,仅允许 pdf
218
- } else if (props.accept === 'word') {
219
- return '.doc,.docx'
220
- } else if (props.accept === 'excel') {
221
- return '.xls,.xlsx'
222
- } else if (props.accept === 'ppt') {
223
- return '.ppt,.pptx'
224
- } else {
225
- return undefined
226
- }
227
- })
210
+ const getAccept = computed(() => getAcceptString(props.accept))
228
211
  const getIcon = (fileName: string) => {
229
212
  const type: string = fileName.split('.').pop() + ''
230
213
  if ('.jpg,.jpeg,.png,.gif,.bmp,.JPG,.JPEG,.PBG,.GIF,.BMP'.includes(type)) {
@@ -15,22 +15,48 @@ const isVisible = ref(false)
15
15
  //@ts-ignore
16
16
  import 'vue-img-viewr/styles/index.css'
17
17
  //@ts-ignore
18
- import ImgViewr, { showImages } from 'vue-img-viewr'
18
+ import { showImages } from 'vue-img-viewr'
19
19
  import documentApi from '../../api/DocumentApi.ts'
20
20
  import frameworkUtils from '../../utils/FrameworkUtils.ts'
21
21
  import framework from '../../api/framework.ts'
22
22
  import FileView from './FileView.vue'
23
+ import request from '../../utils/AxiosConfig.ts'
24
+ import { getFileSuffix, isPreviewableSuffix } from '../../utils/uploadAccept.ts'
25
+ import type { ISysUploadFiles } from '../../interface/ISysUploadFiles.ts'
26
+
23
27
  const fileTitle = ref('')
24
28
  const viewUrl = ref('')
25
29
  const fileId = ref('')
26
30
  const edit = ref('view')
27
31
 
32
+ const IMAGE_SUFFIXES = ['jpg', 'jpeg', 'png', 'gif', 'bmp']
33
+
34
+ const downloadFile = async (data: ISysUploadFiles, url: string) => {
35
+ const res = await request<any>({
36
+ url,
37
+ method: 'get',
38
+ responseType: 'blob',
39
+ })
40
+ const blob = new Blob([res.data])
41
+ const link = document.createElement('a')
42
+ link.href = window.URL.createObjectURL(blob)
43
+ link.download = data.name
44
+ link.click()
45
+ window.URL.revokeObjectURL(link.href)
46
+ }
47
+
28
48
  const viewFile = async (id: string) => {
29
- //根据文件id获取文件信息
30
49
  try {
31
50
  const data = await documentApi.getUpLoadFilesVoById(id)
32
51
  const data1 = await framework.getFileAccessAddress(data.id)
33
- if ('.jpg,.jpeg,.png,.gif,.bmp,.JPG,.JPEG,.PBG,.GIF,.BMP'.includes(data.type)) {
52
+ const suffix = getFileSuffix(data)
53
+
54
+ if (!isPreviewableSuffix(suffix)) {
55
+ await downloadFile(data, data1.url)
56
+ return
57
+ }
58
+
59
+ if (IMAGE_SUFFIXES.includes(suffix)) {
34
60
  showImages({
35
61
  urls: [data1.url],
36
62
  index: 0,
@@ -0,0 +1,49 @@
1
+ /**
2
+ * 与 ElUploads.vue getAccept 保持一致的 accept 配置
3
+ */
4
+ export function getAcceptString(accept: string): string | undefined {
5
+ if (accept === 'images') {
6
+ return '.jpg,.jpeg,.png,.gif,.bmp'
7
+ } else if (accept === 'document') {
8
+ return '.txt,.pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx'
9
+ } else if (accept === 'txt') {
10
+ return '.txt'
11
+ } else if (accept === 'pdf') {
12
+ return '.pdf'
13
+ } else if (accept === 'word') {
14
+ return '.doc,.docx'
15
+ } else if (accept === 'excel') {
16
+ return '.xls,.xlsx'
17
+ } else if (accept === 'ppt') {
18
+ return '.ppt,.pptx'
19
+ }
20
+ return undefined
21
+ }
22
+
23
+ export function getAcceptSuffixes(accept: string): string[] | null {
24
+ const acceptStr = getAcceptString(accept)
25
+ if (!acceptStr) {
26
+ return null
27
+ }
28
+ return acceptStr.split(',').map((suffix) => suffix.slice(1).toLowerCase())
29
+ }
30
+
31
+ const ACCEPT_TYPES = ['images', 'document', 'txt', 'pdf', 'word', 'excel', 'ppt'] as const
32
+
33
+ const ALL_PREVIEW_SUFFIXES = new Set(
34
+ ACCEPT_TYPES.flatMap((accept) => getAcceptSuffixes(accept) ?? []),
35
+ )
36
+
37
+ /** 后缀是否在 getAccept 支持的可预览格式内(合并所有 accept 类型) */
38
+ export function isPreviewableSuffix(suffix: string): boolean {
39
+ const normalized = suffix.replace(/^\./, '').toLowerCase()
40
+ return ALL_PREVIEW_SUFFIXES.has(normalized)
41
+ }
42
+
43
+ export function getFileSuffix(file: { type?: string; name: string }): string {
44
+ const fromType = file.type?.replace(/^\./, '')
45
+ if (fromType) {
46
+ return fromType.toLowerCase()
47
+ }
48
+ return (file.name.split('.').pop() ?? '').toLowerCase()
49
+ }