01.html 28 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8" />
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  6. <script src="https://webapi.amap.com/loader.js"></script>
  7. <title>数据看板</title>
  8. <style>
  9. * {
  10. box-sizing: border-box;
  11. }
  12. body {
  13. margin: 0;
  14. padding: 0;
  15. width: 100%;
  16. background-color: rgba(255, 255, 255, 0.2);
  17. /* background-image: url(./images/bg.png); */
  18. display: flex;
  19. color: #fff;
  20. /* overflow: hidden; */
  21. box-sizing: border-box;
  22. --margin: 5px;
  23. --padding: 10px;
  24. --color: #1f449a;
  25. --border-color: var(--color);
  26. --color1: #27b484;
  27. --h-color: #3ba9f6;
  28. }
  29. .border-svg-container {
  30. position: absolute;
  31. width: 100%;
  32. height: 100%;
  33. top: 0;
  34. left: 0;
  35. }
  36. .margin {
  37. margin: var(--margin);
  38. }
  39. .margin-x {
  40. margin-left: var(--margin);
  41. margin-right: var(--margin);
  42. }
  43. .mt {
  44. margin-top: var(--margin);
  45. }
  46. .mb {
  47. margin-bottom: var(--margin);
  48. }
  49. .margin-y {
  50. margin-top: var(--margin);
  51. margin-bottom: var(--margin);
  52. }
  53. .padding {
  54. padding: var(--padding);
  55. }
  56. .main {
  57. margin: 0;
  58. width: 100%;
  59. /* height: calc(100vh - 120px); */
  60. height: 100vh;
  61. display: flex;
  62. flex: 1 auto;
  63. }
  64. .box {
  65. padding: 0;
  66. /* border: 1px solid var(--border-color); */
  67. }
  68. .d-flex {
  69. display: flex;
  70. }
  71. .flex-center {
  72. justify-content: center;
  73. align-items: center;
  74. }
  75. .flex-row {
  76. display: flex;
  77. flex-direction: row;
  78. }
  79. .flex-column {
  80. display: flex;
  81. flex-direction: column;
  82. }
  83. .flex-column-auto {
  84. flex: none;
  85. }
  86. .flex-column-fluid {
  87. flex: 1 0 auto;
  88. }
  89. .flex-row-auto {
  90. flex: 0 0 auto;
  91. }
  92. .flex-row-fluid {
  93. flex: 1 auto;
  94. }
  95. .box-card {
  96. display: flex;
  97. flex-direction: column;
  98. width: 100%;
  99. height: 100%;
  100. background-color: #f5f5f5;
  101. border: none;
  102. color: #221e1e;
  103. /* border-radius: 11px 11px 0 0; */
  104. border: 1px solid var(--border-color);
  105. }
  106. .box-card .box_header {
  107. display: flex;
  108. align-items: center;
  109. background: #1f449a;
  110. color: #fff;
  111. justify-content: space-between;
  112. flex: none;
  113. padding-left: 15px;
  114. height: 40px;
  115. border-bottom: 2px solid var(--border-color);
  116. font-weight: 600;
  117. /* border-radius: 10px 10px 0 0; */
  118. font-family: 'Trebuchet MS', 'Lucida Sans Unicode', 'Lucida Grande', 'Lucida Sans', Arial, sans-serif;
  119. }
  120. .box-card .box_header .svg-box {
  121. height: 100%;
  122. width: 300px;
  123. }
  124. .box-card .box_header .svg-box img {
  125. width: 100%;
  126. height: 100%;
  127. }
  128. .box-card .box_body {
  129. padding: 10px;
  130. flex: 1 0 auto;
  131. }
  132. .map-container {
  133. width: 100%;
  134. height: calc(100% + 22px);
  135. }
  136. </style>
  137. <style>
  138. .amap-marker-label {
  139. border: none;
  140. border-radius: 10px;
  141. /* background: transparent; */
  142. background-color: rgba(255, 255, 255, 0.5);
  143. color: #1f449a;
  144. font-weight: 600;
  145. }
  146. .infoBox-content {
  147. padding: 10px;
  148. }
  149. .infoBox-content .text {
  150. color: #3c3c3c;
  151. display: flex;
  152. }
  153. .infoBox-content .text span {
  154. width: 100%;
  155. }
  156. .infoBox-content .splite {
  157. margin: 10px 0;
  158. height: 0;
  159. width: 100%;
  160. border-top: 1px dashed #666;
  161. }
  162. .infoBox-title {
  163. color: #fff;
  164. }
  165. </style>
  166. <style>
  167. #company_name {
  168. text-align: center;
  169. font-size: 18px;
  170. margin: 5px 8px;
  171. font-weight: 600;
  172. color: #c6c600;
  173. }
  174. .count-panel {
  175. display: flex;
  176. flex-direction: column;
  177. }
  178. .count-panel .panel-title,
  179. .count-panel .panel-time {
  180. font-size: 14px;
  181. color: #353540;
  182. line-height: 1.5em;
  183. text-align: center;
  184. }
  185. .count-panel .panel-title span {
  186. font-weight: 600;
  187. }
  188. .count-panel .panel-body {
  189. display: flex;
  190. justify-content: center;
  191. }
  192. .count-panel .count-group {
  193. margin-top: 5px;
  194. display: flex;
  195. }
  196. .count-panel .count-group>div {
  197. padding: 5px;
  198. background-color: #4e8eee;
  199. font-size: 30px;
  200. color: #1b1b25;
  201. margin-right: 3px;
  202. overflow: hidden;
  203. text-overflow: ellipsis;
  204. white-space: nowrap;
  205. text-align: center;
  206. }
  207. .count-panel .count-group>div>span {
  208. font-weight: bold;
  209. font-family: helvetica;
  210. text-align: center;
  211. background: linear-gradient(180deg, #eff4f4 0, #b5d5ed 100%);
  212. -webkit-background-clip: text;
  213. -webkit-text-fill-color: transparent;
  214. }
  215. .circle-group {
  216. margin: 5px;
  217. display: flex;
  218. flex-direction: column;
  219. align-items: center;
  220. }
  221. .circle-group .label {
  222. width: 100%;
  223. font-size: 12px;
  224. color: #353540;
  225. overflow: hidden;
  226. text-overflow: ellipsis;
  227. white-space: nowrap;
  228. text-align: center;
  229. overflow: visible;
  230. }
  231. .circle-group .value {
  232. margin: 5px;
  233. margin-top: 13px;
  234. width: 80px;
  235. height: 80px;
  236. font-size: 25px;
  237. color: #3c3c3c;
  238. border: 10px solid #177fd6;
  239. border-radius: 50%;
  240. text-align: center;
  241. overflow: hidden;
  242. text-overflow: ellipsis;
  243. white-space: nowrap;
  244. overflow: visible;
  245. display: flex;
  246. justify-content: center;
  247. align-items: center;
  248. }
  249. .company #jcyh {
  250. display: none;
  251. }
  252. .company .circle-group {
  253. margin-left: 20px;
  254. margin-right: 20px;
  255. }
  256. .log-box {
  257. color: var(--h-color);
  258. }
  259. .log-box .empty {
  260. height: 100%;
  261. display: flex;
  262. justify-content: center;
  263. align-items: center;
  264. font-size: 20px;
  265. font-weight: 600;
  266. }
  267. .log-box .log {
  268. margin: 3px 0;
  269. }
  270. .log-box .log .name {
  271. color: #434242;
  272. }
  273. .log-box .log .info {
  274. color: #3e3838;
  275. }
  276. </style>
  277. </head>
  278. <body>
  279. <div class="main flex-column">
  280. <div class="d-flex flex-column-fluid mb">
  281. <div class="box margin-x flex-row-fluid">
  282. <div class="box-card">
  283. <div class="box_header">
  284. <div class="title">全局概览</div>
  285. <div class="svg-box">
  286. <img src="./images/dec/1.svg" alt="" />
  287. </div>
  288. </div>
  289. <div class="box_body" style="padding: 0; overflow: hidden">
  290. <div class="map-container" id="map-container"></div>
  291. </div>
  292. </div>
  293. </div>
  294. <div class="box margin-x flex-column flex-row-auto" style="width: 40%">
  295. <div class="box flex-column-auto mb" style="height: 650px">
  296. <div class="box-card">
  297. <div class="box_header">
  298. <div class="title">数据监测</div>
  299. <div class="svg-box">
  300. <img src="./images/dec/1.svg" alt="" />
  301. </div>
  302. </div>
  303. <div class="box_body d-flex flex-column" style="overflow: hidden">
  304. <div id="company_name"></div>
  305. <div class="d-flex margin-y flex-column-auto">
  306. <div class="count-panel flex-row-auto" style="width: 33%">
  307. <span class="panel-title"><span>最大</span>负荷(兆瓦)</span>
  308. <!-- <span class="panel-time"> 发生于 <span>16:05:00</span></span> -->
  309. <div class="panel-body">
  310. <div class="count-group clearfix" id="max-power">
  311. <div><span>0</span></div>
  312. <div><span>0</span></div>
  313. <div><span>0</span></div>
  314. <div><span>0</span></div>
  315. <div><span>0</span></div>
  316. <div><span>0</span></div>
  317. </div>
  318. </div>
  319. </div>
  320. <div class="count-panel flex-row-fluid">
  321. <span class="panel-title"><span>最小</span>负荷(兆瓦)</span>
  322. <!-- <span class="panel-time"> 发生于 <span>16:05:00</span></span> -->
  323. <div class="panel-body">
  324. <div class="count-group clearfix" id="min-power">
  325. <div><span>0</span></div>
  326. <div><span>0</span></div>
  327. <div><span>0</span></div>
  328. <div><span>0</span></div>
  329. <div><span>0</span></div>
  330. <div><span>0</span></div>
  331. </div>
  332. </div>
  333. </div>
  334. <div class="count-panel flex-row-auto" style="width: 33%">
  335. <span class="panel-title"><span>平均</span>负荷(兆瓦)</span>
  336. <!-- <span class="panel-time"> 发生于 <span>16:05:00</span></span> -->
  337. <div class="panel-body">
  338. <div class="count-group clearfix" id="avg-power">
  339. <div><span>0</span></div>
  340. <div><span>0</span></div>
  341. <div><span>0</span></div>
  342. <div><span>0</span></div>
  343. <div><span>0</span></div>
  344. <div><span>0</span></div>
  345. </div>
  346. </div>
  347. </div>
  348. </div>
  349. <div class="d-flex margin-y flex-column-auto">
  350. <div class="flex-row-auto" style="width: 200px; height: 115px">
  351. <div id="pieMonitorContainer" style="width: 100%; height: 100%"></div>
  352. </div>
  353. <div class="flex-row-fluid d-flex flex-center">
  354. <div class="flex-row-auto circle-group" id="jcyh">
  355. <div class="label">监测用户</div>
  356. <div class="value"></div>
  357. </div>
  358. <div class="flex-row-auto circle-group" id="jcrl">
  359. <div class="label">监测容量(<span>KVA</span>)</div>
  360. <div class="value"></div>
  361. </div>
  362. <div class="flex-row-auto circle-group" id="jcds">
  363. <div class="label">监测点数</div>
  364. <div class="value"></div>
  365. </div>
  366. </div>
  367. </div>
  368. <div class="d-flex margin-y flex-column-fluid" id="power-chart-box" style="width: 100%">
  369. <div id="powerDataContainer" style="width: 100%; height: 100%"></div>
  370. </div>
  371. </div>
  372. </div>
  373. </div>
  374. <div class="box flex-column-fluid mt d-flex" style="height: 20%">
  375. <div class="box-card" style="height: 100%">
  376. <div class="box_header">
  377. <div class="title">告警记录</div>
  378. <div class="svg-box">
  379. <img src="./images/dec/1.svg" alt="" />
  380. </div>
  381. </div>
  382. <div class="box_body" style="overflow: hidden; width: 100%; height: calc(100% - 40px)">
  383. <div id="warning-box" class="d-flex flex-column log-box"
  384. style="width: calc(100% + 30px); max-height: 110px; overflow-y: auto"></div>
  385. </div>
  386. </div>
  387. </div>
  388. </div>
  389. <!-- <div class="box margin flex-column flex-row-auto" style="width: 20%"></div> -->
  390. </div>
  391. </div>
  392. <script src="http://static.vbdsm.com/js/lib/jquery-1.8.0.min.js" type="text/javascript"></script>
  393. <script src="http://static.vbdsm.com/js/lib/jquery.query-2.1.7.js"></script>
  394. <script src="http://static.vbdsm.com/js/util.js" type="text/javascript"></script>
  395. <script src="./js/echarts.js"></script>
  396. <script>
  397. const cid = $.query.get('auth_cid')
  398. $('body').append('<script src="/system/lang/desktop/config.json?script=1&auth_cid=' + cid + '"><\/script>')
  399. //var host = jQuery.parseJSON(AUTH.site.config).platform['01200009'] + '.' + AUTH.site.domain
  400. //console.log(AUTH)
  401. let warnInfoList = []
  402. let isService = 0,
  403. curCompanyId = ''
  404. $(function () {
  405. initMonitor()
  406. })
  407. ajax({
  408. url: '/web/sys/altips/getWarnInfoList.json',
  409. type: 'post',
  410. dataType: 'json',
  411. success: function (res) {
  412. warnInfoList = res.data
  413. },
  414. })
  415. </script>
  416. <script id="map">
  417. let map
  418. window._AMapSecurityConfig = {
  419. securityJsCode: 'b815cb3bb6aa8516fcfe8c506abe9da2',
  420. }
  421. AMapLoader.load({
  422. key: '0da67b4ef98b3975eed48e8f8d42f9cd', //申请好的Web端开发者 Key,调用 load 时必填
  423. version: '2.0', //指定要加载的 JS API 的版本,缺省时默认为 1.4.15
  424. plugins: ['AMap.Scale', 'AMap.HawkEye', 'AMap.ToolBar', 'AMap.ControlBar'],
  425. })
  426. .then((AMap) => {
  427. const _map = new AMap.Map('map-container', {
  428. //设置地图容器id
  429. viewMode: '3D', //是否为3D地图模式
  430. rotation: 45,
  431. pitch: 65,
  432. zoom: 10, //初始化地图级别
  433. })
  434. const scale = new AMap.Scale(),
  435. toolBar = new AMap.ToolBar({
  436. position: {
  437. top: '110px',
  438. right: '40px',
  439. },
  440. }),
  441. controlBar = new AMap.ControlBar({
  442. position: {
  443. top: '10px',
  444. right: '10px',
  445. },
  446. }),
  447. overView = new AMap.HawkEye({
  448. opened: false,
  449. })
  450. _map.addControl(scale)
  451. _map.addControl(toolBar)
  452. _map.addControl(controlBar)
  453. _map.addControl(overView)
  454. overView.hide()
  455. //_map.setMapStyle('amap://styles/1f1485e5beb2382bd068587d161155a2')
  456. map = _map
  457. getCompanyList()
  458. })
  459. .catch((e) => {
  460. console.error(e) //加载错误提示
  461. })
  462. let pageNumber = 1,
  463. pageSize = 10
  464. let isInitMap = false
  465. let companyData = [],
  466. mapMarkers = []
  467. function getCompanyList() {
  468. ajax({
  469. url: `/web/screen/getCompanyList.json`,
  470. type: 'post',
  471. dataType: 'json',
  472. data: {
  473. pageNo: pageNumber,
  474. pageSize: pageSize,
  475. },
  476. success: function (res) {
  477. //console.log('--------', res)
  478. companyData = res.rows
  479. renderCompany()
  480. },
  481. })
  482. }
  483. function renderCompany() {
  484. mapMarkers = []
  485. companyData.forEach((v) => {
  486. const coordinate = v.coordinate
  487. const coordinateArr = coordinate.split(',')
  488. v.longitude = Number(coordinateArr[0])
  489. v.latitude = coordinateArr.length > 1 ? Number(coordinateArr[1]) : null
  490. if (!isInitMap) {
  491. isInitMap = true
  492. if (v.latitude || v.longitude) {
  493. map.setZoomAndCenter(13, [v.longitude, v.latitude])
  494. }
  495. }
  496. renderMark(v)
  497. })
  498. //console.log('-mapMarkers-', mapMarkers)
  499. }
  500. function renderMark(data) {
  501. if (!data.latitude || !data.longitude) {
  502. return
  503. }
  504. //console.log('---', data)
  505. const infoWindow = new window.AMap.InfoWindow({
  506. isCustom: true,
  507. //anchor: "top-center",
  508. offset: new window.AMap.Pixel(0, -25),
  509. //content: "2", //getInfoBoxHtml(item), //传入 dom 对象,或者 html 字符串
  510. })
  511. infoWindow.on('open', function () {
  512. document.querySelector('.close-btn_info-box')?.addEventListener('click', function () {
  513. infoWindow.close()
  514. getCompanyMonitor()
  515. $('#company_name').text('').hide()
  516. })
  517. })
  518. const oldMark = mapMarkers.find((a) => a.id == data.id)
  519. if (oldMark) {
  520. map.remove(oldMark.marker)
  521. }
  522. // mapMarkers.splice(
  523. // mapMarkers.findIndex((a) => a.id == data.id),
  524. // 1
  525. // )
  526. const mkIcon = new window.AMap.Icon({
  527. size: new window.AMap.Size(35, 35),
  528. image: '/bigScreen/images/map/blue-location.png',
  529. imageOffset: new window.AMap.Pixel(0, 0),
  530. imageSize: new window.AMap.Size(35, 35),
  531. })
  532. const marker = new window.AMap.Marker({
  533. position: new window.AMap.LngLat(data.longitude, data.latitude),
  534. offset: new window.AMap.Pixel(0, 1),
  535. icon: mkIcon, // 添加 Icon 实例
  536. anchor: 'bottom-center',
  537. label: {
  538. content: `<span>${data.name}</span>`,
  539. direction: 'bottom',
  540. },
  541. })
  542. marker.id = data.id
  543. map.add(marker)
  544. let timer
  545. marker.on('click', () => {
  546. clearTimeout(timer)
  547. companyMarkOpen(data, false)
  548. })
  549. // marker.on('mouseover', () => {
  550. // console.log('mouseover', data)
  551. // clearTimeout(timer)
  552. // timer = setTimeout(() => {
  553. // companyMarkOpen(data, false)
  554. // }, 800)
  555. // })
  556. // marker.on('mouseout', () => {
  557. // clearTimeout(timer)
  558. // })
  559. mapMarkers.push({
  560. id: data.id,
  561. marker,
  562. infoWindow,
  563. })
  564. }
  565. function companyMarkOpen(item, moveCenter) {
  566. mapMarkers.forEach((v) => {
  567. if (item && v.id == item.id) {
  568. //console.log('--ID', item.id, v.id)
  569. $('#company_name').text(item.name).show()
  570. getCompanyMonitor(item.id)
  571. renderInfoWindow(v, item, moveCenter)
  572. } else {
  573. v.infoWindow.close()
  574. }
  575. })
  576. }
  577. function renderInfoWindow(mapMarker, item, moveCenter) {
  578. ajax({
  579. url: `/web/screen/getCompanyDetail.json`,
  580. type: 'post',
  581. dataType: 'json',
  582. data: {
  583. orgId: item.id,
  584. },
  585. success: function (res) {
  586. const content = getInfoBoxHtml(res.data, item)
  587. mapMarker.infoWindow.setContent(content)
  588. mapMarker.infoWindow.open(map, [item.longitude, item.latitude])
  589. if (moveCenter || moveCenter == undefined) {
  590. map.setZoomAndCenter(13, [item.longitude, item.latitude + 0.01])
  591. }
  592. },
  593. })
  594. }
  595. function getInfoBoxHtml(data, item) {
  596. console.log('___###', data, item)
  597. return `<div class="infoBox" style="width:500px;height:auto;border:0px solid rgb(11, 44, 114);">
  598. <div class="infoBox-title d-flex flex-center"style="height:40px;font-weight:600;background:#000c31;border-radius:10px 10px 0 0;position: relative;">
  599. <span>${item.name}</span>
  600. <div class="close-btn_info-box" style="position: absolute; right: 10px;top: 4px; width: 30px;height: 30px;border-radius: 50%;display: flex;justify-content: center;align-items: center;background: transparent; cursor: pointer; background-repeat: no-repeat; background-size: 90%;background-position: center;
  601. background-image: url('data:image/svg+xml;base64,PHN2ZyB0PSIxNjU1MzY1ODQ3ODQwIiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjIyNzgiIHdpZHRoPSIyMDAiIGhlaWdodD0iMjAwIj48cGF0aCBkPSJNNTEyIDk2MEMyNjQuOTYgOTYwIDY0IDc1OS4wNCA2NCA1MTJTMjY0Ljk2IDY0IDUxMiA2NHM0NDggMjAwLjk2IDQ0OCA0NDhTNzU5LjA0IDk2MCA1MTIgOTYwek01MTIgMTI4LjI4OEMzMDAuNDE2IDEyOC4yODggMTI4LjI4OCAzMDAuNDE2IDEyOC4yODggNTEyYzAgMjExLjU1MiAxNzIuMTI4IDM4My43MTIgMzgzLjcxMiAzODMuNzEyIDIxMS41NTIgMCAzODMuNzEyLTE3Mi4xNiAzODMuNzEyLTM4My43MTJDODk1LjcxMiAzMDAuNDE2IDcyMy41NTIgMTI4LjI4OCA1MTIgMTI4LjI4OHoiIHAtaWQ9IjIyNzkiIGZpbGw9IiNmZmZmZmYiPjwvcGF0aD48cGF0aCBkPSJNNTU3LjA1NiA1MTMuMzc2bDEzOC4zNjgtMTM2Ljg2NGMxMi41NzYtMTIuNDE2IDEyLjY3Mi0zMi42NzIgMC4yNTYtNDUuMjQ4LTEyLjQxNi0xMi41NzYtMzIuNzA0LTEyLjY3Mi00NS4yNDgtMC4yNTZsLTEzOC41NiAxMzcuMDI0LTEzNi40NDgtMTM2Ljg2NGMtMTIuNTEyLTEyLjUxMi0zMi43MzYtMTIuNTc2LTQ1LjI0OC0wLjA2NC0xMi41MTIgMTIuNDgtMTIuNTQ0IDMyLjczNi0wLjA2NCA0NS4yNDhsMTM2LjI1NiAxMzYuNjcyLTEzNy4zNzYgMTM1LjkwNGMtMTIuNTc2IDEyLjQ0OC0xMi42NzIgMzIuNjcyLTAuMjU2IDQ1LjI0OCA2LjI3MiA2LjMzNiAxNC40OTYgOS41MDQgMjIuNzUyIDkuNTA0IDguMTI4IDAgMTYuMjU2LTMuMTA0IDIyLjQ5Ni05LjI0OGwxMzcuNTY4LTEzNi4wNjQgMTM4LjY4OCAxMzkuMTM2YzYuMjQgNi4yNzIgMTQuNDMyIDkuNDA4IDIyLjY1NiA5LjQwOCA4LjE5MiAwIDE2LjM1Mi0zLjEzNiAyMi41OTItOS4zNDQgMTIuNTEyLTEyLjQ4IDEyLjU0NC0zMi43MDQgMC4wNjQtNDUuMjQ4TDU1Ny4wNTYgNTEzLjM3NnoiIHAtaWQ9IjIyODAiIGZpbGw9IiNmZmZmZmYiPjwvcGF0aD48L3N2Zz4=');"></div>
  602. </div>
  603. <div class="infoBox-content" style="width:100%;overflow:hidden; padding:15px;border-radius: 0 0 10px 10px; background:rgba(255,255,255,.8);color:#3c3c3c;">
  604. <div class="text">
  605. <span style="">详细地址:${item.address}</span>
  606. </div>
  607. <div class="splite"></div>
  608. <div class="text">
  609. <span style="">主变数量:${data._zbsl} 台</span>
  610. </div>
  611. <div class="splite"></div>
  612. <div class="text">
  613. <span style="">报装容量:${data._applyLoad} kVA</span>
  614. <span style="">监测容量:${data._jcrl} kVA</span>
  615. </div>
  616. <div class="splite"></div>
  617. <div class="text">
  618. <span style="">基本电费:${data._jbdj} kVA</span>
  619. <span style="">计费方式:${data._jffs == 1 ? '容量' : data._jffs == 2 ? '需量' : data._jffs == 3 ? '单一电价' : ''} </span>
  620. </div>
  621. </div>
  622. </div>`
  623. }
  624. </script>
  625. <script id="Monitor">
  626. function initMonitor() {
  627. getCompanyMonitor()
  628. setInterval(() => {
  629. getCompanyMonitor(curCompanyId)
  630. }, 1000 * 60 * 1)
  631. }
  632. function getCompanyMonitor(id) {
  633. if (!id) {
  634. isService = 1
  635. curCompanyId = ''
  636. } else {
  637. isService = 0
  638. curCompanyId = id
  639. }
  640. ajax({
  641. url: `/web/screen/getCompanyMonitor.json`,
  642. type: 'post',
  643. dataType: 'json',
  644. data: {
  645. orgId: curCompanyId,
  646. },
  647. success: function (res) {
  648. //console.log('--monitor--', res)
  649. renderMonitor(res.data, isService)
  650. let pieData = [
  651. { name: '在线', value: res.data.onlineCount || 0 },
  652. { name: '离线', value: res.data.notOnlineCount || 0 },
  653. ]
  654. renderMonitorPieChart(pieData)
  655. },
  656. })
  657. ajax({
  658. url: `/web/screen/getMaxPower.json`,
  659. type: 'post',
  660. dataType: 'json',
  661. data: {
  662. orgId: curCompanyId,
  663. },
  664. success: function (res) {
  665. //console.log('min', res)
  666. rendMinMaxPower(res.data)
  667. },
  668. })
  669. ajax({
  670. url: `/web/screen/getCompanyLoadData.json`,
  671. type: 'post',
  672. dataType: 'json',
  673. data: {
  674. orgId: curCompanyId,
  675. },
  676. success: function (res) {
  677. console.log('chart', res)
  678. renderPowerDataChart(res.data)
  679. },
  680. })
  681. ajax({
  682. url: `/web/screen/getWarnInfoList.json`,
  683. type: 'post',
  684. dataType: 'json',
  685. data: {
  686. orgId: curCompanyId,
  687. pageSize: 20,
  688. },
  689. success: function (res) {
  690. renderWarnings(res.data)
  691. },
  692. })
  693. }
  694. function rendMinMaxPower(data) {
  695. let i = 0
  696. render('max')
  697. render('min')
  698. render('avg')
  699. function render(idStr) {
  700. const $that = $('#' + idStr + '-power')
  701. $that.hide()
  702. let time,
  703. val,
  704. str = ''
  705. if (data) {
  706. if (idStr == 'max') {
  707. time = data.maxTime
  708. val = data.mmax
  709. } else if (idStr == 'min') {
  710. time = data.minTime
  711. val = data.mmin
  712. } else if (idStr == 'avg') {
  713. val = data.mavg
  714. }
  715. if (val) {
  716. val = (val / 1000).toFixed(2) + ''
  717. while (val.length < 6) {
  718. val += '0'
  719. }
  720. if (val.length > 6) {
  721. val = (val / 1000).toFixed(0)
  722. if (val.length > 5) {
  723. val = (val / 1000).toFixed(0)
  724. while (val.length < 5) {
  725. val += '0'
  726. }
  727. val += 'M'
  728. } else {
  729. while (val.length < 5) {
  730. val += '0'
  731. }
  732. val += 'K'
  733. }
  734. }
  735. val = val.split('')
  736. val.forEach((v) => {
  737. str += `<div><span>${v}</span></div>`
  738. })
  739. }
  740. } else {
  741. for (let i = 0; i < 6; i++) {
  742. str += `<div><span>0</span></div>`
  743. }
  744. }
  745. $that.html(str).fadeIn(500)
  746. }
  747. }
  748. function renderMonitor(data) {
  749. if (isService) {
  750. $('#jcyh').parent().removeClass('company')
  751. } else {
  752. $('#jcyh').parent().addClass('company')
  753. }
  754. $('#jcyh .value').text(data.companyCount)
  755. if (data.jcrl > 10000) {
  756. let val = (data.jcrl / 10000).toFixed(1) + ''
  757. if (val.length > 4) {
  758. let val = (data.jcrl / 10000).toFixed(0) + ''
  759. }
  760. $('#jcrl span').text('万KVA')
  761. $('#jcrl .value').text(val)
  762. } else {
  763. $('#jcrl span').text('KVA')
  764. $('#jcrl .value').text(data.jcrl)
  765. }
  766. $('#jcds .value').text(data.totalCount)
  767. }
  768. function renderWarnings(data) {
  769. if (data && data.length > 0) {
  770. $('#warning-box').html('')
  771. data.forEach((v) => {
  772. renderWarning(v)
  773. })
  774. } else {
  775. $('#warning-box').html('<div class="empty">暂无告警</div>')
  776. }
  777. }
  778. function renderWarning(data) {
  779. let str = `<div class="log">
  780. <span class="time">[ ${getTime(data.warningTimeStart)} ]</span>
  781. <span class="name">${data.companyName}</span>
  782. <span class="info">${getWarnInfo(data.warningInfoId)}</span>
  783. 发生
  784. <span class="flag">${getFlag(data.overFlag)}</span>
  785. 告警。
  786. </div>`
  787. $('#warning-box').append(str)
  788. function getFlag(value) {
  789. return 1 == value ? '<span style="color:#F95639">越上限↑</span>' : '<span style="color:#3378E0">越下限↓</span>'
  790. }
  791. function getTime(value) {
  792. var val = ''
  793. if (value) {
  794. val = '' + value
  795. val = val.substr(0, 4) + '-' + val.substr(4, 2) + '-' + val.substr(6, 2) + ' ' + val.substr(8, 2) + ':' + val.substr(10, 2) + ':' + val.substr(12, 2)
  796. }
  797. return val
  798. }
  799. function getWarnInfo(value) {
  800. let info = warnInfoList.find((v) => v.id == value)
  801. if (info) {
  802. return info.text
  803. }
  804. return '未知类型'
  805. }
  806. return str
  807. }
  808. </script>
  809. <script id="chart">
  810. const color = ['#177fd6', '#c23531', '#61a0a8', '#d48265', '#91c7ae', '#749f83', '#ca8622', '#bda29a', '#6e7074', '#546570', '#c4ccd3']
  811. function renderMonitorPieChart(data) {
  812. let option = {
  813. color: ['#177fd6', '#05224d'],
  814. title: {
  815. text: '监测点运行情况',
  816. left: 'center',
  817. top: 5,
  818. textStyle: {
  819. fontSize: 12,
  820. color: '#353545',
  821. },
  822. },
  823. tooltip: {
  824. show: false,
  825. trigger: 'item',
  826. },
  827. legend: {
  828. orient: 'vertical',
  829. right: '0',
  830. bottom: '10',
  831. textStyle: {
  832. color: '#353545',
  833. },
  834. selectedMode: false,
  835. },
  836. series: [
  837. {
  838. type: 'pie',
  839. radius: '70%',
  840. center: ['35%', '60%'],
  841. data: data,
  842. label: {
  843. position: 'inside',
  844. formatter: '{c}台',
  845. },
  846. emphasis: {
  847. itemStyle: {
  848. shadowBlur: 10,
  849. shadowOffsetX: 0,
  850. shadowColor: 'rgba(0, 0, 0, 0.5)',
  851. },
  852. },
  853. },
  854. ],
  855. }
  856. const pieMonitorChart = echarts.init(document.getElementById('pieMonitorContainer'))
  857. pieMonitorChart.setOption(option)
  858. }
  859. let powerChart = echarts.init(document.getElementById('powerDataContainer'))
  860. function renderPowerDataChart(data) {
  861. let dataSet = []
  862. for (let i = 0; i < data.date1.length; i++) {
  863. const item1 = $.extend(true, {}, data.date1[i])
  864. item1.name = 'd1'
  865. item1.y = item1.y == -9999 ? null : item1.y
  866. item1.timestamp = formaDate(item1.timestamp)
  867. dataSet.push(item1)
  868. const item2 = $.extend(true, {}, data.date2[i])
  869. item2.name = 'd2'
  870. item2.y = item2.y == -9999 ? null : item2.y
  871. item2.timestamp = formaDate(item2.timestamp)
  872. dataSet.push(item2)
  873. const item3 = $.extend(true, {}, data.date3[i])
  874. item3.name = 'd3'
  875. item3.y = item3.y == -9999 ? null : item3.y
  876. item3.timestamp = formaDate(item3.timestamp)
  877. dataSet.push(item3)
  878. }
  879. // 定义格式化封装函数
  880. function formaDate(timer) {
  881. let date = new Date(timer)
  882. //const year = date.getFullYear()
  883. //const month = date.getMonth() + 1 // 由于月份从0开始,因此需加1
  884. //const day = date.getDate()
  885. const hour = date.getHours()
  886. const minute = date.getMinutes()
  887. //const second = date.getSeconds()
  888. return `${hour < 10 ? '0' + hour : hour}:${minute < 10 ? '0' + minute : minute}`
  889. }
  890. //console.log('DS', dataSet)
  891. let option = {
  892. color: ['#3ba9f6', '#fc6444', '#27b484'],
  893. dataset: [
  894. {
  895. source: dataSet,
  896. },
  897. {
  898. transform: [
  899. {
  900. type: 'filter',
  901. config: { dimension: 'name', value: 'd1' },
  902. },
  903. {
  904. type: 'sort',
  905. config: { dimension: 'timestamp', order: 'asc' },
  906. },
  907. ],
  908. },
  909. {
  910. transform: [
  911. {
  912. type: 'filter',
  913. config: { dimension: 'name', value: 'd2' },
  914. },
  915. {
  916. type: 'sort',
  917. config: { dimension: 'timestamp', order: 'asc' },
  918. },
  919. ],
  920. },
  921. {
  922. transform: [
  923. {
  924. type: 'filter',
  925. config: { dimension: 'name', value: 'd3' },
  926. },
  927. {
  928. type: 'sort',
  929. config: { dimension: 'timestamp', order: 'asc' },
  930. },
  931. ],
  932. },
  933. ],
  934. title: {
  935. text: '负荷波动情况',
  936. left: 'center',
  937. top: 5,
  938. textStyle: {
  939. fontSize: 14,
  940. color: '#353545',
  941. },
  942. },
  943. legend: {
  944. show: true,
  945. bottom: 10,
  946. textStyle: {
  947. fontSize: 12,
  948. color: '#353545',
  949. },
  950. },
  951. xAxis: {
  952. //name: 'timestamp',
  953. type: 'category',
  954. interval: 8,
  955. axisLine: {
  956. lineStyle: {
  957. color: '#353545',
  958. width: 1,
  959. },
  960. },
  961. axisLabel: {
  962. textStyle: {
  963. fontSize: 12,
  964. color: '#353545',
  965. },
  966. },
  967. },
  968. yAxis: {
  969. name: 'KW',
  970. splitNumber: 4,
  971. max: function (value) {
  972. return ((value.max + 50) / 100).toFixed(0) * 100
  973. },
  974. min: function (value) {
  975. return ((value.min - 50) / 100).toFixed(0) * 100
  976. },
  977. axisLine: {
  978. lineStyle: {
  979. color: '#353545',
  980. width: 1,
  981. },
  982. },
  983. axisLabel: {
  984. textStyle: {
  985. fontSize: 12,
  986. color: '#353545',
  987. },
  988. },
  989. splitLine: {
  990. lineStyle: {
  991. type: 'dashed',
  992. color: '#363e4f',
  993. },
  994. },
  995. },
  996. series: [
  997. {
  998. type: 'line',
  999. name: '今日',
  1000. datasetIndex: 1,
  1001. symbol: 'none',
  1002. encode: {
  1003. x: 'timestamp',
  1004. y: 'y',
  1005. },
  1006. },
  1007. {
  1008. type: 'line',
  1009. name: '昨日',
  1010. datasetIndex: 2,
  1011. symbol: 'none',
  1012. encode: {
  1013. x: 'timestamp',
  1014. y: 'y',
  1015. },
  1016. },
  1017. {
  1018. type: 'line',
  1019. name: '前日',
  1020. datasetIndex: 3,
  1021. symbol: 'none',
  1022. encode: {
  1023. x: 'timestamp',
  1024. y: 'y',
  1025. },
  1026. },
  1027. ],
  1028. }
  1029. powerChart.dispose()
  1030. powerChart = echarts.init(document.getElementById('powerDataContainer'))
  1031. powerChart.setOption(option)
  1032. }
  1033. </script>
  1034. </body>
  1035. </html>