From 96be59a64cc1d8fcaf1034e787717663c68df4a7 Mon Sep 17 00:00:00 2001
From: 杨磊 <505174330@qq.com>
Date: 星期一, 26 五月 2025 10:39:58 +0800
Subject: [PATCH] 2025-5-26提交

---
 src/components/TreeMenu.vue |  648 ++++++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 595 insertions(+), 53 deletions(-)

diff --git a/src/components/TreeMenu.vue b/src/components/TreeMenu.vue
index f0c0b6b..55716bb 100644
--- a/src/components/TreeMenu.vue
+++ b/src/components/TreeMenu.vue
@@ -1,100 +1,642 @@
 <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;
   }

--
Gitblit v1.9.1