index.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581
  1. <template>
  2. <section class="mainbox">
  3. <!-- topBox start -->
  4. <div class="topBox">
  5. <div class="column statisSec">
  6. <statis-top
  7. :falarmCount="alarmCount"
  8. :fpersonalCount="personalCount"
  9. :fsiteCount="siteCount"
  10. :fepLoad="epLoad"
  11. ></statis-top>
  12. <statis-bottom :fhtAnalogData="htAnalogData"></statis-bottom>
  13. </div>
  14. <div class="column mapBox" style="position: relative">
  15. <map-static-top :fsiteCount="siteCount"></map-static-top>
  16. <div id="pickerBox">
  17. <input
  18. id="pickerInput"
  19. placeholder="输入关键字选取站点"
  20. v-model="name"
  21. @keyup.enter="siteList_api({ name: this.name })"
  22. />
  23. <i
  24. class="el-icon-search"
  25. @click="siteList_api({ name: this.name })"
  26. ></i>
  27. <div id="poiInfo"></div>
  28. </div>
  29. <div class="panel-footer"></div>
  30. <div
  31. class="map panel"
  32. id="mapF"
  33. style="height: 100%; z-index: 1; width: 100%"
  34. ></div>
  35. </div>
  36. <div class="column">
  37. <div class="panel deviceSum">
  38. <h2>设备运行状态</h2>
  39. <div class="filterSec" style="top: 0.7rem">
  40. <el-date-picker
  41. v-model="dDefaultTime"
  42. type="datetimerange"
  43. range-separator="~"
  44. start-placeholder="开始日期"
  45. end-placeholder="结束日期"
  46. @change="deviceTypeCount_api()"
  47. >
  48. </el-date-picker>
  49. </div>
  50. <pie-chart
  51. :fdeviceTypeCount="deviceTypeCount"
  52. v-if="this.deviceTypeCount"
  53. ></pie-chart>
  54. <div class="panel-footer"></div>
  55. </div>
  56. <div class="panel line1 operStatus">
  57. <h2>负载率</h2>
  58. <triangle-chart
  59. :frtAnalogData="rtAnalogData"
  60. v-if="this.rtAnalogData.heavyLoad"
  61. ></triangle-chart>
  62. <div class="panel-footer"></div>
  63. </div>
  64. </div>
  65. </div>
  66. <!-- topBox end -->
  67. <!-- bottomBox start -->
  68. <div class="bottomBox">
  69. <div class="column">
  70. <div class="panel currentUsage" style="height: 100%">
  71. <h2>总能耗</h2>
  72. <div class="filterSec">
  73. <select name="" id="" v-model="dayType">
  74. <option value="0">当日用量趋势</option>
  75. <option value="1">当月用量趋势</option>
  76. </select>
  77. <!-- <img src="../../assets/images/markIcon.png" alt=""> -->
  78. </div>
  79. <bar-chart
  80. :feptrendIco="eptrendIco"
  81. v-if="this.eptrendIco[0]"
  82. ></bar-chart>
  83. <div class="panel-footer"></div>
  84. </div>
  85. </div>
  86. <div class="column">
  87. <div class="panel currentUsage" style="height: 100%">
  88. <h2>运维管理</h2>
  89. <div class="filterSec">
  90. <el-date-picker
  91. v-model="fDefaultTime"
  92. type="datetimerange"
  93. range-separator="~"
  94. start-placeholder="开始日期"
  95. end-placeholder="结束日期"
  96. @change="trendIcoCount_api()"
  97. >
  98. </el-date-picker>
  99. </div>
  100. <line-chart
  101. :ftrendIcoCount="trendIcoCount"
  102. v-if="this.trendIcoCount[0]"
  103. ></line-chart>
  104. <div class="panel-footer"></div>
  105. </div>
  106. </div>
  107. </div>
  108. <!-- bottomBox end -->
  109. </section>
  110. </template>
  111. <script>
  112. import statisTop from "./components/statisTop";
  113. import statisBottom from "./components/statisBottom";
  114. import pieChart from "./components/pieChart";
  115. import barChart from "./components/barChart";
  116. import lineChart from "./components/lineChart";
  117. import mapStaticTop from "./components/mapStaticTop";
  118. import triangleChart from "./components/triangleChart";
  119. import markIconPath from "../../assets/images/markIcon.png";
  120. import mapData from "../../assets/js/map-data.js";
  121. mapData;
  122. // 地图
  123. import AMap from "AMap";
  124. // import AMapUI from "AMapUI";
  125. import api from "@/api/home/home.js";
  126. export default {
  127. name: "index",
  128. components: {
  129. statisTop,
  130. statisBottom,
  131. pieChart,
  132. barChart,
  133. lineChart,
  134. mapStaticTop,
  135. triangleChart,
  136. },
  137. data() {
  138. return {
  139. dDefaultTime: this.$store.state.se_defaultTime,
  140. // fDefaultTime: [
  141. // new Date("2021-6-23 00:00:00"),
  142. // new Date("2021-7-12 00:00:00"),
  143. // ],
  144. fDefaultTime: this.$store.state.th_defaultTime,
  145. map: null,
  146. alarmCount: {},
  147. personalCount: {},
  148. siteCount: {},
  149. deviceTypeCount: {},
  150. trendIcoCount: [],
  151. rtAnalogData: {},
  152. htAnalogData: {},
  153. dayType: 1,
  154. eptrendIco: {},
  155. eptrendIcoMonth: {},
  156. epLoad: "",
  157. siteOne: {},
  158. name: "",
  159. mapPolList: [],
  160. colorList: [
  161. ["#99e", "#F33"],
  162. ["#ee6", "#c38"],
  163. ["#c38", "#F33"],
  164. ["#6E7", "#F33"],
  165. ["#6A7", "#F33"],
  166. ["#EF7", "#F33"],
  167. ["#AF7", "#F33"],
  168. ["#BAC", "#F33"],
  169. ["#BEF", "#F33"],
  170. ["#BBB", "#F33"],
  171. ["#EFA", "#F33"],
  172. ["#FE6", "#F33"],
  173. ["#7F6", "#F33"],
  174. ["#7dc", "#F33"],
  175. ],
  176. colorIndList: [-1, 7, 21, 26, 31, 37, 46, 52, 57, 66, 68, 71, 74, 100],
  177. };
  178. },
  179. watch: {
  180. dayType(val) {
  181. if (val == 0) {
  182. this.eptrendIco_api();
  183. } else {
  184. this.eptrendIcoMonth_api();
  185. }
  186. },
  187. },
  188. created() {},
  189. mounted() {
  190. this.alarmCount_api();
  191. this.personalCount_api();
  192. this.epLoad_api();
  193. this.siteCount_api();
  194. this.deviceTypeCount_api();
  195. this.trendIcoCount_api();
  196. this.rtAnalogData_api();
  197. this.siteList_api();
  198. this.htAnalogData_api();
  199. // this.eptrendIco_api();
  200. this.eptrendIcoMonth_api();
  201. },
  202. methods: {
  203. // searchSite(){
  204. // this.siteList_api({"name":this.name});
  205. // },
  206. //告警总数数据对接
  207. alarmCount_api() {
  208. api.alarmCount_api().then((requset) => {
  209. this.alarmCount = requset.data;
  210. });
  211. },
  212. //运维人员
  213. personalCount_api() {
  214. api.personalCount_api().then((requset) => {
  215. this.personalCount = requset.data;
  216. });
  217. },
  218. //总实时负荷
  219. epLoad_api() {
  220. api.epLoad_api().then((requset) => {
  221. this.epLoad = requset.data;
  222. });
  223. },
  224. //站点总数
  225. siteCount_api() {
  226. api.siteCount_api().then((requset) => {
  227. this.siteCount = requset.data;
  228. });
  229. },
  230. //设备数量echarts饼图
  231. deviceTypeCount_api() {
  232. var _this = this;
  233. _this.$store.commit("TimeAll_function", this.dDefaultTime);
  234. var time = _this.$store.state.Time_Data;
  235. api
  236. .deviceTypeCount_api({
  237. startTime: time[0],
  238. endTime: time[1],
  239. })
  240. .then((requset) => {
  241. this.deviceTypeCount = requset.data;
  242. });
  243. },
  244. //故障抢修echarts折线图
  245. trendIcoCount_api() {
  246. var _this = this;
  247. _this.$store.commit("TimeAll_function", this.fDefaultTime);
  248. var time = _this.$store.state.Time_Data;
  249. api
  250. .trendIco_api({
  251. startTime: time[0],
  252. endTime: time[1],
  253. })
  254. .then((requset) => {
  255. this.$store.state.trendIcoCount = requset.data;
  256. this.trendIcoCount = requset.data;
  257. });
  258. },
  259. //重载运行echarts锥形图
  260. rtAnalogData_api() {
  261. api.rtAnalogData_api().then((requset) => {
  262. this.rtAnalogData = requset.data;
  263. });
  264. },
  265. //地图撒点
  266. siteList_api(query = {}) {
  267. api.siteList_api(query).then((requset) => {
  268. this.siteList = requset.data;
  269. this.initMap();
  270. });
  271. },
  272. //地图撒点
  273. // 日月年用电量
  274. htAnalogData_api() {
  275. api.htAnalogData_api().then((requset) => {
  276. this.htAnalogData = requset.data;
  277. });
  278. },
  279. // 今日昨日用电量趋势
  280. eptrendIco_api() {
  281. api.eptrendIco_api().then((requset) => {
  282. this.eptrendIco = requset.data;
  283. // console.log("this.eptrendIco");
  284. // console.log(this.eptrendIco[0].name);
  285. });
  286. },
  287. // 今日昨日用电量趋势
  288. eptrendIcoMonth_api() {
  289. api.eptrendIcoMonth_api().then((requset) => {
  290. this.eptrendIco = requset.data;
  291. // console.log("this.eptrendIco");
  292. // console.log(this.eptrendIco);
  293. });
  294. },
  295. Overview() {
  296. // this.$router.push({ path: "/Overview" }); //, query: { title: title }
  297. },
  298. async initMap() {
  299. this.map = await new AMap.Map("mapF", {
  300. mapStyle: "amap://styles/blue", //设置地图的显示样式
  301. resizeEnable: true,
  302. zoom: 13,
  303. zooms: [3, 16],
  304. // features: [] //清空背景道路等
  305. });
  306. // this.initMapUi();
  307. var con = `<div class="siteModelBox" >
  308. <h2>
  309. {siteName}
  310. </h2>
  311. <div >
  312. <div class="siteDetailInfo" >
  313. <div class="infoLine">
  314. <span>站点状态:</span>
  315. <p>{status}</p>
  316. </div>
  317. <div class="infoLine">
  318. <span>设备总数:</span>
  319. <p>{deviceCount}</p >
  320. </div>
  321. <div class="infoLine">
  322. <span>告警数:</span>
  323. <p>{alarmPowerCount}</p >
  324. </div>
  325. <div class="infoLine">
  326. <span>监控类型:</span>
  327. <p>{deviceType}</p >
  328. </div>
  329. <div class="infoLine">
  330. <span>电话:</span>
  331. <p>{phone}</p >
  332. </div>
  333. <div class="infoLine">
  334. <span>地址:</span>
  335. <p>{siteAddress}</p >
  336. </div>
  337. </div>
  338. </div>
  339. </div>`;
  340. var dataList = this.siteList;
  341. dataList.forEach(function (item) {
  342. let conNew = con;
  343. // console.log(item.siteAddress);
  344. conNew = conNew.replace(/{siteAddress}/g, item.siteAddress);
  345. conNew = conNew.replace(/{phone}/g, item.phone);
  346. conNew = conNew.replace(/{siteName}/g, item.siteName);
  347. item.content = conNew;
  348. });
  349. this.addMarker(dataList, "water");
  350. },
  351. addMarker(lnglats) {
  352. // 创建标点和点击事件
  353. let markers = lnglats.map((val, ind) => {
  354. let marker = new AMap.Marker({
  355. position: new AMap.LngLat(val.longitude, val.latitude),
  356. icon: markIconPath,
  357. // icon: '//a.amap.com/jsapi_demos/static/demo-center/icons/dir-via-marker.png',
  358. zIndex: 9,
  359. extData: {
  360. id: ind + 1,
  361. },
  362. });
  363. marker.on("mouseover", async () => {
  364. // console.log([val.latitude, val.longitude], null, val);
  365. await api.siteOne_api({ siteId: val.id }).then((requset) => {
  366. this.siteOne = requset.data;
  367. });
  368. if (this.siteOne) {
  369. val.content = val.content.replace(
  370. /{alarmPowerCount}/g,
  371. this.siteOne.alarmPowerCount ? this.siteOne.alarmPowerCount : "0"
  372. );
  373. val.content = val.content.replace(
  374. /{status}/g,
  375. this.siteOne.status ? this.siteOne.status : "-"
  376. );
  377. val.content = val.content.replace(
  378. /{deviceCount}/g,
  379. this.siteOne.deviceCount ? this.siteOne.deviceCount : "0"
  380. );
  381. val.content = val.content.replace(
  382. /{deviceType}/g,
  383. this.siteOne.deviceType ? this.siteOne.deviceType : "-"
  384. );
  385. }
  386. await this.addMarkerInfo(
  387. [val.longitude, val.latitude],
  388. val.content,
  389. val
  390. );
  391. });
  392. marker.on("mouseout", async () => {
  393. this.map.clearInfoWindow();
  394. });
  395. marker.on("click", async () => {
  396. // localStorage.clear();
  397. localStorage.removeItem("Overview");
  398. this.$router.push({ path: "/Overview" });
  399. this.$store.commit("increment", val.id);
  400. localStorage.setItem("Overview", [val.id, val.siteName]);
  401. });
  402. return marker;
  403. });
  404. this.map.add(new AMap.OverlayGroup(markers));
  405. this.map.setFitView(); // 根据所有点自适应
  406. this.mapPolList = mapData.map((val, ind) => {
  407. // console.log(val)
  408. let color =
  409. this.colorList[
  410. this.colorIndList.findIndex(
  411. (value, index) =>
  412. value <= ind && ind < this.colorIndList[index + 1]
  413. )
  414. ];
  415. return [
  416. new AMap.Polygon({
  417. map: this.map,
  418. fillOpacity: 0.5,
  419. path: val[3],
  420. fillColor: color[0],
  421. strokeColor: color[1],
  422. }),
  423. new AMap.Polygon({
  424. map: this.map,
  425. fillOpacity: 0.5,
  426. path: val[3],
  427. fillColor: color[1],
  428. strokeColor: color[0],
  429. }),
  430. ];
  431. });
  432. this.map.on("mousemove", (e) => {
  433. var point = [e.lnglat.getLng(), e.lnglat.getLat()];
  434. var pointList = mapData.map((val) => {
  435. return AMap.GeometryUtil.isPointInRing(point, val[3]);
  436. });
  437. this.mapPolList.forEach((element, ind) => {
  438. if (pointList[ind]) {
  439. this.map.remove(element[0]);
  440. this.map.add(element[1]);
  441. } else {
  442. this.map.remove(element[1]);
  443. this.map.add(element[0]);
  444. }
  445. });
  446. });
  447. },
  448. // 添加标点
  449. addMarkerInfo(position, content, value = "") {
  450. value;
  451. // console.log("value");
  452. // console.log(value);
  453. this.map.clearInfoWindow();
  454. var infoWindow = new AMap.InfoWindow({
  455. isCustom: true, //使用自定义窗体
  456. closeWhenClickMap: true,
  457. content: content,
  458. offset: new AMap.Pixel(16, -30),
  459. });
  460. infoWindow.open(this.map, position);
  461. },
  462. poiPickerReady(poiPicker) {
  463. // console.log(poiPicker);
  464. var marker = new AMap.Marker();
  465. var infoWindow = new AMap.InfoWindow({
  466. offset: new AMap.Pixel(0, -20),
  467. });
  468. //选取了某个POI
  469. poiPicker.on("poiPicked", (poiResult) => {
  470. var source = poiResult.source,
  471. poi = poiResult.item,
  472. info = {
  473. source: source,
  474. id: poi.id,
  475. name: poi.name,
  476. location: poi.location.toString(),
  477. address: poi.address,
  478. };
  479. marker.setMap(this.map);
  480. infoWindow.setMap(this.map);
  481. marker.setPosition(poi.location);
  482. infoWindow.setPosition(poi.location);
  483. infoWindow.setContent(
  484. "POI信息: <pre>" + JSON.stringify(info, null, 2) + "</pre>"
  485. );
  486. // infoWindow.open(this.map, marker.getPosition());
  487. this.map.setCenter(marker.getPosition());
  488. });
  489. poiPicker.onCityReady(() => {
  490. // poiPicker.suggest("美食");
  491. });
  492. },
  493. // initMapUi() {
  494. // AMapUI.load(["ui/misc/PoiPicker"], (PoiPicker) => {
  495. // // console.log(PoiPicker);
  496. // let poiPickers = new PoiPicker({
  497. // input: "pickerInput",
  498. // });
  499. // this.poiPickerReady(poiPickers);
  500. // });
  501. // },
  502. },
  503. };
  504. </script>
  505. <style lang="scss">
  506. #pickerBox {
  507. position: absolute;
  508. z-index: 9;
  509. top: 0.15rem;
  510. right: 0.15rem;
  511. width: 3rem;
  512. height: 0.425rem;
  513. font-size: 0.15rem;
  514. }
  515. .el-icon-search {
  516. position: absolute;
  517. right: 0.1375rem;
  518. top: 0.1rem;
  519. font-size: 0.2125rem;
  520. color: #00f4fd;
  521. cursor: pointer;
  522. }
  523. #pickerInput {
  524. width: 3rem;
  525. line-height: 0.425rem;
  526. padding: 0 0.125rem;
  527. outline: none;
  528. border: 1px solid #00f4fd;
  529. border-radius: 18px;
  530. background: rgba(0, 0, 0, 0);
  531. color: #fff;
  532. }
  533. #poiInfo {
  534. background: #fff;
  535. }
  536. // 自定义图标调整大小
  537. .amap-icon img {
  538. width: 25px;
  539. }
  540. </style>