Files
2026-09-08 19:49:21 +08:00

671 lines
19 KiB
Vue

<template>
<div>
<el-upload :key="key"
:action="FILE_UPLOAD_ADDRESS"
limit="1" :before-upload="beforeUpload"
list-type="picture-card" :file-list="fileList" :on-success="onSuccess">
<i slot="default" class="el-icon-plus"></i>
<div slot="file" slot-scope="{file}">
<template v-if="resolvingShowByFileName(file.data.filepath) == 1">
<el-image
style="width: 100px; height: 100px"
:src="getFileItemShowIcon(file.data.filepath)"
fit="cover"></el-image>
<!-- <img class="show-img" :src="getFileItemShowIcon(file.filepath)" :alt="file.filename"/>-->
</template>
<template v-else>
<svg aria-hidden="true" style="width: 100px; height: 100px">
<use :xlink:href="getFileItemShowIcon(file.data.filepath)"></use>
</svg>
</template>
<span class="el-upload-list__item-actions">
<span
class="el-upload-list__item-preview"
@click="showSource(file.data)"
>
<i class="el-icon-zoom-in"></i>
</span>
<span
class="el-upload-list__item-delete"
@click="handleDownload(file)"
>
<i class="el-icon-download"></i>
</span>
<span
class="el-upload-list__item-delete"
@click="handleRemove(file)"
>
<i class="el-icon-delete"></i>
</span>
</span>
</div>
</el-upload>
</div>
</template>
<script>
/**
* 文件类型解析
* @type {{isImg: wpUploadFileTypeResolve.isImg}}
*/
let fileTypeResolving = {
/**
* 是否是一张图片
*/
isImg: function (fileItem) {
return fileTypeResolving.resolvingByType(fileItem.type, /image\/(\w)*/)
},
/**
* 通过后缀验证图片
*/
isImgByName: function (fileItemName) {
let checkSuffixArray = ['jpg', 'png', 'jpeg', 'bmp', 'gif', 'webp', 'tif', 'svg', 'wmf'];
return fileTypeResolving.resolvingByName(fileItemName, checkSuffixArray)
},
/**
* 是否是视频
*/
isVideo: function (fileItem) {
return fileTypeResolving.resolvingByType(fileItem.type, /video\/(\w)*/)
},
/**
* 通过后缀验证图片
*/
isVideoByName: function (fileItemName) {
let checkSuffixArray = ['mp4', 'Ogg', 'webm'];
return fileTypeResolving.resolvingByName(fileItemName, checkSuffixArray)
},
/**
* 是否是音频
*/
isAudio: function (fileItem) {
return fileTypeResolving.resolvingByType(fileItem.type, /audio\/(\w)*/)
},
/**
* 通过后缀验证图片
*/
isAudioByName: function (fileItemName) {
let checkSuffixArray = ['mp3', 'ogg', 'wav'];
return fileTypeResolving.resolvingByName(fileItemName, checkSuffixArray)
},
/**
* 是否是doc文件
*/
isDoc: function (fileItemName) {
let checkSuffixArray = ['doc', 'docx', 'dot', 'dotx'];
return fileTypeResolving.resolvingByName(fileItemName, checkSuffixArray);
},
/**
* 是否是excel文件
*/
isExcel: function (fileItemName) {
let checkSuffixArray = ['xls', 'xlsx', 'csv', 'xlt', 'xltx'];
return fileTypeResolving.resolvingByName(fileItemName, checkSuffixArray);
},
/**
* 是否是PPT文件
*/
isPPT: function (fileItemName) {
let checkSuffixArray = ['ppt', 'pptx', 'pot', 'potx', 'odp'];
return fileTypeResolving.resolvingByName(fileItemName, checkSuffixArray);
},
/**
* 是否是Pdf文件
*/
isPdf: function (fileItemName) {
let checkSuffixArray = ['pdf'];
return fileTypeResolving.resolvingByName(fileItemName, checkSuffixArray);
},
/**
* 是否是压缩文件
* @param fileItem
* @returns {boolean}
*/
isZip: function (fileItemName) {
let checkSuffixArray = ['zip', '7z', 'war', 'tar', 'rar', 'jar', 'zipx', 'zix', 'zoo'];
return fileTypeResolving.resolvingByName(fileItemName, checkSuffixArray);
},
isWeb: function (fileItemName) {
let checkSuffixArray = ['html', 'htm'];
return fileTypeResolving.resolvingByName(fileItemName, checkSuffixArray);
},
isTxt: function (fileItemName) {
let checkSuffixArray = ['txt'];
return fileTypeResolving.resolvingByName(fileItemName, checkSuffixArray);
},
isPsd: function (fileItemName) {
let checkSuffixArray = ['psd'];
return fileTypeResolving.resolvingByName(fileItemName, checkSuffixArray);
},
isCad: function (fileItemName) {
let checkSuffixArray = ['cad'];
return fileTypeResolving.resolvingByName(fileItemName, checkSuffixArray);
},
isIso: function (fileItemName) {
let checkSuffixArray = ['iso'];
return fileTypeResolving.resolvingByName(fileItemName, checkSuffixArray);
},
isExe: function (fileItemName) {
let checkSuffixArray = ['exe'];
return fileTypeResolving.resolvingByName(fileItemName, checkSuffixArray);
},
/**
* 根据文件类型来解析
* @param fileType 文件类型
* @param checkTypeModel 文件类型模型,如:image\/(\w)*
* @returns {boolean}
*/
resolvingByType: function (fileType, checkTypeModel) {
if (checkTypeModel.test(fileType)) {
return true;
}
return false;
},
/**
* 根据名字和名字后缀名来验证文件
* @param fileName 文件名
* @param checkSuffixArray 文件类型包含的后缀
*/
resolvingByName: function (fileName, checkSuffixArray) {
let suffixName = wpUploadFileTools.getSuffixNameByFileName(fileName);
// 名字是否有效
if (!wpUploadDataValid.isValidStr(suffixName)) {
// 无效直接返回false
return false;
}
suffixName = suffixName.trim();
suffixName = suffixName.toLowerCase();
if (checkSuffixArray.indexOf(suffixName) != -1) {
return true;
}
return false;
}
}
/**
* 文件工具
* @type {{}}
*/
let wpUploadFileTools = {
/**
* 获取文件显示模版
* @param fileItem
*/
wapFileItemShow: function (fileItem) {
return wpUploadFileTools.wapFileItemShowBase(fileItem, false);
},
/**
* 包装已上传的文件列表
*/
wapFileItemShowWithUpload(uploadFile) {
return wpUploadFileTools.wapFileItemShowBase(uploadFile, true);
},
/**
* 获取文件显示的基本操作
*/
wapFileItemShowBase(fileItem, isUploaded = false) {
let fileName = "";
let suffix = "";
let show = "";
let showIcon = "";
if (!isUploaded) {
fileName = fileItem.name;
suffix = wpUploadFileTools.getSuffixNameByFileName(fileName);
show = wpUploadFileTools.resolvingShow(fileItem);
showIcon = wpUploadFileShowResolving.getFileItemShowIcon(show, fileItem, false);
} else {
fileName = fileItem.name ? fileItem.name : wpUploadFileTools.resolvingUrlFileName(fileItem.url);
let fileNameGetOFuRL = wpUploadFileTools.resolvingUrlFileName(fileItem.url);
suffix = wpUploadFileTools.getSuffixNameByFileName(fileNameGetOFuRL);
show = wpUploadFileTools.resolvingShowByFileName(fileNameGetOFuRL);
showIcon = wpUploadFileShowResolving.getFileItemShowIcon(show, fileItem.url, true);
}
let fileItemShow = {
// 文件的id
id: wpUploadFileTools.uuid(),
// 文件对象
file: null,
// 文件的类型
type: null,
// 文件的大小
size: null,
// 文件的名字
name: fileName,
// 文件地址
url: null,
// 后缀
suffix: suffix,
// 显示的类型
show: show,
// 显示的图标或者图片地址
showIcon: showIcon,
// 显示进度条
processStatus: {
show: false,
width: 0,
isFail: false
},
// 文件来源,0选择文件上传,1回显文件
fileSource: 0,
// 状态0未上传,失败也会转到0,1正在上传,2已经上传
status: 0,
// 上传文件的描述
fileDes: null
}
if (!isUploaded) {
// 如果非选择文件下面三个属性为null
fileItemShow.file = fileItem;
fileItemShow.type = fileItem.type;
fileItemShow.size = fileItem.size;
} else {
// 文件描述
fileItemShow.status = 2;
fileItemShow.fileDes = fileItem;
fileItemShow.fileSource = 1;
fileItemShow.url = fileItem.url;
}
return fileItemShow;
},
/**
* 解析URL的文件名字
*/
resolvingUrlFileName: function (fileUrl) {
let index = fileUrl.lastIndexOf("/");
if (index <= 0) {
index = fileUrl.lastIndexOf("\\");
}
index = index + 1;
let fileName = fileUrl.substring(index, fileUrl.length);
return fileName;
},
/**
* 获取文件名后缀
* @param fileName 文件名全名
* */
getSuffixNameByFileName: function (fileName) {
let str = fileName;
let index = str.lastIndexOf(".");
if (index < 0) {
return "";
}
let pos = index + 1;
return str.substring(pos, str.length);
},
/**
* 解析显示类型
* @param fileItem 文件
* @returns {number}
*/
resolvingShow: function (fileItem) {
// 默认0普通文件
let showResult = 0;
if (wpUploadFileTypeResolving.isImg(fileItem)) {
showResult = 1;
} else if (wpUploadFileTypeResolving.isVideo(fileItem)) {
showResult = 2;
} else if (wpUploadFileTypeResolving.isAudio(fileItem)) {
showResult = 3;
} else if (wpUploadFileTypeResolving.isDoc(fileItem.name)) {
showResult = 4;
} else if (wpUploadFileTypeResolving.isExcel(fileItem.name)) {
showResult = 5;
} else if (wpUploadFileTypeResolving.isPPT(fileItem.name)) {
showResult = 6;
} else if (wpUploadFileTypeResolving.isPdf(fileItem.name)) {
showResult = 7;
} else if (wpUploadFileTypeResolving.isZip(fileItem.name)) {
showResult = 8;
} else if (wpUploadFileTypeResolving.isWeb(fileItem.name)) {
showResult = 9;
} else if (wpUploadFileTypeResolving.isTxt(fileItem.name)) {
showResult = 10;
} else if (wpUploadFileTypeResolving.isPsd(fileItem.name)) {
showResult = 11;
} else if (wpUploadFileTypeResolving.isCad(fileItem.name)) {
showResult = 12;
} else if (wpUploadFileTypeResolving.isIso(fileItem.name)) {
showResult = 13;
} else if (wpUploadFileTypeResolving.isExe(fileItem.name)) {
showResult = 14;
}
return showResult
},
/**
* 解析显示类型
* @param fileItem 文件
* @returns {number}
*/
resolvingShowByFileName: function (fileItemName) {
// 默认0普通文件
let showResult = 0;
if (wpUploadFileTypeResolving.isImgByName(fileItemName)) {
showResult = 1;
} else if (wpUploadFileTypeResolving.isVideoByName(fileItemName)) {
showResult = 2;
} else if (wpUploadFileTypeResolving.isAudioByName(fileItemName)) {
showResult = 3;
} else if (wpUploadFileTypeResolving.isDoc(fileItemName)) {
showResult = 4;
} else if (wpUploadFileTypeResolving.isExcel(fileItemName)) {
showResult = 5;
} else if (wpUploadFileTypeResolving.isPPT(fileItemName)) {
showResult = 6;
} else if (wpUploadFileTypeResolving.isPdf(fileItemName)) {
showResult = 7;
} else if (wpUploadFileTypeResolving.isZip(fileItemName)) {
showResult = 8;
} else if (wpUploadFileTypeResolving.isWeb(fileItemName)) {
showResult = 9;
} else if (wpUploadFileTypeResolving.isTxt(fileItemName)) {
showResult = 10;
} else if (wpUploadFileTypeResolving.isPsd(fileItemName)) {
showResult = 11;
} else if (wpUploadFileTypeResolving.isCad(fileItemName)) {
showResult = 12;
} else if (wpUploadFileTypeResolving.isIso(fileItemName)) {
showResult = 13;
} else if (wpUploadFileTypeResolving.isExe(fileItemName)) {
showResult = 14;
}
return showResult
},
/**
* 生成UUID
* @returns {string}
*/
uuid: function () {
let str = wpUploadFileTools.uuidFull();
str = str.replace(/-/g, "");
return str;
},
uuidFull() {
let s = []
let hexDigits = "0123456789abcdef"
for (var i = 0; i < 36; i++) {
s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1)
}
s[14] = "4"
s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1)
s[8] = s[13] = s[18] = s[23] = "-"
let uuid = s.join("")
return uuid
},
/**
* 禁止某个dom的某个事件
*/
disableObjEvent(domObj, eventName) {
domObj.addEventListener(eventName, function (e) {
e.preventDefault();
})
}
}
/**
* 数据验证工具
* @type {{isValid: wpUploadDataValid.isValid}}
*/
let wpUploadDataValid = {
isValid: function (obj) {
if (undefined === obj || null === obj) {
return false;
}
return true;
},
isValidStr: function (str) {
let isValidObj = wpUploadDataValid.isValid(str);
if (!isValidObj) {
return isValidObj;
}
str = str.trim();
if ("" == str || '' == str) {
return false;
}
return true;
},
isValidArray(array) {
if (null == array || array == undefined || array.length <= 0) {
return false;
}
return true;
}
}
module.exports = {
props: {
files: Array,
type: {
type: Array,
default: ['jpg', 'png', 'doc', 'docx', 'xls', 'xlsx', 'pdf']
},
max_size: {
type: Number,
default: 5 * 1024 * 1024
},
view: {
type: Boolean,
default: false
}
},
watch: {
files(val) {
this.updateFileList(val)
this.key = Math.random()
}
},
data() {
return {
key: Math.random(),
dialogImageUrl: '',
dialogVisible: false,
fileList: []
}
},
methods: {
/**
* 查看资源
*/
showSource(showItem) {
const show = this.resolvingShowByFileName(showItem.filepath)
if (show == 1 || show == 2 || show == 3) {
dd3s.showpic(showItem.filepath)
} else if (show == 4 || show == 5) {
dd3s.preview(showItem.filepath, showItem.id)
}
},
/**
* 解析显示类型
* @param fileItem 文件
* @returns {number}
*/
resolvingShowByFileName(fileItemName) {
// 默认0普通文件
let showResult = 0;
if (fileTypeResolving.isImgByName(fileItemName)) {
showResult = 1;
} else if (fileTypeResolving.isVideoByName(fileItemName)) {
showResult = 2;
} else if (fileTypeResolving.isAudioByName(fileItemName)) {
showResult = 3;
} else if (fileTypeResolving.isDoc(fileItemName)) {
showResult = 4;
} else if (fileTypeResolving.isExcel(fileItemName)) {
showResult = 5;
} else if (fileTypeResolving.isPPT(fileItemName)) {
showResult = 6;
} else if (fileTypeResolving.isPdf(fileItemName)) {
showResult = 7;
} else if (fileTypeResolving.isZip(fileItemName)) {
showResult = 8;
} else if (fileTypeResolving.isWeb(fileItemName)) {
showResult = 9;
} else if (fileTypeResolving.isTxt(fileItemName)) {
showResult = 10;
} else if (fileTypeResolving.isPsd(fileItemName)) {
showResult = 11;
} else if (fileTypeResolving.isCad(fileItemName)) {
showResult = 12;
} else if (fileTypeResolving.isIso(fileItemName)) {
showResult = 13;
} else if (fileTypeResolving.isExe(fileItemName)) {
showResult = 14;
}
return showResult
},
/**
* 获取文件显示图标
* @param filePath
* @returns {string}
*/
getFileItemShowIcon(filePath) {
let showIcon = '';
switch (this.resolvingShowByFileName(filePath)) {
case 0:
showIcon = "#icon-yunpanlogo-3";
break;
// 图片
case 1:
showIcon = this.getImgShowIcon(filePath);
break;
// 视频
case 2:
showIcon = "#icon-yunpanlogo-6";
break;
// 音乐
case 3:
showIcon = "#icon-yunpanlogo-4";
break;
// doc
case 4:
showIcon = "#icon-yunpanlogo-2";
break;
// excel
case 5:
showIcon = "#icon-yunpanlogo-";
break;
// ppt
case 6:
showIcon = "#icon-yunpanlogo-1";
break;
// pdf
case 7:
showIcon = "#icon-yunpanlogo-12";
break;
// zip
case 8:
showIcon = "#icon-yasuobao";
break;
// web文件
case 9:
showIcon = "#icon-yunpanlogo-5";
break;
// txt文件
case 10:
showIcon = "#icon-yunpanlogo-7";
break;
// PSD
case 11:
showIcon = "#icon-yunpanlogo-10";
break;
// cad
case 12:
showIcon = "#icon-yunpanlogo-11";
break;
// ISO
case 13:
showIcon = "#icon-yunpanlogo-8";
break;
// 可执行
case 14:
showIcon = "#icon-yunpanlogo-9";
break;
// 普通文件
default:
showIcon = "#icon-yunpanlogo-3";
}
return showIcon;
},
/**
* 获取图片的显示图标
* @param fileItem
* @returns {string|*}
*/
getImgShowIcon(fileItem) {
return FILE_DOMAIN + fileItem;
},
updateFileList(val) {
if (!val || !val.length) {
this.fileList = []
return
}
this.fileList = val.map(v => {
return {data: v, uid: v.id, name: v.filename, url: FILE_DOMAIN + v.filepath, status: 'success'}
})
},
change() {
this.$emit("update:files", this.fileList.map(v => v.data))
},
onSuccess(response, file, fileList) {
const {data} = response
file.data = data
this.fileList = fileList
this.change()
},
beforeUpload(file) {
const type = this.type.includes(file.name.split('.')[1].toLowerCase());
const size = file.size < this.max_size;
if (!type) {
this.$message.warning(`上传文件只能是 ${this.type.map(v => v.toUpperCase()).join("/")} 格式!`);
}
if (!size) {
this.$message.warning(`上传文件大小不能超过 ${this.max_size / 1024 / 1024} MB!`);
}
return type && size;
},
handleRemove(file) {
if (file.data) {
const {filename, filepath} = file.data
$.post(FILE_DELETE_ADDRESS, {filepath})
this.fileList.splice(this.fileList.findIndex(v => v == file), 1)
this.change()
}
},
handleDownload(file) {
const {filepath, filename} = file.data
if (filepath && filename) {
dd3s.download(filepath, filename)
}
}
},
created() {
this.updateFileList(this.files)
}
}
</script>
<style>
.el-upload--picture-card, .el-upload-list--picture-card .el-upload-list__item {
width: 100px;
height: 100px;
}
.el-upload--picture-card {
line-height: 110px;
}
.el-upload-list--picture-card .el-upload-list__item-actions span + span {
margin-left: 5px;
}
.el-upload-list--picture-card .el-upload-list__item-actions {
font-size: 16px;
}
</style>