<template>
|
<div class="tree-menu-box">
|
<div class="flex">
|
<div class="tree-menu" v-if="$route.name == 'landerModel'">
|
<div class="topMenu">
|
<span class="topMenu-title">{{ menuName }}</span>
|
<div
|
class="btnGroup"
|
v-if="$route.name == 'landerModel' || $route.name == 'systemUse'"
|
>
|
<el-dropdown>
|
<el-icon class="icon1"><FolderAdd /></el-icon>
|
<template #dropdown>
|
<el-dropdown-menu>
|
<el-dropdown-item @click="addBtn('parent')"
|
>新建频道</el-dropdown-item
|
>
|
<el-dropdown-item
|
:disabled="selectData ? false : true"
|
@click="addBtn('child')"
|
>新建子频道</el-dropdown-item
|
>
|
</el-dropdown-menu>
|
</template>
|
</el-dropdown>
|
<el-icon class="icon2" @click="editBtn"><Edit /></el-icon>
|
<el-icon class="icon3" @click="delBtn"><Delete /></el-icon>
|
</div>
|
</div>
|
|
<div v-if="loadTree && $route.name == 'landerModel'">
|
<el-tree
|
ref="treeRef"
|
:key="treeKey"
|
:props="defaultProps"
|
:highlight-current="true"
|
@node-click="handleNodeClick"
|
:current-node-key="currentNodeKey"
|
node-key="key"
|
:data="filteredData"
|
:load="loadNode"
|
:expand-on-click-node="false"
|
lazy
|
>
|
<template #default="{ node, data }">
|
<span class="custom-tree-node">
|
<el-icon v-if="data.icon"
|
><component :is="data.icon"
|
/></el-icon>
|
<span>{{ node.label }}</span>
|
</span>
|
</template>
|
</el-tree>
|
</div>
|
</div>
|
|
<div class="tree-menu" v-if="$route.name.includes('simulation')">
|
<span class="topMenu-title">{{ menuName }}</span>
|
<div
|
class="btnGroup"
|
v-if="$route.name == 'landerModel' || $route.name == 'systemUse'"
|
>
|
<el-dropdown>
|
<el-icon class="icon1"><FolderAdd /></el-icon>
|
<template #dropdown>
|
<el-dropdown-menu>
|
<el-dropdown-item @click="addBtn('parent')"
|
>新建频道</el-dropdown-item
|
>
|
<el-dropdown-item
|
:disabled="selectData ? false : true"
|
@click="addBtn('child')"
|
>新建子频道</el-dropdown-item
|
>
|
</el-dropdown-menu>
|
</template>
|
</el-dropdown>
|
<el-icon class="icon2" @click="editBtn"><Edit /></el-icon>
|
<el-icon class="icon3" @click="delBtn"><Delete /></el-icon>
|
</div>
|
<el-tree
|
ref="treeRef"
|
:key="treeKey"
|
:data="visualSimulationTreeData"
|
:props="defaultProps"
|
node-key="key"
|
:current-node-key="simulationKey"
|
:filter-node-method="filterNode1"
|
:highlight-current="true"
|
default-expand-all
|
@node-click="systemClick"
|
>
|
<template #default="{ node, data }">
|
<span class="custom-tree-node">
|
<el-icon v-if="data.icon"><component :is="data.icon" /></el-icon>
|
<span>{{ node.label }}</span>
|
</span>
|
</template>
|
</el-tree>
|
</div>
|
<div class="tree-menu" v-if="seleStore.curTab == 'systemManage'">
|
<el-tree
|
ref="treeRef"
|
:data="systemManageTreeData"
|
:props="defaultProps"
|
:key="systemKey"
|
:current-node-key="systemKey"
|
node-key="key"
|
:filter-node-method="filterNode1"
|
default-expand-all
|
@node-click="systemClick"
|
:highlight-current="true"
|
>
|
<template #default="{ node, data }">
|
<span class="custom-tree-node">
|
<el-icon v-if="data.icon"><component :is="data.icon" /></el-icon>
|
<span>{{ node.label }}</span>
|
</span>
|
</template>
|
</el-tree>
|
</div>
|
</div>
|
</div>
|
<el-dialog
|
v-model="dialogFormVisible"
|
:title="dialogTitle"
|
width="500"
|
@close="closeDialog(formRef)"
|
>
|
<el-form :model="form" ref="formRef" :rules="formRules" label-width="140px">
|
<el-form-item label="名称" prop="name">
|
<el-input
|
v-model="form.name"
|
autocomplete="off"
|
placeholder="请输入"
|
style="width: 240px"
|
/>
|
</el-form-item>
|
<el-form-item label="编码" prop="refCode">
|
<el-input
|
v-model="form.refCode"
|
autocomplete="off"
|
placeholder="请输入"
|
style="width: 240px"
|
/>
|
</el-form-item>
|
<el-form-item label="描述">
|
<el-input
|
v-model="form.description"
|
style="width: 240px"
|
:rows="2"
|
type="textarea"
|
placeholder="请输入"
|
/>
|
</el-form-item>
|
</el-form>
|
<template #footer>
|
<div class="dialog-footer">
|
<el-button @click="closeDialog(formRef)">取消</el-button>
|
<el-button type="primary" @click="submitBtn(formRef)"> 确定 </el-button>
|
</div>
|
</template>
|
</el-dialog>
|
</template>
|
|
<script setup lang="ts">
|
import {
|
ref,
|
reactive,
|
defineProps,
|
onMounted,
|
inject,
|
watch,
|
nextTick,
|
} from "vue";
|
import { useRoute, useRouter } from "vue-router";
|
import type { FormInstance, FormRules } from "element-plus";
|
import { ElMessage, ElMessageBox } from "element-plus";
|
import { Document, FolderOpened } from "@element-plus/icons-vue";
|
import { fa } from "element-plus/es/locale";
|
const MG: any = inject("MG");
|
const toolClass: any = inject("toolClass");
|
import { curStoreInfo } from "@/store/index";
|
const seleStore = curStoreInfo();
|
const router = useRouter();
|
const loadTree = ref(false);
|
const treeRef = ref(null);
|
const curSelectNode = ref();
|
const props = defineProps<{
|
menuItem: string;
|
modelTreeData: any;
|
storeInfo: any;
|
}>();
|
const menuName = ref("模型库");
|
const filteredData = ref();
|
const systemMenuName = ref("");
|
const currentNodeKey = ref(1);
|
const treeKey = ref(0);
|
const systemKey = ref(0);
|
const simulationKey = ref(0);
|
const systemData = ref([]);
|
const selectData = ref();
|
const createParent = ref(false);
|
interface TreeNode {
|
label: string;
|
path?: string;
|
icon?: string;
|
children?: TreeNode[];
|
}
|
const defaultProps = {
|
children: "children",
|
label: "label",
|
isLeaf: "leaf",
|
key: "key",
|
};
|
const route = useRoute();
|
const visualSimulationTreeData = ref<TreeNode[]>([
|
{
|
label: "测试仿真",
|
path: "/testSimulation",
|
icon: "Document",
|
key: 0,
|
},
|
{
|
label: "实时仿真",
|
path: "realTimeSimulation",
|
icon: "Document",
|
key: 1,
|
},
|
{
|
label: "自主功能",
|
path: "/autonomousFunction",
|
icon: "Document",
|
key: 2,
|
},
|
]);
|
|
const systemManageTreeData = ref<TreeNode[]>([
|
{
|
key: 0,
|
label: "机构用户",
|
path: "/userManage",
|
icon: "Document",
|
},
|
{ key: 1, label: "角色权限管理", path: "/roleManage", icon: "Document" },
|
]);
|
|
const systemTreeData = ref<TreeNode[]>([
|
{
|
label: "501",
|
path: "",
|
icon: "Document",
|
children: [
|
{
|
label: "一室",
|
path: "",
|
icon: "",
|
},
|
{
|
label: "二室",
|
path: "",
|
icon: "",
|
},
|
{
|
label: "三室",
|
path: "",
|
icon: "",
|
},
|
],
|
},
|
]);
|
const systemTreeData1 = ref<TreeNode[]>([
|
{
|
label: "系统管理员",
|
path: "",
|
icon: "",
|
},
|
{
|
label: "模型管理员",
|
path: "",
|
icon: "",
|
},
|
{
|
label: "测试人员",
|
path: "",
|
icon: "",
|
},
|
{
|
label: "报告查看人员",
|
path: "",
|
icon: "",
|
},
|
]);
|
|
const dialogFormVisible = ref(false);
|
const dialogTitle = ref();
|
const formRef = ref<FormInstance>();
|
const form = reactive({
|
name: "",
|
refCode: "",
|
description: "",
|
});
|
|
interface formInfo {
|
name: string;
|
}
|
const formRules = reactive<FormRules<formInfo>>({
|
name: [{ required: true, message: "名称不能为空", trigger: "blur" }],
|
});
|
|
watch(
|
() => route,
|
(newRoute) => {
|
console.log("路由变化:", newRoute.path);
|
// 处理路由变化逻辑
|
},
|
{ deep: true }
|
);
|
|
watch(
|
() => seleStore.curTab, // 监听 reactive 对象(默认深度监听)
|
(newVal) => {
|
if (newVal) {
|
if (seleStore.curTab == "model") {
|
menuName.value = "模型库";
|
} else if (seleStore.curTab == "simulation") {
|
menuName.value = "可视化仿真";
|
filteredData.value = visualSimulationTreeData.value;
|
} else if (seleStore.curTab == "systemManage") {
|
menuName.value = "系统管理";
|
filteredData.value = systemManageTreeData.value;
|
} else {
|
filteredData.value = [];
|
}
|
systemMenuName.value = systemManageTreeData.value[0].label;
|
}
|
}
|
);
|
|
onMounted(() => {
|
console.log(route, "route.route");
|
});
|
|
watch(
|
() => props.storeInfo, // 监听 reactive 对象(默认深度监听)
|
(newVal) => {
|
if (newVal) {
|
loadTree.value = true;
|
}
|
}
|
);
|
|
const loadNode = async (node, resolve) => {
|
if (node.level == 0) {
|
const treeData = await getTableData(0);
|
const list = treeData.filter((item) => item.data.refCode !== "testReport");
|
const testReport = treeData.find(
|
(item) => item.data.refCode === "testReport"
|
);
|
console.log(list, "list");
|
console.log(testReport, "testReport");
|
nextTick(() => {
|
currentNodeKey.value = 0; // 确保节点已渲染
|
seleStore.setChannelInfo(list[0]);
|
seleStore.setTestReportChannel(testReport);
|
selectData.value = list[0];
|
});
|
return resolve(list);
|
}
|
if (node.childNodes.length > 0) {
|
return resolve([]);
|
}
|
// 显示加载状态
|
node.loading = true;
|
const childNodes = await getTableData(node.data.data);
|
resolve(childNodes);
|
};
|
|
//处理树形结构
|
const handleTreeData = (datas: any[], parent, noTriggerSelect = false) => {
|
let parentData = {};
|
if (parent) {
|
parentData = { ...parent, parent: null };
|
} else {
|
parentData = null;
|
}
|
const list = [];
|
for (let i = 0; i < datas.length; i++) {
|
const data = datas[i];
|
const obj = {
|
label: data.name,
|
key: parentData ? parentData.key + "_" + i : i + "",
|
namePath: parentData ? parentData.namePath + "\\" + data.name : data.name,
|
icon: data.icon,
|
data: data,
|
parent: parentData,
|
leaf: false,
|
children: [],
|
};
|
if (data["children"] && data["children"].length) {
|
obj.leaf = false;
|
obj.children = handleTreeData(
|
data["children"],
|
{
|
...data,
|
key: obj.key,
|
namePath: obj.namePath,
|
},
|
i == 0 ? false : true // 如果有子数据处理,只有第一条数据需要展开和回调
|
);
|
} else {
|
obj.leaf =
|
!data["childrenChannelCount"] || data["childrenChannelCount"] == 0;
|
}
|
list.push(obj);
|
}
|
console.log(list, "list");
|
return list;
|
};
|
|
const getTableData = async (path) => {
|
const treeData = await toolClass.getCmsItem({
|
path: path.idPath
|
? path.idPath
|
: props.storeInfo.repositoryData.rootChannel.id,
|
storeId: props.storeInfo.storeId,
|
repositoryId: props.storeInfo.repositoryId,
|
type: "\\",
|
sort: {
|
LinkOrder: "Asc",
|
},
|
paging: {
|
Start: 0,
|
Size: 50,
|
},
|
filters: {
|
"SysType=": ["CmsChannel"],
|
},
|
fields: {
|
ChildrenCount: [],
|
},
|
});
|
if (treeData && treeData.datas.length > 0) {
|
const fomartData = handleTreeData(
|
treeData.datas,
|
path ? path : null,
|
false
|
);
|
seleStore.setChannelInfo(fomartData[0]);
|
seleStore.setChannelList(fomartData);
|
return fomartData;
|
} else {
|
return [];
|
}
|
};
|
|
const filterNode = (value: string, data: TreeNode) => {
|
if (!value) return true;
|
return data.label.toLowerCase().includes(value.toLowerCase());
|
};
|
|
const filterNode1 = (value: string, data: TreeNode) => {
|
if (!value) return true;
|
return data.label.toLowerCase().includes(value.toLowerCase());
|
};
|
|
const handleNodeClick = (data: TreeNode) => {
|
seleStore.setChannelInfo(data);
|
selectData.value = data;
|
};
|
|
//添加目录
|
const addBtn = (type) => {
|
if (type == "child") {
|
dialogTitle.value = "新建子频道";
|
createParent.value = false;
|
} else {
|
dialogTitle.value = "新建频道";
|
createParent.value = true;
|
}
|
|
dialogFormVisible.value = true;
|
};
|
const submitBtn = async (formEl: FormInstance | undefined) => {
|
if (!formEl) return;
|
await formEl.validate(async (valid, fields) => {
|
if (valid) {
|
console.log(form.name, "fields");
|
|
if (dialogTitle.value == "编辑") {
|
const body = {
|
accessPath: selectData.value.data.idPath,
|
accessStoreId: selectData.value.data.storeId,
|
accessRepositoryId: selectData.value.data.repositoryId,
|
accessItemId: selectData.value.data.id,
|
name: form.name, // form.name,
|
description: form.description,
|
refCode: form.refCode,
|
state: selectData.value.data.state,
|
icon: selectData.value.data.icon,
|
type: selectData.value.data.type,
|
};
|
const updateCmsItem = await MG.dps5.UpdateCmsItem({
|
updateList: [body],
|
});
|
if (updateCmsItem) {
|
ElMessage({
|
message: "编辑成功",
|
type: "success",
|
});
|
dialogFormVisible.value = false;
|
form.name = "";
|
form.refCode = "";
|
form.description = "";
|
treeKey.value += 1;
|
}
|
} else {
|
const body = {
|
accessPath: createParent.value
|
? props.storeInfo.repositoryData.rootChannel.id
|
: selectData.value.data.idPath,
|
accessStoreId: props.storeInfo.storeId,
|
accessRepositoryId: props.storeInfo.repositoryId,
|
sysType: "CmsChannel",
|
linkType: "Link",
|
cmsItemRequest: {
|
...form,
|
state: "Normal",
|
type: "Normal",
|
module: "",
|
accessType: "Public",
|
},
|
};
|
const newCmsItem = await MG.dps5.NewCmsItem(body);
|
if (newCmsItem) {
|
ElMessage({
|
message: "添加成功",
|
type: "success",
|
});
|
dialogFormVisible.value = false;
|
form.name = "";
|
form.refCode = "";
|
form.description = "";
|
treeKey.value += 1;
|
} else {
|
ElMessage({
|
message: "添加失败",
|
type: "error",
|
});
|
}
|
}
|
}
|
});
|
};
|
const closeDialog = (formEl: FormInstance | undefined) => {
|
if (!formEl) return;
|
formEl.resetFields();
|
dialogFormVisible.value = false;
|
};
|
|
const editBtn = () => {
|
dialogTitle.value = "编辑";
|
form.name = selectData.value.label;
|
form.refCode = selectData.value.data.refCode;
|
form.description = selectData.value.data.description;
|
dialogFormVisible.value = true;
|
};
|
|
const delBtn = () => {
|
if (selectData.value.data.childrenCmsItemCount > 0) {
|
ElMessage({
|
message: "频道下还有其他资源,请先删除资源后重试!",
|
type: "warning",
|
});
|
return false;
|
}
|
if (selectData.value.data.childrenChannelCount > 0) {
|
ElMessage({
|
message: "频道下还有子频道,请先删除子频道后重试!",
|
type: "warning",
|
});
|
return false;
|
}
|
ElMessageBox.confirm("确定要删除选中的数据?", "删除频道", {
|
confirmButtonText: "确定",
|
cancelButtonText: "取消",
|
type: "warning",
|
})
|
.then(() => {
|
console.log(selectData.value, "selectData.value");
|
let accessPath = "";
|
let accessItemId = 0;
|
if (!selectData.value.parent) {
|
accessPath = props.storeInfo.repositoryData.rootChannel.id + "";
|
accessItemId = props.storeInfo.repositoryData.rootChannel.id;
|
} else {
|
accessPath = selectData.value.parent.data.idPath;
|
accessItemId = selectData.value.parent.data.id;
|
}
|
MG.dps5
|
.DelCmsItemByList({
|
accessPath,
|
accessStoreId: selectData.value.data.storeId,
|
accessRepositoryId: selectData.value.data.repositoryId,
|
accessItemId,
|
itemIds: [selectData.value.data.id],
|
})
|
.then((res) => {
|
ElMessage({
|
message: "删除成功",
|
type: "success",
|
});
|
treeKey.value += 1;
|
});
|
})
|
.catch(() => {});
|
};
|
|
const systemClick = (data: TreeNode) => {
|
curSelectNode.value = data;
|
router.push({
|
path: "/systemManage" + data.path,
|
});
|
console.log(curSelectNode.value, "curSelectNode");
|
};
|
</script>
|
|
<style lang="less" scoped>
|
.tree-menu-box {
|
height: 100%;
|
background-color: #fff;
|
.flex {
|
height: 100%;
|
}
|
}
|
.tree-menu {
|
width: 260px;
|
height: 100%;
|
border-right: 1px solid #e9eef3;
|
:deep(.el-tree) {
|
padding: 10px;
|
}
|
|
.custom-tree-node {
|
display: flex;
|
align-items: center;
|
gap: 8px;
|
}
|
|
.topMenu {
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
padding: 10px;
|
border-bottom: 1px solid #ebeef5;
|
.topMenu-title {
|
font-size: 16px;
|
font-weight: bold;
|
}
|
.btnGroup {
|
display: flex;
|
gap: 12px;
|
cursor: pointer;
|
|
.icon1,
|
.icon2,
|
.icon3 {
|
font-size: 18px;
|
color: #606266;
|
&:hover {
|
color: #409eff;
|
}
|
}
|
}
|
}
|
}
|
</style>
|