modeControl.vue 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568
  1. <template>
  2. <div class="body">
  3. <div class="control">
  4. <div :class="current===0?'smart_on':'smart'" @click="ChangeBar(0)">智能</div>
  5. <div :class="current===1?'recommend_on':'recommend'" @click="ChangeBar(1)">推荐</div>
  6. <div :class="current===2?'manual_on':'manual'" @click="ChangeBar(2)">手动</div>
  7. </div>
  8. <div style="display: flex;flex-direction: row;z-index: 2;">
  9. <div class="showData">
  10. <div class="dataBox" @dblclick="dbClicks(showDate.healthIndex,'健康指数')">
  11. <div class="dataTitle">健康指数</div>
  12. <div class="datas">{{showDate.healthIndex?.value.toFixed(0)}}</div>
  13. </div>
  14. <div class="dataBox" @dblclick="dbClicks(showDate.resourceIndex,'资源指数')">
  15. <div class="dataTitle">资源指数</div>
  16. <div class="datas">{{showDate.resourceIndex?.value.toFixed(0)}}</div>
  17. </div>
  18. </div>
  19. <div>
  20. <div id="mainEcharts" @dblclick="dbClick()" class="echarts"></div>
  21. <div class="powerContent">
  22. <div class="power" @dblclick="dbClicks(showDate.realTimePower,'实际功率')">
  23. <div class="powerTitle">实际功率</div>
  24. <div class="powerDatas" style="background-color: rgba(75, 85, 174, 1);">
  25. {{showDate.realTimePower?.value.toFixed(2)}}</div>
  26. </div>
  27. <div class="power1" @dblclick="dbClicks(showDate.theoreticalPower,'理论功率')">
  28. <div class="powerTitle">理论功率</div>
  29. <div class="powerDatas" style="background-color: rgba(05, 187, 76, 1);">
  30. {{showDate.theoreticalPower?.value.toFixed(2)}}</div>
  31. </div>
  32. <div class="power2" @dblclick="dbClicks(showDate.agcPowerSet,'AGC有功设定')">
  33. <div class="powerTitle">AGC有功设定</div>
  34. <div class="powerDatas" style="background-color: rgba(186, 50, 55, 1);">
  35. {{showDate.agcPowerSet?.value.toFixed(2)}}</div>
  36. </div>
  37. </div>
  38. </div>
  39. <div class="showData">
  40. <div class="dataBox-right" @dblclick="dbClicks(showDate.windEnergyRate,'风能利用率')">
  41. <div class="dataTitle">风能利用率</div>
  42. <div class="datas">{{showDate.windEnergyRate?.value.toFixed(2)}}%</div>
  43. </div>
  44. <div class="dataBox-right" @dblclick="dbClicks(showDate.curveFollowingRate,'曲线跟随率')">
  45. <div class="dataTitle">曲线跟随率</div>
  46. <div class="datas">{{showDate.curveFollowingRate?.value.toFixed(2)}}%</div>
  47. </div>
  48. </div>
  49. </div>
  50. </div>
  51. <DetailPages ref="detials" @closed="closed()" v-model="dialogVisible">
  52. </DetailPages>
  53. <Details @closed="closeds()" v-model="display" :partsName='partsName' echartsId="modelEcharts" :datas="modelDetails"
  54. @search-data="search" @original-data="originalData"></Details>
  55. </template>
  56. <script>
  57. import BackgroundData from 'utils/BackgroundData'
  58. import api from "api/index";
  59. import MessageBridge from 'utils/MessageBridge'
  60. import * as echarts from "echarts";
  61. import DetailPages from "./detailPages.vue";
  62. import Details from "../basicDataDetails.vue";
  63. export default {
  64. props: {
  65. // current: {
  66. // type: Number,
  67. // },
  68. },
  69. components: {
  70. DetailPages,
  71. Details
  72. },
  73. data() {
  74. return {
  75. current: 1,
  76. datas: {},
  77. list: {},
  78. showDate: {},
  79. winFlag: 0,
  80. curveFlag: 0,
  81. fieldFlag: 0,
  82. dialogVisible: false,
  83. display: false,
  84. modelDetails: [],
  85. partsName: '',
  86. modelData: {},
  87. interval: 60,
  88. };
  89. },
  90. created() {
  91. this.initData();
  92. },
  93. computed: {
  94. },
  95. mounted() {
  96. this.$nextTick(() => {
  97. if (document.getElementById('mainEcharts')) {
  98. this.getEcharts()
  99. }
  100. });
  101. },
  102. methods: {
  103. initData() {
  104. let mb = MessageBridge.getInstance();
  105. let vss = [{ key: "/topic/voice-control", action: this.windturbineMessage }];
  106. let vs = [{ key: "/topic/title-info", action: this.getEchartss }];
  107. mb.register(vs);
  108. mb.register(vss);
  109. },
  110. windturbineMessage(msg) {
  111. let arr = []
  112. if (msg === 'CLOSE') {
  113. arr.push(msg)
  114. } else {
  115. arr = msg.split('-')
  116. }
  117. this.dialogVisible = false
  118. this.showSvg = false
  119. this.svgWeb = ''
  120. console.log(arr);
  121. if (arr[0] === 'OPEN_PAGE_MANUAL') {
  122. this.ChangeBar(2)
  123. } else if (arr[0] === 'OPEN_PAGE_AUTOMATIC') {
  124. this.ChangeBar(0)
  125. } else if (arr[0] === 'OPEN_PAGE_RECOMMENDATION') {
  126. this.ChangeBar(1)
  127. } else if (msg === 'OPEN_AGC-GS') {
  128. this.dbClick()
  129. }
  130. },
  131. getEchartss(msg) {
  132. this.showDate = JSON.parse(msg)
  133. this.getEcharts()
  134. },
  135. getEcharts() {
  136. let chartDom = document.getElementById('mainEcharts');
  137. let myChart = echarts.init(chartDom, '#000000');
  138. let option;
  139. option = {
  140. series: [{
  141. type: 'gauge',
  142. max: 664,
  143. splitNumber: 8,
  144. anchor: {
  145. show: true,
  146. showAbove: true,
  147. size: 9,
  148. width: 5,
  149. itemStyle: {
  150. color: '#FAC858'
  151. }
  152. },
  153. pointer: {
  154. icon: '',
  155. width: 3,
  156. length: '80%',
  157. offsetCenter: [0, '8%']
  158. },
  159. progress: {
  160. show: true,
  161. overlap: true,
  162. roundCap: true
  163. },
  164. axisLine: {
  165. lineStyle: {//仪表盘轴线相关配置。
  166. width: 2,
  167. color: [[1, 'rgba(83, 92, 93, 0.5)']]
  168. }
  169. },
  170. axisLabel: {
  171. // textStyle: {//数字刻度样式
  172. // color: '#000000',
  173. // fontSize: 12,
  174. // }
  175. },
  176. splitLine: {//分隔线样式相关
  177. length: 0,//分割线的长度
  178. lineStyle: {
  179. width: 1,
  180. color: '#000000'
  181. }
  182. },
  183. data: [{
  184. value: 125.85,
  185. // name: '实际功率',
  186. itemStyle: {
  187. color: 'rgba(75, 85, 174, 1)'
  188. },
  189. // title: {
  190. // color: '#999999',
  191. // offsetCenter: ['-70%', '90%']
  192. // },
  193. // detail: {
  194. // width: 50,
  195. // height: 12,
  196. // fontSize: 18,
  197. // offsetCenter: ['-70%', '110%']
  198. // }
  199. },
  200. {
  201. value: 137.63,
  202. // name: '理论功率',
  203. itemStyle: {
  204. color: 'rgba(05, 187, 76, 1)'
  205. },
  206. // title: {
  207. // color: '#999999',
  208. // offsetCenter: ['0%', '90%']
  209. // },
  210. // detail: {
  211. // width: 50,
  212. // height: 12,
  213. // fontSize: 18,
  214. // offsetCenter: ['0%', '110%']
  215. // }
  216. },
  217. {
  218. value: 132.04,
  219. // name: 'AGC有功设定',
  220. itemStyle: {
  221. color: 'rgba(186, 50, 55, 1)'
  222. },
  223. // title: {
  224. // color: '#999999',
  225. // offsetCenter: ['70%', '90%']
  226. // },
  227. // detail: {
  228. // align: 'center',
  229. // width: 50,
  230. // height: 12,
  231. // fontSize: 18,
  232. // offsetCenter: ['70%', '110%']
  233. // }
  234. }
  235. ],
  236. title: false,
  237. detail: false,
  238. // title: {
  239. // fontSize: 12
  240. // },
  241. // detail: {
  242. // width: 20,
  243. // height: 7,
  244. // fontSize: 12,
  245. // color: '#fff',
  246. // backgroundColor: 'auto',
  247. // borderRadius: 3,
  248. // formatter: ''
  249. // }
  250. }]
  251. };
  252. option.series[0].data[0].value = Number(this.showDate.realTimePower?.value);
  253. option.series[0].data[1].value = Number(this.showDate.theoreticalPower?.value);
  254. option.series[0].data[2].value = Number(this.showDate.agcPowerSet?.value);
  255. myChart.setOption(option, true);
  256. },
  257. ChangeBar(values) {
  258. let bd = BackgroundData.getInstance();
  259. let mb = MessageBridge.getInstance();
  260. let vss = { key: "/topic/voice-control" };
  261. let popup = { key: "/topic/fault-popup" };
  262. mb.unregister(popup);
  263. mb.unregister(vss);
  264. this.$router.push(`/?current=${values}`)
  265. if (!bd.LoginUser) {
  266. this.$notify({
  267. title: "请登录",
  268. message: "切换模式需要先登录!",
  269. type: "warning",
  270. position: "bottom-right",
  271. offset: 60,
  272. duration: 3000,
  273. });
  274. return;
  275. }
  276. if (this.current !== values) {
  277. this.$store.commit('current', Number(values))
  278. if (values === 2) {
  279. this.current = values
  280. this.$router.push(`/ManualPage?current=${values}`)
  281. } else if (values === 1) {
  282. this.$store.commit('current', values)
  283. if (this.current === 0) {
  284. this.current = values
  285. } else {
  286. this.current = values
  287. this.$router.push(`/?current=${values}`)
  288. }
  289. } else if (values === 0) {
  290. this.$store.commit('current', values)
  291. if (this.current === 2) {
  292. this.current = values
  293. this.$router.push(`/?current=${values}`)
  294. } else {
  295. this.current = values
  296. }
  297. }
  298. }
  299. },
  300. dbClick() {
  301. this.dialogVisible = true;
  302. this.$refs.detials.getDate()
  303. },
  304. dbClicks(data, partsName, timeValues) {
  305. this.modelData = data
  306. let date = new Date()
  307. let endTs = timeValues ? (timeValues[1] > date.getTime()) ? date.getTime() : timeValues[1] : date.getTime();
  308. let startTs = timeValues ? timeValues[0] : endTs - 28800000;
  309. api.getPower({
  310. tagName: data.tag,
  311. startTs: startTs,
  312. endTs: endTs,
  313. interval: this.interval,
  314. }).then(res => {
  315. if (res.data.length > 0) {
  316. this.partsName = partsName
  317. this.display = true;
  318. this.modelDetails = res.data
  319. }
  320. })
  321. },
  322. original(data, partsName, timeValues) {
  323. this.modelData = data
  324. let date = new Date()
  325. let endTs = timeValues ? (timeValues[1] > date.getTime()) ? date.getTime() : timeValues[1] : date.getTime();
  326. let startTs = timeValues ? timeValues[0] : endTs - 28800000;
  327. api.getOriginalPower({
  328. tagName: data.tag,
  329. startTs: startTs,
  330. endTs: endTs,
  331. }).then(res => {
  332. if (res.data.length > 0) {
  333. this.partsName = partsName
  334. this.display = true;
  335. this.modelDetails = res.data
  336. }
  337. })
  338. },
  339. search(values,interval) {
  340. this.interval = interval
  341. this.dbClicks(this.modelData, this.partsName, values)
  342. },
  343. originalData(values) {
  344. this.original(this.modelData, this.partsName, values)
  345. },
  346. closed() {
  347. this.dialogVisible = false;
  348. },
  349. closeds() {
  350. this.display = false;
  351. this.interval = 60
  352. }
  353. },
  354. }
  355. </script>
  356. <style scoped>
  357. .body {
  358. width: 100%;
  359. height: 28.5vh;
  360. /* background-color: #ffffff; */
  361. margin-left: 15px;
  362. margin-top: 20px;
  363. border-left: 1px solid #373737;
  364. border-right: 1px solid #373737;
  365. border-bottom: 1px solid #373737;
  366. /* background-image: url('../../assets/img/type/background.png'); */
  367. background-repeat: no-repeat;
  368. background-position: center;
  369. background-size: cover;
  370. }
  371. .control {
  372. display: flex;
  373. flex-direction: row-reverse;
  374. align-items: center;
  375. font-size: 14px;
  376. color: #ffffff;
  377. /* margin-right: 5px; */
  378. position: absolute;
  379. right: 10px;
  380. z-index: 99;
  381. }
  382. .manual {
  383. display: flex;
  384. align-items: center;
  385. justify-content: center;
  386. height: 29px;
  387. width: 86px;
  388. border-left: 1px solid rgba(51, 51, 51, 1);
  389. border-top: 1px solid rgba(51, 51, 51, 1);
  390. border-bottom: 1px solid rgba(51, 51, 51, 1);
  391. border-top-left-radius: 15px;
  392. border-bottom-left-radius: 15px;
  393. }
  394. .manual_on {
  395. display: flex;
  396. align-items: center;
  397. justify-content: center;
  398. height: 29px;
  399. width: 86px;
  400. border-left: 1px solid rgba(37, 116, 219, 1);
  401. border-top: 1px solid rgba(37, 116, 219, 1);
  402. border-bottom: 1px solid rgba(37, 116, 219, 1);
  403. border-top-left-radius: 15px;
  404. border-bottom-left-radius: 15px;
  405. background-color: rgba(37, 116, 219, 1);
  406. }
  407. .recommend {
  408. display: flex;
  409. align-items: center;
  410. justify-content: center;
  411. height: 29px;
  412. width: 86px;
  413. border-top: 1px solid rgba(51, 51, 51, 1);
  414. border-bottom: 1px solid rgba(51, 51, 51, 1);
  415. }
  416. .recommend_on {
  417. display: flex;
  418. align-items: center;
  419. justify-content: center;
  420. height: 29px;
  421. width: 86px;
  422. border-top: 1px solid rgba(37, 116, 219, 1);
  423. border-bottom: 1px solid rgba(37, 116, 219, 1);
  424. background-color: rgba(37, 116, 219, 1);
  425. }
  426. .smart {
  427. display: flex;
  428. align-items: center;
  429. justify-content: center;
  430. height: 29px;
  431. width: 86px;
  432. border-right: 1px solid rgba(51, 51, 51, 1);
  433. border-top: 1px solid rgba(51, 51, 51, 1);
  434. border-bottom: 1px solid rgba(51, 51, 51, 1);
  435. border-top-right-radius: 15px;
  436. border-bottom-right-radius: 15px;
  437. }
  438. .smart_on {
  439. display: flex;
  440. align-items: center;
  441. justify-content: center;
  442. height: 29px;
  443. width: 86px;
  444. border-right: 1px solid rgba(37, 116, 219, 1);
  445. border-top: 1px solid rgba(37, 116, 219, 1);
  446. border-bottom: 1px solid rgba(37, 116, 219, 1);
  447. border-top-right-radius: 15px;
  448. border-bottom-right-radius: 15px;
  449. background-color: rgba(37, 116, 219, 1);
  450. }
  451. .echarts {
  452. width: 300px;
  453. height: 280px;
  454. margin-top: 10px;
  455. /* background-color: #000000; */
  456. margin-left: 10px;
  457. }
  458. .showData {
  459. display: flex;
  460. flex-direction: column;
  461. align-items: center;
  462. justify-content: center;
  463. }
  464. .dataBox {
  465. display: flex;
  466. flex-direction: column;
  467. width: 120px;
  468. height: 60px;
  469. border: 1px solid rgba(83, 92, 93, 1);
  470. margin-bottom: 15px;
  471. margin-top: 15px;
  472. margin-left: 30px;
  473. }
  474. .dataBox-right {
  475. display: flex;
  476. flex-direction: column;
  477. width: 120px;
  478. height: 60px;
  479. border: 1px solid rgba(83, 92, 93, 1);
  480. margin-bottom: 15px;
  481. margin-top: 15px;
  482. margin-right: 30px;
  483. }
  484. .dataTitle {
  485. height: 50%;
  486. display: flex;
  487. flex-direction: row;
  488. align-items: center;
  489. font-size: 12px;
  490. color: rgba(153, 162, 163, 1);
  491. margin-left: 5px;
  492. }
  493. .datas {
  494. height: 50%;
  495. display: flex;
  496. flex-direction: row-reverse;
  497. align-items: center;
  498. font-size: 16px;
  499. color: rgba(05, 187, 76, 1);
  500. margin-right: 5px;
  501. }
  502. .powerContent {
  503. display: flex;
  504. flex-direction: row;
  505. align-items: center;
  506. color: #ffffff;
  507. position: relative;
  508. bottom: 18%;
  509. left: 11%;
  510. }
  511. .power {
  512. display: flex;
  513. flex-direction: column;
  514. align-items: center;
  515. justify-content: center;
  516. font-size: 14px;
  517. padding: 5px 10px;
  518. }
  519. .power1 {
  520. display: flex;
  521. flex-direction: column;
  522. align-items: center;
  523. justify-content: center;
  524. font-size: 14px;
  525. padding: 5px 3px 5px 10px;
  526. }
  527. .power2 {
  528. display: flex;
  529. flex-direction: column;
  530. align-items: center;
  531. justify-content: center;
  532. font-size: 14px;
  533. padding: 5px 3px;
  534. }
  535. .powerTitle {
  536. margin-bottom: 3px;
  537. }
  538. .powerDatas {
  539. border-radius: 2px;
  540. display: flex;
  541. align-items: center;
  542. justify-content: center;
  543. font-size: 16px;
  544. font-weight: 600;
  545. padding: 2px 5px;
  546. }
  547. </style>