Răsfoiți Sursa

基础信息的完善

“yueshang” 1 an în urmă
părinte
comite
3c28fdd787

+ 9 - 0
src/api/iedNetwork/index.js

@@ -156,5 +156,14 @@ export function getNetworkInfo(query) {
     params: query
   })
 }
+//基础信息主体LDevice数据
+export function getLdeviceList(query) {
+  return request({
+    url: 'screen/scd/ldevice/list',
+    method: 'get',
+    params: query
+  })
+}
+
 
 

+ 375 - 92
src/pages/netStructPicture/components/basicInfo.vue

@@ -1,8 +1,13 @@
 <template>
-  <div id="treedom4">
+  <div id="treedom4" v-loading="loading">
     <div style="position: relative">
       <div class="nav" id="topLine">
-        <div class="nav-cont" v-for="(item, index) in navList" :key="index">
+        <div
+          class="nav-cont"
+          v-for="(item, index) in navList"
+          :key="index"
+          @click="clickNav(item)"
+        >
           <img :src="cylinder" alt="" class="nav-img" />
           <div>{{ item.attr_name }}</div>
           <div class="describe-text">{{ `(${item.attr_desc})` }}</div>
@@ -11,56 +16,145 @@
     </div>
     <div class="wrapper">
       <div class="grid">
-        <div class="col fluid" style="margin-left: 20px" id="leftLine">
-          <div>
-            <div class="title">M1 (一)</div>
-            <div>
-              <span class="decrip">SDFDSF:</span
-              ><span class="decrip-item">SDFSFF</span>
+        <div
+          class="col fluid"
+          :class="{ transp: mainTitle && mainTitle.length < 2 }"
+          style="margin-left: 20px"
+          id="leftLine"
+        >
+          <div v-if="mainTitle && mainTitle.length > 1">
+            <div class="title">
+              {{ mainTitle[1].attr_name
+              }}<span v-if="mainTitle[0].attr_desc">{{
+                `(${mainTitle[1].attr_desc})`
+              }}</span>
             </div>
-          </div>
-          <div class="child-item">
-            <div class="ldevice">LDevice</div>
-            <div>
-              <img :src="legislation" alt="" />
-              <div class="img-title">SVLD_PROT</div>
-              <div class="decrip-child">(录波LD)</div>
+            <div class="attr-desc" v-if="moLeft">
+              <div>
+                <span class="decrip">MAC-Address:</span>
+                <span class="decrip-item" v-if="!moLeft.address">无</span>
+                <span v-else>{{ moLeft.address }}</span>
+              </div>
+              <div>
+                <span class="decrip">VLAN-PRIORITY:</span>
+                <span class="decrip-item" v-if="!moLeft.priority">无</span>
+                <span v-else>{{ moLeft.priority }}</span>
+              </div>
+              <div>
+                <span class="decrip">APPID:</span>
+                <span class="decrip-item" v-if="!moLeft.APPID">无</span>
+                <span v-else>{{ moLeft.APPID }}</span>
+              </div>
+              <div>
+                <span class="decrip">VLAN-ID:</span>
+                <span class="decrip-item" v-if="!moLeft.vlanId">无</span>
+                <span v-else>{{ moLeft.vlanId }}</span>
+              </div>
             </div>
-            <div>
-              <img :src="legislation" alt="" />
-              <div class="img-title">SVLD_PROT</div>
+            <div v-if="mainList" class="circle-all">
+              <span
+                v-for="(item, index) in mainTitle[1].list"
+                :key="index"
+                class="circel"
+                :class="{ 'circel active-circel': index == activeCircel }"
+                @click="clickCircel(item, index, 'moLeft')"
+                ><span v-if="item.address_json != ''">{{
+                  index + 1
+                }}</span></span
+              >
             </div>
-            <div>
+          </div>
+          <div class="child-item" v-if="mainTitle && mainTitle.length > 1">
+            <div class="ldevice">LDevice</div>
+            <div
+              v-for="(item, index) in mainTitle[1].childList[0]"
+              :key="index"
+              @click="clickMain(item)"
+              class="ldevice-cont"
+            >
               <img :src="legislation" alt="" />
