first commit
This commit is contained in:
@@ -0,0 +1,286 @@
|
||||
<template>
|
||||
<div class="component-upload-image">
|
||||
<el-upload
|
||||
action="#"
|
||||
list-type="picture-card"
|
||||
drag
|
||||
:on-success="handleSuccess"
|
||||
:on-change="handleChange"
|
||||
ref="uploadInner"
|
||||
:auto-upload="false"
|
||||
:file-list="fileList"
|
||||
>
|
||||
<el-icon><Plus /></el-icon>
|
||||
<template #file="{ file }">
|
||||
<div style="display: flex; flex-direction: column; position: relative">
|
||||
<div style="width: 146px; height: 146px">
|
||||
<img
|
||||
class="el-upload-list__item-thumbnail"
|
||||
:src="getImageUrl(file)"
|
||||
alt=""
|
||||
/>
|
||||
<span class="el-upload-list__item-actions">
|
||||
<span
|
||||
class="el-upload-list__item-preview"
|
||||
@click="handlePictureCardPreview(file)"
|
||||
>
|
||||
<el-icon><zoom-in /></el-icon>
|
||||
</span>
|
||||
<span
|
||||
class="el-upload-list__item-delete"
|
||||
@click="handleDownload(file)"
|
||||
>
|
||||
<el-icon><Download /></el-icon>
|
||||
</span>
|
||||
<span
|
||||
class="el-upload-list__item-delete"
|
||||
@click="handleRemove(file)"
|
||||
>
|
||||
<el-icon><Delete /></el-icon>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<span
|
||||
style="
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
width: 146px;
|
||||
font-size: 11px;
|
||||
line-height: 14px;
|
||||
"
|
||||
>{{ file.name }}</span
|
||||
>
|
||||
</div>
|
||||
</template>
|
||||
</el-upload>
|
||||
<el-dialog v-model="dialogVisible">
|
||||
<img :src="dialogImageUrl" alt="Preview Image" style="width: 100%;"/>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { Delete, Download, Plus, ZoomIn } from "@element-plus/icons-vue";
|
||||
import dayjs from "dayjs";
|
||||
import OSS from "ali-oss";
|
||||
import { ElLoading } from "element-plus";
|
||||
import { ref, watch } from "vue";
|
||||
import { handleBatchDownload } from "../../utils/downFile";
|
||||
const props = defineProps({
|
||||
modelValue: [String, Object, Array],
|
||||
// 图片数量限制
|
||||
limit: {
|
||||
type: Number,
|
||||
default: 5,
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits();
|
||||
const uploadList = ref([]);
|
||||
const baseUrl = "https://dfdiyfile.oss-cn-fuzhou.aliyuncs.com/";
|
||||
const fileList = ref([]);
|
||||
const dialogImageUrl = ref("");
|
||||
const dialogVisible = ref(false);
|
||||
const disabled = ref(false);
|
||||
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
(val) => {
|
||||
if (val) {
|
||||
// 首先将值转为数组
|
||||
const list = Array.isArray(val) ? val : props.modelValue.split(",");
|
||||
// 然后将数组转为对象数组
|
||||
fileList.value = list.map((item) => {
|
||||
if (typeof item === "string") {
|
||||
if (item.indexOf(baseUrl) === -1 && !item.startsWith("http")) {
|
||||
item = { name: item, url: baseUrl + item };
|
||||
} else {
|
||||
item = { name: item, url: item };
|
||||
}
|
||||
}
|
||||
return item;
|
||||
});
|
||||
} else {
|
||||
fileList.value = [];
|
||||
return [];
|
||||
}
|
||||
},
|
||||
{ deep: true, immediate: true }
|
||||
);
|
||||
|
||||
let fileTypes = [
|
||||
{
|
||||
logo: require("../../assets/iso.png"),
|
||||
types: "iso,gho",
|
||||
},
|
||||
{
|
||||
logo: require("../../assets/mv.png"),
|
||||
types: "rm,wav,mpg,rmvb,mov,mp4",
|
||||
},
|
||||
{
|
||||
logo: require("../../assets/txt.png"),
|
||||
types: "txt,conf",
|
||||
},
|
||||
{
|
||||
logo: require("../../assets/excel.png"),
|
||||
types: "xls,xlsx",
|
||||
},
|
||||
{
|
||||
logo: require("../../assets/exe.png"),
|
||||
types: "exe,sh",
|
||||
},
|
||||
{
|
||||
logo: require("../../assets/html.png"),
|
||||
types: "html,htm",
|
||||
},
|
||||
{
|
||||
logo: require("../../assets/image.png"),
|
||||
types: "png,jpg,jpeg,bpm",
|
||||
},
|
||||
{
|
||||
logo: require("../../assets/music.png"),
|
||||
types: "mp3,m4a",
|
||||
},
|
||||
{
|
||||
logo: require("../../assets/pdf.png"),
|
||||
types: "pdf",
|
||||
},
|
||||
{
|
||||
logo: require("../../assets/psd.png"),
|
||||
types: "psd",
|
||||
},
|
||||
{
|
||||
logo: require("../../assets/sql.png"),
|
||||
types: "sql",
|
||||
},
|
||||
{
|
||||
logo: require("../../assets/word.png"),
|
||||
types: "doc,docx",
|
||||
},
|
||||
{
|
||||
logo: require("../../assets/ppt.png"),
|
||||
types: "ppt,pptx",
|
||||
},
|
||||
{
|
||||
logo: require("../../assets/zip.png"),
|
||||
types: "zip,7z,gz",
|
||||
},
|
||||
{
|
||||
logo: require("../../assets/apk.png"),
|
||||
types: "apk",
|
||||
},
|
||||
];
|
||||
|
||||
function getImageUrl(file) {
|
||||
let suffix = file.name.split(".").pop();
|
||||
if ("png,jpg,jpeg".indexOf(suffix) != -1) {
|
||||
return file.url;
|
||||
}
|
||||
for (let ft of fileTypes) {
|
||||
if (ft.types.indexOf(suffix) != -1) {
|
||||
return ft.logo;
|
||||
}
|
||||
}
|
||||
return "../../assets/other.png";
|
||||
}
|
||||
let loading = null;
|
||||
const handlePictureCardPreview = (file) => {
|
||||
dialogImageUrl.value = file.url;
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
function handleRemove(file) {
|
||||
const findex = fileList.value.map((f) => f.name).indexOf(file.name);
|
||||
fileList.value.splice(findex, 1);
|
||||
emit("update:modelValue", listToString(fileList.value));
|
||||
return false;
|
||||
}
|
||||
function handleDownload(file) {
|
||||
handleBatchDownload([file.url]);
|
||||
}
|
||||
|
||||
function handleSuccess(res, file) {
|
||||
uploadList.value.push({ name: res.name, url: res.url });
|
||||
uploadedSuccessfully();
|
||||
}
|
||||
|
||||
// 上传结束处理
|
||||
function uploadedSuccessfully() {
|
||||
fileList.value = fileList.value
|
||||
.filter((f) => f.url !== undefined)
|
||||
.concat(uploadList.value);
|
||||
|
||||
uploadList.value = [];
|
||||
emit("update:modelValue", listToString(fileList.value));
|
||||
loading && loading.close();
|
||||
}
|
||||
|
||||
function guid() {
|
||||
return "xxxxxxxx-xxxx-4xxx-yxxx".replace(/[xy]/g, function (c) {
|
||||
var r = (Math.random() * 16) | 0,
|
||||
v = c == "x" ? r : (r & 0x3) | 0x8;
|
||||
return v.toString(16);
|
||||
});
|
||||
}
|
||||
const progress = (p, _checkpoint) => {
|
||||
// Object的上传进度。
|
||||
console.log(p);
|
||||
// 分片上传的断点信息。
|
||||
console.log(_checkpoint);
|
||||
};
|
||||
|
||||
function getSuff(name) {
|
||||
return name.substring(name.lastIndexOf("."));
|
||||
}
|
||||
function handleChange(file, fileList) {
|
||||
loading = ElLoading.service({
|
||||
lock: true,
|
||||
text: "Loading",
|
||||
background: "rgba(0, 0, 0, 0.7)",
|
||||
});
|
||||
let fileDir = dayjs().format("YYYYMMDD");
|
||||
const client = new OSS({
|
||||
// yourregion填写Bucket所在地域。以华东1(杭州)为例,Region填写为oss-cn-hangzhou。
|
||||
region: "oss-cn-fuzhou",
|
||||
// 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
|
||||
accessKeyId: process.env.VUE_APP_OSS_ACCESS_KEY_ID,
|
||||
accessKeySecret: process.env.VUE_APP_OSS_ACCESS_KEY_SECRET,
|
||||
// 填写存储空间名称。
|
||||
bucket: "dfdiyfile",
|
||||
endpoint: "https://oss-cn-fuzhou.aliyuncs.com",
|
||||
});
|
||||
let name = "desgn/" + fileDir + "/" + guid() + getSuff(file.name);
|
||||
// storeAs表示上传的object name , file表示上传的文件
|
||||
client
|
||||
.multipartUpload(name, file.raw, {
|
||||
progress,
|
||||
})
|
||||
.then((result) => {
|
||||
console.log(result);
|
||||
let url = `https://dfdiyfile.oss-cn-fuzhou.aliyuncs.com/${result.name}`;
|
||||
/**
|
||||
* 设置本地上传成功的回调
|
||||
*/
|
||||
// this.imageUrl = result.res.requestUrl;
|
||||
handleSuccess({ url, name: result.name }, file);
|
||||
})
|
||||
.catch(function (err) {
|
||||
console.log(err);
|
||||
/**
|
||||
* 设置本地上传失败的回调
|
||||
*/
|
||||
});
|
||||
}
|
||||
// 对象转成指定字符串分隔
|
||||
function listToString(list, separator) {
|
||||
let strs = "";
|
||||
separator = separator || ",";
|
||||
for (let i in list) {
|
||||
if (undefined !== list[i].url && list[i].url.indexOf("blob:") !== 0) {
|
||||
strs += list[i].url.replace(baseUrl, "") + separator;
|
||||
}
|
||||
}
|
||||
return strs != "" ? strs.substr(0, strs.length - 1) : "";
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
Reference in New Issue
Block a user