index.html 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <!-- 引入 ECharts 文件 -->
  6. <script type="text/javascript" src="static/jquery-3.3.1.min.js"></script>
  7. <script src="static/echarts.min.js"></script>
  8. <script src="static/plug-in.min.js"></script>
  9. <script src="static/jquery.liMarquee.js"></script>
  10. <link rel="stylesheet" href="static/index.css" media="all" />
  11. </head>
  12. <body>
  13. <div class="positon">
  14. 底图:<select id="mapName">
  15. </select>
  16. </div>
  17. <div class="title-name">设备运行状态一览图</div>
  18. <div class="title-icon"><span>正常设备</span><span>计划性维修设备</span><span>非计划性维修设备</span></div>
  19. <div id="echart" class="echart"></div>
  20. <div class="data">
  21. <div>
  22. <span id="monthNum">暂无</span>
  23. </div>
  24. <div>
  25. <span id="waitNum">暂无</span>
  26. <span id="rate">暂无</span>
  27. </div>
  28. <div style="height: 80%;">
  29. <div id="weekJob" class="item title">
  30. <span>设备编号</span>
  31. <span>保养任务</span>
  32. <span>保养计划时间</span>
  33. </div>
  34. <div class="scrollDiv str_wrap str_vertical"></div>
  35. <!-- <div class="item">
  36. <span>设备名称</span>
  37. <span>正常</span>
  38. <span>2021/03/21</span>
  39. </div>-->
  40. </div>
  41. </div>
  42. </body>
  43. <style>
  44. /*Plugin CSS*/
  45. .str_wrap {
  46. overflow: hidden;
  47. height: 56%;
  48. width: 100%;
  49. position: relative;
  50. -moz-user-select: none;
  51. -khtml-user-select: none;
  52. user-select: none;
  53. white-space: nowrap;
  54. }
  55. .positon {
  56. position: absolute;
  57. top: 20px;
  58. left: 30%;
  59. z-index: 1000;
  60. }
  61. #mapName {
  62. width: 120px;
  63. }
  64. .str_move {
  65. white-space: nowrap;
  66. position: absolute;
  67. top: 0;
  68. left: 0;
  69. cursor: move;
  70. }
  71. .str_move_clone {
  72. display: inline-block;
  73. vertical-align: top;
  74. position: absolute;
  75. left: 100%;
  76. top: 0;
  77. }
  78. .str_vertical .str_move_clone {
  79. left: 0;
  80. top: 100%;
  81. }
  82. .str_down .str_move_clone {
  83. left: 0;
  84. bottom: 100%;
  85. }
  86. .title-name {
  87. position: absolute;
  88. top: 87px;
  89. left: 26%;
  90. font-size: 34px;
  91. color: black;
  92. z-index: 10000;
  93. }
  94. </style>
  95. <script>
  96. function getBase64(image) {
  97. var canvas = document.createElement("canvas");
  98. canvas.width = image.width;
  99. canvas.height = image.height;
  100. var context = canvas.getContext("2d");
  101. context.drawImage(image, 0, 0, image.width, image.height);
  102. // 将canvas的内容转换为base64编码的字符串
  103. var base64 = canvas.toDataURL("image/png");// 可以根据需要更改为其他格式,如'image/jpeg'等
  104. return base64;
  105. }
  106. const ACCESS_TOKEN = 'Access-Token'
  107. const VUE_STORE_BASE = 'pro__'
  108. let mapName, mapList, dataList
  109. var tooltip_message = ''
  110. // 基于准备好的dom,初始化echarts实例
  111. var myChart = echarts.init(document.getElementById('echart'))
  112. var img = new Image()
  113. var canvas = document.createElement('canvas')
  114. var ctx = canvas.getContext('2d')
  115. canvas.width = myChart.getWidth() * window.devicePixelRatio
  116. canvas.height = myChart.getHeight() * window.devicePixelRatio
  117. var fullImage = new Image()
  118. img.onload = function () {
  119. ctx.drawImage(img, 0, 0, canvas.width, canvas.height)
  120. fullImage.src = canvas.toDataURL()
  121. setTimeout(function () {
  122. myChart.resize()
  123. }, 100)
  124. }
  125. img.src = './static/03_01.png'
  126. var option = {
  127. // 背景
  128. backgroundColor: {
  129. repeat: 'no-repeat',
  130. image: fullImage
  131. },
  132. // 地图
  133. geo: {
  134. map: 'world',
  135. silent: true,
  136. top: 0,
  137. left: 0,
  138. right: 0,
  139. bottom: 0,
  140. itemStyle: {
  141. normal: {
  142. opacity: 0.8,
  143. borderWidth: 0,
  144. color: '#a53d13'
  145. }
  146. }
  147. },
  148. title: {
  149. text: '',
  150. },
  151. // 开启工具栏
  152. tooltip: {
  153. "trigger": "item",
  154. "confine": true,
  155. "formatter": (params, ticket, callback) => {
  156. // params.data [20, 204, "L-012"],水平位置,垂直位置,设备编号
  157. let sbNo = params.data[2];
  158. getSbDetail(sbNo);
  159. return tooltip_message;
  160. }
  161. },
  162. series: [{
  163. name: '正常点',
  164. type: 'effectScatter',
  165. coordinateSystem: 'geo',
  166. data: [
  167. ],
  168. showEffectOn: 'render',
  169. rippleEffect: {
  170. brushType: 'stroke'
  171. },
  172. hoverAnimation: true,
  173. label: {
  174. normal: {
  175. formatter: '{@value}',
  176. position: 'left',
  177. show: false
  178. }
  179. },
  180. itemStyle: {
  181. normal: {
  182. color: '#174FBF',
  183. shadowBlur: 200,
  184. shadowColor: '#174FBF'
  185. }
  186. },
  187. zlevel: 1
  188. }, {
  189. name: '正常点编号',
  190. type: 'scatter',
  191. coordinateSystem: 'geo',
  192. symbol: 'pin', // 气泡
  193. symbolSize: 50,
  194. label: {
  195. normal: {
  196. show: true,
  197. formatter: '{@value}',
  198. textStyle: {
  199. color: '#000',
  200. fontSize: 11
  201. }
  202. }
  203. },
  204. itemStyle: {
  205. normal: {
  206. color: '#174FBF'
  207. }
  208. },
  209. zlevel: 6,
  210. data: [
  211. ]
  212. }, {
  213. name: '红色非计划性报修异常点',
  214. type: 'effectScatter',
  215. coordinateSystem: 'geo',
  216. data: [
  217. ],
  218. showEffectOn: 'render',
  219. rippleEffect: {
  220. brushType: 'stroke'
  221. },
  222. hoverAnimation: true,
  223. label: {
  224. normal: {
  225. formatter: '{@value}',
  226. position: 'left',
  227. show: false
  228. }
  229. },
  230. itemStyle: {
  231. normal: {
  232. color: 'red',
  233. shadowBlur: 200,
  234. shadowColor: 'red'
  235. }
  236. },
  237. zlevel: 1
  238. }, {
  239. name: '红色非计划性报修异常点编号',
  240. type: 'scatter',
  241. coordinateSystem: 'geo',
  242. symbol: 'pin', // 气泡
  243. symbolSize: 50,
  244. label: {
  245. normal: {
  246. show: true,
  247. formatter: '{@value}',
  248. textStyle: {
  249. color: '#000',
  250. fontSize: 11
  251. }
  252. }
  253. },
  254. itemStyle: {
  255. normal: {
  256. color: 'red'
  257. }
  258. },
  259. zlevel: 6,
  260. data: [
  261. ]
  262. }, {
  263. name: '黄色计划性报修异常点',
  264. type: 'effectScatter',
  265. coordinateSystem: 'geo',
  266. data: [
  267. ],
  268. showEffectOn: 'render',
  269. rippleEffect: {
  270. brushType: 'stroke'
  271. },
  272. hoverAnimation: true,
  273. label: {
  274. normal: {
  275. formatter: '{@value}',
  276. position: 'left',
  277. show: false
  278. }
  279. },
  280. itemStyle: {
  281. normal: {
  282. color: 'yellow',
  283. shadowBlur: 200,
  284. shadowColor: 'yellow'
  285. }
  286. },
  287. zlevel: 1
  288. }, {
  289. name: '黄色计划性报修异常点编号',
  290. type: 'scatter',
  291. coordinateSystem: 'geo',
  292. symbol: 'pin', // 气泡
  293. symbolSize: 50,
  294. label: {
  295. normal: {
  296. show: true,
  297. formatter: '{@value}',
  298. textStyle: {
  299. color: '#000',
  300. fontSize: 11
  301. }
  302. }
  303. },
  304. itemStyle: {
  305. normal: {
  306. color: 'yellow'
  307. }
  308. },
  309. zlevel: 6,
  310. data: [
  311. ]
  312. }]
  313. }
  314. function getMapList() {
  315. $('#mapName').on('change', function (e) {
  316. mapName = e.delegateTarget.value
  317. img.src = mapList.find(item => item.targetId == mapName).url
  318. init()
  319. });
  320. $.ajax({
  321. type: "GET",
  322. url: "/api/upms/files?type=56",
  323. headers: getHeader(),
  324. success: function (res) {
  325. var data = res.data
  326. mapList = data
  327. for (var i = 0; i < data.length; i++) {
  328. var option = '<option value="' + data[i].targetId + '">' + data[i].targetId + '</option>'
  329. $('#mapName').append(option)
  330. }
  331. mapName = mapList[0].targetId
  332. img.src = mapList.find(item => item.targetId == mapName).url
  333. $('#mapName').val(mapName);
  334. }
  335. })
  336. }
  337. getMapList()
  338. //初始化加载数据,定时器只能在定时到了才发生
  339. getData();
  340. getScreenJobData();
  341. // 使用刚指定的配置项和数据显示图表
  342. myChart.setOption(option);
  343. // 设备详情
  344. function getSbDetail(sbNo) {
  345. $.ajax({
  346. type: "get",
  347. url: "/api/sb/infos/no/" + sbNo,
  348. headers: getHeader(),
  349. success: function (response) {
  350. tooltip_message = '<div>设备编号:' + response.data.no +
  351. '<br/>设备名称:' + response.data.name +
  352. '<br/>设备型号:' + response.data.model +
  353. '<br/>使用位置:' + response.data.cph +
  354. '<br/>设备维修员:' + response.data.repairUserName + '</div>';
  355. },
  356. error: function (xhr, textStatus, errorThrown) {
  357. error(xhr, textStatus, errorThrown);
  358. }
  359. });
  360. }
  361. // 任务数据
  362. function getScreenJobData() {
  363. console.log(21);
  364. $.ajax({
  365. type: "get",
  366. url: "/api/check/jobs/screen",
  367. headers: getHeader(),
  368. success: function (response) {
  369. $('#monthNum').text(response.data.finishNum + "/" + response.data.monthNum);
  370. $('#waitNum').text("待完成:" + response.data.waitNum);
  371. $('#rate').text("完成率:" + response.data.rate + "%");
  372. let weekJob = '';
  373. response.data.weekList.forEach(item => {
  374. weekJob = weekJob + ' <div class=\'item\'>\n' +
  375. ' <span>' + item.sbNo + '</span>\n' +
  376. ' <span>' + (item.requirement || '') + '</span>\n' +
  377. ' <span>' + item.startTime + '</span>\n' +
  378. ' </div>'
  379. })
  380. $('.scrollDiv').empty().append(weekJob);
  381. $('.scrollDiv').liMarquee({
  382. direction: 'up',//身上滚动
  383. runshort: false,//内容不足时不滚动
  384. scrollamount: 20//速度
  385. });
  386. },
  387. error: function (xhr, textStatus, errorThrown) {
  388. error(xhr, textStatus, errorThrown);
  389. }
  390. });
  391. }
  392. // setInterval(mockData(), 10000);
  393. setInterval(function () { getData() }, 60000);
  394. // setInterval(function(){ getScreenJobData() }, 60000);
  395. function mockData() {
  396. var data = [
  397. [Math.floor(Math.random() * 1000), Math.floor(Math.random() * 1000), '正常'],
  398. [Math.floor(Math.random() * 1000), Math.floor(Math.random() * 1000), '正常'],
  399. [Math.floor(Math.random() * 1000), Math.floor(Math.random() * 1000), '正常'],
  400. [Math.floor(Math.random() * 1000), Math.floor(Math.random() * 1000), '正常'],
  401. [Math.floor(Math.random() * 1000), Math.floor(Math.random() * 1000), '正常'],
  402. [Math.floor(Math.random() * 1000), Math.floor(Math.random() * 1000), '正常']
  403. ];
  404. var data2 = [
  405. [Math.floor(Math.random() * 1000), Math.floor(Math.random() * 1000), '不知道', '不知道'],
  406. [Math.floor(Math.random() * 1000), Math.floor(Math.random() * 1000), '不知道', '不知道'],
  407. [Math.floor(Math.random() * 1000), Math.floor(Math.random() * 1000), '不知道', '不知道'],
  408. [Math.floor(Math.random() * 1000), Math.floor(Math.random() * 1000), '不知道', '不知道'],
  409. [Math.floor(Math.random() * 1000), Math.floor(Math.random() * 1000), '不知道', '不知道'],
  410. [Math.floor(Math.random() * 1000), Math.floor(Math.random() * 1000), '不知道', '不知道']
  411. ];
  412. option.series[0].data = data;// 正常数据
  413. option.series[1].data = data2;// 异常的红色内容名称
  414. option.series[2].data = data2;// 异常黄点
  415. console.log(data);
  416. console.log(data2);
  417. myChart.setOption(option, true)
  418. }
  419. function getData() {
  420. $.ajax({
  421. type: "get",
  422. url: "/api/sb/infos/screen",
  423. headers: getHeader(),
  424. success: function (response) {
  425. dataList = response.data;
  426. init()
  427. },
  428. error: function (xhr, textStatus, errorThrown) {
  429. error(xhr, textStatus, errorThrown);
  430. }
  431. });
  432. }
  433. function init() {
  434. data = dataList.find(item => item.mapName === mapName)
  435. const normalSbInfoList = [];
  436. const repairSbInfoListRed = [];
  437. const repairSbInfoListYellow = [];
  438. if (data.normalSbInfoList != null) {
  439. for (var i = 0; i < data.normalSbInfoList.length; i++) {
  440. normalSbInfoList.push([data.normalSbInfoList[i].zjm, data.normalSbInfoList[i].jbdh,
  441. data.normalSbInfoList[i].no])
  442. }
  443. }
  444. if (data.repairSbInfoListRed != null) {
  445. for (var i = 0; i < data.repairSbInfoListRed.length; i++) {
  446. repairSbInfoListRed.push([data.repairSbInfoListRed[i].zjm, data.repairSbInfoListRed[i].jbdh,
  447. data.repairSbInfoListRed[i].no])
  448. }
  449. }
  450. if (data.repairSbInfoListYellow != null) {
  451. for (var i = 0; i < data.repairSbInfoListYellow.length; i++) {
  452. repairSbInfoListYellow.push([data.repairSbInfoListYellow[i].zjm, data.repairSbInfoListYellow[i].jbdh,
  453. data.repairSbInfoListYellow[i].no])
  454. }
  455. }
  456. option.series[0].data = normalSbInfoList;// 正常数据:
  457. option.series[1].data = normalSbInfoList;// 正常数据的编号
  458. option.series[2].data = repairSbInfoListRed;// 非计划性报修 红色编号
  459. option.series[3].data = repairSbInfoListRed;// 非计划性报修 红色
  460. option.series[4].data = repairSbInfoListYellow;// 计划性报修 黃色编号
  461. option.series[5].data = repairSbInfoListYellow;// 计划性报修 黃色
  462. myChart.setOption(option, true)
  463. }
  464. function getHeader() {
  465. return {
  466. Authorization: getToken(),
  467. "Cache-Control": "no-cache",
  468. accept: "application/json; charset=utf-8",
  469. 'Content-Type': 'application/json;charset=UTF-8'
  470. // accept: "application/json; charset=utf-8",
  471. // "Access-Control-Allow-Origin": "http://localhost:5000",
  472. // "Access-Control-Allow-Headers":"Origin, X-Requested-With, Content-Type, Accept"
  473. }
  474. }
  475. function getToken() {
  476. const storeTokenJson = JSON.parse(localStorage.getItem(VUE_STORE_BASE + ACCESS_TOKEN))
  477. return 'Bearer ' + storeTokenJson.value
  478. }
  479. (function () {
  480. console.log("滚动")
  481. $('.scrollDiv').liMarquee({
  482. direction: 'up',//身上滚动
  483. runshort: false,//内容不足时不滚动
  484. scrollamount: 20//速度
  485. });
  486. });
  487. </script>
  488. </html>