-              <div class="img-title">SVLD_PROT</div>
+              <div class="img-title">{{ item.attr_inst }}</div>
+              <div class="decrip-child">{{ item.attr_desc }}</div>
             </div>
           </div>
         </div>
         <div class="col main-middle" id="middleLine"></div>
-        <div class="col fluid" style="margin-right: 20px" id="rightLine">
-          <div>
-            <div class="title">M1 (一)</div>
-            <div>
-              <span class="decrip">SDFDSF:</span
-              ><span class="decrip-item">SDFSFF</span>
+        <div
+          class="col fluid"
+          style="margin-right: 20px"
+          :class="{ transp: mainTitle && mainTitle.length < 3 }"
+          id="rightLine"
+        >
+          <div v-if="mainTitle && mainTitle.length > 2">
+            <div class="title">
+              {{ mainTitle[2].attr_name
+              }}<span v-if="mainTitle[0].attr_desc">{{
+                `(${mainTitle[2].attr_desc})`
+              }}</span>
+            </div>
+            <div class="attr-desc" v-if="moRight">
+              <div>
+                <span class="decrip">MAC-Address:</span>
+                <span class="decrip-item" v-if="!moRight.address">无</span>
+                <span v-else>{{ moRight.address }}</span>
+              </div>
+              <div>
+                <span class="decrip">VLAN-PRIORITY:</span>
+                <span class="decrip-item" v-if="!moRight.priority">无</span>
+                <span v-else>{{ moRight.priority }}</span>
+              </div>
+              <div>
+                <span class="decrip">APPID:</span>
+                <span class="decrip-item" v-if="!moRight.APPID">无</span>
+                <span v-else>{{ moRight.APPID }}</span>
+              </div>
+              <div>
+                <span class="decrip">VLAN-ID:</span>
+                <span class="decrip-item" v-if="!moRight.vlanId">无</span>
+                <span v-else>{{ moRight.vlanId }}</span>
+              </div>
+            </div>
+            <div v-if="mainList" class="circle-all">
+              <span
+                v-for="(item, index) in mainTitle[2].list"
+                :key="index"
+                class="circel"
+                :class="{ 'circel active-circel': index == activeCircel }"
+                @click="clickCircel(item, index, 'moRight')"
+                ><span v-if="item.address_json != ''">{{
+                  index + 1
+                }}</span></span
+              >
             </div>
           </div>
-          <div class="child-item">
+          <div class="child-item" v-if="mainTitle && mainTitle.length > 2">
             <div class="ldevice">LDevice</div>
-            <div>
+            <div
+              v-for="(item, index) in mainTitle[2].childList[0]"
+              :key="index"
+              @click="clickMain(item)"
+              class="ldevice-cont"
+            >
               <img :src="legislation" alt="" />
-              <div class="img-title">SVLD_PROT</div>
-              <div class="decrip-child">(录波LD)</div>
+              <div class="img-title">{{ item.attr_inst }}</div>
+              <div class="decrip-child">{{ item.attr_desc }}</div>
             </div>
           </div>
         </div>
       </div>
-      <div class="main-bottom" id="bottomLine">
-        <div v-if="titleName && titleName.length > 0">
+      <div
+        class="main-bottom"
+        id="bottomLine"
+        :class="{ transp: mainTitle && mainTitle.length < 1 }"
+      >
+        <div v-if="mainTitle && mainTitle.length > 0">
           <div class="title">
-            {{ `${titleName[0].name}(${titleName[0].desc})` }}
+            {{ mainTitle[0].attr_name
+            }}<span v-if="mainTitle[0].attr_desc">{{
+              `(${mainTitle[0].attr_desc})`
+            }}</span>
           </div>
-          <div class="attr-desc">
+          <div class="attr-desc" v-if="moBottom">
             <div>
               <span class="decrip">MAC-Address:</span>
               <span class="decrip-item" v-if="!moBottom.address">无</span>
