<template>
|
<div id="app">
|
<div class="main">
|
<div class="left" ref="left">
|
<menu-list></menu-list>
|
<btn-list></btn-list>
|
<div class="title">文件列表</div>
|
<div class="file-list" @contextmenu.prevent="openContextMenu($event)">
|
<el-tree
|
:class="['station-tree', { empty: !stationData.length }]"
|
:data="stationData"
|
@node-click="handleNodeClick"
|
@node-contextmenu="nodeContextClick"
|
></el-tree>
|
</div>
|
</div>
|
<div class="handle" ref="handle"></div>
|
<div class="right">
|
<div class="right-inner">
|
<!-- 文件标签 -->
|
<tabs-bar :vnode="getVnode"></tabs-bar>
|
<div class="right-content">
|
<div class="posIner">
|
<!-- <keep-alive :include="cachedViews"> -->
|
<!-- <keep-alive>
|
<router-view :key="$route.path" />
|
</keep-alive> -->
|
<a-keep-alive :exclude-keys="excludeKeys" v-model="clearCaches">
|
<router-view
|
v-if="!refreshing"
|
ref="tabContent"
|
:key="$route.fullPath"
|
/>
|
</a-keep-alive>
|
</div>
|
</div>
|
</div>
|
</div>
|
</div>
|
<!-- 右键菜单 -->
|
<context-menu
|
v-model="contextMenu.visible"
|
:disabled-list="disabledList"
|
:context-data="contextMenu.node"
|
:style="{ left: contextMenu.x + 'px', top: contextMenu.y + 'px' }"
|
@reload="reload"
|
></context-menu>
|
<!-- 文件属性 -->
|
<el-dialog
|
title="属性"
|
class="file-info"
|
:visible.sync="fileInfoVisible"
|
append-to-body
|
:close-on-click-modal="false"
|
:close-on-press-escape="false"
|
:show-close="false"
|
width="800px"
|
>
|
<file-info
|
v-if="fileInfoVisible"
|
:info="fileData"
|
@ok="editOk"
|
@cancel="editCancel"
|
@quit="quit"
|
></file-info>
|
</el-dialog>
|
</div>
|
</template>
|
|
<script>
|
const minWidth = 200,
|
maxWidth = 600;
|
|
import MenuList from "@/components/menuList";
|
import BtnList from "@/components/btnList";
|
import ContextMenu from "@/components/contextMenu";
|
import TabsBar from "@/components/tabsBar";
|
import AKeepAlive from "@/components/AKeepAlive";
|
import FileInfo from "@/components/fileInfo";
|
import { getStation, getParamByFileId, updateFileParam } from "./apis";
|
|
export default {
|
name: "App",
|
components: {
|
MenuList,
|
ContextMenu,
|
TabsBar,
|
AKeepAlive,
|
FileInfo,
|
BtnList
|
},
|
data() {
|
return {
|
clickObj: {},
|
fileInfoVisible: false,
|
fileData: {},
|
currFile: {
|
name: "",
|
url: "",
|
fileId: undefined,
|
},
|
excludeKeys: [],
|
clearCaches: [],
|
refreshing: false,
|
/////////////
|
startX: 0,
|
leftW: 0,
|
stationData: [],
|
contextMenu: {
|
x: 0,
|
y: 0,
|
visible: false,
|
node: {},
|
},
|
disabledList: [],
|
};
|
},
|
computed: {
|
cachedViews() {
|
return this.$store.state.tagsView.cachedViews;
|
},
|
},
|
watch: {
|
"$router.options.routes": function (val) {
|
// console.log("options.rout", val);
|
this.excludeKeys = [];
|
// this.loadCacheConfig(val);
|
},
|
},
|
methods: {
|
getVnode() {
|
return this.$refs.tabContent.$vnode;
|
},
|
onMouseDown(e) {
|
// const el = e.target;
|
this.startX = e.clientX;
|
this.leftW = this.$refs.left.clientWidth;
|
document.addEventListener("mousemove", this.onMouseMove);
|
document.addEventListener("mouseup", this.onMouseUp);
|
},
|
onMouseUp() {
|
// this.$refs.handle.style.background = 'transparent';
|
// document.removeEventListener('mousedown', this.onMouseDown);
|
document.removeEventListener("mousemove", this.onMouseMove);
|
},
|
onMouseMove(e) {
|
const el = this.$refs.handle;
|
const left = this.$refs.left;
|
const endX = e.clientX;
|
const moveLen = endX - this.startX;
|
const CurBoxLen = this.leftW + moveLen;
|
if (CurBoxLen <= minWidth || CurBoxLen >= maxWidth) {
|
return;
|
}
|
left.style.width = CurBoxLen + "px";
|
el.style.left = CurBoxLen + "px";
|
this.$bus.$emit("checkScroll");
|
},
|
getStation() {
|
getStation().then((res) => {
|
const { code, data, data2 } = res.data;
|
let list = [];
|
if (code && data) {
|
// console.log(1, data2);
|
list = this.formatData(data2);
|
}
|
this.stationData = list;
|
});
|
},
|
formatData(data) {
|
let res = data.map((v) => {
|
let sname2s = [];
|
v.sname2s.forEach((val) => {
|
if (val.station2 != "-") {
|
let children = [];
|
val.sname3s.forEach((item) => {
|
if (item.station3 != "-") {
|
children.push({
|
label: item.station3,
|
children: item.fileNames.map((item1) => ({
|
label: item1.fileName,
|
url: item1.fileUrl,
|
fileId: item1.fileId,
|
level: 3,
|
parent: [v.station1, val.station2, item.station3],
|
})),
|
level: 2,
|
parent: [v.station1, val.station2],
|
});
|
} else {
|
children.push(
|
...item.fileNames.map((item1) => ({
|
label: item1.fileName,
|
url: item1.fileUrl,
|
fileId: item1.fileId,
|
level: 3,
|
parent: [v.station1, val.station2],
|
}))
|
);
|
}
|
});
|
sname2s.push({
|
label: val.station2,
|
children,
|
level: 1,
|
parent: [v.station1],
|
});
|
} else {
|
sname2s.push(
|
...val.sname3s[0].fileNames.map((item) => ({
|
label: item.fileName,
|
url: item.fileUrl,
|
fileId: item.fileId,
|
level: 3,
|
parent: [v.station1],
|
}))
|
);
|
}
|
});
|
return {
|
children: sname2s,
|
label: v.station1,
|
level: 0,
|
parent: [],
|
};
|
});
|
// console.log(res);
|
return res;
|
},
|
reload() {
|
this.getStation();
|
},
|
handleNodeClick(obj) {
|
// console.log(123, obj);
|
if (obj.level == 3) {
|
let nStamp = Date.now();
|
const { targetId, timestamp } = this.clickObj;
|
// console.log(targetId, obj.fileId , nStamp, timestamp, nStamp - timestamp);
|
if (targetId == obj.fileId && nStamp - timestamp < 600) {
|
// 触发双击事件
|
this.openFile(obj);
|
}
|
this.clickObj = {
|
timestamp: nStamp,
|
targetId: obj.fileId,
|
};
|
}
|
},
|
openFile(obj) {
|
let { url, fileId, label } = obj;
|
getParamByFileId(fileId).then((res) => {
|
const { code, data, data2 } = res.data;
|
if (code && data) {
|
// console.log(data2);
|
this.fileData = data2;
|
this.currFile.name = label;
|
this.currFile.url = url;
|
this.currFile.fileId = fileId;
|
this.fileInfoVisible = true;
|
} else {
|
this.$message.error("文件解析失败");
|
}
|
});
|
},
|
editOk(data) {
|
this.fileInfoVisible = false;
|
updateFileParam(this.currFile.fileId, data).then((res) => {
|
const { code, data } = res.data;
|
if (code && data) {
|
this.$message.success('修改成功');
|
} else {
|
this.$message.error('修改失败');
|
}
|
});
|
this.toRes();
|
},
|
editCancel(data) {
|
this.fileInfoVisible = false;
|
this.toRes();
|
},
|
toRes() {
|
const { name, url, fileId } = this.currFile;
|
// debugger;
|
this.$router.push({
|
path: "/result/" + name,
|
query: {
|
url,
|
fileId,
|
},
|
});
|
this.$bus.$emit("checkScroll");
|
},
|
quit() {
|
this.fileInfoVisible = false;
|
},
|
nodeContextClick($e, obj) {
|
// console.log(obj);
|
const { clientX, clientY } = $e;
|
this.contextMenu.x = clientX;
|
let y = clientY;
|
let bodyHeight = document.body.clientHeight;
|
if (y + 180 > bodyHeight) {
|
y = bodyHeight - 180;
|
}
|
this.contextMenu.y = y;
|
switch (obj.level) {
|
case 0:
|
case 1:
|
// 子站上按鼠标右键,不能“打开文件”、“新建根文件”
|
this.disabledList = [0, 11];
|
break;
|
case 2:
|
// 此层级 只能添加文件 不能新建子站
|
this.disabledList = [0, 1];
|
break;
|
case 3:
|
// 添加的测试文件上按鼠标右键,可以点击“打开文件”、“重命名”、“删除”
|
this.disabledList = [1, 2];
|
break;
|
default:
|
return false;
|
}
|
this.contextMenu.node = obj;
|
this.contextMenu.visible = true;
|
},
|
// 右键菜单
|
openContextMenu($e) {
|
// console.log($e, "context");
|
const {
|
clientX,
|
clientY,
|
target: { classList },
|
} = $e;
|
this.contextMenu.x = clientX;
|
let y = clientY;
|
let bodyHeight = document.body.clientHeight;
|
if (y + 180 > bodyHeight) {
|
y = bodyHeight - 180;
|
}
|
this.contextMenu.y = y;
|
if (classList.contains("file-list")) {
|
// 在空白处点击的右键 只能新建
|
this.disabledList = [0, 12, 2, 3, 4];
|
this.contextMenu.node = {};
|
this.contextMenu.visible = true;
|
}
|
},
|
closeContextMenu() {
|
this.contextMenu.visible = false;
|
},
|
maskClick() {
|
this.closeContextMenu();
|
},
|
updateCaches(data) {
|
this.clearCaches = data;
|
},
|
},
|
mounted() {
|
let handle = this.$refs.handle;
|
handle.addEventListener("mousedown", this.onMouseDown);
|
this.$bus.$on("clearCaches", this.updateCaches);
|
this.$bus.$on("stationReload", this.reload);
|
this.getStation();
|
},
|
};
|
</script>
|
|
<style>
|
html,
|
body {
|
height: 100%;
|
margin: 0;
|
padding: 0;
|
overflow: hidden;
|
}
|
div {
|
box-sizing: border-box;
|
}
|
#app {
|
height: 100%;
|
font-family: Avenir, Helvetica, Arial, sans-serif;
|
-webkit-font-smoothing: antialiased;
|
-moz-osx-font-smoothing: grayscale;
|
text-align: center;
|
color: #000;
|
background: #076fec;
|
overflow: hidden;
|
}
|
ul,
|
li {
|
list-style: none;
|
margin: 0;
|
padding: 0;
|
user-select: none;
|
}
|
</style>
|
<style lang="less" scoped>
|
.main {
|
height: 100%;
|
position: relative;
|
display: flex;
|
z-index: 1;
|
}
|
.left {
|
width: 14em;
|
box-shadow: 1px 0 2px -1px #000;
|
/* background: rgba(200, 200, 200, .8); */
|
display: flex;
|
flex-direction: column;
|
.title {
|
background: #0055bf;
|
color: #fff;
|
padding: 4px;
|
}
|
.file-list {
|
flex: 1;
|
overflow-y: auto;
|
text-align: left;
|
user-select: none;
|
:deep(.el-tree.station-tree) {
|
background: transparent;
|
color: #fff;
|
display: inline-block;
|
&.empty {
|
display: block;
|
pointer-events: none;
|
}
|
.el-tree-node__content {
|
display: inline-block;
|
}
|
.el-tree-node:hover,
|
.el-tree-node:focus > .el-tree-node__content {
|
background-color: rgba(39, 134, 255, 0.4);
|
.el-tree-node__label {
|
color: #000;
|
}
|
}
|
.el-tree-node__content.el-tree-node__content:hover,
|
.el-tree-node__content.el-upload-list__item:hover {
|
background-color: rgba(200, 200, 200, 0.4);
|
color: #000;
|
.el-tree-node__label {
|
color: #000;
|
}
|
}
|
}
|
}
|
}
|
.handle {
|
width: 6px;
|
z-index: 1;
|
position: absolute;
|
top: 0;
|
bottom: 0;
|
left: 14em;
|
background: transparent;
|
cursor: col-resize;
|
}
|
.handle:hover {
|
background: rgba(200, 200, 200, 0.6);
|
}
|
.right {
|
/* background: rgba(0,0,0,.4); */
|
flex: 1;
|
position: relative;
|
z-index: 0;
|
.right-inner {
|
position: absolute;
|
left: 0;
|
top: 0;
|
right: 0;
|
bottom: 0;
|
display: flex;
|
flex-direction: column;
|
.right-content {
|
flex: 1;
|
position: relative;
|
.posIner {
|
position: absolute;
|
left: 0;
|
top: 0;
|
right: 0;
|
bottom: 0;
|
}
|
}
|
}
|
}
|
.trans-mask {
|
position: fixed;
|
z-index: 99;
|
left: 0;
|
top: 0;
|
right: 0;
|
bottom: 0;
|
background: transparent;
|
}
|
</style>
|