LightMatrix1.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668
  1. <template>
  2. <div class="light-matrix">
  3. <Row class="panel-2" type="">
  4. <Col :span="12" class="left-50-16">
  5. <div class="panel">
  6. <div class="dot left top"></div>
  7. <div class="dot left bottom"></div>
  8. <div class="dot right top"></div>
  9. <div class="dot right bottom"></div>
  10. <div class="item">
  11. <div class="loop"></div>
  12. <span class="svg-icon svg-icon-gray svg-icon-md">
  13. <SvgIcon svgid="svg-wind-site"></SvgIcon>
  14. </span>
  15. </div>
  16. <div class="item write" @click="changeShow('jrfj_FDC')">
  17. <div>接入风机</div>
  18. <div>{{ sourceMap.fcjrnum || "---" }}</div>
  19. </div>
  20. <div class="item blue" @click="changeShow('yx_FDC', 1)">
  21. <div>· 运行</div>
  22. <div>{{ sourceMap.fcyxnum || "---" }}</div>
  23. </div>
  24. <div class="item green" @click="changeShow('dj_FDC', 0)">
  25. <div>· 待机</div>
  26. <div>{{ sourceMap.fcdjnum || "---" }}</div>
  27. </div>
  28. <div class="item pink" @click="changeShow('xd_FDC', 5)">
  29. <div>· 限电</div>
  30. <div>{{ sourceMap.fcxdnum || "---" }}</div>
  31. </div>
  32. <div class="item red" @click="changeShow('gz_FDC', 2)">
  33. <div>· 故障</div>
  34. <div>{{ sourceMap.fcgznum || "---" }}</div>
  35. </div>
  36. <div class="item orange" @click="changeShow('jx_FDC', 4)">
  37. <div>· 检修</div>
  38. <div>{{ sourceMap.fcwhnum || "---" }}</div>
  39. </div>
  40. <div class="item write" @click="changeShow('sl_FDC', 6)">
  41. <div>· 受累</div>
  42. <div>{{ sourceMap.fcslnum || "---" }}</div>
  43. </div>
  44. <div class="item gray" @click="changeShow('lx_FDC', 3)">
  45. <div>· 离线</div>
  46. <div>{{ sourceMap.fclxnum || "---" }}</div>
  47. </div>
  48. </div>
  49. </Col>
  50. <Col :span="12" class="left-50-16">
  51. <div class="panel">
  52. <div class="dot left top"></div>
  53. <div class="dot left bottom"></div>
  54. <div class="dot right top"></div>
  55. <div class="dot right bottom"></div>
  56. <div class="item">
  57. <div class="loop"></div>
  58. <span class="svg-icon svg-icon-gray svg-icon-md">
  59. <SvgIcon
  60. :svgid="'svg-photovoltaic'"
  61. style="margin: 3px 0px -3px 1px"
  62. ></SvgIcon>
  63. </span>
  64. </div>
  65. <div class="item write" @click="changeShow('jrfj1_GDC')">
  66. <div>逆变器</div>
  67. <div>{{ sourceMap.gfjrnum || "---" }}</div>
  68. </div>
  69. <div class="item blue" @click="changeShow('yx1_GDC', 1)">
  70. <div>· 运行</div>
  71. <div>{{ sourceMap.gfyxnum || "---" }}</div>
  72. </div>
  73. <div class="item green" @click="changeShow('dj1_GDC', 0)">
  74. <div>· 待机</div>
  75. <div>{{ sourceMap.gfdjnum || "---" }}</div>
  76. </div>
  77. <div class="item pink" @click="changeShow('xd1_GDC', 5)">
  78. <div>· 限电</div>
  79. <div>{{ sourceMap.gfxdnum || "---" }}</div>
  80. </div>
  81. <div class="item red" @click="changeShow('gz1_GDC', 2)">
  82. <div>· 故障</div>
  83. <div>{{ sourceMap.gfgznum || "---" }}</div>
  84. </div>
  85. <div class="item orange" @click="changeShow('jx1_GDC', 4)">
  86. <div>· 检修</div>
  87. <div>{{ sourceMap.gfwhnum || "---" }}</div>
  88. </div>
  89. <div class="item write" @click="changeShow('sl1_GDC', 6)">
  90. <div>· 受累</div>
  91. <div>{{ sourceMap.gfslnum || "---" }}</div>
  92. </div>
  93. <div class="item gray" @click="changeShow('lx1_GDC', 3)">
  94. <div>· 离线</div>
  95. <div>{{ sourceMap.gflxnum || "---" }}</div>
  96. </div>
  97. </div>
  98. </Col>
  99. </Row>
  100. <div class="panel-box">
  101. <div v-for="(pItem, pIndex) in sourceMap.fjmap" :key="pIndex">
  102. <div class="panel-title">
  103. <div class="panel-title-name">
  104. <i class="svg-icon svg-icon-sm svg-icon-green">
  105. <SvgIcon :svgid="'svg-wind-site'"></SvgIcon>
  106. </i>
  107. <span>{{
  108. sourceMap.fczbmap[sourceMap.fjmap[pIndex][0].wpId].name ||
  109. "------"
  110. }}</span>
  111. <div
  112. class="sub-title-item"
  113. v-for="(fcItem, fcIndex) in fcStateArray"
  114. :key="fcIndex"
  115. >
  116. <span class="sub-title">{{ fcItem.text }}</span>
  117. <span class="sub-count" :class="fcItem.color">{{
  118. sourceMap.fczbmap[sourceMap.fjmap[pIndex][0].wpId][fcItem.key]
  119. }}</span>
  120. </div>
  121. </div>
  122. </div>
  123. <div class="panel-body">
  124. <div
  125. class="card"
  126. v-for="(cItem, cIndex) of pItem"
  127. :key="cIndex"
  128. v-show="cItem.isShow"
  129. :class="cItem.color"
  130. @click="goDetails(cItem)"
  131. >
  132. {{ cItem.wtnum }}
  133. </div>
  134. <!-- 站位用 保证卡片布局最后一行不会有问题 -->
  135. <i class="blank" v-for="i in pItem.length" :key="i"></i>
  136. </div>
  137. </div>
  138. </div>
  139. </div>
  140. </template>
  141. <script>
  142. import Row from "@/components/coms/grid/row.vue";
  143. import Col from "@/components/coms/grid/col.vue";
  144. import SvgIcon from "@com/coms/icon/svg-icon.vue";
  145. import util from "@/helper/util.js";
  146. import store from "@store/index.js";
  147. import { isNumber } from "util";
  148. import { setInterval, clearInterval } from "timers";
  149. export default {
  150. // 名称
  151. name: "LightMatrix1",
  152. // 使用组件
  153. components: {
  154. Row,
  155. Col,
  156. SvgIcon,
  157. },
  158. // 数据
  159. data() {
  160. return {
  161. timmer: null, // 计时器
  162. sourceMap: {}, // 核心数据
  163. fillCategory: null, // 过滤条件
  164. fillFjzt: null, // 过滤条件
  165. fcStateArray: [
  166. {
  167. text: "接入台数",
  168. color: "write",
  169. key: "jrts",
  170. },
  171. {
  172. text: "待机台数",
  173. color: "green",
  174. key: "djts",
  175. },
  176. {
  177. text: "并网台数",
  178. color: "blue",
  179. key: "yxts",
  180. },
  181. {
  182. text: "限电台数",
  183. color: "purple",
  184. key: "xdts",
  185. },
  186. {
  187. text: "故障台数",
  188. color: "red",
  189. key: "gzts",
  190. },
  191. {
  192. text: "检修台数",
  193. color: "orange",
  194. key: "whts",
  195. },
  196. {
  197. text: "受累台数",
  198. color: "write",
  199. key: "slts",
  200. },
  201. {
  202. text: "离线台数",
  203. color: "gray",
  204. key: "lxts",
  205. },
  206. {
  207. text: "风速",
  208. color: "gray",
  209. key: "ssfs",
  210. },
  211. {
  212. text: "预测功率",
  213. color: "gray",
  214. key: "ycgl",
  215. },
  216. {
  217. text: "保证功率",
  218. color: "gray",
  219. key: "bzgl",
  220. },
  221. {
  222. text: "应发功率",
  223. color: "gray",
  224. key: "yfgl",
  225. },
  226. {
  227. text: "实际功率",
  228. color: "gray",
  229. key: "sjgl",
  230. },
  231. {
  232. text: "AGC指令",
  233. color: "gray",
  234. key: "agcygsd",
  235. },
  236. {
  237. text: "出线功率",
  238. color: "gray",
  239. key: "agccxyg",
  240. },
  241. ],
  242. };
  243. },
  244. // 函数
  245. methods: {
  246. // 根据风机状态码返回对应 class
  247. getColor(fjzt) {
  248. switch (fjzt) {
  249. case 0:
  250. return "green";
  251. break;
  252. case 1:
  253. return "blue";
  254. break;
  255. case 2:
  256. return "red";
  257. break;
  258. case 3:
  259. return "gray";
  260. break;
  261. case 4:
  262. return "orange";
  263. break;
  264. case 5:
  265. return "pink";
  266. break;
  267. case 6:
  268. return "pink";
  269. break;
  270. }
  271. },
  272. // 切换显示种类
  273. changeShow(category, fjzt, skipFill) {
  274. if (!skipFill) {
  275. if (this.fillCategory === category) {
  276. this.fillCategory = null;
  277. this.fillFjzt = null;
  278. } else {
  279. this.fillCategory = category;
  280. this.fillFjzt = fjzt;
  281. }
  282. }
  283. let fjmap = this.BASE.deepCopy(this.sourceMap.fjmap);
  284. fjmap.forEach((pEle) => {
  285. pEle.forEach((cEle) => {
  286. cEle.isShow = true;
  287. if (!this.fillCategory) {
  288. cEle.isShow = true;
  289. } else if (cEle.wpId.indexOf(category.split("_")[1]) !== -1) {
  290. if (isNumber(fjzt)) {
  291. cEle.fjzt === fjzt ? (cEle.isShow = true) : (cEle.isShow = false);
  292. } else {
  293. cEle.isShow = true;
  294. }
  295. } else {
  296. cEle.isShow = true;
  297. }
  298. });
  299. });
  300. this.sourceMap.fjmap = fjmap;
  301. },
  302. // 请求服务
  303. requestData(showLoading) {
  304. let that = this;
  305. that.API.requestData({
  306. showLoading,
  307. method: "POST",
  308. subUrl: "matrix/matrixPush",
  309. success(res) {
  310. if (res) {
  311. let sourceMap = res.data;
  312. let fjmap = [];
  313. for (let key in sourceMap) {
  314. if (key !== "fczbmap" && key !== "fjmap") {
  315. sourceMap[key] += "";
  316. } else if (key === "fjmap") {
  317. sourceMap[key].forEach((pItem) => {
  318. pItem.forEach((cItem) => {
  319. cItem.color = that.getColor(cItem.fjzt);
  320. cItem.isShow = true;
  321. });
  322. });
  323. }
  324. }
  325. that.sourceMap = sourceMap;
  326. if (that.fillCategory) {
  327. that.changeShow(that.fillCategory, that.fillFjzt, true);
  328. }
  329. } else {
  330. that.sourceMap = {};
  331. }
  332. },
  333. });
  334. },
  335. // 查看风机详情
  336. goDetails(item) {
  337. if (item.wpId.indexOf("FDC") !== -1) {
  338. this.$router.push({
  339. path: `/monitor/windsite/info/${item.wpId}/${item.wtId}`
  340. });
  341. } else {
  342. // this.$router.push({
  343. // path: `/info/inverter-info/${item.wpId}/${item.wtId}`
  344. // });
  345. }
  346. },
  347. },
  348. created() {
  349. let that = this;
  350. that.$nextTick(() => {
  351. that.requestData(false);
  352. that.timmer = setInterval(() => {
  353. that.requestData(false);
  354. }, that.$store.state.websocketTimeSec);
  355. });
  356. },
  357. unmounted() {
  358. clearInterval(this.timmer);
  359. this.timmer = null;
  360. },
  361. };
  362. </script>
  363. <style lang="less" scoped>
  364. @panelHeight: 6.481vh;
  365. @titleHeight: 2.7778vh;
  366. .light-matrix {
  367. // width: calc(100% - 1.111vh);
  368. height: calc(100vh - 7.222vh);
  369. display: flex;
  370. flex-direction: column;
  371. .panel-2 {
  372. .left-50-16 {
  373. width: calc(50% - 0.741vh);
  374. }
  375. }
  376. .panel {
  377. width: 100%;
  378. border: 0.093vh solid @darkgray;
  379. position: relative;
  380. padding: 0.7407vh 1.4815vh;
  381. background-color: fade(@darkgray, 20%);
  382. display: flex;
  383. .dot {
  384. width: 0.185vh;
  385. height: 0.185vh;
  386. border-radius: 50%;
  387. background-color: @write;
  388. position: absolute;
  389. &.left {
  390. left: 0.37vh;
  391. }
  392. &.right {
  393. right: 0.37vh;
  394. }
  395. &.top {
  396. top: 0.37vh;
  397. }
  398. &.bottom {
  399. bottom: 0.37vh;
  400. }
  401. }
  402. .item {
  403. flex: 1;
  404. display: flex;
  405. align-items: center;
  406. justify-content: center;
  407. flex-direction: column;
  408. color: @write;
  409. position: relative;
  410. .loop {
  411. position: absolute;
  412. width: 4.444vh;
  413. height: 4.444vh;
  414. border-radius: 50%;
  415. border: 0.093vh solid @darkgray;
  416. background-color: fade(@darkgray, 20);
  417. left: calc(50% - 2.222vh);
  418. top: calc(50% - 2.222vh);
  419. }
  420. &.write {
  421. color: @write;
  422. }
  423. &.green {
  424. color: @green;
  425. }
  426. &.blue {
  427. color: @darkBlue;
  428. }
  429. &.pink {
  430. color: @pink;
  431. }
  432. &.red {
  433. color: @red;
  434. }
  435. &.orange {
  436. color: @orange;
  437. }
  438. &.gray {
  439. color: @gray;
  440. }
  441. div {
  442. line-height: 2.222vh;
  443. &:first-child {
  444. font-size: @fontsize-s;
  445. }
  446. &:last-child {
  447. font-size: @fontsize;
  448. font-family: "Bicubik";
  449. }
  450. }
  451. }
  452. .item2 {
  453. flex: 1;
  454. display: flex;
  455. width: 20%;
  456. flex-wrap: wrap;
  457. .name {
  458. color: @gray;
  459. width: 50%;
  460. text-align: center;
  461. }
  462. .num2 {
  463. width: 50%;
  464. color: @yellow;
  465. text-align: left;
  466. }
  467. .num1 {
  468. width: 50%;
  469. color: @yellow;
  470. text-align: center;
  471. position: relative;
  472. &::after {
  473. content: "";
  474. position: absolute;
  475. width: 1.481vh;
  476. height: 0.556vh;
  477. background-color: @yellow;
  478. left: 1.204vh;
  479. top: 0.741vh;
  480. }
  481. }
  482. .num3 {
  483. width: 50%;
  484. color: @yellow;
  485. text-align: left;
  486. }
  487. }
  488. }
  489. .panel-box {
  490. margin-top: 0.7407vh;
  491. flex-grow: 1;
  492. .panel-title {
  493. width: 100%;
  494. height: @titleHeight;
  495. line-height: @titleHeight;
  496. background-color: fade(@darkgray, 40%);
  497. .panel-title-name {
  498. font-size: @fontsize-s;
  499. color: @green;
  500. display: flex;
  501. align-items: center;
  502. padding: 0 16px;
  503. i {
  504. margin-right: 0.7407vh;
  505. }
  506. .sub-title-item {
  507. display: flex;
  508. flex: 1;
  509. .sub-title {
  510. flex: 0 0 auto;
  511. color: @gray;
  512. font-size: 12px;
  513. margin: 0 0.556vh 0 1.481vh;
  514. }
  515. .sub-count {
  516. flex: 1 0 auto;
  517. font-size: 14px;
  518. font-family: "Bicubik";
  519. font-weight: 500;
  520. &.write {
  521. color: @write;
  522. }
  523. &.green {
  524. color: @green;
  525. }
  526. &.blue {
  527. color: @darkBlue;
  528. }
  529. &.pink {
  530. color: @pink;
  531. }
  532. &.red {
  533. color: @red;
  534. }
  535. &.orange {
  536. color: @orange;
  537. }
  538. &.gray {
  539. color: @gray;
  540. }
  541. }
  542. }
  543. }
  544. }
  545. .panel-body {
  546. height: calc(100% - 7.407vh);
  547. padding: 0.3704vh;
  548. width: 100%;
  549. display: flex;
  550. flex-direction: row;
  551. flex-wrap: wrap;
  552. justify-content: space-between;
  553. justify-content: flex-start;
  554. .blank {
  555. margin-right: 2px;
  556. flex: 1 0 40px;
  557. }
  558. .card {
  559. margin-right: 2px;
  560. margin-top: 2px;
  561. flex: 1 0 40px;
  562. cursor: pointer;
  563. }
  564. .card {
  565. border-radius: 0.37vh;
  566. padding: 0.185vh 0.3704vh;
  567. text-align: center;
  568. border: 0.093vh solid;
  569. font-size: 12px;
  570. &.write {
  571. color: @black;
  572. border-color: @write;
  573. background-color: @write;
  574. }
  575. &.green {
  576. color: @green;
  577. border-color: @green;
  578. }
  579. &.blue {
  580. color: @darkBlue;
  581. border-color: @darkBlue;
  582. }
  583. &.pink {
  584. color: @pink;
  585. border-color: @pink;
  586. }
  587. &.red {
  588. color: @write;
  589. border-color: @red;
  590. background-color: @red;
  591. }
  592. &.orange {
  593. color: @orange;
  594. border-color: @orange;
  595. }
  596. &.gray {
  597. color: @write;
  598. border-color: @darkgray;
  599. background-color: @darkgray;
  600. }
  601. }
  602. }
  603. }
  604. }
  605. </style>