@@ -82,35 +176,88 @@
               <span v-else>{{ moBottom.vlanId }}</span>
             </div>
           </div>
-          <div v-if="mainList" style="margin-bottom: 10px">
+          <div v-if="mainList" class="circle-all">
             <span
-              v-for="(item, index) in mainList[titleName[0].name].list"
+              v-for="(item, index) in mainTitle[0].list"
               :key="index"
               class="circel"
-              @click="clickCircel(item)"
-              >{{ index + 1 }}</span
+              :class="{ 'circel active-circel': index == activeCircel }"
+              @click="clickCircel(item, index, 'moBottom')"
+              ><span v-if="item.address_json != ''">{{ index + 1 }}</span></span
             >
           </div>
         </div>
-        <div class="child-item" v-if="titleName && titleName.length > 0">
+        <div class="child-item" v-if="mainTitle && mainTitle.length > 0">
           <div class="ldevice">LDevice</div>
-          <div>
+          <div class="ldevice-cont" v-for="(item, index) in mainTitle[0].childList[0]" :key="index" @click="clickMain(item)">
             <img :src="legislation" alt="" />
-            <div class="img-title">SVLD_PROT</div>
-            <div class="decrip-child">(录波LD)</div>
-          </div>
-          <div>
-            <img :src="legislation" alt="" />
-            <div class="img-title">SVLD_PROT</div>
-          </div>
-          <div>
-            <img :src="legislation" alt="" />
-            <div class="img-title">SVLD_PROT</div>
+            <div class="img-title">{{ item.attr_inst }}</div>
+            <div class="decrip-child">{{ item.attr_desc }}</div>
           </div>
         </div>
       </div>
     </div>
     <div id="wrappers"></div>
+    <!-- 点击头部的弹框 -->
+    <el-dialog
+      @close="cancelClickNav"
+      v-model="isOpennav"
+      append-to-body
+      draggable
+      style="height: 550px"
+    >
+      <template #header>
+        <div class="my-header">
+          <div class="dialog-nav-title">
+            {{ `(${clickNavTitle.attr_desc}) — FCDA列表` }}
+          </div>
+        </div>
+      </template>
+      <el-table
+        :data="clickNavData"
+        style="width: 100%"
+        stripe
+        height="450"
+        :cell-style="{ color: '#000' }"
+      >
+        <el-table-column prop="attr_ld_inst" label="ldInst" />
+        <el-table-column prop="attr_prefix" label="prefix"/>
+        <el-table-column prop="attr_ln_class" label="lnClass"/>
+        <el-table-column prop="attr_ln_inst" label="lnInst" />
+        <el-table-column prop="attr_do_name" label="doName" />
+        <el-table-column prop="da_datatype" label="attr_da_name" width="180"/>
+        <el-table-column prop="attr_fc" label="fc" />
+      </el-table>
+    </el-dialog>
+    <!-- 点击方框的弹窗 -->
+    <el-dialog
+      @close="cancelClickMain"
+      v-model="isOpenMain"
+      append-to-body
+      draggable
+      style="height: 550px"
+    >
+      <template #header>
+        <div class="my-header">
+          <div class="dialog-nav-title">
+            {{ `${clickMainTitle.attr_inst}${clickMainTitle.attr_desc} — LN/LN0节点列表` }}
+          </div>
+        </div>
+      </template>
+      <el-table
+        :data="clickMainData"
+        style="width: 100%"
+        stripe
+        height="450"
+        :cell-style="{ color: '#000' }"
+      >
+      <el-table-column type="index" label="序号" width="80" />
+        <el-table-column prop="attr_inst" label="inst" />
+        <el-table-column prop="attr_ln_class" label="lnClass"/>
+        <el-table-column prop="attr_ln_type" label="lnType"/>
+        <el-table-column prop="attr_desc" label="desc" />
+      </el-table>
+    </el-dialog>
   </div>
 </template>
 
@@ -118,7 +265,7 @@
 import { defineProps, onMounted, ref, inject, nextTick, watch } from "vue";
 import legislation from "@/assets/image/instruct/legislation.png";
 import cylinder from "@/assets/image/instruct/cylinder.png";
