Files
ba_web/src/components/MyComponents/FileUpload/index.vue

248 lines
6.1 KiB
Vue
Raw Normal View History

2025-09-22 09:01:41 +08:00
<template>
<div class="main-box">
<div class="file_box" v-for="(item, index) in fileList" :key="index">
<div class="show_file" :style="{ width: width, height: width }">
<div class="icon_box_y" :style="{ width: width, height: width }">
<svg-icon :icon="getSuffix(item.url)" />
<span class="file_name_box">{{ item.name }}</span>
</div>
<div class="load_and_del" :style="{ width: width, height: width }">
<el-icon class="load_and_del_icon" :size="18" color="#aaaaaa">
<DeleteFilled v-if="props.isEdit" @click="delFile(index)" />
</el-icon>
<el-icon class="load_and_del_icon" :size="18" color="#aaaaaa">
<Download @click="downloadFile(item.url)" />
</el-icon>
</div>
</div>
</div>
<div class="file_box" v-if="fileList.length != props.limit && props.isEdit">
<div class="upload_img" :style="{ width: width, height: width }">
<div class="icon_box" :style="{ width: width, height: width }">
<el-icon :size="30" color="#aaaaaa">
<Plus />
</el-icon>
</div>
<div class="file_box_item" :style="{ width: width, height: width }">
<input
type="file"
:style="{ width: width, height: width }"
class="file_input"
id="file"
@change="fileChange"
/>
</div>
</div>
</div>
</div>
</template>
<script setup>
import {
ref,
defineProps,
defineEmits,
defineExpose,
computed,
onMounted
} from "vue";
import { ElMessage, ElMessageBox } from "element-plus";
import request from "@/utils/request";
import axios from "axios";
const props = defineProps({
modelValue: {
type: String,
default: ""
},
width: {
type: String,
default: "150px"
},
limit: {
type: Number,
default: 1
},
isEdit: {
type: Boolean,
default: false
}
});
const fileList = ref([]);
const count = ref(0); // 上传的数量
const emits = defineEmits(["update:modelValue", "handleChange"]);
//获取后缀
const getSuffix = (fileName) => {
let suffix = "";
try {
suffix = fileName.substr(fileName.lastIndexOf(".") + 1, 4);
if (suffix.indexOf("?") !== -1) suffix = suffix.replaceAll("?", "");
} 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";
};
// 删除
function delFile(index) {
fileList.value = fileList.value.filter((item, i) => {
return i !== index;
});
}
// 文件下载
function downloadFile(url) {
2025-09-26 12:56:52 +08:00
window.open('/bagl/mosty-base/minio/image/download/'+url, "_blank");
2025-09-22 09:01:41 +08:00
}
// 选择文件
function fileChange(e) {
let file = document.getElementById("file").files[0];
let name = file.name;
let formData = new FormData();
formData.append("file", file);
axios
2025-09-26 12:56:52 +08:00
.post("/bagl/mosty-base/minio/image/upload/id", formData, {
2025-09-22 09:01:41 +08:00
"Content-type": "multipart/form-data"
})
.then((res) => {
if (res.status == 200 && res.data && res.data.code === 10000) {
let url = res.data.data;
let f = {
url: url,
name: name
};
fileList.value.push(f);
count.value = count.value + 1;
let list = fileList.value.map((item) => {
return item.url;
});
emits("handleChange", JSON.stringify(list));
} else {
ElMessage.warning("文件上传失败");
}
});
}
onMounted(() => {
if (props.modelValue) {
let list = JSON.parse(props.modelValue);
list.forEach((item, index) => {
let temp = {
url: item,
name: "文件" + (index + 1)
};
fileList.value.push(temp);
});
count.value = list.length;
}
});
</script>
<style scoped lang="scss">
.main-box {
width: 100%;
.file_box {
background-color: #112b63;
border: 1px dashed #4579b5;
margin: 10px 0 0 10px;
border-radius: 5px;
position: relative;
.show_file {
overflow: hidden;
box-sizing: border-box;
&:hover > .load_and_del {
display: block;
}
.load_and_del {
display: none;
position: absolute;
top: 0;
left: 0;
.load_and_del_icon {
cursor: pointer;
margin-left:5px;
margin-top: 5px;
}
}
.icon_box_y {
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
.file_name_box {
margin-top: 10px;
width: 80%;
line-height: 30px;
height: 30px;
overflow: hidden;
text-align: center;
}
}
::v-deep .svg-icon {
font-size: 48px;
}
}
.upload_img {
position: relative;
.icon_box {
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
position: relative;
z-index: 1;
}
.file_box_item {
position: absolute;
opacity: 0;
z-index: 2;
top: 0;
left: 0;
.file_input {
cursor: pointer;
}
}
.file_box_item_show {
position: absolute;
top: 0;
left: 0;
}
}
}
}
</style>