ScdNow.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446
  1. <template>
  2. <div>
  3. <div class="main" v-if="detailData">
  4. <div class="scdBox">
  5. <div class="navs">
  6. <img src="../../../assets/image/squer_scd.png" alt="" />
  7. <p>SCD版本</p>
  8. </div>
  9. <div>
  10. <div id="oldScd">
  11. <img
  12. src="../../../assets/icon/cilce_gray.png"
  13. alt=""
  14. class="circel-png"
  15. />
  16. <span v-if="scdVer && scdVer[1] != ''">{{ scdVer[1] }}</span>
  17. <span v-else>无</span>
  18. </div>
  19. <img :src="jiantouPng" alt="" class="jiantou" />
  20. <div id="newScd">
  21. <img
  22. src="../../../assets/icon/clice_blue.png"
  23. alt=""
  24. class="circel-png"
  25. />
  26. <span v-if="scdVer">{{ scdVer[0] }}</span>
  27. </div>
  28. </div>
  29. </div>
  30. <div class="crcBox">
  31. <div class="navs">
  32. <img
  33. src="../../../assets/image/squer_crc.png"
  34. alt=""
  35. class="circel-png"
  36. />
  37. <p>CRC</p>
  38. </div>
  39. <div>
  40. <div id="oldCrc">
  41. <img
  42. src="../../../assets/icon/cilce_gray.png"
  43. alt=""
  44. class="circel-png"
  45. />
  46. <span v-if="crcVer && crcVer[1] != ''">{{ crcVer[1] }}</span>
  47. <span v-else>无</span>
  48. </div>
  49. <img :src="jiantouPng" alt="" class="jiantou" />
  50. <div id="newCrc">
  51. <img src="../../../assets/icon/clice_blue.png" alt="" />
  52. <span v-if="crcVer">{{ crcVer[0] }}</span>
  53. </div>
  54. </div>
  55. </div>
  56. <div class="iedBox">
  57. <div id="oldIed">
  58. <img src="../../../assets/image/squer_ied.png" alt="" />
  59. <p>IED</p>
  60. </div>
  61. <div id="newIed" v-if="iedVer">
  62. <p id="addId" @click="lookAdd(iedVer.i.list)">
  63. <img :src="newlyPng" alt="" class="icons" />
  64. <span style="color: #134bea">新增({{ iedVer.i.list.length }})</span>
  65. </p>
  66. <p id="editId" @click="lookEdit(iedVer.u.list)">
  67. <img :src="modifyPng" alt="" class="icons" />
  68. <span style="color: #ffcb11">修改({{ iedVer.u.list.length }})</span>
  69. </p>
  70. <p id="delId" @click="lookDel(iedVer.d.list)">
  71. <img :src="delPng" alt="" class="icons" />
  72. <span style="color: #e50505">删除({{ iedVer.d.list.length }})</span>
  73. </p>
  74. </div>
  75. </div>
  76. </div>
  77. <div v-else-if="clickRow" class="no-data">当前两个SCD文件没有差异!</div>
  78. <div v-else-if="!clickRow" class="no-data">
  79. 请选择比对记录或创建新的比对
  80. </div>
  81. <dialog-index
  82. :openBig="openBig"
  83. @done="done"
  84. :checkDialogData="checkDialogData"
  85. :iedRelationData="iedRelationData"
  86. :scdView="scdView"
  87. :delScdId="delScdId"
  88. ></dialog-index>
  89. <scl-update
  90. :openScl="openScl"
  91. @doneScl="doneScl"
  92. :checkDialogData="checkDialogData"
  93. :iedRelationData="iedRelationData"
  94. :clickRowData="clickRowData"
  95. :recordDelIedVer="recordDelIedVer"
  96. ></scl-update>
  97. <div id="wrapperscd"></div>
  98. </div>
  99. </template>
  100. <script setup>
  101. import {
  102. ref,
  103. onMounted,
  104. toRefs,
  105. watch,
  106. onBeforeUnmount,
  107. defineEmits,
  108. } from "vue";
  109. import LeaderLine from "../../../../public/leader-line.min.js";
  110. import dialogIndex from "./dialogIndex.vue";
  111. import SclUpdate from "./SclUpdate.vue";
  112. import jiantouPng from "@/assets/image/scdcheck/jiantou.png";
  113. import modifyPng from "@/assets/image/scdcheck/modify.png";
  114. import newlyPng from "@/assets/image/scdcheck/newly.png";
  115. import delPng from "@/assets/image/scdcheck/del.png";
  116. import { useRoute } from "vue-router";
  117. import { scdIedRelation } from "@/api/iedNetwork";
  118. const props = defineProps({
  119. scdipadMini: {
  120. type: Array,
  121. default: () => [],
  122. },
  123. clickViewData: {
  124. type: Object,
  125. default: () => {},
  126. },
  127. });
  128. let lineList = ref([]);
  129. let lookType = ref(0);
  130. const route = useRoute();
  131. const emit = defineEmits(["nowBack"]);
  132. const openBig = ref(false);
  133. const lineWrite = () => {
  134. let oldIed = document.getElementById("oldIed");
  135. let newIed = document.getElementById("newIed");
  136. let addId = document.getElementById("addId");
  137. let editId = document.getElementById("editId");
  138. let delId = document.getElementById("delId");
  139. LeaderLine.positionByWindowResize = false;
  140. lineList.value.push(
  141. new LeaderLine(oldIed, addId, {
  142. color: "#7484AB", //连接线颜色
  143. size: 2, //连接线宽度
  144. path: "grid", //连接线样式
  145. startSocket: "bottom", //开始链接元素位置
  146. endSocket: "left", //结束链接元素位置
  147. endPlug: "disc", //结束箭头
  148. endPlugSize: 2, //结束箭头size
  149. })
  150. );
  151. lineList.value.push(
  152. new LeaderLine(oldIed, editId, {
  153. color: "#7484AB", //连接线颜色
  154. size: 2, //连接线宽度
  155. path: "grid", //连接线样式
  156. startSocket: "bottom", //开始链接元素位置
  157. endSocket: "left", //结束链接元素位置
  158. endPlug: "disc", //结束箭头
  159. endPlugSize: 2, //结束箭头size
  160. })
  161. );
  162. lineList.value.push(
  163. new LeaderLine(oldIed, delId, {
  164. color: "#7484AB", //连接线颜色
  165. size: 2, //连接线宽度
  166. path: "grid", //连接线样式
  167. startSocket: "bottom", //开始链接元素位置
  168. endSocket: "left", //结束链接元素位置
  169. endPlug: "disc", //结束箭头
  170. endPlugSize: 2, //结束箭头size
  171. })
  172. );
  173. hiddenLine2();
  174. };
  175. const clickRow = ref(false);
  176. const clickRowData = ref({}); //对比列表点击的数据
  177. watch(
  178. () => props.clickViewData,
  179. (newValue) => {
  180. iedVer.value = {};
  181. clickRowData.value = {};
  182. recordDelIedVer.value = null;
  183. if (newValue) {
  184. clickRowData.value = newValue;
  185. clickRow.value = true;
  186. detailData.value = null;
  187. lineList.value = [];
  188. const elmWrapper = document.getElementById("wrapperscd");
  189. if (elmWrapper) {
  190. elmWrapper.querySelectorAll(".leader-line").forEach((node) => {
  191. node.remove();
  192. });
  193. }
  194. }
  195. }
  196. );
  197. const detailData = ref(null);
  198. const scdVer = ref(null);
  199. const crcVer = ref(null);
  200. const iedVer = ref({});
  201. const recordDelIedVer = ref(null); //把删除的弹窗左侧列表记录传给点击修改后的弹窗,用于根据name找到删除项的ied_desc
  202. watch(
  203. () => props.scdipadMini,
  204. (newValue) => {
  205. if (newValue && clickRow.value) {
  206. iedVer.value = {};
  207. detailData.value = newValue;
  208. // SCD版本数据
  209. const scdv = detailData.value.filter(
  210. (item) => item.diff_object_type == "scd.version"
  211. );
  212. scdVer.value =
  213. scdv.length && scdv[0].diff_desc ? JSON.parse(scdv[0].diff_desc) : null;
  214. // CRC版本数据
  215. const crcV = detailData.value.filter(
  216. (item) => item.diff_object_type == "scd.crc"
  217. );
  218. crcVer.value =
  219. crcV.length && crcV[0].diff_desc ? JSON.parse(crcV[0].diff_desc) : null;
  220. //IED版本数据,diff_opt中u是修改,i是新增,d是删除
  221. const iedV = detailData.value.filter(
  222. (item) => item.diff_object_type == "scd.ied"
  223. );
  224. for (let k = 0; k < iedV.length; k++) {
  225. let item = iedV[k];
  226. const key = item.diff_opt;
  227. if (iedVer.value[key] == null) {
  228. iedVer.value[key] = {
  229. list: [item],
  230. };
  231. } else {
  232. iedVer.value[key].list.push(item);
  233. }
  234. }
  235. console.log('iedVer.valu===', iedVer.value)
  236. setTimeout(() => {
  237. lineWrite();
  238. }, 50);
  239. }
  240. }
  241. );
  242. //弹窗====
  243. const checkDialogData = ref(null); //选择弹框的第一条数据
  244. const done = (emits) => {
  245. openBig.value = emits;
  246. checkDialogData.value = null;
  247. scdView.value = false;
  248. delScdId.value = "";
  249. };
  250. const iedRelationData = ref({}); //左侧所有数据
  251. const scdView = ref(false); //是否是点击Scd文件一致性校核进入的
  252. const delScdId = ref(""); //点击删除的scd_id
  253. const lookAddOrDel = async (comData, del) => {
  254. iedRelationData.value = {};
  255. checkDialogData.value = null;
  256. scdView.value = true;
  257. const iedDetail = {};
  258. for (let k = 0; k < comData.length; k++) {
  259. let item = comData[k];
  260. const key = item.ied_name;
  261. iedDetail[key] = item;
  262. }
  263. // 获取对象的所有键,并存入数组
  264. let keys = Object.keys(iedDetail);
  265. // 对键进行排序按a,b,c===
  266. keys.sort();
  267. for (let key of keys) {
  268. iedRelationData.value[key] = iedDetail[key];
  269. }
  270. if (del == "del" && clickRowData.value.target_id) {
  271. delScdId.value = clickRowData.value.target_id; //点击删除的scdid要用对比文件的
  272. } else if (del == "add") {
  273. delScdId.value = route.query.id;
  274. } else if (del == "edit") {
  275. recordDelIedVer.value = iedVer.value ? iedVer.value.d.list : null;
  276. }
  277. // 对键进行排序===
  278. // if (del != "edit") {
  279. const iedRes = await scdIedRelation({
  280. scd_id: delScdId.value,
  281. ied_name: comData[0].ied_name,
  282. reset: 1,
  283. });
  284. console.log('iedRelationData.value111111111', iedRelationData.value)
  285. checkDialogData.value = iedRes.data ? iedRes.data[comData[0].ied_name] : null;
  286. if (del != "edit") {
  287. openBig.value = true;
  288. }
  289. };
  290. const lookAdd = async (comData) => {
  291. console.log("comData=====", comData);
  292. lookAddOrDel(comData, "add");
  293. // lookType.value = 1;
  294. // emit("nowBack", lookType.value);
  295. };
  296. const lookDel = (comData) => {
  297. lookAddOrDel(comData, "del");
  298. // lookType.value = 3;
  299. // emit("nowBack", lookType.value);
  300. };
  301. const hiddenLine2 = () => {
  302. const elmWrapper = document.getElementById("wrapperscd");
  303. // 移动 line
  304. document.body.querySelectorAll("body>.leader-line").forEach((node) => {
  305. elmWrapper.appendChild(node);
  306. });
  307. elmWrapper.style.transform = "none";
  308. var rectWrapper = elmWrapper.getBoundingClientRect();
  309. elmWrapper.style.transform = `translate(${
  310. (rectWrapper.left + window.scrollY) * -1
  311. }px, ${(rectWrapper.top + window.scrollX) * -1}px)`;
  312. };
  313. watch(
  314. () => openBig.value,
  315. (newValue) => {
  316. lineList.value = [];
  317. const elmWrapper = document.getElementById("wrapperscd");
  318. if (elmWrapper) {
  319. elmWrapper.querySelectorAll(".leader-line").forEach((node) => {
  320. node.remove();
  321. });
  322. }
  323. if (!newValue) {
  324. setTimeout(() => {
  325. lineWrite(); //时间400是一定需要的,不然显示了会马上删除,暂未找到原因
  326. }, 400);
  327. }
  328. }
  329. );
  330. const openScl = ref(false);
  331. watch(()=>openScl.value,(newValue)=>{
  332. if (!newValue) {
  333. setTimeout(() => {
  334. lineWrite(); //时间400是一定需要的,不然显示了会马上删除,暂未找到原因
  335. }, 400);
  336. }
  337. })
  338. const lookEdit = (comData) => {
  339. openScl.value = true;
  340. lookAddOrDel(comData, "edit");
  341. // emit("nowBack", lookType.value);
  342. };
  343. //关闭scl修改弹窗
  344. const doneScl = () => {
  345. openScl.value = false;
  346. checkDialogData.value = null;
  347. iedRelationData.value = {};
  348. };
  349. onMounted(() => {});
  350. onBeforeUnmount(() => {
  351. // lineList.value.forEach((item) => item.remove());
  352. });
  353. </script>
  354. <style scoped lang="scss">
  355. .main {
  356. display: flex;
  357. justify-content: center;
  358. }
  359. p {
  360. margin: 0;
  361. padding: 0;
  362. font-size: 16px;
  363. }
  364. .scdBox,
  365. .crcBox,
  366. .iedBox {
  367. width: 23%;
  368. height: auto;
  369. text-align: center;
  370. /* border: 1px solid red; */
  371. }
  372. .crcBox {
  373. }
  374. .iedBox {
  375. position: relative;
  376. }
  377. #newIed {
  378. position: absolute;
  379. right: -50px;
  380. margin-top: 24px;
  381. span {
  382. font-size: 16px;
  383. }
  384. }
  385. #addId,
  386. #editId,
  387. #delId {
  388. display: flex;
  389. justify-content: center;
  390. align-items: center;
  391. width: 112px;
  392. height: 40px;
  393. border: 2px dashed #255ce7;
  394. background-color: rgb(239, 243, 255);
  395. border-radius: 2px;
  396. margin-bottom: 20px;
  397. cursor: pointer;
  398. }
  399. #editId {
  400. border: 2px dashed #ffcb11;
  401. background-color: rgb(255, 251, 242);
  402. }
  403. #delId {
  404. border: 2px dashed #e50505;
  405. background-color: rgb(255, 236, 236);
  406. }
  407. .jiantou {
  408. width: 10px;
  409. height: 42px;
  410. margin: 4px 0;
  411. }
  412. #oldScd,
  413. #oldCrc {
  414. color: #7484ab;
  415. font-size: 16px;
  416. }
  417. #newScd,
  418. #newCrc {
  419. font-size: 16px;
  420. }
  421. .navs {
  422. color: #1a2447;
  423. font-size: 16px;
  424. margin-bottom: 24px;
  425. }
  426. .icons {
  427. width: 20px;
  428. height: 20px;
  429. margin-right: 4px;
  430. }
  431. .circel-png {
  432. margin-right: 4px;
  433. }
  434. .no-data {
  435. text-align: center;
  436. margin-top: 40px;
  437. }
  438. </style>