<template>
|
<div class="context-menu" v-show="visible">
|
<!-- mask -->
|
<div
|
class="mask"
|
v-show="visible"
|
@click="close"
|
@contextmenu="close"
|
></div>
|
<div class="contain">
|
<ul class="main-ul">
|
<li
|
class="main-li"
|
v-for="(item, idx) in menuList"
|
:key="'main_' + idx"
|
>
|
<div
|
:class="['title', { disabled: item.disabled }]"
|
@click="itemClick(item)"
|
@mouseenter="itemHover(item)"
|
>
|
{{ item.title }}
|
</div>
|
<ul
|
class="sub-ul"
|
v-show="item.visible && item.children && item.children.length"
|
>
|
<li
|
:class="['sub-li', { disabled: subItem.disabled }]"
|
v-for="(subItem, index) in item.children"
|
:key="'sub_' + index"
|
@click="itemClick(subItem)"
|
>
|
{{ subItem.title }}
|
</li>
|
</ul>
|
</li>
|
</ul>
|
</div>
|
<!-- -->
|
<el-dialog
|
:title="dialogTitle"
|
:visible.sync="dialogVisible"
|
append-to-body
|
width="30%"
|
>
|
<el-input v-model="stationName" placeholder="请输入..."></el-input>
|
<span slot="footer" class="dialog-footer">
|
<el-button @click="dialogVisible = false">取 消</el-button>
|
<el-button type="primary" @click="stationNameOk">确 定</el-button>
|
</span>
|
</el-dialog>
|
<!-- 文件属性 -->
|
<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
|
:info="fileData"
|
@ok="editOk"
|
@cancel="editCancel"
|
@quit="quit"
|
></file-info>
|
</el-dialog>
|
</div>
|
</template>
|
|
<script>
|
import FileInfo from "@/components/fileInfo";
|
import {
|
addStation,
|
addFileInStation,
|
updateStation,
|
deleteStation,
|
delFileFromStation,
|
getXmlValue,
|
} from "@/apis";
|
export default {
|
name: "ContextMenu",
|
model: {
|
prop: "visible",
|
event: "change",
|
},
|
props: {
|
visible: {
|
type: Boolean,
|
required: true,
|
default: false,
|
},
|
disabledList: {
|
type: Array,
|
default() {
|
return [];
|
},
|
},
|
contextData: {
|
type: Object,
|
default() {
|
return {};
|
},
|
},
|
},
|
data() {
|
const menuList = [
|
{
|
id: 0,
|
title: "打开文件",
|
method: "openFile",
|
disabled: false,
|
visible: false,
|
},
|
{
|
id: 1,
|
title: "新建",
|
disabled: false,
|
visible: false,
|
children: [
|
{
|
id: 11,
|
title: "新建根文件",
|
method: "addRootStation",
|
disabled: false,
|
},
|
{
|
id: 12,
|
title: "新建子文件",
|
method: "addSubStation",
|
disabled: false,
|
},
|
],
|
},
|
{
|
id: 2,
|
title: "添加",
|
disabled: false,
|
visible: false,
|
children: [
|
{
|
id: 13,
|
title: "指定目录下所有文件",
|
method: "selectDir",
|
disabled: false,
|
},
|
{
|
id: 14,
|
title: "单一文件",
|
method: "selectFile",
|
disabled: false,
|
},
|
],
|
},
|
{
|
id: 3,
|
title: "重命名",
|
method: "rename",
|
disabled: false,
|
visible: false,
|
},
|
{
|
id: 4,
|
title: "删除",
|
method: "deleteItem",
|
disabled: false,
|
visible: false,
|
},
|
];
|
return {
|
menuList,
|
dialogTitle: "",
|
dialogVisible: false,
|
stationName: "",
|
// 操作类型 'rename', 'add'
|
type: "",
|
fileInfoVisible: false,
|
fileData: {},
|
currFile: {
|
name: "",
|
url: "",
|
},
|
};
|
},
|
components: {
|
FileInfo,
|
},
|
watch: {
|
visible(n) {
|
if (n) {
|
this.initData();
|
}
|
},
|
},
|
methods: {
|
itemClick(obj) {
|
// console.log(obj)
|
if (
|
obj.method &&
|
"function" == typeof this[obj.method] &&
|
!obj.disabled
|
) {
|
this.close();
|
this[obj.method](obj);
|
}
|
},
|
close() {
|
this.invisibleSubMenu();
|
this.$emit("change", false);
|
},
|
showChildren(obj) {
|
// this.menuList.forEach((v) => {
|
// v.visible = false;
|
// });
|
obj.visible = true;
|
},
|
invisibleSubMenu() {
|
this.menuList.forEach((v) => {
|
v.visible = false;
|
});
|
},
|
itemHover(obj) {
|
if (obj.disabled) {
|
return false;
|
}
|
this.invisibleSubMenu();
|
this.$nextTick(() => {
|
obj.visible = true;
|
});
|
},
|
openFile() {
|
let { url } = this.contextData;
|
const params = {
|
filePath: url,
|
};
|
getXmlValue(params).then((res) => {
|
const { code, data, data2 } = res.data;
|
if (code && data) {
|
console.log(data2);
|
this.fileData = data2.fileParam;
|
this.currFile.name = data2.fileName;
|
this.currFile.url = data2.fileUrl;
|
this.fileInfoVisible = true;
|
// this.$router.push({
|
// path: "/result/" + data2.fileName,
|
// query: {
|
// url: data2.fileUrl,
|
// },
|
// });
|
// this.$bus.$emit("checkScroll");
|
} else {
|
this.$message.error("文件解析失败");
|
}
|
});
|
},
|
initEvents() {
|
window.api.receive("selected-file", (path, data) => {
|
if (data && data == "ContextMenu") {
|
console.log(path.filePaths, "contextMenu?");
|
path = path.filePaths[0];
|
this.addFileInStation(path);
|
}
|
});
|
window.api.receive("selected-directory", (path, data) => {
|
if (data && data == "ContextMenu") {
|
// console.log(path.filePaths);
|
path = path.filePaths[0];
|
this.addFileInStation(path);
|
}
|
});
|
},
|
initData() {
|
this.menuList.forEach((v) => {
|
v.visible = false;
|
v.disabled = this.disabledList.some((val) => val == v.id);
|
(v.children || []).forEach((item) => {
|
item.disabled = this.disabledList.some((val) => val == item.id);
|
});
|
});
|
console.log(this.menuList, this.disabledList, 9090);
|
},
|
addRootStation() {
|
this.dialogTitle = "新建根文件名称";
|
this.stationName = "";
|
this.type = "add";
|
this.dialogVisible = true;
|
},
|
addSubStation() {
|
this.dialogTitle = "新建子文件名称";
|
this.stationName = "";
|
this.type = "add";
|
this.dialogVisible = true;
|
},
|
stationNameOk() {
|
if ("" == this.stationName.trim()) {
|
this.$message.error("名称不能为空");
|
return false;
|
}
|
if (this.type == "add") {
|
this.addStation();
|
} else if (this.type == "rename") {
|
this.renameOk();
|
}
|
},
|
addStation() {
|
const { label, parent, level } = this.contextData;
|
let params = {};
|
const stationName = this.stationName.trim();
|
switch (level) {
|
case 0:
|
params["stationName1"] = label;
|
params["stationName2"] = stationName;
|
break;
|
case 1:
|
params["stationName1"] = parent[0];
|
params["stationName2"] = label;
|
params["stationName3"] = stationName;
|
break;
|
default:
|
params["stationName1"] = stationName;
|
}
|
addStation(params).then((res) => {
|
const { code, data } = res.data;
|
if (code && data) {
|
this.dialogVisible = false;
|
this.$message.success("添加成功");
|
this.reload();
|
} else {
|
this.$message.error("操作失败");
|
}
|
});
|
},
|
selectDir() {
|
window.api.send("open-directory-dialog", "ContextMenu");
|
},
|
selectFile() {
|
window.api.send("open-file-dialog", "ContextMenu");
|
},
|
addFileInStation(path) {
|
let { label, parent } = this.contextData;
|
parent = parent.map((v) => v);
|
parent.push(label);
|
const params = {
|
FilePath: path,
|
stationName: parent.join("-"),
|
};
|
addFileInStation(params).then((res) => {
|
const { code, data, data2 } = res.data;
|
if (code && data) {
|
console.log(data2);
|
this.reload();
|
}
|
});
|
},
|
// 删除站点 或都从站点删除文件
|
deleteItem() {
|
let { label, parent, level } = this.contextData;
|
if (level == 3) {
|
this.$confirm("此操作将从站点移除该文件, 是否继续?", "提示", {
|
confirmButtonText: "确定",
|
cancelButtonText: "取消",
|
type: "warning",
|
}).then(() => {
|
this.deleteFile();
|
});
|
} else {
|
this.$confirm("此操作将删除该站点, 是否继续?", "提示", {
|
confirmButtonText: "确定",
|
cancelButtonText: "取消",
|
type: "warning",
|
}).then(() => {
|
this.deleteStation();
|
});
|
}
|
},
|
deleteStation() {
|
let { label, parent, level } = this.contextData;
|
let params = {};
|
switch (level) {
|
case 0:
|
params["stationName1"] = label;
|
break;
|
case 1:
|
params["stationName1"] = parent[0];
|
params["stationName2"] = label;
|
break;
|
case 2:
|
params["stationName1"] = parent[0];
|
params["stationName2"] = parent[1];
|
params["stationName3"] = label;
|
break;
|
}
|
deleteStation(params).then((res) => {
|
const { code, data, data2 } = res.data;
|
if (code && data) {
|
console.log(data2);
|
this.reload();
|
}
|
});
|
},
|
deleteFile() {
|
let { label, parent, url } = this.contextData;
|
parent = parent.map((v) => v);
|
let params = {
|
stationName: parent.join("-"),
|
FilePath: url,
|
};
|
delFileFromStation(params).then((res) => {
|
const { code, data, data2 } = res.data;
|
if (code && data) {
|
this.$message.success("操作成功");
|
this.reload();
|
} else {
|
this.$message.error("操作失败");
|
}
|
});
|
},
|
// 重命名现只针对台站 (文件是否重命名需要确认需求)
|
rename() {
|
this.dialogTitle = "修改站点名称";
|
this.stationName = this.contextData.label;
|
this.type = "rename";
|
this.dialogVisible = true;
|
},
|
renameOk() {
|
let { label, parent, level } = this.contextData;
|
const stationName = this.stationName.trim();
|
let params = {};
|
switch (level) {
|
case 0:
|
params["stationName1"] = label;
|
params["updateName"] = stationName;
|
break;
|
case 1:
|
params["stationName1"] = parent[0];
|
params["stationName2"] = label;
|
params["updateName"] = stationName;
|
break;
|
case 2:
|
params["stationName1"] = parent[0];
|
params["stationName2"] = parent[1];
|
params["stationName3"] = label;
|
params["updateName"] = stationName;
|
break;
|
}
|
updateStation(params).then((res) => {
|
const { code, data } = res.data;
|
if (code && data) {
|
this.dialogVisible = false;
|
this.$message.success("操作成功");
|
this.reload();
|
} else {
|
this.$message.error("操作失败");
|
}
|
});
|
},
|
reload() {
|
this.$emit("reload");
|
},
|
editOk(data) {
|
console.log("ok", data);
|
this.fileInfoVisible = false;
|
this.toRes();
|
},
|
editCancel(data) {
|
console.log("cancel", data);
|
this.fileInfoVisible = false;
|
this.toRes();
|
},
|
toRes() {
|
const { name, url } = this.currFile;
|
this.$router.push({
|
path: "/result/" + name,
|
query: {
|
url,
|
},
|
});
|
this.$bus.$emit("checkScroll");
|
},
|
quit() {
|
console.log("quit");
|
this.fileInfoVisible = false;
|
},
|
},
|
|
mounted() {
|
this.initData();
|
this.initEvents();
|
},
|
};
|
</script>
|
|
<style lang="less" scoped>
|
.context-menu {
|
z-index: 1;
|
position: absolute;
|
background: #c0c0c0;
|
// border: 1px #055AC6 solid;
|
border-radius: 4px;
|
padding: 4px;
|
.contain {
|
position: relative;
|
background: #c0c0c0;
|
z-index: 100;
|
.main-ul {
|
display: flex;
|
flex-direction: column;
|
.main-li {
|
position: relative;
|
cursor: pointer;
|
flex: 1;
|
border: 1px #fff solid;
|
.title {
|
padding: 4px;
|
color: #333;
|
background: #f0f0f0;
|
&:hover {
|
background: #ccc;
|
}
|
}
|
& ~ .main-li {
|
margin-top: 2px;
|
}
|
}
|
.sub-ul {
|
// display: none;
|
display: flex;
|
flex-direction: column;
|
position: absolute;
|
left: 100%;
|
top: 0;
|
transform: translateX(6px);
|
min-width: 10em;
|
background: #c0c0c0;
|
border-radius: 4px;
|
padding: 4px;
|
.sub-li {
|
border-radius: 4px;
|
border: 1px #fff solid;
|
background: #d9dce2;
|
&:hover {
|
background: #169bd5;
|
}
|
}
|
}
|
.disabled.disabled.disabled {
|
cursor: not-allowed;
|
color: #eee;
|
background: #999;
|
}
|
}
|
}
|
.mask {
|
position: fixed;
|
left: 0;
|
right: 0;
|
top: 0;
|
bottom: 0;
|
background: transparent;
|
z-index: 99;
|
}
|
}
|
.file-info {
|
:deep(.el-dialog__header) {
|
position: relative;
|
z-index: 0;
|
text-align: center;
|
padding-bottom: 16px;
|
filter: drop-shadow(0 1px 2px #333);
|
&::before {
|
content: "";
|
position: absolute;
|
left: 0;
|
top: 0;
|
bottom: 0;
|
right: 0;
|
background: #ccc;
|
z-index: -1;
|
clip-path: polygon(0 0, 100% 0, 100% 60%, 50% 100%, 0 60%);
|
background: linear-gradient(#ccc 10%, #fff 50%, #ccc 90%);
|
}
|
}
|
}
|
</style>
|