basicInfo.vue 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873
  1. <template>
  2. <div id="treedom4" v-loading="loading">
  3. <div style="position: relative">
  4. <div class="nav" id="topLine">
  5. <div
  6. class="nav-cont"
  7. v-for="(item, index) in navList"
  8. :key="index"
  9. @click="clickNav(item)"
  10. >
  11. <img :src="cylinder" alt="" class="nav-img" />
  12. <div>{{ item.attr_name }}</div>
  13. <div class="describe-text">{{ `(${item.attr_desc})` }}</div>
  14. </div>
  15. </div>
  16. </div>
  17. <div class="wrapper">
  18. <div class="grid">
  19. <!-- 左侧 -->
  20. <div
  21. class="col fluid"
  22. :class="{ transp: mainTitle && mainTitle.length < 2 }"
  23. style="margin-left: 20px"
  24. id="leftLine"
  25. >
  26. <div v-if="mainTitle && mainTitle.length > 1">
  27. <div class="title">
  28. {{ mainTitle[1].attr_name
  29. }}<span v-if="mainTitle[0].attr_desc">{{
  30. `(${mainTitle[1].attr_desc})`
  31. }}</span>
  32. </div>
  33. <div class="attr-desc" v-if="moLeft">
  34. <div>
  35. <span class="decrip">MAC-Address:</span>
  36. <span class="decrip-item" v-if="!moLeft.address">无</span>
  37. <span v-else>{{ moLeft.address }}</span>
  38. </div>
  39. <div>
  40. <span class="decrip">VLAN-PRIORITY:</span>
  41. <span class="decrip-item" v-if="!moLeft.priority">无</span>
  42. <span v-else>{{ moLeft.priority }}</span>
  43. </div>
  44. <div>
  45. <span class="decrip">APPID:</span>
  46. <span class="decrip-item" v-if="!moLeft.APPID">无</span>
  47. <span v-else>{{ moLeft.APPID }}</span>
  48. </div>
  49. <div>
  50. <span class="decrip">VLAN-ID:</span>
  51. <span class="decrip-item" v-if="!moLeft.vlanId">无</span>
  52. <span v-else>{{ moLeft.vlanId }}</span>
  53. </div>
  54. </div>
  55. <div v-if="mainList" class="circle-all">
  56. <span
  57. v-for="(item, index) in mainTitle[1].list"
  58. :key="index"
  59. class="circel"
  60. :class="{ 'circel active-circel': index == activeCircel }"
  61. @click="clickCircel(item, index, 'moLeft')"
  62. ><span v-if="item.address_json != ''">{{
  63. index + 1
  64. }}</span></span
  65. >
  66. </div>
  67. </div>
  68. <div class="child-item" v-if="mainTitle && mainTitle.length > 1">
  69. <div class="ldevice">LDevice</div>
  70. <div
  71. v-for="(item, index) in mainTitle[1].childList[0]"
  72. :key="index"
  73. @click="clickMain(item)"
  74. class="ldevice-cont"
  75. >
  76. <img :src="legislation" alt="" />
  77. <div class="img-title">{{ item.attr_inst }}</div>
  78. <div class="decrip-child">{{ item.attr_desc }}</div>
  79. </div>
  80. </div>
  81. </div>
  82. <!-- 中间 -->
  83. <div class="col main-middle" id="middleLine">
  84. <div v-if="attrsData">
  85. <el-tooltip
  86. class="box-item"
  87. effect="light"
  88. :content="attrsData.desc"
  89. placement="top-start"
  90. >
  91. <div class="text-overflow ied_struct_desc">
  92. {{ attrsData.desc }}
  93. </div>
  94. </el-tooltip>
  95. <el-tooltip
  96. class="box-item"
  97. effect="light"
  98. :content="attrsData.type"
  99. placement="top-start"
  100. >
  101. <div class="text-overflow ied_struct_type">
  102. {{ attrsData.type }}
  103. </div>
  104. </el-tooltip>
  105. <el-tooltip
  106. class="box-item"
  107. effect="light"
  108. :content="attrsData.manufacturer"
  109. placement="top-start"
  110. >
  111. <div class="text-overflow ied_struct_manufacturer">
  112. {{ attrsData.manufacturer }}
  113. </div>
  114. </el-tooltip>
  115. <el-tooltip
  116. class="box-item"
  117. effect="light"
  118. :content="attrsData.name"
  119. placement="top-start"
  120. >
  121. <div
  122. class="text-overflow ied_struct_manufacturer ied_struct_manufacturer1"
  123. >
  124. {{ attrsData.name }}
  125. </div>
  126. </el-tooltip>
  127. </div>
  128. </div>
  129. <!-- 右侧 -->
  130. <div
  131. class="col fluid"
  132. style="margin-right: 20px"
  133. :class="{ transp: mainTitle && mainTitle.length < 3 }"
  134. id="rightLine"
  135. >
  136. <div v-if="mainTitle && mainTitle.length > 2">
  137. <div class="title">
  138. {{ mainTitle[2].attr_name
  139. }}<span v-if="mainTitle[0].attr_desc">{{
  140. `(${mainTitle[2].attr_desc})`
  141. }}</span>
  142. </div>
  143. <div class="attr-desc" v-if="moRight">
  144. <div>
  145. <span class="decrip">MAC-Address:</span>
  146. <span class="decrip-item" v-if="!moRight.address">无</span>
  147. <span v-else>{{ moRight.address }}</span>
  148. </div>
  149. <div>
  150. <span class="decrip">VLAN-PRIORITY:</span>
  151. <span class="decrip-item" v-if="!moRight.priority">无</span>
  152. <span v-else>{{ moRight.priority }}</span>
  153. </div>
  154. <div>
  155. <span class="decrip">APPID:</span>
  156. <span class="decrip-item" v-if="!moRight.APPID">无</span>
  157. <span v-else>{{ moRight.APPID }}</span>
  158. </div>
  159. <div>
  160. <span class="decrip">VLAN-ID:</span>
  161. <span class="decrip-item" v-if="!moRight.vlanId">无</span>
  162. <span v-else>{{ moRight.vlanId }}</span>
  163. </div>
  164. </div>
  165. <div v-if="mainList" class="circle-all">
  166. <span
  167. v-for="(item, index) in mainTitle[2].list"
  168. :key="index"
  169. class="circel"
  170. :class="{ 'circel active-circel': index == activeCircel }"
  171. @click="clickCircel(item, index, 'moRight')"
  172. ><span v-if="item.address_json != ''">{{
  173. index + 1
  174. }}</span></span
  175. >
  176. </div>
  177. </div>
  178. <div class="child-item" v-if="mainTitle && mainTitle.length > 2">
  179. <div class="ldevice">LDevice</div>
  180. <div
  181. v-for="(item, index) in mainTitle[2].childList[0]"
  182. :key="index"
  183. @click="clickMain(item)"
  184. class="ldevice-cont"
  185. >
  186. <img :src="legislation" alt="" />
  187. <div class="img-title">{{ item.attr_inst }}</div>
  188. <div class="decrip-child">{{ item.attr_desc }}</div>
  189. </div>
  190. </div>
  191. </div>
  192. </div>
  193. <div
  194. class="main-bottom"
  195. id="bottomLine"
  196. :class="{ transp: mainTitle && mainTitle.length < 1 }"
  197. >
  198. <div v-if="mainTitle && mainTitle.length > 0">
  199. <div class="title">
  200. {{ mainTitle[0].attr_name
  201. }}<span v-if="mainTitle[0].attr_desc">{{
  202. `(${mainTitle[0].attr_desc})`
  203. }}</span>
  204. </div>
  205. <div class="attr-desc" v-if="moBottom">
  206. <div>
  207. <span class="decrip">MAC-Address:</span>
  208. <span class="decrip-item" v-if="!moBottom.address">无</span>
  209. <span v-else>{{ moBottom.address }}</span>
  210. </div>
  211. <div>
  212. <span class="decrip">VLAN-PRIORITY:</span>
  213. <span class="decrip-item" v-if="!moBottom.priority">无</span>
  214. <span v-else>{{ moBottom.priority }}</span>
  215. </div>
  216. <div>
  217. <span class="decrip">APPID:</span>
  218. <span class="decrip-item" v-if="!moBottom.APPID">无</span>
  219. <span v-else>{{ moBottom.APPID }}</span>
  220. </div>
  221. <div>
  222. <span class="decrip">VLAN-ID:</span>
  223. <span class="decrip-item" v-if="!moBottom.vlanId">无</span>
  224. <span v-else>{{ moBottom.vlanId }}</span>
  225. </div>
  226. </div>
  227. <div v-if="mainList" class="circle-all">
  228. <span
  229. v-for="(item, index) in mainTitle[0].list"
  230. :key="index"
  231. class="circel"
  232. :class="{ 'circel active-circel': index == activeCircel }"
  233. @click="clickCircel(item, index, 'moBottom')"
  234. ><span v-if="item.address_json != ''">{{ index + 1 }}</span></span
  235. >
  236. </div>
  237. </div>
  238. <div class="child-item" v-if="mainTitle && mainTitle.length > 0">
  239. <div class="ldevice">LDevice</div>
  240. <div
  241. class="ldevice-cont"
  242. v-for="(item, index) in mainTitle[0].childList[0]"
  243. :key="index"
  244. @click="clickMain(item)"
  245. >
  246. <img :src="legislation" alt="" />
  247. <div class="img-title">{{ item.attr_inst }}</div>
  248. <div class="decrip-child">{{ item.attr_desc }}</div>
  249. </div>
  250. </div>
  251. </div>
  252. </div>
  253. <div id="wrappers"></div>
  254. <!-- 点击头部的弹框 -->
  255. <el-dialog
  256. @close="cancelClickNav"
  257. v-model="isOpennav"
  258. append-to-body
  259. draggable
  260. style="height: 550px"
  261. >
  262. <template #header>
  263. <div class="my-header">
  264. <div class="dialog-nav-title">
  265. {{ `(${clickNavTitle.attr_desc}) — FCDA列表` }}
  266. </div>
  267. </div>
  268. </template>
  269. <el-table
  270. :data="clickNavData"
  271. style="width: 100%"
  272. stripe
  273. height="450"
  274. :cell-style="{ color: '#000' }"
  275. >
  276. <el-table-column prop="attr_ld_inst" label="ldInst" />
  277. <el-table-column prop="attr_prefix" label="prefix" />
  278. <el-table-column prop="attr_ln_class" label="lnClass" />
  279. <el-table-column prop="attr_ln_inst" label="lnInst" />
  280. <el-table-column prop="attr_do_name" label="doName" />
  281. <el-table-column prop="da_datatype" label="attr_da_name" width="180" />
  282. <el-table-column prop="attr_fc" label="fc" />
  283. </el-table>
  284. </el-dialog>
  285. <!-- 点击方框的弹窗 -->
  286. <el-dialog
  287. @close="cancelClickMain"
  288. v-model="isOpenMain"
  289. append-to-body
  290. draggable
  291. style="height: 550px"
  292. >
  293. <template #header>
  294. <div class="my-header">
  295. <div class="dialog-nav-title">
  296. {{
  297. `${clickMainTitle.attr_inst}${clickMainTitle.attr_desc} — LN/LN0节点列表`
  298. }}
  299. </div>
  300. </div>
  301. </template>
  302. <el-table
  303. :data="clickMainData"
  304. style="width: 100%"
  305. stripe
  306. height="450"
  307. :cell-style="{ color: '#000' }"
  308. >
  309. <el-table-column type="index" label="序号" width="80" />
  310. <el-table-column prop="attr_inst" label="inst" />
  311. <el-table-column prop="attr_ln_class" label="lnClass" />
  312. <el-table-column prop="attr_ln_type" label="lnType" />
  313. <el-table-column prop="attr_desc" label="desc" />
  314. </el-table>
  315. </el-dialog>
  316. </div>
  317. </template>
  318. <script setup>
  319. import { defineProps, onMounted, ref, inject, nextTick, watch } from "vue";
  320. import legislation from "@/assets/image/instruct/legislation.png";
  321. import cylinder from "@/assets/image/instruct/cylinder.png";
  322. import {
  323. getNodeList,
  324. getNetworkInfo,
  325. getLdeviceList,
  326. nodeList,
  327. getNodeAttrs,
  328. } from "@/api/iedNetwork";
  329. import LeaderLine from "../../../../public/leader-line.min.js";
  330. import AnimEvent from "../../../../public/anim-event.min.js";
  331. import { CloseBold } from "@element-plus/icons-vue";
  332. const props = defineProps({
  333. checkData: {
  334. type: Object,
  335. default: () => {},
  336. },
  337. isOpen: {
  338. type: Boolean,
  339. default: false,
  340. },
  341. });
  342. const scdIdValue = inject("scdId");
  343. const navList = ref(null); //最头部的数据
  344. const mainTitle = ref(null); //每个方框的标题
  345. const moBottom = ref(null); //底部方框所展示的MAC-Address等desc
  346. const moLeft = ref(null); //左侧方框所展示的MAC-Address等desc
  347. const moRight = ref(null); //右侧方框所展示的MAC-Address等desc
  348. const activeCircel = ref(0); //点击数字圆圈的样式
  349. const isOpennav = ref(false); //头部点击弹窗显示
  350. const clickNavTitle = ref(null); //头部点击弹窗数据
  351. const clickNavData = ref(null); //头部点击弹窗数据
  352. const isOpenMain = ref(false); //点击方框
  353. const clickMainTitle = ref(null);
  354. const clickMainData = ref(null);
  355. const loading = ref(true);
  356. const getNav = async () => {
  357. const navRes = await getNodeList({
  358. scd_id: scdIdValue,
  359. pagesize: 10000,
  360. ied_name: props.checkData.ied_name,
  361. name: "DataSet",
  362. });
  363. navList.value = navRes.data;
  364. };
  365. const getMainTitle = async () => {
  366. const mainRes = await getNodeList({
  367. scd_id: scdIdValue,
  368. pagesize: 10000,
  369. ied_name: props.checkData.ied_name,
  370. name: "AccessPoint",
  371. });
  372. //得到每个方框中LDevice中的内容
  373. Promise.all(
  374. mainRes.data.map(async (item) => {
  375. item.childList = [];
  376. const res = await getLdeviceList({
  377. accessPointId: item.node_id,
  378. scd_id: scdIdValue,
  379. });
  380. item.childList.push(res.data);
  381. })
  382. ).then(() => {
  383. //等待执行完上面的api
  384. loading.value = false;
  385. mainTitle.value = mainRes.data;
  386. getMainList();
  387. });
  388. };
  389. const mainList = ref({});
  390. const titleName = ref([]);
  391. //几个方框的数据
  392. const getMainList = async () => {
  393. mainList.value = {};
  394. titleName.value = [];
  395. const newarr = [];
  396. const infoRes = await getNetworkInfo({
  397. scd_id: scdIdValue,
  398. ied_name: props.checkData.ied_name,
  399. });
  400. //处理分类数据
  401. for (let i = 0; i < infoRes.data.length; i++) {
  402. if (infoRes.data[i].address_json != "") {
  403. let newData = infoRes.data[i].address_json
  404. .replace("MAC-Address", "address")
  405. .replace("VLAN-PRIORITY", "priority")
  406. .replace("VLAN-ID", "vlanId");
  407. infoRes.data[i].address_json = JSON.parse(newData);
  408. }
  409. let item = infoRes.data[i];
  410. const key = item.ap_name;
  411. newarr.push(key);
  412. if (mainList.value[key] == null) {
  413. mainList.value[key] = {
  414. name: key,
  415. list: [item],
  416. };
  417. } else {
  418. mainList.value[key].list.push(item);
  419. }
  420. }
  421. //处理表头下方段落的描述
  422. if (mainList.value && mainTitle.value) {
  423. mainTitle.value.forEach((key) => {
  424. key.list = [];
  425. Object.keys(mainList.value).forEach((item) => {
  426. if (item == key.attr_name) {
  427. key.list = mainList.value[item].list;
  428. }
  429. });
  430. });
  431. //分布默认的左侧右侧和下侧的数据
  432. for (let i = 0; i < mainTitle.value.length; i++) {
  433. if (
  434. mainTitle.value[i].list.length > 0 &&
  435. mainTitle.value[i].list[0].address_json != ""
  436. ) {
  437. const targetElement = mainTitle.value[i];
  438. switch (i) {
  439. case 0:
  440. moBottom.value = targetElement.list[0].address_json;
  441. break;
  442. case 1:
  443. moLeft.value = targetElement.list[0].address_json;
  444. break;
  445. case 2:
  446. moRight.value = targetElement.list[0].address_json;
  447. break;
  448. }
  449. }
  450. }
  451. }
  452. };
  453. //弹窗打开后使得线条在指定区域中
  454. const hiddenLine2 = () => {
  455. const elmWrapper = document.getElementById("wrappers");
  456. // 移动 line
  457. document.body.querySelectorAll("body .leader-line").forEach((node) => {
  458. elmWrapper.appendChild(node);
  459. });
  460. elmWrapper.style.transform = "none";
  461. var rectWrapper = elmWrapper.getBoundingClientRect();
  462. elmWrapper.style.transform = `translate(${
  463. (rectWrapper.left + window.scrollY) * -1
  464. }px, ${(rectWrapper.top + window.scrollX) * -1}px)`;
  465. };
  466. const leaderLines = ref([]); //控制线条显示
  467. //滚动时重定位线条
  468. const newPositionLine2 = () => {
  469. document.getElementById("treedom4").addEventListener(
  470. "scroll",
  471. AnimEvent.add(() => {
  472. leaderLines.value.forEach((line) => {
  473. if (line) {
  474. hiddenLine2();
  475. line.position();
  476. line.positionByWindowResize = false;
  477. }
  478. });
  479. //中间展示图片的
  480. }),
  481. false
  482. );
  483. };
  484. const getLine = () => {
  485. const topDom = document.getElementById("topLine");
  486. const leftDom = document.getElementById("leftLine");
  487. const rightDom = document.getElementById("rightLine");
  488. const bottomDom = document.getElementById("bottomLine");
  489. const middlDom = document.getElementById("middleLine");
  490. let lineStyle = {
  491. color: "#134BEA",
  492. size: 2,
  493. path: "straight",
  494. endPlug: "disc",
  495. startPlug: "disc",
  496. middleLabel: LeaderLine.captionLabel("AccessPoint", {
  497. fontSize: 10,
  498. color: "#7F8EB2",
  499. }),
  500. };
  501. let lineStyleTop = {
  502. ...lineStyle,
  503. middleLabel: LeaderLine.captionLabel({
  504. text: "DataSet",
  505. fontSize: 10,
  506. color: "#7F8EB2",
  507. }),
  508. };
  509. let lineStyleright = {
  510. ...lineStyle,
  511. middleLabel: LeaderLine.captionLabel("AccessPoint", {
  512. fontSize: 10,
  513. color: "#7F8EB2",
  514. }),
  515. };
  516. let lineStylebottom = {
  517. ...lineStyle,
  518. middleLabel: LeaderLine.captionLabel({
  519. text: "AccessPoint",
  520. fontSize: 10,
  521. color: "#7F8EB2",
  522. }),
  523. };
  524. leaderLines.value.push(new LeaderLine(middlDom, topDom, lineStyleTop)); //上面和中间连线
  525. if (mainTitle.value && mainTitle.value.length > 0) {
  526. leaderLines.value.push(
  527. new LeaderLine(middlDom, bottomDom, lineStylebottom)
  528. );
  529. }
  530. if (mainTitle.value && mainTitle.value.length > 2) {
  531. leaderLines.value.push(new LeaderLine(middlDom, rightDom, lineStyleright));
  532. }
  533. if (mainTitle.value && mainTitle.value.length > 1) {
  534. leaderLines.value.push(new LeaderLine(leftDom, middlDom, lineStyle));
  535. }
  536. newPositionLine2();
  537. hiddenLine2();
  538. };
  539. //点击数字
  540. const clickCircel = (item, index, type) => {
  541. activeCircel.value = index;
  542. let data = JSON.stringify(item.address_json);
  543. let newData = data
  544. .replace("MAC-Address", "address")
  545. .replace("VLAN-PRIORITY", "priority")
  546. .replace("VLAN-ID", "vlanId");
  547. if (type == "moBottom") {
  548. moBottom.value = JSON.parse(newData);
  549. } else if (type == "moRight") {
  550. moRight.value = JSON.parse(newData);
  551. } else {
  552. moLeft.value = JSON.parse(newData);
  553. }
  554. };
  555. const attrsData = ref(null);
  556. const getNode = async () => {
  557. const attrRes = await getNodeAttrs({
  558. scd_id: scdIdValue,
  559. ied_name: props.checkData.ied_name,
  560. node_id: props.checkData.node_id,
  561. });
  562. attrsData.value = attrRes.data;
  563. };
  564. onMounted(() => {
  565. getNav();
  566. getMainTitle();
  567. getNode();
  568. nextTick(() => {
  569. setTimeout(() => {
  570. getLine();
  571. }, 500);
  572. });
  573. });
  574. watch(
  575. () => props.isOpen,
  576. (newValue) => {
  577. nextTick(() => {
  578. if (!newValue) {
  579. removeLine2();
  580. leaderLines.value = [];
  581. loading.value = false;
  582. } else {
  583. setTimeout(() => {
  584. getLine();
  585. }, 500);
  586. }
  587. });
  588. }
  589. );
  590. watch(
  591. () => props.checkData,
  592. (newValue) => {
  593. removeLine2();
  594. if (newValue && leaderLines.value.length > 0) {
  595. leaderLines.value = [];
  596. }
  597. if (newValue) {
  598. activeCircel.value = 0;
  599. isOpenMain.value = false;
  600. isOpennav.value = false;
  601. getNav();
  602. loading.value = true;
  603. getMainTitle();
  604. getNode();
  605. nextTick(() => {
  606. setTimeout(() => {
  607. getLine();
  608. }, 500);
  609. });
  610. }
  611. }
  612. );
  613. const removeLine2 = () => {
  614. const elmWrapper = document.getElementById("wrappers");
  615. document.body.querySelectorAll("body .leader-line").forEach((node) => {
  616. elmWrapper.removeChild(node);
  617. });
  618. };
  619. //点击头部展示的弹框
  620. const clickNav = async (item) => {
  621. clickNavTitle.value = item;
  622. isOpennav.value = true;
  623. const navRes = await nodeList({
  624. scd_id: scdIdValue,
  625. parent_node_id: item.node_id,
  626. pagesize: 10000,
  627. name: "FCDA",
  628. });
  629. clickNavData.value = navRes.data;
  630. };
  631. const cancelClickNav = () => {
  632. clickNavData.value = null;
  633. isOpennav.value = false;
  634. };
  635. const clickMain = async (item) => {
  636. clickMainTitle.value = item;
  637. isOpenMain.value = true;
  638. const navRes = await nodeList({
  639. scd_id: scdIdValue,
  640. parent_node_id: item.node_id,
  641. pagesize: 10000,
  642. name: "LN0",
  643. });
  644. const navRes2 = await nodeList({
  645. scd_id: scdIdValue,
  646. parent_node_id: item.node_id,
  647. pagesize: 10000,
  648. name: "LN",
  649. });
  650. clickMainData.value = [...navRes.data, ...navRes2.data];
  651. };
  652. const cancelClickMain = () => {
  653. clickMainData.value = null;
  654. isOpenMain.value = false;
  655. };
  656. </script>
  657. <style scoped lang="scss">
  658. #treedom4 {
  659. height: 72vh;
  660. overflow-y: auto;
  661. }
  662. .wrapper {
  663. position: relative;
  664. }
  665. .nav {
  666. height: 160px;
  667. background: #f3f5fa;
  668. overflow-y: auto;
  669. border: 2px dashed #a3ade0;
  670. display: flex;
  671. justify-content: start;
  672. flex-wrap: wrap;
  673. position: relative;
  674. margin: 16px;
  675. .nav-img {
  676. width: 30px;
  677. height: 30px;
  678. }
  679. .nav-cont {
  680. display: flex;
  681. flex-direction: column;
  682. align-items: center;
  683. cursor: pointer;
  684. margin: 8px 0;
  685. flex-basis: 14%;
  686. .describe-text {
  687. color: #134bea;
  688. }
  689. }
  690. }
  691. .main-bottom,
  692. .fluid {
  693. border: 2px dashed #a3ade0;
  694. background-color: #f7f8f8;
  695. display: flex;
  696. flex-direction: column;
  697. max-width: 36%;
  698. img {
  699. width: 40px;
  700. height: 40px;
  701. }
  702. .title {
  703. font-size: 16px;
  704. font-weight: bold;
  705. margin: 12px 0;
  706. text-align: center;
  707. }
  708. .attr-desc {
  709. margin: 10px;
  710. }
  711. .decrip {
  712. color: #7484ab;
  713. font-size: 14px;
  714. margin-right: 15px;
  715. width: 130px;
  716. display: inline-block;
  717. }
  718. .decrip-child {
  719. color: #7484ab;
  720. font-size: 14px;
  721. }
  722. .decrip-item {
  723. font-weight: bold;
  724. font-size: 14px;
  725. }
  726. .child-item {
  727. display: flex;
  728. margin: 12px;
  729. flex-wrap: wrap;
  730. border: 1px solid #5182ff;
  731. position: relative;
  732. & > div {
  733. margin: 8px;
  734. }
  735. .ldevice {
  736. position: absolute;
  737. top: -20px;
  738. left: -10px;
  739. padding: 0 4px;
  740. background: #5182ff;
  741. color: white;
  742. border-radius: 10px;
  743. }
  744. .ldevice-cont {
  745. display: flex;
  746. flex-direction: column;
  747. align-items: center;
  748. }
  749. }
  750. .img-title {
  751. color: #134bea;
  752. }
  753. }
  754. .circle-all {
  755. margin-bottom: 10px;
  756. display: flex;
  757. flex-wrap: wrap;
  758. }
  759. .circel {
  760. color: #7c58a8;
  761. width: 20px;
  762. height: 20px;
  763. margin-bottom: 5px;
  764. margin-right: 5px;
  765. border: 1px solid #606c93;
  766. border-radius: 10px;
  767. text-align: center;
  768. line-height: 20px;
  769. margin-left: 0.5rem;
  770. cursor: pointer;
  771. }
  772. .active-circel {
  773. color: #134bea;
  774. border: 1px solid #134bea;
  775. }
  776. .Image {
  777. width: 193px;
  778. height: 150px;
  779. }
  780. /* 设置网格布局相关的样式 */
  781. .grid {
  782. display: flex;
  783. flex-wrap: nowrap;
  784. justify-content: space-between;
  785. align-items: center;
  786. margin-top: 50px;
  787. }
  788. .grid > .col {
  789. box-sizing: border-box;
  790. // padding: 10px;
  791. }
  792. /* 设置fixed2样式 */
  793. .main-middle {
  794. width: 160px;
  795. height: 160px;
  796. background: #fff url("~@/assets/image/instruct/network_slices.png") no-repeat
  797. center;
  798. background-size: 160px;
  799. position: relative;
  800. font-size: 12px;
  801. .text-overflow {
  802. overflow: hidden;
  803. text-overflow: ellipsis;
  804. white-space: nowrap;
  805. display: block;
  806. cursor: pointer;
  807. }
  808. .ied_struct_manufacturer {
  809. line-height: 2rem;
  810. transform: rotate(-33deg);
  811. top: 65%;
  812. position: absolute;
  813. left: 62%;
  814. border: 0px solid #cccccc1c;
  815. font-style: italic;
  816. font-size: 1rem;
  817. width: 6rem;
  818. text-align: center;
  819. }
  820. .ied_struct_manufacturer1 {
  821. top: 54%;
  822. left: 59%;
  823. }
  824. .ied_struct_desc {
  825. line-height: 2rem;
  826. position: absolute;
  827. transform: rotate(31deg);
  828. top: 15%;
  829. left: 32%;
  830. width: 59%;
  831. word-break: break-word;
  832. color: #134bea;
  833. font-weight: bold;
  834. font-style: italic;
  835. text-align: center;
  836. }
  837. .ied_struct_type {
  838. position: absolute;
  839. transform: rotate(31deg);
  840. top: 26%;
  841. left: 17%;
  842. color: #15010152;
  843. font-size: 1rem;
  844. font-style: italic;
  845. width: 60%;
  846. line-height: 1.5rem;
  847. text-align: center;
  848. }
  849. }
  850. /* 设置fluid样式 */
  851. .fluid {
  852. flex-grow: 1;
  853. }
  854. .transp {
  855. border: none;
  856. }
  857. .main-bottom {
  858. position: absolute;
  859. left: 50%;
  860. transform: translateX(-50%);
  861. margin-top: 40px;
  862. }
  863. .dialog-nav-title {
  864. color: #09162c;
  865. font-size: 16px;
  866. }
  867. </style>