-import { getNodeList, getNetworkInfo } from "@/api/iedNetwork";
+import { getNodeList, getNetworkInfo, getLdeviceList,nodeList } from "@/api/iedNetwork";
 import LeaderLine from "../../../../public/leader-line.min.js";
 import AnimEvent from "../../../../public/anim-event.min.js";
 import { CloseBold } from "@element-plus/icons-vue";
@@ -138,6 +285,14 @@ const mainTitle = ref(null); //每个方框的标题
 const moBottom = ref(null); //底部方框所展示的MAC-Address等desc
 const moLeft = ref(null); //左侧方框所展示的MAC-Address等desc
 const moRight = ref(null); //右侧方框所展示的MAC-Address等desc
+const activeCircel = ref(0); //点击数字圆圈的样式
+const isOpennav = ref(false);//头部点击弹窗显示
+const clickNavTitle= ref(null);//头部点击弹窗数据
+const clickNavData = ref(null);//头部点击弹窗数据
+const isOpenMain = ref(false);//点击方框
+const clickMainTitle = ref(null);
+const clickMainData = ref(null);
+const loading = ref(true);
 const getNav = async () => {
   const navRes = await getNodeList({
     scd_id: scdIdValue,
@@ -154,7 +309,22 @@ const getMainTitle = async () => {
     ied_name: props.checkData.ied_name,
     name: "AccessPoint",
   });
-  mainTitle.value = mainRes.data;
+  //得到每个方框中LDevice中的内容
+  Promise.all(
+    mainRes.data.map(async (item) => {
+      item.childList = [];
+      const res = await getLdeviceList({
+        accessPointId: item.node_id,
+        scd_id: scdIdValue,
+      });
+      item.childList.push(res.data);
+    })
+  ).then(() => {
+    //等待执行完上面的api
+    loading.value = false;
+    mainTitle.value = mainRes.data;
+    getMainList();
+  });
 };
 const mainList = ref({});
 const titleName = ref([]);
@@ -167,13 +337,15 @@ const getMainList = async () => {
     scd_id: scdIdValue,
     ied_name: props.checkData.ied_name,
   });
+
   //处理分类数据
   for (let i = 0; i < infoRes.data.length; i++) {
     if (infoRes.data[i].address_json != "") {
-      infoRes.data[i].address_json.replace("MAC-Address", "address");
-      infoRes.data[i].address_json.replace("VLAN-PRIORITY", "priority");
-      infoRes.data[i].address_json.replace("VLAN-ID", "vlanId");
-      infoRes.data[i].address_json = JSON.parse(infoRes.data[i].address_json);
+      let newData = infoRes.data[i].address_json
+        .replace("MAC-Address", "address")
+        .replace("VLAN-PRIORITY", "priority")
+        .replace("VLAN-ID", "vlanId");
+      infoRes.data[i].address_json = JSON.parse(newData);
     }
     let item = infoRes.data[i];
     const key = item.ap_name;
@@ -187,21 +359,37 @@ const getMainList = async () => {
       mainList.value[key].list.push(item);
     }
   }
