| | |
| | | <template> |
| | | <div class="tree-menu"> |
| | | <div class="topMenu"> |
| | | <span class="topMenu-title">模型库</span> |
| | | <div class="btnGroup"> |
| | | <el-icon class="icon1"><FolderAdd /></el-icon> |
| | | <el-icon class="icon2"><Edit /></el-icon> |
| | | <el-icon class="icon3"><Delete /></el-icon> |
| | | <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> |
| | | <el-tree |
| | | ref="treeRef" |
| | | :data="filteredData" |
| | | :props="defaultProps" |
| | | :filter-node-method="filterNode" |
| | | default-expand-all |
| | | @node-click="handleNodeClick" |
| | | > |
| | | <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> |
| | | <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, watch, defineProps } from "vue"; |
| | | import { useRouter } from "vue-router"; |
| | | 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 treeRef = ref(); |
| | | 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 modelTreeData = ref<TreeNode[]>([ |
| | | const defaultProps = { |
| | | children: "children", |
| | | label: "label", |
| | | isLeaf: "leaf", |
| | | key: "key", |
| | | }; |
| | | const route = useRoute(); |
| | | const visualSimulationTreeData = ref<TreeNode[]>([ |
| | | { |
| | | label: "型号", |
| | | icon: "FolderOpened", |
| | | 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: "型号1", |
| | | path: "/model/childrenModel01", |
| | | label: "一室", |
| | | path: "", |
| | | icon: "", |
| | | }, |
| | | { |
| | | label: "型号2", |
| | | label: "二室", |
| | | path: "", |
| | | icon: "", |
| | | }, |
| | | { |
| | | label: "三室", |
| | | path: "", |
| | | icon: "", |
| | | }, |
| | | ], |
| | | }, |
| | | ]); |
| | | const systemTreeData1 = ref<TreeNode[]>([ |
| | | { |
| | | label: "系统管理员", |
| | | path: "", |
| | | icon: "", |
| | | }, |
| | | { |
| | | label: "模型管理员", |
| | | path: "", |
| | | icon: "", |
| | | }, |
| | | { |
| | | label: "测试人员", |
| | | path: "", |
| | | icon: "", |
| | | }, |
| | | { |
| | | label: "报告查看人员", |
| | | path: "", |
| | | icon: "", |
| | | }, |
| | | ]); |
| | | |
| | | const defaultProps = { |
| | | children: "children", |
| | | label: "label", |
| | | 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 filteredData = ref(modelTreeData.value); |
| | | //处理树形结构 |
| | | 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 handleNodeClick = (data: TreeNode) => { |
| | | if (data.path) { |
| | | router.push(data.path); |
| | | } |
| | | const filterNode1 = (value: string, data: TreeNode) => { |
| | | if (!value) return true; |
| | | return data.label.toLowerCase().includes(value.toLowerCase()); |
| | | }; |
| | | |
| | | watch( |
| | | () => props.menuItem, |
| | | (value) => { |
| | | if (value == "/" || value == "/model") { |
| | | filteredData.value = modelTreeData.value; |
| | | } else { |
| | | filteredData.value = [] |
| | | } |
| | | 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 { |
| | | .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; |
| | | } |