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

775 lines
21 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div v-if="view" class="viewFile">
<div v-for="(file,index) in files" class="viewFileItem" title="点击查看" @click="showSource(file,index,$event)">
<template v-if="resolvingShowByFileName(file.filename) == 1">
<el-image
:src="APP_DOMAIN + '/file_server/fileStreamPreview?id=' + file.id"
fit="cover"
style="width: 100%; height: 100%;"></el-image>
<!-- <img class="show-img" :src="getFileItemShowIcon(file.filepath)" :alt="file.filename"/>-->
</template>
<template v-else>
<svg aria-hidden="true">
<use
:xlink:href="wpUploadFileShowResolving.getFileItemShowIcon(resolvingShowByFileName(file.filename),file.filepath,true)"></use>
</svg>
</template>
<div :title="file.filename" class="viewFileName">{{ file.filename }}</div>
</div>
</div>
{{ fileList }}
<el-upload
v-else-if="card"
:limit="max"
:action="FILE_UPLOAD_ADDRESS"
:before-upload="beforeUpload"
:on-remove="handleRemove"
:on-success="onSuccess"
:file-list="fileList"
:on-exceed="handleExceed"
class="x100000"
drag
:on-preview="handlePreview"
:data="{source:source}"
multiple>
<i class="el-icon-upload"></i>
<div class="el-upload__text">
将文件拖到此处<em>点击上传</em>
<slot name="el-upload__tip"></slot>
</div>
</el-upload>
<el-upload
v-else
:limit="max"
:action="FILE_UPLOAD_ADDRESS"
:before-upload="beforeUpload"
:on-remove="handleRemove"
:on-success="onSuccess"
:file-list="fileList"
:on-exceed="handleExceed"
:on-preview="handlePreview"
:data="{source:source}"
class="x100000"
multiple>
<el-button size="small" type="primary">点击上传</el-button>
<slot name="el-upload__tip"></slot>
</el-upload>
</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', 'jpeg', 'png', 'doc', 'docx', 'xls', 'xlsx', 'pdf', 'zip']
},
max: {
type: Number,
default: 5
},
max_size: {
type: Number,
default: 20 * 1024 * 1024
},
view: {
type: Boolean,
default: false
},
card: {
type: Boolean,
default: false
},
del: {
type: Boolean,
default: true
},
//"来源(1.文件管理 2.业务上传)"
source: {
type: Number,
default: 2
}
},
data() {
return {
fileList: []
}
},
watch: {
files(val) {
this.updateFileList(val)
}
},
methods: {
/**
* 查看资源
*/
showSource(showItem, index, e) {
const viewFileParent = $(e.target).closest(".viewFile")
const show = this.resolvingShowByFileName(showItem.filename)
if (show == 1 || show == 2 || show == 3) {
const vv = new Viewer(viewFileParent.clone()[0], {
url: 'src',
initialViewIndex: index
})
vv.show()
} else if (show == 4 || show == 5 || show == 7) {
preview(showItem.filename, 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, status: 'success'}
})
},
change(fileList) {
this.$emit("update:files", fileList.map(v => v.data))
},
handleExceed(files, fileList) {
this.$message.warning(`当前限制选择 ${this.max} 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`);
},
onSuccess(response, file, fileList) {
debugger
if (response.code === 0) {
const {data} = response
file.data = data
this.change(fileList)
} else {
this.$message.warning(response.msg)
const s = fileList.filter(f => (f.response && f.response.code === 0) || !f.response)
this.change(s)
}
},
beforeUpload(file) {
const lastIndexOf = file.name.lastIndexOf(".")
const type = this.type.map(v => v.toLowerCase()).includes(file.name.substr(lastIndexOf + 1).toLowerCase())
const size = file.size < this.max_size;
if (!type) {
this.$message.warning(`上传文件只能是 ${this.type.map(v => v.toLowerCase()).join("/")} 格式!`);
}
if (!size) {
this.$message.warning(`上传文件大小不能超过 ${this.max_size / 1024 / 1024} MB!`);
}
return type && size;
},
async handleRemove(file, fileList) {
if (file.data) {
const {id} = file.data
if (this.del) {
const resp = await $.post(FILE_DELETE_ADDRESS, {id})
if (resp.code === 0) {
this.$message.success(resp.msg)
} else {
this.$message.warning(resp.msg)
}
}
this.change(fileList)
}
},
handlePreview(file) {
if (file.data) {
const {filename, id} = file.data
preview(filename, id)
}
},
},
created() {
this.updateFileList(this.files)
}
}
</script>
<style>
.viewFileName {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 24px;
line-height: 24px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
padding: 0 10px;
color: white;
background-color: rgb(160, 160, 160);
border-radius: 2px;
opacity: .95;
}
.viewFile {
position: relative;
display: flex;
width: 100%;
max-height: 256px;
flex-direction: row;
flex-wrap: wrap;
overflow-y: auto;
overflow-x: hidden;
height: 150px;
}
.viewFileItem {
width: 118px;
height: 118px;
margin-right: 10px;
position: relative;
transition: all 500ms;
border-radius: 5px;
cursor: pointer;
margin-bottom: 10px;
}
.viewFileItem:hover {
background-color: rgb(230, 230, 230);
}
.viewFileItem img {
padding: 10px 10px;
}
.viewFileItem svg {
width: 100%;
height: 100%;
}
.x100000 .el-upload-dragger {
height: 120px;
width: 100%;
}
.x100000 .el-upload {
width: 100%;
text-align: left;
}
.el-upload-dragger .el-icon-upload {
font-size: 54px;
line-height: 0;
}
</style>