areaCard.vue 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769
  1. /* 自定义tabs */
  2. <template>
  3. <!-- <transition>
  4. <div :class='areaClass' @mouseover="hover = false" @mouseleave="hover = false" onselectstart="return false">
  5. <div :class="headerClass">
  6. <div :class='circleClass'></div>
  7. <span class="gy-card-title">{{ title }}</span>
  8. <img class="gy-card-decoration01" src="../../assets/img/controlcenter/decoration01.png">
  9. <img class="gy-card-decoration02" src="../../assets/img/controlcenter/decoration02.png">
  10. </div>
  11. <div :class='contentClass'>
  12. <el-scrollbar style="height: 100%">
  13. <slot></slot>
  14. </el-scrollbar>
  15. </div>
  16. </div>
  17. </transition> -->
  18. <div class="body" :style="style">
  19. <img class="logo" src="../assets/img/logo.png" alt="">
  20. <div class="title">{{ title }}</div>
  21. <div style="margin-top: 50px; height: 91%;">
  22. <el-scrollbar>
  23. <div class="scoll">
  24. <div class="matrix" v-if="faultList.length>0">
  25. <div class="problemTitle">故障</div>
  26. <MatrixBlock @on-click="handleClick" :dataList="faultList"></MatrixBlock>
  27. </div>
  28. <div class="matrix" v-if="maintainList.length>0">
  29. <div class="problemTitle">维护</div>
  30. <MatrixBlock @on-click="handleClick" :dataList="maintainList"></MatrixBlock>
  31. </div>
  32. <div class="matrix" v-if="offlineList.length>0">
  33. <div class="problemTitle">离线</div>
  34. <MatrixBlock @on-click="handleClick" :dataList="offlineList"></MatrixBlock>
  35. </div>
  36. <div class="matrix" v-if="listedList.length>0">
  37. <div class="problemTitle">挂牌</div>
  38. <MatrixBlock @on-click="handleClick" :dataList="listedList"></MatrixBlock>
  39. </div>
  40. <div class="matrix" v-if="listedList.length>0">
  41. <div class="problemTitle">挂牌</div>
  42. <MatrixBlock @on-click="handleClick" :dataList="listedList"></MatrixBlock>
  43. </div>
  44. </div>
  45. </el-scrollbar>
  46. </div>
  47. </div>
  48. </template>
  49. <script>
  50. import BackgroundData from 'utils/BackgroundData'
  51. // import ProblemMatrixCard from "./problem/ProblemMatrixCard.vue";
  52. import MatrixBlock from "./matrixBlock.vue";
  53. /**
  54. * todo 拖动
  55. * todo 控制区
  56. *
  57. * 动态值:
  58. * 1. gy-card-area-label中的 height,margin-top
  59. * 2. gy-card-circle-yellow中的颜色
  60. * 3. gy-card-content-25 中的高度
  61. *
  62. * 使用事例:
  63. * <gy-card title="校验区" area-style="check" circle-style="green" content-style="44">
  64. * <div>动态内容</div>
  65. * </gy-card>
  66. */
  67. export default {
  68. name: 'gy-card',
  69. components: {
  70. // ProblemMatrixCard,
  71. MatrixBlock
  72. },
  73. emits: ["parentRun"],
  74. props: {
  75. title: {
  76. type: String,
  77. default: '校验区',
  78. required: true
  79. },
  80. height: {
  81. type: Number,
  82. default: 200,
  83. },
  84. areaStyle: {
  85. type: String,
  86. default: 'check',
  87. required: true
  88. },
  89. circleStyle: {
  90. type: String,
  91. default: 'green',
  92. required: true
  93. },
  94. contentStyle: {
  95. type: String,
  96. default: '44',
  97. required: true
  98. },
  99. showFlag: {
  100. type: Boolean,
  101. default: false,
  102. }
  103. },
  104. data() {
  105. return {
  106. dialogVisible: false,
  107. currentWindturbine: {},
  108. values: [],
  109. hover: false,
  110. big: false,
  111. current: 0,
  112. faultList: [],
  113. maintainList: [],
  114. offlineList: [],
  115. listedList: [],
  116. chooseList: [],
  117. totleList: [],
  118. titleList: [
  119. {
  120. id: 0,
  121. title: '麻黄山',
  122. },
  123. {
  124. id: 1,
  125. title: '牛首山',
  126. },
  127. {
  128. id: 2,
  129. title: '青山',
  130. },
  131. {
  132. id: 3,
  133. title: '石板泉',
  134. },
  135. {
  136. id: 4,
  137. title: '香山',
  138. },
  139. ],
  140. }
  141. },
  142. computed: {
  143. style() {
  144. return `width: 100%; height: 82%;`
  145. },
  146. areaClass() {
  147. if (this.big) {
  148. return `gy-card-area-big`;
  149. } else {
  150. return `gy-card-area-${this.areaStyle}`;
  151. }
  152. },
  153. circleClass() {
  154. return `gy-card-circle gy-card-circle-${this.circleStyle}`;
  155. },
  156. contentClass() {
  157. if (this.big) {
  158. return `gy-card-content-big`;
  159. } else {
  160. return `gy-card-content-${this.contentStyle}`;
  161. }
  162. },
  163. headerClass() {
  164. if (this.hover) {
  165. return `gy-card-header-hover`;
  166. } else {
  167. return `gy-card-header`;
  168. }
  169. }
  170. },
  171. methods: {
  172. handleClick(values) {
  173. console.log(this.chooseList, values)
  174. if (values.active) {
  175. let showIndex = null
  176. this.chooseList.forEach((item, index) => {
  177. if (item.windturbineId === values.windturbineId) {
  178. showIndex = index
  179. }
  180. })
  181. this.chooseList.splice(showIndex, 1);
  182. } else {
  183. this.chooseList.push(values)
  184. }
  185. },
  186. /* 右键菜单 */
  187. contextmenu() {
  188. const { remote } = require("electron");
  189. var that = this;
  190. const menuTemplate = [
  191. {
  192. label: "启动",
  193. click() {
  194. that.menuClicked({ type: "send", controlType: '1' });
  195. },
  196. },
  197. {
  198. label: "停机",
  199. click() {
  200. that.menuClicked({ type: "send", controlType: '2' });
  201. },
  202. },
  203. {
  204. label: "复位",
  205. click() {
  206. that.menuClicked({ type: "send", controlType: '5' });
  207. },
  208. },
  209. {
  210. label: "维护",
  211. click() {
  212. that.menuClicked({ type: "send", controlType: '6' });
  213. },
  214. },
  215. {
  216. label: "取消维护",
  217. click() {
  218. that.menuClicked({ type: "send", controlType: '8' });
  219. },
  220. },
  221. {
  222. label: "挂牌",
  223. submenu: [
  224. {
  225. label: "检修",
  226. click() {
  227. that.menuClicked({ type: "lock", value: "CheckLock" });
  228. },
  229. },
  230. {
  231. label: "故障维修",
  232. click() {
  233. that.menuClicked({ type: "lock", value: "FaultLock" });
  234. },
  235. },
  236. {
  237. label: "场内受累检修",
  238. click() {
  239. that.menuClicked({ type: "lock", value: "StationCheckLock" });
  240. },
  241. },
  242. {
  243. label: "场内受累故障",
  244. click() {
  245. that.menuClicked({ type: "lock", value: "StationFaulLock" });
  246. },
  247. },
  248. {
  249. label: "场外受累电网",
  250. click() {
  251. that.menuClicked({
  252. type: "lock",
  253. value: "StationPowerLineLock",
  254. });
  255. },
  256. },
  257. {
  258. label: "场外受累天气",
  259. click() {
  260. that.menuClicked({ type: "lock", value: "StationWeatherLock" });
  261. },
  262. },
  263. ],
  264. },
  265. {
  266. label: "取消挂牌",
  267. click() {
  268. that.menuClicked({ type: 'lock', value: 'UnLock' });
  269. },
  270. },
  271. {
  272. label: "标注",
  273. click() {
  274. that.menuClicked({ type: "marking" });
  275. },
  276. },
  277. ];
  278. const menu = remote.Menu.buildFromTemplate(menuTemplate);
  279. menu.popup(remote.getCurrentWindow());
  280. },
  281. menuClicked(msg) {
  282. var bd = BackgroundData.getInstance();
  283. if (!bd.LoginUser) {
  284. this.$notify({
  285. title: "请登录",
  286. message: "控制风机需要先登录!",
  287. type: "warning",
  288. position: "bottom-right",
  289. offset: 60,
  290. });
  291. return;
  292. }
  293. if (msg.type == "lock") {
  294. // 挂牌
  295. var los = this.getSelectedItems();
  296. for (var id in los) {
  297. los[id].lockType = msg.value;
  298. }
  299. bd.windturbineControl(
  300. los,
  301. true,
  302. this.controlSuccess,
  303. this.controlError
  304. );
  305. } else if (msg.type == "send") {
  306. // 发送
  307. var vs = this.getSelectedItems(true);
  308. for (var item in los) {
  309. los[item].controlType = Number(msg.controlType)
  310. }
  311. bd.windturbineControl(
  312. vs,
  313. false,
  314. this.controlSuccess,
  315. this.controlError
  316. );
  317. } else if (msg.type == "marking") {
  318. // 标注
  319. var vvs = this.getSelectedItems();
  320. bd.marking(vvs);
  321. }
  322. this.clearSelected();
  323. },
  324. /* 获取选中的项目,isControl:是否是控制 */
  325. getSelectedItems() {
  326. // isControl
  327. var ls = new Array();
  328. this.$refs.malfunction.outputSelectedItems(ls);
  329. return ls;
  330. },
  331. /* 清除所有选择 */
  332. clearSelected() {
  333. this.$refs.malfunction.clearSelected();
  334. },
  335. filter(value, windturbineId) {
  336. var array = [];
  337. var flag = false;
  338. for (var i = 0; i < value.length; i++) {
  339. if (value[i].windturbineId == windturbineId) {
  340. flag = true;
  341. array.push(flag); // 风机是否已经存在
  342. array.push(i); // 风机在values数组的位置
  343. array.push(value[i].active); // 当前风机是否被选中
  344. break;
  345. }
  346. }
  347. return array;
  348. },
  349. changeTitle(id) {
  350. this.current = id
  351. this.$refs.malfunction.dateClick(id)
  352. },
  353. addCard(val) {
  354. var active = false;
  355. var array = this.filter(this.values, val.windturbineId);
  356. if (!array[0]) {
  357. // 维护
  358. val.active = active;
  359. if (val.modelId.indexOf("105") >= 0) {
  360. val.rollSpeed *= 9.55;
  361. }
  362. this.values.push(val);
  363. } else {
  364. val.active = array[2];
  365. this.values.splice(array[1], 1, val);
  366. }
  367. console.log(this.values)
  368. },
  369. clear(vs) {
  370. var ll = new Array();
  371. this.values.forEach((item) => {
  372. var it = vs[item.windturbineId];
  373. if (typeof it === "undefined") {
  374. ll.push(item);
  375. }
  376. });
  377. for (var v1 in ll) {
  378. var ind = this.values.indexOf(ll[v1]);
  379. if (ind < 0) continue;
  380. this.values.splice(ind, 1);
  381. }
  382. },
  383. showWindows(item) {
  384. this.dialogVisible = true;
  385. this.currentWindturbine = item;
  386. }
  387. },
  388. watch: {
  389. "$store.getters.windturbinelist": {
  390. deep: true,
  391. handler: function (json) {
  392. var vs = {};
  393. this.faultList = []
  394. this.maintainList = []
  395. this.offlineList = []
  396. this.listedList = []
  397. let arr = Object.keys(json).sort()
  398. for (var id of arr) {
  399. var val = json[id];
  400. this.chooseList.forEach(item => {
  401. if (item.windturbineId === val.windturbineId) {
  402. val.active = true
  403. }
  404. })
  405. this.totleList.push(val)
  406. switch (val.status) {
  407. case 5:
  408. this.faultList.push(val)
  409. break;
  410. case 6:
  411. this.maintainList.push(val)
  412. break;
  413. case 7:
  414. this.offlineList.push(val)
  415. break;
  416. }
  417. if (val.lockValue > 0) {
  418. this.listedList.push(val)
  419. }
  420. }
  421. console.log(this.faultList);
  422. // this.clear(vs);
  423. },
  424. },
  425. },
  426. }
  427. </script>
  428. <style scoped="scoped">
  429. .body {
  430. border: 1px solid #373737;
  431. width: 100%;
  432. margin-left: 15px;
  433. margin-top: 10px;
  434. }
  435. .body .scoll {
  436. height: 91%;
  437. }
  438. .title {
  439. color: #ffffff;
  440. font-size: 14px;
  441. margin-left: 32px;
  442. /* margin-top: 12px; */
  443. margin-bottom: 10px;
  444. width: 570px;
  445. height: 50px;
  446. display: flex;
  447. align-items: center;
  448. position: absolute;
  449. background-color: #000000;
  450. }
  451. .title::before {
  452. z-index: 1;
  453. content: '';
  454. position: absolute;
  455. left: -18px !important;
  456. /* top: 30px !important; */
  457. width: 5px;
  458. height: 5px;
  459. background-color: #54B75A;
  460. border-radius: 50%;
  461. }
  462. .logo {
  463. position: absolute;
  464. top: 2px;
  465. left: 18px;
  466. }
  467. .matrix {
  468. margin-left: 32px;
  469. margin-right: 10px;
  470. padding-bottom: 20px;
  471. border-bottom: 1px solid rgba(31, 31, 31, 1);
  472. }
  473. .problemTitle {
  474. font-size: 12px;
  475. color: #BFBFBF;
  476. margin-top: 20px;
  477. margin-bottom: 20px;
  478. }
  479. .gy-card-header {
  480. position: relative;
  481. height: 40px;
  482. background-color: #292929;
  483. color: white;
  484. box-sizing: border-box;
  485. }
  486. .gy-card-content-89 {
  487. position: relative;
  488. height: calc(89vh - 50px);
  489. background-color: #000000;
  490. color: white;
  491. box-sizing: border-box;
  492. border-radius: 7px;
  493. }
  494. .gy-card-content-44 {
  495. position: relative;
  496. height: calc(44vh - 50px);
  497. background-color: #000000;
  498. color: white;
  499. box-sizing: border-box;
  500. border-radius: 7px;
  501. }
  502. .gy-card-content-37 {
  503. position: relative;
  504. height: calc(37vh - 50px);
  505. background-color: #000000;
  506. color: white;
  507. box-sizing: border-box;
  508. border-radius: 7px;
  509. }
  510. .gy-card-content-25 {
  511. position: relative;
  512. height: calc(25vh - 50px);
  513. background-color: #000000;
  514. color: white;
  515. box-sizing: border-box;
  516. border-radius: 7px;
  517. }
  518. .gy-card-circle {
  519. position: relative;
  520. top: 7px;
  521. display: inline-block;
  522. width: 7px;
  523. height: 7px;
  524. -moz-border-radius: 50%;
  525. -webkit-border-radius: 50%;
  526. border-radius: 50%;
  527. }
  528. .gy-card-circle-green {
  529. background-color: #008000;
  530. }
  531. .gy-card-circle-yellow {
  532. background-color: #ffff00;
  533. }
  534. .gy-card-title {
  535. position: relative;
  536. top: 10px;
  537. left: 10px;
  538. }
  539. .gy-card-decoration01 {
  540. position: absolute;
  541. right: 80px;
  542. }
  543. .gy-card-decoration02 {
  544. position: absolute;
  545. top: 20px;
  546. right: 20px;
  547. }
  548. .gy-card-area-problem {
  549. position: relative;
  550. height: 89vh;
  551. background-color: #292929;
  552. border-radius: 7px;
  553. margin: 0px;
  554. padding-top: 0;
  555. padding-left: 10px;
  556. padding-right: 10px;
  557. padding-bottom: 10px;
  558. box-sizing: border-box;
  559. }
  560. .gy-card-area-alarm {
  561. position: relative;
  562. height: 25vh;
  563. margin-top: 10px;
  564. background-color: #292929;
  565. border-radius: 7px;
  566. padding-left: 10px;
  567. padding-right: 10px;
  568. padding-bottom: 10px;
  569. box-sizing: border-box;
  570. }
  571. .gy-card-area-check {
  572. position: relative;
  573. height: 44vh;
  574. background-color: #292929;
  575. border-radius: 7px;
  576. margin-top: 10px;
  577. padding-top: 0;
  578. padding-left: 10px;
  579. padding-right: 10px;
  580. padding-bottom: 10px;
  581. box-sizing: border-box;
  582. }
  583. .gy-card-area-control {
  584. position: relative;
  585. width: 100%;
  586. height: 44vh;
  587. background-color: #292929;
  588. border-radius: 7px;
  589. margin: 0px;
  590. padding-top: 0;
  591. padding-left: 10px;
  592. padding-right: 10px;
  593. padding-bottom: 10px;
  594. box-sizing: border-box;
  595. }
  596. .gy-card-area-label {
  597. position: relative;
  598. height: 25vh;
  599. margin-top: 10px;
  600. background-color: #292929;
  601. border-radius: 7px;
  602. padding-left: 10px;
  603. padding-right: 10px;
  604. padding-bottom: 10px;
  605. box-sizing: border-box;
  606. }
  607. .gy-card-area-recommended {
  608. position: relative;
  609. height: 37vh;
  610. background-color: #292929;
  611. border-radius: 7px;
  612. padding-left: 10px;
  613. padding-right: 10px;
  614. padding-bottom: 10px;
  615. box-sizing: border-box;
  616. }
  617. .gy-card-header-hover {
  618. position: relative;
  619. height: 40px;
  620. background-color: #292929;
  621. color: white;
  622. box-sizing: border-box;
  623. }
  624. .gy-card-area-problem:hover {
  625. position: relative;
  626. height: 89vh;
  627. background-color: #292929;
  628. border-radius: 7px;
  629. margin: 0px;
  630. padding-top: 0;
  631. padding-left: 10px;
  632. padding-right: 10px;
  633. padding-bottom: 10px;
  634. box-sizing: border-box;
  635. }
  636. .gy-card-area-alarm:hover {
  637. position: relative;
  638. height: 25vh;
  639. margin-top: 10px;
  640. background-color: #292929;
  641. border-radius: 7px;
  642. padding-left: 10px;
  643. padding-right: 10px;
  644. padding-bottom: 10px;
  645. box-sizing: border-box;
  646. }
  647. .gy-card-area-label:hover {
  648. position: relative;
  649. height: 25vh;
  650. margin-top: 10px;
  651. background-color: #292929;
  652. border-radius: 7px;
  653. padding-left: 10px;
  654. padding-right: 10px;
  655. padding-bottom: 10px;
  656. box-sizing: border-box;
  657. }
  658. .gy-card-area-recommended:hover {
  659. position: relative;
  660. height: 37vh;
  661. background-color: #292929;
  662. border-radius: 7px;
  663. padding-left: 10px;
  664. padding-right: 10px;
  665. padding-bottom: 10px;
  666. box-sizing: border-box;
  667. }
  668. .gy-card-area-big {
  669. position: fixed;
  670. top: 0px;
  671. left: 0px;
  672. width: 100vw;
  673. height: 100vh;
  674. background-color: #292929;
  675. border-radius: 7px;
  676. margin: 0px;
  677. padding-top: 0;
  678. padding-left: 10px;
  679. padding-right: 10px;
  680. padding-bottom: 10px;
  681. box-sizing: border-box;
  682. z-index: 900;
  683. }
  684. .gy-card-content-big {
  685. position: relative;
  686. height: calc(100vh - 50px);
  687. background-color: #000000;
  688. color: white;
  689. box-sizing: border-box;
  690. border-radius: 7px;
  691. }
  692. .el-scrollbar__wrap {
  693. overflow: scroll;
  694. width: 110%;
  695. height: 120%;
  696. }
  697. ::-webkit-scrollbar {
  698. width: 0;
  699. height: 0;
  700. }
  701. .scroll {
  702. color: #ffffff;
  703. min-height: 300px;
  704. height: 400px;
  705. }
  706. .content {
  707. display: flex;
  708. align-items: center;
  709. justify-content: center;
  710. width: 80px;
  711. color: #ffffff;
  712. height: 25px;
  713. border: 1px solid blue;
  714. margin-right: 10px;
  715. margin-bottom: 10px;
  716. }
  717. .content_on {
  718. display: flex;
  719. align-items: center;
  720. justify-content: center;
  721. width: 80px;
  722. color: #ffffff;
  723. height: 25px;
  724. border: 1px solid blue;
  725. margin-right: 10px;
  726. margin-bottom: 10px;
  727. background-color: chartreuse;
  728. }
  729. </style>