scdVisual.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450
  1. <template>
  2. <div class="main">
  3. <!-- 统计和搜索栏 -->
  4. <div class="search-nav">
  5. <el-form
  6. :model="queryParams"
  7. ref="queryRef"
  8. :inline="true"
  9. label-width="68px"
  10. >
  11. <el-form-item
  12. ><div class="nav-item">
  13. 总计 <span>{{ count }}</span> 个设备
  14. </div></el-form-item
  15. >
  16. <el-form-item label="电压等级" prop="voltage_level_id">
  17. <el-select
  18. ref="levelRef"
  19. v-model="queryParams.voltage_level_id"
  20. placeholder="请选择电压等级"
  21. clearable
  22. @change="changeLevel"
  23. >
  24. <el-option
  25. v-for="dict in voltageLevel"
  26. :key="dict.id"
  27. :label="dict.name"
  28. :value="dict.id"
  29. />
  30. </el-select>
  31. </el-form-item>
  32. <el-form-item label="间隔" prop="area_id">
  33. <el-select
  34. ref="levelRef"
  35. v-model="queryParams.area_id"
  36. placeholder="请选择间隔"
  37. @change="changeLevel"
  38. clearable
  39. >
  40. <el-option
  41. v-for="dict in areaData"
  42. :key="dict.id"
  43. :label="dict.name"
  44. :value="dict.id"
  45. />
  46. </el-select>
  47. </el-form-item>
  48. <el-form-item label="设备类型" prop="device_type_id">
  49. <el-select
  50. ref="levelRef"
  51. v-model="queryParams.device_type_id"
  52. placeholder="请选择设备类型"
  53. @change="changeLevel"
  54. clearable
  55. >
  56. <el-option
  57. v-for="dict in iedTypeData"
  58. :key="dict.code"
  59. :label="dict.name"
  60. :value="dict.code"
  61. />
  62. </el-select>
  63. </el-form-item>
  64. <el-form-item label="快捷搜索" prop="iedrela">
  65. <el-select
  66. v-model="queryParams.iedrela"
  67. placeholder="请输入IED编码或名称"
  68. multiple
  69. filterable
  70. remote
  71. reserve-keyword
  72. :remote-method="remoteMethod"
  73. :loading="loadingsearch"
  74. @clear="showIedList = false"
  75. >
  76. <template #header>
  77. <span class="search-header" v-if="searchIedList.length > 0">
  78. 为您找到 <span>{{ searchIedList.length }}</span> 个相关结果
  79. </span>
  80. </template>
  81. <el-option
  82. v-for="dict in searchIedList"
  83. :key="dict.node_id"
  84. :label="dict.desc"
  85. :value="dict.node_id"
  86. ></el-option>
  87. </el-select>
  88. <!-- <el-input
  89. ref="selectInputRef"
  90. v-model="queryParams.iedrela"
  91. placeholder="请输入IED编码或名称"
  92. :suffix-icon="Search"
  93. clearable
  94. @change="searchInput"
  95. v-else
  96. /> -->
  97. </el-form-item>
  98. </el-form>
  99. </div>
  100. <el-scrollbar height="54vh" v-loading="loading" v-if="loadDating">
  101. <div
  102. v-for="(item, index) in voltageLevel"
  103. :key="index"
  104. style="padding-right: 10px"
  105. >
  106. <el-row class="contanier" v-if="item.id != 'alls'">
  107. <el-col :span="3">
  108. <div
  109. :class="
  110. item.levelData.length > 7 ? 'file_img' : 'file_img file_lim'
  111. "
  112. >
  113. {{ item.name }}
  114. </div>
  115. </el-col>
  116. <el-col :span="20" class="ied_item">
  117. <div
  118. class="ied_item_child"
  119. v-for="(itemChild, indexChild) in item.levelData"
  120. :key="indexChild"
  121. @click="changeLevel(itemChild.id, itemChild.name)"
  122. >
  123. <el-tooltip
  124. :content="itemChild.name"
  125. effect="light"
  126. placement="top"
  127. ><div>{{ itemChild.name }}</div></el-tooltip
  128. >
  129. <img :src="scdIed" alt="" />
  130. </div>
  131. </el-col>
  132. </el-row>
  133. </div>
  134. </el-scrollbar>
  135. </div>
  136. <div class="container-none" v-if="!loading && !loadDating">
  137. <img src="../../../assets/image/create.png" alt="" />
  138. 该变电站还未签入任何SCD文件!
  139. </div>
  140. <scd-dialog-index
  141. :open="open"
  142. @done="done"
  143. :dialogData="dialogData"
  144. :checkLabel="checkLabel"
  145. ></scd-dialog-index>
  146. </template>
  147. <script setup>
  148. import {
  149. getCurrentInstance,
  150. onMounted,
  151. reactive,
  152. ref,
  153. toRefs,
  154. nextTick,
  155. provide,
  156. } from "vue";
  157. import scdIed from "@/assets/image/instruct/scdIed.png";
  158. import {
  159. iedTypelist,
  160. areaList,
  161. scdIedRelation,
  162. areaIedList,
  163. } from "@/api/iedNetwork";
  164. import { useDataStore } from "@/store/modules/golbal-data";
  165. import scdDialogIndex from "./scdDialogIndex";
  166. import { useRoute } from "vue-router";
  167. import { Search } from "@element-plus/icons-vue";
  168. const userStoreCode = useDataStore();
  169. const route = useRoute();
  170. // const scdIdValue = 1248000337;
  171. const scdIdValue = route.query.id;
  172. const loadingsearch = ref(false); //快捷搜索
  173. const data = reactive({
  174. queryParams: {
  175. scd_id: scdIdValue,
  176. },
  177. });
  178. const loading = ref(true);
  179. const loadDating = ref(false);
  180. const open = ref(false);
  181. const { queryParams } = toRefs(data);
  182. // 表单重置
  183. const reset = () => {
  184. queryParams.value = {
  185. scd_id: scdIdValue,
  186. voltage_level_id: null, //电压等级
  187. area_id: null, //间隔
  188. device_type_id: null, //装置类型
  189. };
  190. };
  191. const remoteMethod = (value) => {
  192. searchInput(value);
  193. };
  194. const areaData = ref([]); //获取间隔
  195. const allLevel = ref([]); // 获取所有电压
  196. const all = [{ name: "全部", id: "alls" }];
  197. const allIedType = [{ name: "全部", code: "alls" }];
  198. const voltageLevel = ref([{ name: "全部", id: "alls" }]); //电压等级
  199. const areaType = ref([]);
  200. const getArea = async () => {
  201. const areaRes = await areaList({ scd_id: scdIdValue });
  202. if (!areaRes.data) {
  203. voltageLevel.value = [];
  204. loading.value = false;
  205. loadDating.value = false;
  206. return;
  207. }
  208. loading.value = false;
  209. areaData.value = [...all, ...areaRes.data]; //搜索处的间隔
  210. //处理电压等级的搜索展示数据
  211. const levelData = [
  212. ...new Set(areaRes.data.map((itemlevel) => itemlevel.voltage_level)),
  213. ];
  214. if (!levelData) return;
  215. levelData.forEach((myLevelItem) => {
  216. const findData = allLevel.value.find((allItem) => {
  217. return allItem.id == myLevelItem;
  218. });
  219. if (findData) {
  220. voltageLevel.value.push(findData);
  221. }
  222. });
  223. //处理主界面的数据展示
  224. if (!voltageLevel.value) return;
  225. voltageLevel.value.forEach((item) => {
  226. if (item.id == "alls") return;
  227. item.levelData = [];
  228. const findType = areaRes.data.filter((itemType) => {
  229. return itemType.voltage_level == item.id;
  230. });
  231. if (findType) {
  232. item.levelData.push(...findType);
  233. }
  234. });
  235. loadDating.value = true;
  236. };
  237. //设备类型
  238. const iedTypeData = ref([]);
  239. const getTypelist = async () => {
  240. const typeRes = await iedTypelist({ scd_id: scdIdValue });
  241. iedTypeData.value = typeRes.data ? [...allIedType, ...typeRes.data] : [];
  242. };
  243. const iedName = ref([]);
  244. const showIedList = ref(false);
  245. //搜索ied编码或名称
  246. const searchIedList = ref([]);
  247. const selectRef = ref(null);
  248. const searchInput = (value) => {
  249. loadingsearch.value = true;
  250. setTimeout(() => {
  251. if (value && iedName.value) {
  252. loadingsearch.value = false;
  253. showIedList.value = true;
  254. searchIedList.value = Object.values(iedName.value).filter((item) => {
  255. const lowercaseValue = value.toLowerCase(); //不区分大小写
  256. const iedNameLower = item.ied_name ? item.ied_name.toLowerCase() : null;
  257. const descLower = item.desc ? item.desc.toLowerCase() : null;
  258. return (
  259. (iedNameLower !== null && iedNameLower.includes(lowercaseValue)) ||
  260. (descLower !== null && descLower.includes(lowercaseValue))
  261. );
  262. });
  263. // 选择框自动展开
  264. // nextTick(() => {
  265. // selectRef.value.toggleMenu();
  266. // });
  267. } else {
  268. showIedList.value = false;
  269. searchIedList.value = [];
  270. }
  271. }, 200);
  272. };
  273. const count = ref(0);
  274. const iedNameData = async () => {
  275. //IED编码或名称
  276. const iedRes = await scdIedRelation({ scd_id: scdIdValue });
  277. iedName.value = iedRes.data;
  278. count.value = iedRes.count;
  279. };
  280. const done = (emits) => {
  281. open.value = emits;
  282. reset();
  283. dialogData.value = [];
  284. };
  285. //选择电压
  286. const dialogData = ref([]);
  287. const levelRef = ref(null); //为了得到选中的label值
  288. const checkLabel = ref("");
  289. const changeLevel = async (value, mainValue) => {
  290. nextTick(() => {
  291. checkLabel.value = mainValue ? mainValue : levelRef.value.selectedLabel;
  292. });
  293. //如果选中的是当前选项,那么其他搜索框的内容应置为空
  294. Object.keys(queryParams.value).forEach((item) => {
  295. if (queryParams.value[item] !== value && item != "scd_id") {
  296. queryParams.value[item] = null;
  297. }
  298. });
  299. if (value == "alls") {
  300. //全部
  301. open.value = true;
  302. dialogData.value = iedName.value;
  303. } else if (value) {
  304. const mainClick = { scd_id: scdIdValue, area_id: value };
  305. const forms = mainValue ? mainClick : queryParams.value;
  306. open.value = true;
  307. dialogData.value = [];
  308. //搜索的弹框内容
  309. const searchLevel = await areaIedList(forms);
  310. if (!searchLevel.data) return;
  311. dialogData.value = Object.values(iedName.value).filter((item) => {
  312. return searchLevel.data.some((levelItem) => {
  313. return item.node_id == levelItem.ied_id;
  314. });
  315. });
  316. }
  317. };
  318. //弹窗=============
  319. provide("scdId", scdIdValue);
  320. onMounted(async () => {
  321. iedNameData();
  322. allLevel.value = await userStoreCode.GlobalCodes();
  323. getArea();
  324. getTypelist();
  325. });
  326. </script>
  327. <style scoped lang="scss">
  328. @mixin mid-center {
  329. display: flex;
  330. align-items: center;
  331. }
  332. .main {
  333. margin: 40px;
  334. }
  335. .search-nav {
  336. @include mid-center;
  337. justify-content: center;
  338. .nav-item {
  339. color: #134bea;
  340. font-size: 16px;
  341. span {
  342. color: #ffcb11;
  343. font-size: 20px;
  344. }
  345. }
  346. :deep(.el-form-item__label) {
  347. color: #1a2447;
  348. line-height: 40px;
  349. }
  350. :deep(.el-input) {
  351. height: 40px;
  352. }
  353. }
  354. .search-header {
  355. display: flex;
  356. justify-content: center;
  357. span {
  358. color: #134bea;
  359. padding: 0 2px;
  360. }
  361. }
  362. //主要内容版块
  363. .contanier {
  364. background: #f6faff;
  365. box-shadow: inset 0px 0px 11px 1px rgba(188, 207, 255, 0.78);
  366. border-radius: 8px;
  367. margin-bottom: 24px;
  368. // max-height: 320px;
  369. @include mid-center;
  370. overflow-y: auto;
  371. .file_img {
  372. @include mid-center;
  373. justify-content: center;
  374. background: url("~@/assets/image/instruct/file_back.png") no-repeat;
  375. background-size: 144px;
  376. width: 144px;
  377. height: 144px;
  378. margin: 24px;
  379. font-size: 20px;
  380. color: #1a2447;
  381. font-weight: bold;
  382. padding-top: 8px;
  383. }
  384. .file_lim {
  385. background-size: 144px 80px;
  386. width: 144px;
  387. height: 80px;
  388. font-size: 16px;
  389. }
  390. @media (max-width: 1220px) {
  391. .file_img {
  392. background-size: 100px;
  393. width: 100px;
  394. height: 100px;
  395. }
  396. }
  397. .ied_item {
  398. // margin: 0px 24px 10px 0;
  399. margin: 24px;
  400. margin-left: 0;
  401. display: flex;
  402. align-items: start;
  403. flex-wrap: wrap;
  404. .ied_item_child {
  405. display: flex;
  406. flex-basis: 14%;
  407. flex-direction: column;
  408. align-items: center;
  409. font-size: 16px;
  410. cursor: pointer;
  411. div {
  412. position: relative;
  413. top: 10px;
  414. display: -webkit-box;
  415. /*弹性伸缩盒子模型显示*/
  416. -webkit-box-orient: vertical;
  417. /*排列方式*/
  418. -webkit-line-clamp: 1;
  419. /*显示文本行数*/
  420. overflow: hidden;
  421. /*溢出隐藏*/
  422. }
  423. }
  424. .ied_item_child:hover div {
  425. color: #255ce7;
  426. font-weight: 600;
  427. }
  428. img {
  429. width: 64px;
  430. height: 64px;
  431. }
  432. }
  433. }
  434. .container-none {
  435. font-size: 18px;
  436. display: flex;
  437. flex-direction: column;
  438. justify-content: center;
  439. align-items: center;
  440. & > img {
  441. width: 220px;
  442. height: 220px;
  443. }
  444. }
  445. :deep(.el-input .el-input__icon) {
  446. cursor: pointer;
  447. }
  448. </style>