index.vue 14 KB

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