App.vue 13 KB

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