App.vue 26 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031
  1. <template>
  2. <div
  3. v-if="!showSisView"
  4. id="screen"
  5. :style="{
  6. width: `${style.width}px`,
  7. height: `${style.height}px`,
  8. transform: `${style.transform}`,
  9. }"
  10. >
  11. <div v-if="isLogined" class="main">
  12. <div class="header-body" v-if="hideHeard === '0'">
  13. <!-- <div class="header-title" @click="handleClickJump()"> -->
  14. <!-- <img v-if="$store.state.themeName === 'dark'" src="./assets/projectLogo.png" alt="" />
  15. <img v-if="$store.state.themeName === 'light'" src="./assets/light-projectLogo.png" alt="" /> -->
  16. <!-- <img src="./assets/logonx.png" alt="" /> -->
  17. <!-- <span
  18. :style="
  19. $store.state.themeName === 'dark'
  20. ? 'color:#fff; font-size:18px;font-family: SimHei'
  21. : 'color:#000'
  22. "
  23. >
  24. &gt;&gt;&nbsp;演示平台</span
  25. > -->
  26. <!-- </div> -->
  27. <div class="header-menu-body">
  28. <!-- <Header /> -->
  29. <tab-header />
  30. </div>
  31. </div>
  32. <div
  33. class="menu-body"
  34. :class="{ hover: isFixed ? true : isShowMenu }"
  35. @mouseenter="showMenu"
  36. @mouseleave="hideMenu"
  37. v-show="$store.state?.menuData?.length"
  38. >
  39. <Menu />
  40. </div>
  41. <!-- <div>
  42. <el-menu
  43. class="lightMenu"
  44. :class="$store.state.themeName === 'light' ? 'show' : 'hidden'"
  45. :collapse="true"
  46. text-color="#ffffff"
  47. active-text-color="#6262a2"
  48. background-color="#36348e"
  49. @select="selectMenu"
  50. v-if="hideMenus === '0' && $store.state.menuData.length"
  51. >
  52. <el-sub-menu
  53. :index="index"
  54. :title="item.text"
  55. v-for="(item, index) in menuData"
  56. :key="index"
  57. >
  58. <template #title>
  59. <router-link :to="item.path">
  60. <el-icon>
  61. <SvgIcon :svgid="item.icon" />
  62. </el-icon>
  63. </router-link>
  64. </template>
  65. <el-menu-item-group
  66. v-for="(menu, idx) in item.children"
  67. :index="idx"
  68. :key="idx"
  69. >
  70. <router-link :to="menu.path">
  71. <el-menu-item :index="index + '-' + idx">{{
  72. menu.text
  73. }}</el-menu-item>
  74. </router-link>
  75. </el-menu-item-group>
  76. </el-sub-menu>
  77. </el-menu>
  78. </div> -->
  79. <div
  80. class="main-body"
  81. :style="{ paddingLeft: isFixed && menuLength > 0 ? '52px' : 0 }"
  82. >
  83. <router-view />
  84. </div>
  85. <!-- <alarmBadge /> -->
  86. </div>
  87. <div v-else class="login"><login-page @onLogin="login" /></div>
  88. </div>
  89. </template>
  90. <script>
  91. import {
  92. alarm_history,
  93. fetchStationListAll,
  94. } from "@/api/zhbj/index.js";
  95. // 导入header.vue文件
  96. import alarmBadge from "@/components/alarm-badge/index.vue";
  97. import Menu from "@/views/layout/Menu.vue";
  98. import Header from "@/views/layout/Header.vue";
  99. import tabHeader from "@/views/layout/tabHeader.vue";
  100. import LoginPage from "./views/layout/login-page.vue";
  101. import { GetBoosterlist } from "@/api/factoryMonitor/index.js";
  102. import { getApiWeatherstation } from "@/api/monthlyPerformanceAnalysis";
  103. import { getAllStation } from "@/api/common.js";
  104. import SvgIcon from "@com/coms/icon/svg-icon.vue";
  105. import { GetDeviceTableData } from "@/api/zhbj/index.js";
  106. import { ElNotification } from "element-plus";
  107. import dayjs from "dayjs";
  108. import $ from "jquery";
  109. export default {
  110. components: {
  111. Menu,
  112. Header,
  113. tabHeader,
  114. LoginPage,
  115. alarmBadge,
  116. SvgIcon,
  117. },
  118. data() {
  119. return {
  120. isShowMenu: false,
  121. // 当前子系统
  122. root: "",
  123. // isLogined: localStorage.getItem("loginState") || false,
  124. showSisView: false,
  125. memuCloseTimeout: null,
  126. menuData: [],
  127. hideMenus: "0",
  128. hideHeard: "0",
  129. style: {
  130. width: "1920",
  131. height: "1080",
  132. fontsize: "16px",
  133. transform: "scaleY(1) scaleX(1) translate(-50%, -50%)",
  134. },
  135. alarmConfigArray: [],
  136. //请求参数
  137. requestAlarmHistoryParams: [
  138. {
  139. alarmType: "booststation",
  140. deviceType: "",
  141. },
  142. {
  143. alarmType: "inverter",
  144. deviceType: "",
  145. },
  146. {
  147. alarmType: "windturbine",
  148. deviceType: "",
  149. },
  150. {
  151. alarmType: "custom",
  152. deviceType: "inverter",
  153. },
  154. {
  155. alarmType: "custom",
  156. deviceType: "windturbine",
  157. },
  158. ],
  159. realList: [],
  160. dialogList: [],
  161. alarmList: []
  162. };
  163. },
  164. computed: {
  165. isLogined() {
  166. return this.$store.state.user?.loginState;
  167. },
  168. isFixed() {
  169. return this.$store.state?.isFixed;
  170. },
  171. menuLength() {
  172. return this.$store.state?.menuData?.length;
  173. },
  174. },
  175. async created() {
  176. await this.initWebSocket();
  177. this.getAlarmConfig();
  178. this.x = 80;
  179. this.y = 80;
  180. let requestResult = [];
  181. this.requestAlarmHistoryParams.forEach(({ alarmType, deviceType }) => {
  182. requestResult.push(this.getAlarmHistory(alarmType, deviceType));
  183. });
  184. Promise.all(requestResult)
  185. .then((promiseResult) => {
  186. this.alarmList = [];
  187. promiseResult.forEach(({ data }) => {
  188. data?.ls?.forEach((ele) => {
  189. this.pushALarmItem(ele);
  190. });
  191. });
  192. this.dialogList.sort((a, b) => {
  193. return b.ts - a.ts;
  194. });
  195. this.realList.sort((a, b) => {
  196. return b.ts - a.ts;
  197. });
  198. this.$store.commit("changeAlarmlist", this.alarmList);
  199. this.$store.commit("setWarning", this.dialogList);
  200. this.$store.commit("setWarningList", this.realList);
  201. // if (!this.socketLeaveFlag) {
  202. // // 没有离开——重连
  203. // // websocket重连
  204. // this.socketReconnect1();
  205. // }
  206. })
  207. .catch(() => {
  208. requestResult.forEach((ele, index) => {
  209. ele
  210. .then(({ data }) => {
  211. data?.ls?.forEach((ele) => {
  212. this.pushALarmItem(ele);
  213. });
  214. })
  215. .catch((error) => {
  216. ElNotification({
  217. type: "error",
  218. title: "查询历史未处理报警请求出错!",
  219. dangerouslyUseHTMLString: true,
  220. message: `<div class="currentRequestErrorNotification">
  221. <p><span>主要参数:</p>
  222. <p style="color:var(--el-color-primary)"><span class="errorTitle">alarmType:</span><span class="errorDesc">"${this.requestAlarmHistoryParams[index].alarmType}"</span></p>
  223. <p style="color:var(--el-color-primary)"><span class="errorTitle">deviceType:</span><span class="errorDesc">"${this.requestAlarmHistoryParams[index].deviceType}"</span></p>
  224. <p style="color:var(--el-color-danger)"><span class="errorTitle">错误正文:</span><span class="errorDesc">${error}</span></p>
  225. </div>`,
  226. });
  227. throw error;
  228. });
  229. });
  230. });
  231. },
  232. mounted() {
  233. let that = this;
  234. that.setScale();
  235. /*窗口改变事件*/
  236. $(window).resize(() => {
  237. that.setScale();
  238. });
  239. },
  240. unmounted() {
  241. console.log("离开标记", this.socketLeaveFlag);
  242. },
  243. methods: {
  244. //获取报警配置
  245. getAlarmConfig() {
  246. if (localStorage.getItem("alarmConfigArray")) {
  247. this.alarmConfigArray = JSON.parse(
  248. localStorage.getItem("alarmConfigArray")
  249. );
  250. } else {
  251. this.alarmConfigArray = [
  252. {
  253. id: "1",
  254. alarmLevel: 1,
  255. isAlart: false,
  256. isAlarmSound: false,
  257. isContinuousAlarm: false,
  258. },
  259. {
  260. id: "2",
  261. alarmLevel: 2,
  262. isAlart: false,
  263. isAlarmSound: false,
  264. isContinuousAlarm: false,
  265. },
  266. {
  267. id: "3",
  268. alarmLevel: 3,
  269. isAlart: false,
  270. isAlarmSound: false,
  271. isContinuousAlarm: false,
  272. },
  273. {
  274. id: "4",
  275. alarmLevel: 4,
  276. isAlart: true,
  277. isAlarmSound: true,
  278. isContinuousAlarm: false,
  279. },
  280. {
  281. id: "5",
  282. alarmLevel: 5,
  283. isAlart: true,
  284. isAlarmSound: true,
  285. isContinuousAlarm: true,
  286. },
  287. ];
  288. localStorage.setItem(
  289. "alarmConfigArray",
  290. JSON.stringify(this.alarmConfigArray)
  291. );
  292. }
  293. },
  294. //查历史报警
  295. getAlarmHistory(alarmType, deviceType) {
  296. let params = {
  297. pageNum: 1,
  298. pageSize: 50,
  299. alarmId: "",
  300. alarmType,
  301. deviceType,
  302. stationid: "",
  303. deviceid: "",
  304. modelId: "",
  305. components: "",
  306. description: "",
  307. isclose: false,
  308. // begin: dayjs().add(-1, "hour").format("YYYY-MM-DD HH:mm:ss"),
  309. // end: dayjs().format("YYYY-MM-DD HH:mm:ss"),
  310. begin: `${dayjs().add(-1, "hour").format("YYYY-MM-DD")} 00:00:00`,
  311. end: `${dayjs().format("YYYY-MM-DD")} 23:59:59`,
  312. };
  313. if (params.alarmType == "windturbine") {
  314. params.stationid = "";
  315. } else if (params.alarmType == "inverter") {
  316. params.stationid = "";
  317. }
  318. return alarm_history(params, 12000);
  319. },
  320. pushALarmItem(alarmItem, type) {
  321. const configItem = this.getConfigItem(alarmItem.rank);
  322. const alarmOption = {
  323. id: alarmItem.id ? alarmItem.id : alarmItem.tbname,
  324. lv: alarmItem.rank,
  325. modelId: alarmItem.modelId,
  326. lvName: this.getLvName(alarmItem),
  327. rank: alarmItem.rank,
  328. confirmed: alarmItem.confirmed,
  329. class: `animate__bounceInRight lv${alarmItem.rank}`,
  330. deviceId: alarmItem.deviceId,
  331. faultCause: alarmItem.faultCause,
  332. resolvent: alarmItem.resolvent,
  333. characteristic: alarmItem.characteristic,
  334. code: alarmItem.code,
  335. wpName: alarmItem.stationName
  336. ? alarmItem.stationName
  337. : alarmItem.wpName,
  338. stationId: alarmItem.stationId ? alarmItem.stationId : alarmItem.wpId,
  339. isClose: alarmItem.closeTime ? true : alarmItem.endts ? true : false,
  340. isCloseName: alarmItem.closeTime
  341. ? "已解除"
  342. : alarmItem.endts
  343. ? "已解除"
  344. : "未解除",
  345. alarmId: alarmItem.alarmId,
  346. alarmType: alarmItem.alarmType,
  347. alarmName: this.getAlarmName(alarmItem),
  348. description: alarmItem.description,
  349. deviceType: alarmItem.deviceType,
  350. oval: alarmItem.oval,
  351. triggerType: alarmItem.triggerType,
  352. ts: alarmItem.ts
  353. ? dayjs(alarmItem.ts).valueOf()
  354. : dayjs(alarmItem.updateTime).valueOf(),
  355. endts: alarmItem.endts
  356. ? dayjs(alarmItem.endts).format("YYYY-MM-DD HH:mm:ss")
  357. : null,
  358. closeTime: alarmItem.closeTime
  359. ? dayjs(alarmItem.closeTime).format("YYYY-MM-DD HH:mm:ss")
  360. : null,
  361. deviceName: alarmItem.deviceName
  362. ? alarmItem.deviceName
  363. : alarmItem.code,
  364. tsName: alarmItem.ts
  365. ? new Date(alarmItem.ts).formatDate("MM-dd hh:mm:ss")
  366. : new Date(alarmItem.updateTime).formatDate("MM-dd hh:mm:ss"),
  367. fullTsName: alarmItem.ts
  368. ? new Date(alarmItem.ts).formatDate("yyyy-MM-dd hh:mm:ss")
  369. : new Date(alarmItem.updateTime).formatDate("yyyy-MM-dd hh:mm:ss"),
  370. };
  371. if (
  372. alarmOption.alarmType == "booststation" &&
  373. alarmOption.deviceType != "custom"
  374. ) {
  375. if (
  376. configItem.isAlarmSound ||
  377. configItem.isAlart ||
  378. configItem.isContinuousAlarm
  379. ) {
  380. let a = {};
  381. a[`${alarmOption.stationId}`] =
  382. alarmOption.closeTime || alarmOption.confirmed ? false : true;
  383. this.alarmList.push(a);
  384. this.alarmList = [
  385. ...new Set(this.alarmList.map((t) => JSON.stringify(t))),
  386. ].map((s) => JSON.parse(s));
  387. }
  388. }
  389. if (
  390. configItem.isAlarmSound ||
  391. configItem.isAlart ||
  392. configItem.isContinuousAlarm
  393. ) {
  394. if (type && type == "ws") {
  395. this.dialogList.unshift(alarmOption);
  396. } else {
  397. this.dialogList.push(alarmOption);
  398. }
  399. }
  400. if (type && type == "ws") {
  401. this.realList.unshift(alarmOption);
  402. } else {
  403. this.realList.push(alarmOption);
  404. }
  405. // && alarmOption.deviceType != "custom"
  406. this.playAudioEffect();
  407. },
  408. getAlarmName(alarmItem) {
  409. let alarmName = "";
  410. if (alarmItem.deviceType === "booststation") {
  411. alarmName = "升压站报警";
  412. } else if (alarmItem.deviceType === "inverter") {
  413. alarmName = "光伏报警";
  414. } else if (alarmItem.deviceType === "windturbine") {
  415. alarmName = "设备报警";
  416. } else if (alarmItem.deviceType === "station") {
  417. alarmName = "场站";
  418. }
  419. if (alarmItem.alarmType === "custom") {
  420. alarmName = "自定义报警";
  421. }
  422. return alarmName;
  423. },
  424. getLvName(alarmItem) {
  425. if (alarmItem.rank === 1) {
  426. return "低级";
  427. } else if (alarmItem.rank === 2) {
  428. return "低中级";
  429. } else if (alarmItem.rank === 3) {
  430. return "中级";
  431. } else if (alarmItem.rank === 4) {
  432. return "中高级";
  433. } else if (alarmItem.rank === 5) {
  434. return "高级";
  435. }
  436. },
  437. playAudioEffect() {
  438. const lv1Config = this.getConfigItem(1);
  439. let lv1Play = false;
  440. if (lv1Config.isAlarmSound) {
  441. lv1Play = this.dialogList.some((ele) => {
  442. return ele.lv === 1 && !ele.confirm;
  443. });
  444. }
  445. const lv2Config = this.getConfigItem(2);
  446. let lv2Play = false;
  447. if (lv2Config.isAlarmSound) {
  448. lv2Play = this.dialogList.some((ele) => {
  449. return ele.lv === 2 && !ele.confirm;
  450. });
  451. }
  452. const lv3Config = this.getConfigItem(3);
  453. let lv3Play = false;
  454. if (lv3Config.isAlarmSound) {
  455. lv3Play = this.dialogList.some((ele) => {
  456. return ele.lv === 3 && !ele.confirm;
  457. });
  458. }
  459. const lv4Config = this.getConfigItem(4);
  460. let lv4Play = false;
  461. if (lv4Config.isAlarmSound) {
  462. lv4Play = this.dialogList.some((ele) => {
  463. return ele.lv === 4 && !ele.confirm;
  464. });
  465. }
  466. const lv5Config = this.getConfigItem(5);
  467. let lv5Play = false;
  468. if (lv5Config.isAlarmSound) {
  469. lv5Play = this.dialogList.some((ele) => {
  470. return ele.lv === 5 && !ele.confirm;
  471. });
  472. }
  473. // console.log(lv1Play, lv2Play, lv3Play, lv4Play, lv5Play);
  474. if (lv5Play && !this.seriousWarning) {
  475. this.seriousWarning = true;
  476. this.audioElement = new Audio();
  477. this.audioElement.src = "./static/sound/lv5.mp3";
  478. this.audioElement.loop = true;
  479. false && this.audioElement?.play();
  480. } else if (
  481. (lv1Play || lv2Play || lv3Play || lv4Play) &&
  482. !this.seriousWarning
  483. ) {
  484. this.audioElement = new Audio();
  485. this.audioElement.src = "./static/sound/lv4.mp3";
  486. this.audioElement.addEventListener("ended", () => {
  487. this.audioElement?.removeEventListener(
  488. "ended",
  489. this.stopPlayAudioEffect
  490. );
  491. });
  492. false && this.audioElement?.play();
  493. } else {
  494. if (!this.seriousWarning) {
  495. this.stopPlayAudioEffect();
  496. }
  497. }
  498. },
  499. getConfigItem(lv) {
  500. return (
  501. this.alarmConfigArray.find((ele) => {
  502. return ele.alarmLevel === lv;
  503. }) || {}
  504. );
  505. },
  506. stopPlayAudioEffect() {
  507. this.seriousWarning = false;
  508. if (this.audioElement) {
  509. this.audioElement.pause();
  510. this.audioElement.currentTime = 0;
  511. this.audioElement.loop = false;
  512. }
  513. this.audioElement = null;
  514. },
  515. async initWebSocket() {
  516. this.$ws.initWebSocket();
  517. },
  518. getScale() {
  519. const w = window.innerWidth / this.style.width;
  520. const h = window.innerHeight / this.style.height;
  521. const d = window.devicePixelRatio;
  522. // let f = 16;
  523. // if (d > 1) {
  524. // f = 18;
  525. // }
  526. return { x: w, y: h };
  527. },
  528. setScale() {
  529. let scale = this.getScale();
  530. this.style.transform =
  531. "scaleY(" + scale.y + ") scaleX(" + scale.x + ") translate(-50%, -50%)";
  532. },
  533. // 切换子系统事件
  534. HeaderMenuClick(data) {
  535. this.root = data.id;
  536. },
  537. showMenu() {
  538. if (!this.isFixed) {
  539. this.isShowMenu = true;
  540. clearTimeout(this.memuCloseTimeout);
  541. this.memuCloseTimeout = null;
  542. }
  543. },
  544. hideMenu() {
  545. if (!this.isFixed) {
  546. this.memuCloseTimeout = setTimeout(() => {
  547. this.isShowMenu = false;
  548. }, 500);
  549. }
  550. },
  551. getBooster() {
  552. // GetBoosterlist().then((res) => {
  553. // if (res.data && res.data.code == 200) {
  554. // this.$store.commit("changeBooster", res.data.data);
  555. // }
  556. // });
  557. },
  558. // 获取测风塔
  559. async getCftlist() {
  560. // const { data: datas } = await getApiWeatherstation();
  561. // this.$store.commit("changeCft", datas.data);
  562. },
  563. // 获取全部场站(不分风电光伏)
  564. async getAllStation() {
  565. const { data: datas } = await getAllStation();
  566. if (datas) {
  567. this.$store.commit("changeStationAll", datas);
  568. } else {
  569. this.$store.commit("changeStationAll", []);
  570. }
  571. },
  572. login() {
  573. this.$store.commit("user/SET_LOGINSTATE", true);
  574. },
  575. },
  576. watch: {
  577. "$store.state.menuData"(res) {
  578. this.menuData = res || [];
  579. },
  580. isLogined: {
  581. handler(res) {
  582. if (!res && this.socketObj) {
  583. // 离开标记
  584. this.socketLeaveFlag = true;
  585. // 关闭WebSocket
  586. this.socketObj.close();
  587. }
  588. if (res) {
  589. this.getBooster();
  590. this.getCftlist();
  591. this.getAllStation();
  592. }
  593. },
  594. immediate: true,
  595. },
  596. "$store.state.moudleName"(msg) {
  597. if (window.__MODE__.showModuleName && msg) {
  598. this.BASE.showMsg({
  599. type: this.$store.state.themeName === "dark" ? "success" : "warning",
  600. showClose: true,
  601. msg,
  602. });
  603. }
  604. },
  605. },
  606. };
  607. </script>
  608. <style lang="less">
  609. @import "~@/assets/styles/main.less";
  610. #screen {
  611. z-index: 100;
  612. transform-origin: 0 0;
  613. position: fixed;
  614. left: 50%;
  615. top: 50%;
  616. transition: 0.3s;
  617. }
  618. .alarmDeligo {
  619. z-index: 2003;
  620. position: relative;
  621. img {
  622. width: 43px;
  623. max-width: 43px;
  624. height: 43px;
  625. z-index: 3;
  626. }
  627. img:first-child {
  628. width: 53px;
  629. height: 57px;
  630. max-width: 53px;
  631. top: -7px;
  632. left: -5px;
  633. position: absolute;
  634. z-index: 3;
  635. }
  636. }
  637. * {
  638. box-sizing: border-box;
  639. &::-webkit-scrollbar {
  640. width: 6px;
  641. height: 8px;
  642. }
  643. &::-webkit-scrollbar-track-piece {
  644. background-color: rgba(255, 255, 255, 0.05);
  645. border-radius: 4px;
  646. }
  647. &::-webkit-scrollbar-thumb {
  648. background-color: fade(@gray, 75);
  649. border-radius: 4px;
  650. outline: none;
  651. outline-offset: 0px;
  652. border: none;
  653. }
  654. }
  655. body {
  656. margin: 0;
  657. background: #fff;
  658. color: #fff;
  659. // background-image: url("./assets/background.png");
  660. background: rgb(4, 12, 11);
  661. background-size: cover;
  662. font-size: @fontsize;
  663. font-family: @defalut-font-family;
  664. }
  665. @menuWidth: 51.28px;
  666. @headerHeight: 39px;
  667. .main {
  668. width: 100%;
  669. height: 100%;
  670. display: flex;
  671. flex-wrap: wrap;
  672. overflow: hidden;
  673. .header-body {
  674. z-index: 2;
  675. // background: radial-gradient(closest-corner at 22% 40%, #2d5a47, #040d0a, #040d0a);
  676. // flex: 0 0 100%;
  677. width: 100%;
  678. display: flex;
  679. flex-direction: row;
  680. height: @headerHeight;
  681. border-bottom: 1px solid #142b29;
  682. .header-title {
  683. padding-left: 20px;
  684. margin: auto;
  685. color: #fff;
  686. }
  687. .header-menu-body {
  688. flex-grow: 1;
  689. }
  690. }
  691. .menu-body {
  692. position: absolute;
  693. display: flex;
  694. flex-direction: column;
  695. align-items: center;
  696. justify-content: space-between;
  697. flex: 0 0 @menuWidth;
  698. width: @menuWidth;
  699. height: calc(100% - @headerHeight);
  700. // height: calc(100vh - 59px);
  701. top: @headerHeight;
  702. // top: 59px;
  703. background-color: fade(#192a26, 75%);
  704. z-index: 2002;
  705. opacity: 0;
  706. transition: opacity 0.2s;
  707. transition-timing-function: ease-in;
  708. // transform: translate(-@menuWidth);
  709. &:hover,
  710. &.hover {
  711. opacity: 1;
  712. transition: opacity 0.2s;
  713. transition-timing-function: ease-out;
  714. transform: translate(0);
  715. }
  716. }
  717. .main-body {
  718. flex: 0 0 100%;
  719. max-width: 100%;
  720. height: calc(100% - @headerHeight);
  721. // padding: 1.481vh;
  722. // transition: flex 0.1s, margin-left 0.1s;
  723. // transition-timing-function: ease-in-out;
  724. // &.show-menu {
  725. // flex: 0 0 calc(100vw - @menuWidth);
  726. // margin-left: @menuWidth;
  727. // transition: flex 0.1s, margin-left 0.1s;
  728. // transition-timing-function: ease-in-out;
  729. // }
  730. }
  731. .el-table__body tr.current-row > td {
  732. color: #fff;
  733. background: rgba(66, 66, 66, 0.66) !important;
  734. }
  735. .el-transfer-panel {
  736. width: 450px !important;
  737. height: 73vh;
  738. background-color: #111d1c !important;
  739. border: 1px solid #999999 !important;
  740. .el-transfer-panel__body {
  741. height: 100% !important;
  742. .el-transfer-panel__list {
  743. height: 100% !important;
  744. }
  745. }
  746. }
  747. .el-transfer-panel .el-transfer-panel__header {
  748. background-color: #111d1c !important;
  749. color: #05bb4c !important;
  750. .el-checkbox .el-checkbox__label {
  751. color: #05bb4c !important;
  752. }
  753. }
  754. .el-button--primary.is-disabled,
  755. .el-button--primary.is-disabled:active,
  756. .el-button--primary.is-disabled:focus,
  757. .el-button--primary.is-disabled:hover {
  758. background-color: #05bb4c;
  759. border-color: #05bb4c;
  760. }
  761. }
  762. .login {
  763. width: 100%;
  764. height: 100%;
  765. background: url("~@/assets/login-bg.png") no-repeat;
  766. background-size: cover;
  767. position: relative;
  768. }
  769. .el-badge {
  770. &.active {
  771. .el-badge__content--danger {
  772. opacity: 0 !important;
  773. }
  774. }
  775. }
  776. .el-badge__content--danger {
  777. background: #ff4e00 !important;
  778. border: none !important;
  779. }
  780. .el-badge__content.is-fixed {
  781. top: 7px !important;
  782. right: 14px !important;
  783. z-index: 2003 !important;
  784. }
  785. .trans {
  786. animation: circleProgess 3s linear infinite;
  787. }
  788. @keyframes circleProgess {
  789. 0% {
  790. transform: rotateZ(360deg);
  791. }
  792. 25% {
  793. transform: rotateZ(270deg);
  794. }
  795. 50% {
  796. transform: rotateZ(180deg);
  797. }
  798. 75% {
  799. transform: rotateZ(90deg);
  800. }
  801. 100% {
  802. transform: rotateZ(0deg);
  803. }
  804. }
  805. .el-tree-node__content {
  806. height: 40px !important;
  807. }
  808. .el-tree-node__label {
  809. font-size: 14px !important;
  810. }
  811. .el-pagination.is-background .el-pager li:not(.disabled).active {
  812. background-color: #05bb4c !important;
  813. }
  814. .el-table__body tr.hover-row > td.el-table__cell {
  815. background-color: rgba(2, 2, 2) !important;
  816. }
  817. #appBody.light .el-table th.el-table__cell > .cell {
  818. height: 8.2vh !important;
  819. }
  820. .power-benchmarking-page
  821. .top
  822. .top-left
  823. .table.el-table
  824. thead
  825. tr:last-child
  826. th
  827. .cell {
  828. height: 116px !important;
  829. }
  830. * {
  831. -webkit-touch-callout: none; /*系统默认菜单被禁用*/
  832. -webkit-user-select: none; /*webkit浏览器*/
  833. -khtml-user-select: none; /*早期浏览器*/
  834. -moz-user-select: none; /*火狐*/
  835. -ms-user-select: none; /*IE10*/
  836. user-select: none;
  837. }
  838. input {
  839. -webkit-user-select: auto; /*webkit浏览器*/
  840. }
  841. textarea {
  842. -webkit-user-select: auto; /*webkit浏览器*/
  843. }
  844. .gfSelect .el-input__suffix {
  845. display: none !important;
  846. }
  847. body .gfSelect .el-input__inner {
  848. background: rgba(83, 98, 104, 0);
  849. color: #ffffff;
  850. font-size: 16px;
  851. }
  852. .main-body {
  853. .query {
  854. display: flex;
  855. // justify-content: space-between;
  856. &.left {
  857. justify-content: flex-start;
  858. }
  859. .query-items {
  860. flex: 0 0 auto;
  861. display: flex;
  862. .query-item {
  863. flex: 0 0 auto;
  864. display: flex;
  865. margin: 0 1.4815vh;
  866. .el-input {
  867. &.placeholder-left {
  868. input {
  869. &::placeholder {
  870. text-align: left;
  871. }
  872. }
  873. }
  874. }
  875. .placeholder-left {
  876. .el-input {
  877. input {
  878. height: 33px !important;
  879. &::placeholder {
  880. text-align: left;
  881. }
  882. }
  883. }
  884. }
  885. .lable {
  886. flex: 0 0 auto;
  887. margin-right: 1.4815vh;
  888. line-height: 33px;
  889. color: @gray-l;
  890. }
  891. .search-input {
  892. position: relative;
  893. // input {
  894. // box-sizing: border-box;
  895. // flex: 0 0 200px;
  896. // border: 0px solid @darkgray;
  897. // color: @white;
  898. // outline: unset;
  899. // border-radius: 0%;
  900. // padding-right: 40px;
  901. // background: fade(#536268, 20);
  902. // height: 33px;
  903. // line-height: 33px;
  904. // &::placeholder {
  905. // font-size: 12px;
  906. // text-align: right;
  907. // color: @darkgray;
  908. // }
  909. // }
  910. // .unit {
  911. // position: absolute;
  912. // right: 12px;
  913. // top: 6px;
  914. // line-height: 33px;
  915. // margin: auto;
  916. // }
  917. }
  918. }
  919. }
  920. .query-actions {
  921. flex: 0 0 auto;
  922. margin-left: 50px;
  923. display: flex;
  924. justify-content: flex-start;
  925. align-items: center;
  926. .btn {
  927. cursor: pointer;
  928. }
  929. }
  930. }
  931. input {
  932. box-sizing: border-box;
  933. flex: 0 0 200px;
  934. border: 0px solid @darkgray;
  935. color: @white;
  936. outline: unset;
  937. border-radius: 0%;
  938. padding-right: 40px;
  939. background: fade(#536268, 20);
  940. height: 33px;
  941. line-height: 33px;
  942. &::placeholder {
  943. font-size: 12px;
  944. text-align: right;
  945. color: @darkgray;
  946. }
  947. }
  948. input[type="checkbox"] {
  949. position: relative;
  950. display: inline-block;
  951. appearance: none;
  952. width: 14px;
  953. height: 14px;
  954. outline: none;
  955. border: 1px solid @gray;
  956. background-color: #000;
  957. border-radius: 20%;
  958. margin: 0;
  959. padding: 0;
  960. &:checked {
  961. border-color: @green;
  962. background: @green;
  963. }
  964. &::after {
  965. display: inline-block;
  966. content: " ";
  967. position: absolute;
  968. left: 30%;
  969. top: 5%;
  970. width: 3px;
  971. height: 7px;
  972. border-color: #fff;
  973. border-style: solid;
  974. border-width: 0px 2px 2px 0px;
  975. transform: rotate(45deg);
  976. opacity: 0;
  977. }
  978. &:checked::after {
  979. content: "";
  980. opacity: 1;
  981. transition: opacity 0.3s ease-out;
  982. }
  983. }
  984. }
  985. </style>