-  const newarr2 = [...new Set(newarr)];
-  //处理表头描述
-  if (newarr2 && mainTitle.value) {
-    newarr2.map((item) => {
-      const descObj = mainTitle.value.find((key) => key.attr_name == item);
-      if (descObj) {
-        titleName.value.push({ name: item, desc: descObj.attr_desc });
-      }
+  //处理表头下方段落的描述
+  if (mainList.value && mainTitle.value) {
+    mainTitle.value.forEach((key) => {
+      key.list = [];
+      Object.keys(mainList.value).forEach((item) => {
+        if (item == key.attr_name) {
+          key.list = mainList.value[item].list;
+        }
+      });
     });
-  }
-  if (titleName.value.length > 0 && mainList.value) {
-    moBottom.value =
-      mainList.value[titleName.value[0].name].list[0].address_json;
-    console.log("address_json", moBottom.value);
-    console.log("first", titleName.value, mainList.value);
+    //分布默认的左侧右侧和下侧的数据
+    for (let i = 0; i < mainTitle.value.length; i++) {
+      if (
+        mainTitle.value[i].list.length > 0 &&
+        mainTitle.value[i].list[0].address_json != ""
+      ) {
+        const targetElement = mainTitle.value[i];
+        switch (i) {
+          case 0:
+            moBottom.value = targetElement.list[0].address_json;
+            break;
+          case 1:
+            moLeft.value = targetElement.list[0].address_json;
+            break;
+          case 2:
+            moRight.value = targetElement.list[0].address_json;
+            break;
+        }
+      }
+    }
+    console.log("mainTitle.value", mainTitle.value);
   }
 };
 //弹窗打开后使得线条在指定区域中
@@ -276,27 +464,43 @@ const getLine = () => {
     }),
   };
   leaderLines.value.push(new LeaderLine(middlDom, topDom, lineStyleTop)); //上面和中间连线
-  leaderLines.value.push(new LeaderLine(middlDom, rightDom, lineStyleright));
-  leaderLines.value.push(new LeaderLine(middlDom, bottomDom, lineStylebottom));
-  leaderLines.value.push(new LeaderLine(leftDom, middlDom, lineStyle));
+  if (mainTitle.value && mainTitle.value.length > 0) {
+    leaderLines.value.push(
+      new LeaderLine(middlDom, bottomDom, lineStylebottom)
+    );
+  }
+  if (mainTitle.value && mainTitle.value.length > 2) {
+    leaderLines.value.push(new LeaderLine(middlDom, rightDom, lineStyleright));
+  }
+  if (mainTitle.value && mainTitle.value.length > 1) {
+    leaderLines.value.push(new LeaderLine(leftDom, middlDom, lineStyle));
+  }
   newPositionLine2();
   hiddenLine2();
 };
 //点击数字
-const clickCircel = (item) => {
-
-  const data = JSON.stringify(item.address_json);
-  // data.replace("MAC-Address", "address");
-  // data.replace("VLAN-PRIORITY", "priority");
-  // data.replace("VLAN-ID", "vlanId");
-  moBottom.value = JSON.parse(data);
+const clickCircel = (item, index, type) => {
+  activeCircel.value = index;
+  let data = JSON.stringify(item.address_json);
+  let newData = data
+    .replace("MAC-Address", "address")
+    .replace("VLAN-PRIORITY", "priority")
+    .replace("VLAN-ID", "vlanId");
+  if (type == "moBottom") {
+    moBottom.value = JSON.parse(newData);
+  } else if (type == "moRight") {
+    moRight.value = JSON.parse(newData);
+  } else {
+    moLeft.value = JSON.parse(newData);
+  }
 };
 onMounted(() => {
   getNav();
   getMainTitle();
-  getMainList();
   nextTick(() => {
-    getLine();
+    setTimeout(() => {
+      getLine();
+    }, 500);
   });
 });
 watch(
@@ -306,8 +510,11 @@ watch(
       if (!newValue) {
         removeLine2();
         leaderLines.value = [];
+        loading.value = false;
       } else {
-        getLine();
+        setTimeout(() => {
+          getLine();
+        }, 500);
       }
     });
   }
@@ -315,12 +522,23 @@ watch(
 watch(
   () => props.checkData,
   (newValue) => {
-    getNav();
-    getMainTitle();
-    getMainList();
-    nextTick(() => {
-      getLine();
-    });
+    removeLine2();
+    if (newValue && leaderLines.value.length > 0) {
+      leaderLines.value = [];
+    }
+    if (newValue) {
+      activeCircel.value = 0;
+      isOpenMain.value = false;
+      isOpennav.value = false;
+      getNav();
+      loading.value = true;
+      getMainTitle();
+      nextTick(() => {
+        setTimeout(() => {
+          getLine();
+        }, 500);
+      });
+    }
   }
 );
 const removeLine2 = () => {
@@ -329,6 +547,44 @@ const removeLine2 = () => {
     elmWrapper.removeChild(node);
   });
 };
