App.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517
  1. <template class="app">
  2. <div style="background-color: #000000" ref="imageTofile">
  3. <div v-if="lockMaskDisplay" class="lockMask"></div>
  4. <!-- <div class="warningMask"></div> -->
  5. <TitleBar class="titleBar" />
  6. <div class="left">
  7. <Menu :lockMaskDisplay="lockMaskDisplay" :temperatureNum="temperatureNum" @handleChange="handleChange"
  8. @handleSearch="handleSearch" />
  9. </div>
  10. <div class="right">
  11. <el-col>
  12. <el-row>
  13. <el-col>
  14. <ModeControl ref="modeControl" :current="current" @clicks="handleClick"></ModeControl>
  15. </el-col>
  16. </el-row>
  17. <el-row>
  18. <el-col>
  19. <FocusArea />
  20. </el-col>
  21. </el-row>
  22. <el-row>
  23. <el-col>
  24. <WarningArea></WarningArea>
  25. </el-col>
  26. </el-row>
  27. </el-col>
  28. </div>
  29. <div class="Dialog" v-show="state">
  30. <div class="D-" @click="none">-</div>
  31. </div>
  32. <StatusBar class="statusBar" @getData="getData" />
  33. <router-view />
  34. <AllMatrices v-model="matricesDisplay" />
  35. <SYZDetails v-model="syzDialogShow" :activeTabStation="activeTabStation"></SYZDetails>
  36. <AGCDetails v-model="agcDisplay"></AGCDetails>
  37. <TemperatureMatrix v-model="temperatureDisplay" />
  38. <Fault v-model="faultDisplay" />
  39. <Warning v-model="warningDisplay" />
  40. <Status v-model="statusDisplay" />
  41. <Action v-model="actionDisplay" />
  42. <Calendar v-model="calendarDisplay" />
  43. <Record v-model="recordDisplay" />
  44. <State v-model="stateDisplay" />
  45. <Setting v-model="settingDisplay" />
  46. </div>
  47. </template>
  48. <script>
  49. import TitleBar from "views/TitleBar.vue";
  50. import StatusBar from "views/StatusBar.vue";
  51. import Menu from "views/Menu.vue";
  52. import MessageBridge from "utils/MessageBridge";
  53. import ModeControl from "components/modeControl/modeControl.vue";
  54. import FocusArea from "components/focus/focusArea.vue";
  55. import WarningArea from "components/warning/warningArea.vue";
  56. import api from "api/index";
  57. import boxSelect from "components/boxSelect.vue";
  58. import AGCDetails from "components/focus/agcDetails.vue";
  59. import SYZDetails from "components/focus/syzDetails.vue";
  60. import AllMatrices from "components/allMatrices.vue";
  61. import Setting from "components/setting.vue";
  62. import TemperatureMatrix from "components/temperatureMatrix.vue";
  63. import Fault from "components/search/fault.vue";
  64. import Warning from "components/search/warning.vue";
  65. import Status from "components/search/status.vue";
  66. import Action from "components/search/action.vue";
  67. import html2canvas from "html2canvas";
  68. import Calendar from "components/search/calendar.vue";
  69. import Record from "components/search/record.vue";
  70. import State from "components/search/state.vue";
  71. import { debounce } from "lodash";
  72. export default {
  73. data() {
  74. return {
  75. state: false,
  76. agcDisplay: false, //AGC功能
  77. matricesDisplay: false, //全部矩阵
  78. temperatureDisplay: false, //温度矩阵
  79. faultDisplay: false, //查询-报警/故障查询
  80. warningDisplay: false, //查询-预警查询
  81. statusDisplay: false, //查询-状态时间查询
  82. actionDisplay: false, //查询-动作查询
  83. lockMaskDisplay: false, //锁屏
  84. syzDialogShow: false,
  85. settingDisplay: false,
  86. recordDisplay: false, //查询-推荐记录
  87. stateDisplay: false, //查询-状态变化查询
  88. calendarDisplay: false, //查询-日历查询
  89. temperatureNum: 0, //温度矩阵故障数
  90. activeTabStation: '',
  91. };
  92. },
  93. components: {
  94. TitleBar,
  95. StatusBar,
  96. Menu,
  97. ModeControl,
  98. FocusArea,
  99. WarningArea,
  100. boxSelect,
  101. AGCDetails,
  102. SYZDetails,
  103. AllMatrices,
  104. TemperatureMatrix,
  105. Fault,
  106. Warning,
  107. Status,
  108. Action,
  109. Setting,
  110. Calendar,
  111. Record,
  112. State,
  113. },
  114. created: function () {
  115. this.getStation();
  116. this.initData();
  117. },
  118. methods: {
  119. getData(val) {
  120. this.state = val;
  121. },
  122. none() {
  123. this.state = false;
  124. },
  125. initData: function () {
  126. let mb = MessageBridge.getInstance();
  127. let temperature = [
  128. { key: "/topic/temperature-count", action: this.debounceTemperatureMessage },
  129. ];
  130. let vss = [
  131. { key: "/topic/voice-control", action: this.windturbineMessage },
  132. ];
  133. mb.register(vss);
  134. mb.register(temperature);
  135. },
  136. debounceTemperatureMessage: debounce(function (msg) {
  137. this.temperatureMessage(msg)
  138. }, 1000),
  139. temperatureMessage(msg) {
  140. let json = JSON.parse(msg);
  141. this.temperatureNum = json.countOverLimit + json.countCrossingLimit;
  142. },
  143. windturbineMessage(msg) {
  144. let arr = msg.split("-");
  145. if (msg === "CLOSE") {
  146. this.handleClosed()
  147. }
  148. if (msg === "OPEN_FJJZ-ALL") {
  149. this.handleChange(2)
  150. }
  151. if (msg === "OPEN_WDJZ-ALL") {
  152. this.handleChange(3)
  153. }
  154. if (msg === "OPEN_AGC-ALL") {
  155. this.handleChange(5)
  156. }
  157. if (arr[0] === "OPEN_SYZ") {
  158. this.activeTabStation = arr[1]
  159. this.handleClosed()
  160. setTimeout(() => {
  161. this.handleChange(4)
  162. }, 3000);
  163. }
  164. },
  165. getStation() {
  166. api.getStation().then((res) => {
  167. let stationList = [];
  168. res.data.forEach((item) => {
  169. if (item.type === 1) {
  170. stationList.push(item);
  171. }
  172. });
  173. this.$store.commit("stationList", stationList);
  174. let syzArray = [];
  175. stationList.forEach((item) => {
  176. let obj = {
  177. id: item.id, // 升压站 ID
  178. isWarning: "0", // 升压站是否显示报警小红点
  179. name: item.name, // 升压站中文名称
  180. isMute: false, // 升压站报警是否静音
  181. };
  182. syzArray.push(obj);
  183. });
  184. this.$store.commit("syzArray", syzArray);
  185. this.$store.commit("activeTab", syzArray[0].name);
  186. });
  187. },
  188. handleChange(val) {
  189. if (val !== 9) {
  190. this.matricesDisplay = false;
  191. this.syzDialogShow = false;
  192. // this.$store.commit("syzDialogShow", false);
  193. this.agcDisplay = false;
  194. this.temperatureDisplay = false;
  195. this.faultDisplay = false;
  196. this.warningDisplay = false;
  197. this.statusDisplay = false;
  198. this.actionDisplay = false;
  199. this.settingDisplay = false
  200. this.calendarDisplay = false;
  201. this.recordDisplay = false;
  202. this.stateDisplay = false;
  203. }
  204. switch (val) {
  205. case 2:
  206. this.matricesDisplay = true;
  207. break;
  208. case 3:
  209. this.temperatureDisplay = true;
  210. break;
  211. case 4:
  212. this.syzDialogShow = true;
  213. break;
  214. case 5:
  215. this.agcDisplay = true;
  216. break;
  217. case 7:
  218. this.lockMaskDisplay = !this.lockMaskDisplay;
  219. break;
  220. case 9:
  221. this.toImage();
  222. break;
  223. case 10:
  224. this.settingDisplay = true;
  225. break;
  226. default:
  227. break;
  228. }
  229. },
  230. handleClosed() {
  231. this.matricesDisplay = false;
  232. this.syzDialogShow = false;
  233. // this.$store.commit("syzDialogShow", false);
  234. this.agcDisplay = false;
  235. this.temperatureDisplay = false;
  236. this.faultDisplay = false;
  237. this.warningDisplay = false;
  238. this.statusDisplay = false;
  239. this.actionDisplay = false;
  240. this.settingDisplay = false
  241. this.calendarDisplay = false;
  242. this.recordDisplay = false;
  243. this.stateDisplay = false;
  244. },
  245. handleSearch(val) {
  246. this.matricesDisplay = false;
  247. this.$store.commit("syzDialogShow", false);
  248. this.agcDisplay = false;
  249. this.temperatureDisplay = false;
  250. this.faultDisplay = false;
  251. this.warningDisplay = false;
  252. this.statusDisplay = false;
  253. this.actionDisplay = false;
  254. this.settingDisplay = false;
  255. this.calendarDisplay = false;
  256. this.recordDisplay = false;
  257. this.stateDisplay = false;
  258. switch (val) {
  259. case "fault":
  260. this.faultDisplay = true;
  261. break;
  262. case "warning":
  263. this.warningDisplay = true;
  264. break;
  265. case "status":
  266. this.statusDisplay = true;
  267. break;
  268. case "action":
  269. this.actionDisplay = true;
  270. break;
  271. case "calendar":
  272. this.calendarDisplay = true;
  273. break;
  274. case "record":
  275. this.recordDisplay = true;
  276. break;
  277. case "changeState":
  278. this.stateDisplay = true;
  279. break;
  280. default:
  281. break;
  282. }
  283. },
  284. // 页面元素转图片
  285. toImage() {
  286. // 手动创建一个 canvas 标签
  287. const canvas = document.createElement("canvas");
  288. // 获取父标签,意思是这个标签内的 DOM 元素生成图片
  289. // imageTofile是给截图范围内的父级元素自定义的ref名称
  290. let canvasBox = this.$refs.imageTofile;
  291. // 获取父级的宽高
  292. const width = parseInt(window.getComputedStyle(canvasBox).width);
  293. const height = parseInt(window.getComputedStyle(canvasBox).height);
  294. // 宽高 * 2 并放大 2 倍 是为了防止图片模糊
  295. canvas.width = width * 2;
  296. canvas.height = height * 2;
  297. canvas.style.width = width + "px";
  298. canvas.style.height = height + "px";
  299. const context = canvas.getContext("2d");
  300. context.scale(2, 2);
  301. const options = {
  302. backgroundColor: null,
  303. canvas: canvas,
  304. useCORS: true,
  305. };
  306. html2canvas(canvasBox, options).then((canvas) => {
  307. // toDataURL 图片格式转成 base64
  308. let dataURL = canvas.toDataURL("image/png");
  309. console.log(dataURL);
  310. this.downloadImage(dataURL);
  311. });
  312. },
  313. //下载图片
  314. downloadImage(url) {
  315. // 如果是在网页中可以直接创建一个 a 标签直接下载
  316. let a = document.createElement("a");
  317. a.href = url;
  318. a.download = "页面截图";
  319. a.click();
  320. },
  321. },
  322. };
  323. </script>
  324. <style>
  325. @import "../src/assets/styles/main.css";
  326. body {
  327. /* 设置内容不可选中 */
  328. -webkit-user-select: none;
  329. -moz-user-select: none;
  330. -ms-user-select: none;
  331. user-select: none;
  332. }
  333. /* .app{
  334. background-color: #000000;
  335. } */
  336. .Dialog {
  337. width: 520px;
  338. height: 800px;
  339. background-color: rgb(250, 249, 249);
  340. position: absolute;
  341. right: 30px;
  342. z-index: 999;
  343. bottom: 50px;
  344. /* display: none; */
  345. }
  346. .D- {
  347. width: 30px;
  348. height: 30px;
  349. background-color: rgb(167, 204, 192);
  350. font-size: 30px;
  351. position: absolute;
  352. top: 5px;
  353. right: 10px;
  354. line-height: 30px;
  355. text-align: center;
  356. }
  357. .D-:hover {
  358. background-color: #999999;
  359. }
  360. .left {
  361. width: 40px;
  362. position: absolute;
  363. left: 0px;
  364. height: 100%;
  365. z-index: 9999;
  366. background-color: #242424;
  367. margin-left: 7px;
  368. border-radius: 8px;
  369. }
  370. .right {
  371. width: 31%;
  372. position: absolute;
  373. right: 20px;
  374. z-index: 99;
  375. }
  376. .statusBar {
  377. width: 100%;
  378. position: absolute;
  379. bottom: 0;
  380. left: 0;
  381. z-index: 9999;
  382. }
  383. .titleBar {
  384. width: 100%;
  385. position: relative;
  386. top: 0;
  387. left: 0;
  388. z-index: 999;
  389. }
  390. .el-table__body-wrapper::-webkit-scrollbar-thumb {
  391. background-color: #999999;
  392. border-radius: 8px;
  393. }
  394. .el-collapse-item__wrap {
  395. background-color: #000000 !important;
  396. box-sizing: border-box !important;
  397. padding-left: 27px !important;
  398. }
  399. .el-collapse-item__header {
  400. background-color: rgb(20, 20, 20) !important;
  401. font-size: 12px !important;
  402. color: #bfbfbf !important;
  403. box-sizing: border-box !important;
  404. padding-left: 30px !important;
  405. margin-bottom: 2px !important;
  406. }
  407. .el-collapse {
  408. border: none !important;
  409. }
  410. .el-collapse-item__header {
  411. border: none !important;
  412. }
  413. .el-collapse-item__wrap {
  414. border: none !important;
  415. }
  416. .lockMask {
  417. width: 100%;
  418. height: 100%;
  419. position: absolute;
  420. background-color: rgba(0, 0, 0, 0.2);
  421. z-index: 9998;
  422. }
  423. .warningMask {
  424. width: 100%;
  425. height: 100%;
  426. position: absolute;
  427. background-image: radial-gradient(circle,
  428. rgb(255, 0, 0, 0),
  429. rgb(255, 0, 0, 0),
  430. rgb(255, 0, 0, 0),
  431. rgb(255, 0, 0));
  432. animation: fade 2000ms infinite;
  433. -webkit-animation: fade 2000ms infinite;
  434. z-index: 999;
  435. pointer-events: none;
  436. }
  437. @keyframes fade {
  438. from {
  439. opacity: 0.7;
  440. }
  441. 50% {
  442. opacity: 0.3;
  443. }
  444. to {
  445. opacity: 0.7;
  446. }
  447. }
  448. @-webkit-keyframes fade {
  449. from {
  450. opacity: 0.7;
  451. }
  452. 50% {
  453. opacity: 0.3;
  454. }
  455. to {
  456. opacity: 0.7;
  457. }
  458. }
  459. </style>
  460. <style lang="less">
  461. #app {
  462. .currentScroll::-webkit-scrollbar {
  463. width: 8px;
  464. height: 0px;
  465. background-color: black;
  466. }
  467. .currentScroll::-webkit-scrollbar-thumb {
  468. background-color: #999999;
  469. border-radius: 6px;
  470. }
  471. }
  472. ::-webkit-scrollbar {
  473. width: 8px !important;
  474. height: 8px !important;
  475. background-color: black !important;
  476. }
  477. ::-webkit-scrollbar-thumb {
  478. background-color: #999999 !important;
  479. border-radius: 6px !important;
  480. }
  481. .el-table--enable-row-hover .el-table__body tr:hover>td {
  482. color: rgba(37, 116, 219, 0.8) !important;
  483. }
  484. .el-table__body tr.current-row>td {
  485. color: rgba(37, 116, 219, 0.8) !important;
  486. }
  487. </style>