提交代码
This commit is contained in:
299
src/components/MyComponents/Upload/index.vue
Normal file
299
src/components/MyComponents/Upload/index.vue
Normal file
@ -0,0 +1,299 @@
|
||||
<template>
|
||||
<div class="form-item-box" :style="{ width: width }">
|
||||
<el-upload
|
||||
v-bind="$attrs"
|
||||
:headers="headers"
|
||||
:multiple="false"
|
||||
class="avatar-uploader"
|
||||
:limit="props.limit"
|
||||
:action="actionUrl"
|
||||
list-type="picture-card"
|
||||
:file-list="fileList"
|
||||
show-file-list
|
||||
:on-exceed="handleExceed"
|
||||
:on-success="handlerSuccess"
|
||||
:before-upload="beforeImgUpload"
|
||||
>
|
||||
<template #default>
|
||||
<el-icon> <Plus /> </el-icon>
|
||||
</template>
|
||||
<template #file="{ file }">
|
||||
<div v-if="props.isImg">
|
||||
<img class="el-upload-list__item-thumbnail" :src="file.url" 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
|
||||
v-if="!disabled"
|
||||
class="el-upload-list__item-delete"
|
||||
@click="handleRemove(file, fileList)"
|
||||
>
|
||||
<el-icon>
|
||||
<Delete />
|
||||
</el-icon>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<div v-else>
|
||||
<div class="file-wrap">
|
||||
<span>
|
||||
<svg-icon :icon="getSuffix(file.name)" />
|
||||
</span>
|
||||
<span class="file-name">{{ file.name }}</span>
|
||||
</div>
|
||||
<span class="el-upload-list__item-actions">
|
||||
<span
|
||||
v-if="!disabled"
|
||||
class="el-upload-list__item-delete"
|
||||
@click="handleDownload(file)"
|
||||
>
|
||||
<el-icon>
|
||||
<Download />
|
||||
</el-icon>
|
||||
</span>
|
||||
<span
|
||||
v-if="!disabled"
|
||||
class="el-upload-list__item-delete"
|
||||
@click="handleRemove(file, fileList)"
|
||||
>
|
||||
<el-icon>
|
||||
<Delete />
|
||||
</el-icon>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
</el-upload>
|
||||
<el-dialog v-model="dialogVisible">
|
||||
<img style="width: 100%" :src="dialogImageUrl" alt="" />
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { COMPONENT_WIDTH } from "@/constant";
|
||||
import {
|
||||
ref,
|
||||
defineProps,
|
||||
defineEmits,
|
||||
defineExpose,
|
||||
computed,
|
||||
watch,
|
||||
onMounted
|
||||
} from "vue";
|
||||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
import type from "element-plus/es/components/upload/src/upload.type";
|
||||
import { useStore } from "vuex";
|
||||
const props = defineProps({
|
||||
//获取组件传值
|
||||
modelValue: {
|
||||
type: Array,
|
||||
default: []
|
||||
},
|
||||
limit: {
|
||||
type: Number,
|
||||
default: 1
|
||||
},
|
||||
isImg: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
width: {
|
||||
default: COMPONENT_WIDTH,
|
||||
type: String
|
||||
}
|
||||
});
|
||||
|
||||
const actionUrl = computed(() =>
|
||||
props.isImg
|
||||
? "/mosty-api/mosty-base/minio/image/upload/id"
|
||||
: "/mosty-api/mosty-base/minio/file/upload"
|
||||
);
|
||||
|
||||
const emits = defineEmits(["update:modelValue", "handleChange"]);
|
||||
|
||||
//获取后缀
|
||||
const getSuffix = (fileName) => {
|
||||
let suffix = "";
|
||||
try {
|
||||
suffix = fileName.substr(fileName.lastIndexOf(".") + 1, 4); //截取最后一个点号后4个字符
|
||||
} catch (err) {
|
||||
suffix = "";
|
||||
return "OTHER";
|
||||
}
|
||||
// fileName无后缀返回 false
|
||||
if (!suffix) return "";
|
||||
|
||||
// 图片格式
|
||||
var imglist = ["png", "jpg", "jpeg", "bmp", "gif"];
|
||||
if (imglist.includes(suffix)) return "IMG";
|
||||
|
||||
//txt
|
||||
if (suffix === "txt") return "TXT";
|
||||
|
||||
//excel XLS
|
||||
const excelist = ["xls", "xlsx"];
|
||||
if (excelist.includes(suffix)) return "XLS";
|
||||
|
||||
// 匹配 word
|
||||
var wordlist = ["doc", "docx"];
|
||||
if (wordlist.includes(suffix)) return "DOC";
|
||||
|
||||
//pdf
|
||||
if (suffix === "pdf") return "PDF";
|
||||
|
||||
//视频 音频
|
||||
var videolist = [
|
||||
"mp4",
|
||||
"m2v",
|
||||
"mkv",
|
||||
"rmvb",
|
||||
"wmv",
|
||||
"avi",
|
||||
"flv",
|
||||
"mov",
|
||||
"m4v"
|
||||
];
|
||||
if (videolist.includes(suffix)) return "VIDEO";
|
||||
|
||||
var musiclist = ["mp3", "wav", "wmv"];
|
||||
if (musiclist.includes(suffix)) return "MUSIC";
|
||||
|
||||
var pptlist = ["ppt", "pptx"];
|
||||
if (pptlist.includes(suffix)) return "PPT";
|
||||
|
||||
//压缩包
|
||||
var yslist = ["7z", "rar", "zip", "apz", "ar", "hpk", "hyp", "hbc2"];
|
||||
if (yslist.includes(suffix)) return "YS";
|
||||
|
||||
//否则返回other
|
||||
return "OTHER";
|
||||
};
|
||||
|
||||
const imageUrl = ref("");
|
||||
const store = useStore();
|
||||
const dialogImageUrl = ref("");
|
||||
const dialogVisible = ref(false);
|
||||
const disabled = ref(false);
|
||||
const headers = ref({
|
||||
Authorization: store.getters.token
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
if (props.modelValue) {
|
||||
fileList.value = props.modelValue.map((el) => {
|
||||
return {
|
||||
url: `/mosty-api/mosty-base/minio/image/download/` + el
|
||||
};
|
||||
});
|
||||
}
|
||||
});
|
||||
const fileList = ref([]);
|
||||
const handlerSuccess = (res, file) => {
|
||||
file.url = `/mosty-api/mosty-base/minio/image/download/` + res.data;
|
||||
fileList.value.push(file);
|
||||
props.modelValue.push(res.data);
|
||||
emits("handleChange", props.modelValue);
|
||||
// emits("update:modelValue", props.modelValue);
|
||||
};
|
||||
const handlePreview = (file) => {};
|
||||
const handleExceed = (files, fileList) => {
|
||||
ElMessage.warning(`限制,只能上传${props.limit}个文件或图片`);
|
||||
};
|
||||
|
||||
const beforeImgUpload = (file) => {
|
||||
if (props.isImg) {
|
||||
let isIMG = false;
|
||||
if (getSuffix(file.name) === "IMG") {
|
||||
isIMG = true;
|
||||
}
|
||||
const isLt5M = file.size / 1024 / 1024 < 5;
|
||||
if (!isIMG) {
|
||||
ElMessage.error("上传图片只能是jpg/png/jpeg/bmp/gif格式!");
|
||||
}
|
||||
if (!isLt5M) {
|
||||
ElMessage.error("上传图片大小不能超过 5MB!");
|
||||
}
|
||||
return isIMG && isLt5M;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
const handleAvatarSuccess = (res, file) => {
|
||||
imageUrl.value = URL.createObjectURL(file.raw);
|
||||
};
|
||||
//查询图片
|
||||
const handlePictureCardPreview = (file) => {
|
||||
dialogImageUrl.value = file.url;
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
const handleDownload = (file) => {
|
||||
window.open(file.response.data);
|
||||
};
|
||||
const handleRemove = (file) => {
|
||||
let index = fileList.value.findIndex(function (item) {
|
||||
return item.url === file.url;
|
||||
});
|
||||
fileList.value.splice(index, 1);
|
||||
props.modelValue.splice(index, 1);
|
||||
emits("handleChange", props.modelValue);
|
||||
// emits("update:modelValue", props.modelValue);
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.avatar-uploader .el-upload {
|
||||
border: 1px dashed #d9d9d9;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.avatar-uploader .el-upload:hover {
|
||||
border-color: #409eff;
|
||||
}
|
||||
|
||||
.el-icon.avatar-uploader-icon {
|
||||
font-size: 28px;
|
||||
color: #8c939d;
|
||||
width: 178px;
|
||||
height: 178px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.avatar {
|
||||
width: 178px;
|
||||
height: 178px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.file-wrap {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
::v-deep .svg-icon {
|
||||
font-size: 48px;
|
||||
margin: 28px 0 2px 0;
|
||||
}
|
||||
|
||||
.file-name {
|
||||
width: 88%;
|
||||
font-size: 14px;
|
||||
line-height: 22px;
|
||||
text-align: center;
|
||||
overflow: hidden;
|
||||
/*将对象作为弹性伸缩盒子模型显示*/
|
||||
display: -webkit-box;
|
||||
/*设置子元素排列方式*/
|
||||
-webkit-box-orient: vertical;
|
||||
/*设置显示的行数,多出的部分会显示为...*/
|
||||
-webkit-line-clamp: 2;
|
||||
}
|
||||
}
|
||||
</style>
|
Reference in New Issue
Block a user