scdVisual.vue 12 KB

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