Commit 831d6195 authored by “yiyousong”'s avatar “yiyousong”

perf: 添加上传组件

parent 3e6e4621
<template>
<div>
<el-upload
v-if="listType === 'picture' || listType === 'text'"
:name="name"
:list-type="listType"
:action="action"
:multiple="multiple"
:accept="accept"
:file-list="FileList"
v-bind="$attrs"
v-on="$listeners"
:before-upload="beforeUpload"
:on-preview="handlePreview"
:on-success="handleSuccess"
:on-remove="handleRemove"
>
<slot>
<el-button size="small" type="primary">点击上传</el-button>
</slot>
</el-upload>
<el-upload
v-else
:name="name"
:list-type="listType"
:action="action"
:multiple="multiple"
:accept="accept"
:file-list="FileList"
v-bind="$attrs"
v-on="$listeners"
:before-upload="beforeUpload"
:on-preview="handlePreview"
:on-success="handleSuccess"
:on-remove="handleRemove"
>
<slot>
<i class="el-icon-plus"></i>
</slot>
</el-upload>
<!-- 图片查看 -->
<el-image-viewer
v-if="preview"
:appendToBody="false"
:on-close="
() => {
(preview = false), (filepaths = []);
}
"
:url-list="filepaths"
/>
<!-- 视频预览 -->
<div
class="fixed left-0 top-0 z-[999] flex h-full w-full flex-col items-center justify-center gap-2 bg-[rgba(0,0,0,.5)]"
v-if="show"
>
<video
v-if="previewData.type === 'video'"
class="h-[400px]"
:src="previewData.url"
autoplay
muted
controls
></video>
<audio
v-else-if="previewData.type === 'audio'"
:src="previewData.url"
autoplay
muted
controls
></audio>
<i
class="el-icon-circle-close cursor-pointer text-[40px] text-white"
@click.self="show = false"
></i>
</div>
</div>
</template>
<script>
export default {
name: "YUpload",
model: {
prop: "value",
event: "change",
},
components: {},
props: {
name: {
type: String,
default: "file",
},
listType: {
type: String,
default: "text",
},
multiple: {
type: Boolean,
default: false,
},
value: {
required: true,
type: [String, Array],
default: "",
},
// 文件限制
accept: {
type: String,
default: "",
},
// 上传数量
limit: {
type: Number,
validator: (value) => {
return value >= 0;
},
default: 1, // 0为不限制
},
// 上传文件大小限制mb 0为不限制
MB: {
type: Number,
validator: (value) => {
return value >= 0;
},
default: 10,
},
action: {
type: String,
default: "/bill/file/commonupload",
},
},
data() {
return {
FileList: [],
imageType: ["png", "jpg", "jpeg", "gif", "svg"],
videoType: ["mp4", "avi", "wmv", "rmvb", "flv", "mkv"],
audioType: [
"mp3",
"wav",
"amr",
"aac",
"ogg",
"wma",
"flac",
"ape",
"mid",
"wav",
"wma",
"mp3",
"m4a",
"m4r",
"m4p",
"m4b",
"wma",
"wav",
"wma",
"wma",
],
// 图片预览
filepaths: [],
preview: false,
previewData: {
type: "",
url: "",
},
show: false,
};
},
watch: {
value: {
handler(newValue) {
if (newValue) {
if (Array.isArray(newValue)) {
this.FileList = newValue.map((v) => {
let index = v.lastIndexOf("/");
let name = v.slice(index + 1);
return {
name,
url: v,
};
});
} else {
this.FileList = newValue.split(",").map((v) => {
let index = v.lastIndexOf("/");
let name = v.slice(index + 1);
return {
name,
url: v,
};
});
}
} else {
this.FileList = [];
}
},
deep: true,
immediate: true,
},
},
computed: {},
created() {},
methods: {
handleSuccess(response, file, fileList) {
this.FileList = [...fileList];
if (file.status == "success") {
if (file.response && file.response.code === -1) {
let msg = file.response.msg || "上传失败";
this.$message.error(msg);
fileList = fileList.filter((file) => file.response.code !== -1);
}
if (this.limit) {
this.FileList = [...fileList].slice(-this.limit);
}
this.FileList = this.FileList.map((v) => {
if (v.response) {
v.url = v.response.url;
}
return v;
});
let value;
if (Array.isArray(this.value)) {
value = this.FileList.map((v) => v.url);
} else {
value = this.FileList.map((v) => v.url).join(",");
}
this.$emit("change", value);
this.$emit("success", { file, fileList });
}
},
handleRemove(file, fileList) {
let value;
if (Array.isArray(this.value)) {
value = fileList.map((v) => v.url);
} else {
value = fileList.map((v) => v.url).join(",");
}
this.$emit("change", value);
this.$emit("success", { file, fileList });
},
beforeUpload(file) {
let isType = true;
let isExceed = true;
return new Promise((resolve, reject) => {
if (this.accept) {
const fileType = this.accept.split(","); // 限制文件类型
let index = file.name.lastIndexOf(".");
let type = file.name.slice(index);
isType = fileType.includes(type);
}
if (!isType) {
let msg = this.accept.replaceAll(",", "或者");
this.$message.error(`请上传${msg}文件!`);
}
if (this.MB) {
isExceed = file.size / 1024 / 1024 <= this.MB;
}
if (!isExceed) {
this.$message.error(`文件大小不能超过${this.MB}MB!`);
}
if (isType && isExceed) {
resolve(file);
} else {
reject();
}
});
},
// 预览
handlePreview(file) {
let { url } = file;
if (!url) return;
let index = url.lastIndexOf(".");
let type = url.slice(index + 1);
if (this.imageType.includes(type)) {
this.filepaths = [url];
this.preview = true;
} else if (this.videoType.includes(type)) {
this.previewData.type = "video";
this.previewData.url = url;
this.show = true;
} else if (this.audioType.includes(type)) {
this.previewData.type = "audio";
this.previewData.url = url;
this.show = true;
} else {
let a = document.createElement("a");
a.href = url;
a.download = file.name;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
}
},
},
};
</script>
<style lang="less" scoped></style>
......@@ -47,18 +47,11 @@
</div>
</el-form-item>
<el-form-item label="背景图片" prop="bigPath">
<el-upload
name="file"
accept="image/jpeg,image/png"
:file-list="fileList"
:action="api + '/bill/file/commonupload'"
<YUpload
accept=".png,.gif,.jpeg,.jpg"
list-type="picture-card"
:on-remove="handleRemoveImg"
:on-success="handleExampleImgSuccess"
:on-preview="handlePreview"
>
<i class="el-icon-plus"></i>
</el-upload>
v-model="form.bigPath"
></YUpload>
</el-form-item>
<el-form-item label="对接日期" prop="accessTime">
<el-date-picker
......@@ -106,17 +99,6 @@
>确 定</el-button
>
</span>
<!-- 图片查看 -->
<el-image-viewer
v-if="preview"
:appendToBody="false"
:on-close="
() => {
(preview = false), (filepaths = []);
}
"
:url-list="filepaths"
/>
</el-dialog>
</div>
</template>
......@@ -145,9 +127,6 @@ export default {
return {
api: process.env.VUE_APP_API_BASE_URL,
loading: false,
fileList: [],
preview: false,
filepaths: [],
inputVisible: false,
inputValue: "",
form: {
......@@ -227,14 +206,6 @@ export default {
} else {
this.form.tag = [];
}
if (this.form.bigPath) {
this.fileList = [
{
name: this.form.bigPath,
url: this.form.bigPath,
},
];
}
}, 10);
},
// 重置
......@@ -291,31 +262,7 @@ export default {
});
return arr;
},
handleExampleImgSuccess(response, file, fileList) {
if (response.code && response.code == 1) {
let list = fileList.slice(-1);
this.fileList = list.map((v) => {
if (v.response) {
v.url = v.response.url;
}
return v;
});
this.form.bigPath = response.url;
} else {
let msg = response.msg || "上传失败";
this.$message.error(msg);
}
},
// 删除示例图片
handleRemoveImg() {
this.form.bigPath = "";
this.fileList = [];
},
// 预览
handlePreview(file) {
this.filepaths = [file.url];
this.preview = true;
},
handleCloseTag(tag) {
this.form.tag.splice(this.form.tag.indexOf(tag), 1);
},
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment