index.vue 53 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378
  1. <template>
  2. <div class="overview">
  3. <!-- 顶部路由 -->
  4. <div class='menu'>
  5. <div class='home' @click='$emit("update:modelNum", 0)'>
  6. <div class='downright'></div>
  7. <div class='home-box'>
  8. <img src='@/assets/imgs/logo.png' alt />
  9. <span>{{plazas.length>0?formatter(plazaId,plazas):'--'}}</span>
  10. </div>
  11. </div>
  12. <div class='home-right'>
  13. <span style="color:#8D9399">
  14. <span class='span3'>{{times}}</span>
  15. </span>
  16. </div>
  17. </div>
  18. <!-- 面包屑 -->
  19. <nav class="navigation">
  20. <section class="crumbs" >
  21. <span>{{currentZone.cname}}</span>
  22. <span v-for="(item , index) in crumbsHtml" :key="index" @click="navgateFromCrumbs(item[1], index)">{{item[0]}} <em v-if="index !== crumbsHtml.length - 1"> > </em></span>
  23. </section>
  24. <section>
  25. <TreeSelect
  26. width="280"
  27. :hideClear="false"
  28. :isReadOnly='false'
  29. :caption="'选择管理分区'"
  30. :data="regulateDistrictData"
  31. :disabled="false"
  32. @change="selectProjectItem"
  33. />
  34. </section>
  35. </nav>
  36. <main class="container">
  37. <section class="system-general">
  38. <div class="system-main-title">
  39. <h4 class="section-title ">系统概况</h4>
  40. </div>
  41. <div class="system-list">
  42. <ul>
  43. <li @click="getInfoOfProject(item)" :class="['system-item', item.selected ? 'selected':'']" v-for="(item , index) in systemList" :key="index">
  44. <div class="system-name">
  45. <div :class="['img', item.selected ? 'selected':'']">
  46. <img :src="imgSrc(item.smsxt)">
  47. </div>
  48. <span>{{item.smsxtname}}</span>
  49. </div>
  50. <div class="system-equipments" >
  51. <div class="number" v-for="(equip , index) in item.assetTypeList" :key="index">
  52. <p>{{equip.category_name}}<span v-if="equip.is_exception_num">{{equip.is_exception_num}}</span></p>
  53. <p><span>{{equip.asset_num}}</span><span>台</span></p>
  54. </div>
  55. </div>
  56. </li>
  57. </ul>
  58. </div>
  59. </section>
  60. <section class="map-box">
  61. <section class="cards-list">
  62. <div class="card">
  63. <div class="img">
  64. <img src="../../assets/images/icons/ratio.png">
  65. </div>
  66. <p>上线管理说明书数量</p>
  67. <strong>{{plazaInfoCount.upwcCount}}</strong>
  68. </div>
  69. <div class="card">
  70. <div class="img">
  71. <img src="../../assets/images/icons/audit.png">
  72. </div>
  73. <p>当月说明书更新项目数量</p>
  74. <strong>{{plazaInfoCount.rptChangeCount}}</strong>
  75. </div>
  76. <div class="card">
  77. <div class="img">
  78. <img src="../../assets/images/icons/contract.png">
  79. </div>
  80. <p>当月重点关注事项项目数量ff</p>
  81. <strong>{{plazaInfoCount.zhsxChangeCount}}</strong>
  82. </div>
  83. </section>
  84. <section class="map-container">
  85. <div id="map"></div>
  86. <div class="legend">
  87. <div class="legend-bar" v-for="(bar , index) in legendList" :key="index">
  88. <span :style="{background:bar.color}"></span><em>{{bar.num}}</em>
  89. </div>
  90. </div>
  91. </section>
  92. </section>
  93. <section class="ratio-list">
  94. <section class="block" v-for="(item , index) in maintainList" :key="index">
  95. <h4 class="section-title" @click="toggerPanel(item)">{{item.title}}</h4>
  96. <div class="list" :style="panelStyle(item)">
  97. <ul>
  98. <li v-for="(option , index) in item.data" :key="index">
  99. <div class="ratio">
  100. <span>{{option.cname}}</span>
  101. <span>
  102. <span>{{option.rptGlsmsStatistics.due_num}} / </span>
  103. <span>{{option.rptGlsmsStatistics.total}}</span>
  104. </span>
  105. </div>
  106. <div class="bar">
  107. <div class="inner-bar" :style="barStyle(option.rptGlsmsStatistics)"></div>
  108. </div>
  109. </li>
  110. </ul>
  111. <div class="arrow" v-show="item.expand !== 2" :style="{transform: item.expand === 1 ? 'rotate(-90deg)' : 'rotate(90deg)' }" @click="toggerPanel(item)">
  112. <img src="../../assets/images/icons/right.png">
  113. </div>
  114. </div>
  115. </section>
  116. </section>
  117. </main>
  118. </div>
  119. </template>
  120. <script>
  121. let maps = null
  122. import {login} from "@/api/login"
  123. import {getPlazaInfoCount , querySystemCard , getCardList , queryEventStatus} from "@/api/homePage"
  124. import { formatTime } from '@/utils/format.js'
  125. import { mapGetters } from 'vuex'
  126. import ChinaGeoJson from "../../assets/CHN.geo2.json";
  127. import {sortBy} from "lodash"
  128. import OtherJson from "../../assets/regionData/other.json"
  129. import moment from 'moment'
  130. import L from "leaflet";
  131. import "leaflet-contextmenu";
  132. export default {
  133. data() {
  134. return {
  135. crumbsHtml:[],
  136. zoneNames:{
  137. "东北":"dongbei",
  138. "西北":"xibei",
  139. "华北":"huabei",
  140. "华中":"huazhong",
  141. "华东":"huadong",
  142. "中南":"zhongnan",
  143. "西南":"xinan",
  144. "华南":"huanan",
  145. "东南":"dongnan",
  146. "其他":"Other"
  147. },
  148. zoneGroup:{
  149. "dongbei":["heilongjiang","liaoning","jilin"],
  150. "xibei":["neimenggu","ningxia","shanxi1","xinjiang"],
  151. "huabei":["shandong","hebei","beijing","tianjin"],
  152. "huazhong":["shanxi2","henan","hubei"],
  153. "huadong":["jiangsu","shanghai"],
  154. "zhongnan":["hunan","anhui","jiangxi"],
  155. "huanan":["guangdong","guangxi"],
  156. "dongnan":["fujian","zhejiang"],
  157. "xinan":["guizhou","sichuan","yunnan","chongqing"]
  158. },
  159. zoneCity:{
  160. "shandong":["青岛区域","济南区域"]
  161. },
  162. provinceCities:{
  163. "青岛区域": {"province":"shandong", center: [36.06667 , 120.33333]},
  164. "北京区域": {"province":"beijing", center: [39.91667 ,114.41667]},
  165. "天津区域": {"province":"tianjin", center:[39.13333, 117.20000]},
  166. "济南区域": {"province":"shandong", center: [36.40, 117.00]},
  167. "上海区域": {"province":"shanghai", center: [34.50000 , 119.43333]},
  168. "南京区域": {"province":"jiangsu", center:[ 32.05000, 118.78333 ]},
  169. "无锡区域": {"province":"jiangsu", center: [31.34, 120.18]},
  170. "厦门区域": {"province":"fujian", center: [24.46667, 118.10000]},
  171. "宁波区域": {"province":"zhejiang", center: [29.52, 121.33]},
  172. "杭州区域": {"province":"zhejiang", center: [30.16, 120.10]},
  173. "福州区域": {"province":"fujian", center: [26.05, 119.18]},
  174. "合肥区域": {"province":"anhui", center: [31.52, 117.17]},
  175. "长沙区域": {"province":"hunan", center: [28.12, 112.59]},
  176. "南昌区域": {"province":"jiangxi", center: [28.40, 115.55]},
  177. "哈尔滨区域": {"province":"heilongjiang", center: [45.44, 126.36]},
  178. "大连区域": {"province":"liaoning", center: [38.55,121.36]},
  179. "沈阳区域": {"province":"liaoning", center: [41.48, 123.25]},
  180. "长春区域": {"province":"jilin", center: [43.54, 125.19]},
  181. "东莞区域": {"province":"guangdong", center: [23.02,113.45]},
  182. "南宁区域": {"province":"guangxi", center: [22.48, 108.19]},
  183. "广州区域": {"province":"guangdong", center: [23.08, 113.14]},
  184. "太原区域": {"province":"shanxi1", center: [37.54, 112.33]},
  185. "武汉区域": {"province":"hubei", center: [30.35, 114.17]},
  186. "郑州区域": {"province":"henan", center: [34.46, 113.40]},
  187. "乌鲁木齐区域": {"province":"xinjiang", center: [43.45, 87.36]},
  188. "呼和浩特区域": {"province":"neimenggu", center:[40.48, 111.41]},
  189. "西安区域": {"province":"shanxi2", center: [34.26667, 108.95]},
  190. "银川区域": {"province":"ningxia", center: [38.27, 106.16]},
  191. "成都区域": {"province":"sichuan", center: [30.40, 104.04]},
  192. "昆明区域": {"province":"yunnan", center: [25.04, 102.42]},
  193. "重庆区域": {"province":"chongqing", center: [29.35, 106.33]},
  194. },
  195. provincesCenter:{
  196. "anhui":[31.852559691577845, 117.2253589137454],
  197. "beijing": [40.186106951230485,116.42285651967009],
  198. "chongqing": [30.060254204354784, 107.89013862196842],
  199. "fujian": [26.071368377569776, 118.00455426638014],
  200. "gansu":[38.00325279557638, 100.5012462408473],
  201. "guangdong":[23.334243521962527, 113.43297176882082],
  202. "guangxi":[23.83265626692407, 108.79223788629494],
  203. "guizhou":[26.824014276407205, 106.87707047290361],
  204. "hebei": [39.60459587653637, 116.15817616286789],
  205. "heilongjiang":[48.03564457240887, 127.69009579234847],
  206. "henan": [33.902894471142176, 113.61599693888945],
  207. "hubei": [30.988423598416457, 112.27635740895998],
  208. "hunan":[27.633668515110255, 111.70882955621366],
  209. "jiangsu": [32.981911362532585, 119.48201035757698],
  210. "jiangxi":[27.637831291898365, 115.73252266448846],
  211. "jilin":[43.703126756480735, 126.15512329582789],
  212. "liaoning":[41.30041310409345, 122.6094238905765],
  213. "neimenggu":[44.47324785058833, 114.30352505865382],
  214. "ningxia":[37.29635258864683, 106.17634546083286],
  215. "qinghai":[35.7281048004562, 96.0459309719495],
  216. "shandong":[36.374647201891335, 118.18901718013844],
  217. "shanghai":[31.07710542026598, 121.44651073619633],
  218. "shanxi1":[35.263055624551846, 108.88970748546511],
  219. "shanxi2":"",
  220. "sichuan":[30.67066959682666, 102.69531108397375],
  221. "tianjin":[39.29260116656163, 117.35013172238374],
  222. "xinjiang":[41.37183707717329, 85.29450850581013],
  223. "xizang":[31.56242864291341, 88.39191208626079],
  224. "yunnan":[25.004865694004916, 101.4821386658875],
  225. "zhejiang": [29.180481383933902, 120.11087647324501],
  226. },
  227. zoneCenter:{
  228. "dongbei":[46.05917927005029, 126.53664921197083],
  229. "xibei":[43.2417396142428,113.41468998579546],
  230. "huabei":[38.348983721228436, 117.02472809706543],
  231. "huazhong":[34.20577123689604 , 112.71908762827616],
  232. "huadong":[ 32.865884180878325 , 119.61413071750152],
  233. "zhongnan":[28.860875644389676, 114.55131767165491],
  234. "huanan":[23.618261575763043,110.79063366644355 ],
  235. "dongnan":[27.555323121883916, 119.00243042111592],
  236. "xinan":[ 28.255078828220462, 103.33429493217788]
  237. },
  238. legendList:[
  239. {color: "#FDE3E2", num:'≥200'},
  240. {color: "#FEE9D2", num:'100-200'},
  241. {color: "#FFF6EB", num:'50-99'},
  242. {color: "#CCE9FF", num:'10-49'},
  243. {color: "#E1F2FF", num:'1-9'},
  244. {color: "#E1F2FF", num:'0'},
  245. ],
  246. plazaInfoCount:{},
  247. systemList:[],
  248. currentZone:{}, //
  249. currentDistrictData:[], //当前管理分区数据
  250. currentSelectedSys:{},
  251. currentSysId:"",
  252. state: '',
  253. value: 190,
  254. currentPanel:'',
  255. regulateDistrictData: [
  256. ],
  257. projectsCode:[],
  258. maintainList:[
  259. // {
  260. // title:'维保',
  261. // expand:0,
  262. // subList:[
  263. // {
  264. // name:'华南运营中心',
  265. // num1:81,
  266. // num2:128
  267. // },
  268. // {
  269. // name:'华南运营中心',
  270. // num1:31,
  271. // num2:128
  272. // },
  273. // {
  274. // name:'华南运营中心',
  275. // num1:81,
  276. // num2:128
  277. // },
  278. // {
  279. // name:'华南运营中心',
  280. // num1:11,
  281. // num2:128
  282. // },
  283. // {
  284. // name:'华南运营中心',
  285. // num1:41,
  286. // num2:128
  287. // },
  288. // {
  289. // name:'华南运营中心',
  290. // num1:81,
  291. // num2:128
  292. // },
  293. // {
  294. // name:'华南运营中心',
  295. // num1:81,
  296. // num2:128
  297. // },
  298. // {
  299. // name:'华南运营中心',
  300. // num1:81,
  301. // num2:128
  302. // },
  303. // {
  304. // name:'华南运营中心',
  305. // num1:81,
  306. // num2:128
  307. // },
  308. // {
  309. // name:'华南运营中心',
  310. // num1:81,
  311. // num2:128
  312. // },
  313. // {
  314. // name:'华南运营中心',
  315. // num1:81,
  316. // num2:128
  317. // },
  318. // {
  319. // name:'华南运营中心',
  320. // num1:81,
  321. // num2:128
  322. // },
  323. // {
  324. // name:'华南运营中心',
  325. // num1:81,
  326. // num2:128
  327. // },
  328. // ]
  329. // },
  330. // {
  331. // title:'第三方检测33',
  332. // expand:0,
  333. // subList:[
  334. // {
  335. // name:'华南运营中心',
  336. // num1:81,
  337. // num2:128
  338. // },
  339. // {
  340. // name:'华南运营中心',
  341. // num1:81,
  342. // num2:128
  343. // },
  344. // {
  345. // name:'华南运营中心',
  346. // num1:81,
  347. // num2:128
  348. // },
  349. // ]
  350. // },
  351. // {
  352. // title:'专维',
  353. // expand:0,
  354. // subList:[
  355. // {
  356. // name:'华南运营中心',
  357. // num1:81,
  358. // num2:128
  359. // },
  360. // {
  361. // name:'华南运营中心',
  362. // num1:81,
  363. // num2:128
  364. // },
  365. // {
  366. // name:'华南运营中心',
  367. // num1:81,
  368. // num2:128
  369. // },
  370. // {
  371. // name:'华南运营中心',
  372. // num1:81,
  373. // num2:128
  374. // },
  375. // ]
  376. // },
  377. ],
  378. }
  379. },
  380. computed: {
  381. ...mapGetters(['plazas', 'plazaId']),
  382. },
  383. watch: {
  384. },
  385. created() {
  386. this.currentTime()
  387. },
  388. mounted() {
  389. window.vm = this
  390. this.getFrameworkTreeData()
  391. this.getSystemList()
  392. this.queryPlazaInfoCount(1002347,0)
  393. this.getEventStatusData()
  394. },
  395. methods: {
  396. imgSrc(code) {
  397. return require('../../assets/images/icons/' + code + '.png')
  398. },
  399. /**
  400. * 通过导航进行导航
  401. *
  402. */
  403. navgateFromCrumbs (id, index) {
  404. let data = this.getDataByCityCcode(id)
  405. if (!data) return ;
  406. this.currentZone = data
  407. let level = data.level //1集团 2中心 3区域 0广场
  408. if (level === 1) {
  409. this.pantGroupMap(data, this.currentSysId)
  410. } else if(level === 2) {
  411. this.pantZonesMap(data, this.currentSysId)
  412. } else {
  413. this.pantProjectsMap(data, this.currentSysId)
  414. }
  415. this.crumbsHtml = this.crumbsHtml.splice(0, index + 1)
  416. },
  417. /**
  418. * 获取事项状态统计数据
  419. */
  420. getEventStatusData () {
  421. let params = {
  422. getParams: {
  423. "level":1,
  424. "ccode":"0000000000",
  425. }
  426. }
  427. queryEventStatus(params).then(res => {
  428. if (res.result === "success") {
  429. let arr =[]
  430. let data = res.data
  431. for(let key in data) {
  432. let obj = {}
  433. if (data.hasOwnProperty(key)) {
  434. if (key == "0") {
  435. obj.title = "专维" // due_num 即将到期 unfinished 逾期未完成
  436. sortBy(data[key], function(item){
  437. return item.due_num + item.unfinished
  438. }) // 维保,第三方检测排名按照即将到期任务数量从多到少排序,多的靠前。专维按照 逾期未完成 + 即将到期任务数据排序,多的靠前
  439. } else if (key == "1") {
  440. obj.title = "维保"
  441. sortBy(data[key], function(item) {
  442. return item.due_num
  443. })
  444. } else {
  445. obj.title = "第三方检测"
  446. sortBy(data[key], function(item){
  447. return item.due_num
  448. })
  449. }
  450. obj.data = data[key]
  451. obj.expand = 0
  452. }
  453. arr.push(obj)
  454. }
  455. this.maintainList = arr
  456. }
  457. })
  458. },
  459. /**
  460. * 切换系统时 地图响应
  461. * @params system:当前选择的系统
  462. */
  463. getInfoOfProject (system) {
  464. this.systemList.forEach(item=>{ item.selected = false})
  465. system.selected = true
  466. this.currentSelectedSys = system
  467. this.currentSysId = system.smsxt
  468. //1集团 2中心 3区域 0广场
  469. if(this.currentLevel === 1) { //1集团 3区域 0广场
  470. this.pantGroupMap(this.currentDistrictData[0], system.smsxt)
  471. } else if (this.currentLevel === 2) { // 2中心
  472. this.pantZonesMap(this.currentDistrictData[0])
  473. } else if (this.currentLevel === 0) {
  474. this.pantProjectsMap(this.currentDistrictData[0])
  475. }
  476. },
  477. // 处理集团地图
  478. pantGroupMap (data, sysId) {
  479. this.clearAllLayers()
  480. let that = this
  481. data.children.forEach(item=>{
  482. let params = {
  483. getParams: {
  484. // "plazaId":1000423,
  485. "smsxt": sysId, //TODO that.systemList[0].smsxt
  486. "level":1,
  487. "ccode":item.ccode
  488. }
  489. }
  490. querySystemCard(params).then(res => {
  491. if (res.result === "success") {
  492. let name = item.cname.substr(0,2)
  493. let zone = this.zoneNames[name]
  494. let JsonData = require(`../../assets/regionData/${zone}.json`)
  495. let num = 0
  496. let contentHtml = ''
  497. let popup = null
  498. if (res.data) {
  499. let equip = res.data[0]
  500. if (equip.assetTypeList.length > 3) {
  501. equip.assetTypeList = equip.assetTypeList.splice(0,3)
  502. }
  503. contentHtml= that.createPopupHtmlContent(equip.assetTypeList)
  504. equip.assetTypeList.forEach(item => {
  505. num += item.is_exception_num
  506. })
  507. }
  508. let color = that.paintColorByData(num)
  509. let layer = L.geoJSON(JsonData.features, {
  510. style:function(){
  511. return {
  512. 'weight': 1,
  513. 'color': color.border,
  514. 'fillColor':color.area
  515. }
  516. }
  517. }).addTo(maps);
  518. let center = JsonData.features[0].properties.center
  519. let marker = L.divIcon({
  520. html: JsonData.features[0].properties.name,
  521. iconSize:30
  522. })
  523. // let marker = L.circle(center, {radius: 2000}).addTo(maps).bindPopup(contentHtml);
  524. if (res.data) {
  525. popup = L.popup().setLatLng(center).setContent(contentHtml)
  526. layer.on("click", (ev)=>{
  527. let property = ev.layer.feature.properties
  528. let layerName = this.zoneNames[property.name]
  529. let target = that.getDataByCityCcode(item.ccode)
  530. if (target) {
  531. this.currentZone = target
  532. that.createNavpathByData(target)
  533. }
  534. if (layerName !== "其他") {
  535. this.pantZonesMap(item, sysId)
  536. }
  537. })
  538. layer.on("mousemove" , (ev)=> {
  539. maps.openPopup(popup)
  540. })
  541. }
  542. }
  543. })
  544. })
  545. let otherRegion = require("../../assets/regionData/other.json")
  546. let layer = L.geoJSON( otherRegion.features, {
  547. style:function(){
  548. return {
  549. 'weight': 1,
  550. 'color': '#e3ecf3',
  551. 'fillColor': "#fff"
  552. }
  553. }
  554. }).addTo(maps);
  555. maps.setView([38,103], 4)
  556. },
  557. /**
  558. * 生成弹框HTML
  559. */
  560. createPopupHtmlContent (data) {
  561. let that = this
  562. let html = ""
  563. for (let i =0 ; i < data.length; i++) {
  564. let item = data[i]
  565. if (item.is_exception_num) {
  566. html += `<div class="line">
  567. <span>${item.category_name}</span>
  568. <span>${item.asset_num}台</span>
  569. <span><i></i><em>${item.is_exception_num}</em></span>
  570. </div>`
  571. } else {
  572. html += `<div class="line">
  573. <span>${item.category_name}</span>
  574. <span>${item.asset_num}台</span>
  575. </div>`
  576. }
  577. }
  578. return `<div class="leaflet-mypopup-content">
  579. <div class="title"><span>${that.currentSelectedSys.smsxtname}</span>-<span>${that.currentZone.cname}</span></div>
  580. ${html}</div>`
  581. },
  582. /**
  583. * 用于绘制中心下的地图
  584. */
  585. pantZonesMap (data, sysId) {
  586. let vm = this
  587. let obj = []
  588. let htmlContent = []
  589. let pArr = []
  590. let zonenames = new Set()
  591. let zone = data.cname.substr(0,2)
  592. let zonename = this.zoneNames[zone]
  593. this.clearAllLayers()
  594. data.children.forEach(item => {
  595. let name = this.provinceCities[item.cname].province
  596. zonenames.add(name)
  597. let data = require(`../../assets/provinceData/${name}.json`)
  598. let layer = L.geoJSON(data.features,{
  599. style:function(){
  600. return {
  601. 'weight': 1,
  602. 'color': 'black',
  603. 'fillColor': "#f1f1f1"
  604. }
  605. }
  606. }).addTo(maps);
  607. layer.on("click", (ev)=>{
  608. let target = vm.getDataByCityCcode(item.ccode)
  609. if (target) {
  610. vm.currentZone = target
  611. vm.createNavpathByData(target)
  612. }
  613. vm.clearAllLayers()
  614. let data = require(`../../assets/provinceData/${name}.json`)
  615. let layer = L.geoJSON(data.features,{
  616. style:() => {
  617. return {
  618. 'weight': 1,
  619. 'color': 'black',
  620. 'fillColor': "#f1f1f1"
  621. }
  622. }
  623. }).addTo(maps);
  624. this.panTo(this.provincesCenter[name], 6)
  625. })
  626. })
  627. this.panTo(this.zoneCenter[zonename], this.setZoomSize(zonename))
  628. },
  629. /***
  630. * 用于绘制项目的点
  631. */
  632. pantProjectsMap (data) {
  633. let zone = this.provinceCities[data.cname]
  634. let province = zone.province
  635. let center = zone.center
  636. let Json = require(`../../assets/provinceData/${province}.json`)
  637. this.clearAllLayers()
  638. let markerArr = []
  639. let pArr = []
  640. data.children.forEach(item => {
  641. let p = new Promise((resolve,reject) => {
  642. let params = {
  643. getParams: {
  644. "plazaId":1000423,
  645. "smsxt": "1007", //TODO that.systemList[0].smsxt
  646. "level":0,
  647. "ccode": item.ccode
  648. }
  649. }
  650. querySystemCard(params).then(res => {
  651. if (res.result === 'success') {
  652. if (res.data) {
  653. markerArr.push({
  654. name: item.name,
  655. center: item.center,
  656. data: res.data
  657. })
  658. resolve(res.data)
  659. } else {
  660. markerArr.push({
  661. name: item.name,
  662. center: item.center,
  663. data: 0
  664. })
  665. resolve(0)
  666. }
  667. }
  668. })
  669. })
  670. pArr.push(p)
  671. })
  672. Promise.all(pArr).then(result => {
  673. markerArr.forEach(item => {
  674. let popupContent = '<p>Hello world!<br />This is a nice popup.</p>'
  675. L.circle(item.center, {radius: 20000}).bindPopup(popupContent).addTo(maps);
  676. })
  677. L.geoJSON(Json.features,{
  678. style:function(){
  679. return {
  680. 'weight': 1,
  681. 'color': 'black',
  682. 'fillColor': "red"
  683. }
  684. }
  685. }).addTo(maps)
  686. this.panTo(center, 7)
  687. })
  688. },
  689. /**
  690. * 根据数据创建导航路径
  691. */
  692. createNavpathByData (data) {
  693. if (data.level === 1) {
  694. this.crumbsHtml = []
  695. } else {
  696. let pathArr = data.path.split("/")
  697. let newArr = []
  698. pathArr.forEach(item => {
  699. newArr.push(item.split("&"))
  700. })
  701. this.crumbsHtml = newArr
  702. }
  703. this.currentZone = data
  704. },
  705. // 获取 区域/中心/项目
  706. selectProjectItem (ids, data) {
  707. this.createNavpathByData(data)
  708. this.currentZone = data
  709. let JSONName = data.cname
  710. let level = data.level // //1集团 2中心 3区域 0广场
  711. if (level === 1) {
  712. this.pantGroupMap(data,"1001")
  713. } else if (level === 2) {
  714. this.pantZonesMap(data, '1001')
  715. } else if (level === 3) {
  716. let res = this.provinceCities[JSONName]
  717. this.clearAllLayers()
  718. let data = require(`../../assets/provinceData/${res.province}.json`)
  719. let layer = L.geoJSON(data.features,{
  720. style:function(){
  721. return {
  722. 'weight': 1,
  723. 'color': 'black',
  724. 'fillColor':'red'
  725. }
  726. }
  727. }).addTo(maps);
  728. this.panTo(res.center, 7)
  729. } else { // 点击广场时 直接跳转到详情页 地图不用响应
  730. // this.$router.push({path:"/"})
  731. }
  732. },
  733. //查询项目信息统计数量
  734. queryPlazaInfoCount (ccode, level) {
  735. let params = {
  736. getParams: {
  737. "ccode":ccode,
  738. "level":level,
  739. }
  740. }
  741. getPlazaInfoCount(params).then(res => {
  742. if (res.result === 'success') {
  743. if (res.data) {
  744. this.plazaInfoCount = res.data
  745. }
  746. }
  747. })
  748. },
  749. //** */
  750. getDataByCityCcode (id) {
  751. return recursionFindData(this.currentDistrictData, id)
  752. let target = null
  753. function recursionFindData (data, id) {
  754. data.forEach(item => {
  755. if (item.ccode === id) {
  756. target = item
  757. } else {
  758. if (item.children && item.children.length) {
  759. recursionFindData(item.children , id)
  760. }
  761. }
  762. })
  763. if (target) {
  764. return target
  765. }
  766. }
  767. },
  768. // 获取 中心 区域 项目 数据树数据
  769. getFrameworkTreeData () {
  770. login({
  771. "username":"xiejialin1",
  772. "returnTree":true
  773. }).then(res => {
  774. if (res.result === 'success') {
  775. recursionData(res.treeData)
  776. let data = res.treeData[0]
  777. this.currentDistrictData = res.treeData
  778. this.currentZone = data
  779. this.currentLevel = res.treeData[0].level // 初始化的时候判断是哪一级 //1集团 2中心 3区域 0广场
  780. this.regulateDistrictData = [data]
  781. this.initMap()
  782. }
  783. function recursionData (data, parent) {
  784. data.forEach(item => {
  785. item.name= item.cname
  786. item.id = item.cid
  787. if (parent) {
  788. item.path = parent + "/" + (item.cname + "&" + item.ccode)
  789. }
  790. let children = item.children
  791. if (Array.isArray(children) && children.length) {
  792. recursionData(children, ( item.path? item.path: item.cname +"&"+ item.ccode))
  793. }
  794. })
  795. }
  796. })
  797. },
  798. //初始化地图
  799. initMap() {
  800. let that = this;
  801. maps = L.map("map", {
  802. center: new L.LatLng(38, 103),
  803. zoom: 4,
  804. crs: L.CRS.EPSG3857,
  805. minZoom: 3,
  806. maxZoom: 14,
  807. zoomControl: false,
  808. attributionControl: false,
  809. contextmenu: true,
  810. contextmenuWidth: 140,
  811. })
  812. if(this.currentLevel === 1) { //1集团 3区域 0广场
  813. this.pantGroupMap(this.currentDistrictData[0],"1001")
  814. } else if (this.currentLevel === 2) { // 2中心
  815. this.pantZonesMap(this.currentDistrictData[0])
  816. } else if (this.currentLevel === 0) {
  817. this.pantProjectsMap(this.currentDistrictData[0])
  818. }
  819. },
  820. //**清空地图 并添加全国底图*/
  821. clearAllLayers(){
  822. maps.eachLayer(function(layer){
  823. maps.removeLayer(layer)
  824. })
  825. let data = require(`../../assets/geoData/ChinaBorder.json`)
  826. L.geoJSON(data.features, {
  827. style:function(){
  828. return {
  829. 'weight': 1,
  830. 'color': 'black',
  831. 'fillColor':'#f1f1f1'
  832. }
  833. }
  834. }).addTo(maps);
  835. },
  836. panTo(center, zoom){
  837. maps.panTo(center)
  838. maps.setView(center, zoom)
  839. },
  840. setZoomSize (zone) {
  841. if (["habei","dongbei"].includes(zone)) {
  842. return 5
  843. } else if (["huadong","dongnan","huanan"].includes(zone)) {
  844. return 7
  845. } else if (["zhongnan","huabei","xinan","huazhong"].includes(zone)) {
  846. return 6
  847. } else if (["xibei"].includes(zone)) {
  848. return 4
  849. }
  850. },
  851. toggerPanel (item) {
  852. this.currentPanel = item.title
  853. // expand 0 初始状态 1 展开状态 2 隐藏状态
  854. if (item.expand === 0 || item.expand === 2) {
  855. item.expand = 1 // 展开
  856. this.maintainList.forEach(option => {
  857. if (option.title !== item.title) {
  858. option.expand = 2 // 隐藏
  859. }
  860. })
  861. } else {
  862. this.maintainList.forEach(option => {
  863. option.expand = 0 // 回到初始状态
  864. })
  865. }
  866. },
  867. panelStyle (item) {
  868. // expand 0 初始状态 1 展开状态 2 隐藏状态
  869. if (item.expand === 0) {
  870. return {height:'22rem'}
  871. } else if (item.expand === 1) {
  872. return {height:'63rem'}
  873. } else {
  874. return {height:'0', margin:0}
  875. }
  876. },
  877. /**
  878. * 计算长度
  879. */
  880. barStyle(item) {
  881. let type = item.type
  882. let ratio = (item.unfinished/ item.total ) * 100
  883. let bg = ''
  884. if ( type === 0) {
  885. bg = "linear-gradient(to right, #F54E45 , #F54E45)"
  886. }
  887. if ( type === 1) {
  888. bg = "linear-gradient(to right, #F58300 , #F58300)"
  889. }
  890. if ( type === 2) {
  891. bg = "linear-gradient(to right, #369CF7 , #025BAA)"
  892. }
  893. return {
  894. width: ratio + '%',
  895. backgroundImage: bg
  896. }
  897. },
  898. // 根据数据渲染颜色
  899. paintColorByData (data) {
  900. let color = {
  901. area:'',
  902. border:''
  903. }
  904. if (data >= 200) {
  905. color.area = "#FDE3E2"
  906. color.border = "#FBBFBC"
  907. } else if (data >= 100 && data < 200) {
  908. color.area = "#FEE9D2"
  909. color.border = "#FFBA6B"
  910. } else if (data>=50 && data<100) {
  911. color.area = "#FFF6EB"
  912. color.border = "#F7DC82"
  913. } else if (data >= 10 && data< 50) {
  914. color.area = "#CCE9FF"
  915. color.border = "#4EB1FD"
  916. } else if (data>= 1 && data <10) {
  917. color.area = "#E1F2FF"
  918. color.border = "#82C7FC"
  919. } else {
  920. color.area = "#EEEEEE"
  921. color.border = "#CCC"
  922. }
  923. return color
  924. },
  925. currentTime() {
  926. this.times = moment().format('YYYY.MM.DD HH:mm')
  927. setTimeout(this.currentTime, 1000)
  928. },
  929. /**根据选择的系统重新渲染地图
  930. * param sysId:系统Id
  931. */
  932. formatter(str, arrv) {
  933. if (str && arrv) {
  934. const Objs = arrv.find(e => e && e.plazaid == str)
  935. return Objs ? Objs.plazaname : '--'
  936. } else {
  937. return ''
  938. }
  939. },
  940. //TODO plazaId目前是写死的 后期需要更换成用户对应的ID
  941. getSystemList () {
  942. let params = {
  943. getParams: {
  944. "plazaId":1000423,
  945. }
  946. }
  947. getCardList(params).then(res => {
  948. if (res.result == 'success') {
  949. let result = res.data
  950. if (result && Array.isArray(result)) {
  951. result.forEach(item => {
  952. item.assetTypeList = item.assetTypeList.splice(0,3)
  953. })
  954. res.data.forEach(item => {
  955. item.selected = false
  956. })
  957. this.currentSelectedSys = res.data[0]
  958. this.currentSysId = res.data[0].smsxt
  959. this.systemList = res.data
  960. }
  961. }
  962. })
  963. },
  964. },
  965. components: {}
  966. }
  967. </script>
  968. <style scoped lang="less">
  969. .overview{
  970. height: 100vh;
  971. background: rgba(247,249,250,1);
  972. .menu {
  973. height: 48px;
  974. min-width: 1366px;
  975. color: #1f2429;
  976. font-size: 1.6rem;
  977. background: rgba(255, 255, 255, 1);
  978. box-shadow:0px 2px 10px 0px rgba(31,35,41,0.1);
  979. overflow: hidden;
  980. .home {
  981. width: 265px;
  982. height: 48px;
  983. // line-height: 48px;
  984. text-align: center;
  985. cursor: pointer;
  986. color: #ffffff;
  987. float: left;
  988. margin-right: 83px;
  989. // background: linear-gradient(180deg, rgba(54, 156, 247, 1) 0%, rgba(2, 91, 170, 1) 100%);
  990. background: linear-gradient(180deg, rgba(54, 156, 247, 1) 0%, rgba(2, 91, 170, 1) 100%);
  991. position: relative;
  992. .downright {
  993. position: absolute;
  994. width: 0;
  995. height: 0;
  996. border-left: 20px solid transparent;
  997. border-bottom: 48px solid #fff;
  998. right: 0px;
  999. top: 0;
  1000. }
  1001. .home-box {
  1002. height: 100%;
  1003. display: flex;
  1004. align-items: center;
  1005. img {
  1006. width: 28px;
  1007. height: 28px;
  1008. margin-left: 20px;
  1009. margin-right: 24px;
  1010. margin-top: -3px;
  1011. }
  1012. span {
  1013. font-size: 2rem;
  1014. font-family: MicrosoftYaHei;
  1015. height: 27px;
  1016. line-height: 27px;
  1017. margin-top: -4px;
  1018. &:after {
  1019. content: '|';
  1020. position: absolute;
  1021. left: 60px;
  1022. }
  1023. }
  1024. }
  1025. }
  1026. & > div:nth-of-type(2) {
  1027. & > div {
  1028. line-height: 48px;
  1029. text-align: center;
  1030. //background: url('../assets/images/topbar1.png') no-repeat;
  1031. float: left;
  1032. width: 80px;
  1033. height: 48px;
  1034. cursor: pointer;
  1035. transition: all 0.2s;
  1036. }
  1037. .is-active {
  1038. color: #025baa;
  1039. font-weight: bolder;
  1040. border-bottom: 2px solid #025baa;
  1041. background: linear-gradient(180deg, rgba(2, 91, 170, 0) 0%, rgba(2, 91, 170, 0.2) 100%);
  1042. }
  1043. }
  1044. .home-right {
  1045. float: right;
  1046. margin-right: 20px;
  1047. line-height: 48px;
  1048. color: #646c73;
  1049. font-size: 1.4rem;
  1050. cursor: pointer;
  1051. display: flex;
  1052. align-content: center;
  1053. img {
  1054. margin-top: -2px;
  1055. }
  1056. .span-out {
  1057. position: relative;
  1058. margin: 0 16px;
  1059. .span2-num {
  1060. position: absolute;
  1061. right: -5px;
  1062. top: 5px;
  1063. display: inline-block;
  1064. width: 18px;
  1065. height: 18px;
  1066. background: red;
  1067. border-radius: 90px;
  1068. font-size: 1.2rem;
  1069. text-align: center;
  1070. line-height: 18px;
  1071. color: #ffffff;
  1072. }
  1073. }
  1074. }
  1075. .span1,
  1076. .span2 {
  1077. padding: 0 6px 0 3px;
  1078. }
  1079. .span3 {
  1080. padding-left: 3px;
  1081. }
  1082. }
  1083. .navigation{
  1084. display: flex;
  1085. justify-content: space-between;
  1086. align-items: center;
  1087. height: 50px;
  1088. padding: 0 16px;
  1089. background: white;
  1090. .crumbs{
  1091. span{
  1092. cursor: pointer;
  1093. }
  1094. span:first-child{
  1095. display: inline-block;
  1096. width: 14.4rem;
  1097. height: 2.8rem;
  1098. margin-right: 1.2rem;
  1099. border: 1px solid rgba(195, 199, 203, 1);
  1100. border-radius: 1.4rem;
  1101. text-align: center;
  1102. line-height: 2.8rem;
  1103. font-size: 14px;
  1104. cursor: default;
  1105. }
  1106. span:last-child{
  1107. font-weight: bold;
  1108. }
  1109. }
  1110. }
  1111. .container{
  1112. display: flex;
  1113. justify-content: space-between;
  1114. height: calc(100vh - 98px);
  1115. padding: 1.2rem 1.6rem;
  1116. .section-title{
  1117. padding-left: 10px;
  1118. border-left: 4px solid #025BAA;
  1119. color: #1F2429;
  1120. font-size: 1.6rem;
  1121. font-weight: bolder;
  1122. line-height: 2rem;
  1123. }
  1124. .system-general{
  1125. width: 25.4%;
  1126. box-sizing: border-box;
  1127. background: white;
  1128. .system-main-title{
  1129. padding: 2rem 0 2.4rem 1.6rem;
  1130. }
  1131. .system-list{
  1132. ul{
  1133. li.system-item{
  1134. display: flex;
  1135. justify-content: space-around;
  1136. align-items: center;
  1137. width: calc(100% - 3.2rem);
  1138. margin-left: 1.6rem;
  1139. padding: 2.7rem 0;
  1140. box-sizing: border-box;
  1141. border:1px solid white;
  1142. border-radius: 4px;
  1143. border-bottom: 1px solid #EFF0F1;
  1144. transition: 0.5s;
  1145. cursor: pointer;
  1146. .system-name{
  1147. display: flex;
  1148. align-items: center;
  1149. width: 30%;
  1150. padding-right: 2rem;
  1151. padding-left:1.6rem;
  1152. .img{
  1153. height: 2.8rem;
  1154. width: 2.8rem;
  1155. display: flex;
  1156. align-items: center;
  1157. justify-content: center;
  1158. border-radius: 50%;
  1159. background: #dce7f0;
  1160. filter: saturate(0%);
  1161. img{
  1162. width: 1.6rem;
  1163. height: 1.6rem;
  1164. }
  1165. }
  1166. .selected {
  1167. filter: saturate(100%);
  1168. }
  1169. span{
  1170. display: inline-block;
  1171. margin-left: 0.8rem;
  1172. color: #1F2429;
  1173. font-size: 1.4rem;
  1174. font-weight: bolder;
  1175. border-right: 1px solid #EFF0F1;
  1176. }
  1177. }
  1178. .system-equipments{
  1179. width: 70%;
  1180. display: flex;
  1181. align-items: center;
  1182. .number{
  1183. width: 33.3%;
  1184. p:nth-of-type(1) {
  1185. position: relative;
  1186. color: #1F2429;
  1187. font-size: 1.4rem;
  1188. line-height: 1.6rem;
  1189. span{
  1190. position: absolute;
  1191. top:-10px;
  1192. padding: 2px 4px;
  1193. border-radius: 0.9rem;
  1194. font-size: 1.2rem;
  1195. color: #F54E45;
  1196. background: #FDE3E2;
  1197. }
  1198. }
  1199. p:nth-of-type(2) {
  1200. span:first-child{
  1201. color:#1F2429;
  1202. font-size: 1.8rem;
  1203. font-weight:bold;
  1204. }
  1205. }
  1206. }
  1207. }
  1208. }
  1209. li.selected{
  1210. border-color: rgba(0, 118, 197, 0.6);
  1211. box-shadow: 0 2px 10px 0px rgba(0, 118, 197, 0.4);
  1212. }
  1213. li:last-child{
  1214. border-bottom: none;
  1215. }
  1216. li:hover{
  1217. border-color: #66ADDD;
  1218. box-shadow: 0 2px 10px 0px rgba(204, 100, 77, 0.4);
  1219. }
  1220. }
  1221. }
  1222. }
  1223. .map-box{
  1224. width: calc(56.6% - 2.4rem);
  1225. margin: 0 12px;
  1226. .cards-list{
  1227. display: flex;
  1228. justify-content: space-between;
  1229. .card{
  1230. width: calc( (100% - 24px) / 3);
  1231. box-sizing: border-box;
  1232. padding: 12px 16px;
  1233. border-radius: 4px;
  1234. background: white;
  1235. .img{
  1236. display: flex;
  1237. justify-content: center;
  1238. align-items: center;
  1239. width: 4.4rem;
  1240. height: 4.4rem;
  1241. border-radius: 50%;
  1242. img{
  1243. width: 2rem;
  1244. height: 2rem;
  1245. }
  1246. }
  1247. }
  1248. div:nth-of-type(1) .img{
  1249. background: rgba(130,199,252,0.14);
  1250. }
  1251. div:nth-of-type(2) .img{
  1252. background: rgba(0,214,185,0.14);
  1253. }
  1254. div:nth-of-type(3) .img{
  1255. background: rgba(255,186,107,0.14);
  1256. }
  1257. p{
  1258. color:#646C73;
  1259. margin: 12px 0 8px 0;
  1260. }
  1261. strong{
  1262. color:#1F2429;
  1263. font-size: 2.4rem;
  1264. }
  1265. }
  1266. .map-container{
  1267. position: relative;
  1268. height: 70rem;
  1269. #map{
  1270. height: 70rem;
  1271. overflow: hidden;
  1272. }
  1273. .legend{
  1274. position: absolute;
  1275. left: 1.4rem;
  1276. bottom: 2.7rem;
  1277. padding: 0.6rem;
  1278. background: white;
  1279. .legend-bar{
  1280. display: flex;
  1281. align-items: center;
  1282. span{
  1283. display: inline-block;
  1284. height: 4px;
  1285. width: 20px;
  1286. margin-right: 12px;
  1287. }
  1288. em{
  1289. }
  1290. }
  1291. }
  1292. }
  1293. }
  1294. .ratio-list{
  1295. width: 18%;
  1296. .block{
  1297. position: relative;
  1298. padding:1.2rem 1.6rem;
  1299. border-radius: 4px;
  1300. margin-bottom: 1.2rem;
  1301. background: white;
  1302. .section-title{
  1303. font-size: 1.6rem;
  1304. }
  1305. .list{
  1306. margin-top: 1.4rem;
  1307. height: 21rem;
  1308. overflow: hidden;
  1309. transition: height 0.3s ease-in-out;
  1310. ul{
  1311. overflow: hidden;
  1312. li{
  1313. display: flex;
  1314. flex-direction: column;
  1315. justify-content: center;
  1316. margin-bottom: 1.2rem;
  1317. .ratio{
  1318. display: flex;
  1319. justify-content: space-between;
  1320. margin-bottom: 0.5rem;
  1321. span:first-child{
  1322. color:#646C73;
  1323. font-size: 1.4rem;
  1324. }
  1325. }
  1326. .bar{
  1327. position: relative;
  1328. height: 6px;
  1329. border-radius: 3px;
  1330. background: #C3C7CB;
  1331. .inner-bar{
  1332. position: absolute;
  1333. height: 6px;
  1334. left: 0;
  1335. top: 0;
  1336. border-radius: 3px;
  1337. }
  1338. }
  1339. }
  1340. }
  1341. }
  1342. .arrow{
  1343. position: absolute;
  1344. bottom: 0.5rem;
  1345. left:50%;
  1346. cursor: pointer;
  1347. transform-origin: center center;
  1348. transform: translateX(-50%) rotate(90deg);
  1349. }
  1350. }
  1351. section:last-child.block{
  1352. margin-bottom: 0;
  1353. }
  1354. }
  1355. }
  1356. }
  1357. </style>