first commit

This commit is contained in:
2025-02-20 13:46:19 +08:00
commit 38fbfdaef6
37 changed files with 908 additions and 0 deletions
+286
View File
@@ -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>