|
|
@@ -2,7 +2,7 @@
|
|
|
const props = withDefaults(
|
|
|
defineProps<{
|
|
|
modelValue: string | any[]
|
|
|
- prefixUrl?: string
|
|
|
+ previewPrefixUrl?: string
|
|
|
uploadType?: "image" | "file"
|
|
|
uploadUrl?: string
|
|
|
limit?: number // 图片数量限制
|
|
|
@@ -12,7 +12,8 @@ const props = withDefaults(
|
|
|
}>(),
|
|
|
{
|
|
|
uploadType: "image",
|
|
|
- prefixUrl: "/resource/oss/",
|
|
|
+ uploadUrl: "resource/oss/upload",
|
|
|
+ previewPrefixUrl: "resource/oss/preview/",
|
|
|
limit: 5,
|
|
|
fileSize: 5,
|
|
|
fileType: () => ["png", "jpg", "jpeg"],
|
|
|
@@ -25,13 +26,17 @@ const emits = defineEmits<{
|
|
|
(e: "delete", v: any): void
|
|
|
}>()
|
|
|
const imageUploadRef = ref()
|
|
|
+const pdfPreviewRef = ref()
|
|
|
+const notInit = ref(false)
|
|
|
const number = ref(0)
|
|
|
const uploadList = ref<any[]>([])
|
|
|
const showViewer = ref(false)
|
|
|
const viewerInitialIndex = ref(0)
|
|
|
const baseUrl = import.meta.env.VITE_APP_BASE_API
|
|
|
-const uploadImgUrl = ref(
|
|
|
- import.meta.env.VITE_APP_BASE_API + (props.uploadUrl ? props.uploadUrl : "/resource/oss/upload")
|
|
|
+const uploadImgFileUrl = ref(
|
|
|
+ import.meta.env.VITE_APP_BASE_API +
|
|
|
+ "/" +
|
|
|
+ (props.uploadUrl ? props.uploadUrl : "resource/oss/upload")
|
|
|
) // 上传的图片服务器地址
|
|
|
const headers = ref({
|
|
|
Authorization: "Bearer " + getToken(),
|
|
|
@@ -92,20 +97,21 @@ function handleUploadError() {
|
|
|
|
|
|
// 上传成功回调
|
|
|
function handleUploadSuccess(res: any, file: any) {
|
|
|
- //console.log("RES", res, file)
|
|
|
if (res.code === 200 && res.data.url) {
|
|
|
- let url = `${baseUrl}/${
|
|
|
- props.prefixUrl
|
|
|
- ? props.prefixUrl.lastIndexOf("/") == props.prefixUrl.length - 1
|
|
|
- ? props.prefixUrl
|
|
|
- : props.prefixUrl + "/"
|
|
|
- : ""
|
|
|
- }${res.data.url}`
|
|
|
+ let url = `/${props.previewPrefixUrl ? props.previewPrefixUrl : ""}/${res.data.url}`
|
|
|
+ url = url
|
|
|
+ .replace("https://", "$$$$")
|
|
|
+ .replace("http://", "@@@@")
|
|
|
+ .replace(/\/\//g, "/")
|
|
|
+ .replace("$$$$", "https://")
|
|
|
+ .replace("@@@@", "http://")
|
|
|
uploadList.value.push({
|
|
|
- id: res.data.ossId,
|
|
|
- name: res.data.url,
|
|
|
realUrl: url,
|
|
|
- url: file.url
|
|
|
+ url: file.url,
|
|
|
+ name: res.data.fileId,
|
|
|
+ fileName: res.data.fileName,
|
|
|
+ fileId: res.data.fileId,
|
|
|
+ ossId: res.data.ossId
|
|
|
})
|
|
|
uploadedSuccessfully()
|
|
|
} else {
|
|
|
@@ -144,6 +150,7 @@ function uploadedSuccessfully() {
|
|
|
uploadList.value = []
|
|
|
number.value = 0
|
|
|
emits("update:modelValue", listToString(fileList.value))
|
|
|
+ notInit.value = true
|
|
|
message.closeLoading()
|
|
|
}
|
|
|
}
|
|
|
@@ -151,18 +158,14 @@ function uploadedSuccessfully() {
|
|
|
// 预览
|
|
|
function handlePictureCardPreview(file: any) {
|
|
|
//dialogImageUrl.value = file.url
|
|
|
- console.log("---", file)
|
|
|
viewerInitialIndex.value = file.index //fileList.value.map((f) => f.url).indexOf(file.url)
|
|
|
showViewer.value = true
|
|
|
}
|
|
|
-
|
|
|
-// 获取文件名称
|
|
|
-function getFileName(name: string) {
|
|
|
- if (name.lastIndexOf("/") > -1) {
|
|
|
- return name.slice(name.lastIndexOf("/") + 1)
|
|
|
- } else {
|
|
|
- return ""
|
|
|
- }
|
|
|
+function handlePreviewPdf(fileId: string, fileName: string) {
|
|
|
+ pdfPreviewRef.value.open({
|
|
|
+ fileId,
|
|
|
+ fileName
|
|
|
+ })
|
|
|
}
|
|
|
|
|
|
// 对象转成指定字符串分隔
|
|
|
@@ -170,8 +173,8 @@ function listToString(list: any[], separator?: string) {
|
|
|
let str = ""
|
|
|
separator = separator ?? ","
|
|
|
list.forEach((v) => {
|
|
|
- if (undefined !== v.url && v.url.indexOf("blob:") !== 0) {
|
|
|
- str += v.name + separator
|
|
|
+ if (undefined !== v.fileId) {
|
|
|
+ str += `${v.fileId}$${v.fileName}$${v.ossId}` + separator
|
|
|
}
|
|
|
})
|
|
|
return str != "" ? str.substring(0, str.length - 1) : ""
|
|
|
@@ -179,26 +182,48 @@ function listToString(list: any[], separator?: string) {
|
|
|
|
|
|
function initFile(files: any) {
|
|
|
if (files) {
|
|
|
+ let temp = 0
|
|
|
// 首先将值转为数组
|
|
|
let list = Array.isArray(files) ? files : (files as string)?.split(",")
|
|
|
// 然后将数组转为对象数组
|
|
|
list = list.map((item) => {
|
|
|
if (typeof item === "string") {
|
|
|
- if (!item.includes(baseUrl)) {
|
|
|
- let url = `${baseUrl}/${
|
|
|
- props.prefixUrl
|
|
|
- ? props.prefixUrl.lastIndexOf("/") == props.prefixUrl.length - 1
|
|
|
- ? props.prefixUrl
|
|
|
- : props.prefixUrl + "/"
|
|
|
- : ""
|
|
|
- }${item}`
|
|
|
- item = {
|
|
|
- name: item,
|
|
|
- realUrl: url
|
|
|
+ const itemArr = item.split("$")
|
|
|
+ if (itemArr.length == 1) {
|
|
|
+ itemArr.push("01.pdf")
|
|
|
+ }
|
|
|
+ if (itemArr.length == 2) {
|
|
|
+ itemArr.push("0")
|
|
|
+ }
|
|
|
+ item = {
|
|
|
+ fileId: itemArr[0],
|
|
|
+ fileName: itemArr[1],
|
|
|
+ ossId: itemArr[2],
|
|
|
+ index: temp
|
|
|
+ }
|
|
|
+ if (!itemArr[0].includes(baseUrl)) {
|
|
|
+ let url = `/${props.previewPrefixUrl ? props.previewPrefixUrl : ""}/${itemArr[0]}`
|
|
|
+ url = url
|
|
|
+ .replace("https://", "$$$$")
|
|
|
+ .replace("http://", "@@@@")
|
|
|
+ .replace(/\/\//g, "/")
|
|
|
+ .replace("$$$$", "https://")
|
|
|
+ .replace("@@@@", "http://")
|
|
|
+ if (isImage.value) {
|
|
|
+ item.realUrl = url
|
|
|
+ } else {
|
|
|
+ item.url = url
|
|
|
}
|
|
|
+ item.name = itemArr[0]
|
|
|
} else {
|
|
|
- item = { name: item, url: item }
|
|
|
+ if (isImage.value) {
|
|
|
+ item.realUrl = itemArr[0]
|
|
|
+ } else {
|
|
|
+ item.url = itemArr[0]
|
|
|
+ }
|
|
|
+ item.name = itemArr[0]
|
|
|
}
|
|
|
+ item.uid = item.uid || new Date().getTime() + temp++
|
|
|
}
|
|
|
return item
|
|
|
})
|
|
|
@@ -206,21 +231,29 @@ function initFile(files: any) {
|
|
|
list.forEach((v: any) => {
|
|
|
if (v.url) {
|
|
|
fileList.value.push({
|
|
|
+ index: v.index,
|
|
|
+ fileId: v.fileId,
|
|
|
+ fileName: v.fileName,
|
|
|
+ ossId: v.ossId,
|
|
|
name: v.name,
|
|
|
realUrl: v.realUrl,
|
|
|
url: v.url
|
|
|
})
|
|
|
} else {
|
|
|
- RequestService.get({ url: v.realUrl, loading: false, responseType: "blob" }).then((res) => {
|
|
|
- if (res.status === 200) {
|
|
|
- const blobUrl = URL.createObjectURL(res.data)
|
|
|
+ Rs.get(v.realUrl, { url: v.realUrl, loading: false, responseType: "blob" }).then(
|
|
|
+ (res: any) => {
|
|
|
+ const blobUrl = URL.createObjectURL(res)
|
|
|
fileList.value.push({
|
|
|
+ index: v.index,
|
|
|
+ fileId: v.fileId,
|
|
|
+ fileName: v.fileName,
|
|
|
+ ossId: v.ossId,
|
|
|
name: v.name,
|
|
|
url: blobUrl,
|
|
|
realUrl: v.realUrl
|
|
|
})
|
|
|
}
|
|
|
- })
|
|
|
+ )
|
|
|
}
|
|
|
})
|
|
|
} else {
|
|
|
@@ -233,13 +266,23 @@ function init() {
|
|
|
}
|
|
|
|
|
|
onMounted(init)
|
|
|
+watch(
|
|
|
+ () => props.modelValue,
|
|
|
+ (val) => {
|
|
|
+ if (notInit.value) {
|
|
|
+ notInit.value = false
|
|
|
+ return
|
|
|
+ }
|
|
|
+ initFile(val)
|
|
|
+ }
|
|
|
+)
|
|
|
</script>
|
|
|
<template>
|
|
|
<div class="component-upload-image">
|
|
|
<el-upload
|
|
|
multiple
|
|
|
ref="imageUploadRef"
|
|
|
- :action="uploadImgUrl"
|
|
|
+ :action="uploadImgFileUrl"
|
|
|
:list-type="isImage ? 'picture-card' : undefined"
|
|
|
:file-list="fileList"
|
|
|
:limit="limit"
|
|
|
@@ -291,14 +334,15 @@ onMounted(init)
|
|
|
:key="file.uid"
|
|
|
class="el-upload-list__item ele-upload-list__item-content"
|
|
|
v-for="(file, index) in fileList">
|
|
|
- <el-link :href="`${baseUrl}${file.url}`" :underline="false" target="_blank">
|
|
|
- <span class="el-icon-document">{{ getFileName(file.name) }}</span>
|
|
|
+ <el-link href="#" :underline="false" @click="handlePreviewPdf(file.fileId, file.fileName)">
|
|
|
+ <span class="el-icon-document">{{ file.fileName }}</span>
|
|
|
</el-link>
|
|
|
<div class="ele-upload-list__item-content-action">
|
|
|
<el-link :underline="false" @click="handleDeleteFile(index)" type="danger">删除</el-link>
|
|
|
</div>
|
|
|
</li>
|
|
|
</transition-group>
|
|
|
+ <VbPdfPreview ref="pdfPreviewRef" />
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
@@ -307,6 +351,14 @@ onMounted(init)
|
|
|
:deep(.hide .el-upload--picture-card) {
|
|
|
display: none;
|
|
|
}
|
|
|
+:deep(.el-link) {
|
|
|
+ width: 100%;
|
|
|
+ justify-content: flex-start;
|
|
|
+ .el-link__inner {
|
|
|
+ padding: 0 10px;
|
|
|
+ color: var(--bs-primary);
|
|
|
+ }
|
|
|
+}
|
|
|
|
|
|
.upload-file-uploader {
|
|
|
margin-bottom: 5px;
|