+//点击头部展示的弹框
+const clickNav =async (item) => {
+  clickNavTitle.value = item;
+  isOpennav.value = true;
+  const navRes = await nodeList({
+    scd_id: scdIdValue,
+    parent_node_id:item.node_id,
+    pagesize: 10000,
+    name: "FCDA",
+  });
+  clickNavData.value = navRes.data;
+};
+const cancelClickNav = () => {
+  clickNavData.value = null;
+  isOpennav.value = false;
+}
+const clickMain =async (item) => {
+  console.log('item', item)
+  clickMainTitle.value = item;
+  isOpenMain.value = true;
+  const navRes = await nodeList({
+    scd_id: scdIdValue,
+    parent_node_id:item.node_id,
+    pagesize: 10000,
+    name: "LN0",
+  });
+  const navRes2 = await nodeList({
+    scd_id: scdIdValue,
+    parent_node_id:item.node_id,
+    pagesize: 10000,
+    name: "LN",
+  });
+  clickMainData.value = [...navRes.data,...navRes2.data];
+};
+const cancelClickMain = () => {
+  clickMainData.value = null;
+  isOpenMain.value = false;
+}
 </script>
 
 <style scoped lang="scss">
@@ -357,6 +613,7 @@ const removeLine2 = () => {
     display: flex;
     flex-direction: column;
     align-items: center;
+    cursor: pointer;
     margin: 8px 0;
     flex-basis: 14%;
     .describe-text {
@@ -367,6 +624,7 @@ const removeLine2 = () => {
 .main-bottom,
 .fluid {
   border: 2px dashed #a3ade0;
+  background-color: #f7f8f8;
   display: flex;
   flex-direction: column;
   max-width: 36%;
@@ -416,19 +674,38 @@ const removeLine2 = () => {
       color: white;
       border-radius: 10px;
     }
+    .ldevice-cont{
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+    }
   }
   .img-title {
     color: #134bea;
   }
 }
+.circle-all {
+  margin-bottom: 10px;
+  display: flex;
+  flex-wrap: wrap;
+}
 .circel {
   color: #7c58a8;
-  padding: 0rem 0.4rem;
+  width: 20px;
+  height: 20px;
+  margin-bottom: 5px;
+  margin-right: 5px;
   border: 1px solid #606c93;
-  border-radius: 1rem;
+  border-radius: 10px;
+  text-align: center;
+  line-height: 20px;
   margin-left: 0.5rem;
   cursor: pointer;
 }
+.active-circel {
+  color: #134bea;
+  border: 1px solid #134bea;
+}
 .Image {
   width: 193px;
   height: 150px;
@@ -459,7 +736,9 @@ const removeLine2 = () => {
 /* 设置fluid样式 */
 .fluid {
   flex-grow: 1;
-  background-color: #f7f8f8;
+}
+.transp {
+  border: none;
 }
 .main-bottom {
   position: absolute;
@@ -467,4 +746,8 @@ const removeLine2 = () => {
   transform: translateX(-50%);
   margin-top: 40px;
 }
+.dialog-nav-title{
+  color:#09162C;
+  font-size: 16px;
+}
 </style>

+ 1 - 1
src/pages/netStructPicture/components/dialogIndex.vue

@@ -12,7 +12,7 @@
     <template #header>
       <div class="my-header">
         <div class="title" v-if="checkData">
-          {{ checkData.desc }}
+          {{ `${checkData.desc}(${checkData.ied_name}) — 详细信息` }}
         </div>
       </div>
     </template>

+ 3 - 1
src/pages/netStructPicture/components/fixedEntry.vue

@@ -1,6 +1,6 @@
 <!-- 定值条目 -->
 <template>
-  <div>
+  <div v-loading="loading">
     <div class="cont-table">
       <el-table
         :data="dingzhiData"
@@ -61,11 +61,13 @@ const scdIdValue = inject("scdId");
 const dingzhiData = ref(null);
 const dingzhiDataChild = ref(null);
 const myTable5 = ref(null);
+const loading = ref(true);
 const getDingzhisList = async () => {
   const dingRes= await getDingzhis({
     scd_id: scdIdValue,
     ied_name: props.checkData.ied_name,
   })
+  loading.value = false;
   if(dingRes.data.length>0){
     dingzhiData.value = dingRes.data;
     dingzhiDataChild.value = dingRes.data[0].list;

+ 3 - 1
src/pages/netStructPicture/components/infoTable.vue

@@ -1,6 +1,6 @@
 <!-- 信息点表 -->
 <template>
-  <div>
+  <div v-loading="loading">
     <div class="cont-table">
       <el-table
         :data="dingzhiData"
@@ -69,11 +69,13 @@ const scdIdValue = inject("scdId");
 const dingzhiData = ref(null);
 const dingzhiDataChild = ref(null);
 const myTable5 = ref(null);
+const loading = ref(true);
 const getDingzhisList = async () => {
   const dingRes = await getPointtable({
     scd_id: scdIdValue,
     ied_name: props.checkData.ied_name,
   });
+  loading.value= false;
   if (dingRes.data.length > 0) {
     dingzhiData.value = dingRes.data;
     dingzhiDataChild.value = dingRes.data[0].list;

+ 6 - 6
src/pages/netStructPicture/components/scdVisual.vue

@@ -161,7 +161,7 @@ import scdDialogIndex from "./scdDialogIndex";
 const userStoreCode = useDataStore();
 const data = reactive({
   queryParams: {
-    scd_id: 512000138,
+    scd_id: 568000158,
   },
 });
 const loading = ref(true);
@@ -171,7 +171,7 @@ const { queryParams } = toRefs(data);
 // 表单重置
 const reset = () => {
   queryParams.value = {
-    scd_id: 512000138,
+    scd_id: 568000158,
     voltage_level_id: null, //电压等级
     area_id: null, //间隔
     device_type_id: null, //装置类型
@@ -185,7 +185,7 @@ const allIedType = [{ name: "全部", code: "alls" }];
 const voltageLevel = ref([{ name: "全部", id: "alls" }]); //电压等级
 const areaType = ref([]);
 const getArea = async () => {
-  const areaRes = await areaList({ scd_id: 512000138 });
+  const areaRes = await areaList({ scd_id: 568000158 });
   if (!areaRes.data) {
     voltageLevel.value = [];
     loading.value = false;
@@ -223,7 +223,7 @@ const getArea = async () => {
 //设备类型
 const iedTypeData = ref([]);
 const getTypelist = async () => {
-  const typeRes = await iedTypelist({ scd_id: 512000138 });
+  const typeRes = await iedTypelist({ scd_id: 568000158 });
   iedTypeData.value = typeRes.data ? [...allIedType, ...typeRes.data] : [];
 };
 const iedName = ref([]);
@@ -254,7 +254,7 @@ const searchInput = (value) => {
 const count = ref(0);
 const iedNameData = async () => {
   //IED编码或名称
-  const iedRes = await scdIedRelation({ scd_id: 512000138 });
+  const iedRes = await scdIedRelation({ scd_id: 568000158 });
   iedName.value = iedRes.data;
   count.value = iedRes.count;
 };
@@ -282,7 +282,7 @@ const changeLevel = async (value, mainValue) => {
     open.value = true;
     dialogData.value = iedName.value;
   } else if (value) {
-    const mainClick = { scd_id: 512000138, area_id: value };
+    const mainClick = { scd_id: 568000158, area_id: value };
     const forms = mainValue ? mainClick : queryParams.value;
     open.value = true;
     dialogData.value = [];

+ 98 - 13
src/pages/netStructPicture/components/soureFile.vue

@@ -1,11 +1,15 @@
 <!-- 源文件 -->
 <template>
   <div class="source" v-loading="loading">
-    <div class="cont" v-if="text">{{ text }}</div>
+    <el-input
+    v-model="text"
+    :rows="2"
+    type="textarea"
+  />
   </div>
 </template>
 <script setup>
-import { onMounted, watch, ref,inject  } from "vue";
+import { onMounted, watch, ref, inject } from "vue";
 import { getSourcexml } from "@/api/iedNetwork";
 const props = defineProps({
   checkData: {
@@ -15,21 +19,99 @@ const props = defineProps({
 });
 const loading = ref(true);
 const scdIdValue = inject("scdId");
-const text = ref('');
-const getHtml= async () => {
+const text = ref("");
+
+const setPrefix = function (prefixIndex) {
+  let result = "";
+  let span = "    "; //缩进长度
+  let output = [];
+  for (let i = 0; i < prefixIndex; ++i) {
+    output.push(span);
+  }
+  result = output.join("");
+  return result;
+};
+const formateXml = function (xmlStr) {
+  let text = xmlStr;
+  //使用replace去空格
+  text =
+    "\n" +
+    text
+      .replace(/(<\w+)(\s.*?>)/g, ($0, name, props) => {
+        return name + " " + props.replace(/\s+(\w+=)/g, " $1");
+      })
+      .replace(/>\s*?</g, ">\n<");
+
+  //处理注释,对注释进行编码
+  text = text
+    .replace(/\n/g, "\r")
+    .replace(/<!--(.+?)-->/g, function ($0, text) {
+      return "<!--" + escape(text) + "-->";
+    })
+    .replace(/\r/g, "\n");
+
+  //调整格式  以压栈方式递归调整缩进
+  let rgx =
+    /\n(<(([^\?]).+?)(?:\s|\s*?>|\s*?(\/)>)(?:.*?(?:(?:(\/)>)|(?:<(\/)\2>)))?)/gm;
+  let nodeStack = [];
+  let output = text.replace(
+    rgx,
+    ($0, all, name, isBegin, isCloseFull1, isCloseFull2, isFull1, isFull2) => {
+      let isClosed =
+        isCloseFull1 == "/" ||
+        isCloseFull2 == "/" ||
+        isFull1 == "/" ||
+        isFull2 == "/";
+      let prefix = "";
+      if (isBegin == "!") {
+        //!开头
+        prefix = setPrefix(nodeStack.length);
+      } else {
+        if (isBegin != "/") {
+          ///开头
+          prefix = setPrefix(nodeStack.length);
+          if (!isClosed) {
+            //非关闭标签
+            nodeStack.push(name);
+          }
+        } else {
+          nodeStack.pop(); //弹栈
+          prefix = setPrefix(nodeStack.length);
+        }
+      }
+      return "\n" + prefix + all;
+    }
+  );
+  let outputText = output.substring(1);
+
+  //还原注释内容
+  outputText = outputText
+    .replace(/\n/g, "\r")
+    .replace(/(\s*)<!--(.+?)-->/g, function ($0, prefix, text) {
+      if (prefix.charAt(0) == "\r") prefix = prefix.substring(1);
+      // 解码
+      text = window.unescape(text).replace(/\r/g, "\n");
+      let ret = "\n" + prefix + "<!--" + text.replace(/^\s*/gm, prefix) + "-->";
+      return ret;
+    });
+  return outputText;
+
+};
+const getHtml = async () => {
   const res = await getSourcexml({
     scd_id: scdIdValue,
     ied_name: props.checkData.ied_name,
-  })
-  text.value = res.data
-  if(res){
+  });
+  text.value = formateXml(res.data);
+  if (res) {
     loading.value = false;
   }
-}
+};
 watch(
   () => props.checkData,
   (newValue) => {
-    text.value = '';
+    text.value = "";
+    loading.value = true;
     if (newValue != null) {
       getHtml();
     }
@@ -40,12 +122,15 @@ onMounted(() => {
 });
 </script>
 <style scoped lang="scss">
-.source{
-    margin: 12px;
-    border-radius: 2px;
+.source {
+  margin: 12px;
+  border-radius: 2px;
+}
+:deep(.el-textarea__inner){
+  height: 69vh;
 }
 .cont {
   border: 1px solid #d3d1d1;
-  padding:10px;
+  padding: 10px;
 }
 </style>