FileManage/web/src/views/special/document/index.vue
2025-03-19 09:17:05 +08:00

1004 lines
34 KiB
Vue
Raw 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.

<script lang="ts">
export default {
name: "document",//文档管理
};
</script>
<script setup lang="ts">
import { ref, onMounted, nextTick, defineAsyncComponent } from "vue";
import { useAppStore } from '@/store/modules/app';
import { ElMessageBox, ElMessage } from "element-plus";
import { Search } from '@element-plus/icons-vue'
import Page from '@/components/Pagination/page.vue';
import AudioPlayer from '@/components/file/preview/AudioPlayer.vue';
import { batchDeleteReq } from "@/api/file-operator";
import { projectList, getNodesTree, addNodes, updateNodes, deleteNodesById, getFilesPage, addFiles, updateFiles, deleteFilesById, deleteFilesByIds } from "@/api/document";
import ZUpload from '@/components/file/ZUpload.vue'
import useFileUpload from "@/components/file/file/useFileUpload";
import useHeaderStorageList from "@/components/header/useHeaderStorageList";
import useFileData from "@/components/file/file/useFileData";
// 在顶部添加导入
import PDFImg from '@/assets/fileimg/PDF.png'
import WordImg from '@/assets/fileimg/word.png'
import ExcelImg from '@/assets/fileimg/excel.png'
import PPTImg from '@/assets/fileimg/ppt.png'
import ZipImg from '@/assets/fileimg/zip.png'
import Mp3Img from '@/assets/fileimg/mp3.png'
import Mp4Img from '@/assets/fileimg/mp4.png'
import ImageImg from '@/assets/fileimg/img.png'
import TextImg from '@/assets/fileimg/text_line.png'
// 文件预览相关
import Viewfile from '@/views/component/Viewfile.vue'
import useFilePreview from "@/components/file/file/useFilePreview";
import MarkdownViewerAsyncLoading from "@/components/file/preview/MarkdownViewerAsyncLoading.vue";
import VideoPlayerAsyncLoading from "@/components/file/preview/VideoPlayerAsyncLoading.vue";
import TextViewerAsyncLoading from "@/components/file/preview/TextViewerAsyncLoading.vue";
import MarkdownViewerDialogAsyncLoading from "@/components/file/preview/MarkdownViewerDialogAsyncLoading.vue";
const { dialogVideoVisible, dialogTextVisible, dialogPdfVisible, dialogOfficeVisible, dialog3dVisible } = useFilePreview();
const { openUploadDialog, openUploadFolderDialog, uploadProgressInfoStatistics, clearALlFinishedUploadFile } = useFileUpload();
const { currentStorageKey } = useHeaderStorageList();
const { openRow } = useFileData();
onMounted(() => {
getProject()
});
//拖动条
const vMove = {
mounted(el: any) {
el.onmousedown = function (e: any) {
var init = e.clientX;
var parent: any = document.getElementById("silderLeft");
const initWidth: any = parent.offsetWidth;
document.onmousemove = function (e) {
var end = e.clientX;
var newWidth = end - init + initWidth;
parent.style.width = newWidth + "px";
};
document.onmouseup = function () {
document.onmousemove = document.onmouseup = null;
};
};
}
}
//左侧树的选择框
const projectId = ref()
const projectArr = ref([])
//获取所有项目
function getProject() {
projectList().then((res: any) => {
projectArr.value = res.data
projectId.value = projectArr.value[0].id
gettreedata()
})
}
//左侧树配置
const treedata = ref([])
const treeloading = ref(false)
const defaultProps = {
children: "children",
label: "nodeName"
};
const treeForm = ref({
projectId: '',
nodeName: '',
})
//获取树数据
const treeRef = ref();
function gettreedata() {
treeloading.value = true
treeForm.value.projectId = projectId.value
getNodesTree(treeForm.value).then((res: any) => {
treedata.value = res.data
treeloading.value = false
pathid.value = treedata.value[0].id
nextTick(() => {
treeRef.value?.setCurrentKey(pathid.value);
});
getdata()
})
}
const pathid = ref()
function handleNodeClick(data: any, node: any) {
pathid.value = data.id
getdata()
}
//子项目配置
const frame = ref(false)
const title = ref()
const ruleFormRef = ref()
const projectForme: any = ref({
projectId: '',//所属项目id
parentId: "",//父节点id
nodeType: "",//节点类型
nodeName: "",//节点名称
})
//用户弹窗规则定义
const moderules = ref({
nodeName: [{ required: true, message: "请输入节点名称", trigger: "blur" }],
});
const moderqqqules = ref({
fileName: [{ required: true, message: "请输入文件/文件夹名称", trigger: "blur" },
{ pattern: /^[^<>:"/\\|?*]*$/, message: "名称不能包含特殊字符 [<>:\"/\\\\|?*]", trigger: "blur" }
],
});
//新增子项目
function addSubItem(row: any) {
frame.value = true
projectForme.value = {
projectId: '',//所属项目id
parentId: "",//父节点id
nodeType: "",//节点类型
nodeName: "",//节点名称
}
projectForme.value.projectId = projectId.value
if (row.nodeType == '00') {
projectForme.value.parentId = '00'
} else {
projectForme.value.parentId = row.id
}
if (row.nodeType == '00') {
title.value = "添加子项目"
projectForme.value.nodeType = '01'
} else if (row.nodeType == '01') {
title.value = "添加课题"
projectForme.value.nodeType = '02'
} else if (row.nodeType == '02') {
title.value = "添加年度"
projectForme.value.nodeType = '03'
} else if (row.nodeType == '03') {
title.value = "添加主题"
projectForme.value.nodeType = '04'
}
}
//修改子项目
function editSubItem(row: any) {
if (row.nodeType == '01') {
title.value = "修改子项目"
} else if (row.nodeType == '02') {
title.value = "修改课题"
} else if (row.nodeType == '03') {
title.value = "修改年度"
} else if (row.nodeType == '04') {
title.value = "修改主题"
}
// title.value = "修改子项目"
frame.value = true
if (row.subRegions) {
delete row.subRegions
}
if (row.createTime) {
delete row.createTime
}
projectForme.value = JSON.parse(JSON.stringify(row))
}
//表单确定
async function submitForm(formEl: any) {
if (!formEl) return
await formEl.validate((valid: any, fields: any) => {
if (valid) {
if (projectForme.value.id) {
updateNodes(projectForme.value).then((res: any) => {
if (res.code == 0) {
gettreedata()
ElMessage.success("修改成功")
frame.value = false
}
})
} else {
addNodes(projectForme.value).then((res: any) => {
if (res.code == 0) {
gettreedata()
ElMessage.success("添加成功")
frame.value = false
}
})
}
}
})
}
//弹框关闭
function handleClose(formEl: any) {
// if (!formEl) return
// formEl.resetFields()
frame.value = false
}
//删除子节点
function delSubItem(row: any) {
ElMessageBox.confirm(
'您确定要删除该项目吗?',
'警告',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}
)
.then(() => {
deleteNodesById({ id: row.id }).then((res: any) => {
if (res.code == 0) {
gettreedata()
ElMessage({
type: 'success',
message: '删除成功',
})
}
})
})
}
//表格数据配置
const queryParams: any = ref({
current: 1,
size: 20,
fileName: '',
startDate: '',
endDate: '',
keywords: '',
nodeId: '',//节点ID
projectId: '',//项目Id
});
const dataarr = ref([])
//定义表格数据
const tableData: any = ref([]);
const total = ref(0);
// 表格加载
const loading = ref(false)
//获取表格数据
function getdata() {
loading.value = true
console.log(dataarr.value)
if (dataarr.value && dataarr.value.length > 0) {
queryParams.value.startDate = dataarr.value[0]
queryParams.value.endDate = dataarr.value[1]
} else {
queryParams.value.startDate = ''
queryParams.value.endDate = ''
}
queryParams.value.nodeId = pathid.value
queryParams.value.projectId = projectId.value
getFilesPage(queryParams.value).then((res: any) => {
queryParams.value.current = res.data.current
queryParams.value.size = res.data.size
total.value = res.data.total
loading.value = false
tableData.value = res.data.records
})
}
//新增文件对象
const fileObj: any = ref({
projectId: '', //所属项目ID
nodeId: '', //节点ID
fileName: '', //文件名称
filePath: '', //文件对象存储路径
keywords: '', //关键字
description: '', //文件描述
fileSize: '', //M
})
//上传组件
const upfile = ref(false)
function openFile() {
localStorage.setItem('filepath', findPathById(treedata.value, pathid.value));
localStorage.setItem('storageKey', JSON.stringify(['minio']));
upfile.value = true
fileObj.value = {
projectId: '', //所属项目ID
nodeId: '', //节点ID
fileName: '', //文件名称
filePath: '', //文件对象存储路径
keywords: '', //关键字
description: '', //文件描述
fileSize: '', //M
}
judge.value = true
}
//修改文件
const judge = ref(false)
function editfile(row: any, item: any) {
upfile.value = true
fileObj.value = JSON.parse(JSON.stringify(row))
if (item) {
title.value = "修改文件"
} else {
title.value = "重命名"
}
judge.value = item
}
// 如果有上传完成的文件,关闭对话框时调用 close 方法刷新文件列表
const emit = defineEmits([])
const closeDialog = () => {
let deleteCount = clearALlFinishedUploadFile();
if (deleteCount > 0) {
emit('close');
}
}
function fileClose() {
closeDialog()
upfile.value = false
let fileArr = JSON.parse(localStorage.getItem('fileArr'))
fileArr.forEach((item: any) => {
delfileOne(item)
})
}
//删除文件
function delfileOne(row: any) {
const parmas = {
deleteItems: [
{
name: row.name,
password: "",
path: findPathById(treedata.value, pathid.value),
type: "FILE"
}
],
storageKey: "minio"
}
batchDeleteReq(JSON.stringify(parmas)).then((res) => {
})
}
//字节转mb
function bytesToMB(bytes: any) {
return bytes / Math.pow(1024, 2);
}
//上传确定
function submitfile() {
// console.log( )
if (fileObj.value.id) {
updateFiles(fileObj.value).then((res: any) => {
if (res.code == 0) {
closeDialog()
ElMessage.success('修改成功')
getdata()
upfile.value = false
}
})
} else {
let fileArr: any
if (localStorage.getItem('fileArr')) {
fileArr = JSON.parse(localStorage.getItem('fileArr'))
} else {
ElMessage.warning('请先选择文件')
return
}
let fileName = []
let fileSize = []
if (fileArr.length > 0) {
fileArr.forEach((item: any) => {
fileName.push(item.name)
fileSize.push(bytesToMB(item.size))
})
}
fileObj.value.projectId = projectId.value
fileObj.value.nodeId = pathid.value
fileObj.value.filePath = findPathById(treedata.value, pathid.value)
fileObj.value.fileName = fileName.join(',')
fileObj.value.fileSize = fileSize.join(',')
addFiles(fileObj.value).then((res: any) => {
if (res.code == 0) {
closeDialog()
ElMessage.success('增加成功')
getdata()
upfile.value = false
localStorage.setItem('fileArr', '');
}
})
}
}
//单个删除文件
function delfile(row: any) {
ElMessageBox.confirm(
'您确定要删除该文件吗?',
'警告',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}
)
.then(() => {
deleteFilesById({ id: row.id }).then((res: any) => {
if (res.code == 0) {
getdata()
ElMessage({
type: 'success',
message: '删除成功',
})
}
})
})
}
//多个删除文件
//表格多选
const tableIdarr = ref([])
function handleSelectionChange(val: any) {
tableIdarr.value = val
}
//多选删除
function delprojectArr() {
const ids = []
tableIdarr.value.forEach((item: any) => {
ids.push(item.id)
})
ElMessageBox.confirm(
'您确定要删除这些项目吗?',
'警告',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}
)
.then(() => {
deleteFilesByIds({ ids: ids.join(',') }).then((res: any) => {
if (res.code == 0) {
ElMessage({
type: 'success',
message: '删除成功',
})
getdata()
}
})
})
}
//下载
function xiafile(row: any) {
ElMessageBox.confirm(
'您确定要下载该文件吗?',
'警告',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}
)
.then(() => {
window.open(row.url);
})
}
//多选下载
function xiafilemony() {
ElMessageBox.confirm(
'您确定要下载这些项目吗?',
'警告',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}
)
.then(() => {
tableIdarr.value.forEach((item: any) => {
if (item.url) {
downloadFileUseIframeMode(item.url);
}
})
})
}
/**
* 使用 iframe 模式下载文件
*
* @param url 下载文件 url
*/
const downloadFileUseIframeMode = (url: any) => {
const iframe: any = document.createElement("iframe");
iframe.style.display = "none"; // 防止影响页面
iframe.style.height = 0; // 防止影响页面
iframe.src = url;
document.body.appendChild(iframe);
setTimeout(() => {
iframe.remove();
}, 5 * 60 * 1000);
}
function findPathById(array: any, targetId: any) {
// 辅助函数,用于递归查找路径
function recursiveSearch(items: any, target: any, path: any) {
for (let item of items) {
// 将当前对象的name添加到路径中
let newPath = [...path, item.nodeName];
// 检查当前对象的id是否匹配目标id
if (item.id === target) {
return newPath.join('/'); // 找到匹配项,返回路径字符串
}
// 如果没有找到匹配项继续检查children数组
if (item.children && item.children.length > 0) {
let result = recursiveSearch(item.children, target, newPath);
if (result) { // 如果在children中找到了匹配项返回结果
return result;
}
}
}
return null; // 如果没有找到匹配项返回null
}
// 从顶层数组开始搜索
let patharr = recursiveSearch(array, targetId, [])
return '/' + patharr; // 注意这里我们传入了一个空数组作为初始路径
}
// markdown viewer 组件懒加载, 节约首屏打开时间
const VMdPreview = defineAsyncComponent({
loader: () => {
return new Promise((resolve, reject) => {
; (async function () {
try {
const res = await import('@kangc/v-md-editor/lib/preview')
import('@kangc/v-md-editor/lib/style/preview.css');
import('@kangc/v-md-editor/lib/theme/style/github.css');
const hljs = await import('highlight.js');
const githubTheme = await import('@kangc/v-md-editor/lib/theme/github.js');
res.use(githubTheme, {
Hljs: hljs,
});
resolve(res)
} catch (error) {
reject(error)
}
})()
})
},
loadingComponent: MarkdownViewerAsyncLoading
})
// 文件预览相关, 视频、音频、文本、图片
const VideoPlayer = defineAsyncComponent({
loader: () => import("@/components/file/preview/VideoPlayer.vue"),
loadingComponent: VideoPlayerAsyncLoading
})
const TextViewer = defineAsyncComponent({
loader: () => import("@/components/file/preview/TextViewer.vue"),
loadingComponent: TextViewerAsyncLoading
})
const MarkdownViewer = defineAsyncComponent({
loader: () => import("@/components/file/preview/MarkdownViewer.vue"),
loadingComponent: MarkdownViewerDialogAsyncLoading
})
const FileGallery = defineAsyncComponent(() => import("@/components/file/preview/FileGallery.vue"))
//单击预览
const filePreview: any = ref({})
//预览pdf
const ViewfileUrl = ref("")
const title1 = ref('')
const isViewfile = ref(false)
const fileType = ref('')
function openPreview(row: any) {
if (getFileExtension(row.fileName) == 'pdf' || getFileExtension(row.fileName) == 'xlsx' || getFileExtension(row.fileName) == 'docx' || getFileExtension(row.fileName) == 'doc' || getFileExtension(row.fileName) == 'bin') {
title1.value = row.fileName
ViewfileUrl.value = row.url
isViewfile.value = true
fileType.value = getFileExtension(row.fileName)
} else {
row.fileType = getFileType(row.fileName)
filePreview.value = row
localStorage.setItem('videorow', JSON.stringify(row));
openRow(row)
}
}
function getFileExtension(filename: any) {
// 获取点号在文件名中的位置(从后往前查找)
const lastIndex = filename.lastIndexOf('.');
// 如果点号存在且不是文件名的第一个字符,则返回后缀名
if (lastIndex !== -1 && lastIndex !== 0) {
return filename.substring(lastIndex + 1);
} else {
// 如果没有找到点号,则返回空字符串或根据需要返回其他值
return '';
}
}
function CloseView() {
isViewfile.value = false
}
// 文件分类
const fileTypeMap = {
image: ['gif', 'jpg', 'jpeg', 'png', 'bmp', 'webp', 'ico'],
video: ['mp4', 'webm', 'm3u8', 'rmvb', 'avi', 'swf', '3gp', 'mkv', 'flv'],
audio: ['mp3', 'wav', 'wma', 'ogg', 'aac', 'flac', 'm4a'],
text: ['scss', 'sass', 'kt', 'gitignore', 'bat', 'properties', 'yml', 'css', 'js', 'md', 'xml', 'txt', 'py', 'go', 'html', 'less', 'php', 'rb', 'rust', 'script', 'java', 'sh', 'sql'],
executable: ['exe', 'dll', 'com', 'vbs'],
archive: ['7z', 'zip', 'rar', 'tar', 'gz'],
pdf: ['pdf'],
office: ['doc', 'docx', 'csv', 'xls', 'xlsx', "ppt", 'pptx'],
three3d: ['dae', 'fbx', 'gltf', 'glb', 'obj', 'ply', 'stl'],
document: ['txt', 'pages', 'epub', 'numbers', 'keynote']
};
function getFileType(name: any) {
let fileType: any;
for (let key in fileTypeMap) {
let suffix = getFileSuffix(name);
if (fileTypeMap[key].indexOf(suffix) !== -1) {
fileType = key;
break;
}
}
return fileType;
}
function getFileSuffix(name: any) {
let lastIndex = name.lastIndexOf('.');
if (lastIndex === -1) {
return 'other';
}
return name.substring(lastIndex + 1).toLowerCase();
}
// 修改映射表
const FILE_ICONS = {
pdf: PDFImg,
doc: WordImg,
docx: WordImg,
xls: ExcelImg,
xlsx: ExcelImg,
ppt: PPTImg,
pptx: PPTImg,
zip: ZipImg,
rar: ZipImg,
mp3: Mp3Img,
mp4: Mp4Img,
avi: Mp4Img,
png: ImageImg,
jpg: ImageImg,
jpeg: ImageImg,
gif: ImageImg,
txt: TextImg
};
// 获取文件图标
const fileIcon = (filename: string) => {
const ext = filename.split('.').pop()?.toLowerCase() || 'unknown';
return FILE_ICONS[ext as keyof typeof FILE_ICONS] || require('@/assets/fileimg/text_line.png');
};
// 判断是否可预览(基于文件图标映射表)
const shouldPreview = (filename: string): boolean => {
// 获取文件扩展名并转为小写,兼容无扩展名情况
const fileExtension = filename.split('.').pop()?.toLowerCase() || '';
// 通过 keyof 类型保护确保类型安全
return Object.keys(FILE_ICONS).includes(fileExtension);
};
</script>
<template>
<div class="faulttemplate-box">
<aside id="silderLeft">
<div>
<el-select v-model="projectId" placeholder="请选择项目" @change="gettreedata()">
<el-option v-for="item in projectArr" :key="item.id" :label="item.projectName" :value="item.id" />
</el-select>
<div class="tree_sou">
<el-input v-model="treeForm.nodeName" style="width:100%;margin:10px 9px 10px 0px;"
placeholder="节点名称" clearable :suffix-icon="Search" @change="gettreedata()" />
<img src="@/assets/images/addNew.png" style="cursor: pointer;" title="新增子项目"
@click="addSubItem({ nodeType: '00' })" alt="">
</div>
<el-tree ref="treeRef" node-key="id" :data="treedata" :highlight-current="true" :props="defaultProps"
v-loading="treeloading" @node-click="handleNodeClick"
:class="useAppStore().size === 'default' ? 'silderLeft-large' : 'silderLeft-default'"
style="height: calc(100vh - 280px); overflow: auto;margin-top: 10px;">
<template #default="{ data }">
<span class="custom-tree-node">
<span class="text">{{ data.nodeName }}</span>
<span class="img_tree">
<img src="@/assets/project/xiu.png" alt="" title="编辑" @click="editSubItem(data)">
<img src="@/assets/project/del.png" alt="" title="删除" @click="delSubItem(data)">
<img v-if="data.nodeType == '01'" src="@/assets/project/jia.png" alt="" title="添加课题"
@click="addSubItem(data)">
<img v-if="data.nodeType == '02'" src="@/assets/project/jia.png" alt="" title="添加年度"
@click="addSubItem(data)">
<img v-if="data.nodeType == '03'" src="@/assets/project/jia.png" alt="" title="添加主题"
@click="addSubItem(data)">
</span>
</span>
</template>
</el-tree>
</div>
<div class="moveBtn" v-move>
<div class="moveBtn-line"></div>
</div>
</aside>
<section class="silderRight">
<div class="sou_title">
<div class="sou_title_left">
<el-input style="margin-right: 10px ;" v-model="queryParams.fileName" clearable @change="getdata()"
placeholder="文件名称"></el-input>
<el-input style="margin-right: 10px ;" v-model="queryParams.keywords" clearable @change="getdata()"
placeholder="关键字"></el-input>
<el-date-picker v-model="dataarr" type="daterange" @change="getdata()"
style="width: 150%;margin-right: 10px ;" start-placeholder="开始时间" end-placeholder="结束时间"
format="YYYY-MM-DD" value-format="YYYY-MM-DD" range-separator="至" />
<el-button type="primary" @click="getdata()">搜索</el-button>
</div>
<div>
<!-- :disabled="pathid.value" -->
<el-button type="primary" :disabled="!pathid" @click="openFile">上传</el-button>
<el-button type="primary" @click="delprojectArr()" :disabled="tableIdarr.length == 0">删除</el-button>
<el-button type="primary" @click="xiafilemony()" :disabled="tableIdarr.length == 0">下载</el-button>
</div>
</div>
<el-table v-loading="loading" :data="tableData" @selection-change="handleSelectionChange"
:header-cell-style="{ background: 'rgb(250 250 250)', height: '50px' }"
style="width: 100%; height: calc(100vh - 275px);margin-bottom: 20px;" border>
<el-table-column type="selection" width="40" />
<!-- <el-table-column type="index" label="序号" width="70" align="center"></el-table-column> -->
<el-table-column prop="fileName" label="文件名称">
</el-table-column>
<el-table-column prop="keywords" label="关键字"></el-table-column>
<el-table-column prop="description" label="文件描述"></el-table-column>
<el-table-column prop="fileName" label="预览" width="80" align="center">
<template #default="{ row }">
<div class="preview-icon">
<img :src="fileIcon(row.fileName)" alt="file icon" class="file-icon"
@click="shouldPreview(row.fileName) && openPreview(row)">
</div>
</template>
</el-table-column>
<el-table-column prop="uploader" width="80" label="上传人"></el-table-column>
<el-table-column prop="uploadTime" width="170" label="上传时间"></el-table-column>
<el-table-column fixed="right" label="操作" width="100" align="center">
<template #default="scope">
<span
style="display: flex;display: -webkit-flex;justify-content: space-between;-webkit-justify-content: space-between; ">
<img src="@/assets/project/chong.png" alt="" title="重命名" @click="editfile(scope.row, false)"
style="cursor: pointer;">
<img src="@/assets/MenuIcon/lbcz_xg.png" alt="" @click="editfile(scope.row, true)" title="修改"
style="cursor: pointer;">
<img src="@/assets/MenuIcon/lbcz_sc.png" alt="" @click="delfile(scope.row)" title="删除"
style="cursor: pointer;">
<img src="@/assets/MenuIcon/xia1.png" alt="" @click="xiafile(scope.row)" title="下载"
style="cursor: pointer;">
</span>
</template>
</el-table-column>
</el-table>
<Page :total="total" v-model:size="queryParams.size" v-model:current="queryParams.current"
@pagination="getdata()">
</Page>
</section>
<el-dialog :title="title" v-model="frame" width="30%" :before-close="handleClose" top="30px" draggable
destroy-on-close>
<el-form ref="ruleFormRef" style="max-width: 600px" :model="projectForme" :rules="moderules"
label-width="auto" class="demo-ruleForm" status-icon>
<el-form-item label="节点名称" prop="nodeName">
<el-input v-model="projectForme.nodeName" />
</el-form-item>
<el-form-item>
<div style="width: 100%;display: flex;justify-content: end;">
<el-button type="primary" @click="submitForm(ruleFormRef)">确定</el-button>
<el-button @click="handleClose(ruleFormRef)">取消</el-button>
</div>
</el-form-item>
</el-form>
</el-dialog>
<el-dialog title="上传文件" v-model="upfile" width="50%" :before-close="fileClose" top="30px" draggable
destroy-on-close>
<el-scrollbar :height="!fileObj.id ? '400px' : ''">
<el-form ref="ruleFormRef" style="max-width: 100%" :model="fileObj" :rules="moderqqqules"
label-width="auto" class="demo-ruleForm" status-icon>
<el-form-item v-if="!fileObj.id" label="文件:" prop="taskCode">
<!-- <el-button @click="openUploadDialog" type="primary">上传文件</el-button>
<el-button @click="openUploadFolderDialog" type="primary">上传文件夹</el-button> -->
<ZUpload />
</el-form-item>
<el-form-item v-else prop="fileName" label="文件名称:">
<el-input v-model="fileObj.fileName" />
</el-form-item>
<el-form-item v-if="judge" label="关键字:" prop="taskName">
<el-input v-model="fileObj.keywords" />
</el-form-item>
<el-form-item v-if="judge" label="描述:">
<el-input v-model="fileObj.description" :rows="2" type="textarea" />
</el-form-item>
<el-form-item>
<div style="width: 100%;display: flex;justify-content: end;">
<el-button type="primary" @click="submitfile">确定</el-button>
<el-button @click="fileClose">取消</el-button>
</div>
</el-form-item>
</el-form>
</el-scrollbar>
</el-dialog>
<!-- 组件预览 -->
<!-- 视频播放器 -->
<el-dialog draggable class="zfile-video-dialog" :destroy-on-close="true" v-model="dialogVideoVisible">
<video-player v-if="dialogVideoVisible" ref="videoPlayer" />
</el-dialog>
<!-- 文本编辑器 -->
<el-dialog draggable class="zfile-text-dialog zfile-dialog-mini-close" :destroy-on-close="true"
:title="filePreview.fileName" v-model="dialogTextVisible">
<TextViewer :file-name="filePreview.fileName" :file-url="filePreview.url"
v-if="dialogTextVisible && filePreview.fileName.indexOf('.md') === -1" />
<MarkdownViewer :file-name="filePreview.fileName" :file-url="filePreview.url"
v-if="dialogTextVisible && filePreview.fileName.indexOf('.md') !== -1" />
</el-dialog>
<!-- pdf 在线预览 -->
<el-dialog draggable class="zfile-pdf-dialog" :title="filePreview.fileName" v-model="dialogPdfVisible">
<PdfViewer :file-name="filePreview.fileName" :file-url="filePreview.url" v-if="dialogPdfVisible" />
</el-dialog>
<!-- office 在线预览 -->
<el-dialog draggable class="zfile-office-dialog zfile-dialog-mini-close zfile-dialog-hidden-title"
:title="filePreview.fileName" v-model="dialogOfficeVisible">
<OfficeViewer :file-name="filePreview.fileName" :file-url="filePreview.url" v-if="dialogOfficeVisible" />
</el-dialog>
<!-- 3d 在线预览 -->
<el-dialog draggable class="zfile-3d-dialog" :title="filePreview.fileName" v-model="dialog3dVisible">
<Three3dPreview :file-name="filePreview.fileName" :file-url="filePreview.url" v-if="dialog3dVisible" />
</el-dialog>
<!-- 音频播放器 -->
<AudioPlayer></AudioPlayer>
<!-- <audio-player></audio-player> -->
<Viewfile v-if="isViewfile" :showTime="true" :title="title1" :url="ViewfileUrl" :type="fileType"
@update="CloseView" />
</div>
</template>
<style scoped lang="scss">
.faulttemplate-box {
height: 100%;
display: flex;
display: -webkit-flex;
background-color: #f2f4f9;
}
#silderLeft {
width: 300px;
padding: 10px;
box-sizing: border-box;
background: #fff;
border-radius: 3px;
position: relative;
.tree_sou {
display: flex;
align-items: center;
justify-content: space-between;
}
&:hover {
.moveBtn {
opacity: 1;
}
}
}
/* 拖动条 */
.moveBtn {
height: 100%;
width: 15px;
padding: 0 6px;
opacity: 0;
position: absolute;
right: -15px;
top: 0;
}
.moveBtn-line {
width: 100%;
height: 100%;
cursor: col-resize;
user-select: none;
background-color: #60bfff;
}
.silderRight {
flex: 1;
width: 100%;
height: calc(100vh - 130px);
overflow: auto;
background-color: rgba(255, 255, 255, 1);
border-radius: 3px;
padding: 15px;
padding-bottom: 0px;
box-sizing: border-box;
margin-left: 15px;
.sou_title {
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
.sou_title_left {
width: 50%;
display: flex;
align-items: center;
justify-content: space-between;
}
}
}
.custom-tree-node {
flex: 1;
display: flex;
align-items: center;
justify-content: space-between;
font-size: 14px;
padding: 8px;
.img_tree {
display: flex;
width: 20%;
align-items: center;
justify-content: space-between;
img {
cursor: pointer;
}
}
}
.tableHover {
cursor: pointer;
}
.tableHover:hover {
color: #409eff;
}
//文字换行处理
.text {
overflow-wrap: break-word;
word-break: break-all;
white-space: normal;
// line-height: 1.5;
max-width: 80%;
// border: 1px solid #000;
// padding: 10px;
}
:deep() {
.el-tree-node__content {
height: auto !important;
line-height: 20px !important;
// padding-left: 10px !important;
}
.el-tree-node__content>.el-tree-node__expand-icon {
padding: 0px !important;
}
}
.preview-icon {
display: flex;
align-items: center;
justify-content: center;
}
.file-icon {
cursor: pointer;
width: 20px;
height: 20px;
transition: opacity 0.2s;
}
.file-icon:hover {
opacity: 0.8;
}
</style>