MapBox-copy.vue 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959
  1. <template>
  2. <div>
  3. <div class="space-main" id="spaceMain">
  4. <div class="space-box"
  5. v-if="mapData && mapData.spaceList && mapData.spaceList.length"
  6. v-for="(area,index) in mapData.spaceList"
  7. :style="{width:area.width+'px',
  8. height:area.height+'px',
  9. top:area.top+'px',
  10. left:area.left+'px'}"
  11. >
  12. <div class="space"
  13. :id="'space'+area.id"
  14. :class="[area.canClick?'':'click-disable',selectArea.id===area.id?'select':'',
  15. spaceInfo.spaceId===area.spaceId && spaceInfo.isPermanent?'use-select':'']"
  16. @click.stop="checkSpace(area)"
  17. :style="{backgroundColor:area.backgroundColor?area.backgroundColor:''}"
  18. >
  19. <div class="device"
  20. :class="selectArea.id===area.id?'select-device':''"
  21. v-show="area.width*displacement.scale>24 && area.height*displacement.scale>24"
  22. >
  23. <img :src="area.icon" v-if="selectArea.id!==area.id && area.icon">
  24. <img :src="area.selectIcon" v-else class="select-icon" alt="">
  25. <template v-if="area.localName">
  26. <span v-if="area.height>80 && area.localName.length*12<area.width || selectArea.id===area.id"
  27. style="font-size: 12px"
  28. >{{ area.localName }}</span>
  29. </template>
  30. </div>
  31. <!-- <div class="circle" v-else :style="{backgroundColor: area.circleColor?area.circleColor:''}"></div>-->
  32. </div>
  33. </div>
  34. </div>
  35. <!--地图右侧的操作按钮-->
  36. <div class="map-toolbar">
  37. <img
  38. :src="parseImgUrl('map-icon','icon-search-big.svg')"
  39. @click.stop="goSearch"
  40. class="icon-search" alt=""
  41. >
  42. <div class="toolbar-item" @click.stop="checkFloor">
  43. <span class="text-hidden">{{ floorItem.localName }}</span>
  44. </div>
  45. <div class="toolbar-item" @click.stop="checkBuilding">
  46. <span class="text-hidden">{{ buildingItem.localName }}</span>
  47. </div>
  48. <!-- <div class="toolbar-item">-->
  49. <!-- <img src="../../assets/images/map-icon/icon-floor-arrow.svg" alt="">-->
  50. <!-- </div>-->
  51. </div>
  52. <!-- 选择建筑 -->
  53. <van-popup v-model:show="showBuilding"
  54. teleport="body"
  55. class="buiding-box"
  56. style="width: 40%;height: 100%;padding: 20px"
  57. position="right"
  58. >
  59. <div class="buiding-item"
  60. :key="item.id"
  61. :class="buildingItem.buildingId===item.id?'active':''"
  62. @click.stop="comfirmBuilding(item)"
  63. v-for="item in buildingData"
  64. >
  65. {{ item.localName }}
  66. </div>
  67. </van-popup>
  68. <!-- 选择楼层 -->
  69. <van-popup v-model:show="showFloor"
  70. teleport="body"
  71. class="buiding-box"
  72. style="width: 40%;height: 100%;padding: 20px"
  73. position="right"
  74. >
  75. <div class="buiding-item"
  76. :key="item.id"
  77. :class="floorItem.id===item.id?'active':''"
  78. @click.stop="comfirmFloor(item)"
  79. v-for="item in floorData"
  80. >
  81. {{ item.localName }}
  82. </div>
  83. </van-popup>
  84. <!--搜索-->
  85. <van-popup v-model:show="showSearch"
  86. teleport="body"
  87. class="buiding-box"
  88. style="width: 100%;height: 100%"
  89. position="right"
  90. >
  91. <div style="width: 100%;height: 100%">
  92. <space-search @closeSearch="closeSearch"></space-search>
  93. </div>
  94. </van-popup>
  95. </div>
  96. </template>
  97. <script lang="ts">
  98. import { defineComponent, onMounted, nextTick, reactive, toRefs, watch } from 'vue'
  99. import { mapObj } from '@/model/map'
  100. import {
  101. getLocalStorageFloor,
  102. getStorageSpaceId,
  103. localStorageFloor,
  104. localStorageSpaceId,
  105. parseImgUrl,
  106. setLocalNewSpaceInfo
  107. } from '@/utils'
  108. import { Toast, Dialog } from 'vant'
  109. import { getBuildingList, getFloorList, getMapInfo } from '@/apis/envmonitor'
  110. import SpaceSearch from '@/views/envmonitor/Search/SpaceSearch.vue'
  111. import { useRouter } from 'vue-router'
  112. import { getSpaceType, mapIcon } from '@/utils/mapIcon'
  113. export default defineComponent({
  114. props: {
  115. projectId: {
  116. type: String,
  117. default: () => ''
  118. },
  119. spaceInfo: {
  120. type: Object,
  121. default: () => {
  122. }
  123. },
  124. isSetSpace: {
  125. type: Boolean,
  126. default: () => false
  127. }
  128. },
  129. components: {
  130. SpaceSearch
  131. },
  132. setup(props, contx) {
  133. const router = useRouter()
  134. const mapData: any = {}
  135. const document: any = window.document
  136. const screenInfo: any = {
  137. screenWidth: document.body.clientWidth,
  138. screenHeight: document.body.clientHeight
  139. }
  140. const comMapScale: any = 0.8
  141. const displacement: any = {
  142. scale: 1,
  143. pageX: 0,
  144. pageX2: 0,
  145. originScale: 0,
  146. moveable: false
  147. }
  148. let buildingData: any = []
  149. let floorData: any = []
  150. let floorItem: any = {}
  151. let selectArea: any = {}
  152. const proxyData = reactive({
  153. parseImgUrl: parseImgUrl,
  154. isSetSpace: props.isSetSpace, // isSetSpace:true 代表常驻空间页面展示
  155. widthMapScale: 1,
  156. tempScale: 0.8,
  157. comMapScale: comMapScale,
  158. heightScale: 1,
  159. showSearch: false,
  160. showBuilding: false,
  161. showFloor: false,
  162. buildingItem: {
  163. buildingId: '',
  164. localName: ''
  165. },
  166. floorData: floorData,
  167. floorItem: floorItem,
  168. buildingData: buildingData,
  169. mapData: mapData,
  170. selectArea: selectArea,
  171. displacement: displacement,
  172. screenInfo: screenInfo,
  173. // 切换楼层的时候恢缩放和滚动的样式
  174. clearPreStyle() {
  175. let mapDom = document.querySelector('#map')
  176. mapDom.scrollLeft = 0
  177. mapDom.scrollTop = 0
  178. let matrix_box: any = document.querySelector('#spaceMain')
  179. // 记住使用的缩放值
  180. proxyData.displacement.scale = 1
  181. // 图像应用缩放效果
  182. // console.log(newScale);
  183. matrix_box.style.transform = 'scale(' + 1 + ')'
  184. },
  185. /**
  186. * 地图滚动
  187. */
  188. mapScroll() {
  189. let mapDom = document.querySelector('#map')
  190. let houseDesDom = document.querySelector('#houseDes')
  191. let houseHeight: any = houseDesDom ? houseDesDom.offsetHeight : 0
  192. // let headerDom = document.querySelector('#header')
  193. // let headerHeight: any = headerDom.offsetHeight
  194. mapDom.addEventListener('scroll', () => {
  195. let scrollTop: any = mapDom.scrollTop
  196. let height: any = proxyData.mapData.height * proxyData.displacement.scale
  197. let tempHeight: any = proxyData.screenInfo.screenHeight - houseHeight - 130
  198. if (height < tempHeight) {
  199. mapDom.scrollTop = 0
  200. } else {
  201. if (height - tempHeight < scrollTop) {
  202. mapDom.scrollTop = height - tempHeight
  203. }
  204. }
  205. })
  206. },
  207. /**
  208. * 关闭搜索页面
  209. * @param item
  210. */
  211. closeSearch(item: any) {
  212. proxyData.showSearch = false
  213. if (item) {
  214. proxyData.loadingStart()
  215. let searchSpace: any = {
  216. buildingId: item.buildingId,
  217. buildingName: '',
  218. floorId: item.floorId,
  219. floorName: '',
  220. spaceId: item.id
  221. }
  222. proxyData.init(searchSpace)
  223. }
  224. },
  225. /*
  226. 去搜索页面
  227. */
  228. goSearch() {
  229. proxyData.showSearch = true
  230. // router.push({ path: '/search' })
  231. },
  232. /**
  233. * 设置选中的空间的位置,
  234. */
  235. setSelectSpacePosition(area: any) {
  236. setTimeout(() => {
  237. proxyData.setScrollLeft(area)
  238. proxyData.scrollTop(area)
  239. })
  240. },
  241. /**
  242. * 判断像左还是像右滚动
  243. */
  244. setScrollLeft(area: any) {
  245. let mapDom = document.getElementById('map')
  246. let left: any = area.left * proxyData.displacement.scale - (proxyData.screenInfo.screenWidth - area.width * proxyData.displacement.scale) / 2
  247. mapDom.scrollLeft = left
  248. },
  249. /**
  250. * 获取竖着的方向
  251. */
  252. scrollTop(area: any) {
  253. let mapDom = document.querySelector('#map')
  254. let houseDesDom = document.querySelector('#houseDes')
  255. let houseHeight: any = houseDesDom ? houseDesDom.offsetHeight : 0
  256. if ((area.top + area.height) * proxyData.displacement.scale > proxyData.screenInfo.screenHeight - houseHeight - 20) {
  257. mapDom.scrollTop = (area.top * proxyData.displacement.scale - (proxyData.screenInfo.screenHeight - houseHeight) / 2 + (area.height * proxyData.displacement.scale) / 2)
  258. } else {
  259. if ((area.top - area.height) * proxyData.displacement.scale < mapDom.scrollTop) {
  260. mapDom.scrollTop = (area.top - area.height) * proxyData.displacement.scale
  261. }
  262. }
  263. },
  264. /**
  265. * 切换空间
  266. */
  267. checkSpace(area: any) {
  268. if (area.canClick) {
  269. proxyData.setSelectSpacePosition(area)
  270. if (proxyData.isSetSpace) {
  271. // 记录当前选中的id
  272. proxyData.comfirSetSpace(area)
  273. } else {
  274. proxyData.selectArea = area
  275. proxyData.setLocalSpaceInfo()
  276. // 记录当前选中的id
  277. contx.emit('changeSpaceId', proxyData.selectArea.spaceId)
  278. }
  279. } else {
  280. Toast('不可选区域')
  281. }
  282. },
  283. /**
  284. * 确认设置为常驻空间
  285. */
  286. comfirSetSpace(item: any) {
  287. if (item.spaceId === props.spaceInfo.spaceId) {
  288. Dialog.confirm({
  289. title: '取消常驻空间',
  290. confirmButtonColor: '#000000',
  291. cancelButtonColor: '#4D5262',
  292. message: `是否取消常驻空间设置?`
  293. }).then(() => {
  294. contx.emit('delPermanentSpace')
  295. }).catch(() => {
  296. })
  297. } else {
  298. Dialog.confirm({
  299. title: '设置常驻空间',
  300. confirmButtonColor: '#000000',
  301. cancelButtonColor: '#4D5262',
  302. message: `是否将常驻空间设置为${item.localName}?`
  303. }).then(() => {
  304. proxyData.selectArea = item
  305. contx.emit('changeSpaceId', proxyData.selectArea.spaceId)
  306. }).catch(() => {
  307. })
  308. }
  309. },
  310. /**
  311. * 本地缓存最新的空间建筑信息,提供给首次进入页面使用
  312. */
  313. setLocalSpaceInfo() {
  314. localStorageSpaceId(proxyData.buildingItem.buildingId, proxyData.floorItem.id, proxyData.selectArea.spaceId)
  315. let spaceInfo: any = {
  316. buildingId: proxyData.buildingItem.buildingId,
  317. buildingName: proxyData.buildingItem.localName,
  318. floorId: proxyData.floorItem.id,
  319. floorName: proxyData.floorItem.localName,
  320. spaceId: proxyData.selectArea.spaceId // 上格云3
  321. }
  322. setLocalNewSpaceInfo(spaceInfo)
  323. },
  324. /**
  325. * 地图放大的距离
  326. * @param start
  327. * @param stop
  328. */
  329. getDistance(start: any, stop: any) {
  330. return Math.hypot(stop.x - start.x, stop.y - start.y)
  331. },
  332. /**
  333. * 格式化地图数据
  334. */
  335. formateMapData() {
  336. let data: any = proxyData.mapData
  337. if (data) {
  338. proxyData.setSpaceScale()
  339. proxyData.setTempScale()
  340. if (data.width < 3000) {
  341. proxyData.comMapScale = 0.8
  342. }
  343. data.width = data.width * proxyData.comMapScale
  344. data.height = data.height * proxyData.comMapScale
  345. let spaceList: any = data?.spaceList ?? []
  346. for (let i = 0; i < spaceList.length; i++) {
  347. let item = spaceList[i]
  348. item.width = item.width * proxyData.comMapScale
  349. item.height = item.height * proxyData.comMapScale
  350. item.top = item.top * proxyData.comMapScale
  351. item.left = item.left * proxyData.comMapScale
  352. // item.canClick = !item.canClick
  353. proxyData.setSpaceIcon(item)
  354. }
  355. }
  356. },
  357. // 获取空间最小宽
  358. setSpaceScale() {
  359. let data: any = proxyData.mapData
  360. if (data) {
  361. let spaceList: any = data?.spaceList ?? []
  362. let minHeight: any = Math.min.apply(null, spaceList.map((item: any) => item.height))
  363. let minWidth: any = Math.min.apply(null, spaceList.map((item: any) => item.width))
  364. let min: any = minHeight < minWidth ? minHeight : minWidth
  365. min = min ? min : 30
  366. proxyData.comMapScale = 30 / min
  367. }
  368. },
  369. // 缩放的临界值修改
  370. setTempScale() {
  371. proxyData.tempScale = 0.4
  372. let data: any = proxyData.mapData
  373. if (data) {
  374. let width: any = proxyData.mapData.width
  375. let height: any = proxyData.mapData.height
  376. if (width > height) {
  377. let num: any = Math.ceil(width / proxyData.screenInfo.screenWidth)
  378. if (num < 10) {
  379. proxyData.tempScale = 0.4
  380. } else if (num < 20) {
  381. proxyData.tempScale = 0.3
  382. } else {
  383. proxyData.tempScale = 0.25
  384. }
  385. } else {
  386. let num: any = Math.ceil(height / proxyData.screenInfo.screenHeight)
  387. if (num < 10) {
  388. proxyData.tempScale = 0.4
  389. } else if (num < 20) {
  390. proxyData.tempScale = 0.3
  391. } else {
  392. proxyData.tempScale = 0.25
  393. }
  394. }
  395. }
  396. },
  397. /**
  398. * 设置地图最外框宽和高
  399. */
  400. setMapBoxStyle() {
  401. let mapBoxEle = document.querySelector('#spaceMain')
  402. if (proxyData.mapData && proxyData.mapData.width) {
  403. mapBoxEle.style.width = proxyData.mapData.width + 'px'
  404. mapBoxEle.style.height = proxyData.mapData.height + 'px'
  405. }
  406. },
  407. /**
  408. * 设置空间的图标
  409. *
  410. */
  411. setSpaceIcon(item: any) {
  412. // if(item.can)
  413. if (item.canClick) {
  414. let typeName: any = getSpaceType(item.roomFuncType)
  415. item.icon = mapIcon[typeName].icon
  416. item.selectIcon = mapIcon[typeName].selectIcon
  417. item.backgroundColor = mapIcon[typeName].backgroundColor
  418. item.bg = mapIcon[typeName].bg
  419. item.icon = parseImgUrl('map-new-icon', item.icon)
  420. item.selectIcon = parseImgUrl('map-new-icon', item.selectIcon)
  421. }
  422. },
  423. midpoint(x1: any, y1: any, x2: any, y2: any) {
  424. return [(x1 + x2) / 2, (y1 + y2) / 2]
  425. },
  426. /**
  427. * 地图缩放功能
  428. */
  429. mapScale() {
  430. let matrix_box: any = document.querySelector('#spaceMain')
  431. let mapDom: any = document.querySelector('#map')
  432. matrix_box.addEventListener('touchstart', function(event: any) {
  433. let touches: any = event.touches
  434. let events: any = touches[0]
  435. let events2: any = touches[1]
  436. // 第一个触摸点的坐标
  437. proxyData.displacement.pageX = events.pageX
  438. proxyData.displacement.pageY = events.pageY
  439. proxyData.displacement.moveable = true
  440. if (events2) {
  441. proxyData.displacement.pageX2 = events2.pageX
  442. proxyData.displacement.pageY2 = events2.pageY
  443. proxyData.displacement.center = proxyData.midpoint(proxyData.displacement.pageX, proxyData.displacement.pageY, proxyData.displacement.pageX2, proxyData.displacement.pageY2)
  444. }
  445. proxyData.displacement.originScale = proxyData.displacement.scale || 1
  446. })
  447. matrix_box.addEventListener('touchmove', function(event: any) {
  448. if (!proxyData.displacement.moveable) {
  449. return
  450. }
  451. // event.preventDefault();
  452. let touches: any = event.touches
  453. let events: any = touches[0]
  454. let events2: any = touches[1]
  455. // 双指移动
  456. if (events2) {
  457. // 第2个指头坐标在touchmove时候获取
  458. if (!proxyData.displacement.pageX2) {
  459. proxyData.displacement.pageX2 = events2.pageX
  460. }
  461. if (!proxyData.displacement.pageY2) {
  462. proxyData.displacement.pageY2 = events2.pageY
  463. }
  464. // 双指缩放比例计算
  465. let zoom: any = proxyData.getDistance(
  466. {
  467. x: events.pageX,
  468. y: events.pageY
  469. },
  470. {
  471. x: events2.pageX,
  472. y: events2.pageY
  473. }
  474. ) / proxyData.getDistance(
  475. {
  476. x: proxyData.displacement.pageX,
  477. y: proxyData.displacement.pageY
  478. },
  479. {
  480. x: proxyData.displacement.pageX2,
  481. y: proxyData.displacement.pageY2
  482. }
  483. )
  484. // 应用在元素上的缩放比例
  485. let newScale: any = proxyData.displacement.originScale * zoom
  486. // 最大缩放比例限制
  487. if (newScale < proxyData.tempScale) {
  488. newScale = proxyData.tempScale
  489. }
  490. if (newScale > 1) {
  491. newScale = 1
  492. }
  493. // 记住使用的缩放值
  494. proxyData.displacement.scale = newScale
  495. // 图像应用缩放效果
  496. // console.log(newScale);
  497. matrix_box.style.transform = 'scale(' + newScale + ')'
  498. // 设置旋转元素的基点位置
  499. // matrix_box.style.transformOrigin = '0px 0px 0px'
  500. // matrix_box.style.transformOrigin = -proxyData.displacement.center[0] + ' ' + -proxyData.displacement.center[1]
  501. // mapDom.scrollTop = proxyData.displacement.center[1]
  502. // mapDom.scrollLeft = proxyData.displacement.center[0]
  503. // if (proxyData.selectArea) {
  504. // proxyData.setSelectSpacePosition(proxyData.selectArea)
  505. // }
  506. }
  507. })
  508. },
  509. /**
  510. * 获取建筑信息
  511. */
  512. getBuildingList() {
  513. let params: any = {
  514. 'criteria': {
  515. 'projectId': props.projectId
  516. }
  517. }
  518. getBuildingList(params).then(res => {
  519. let resData: any = res
  520. if (resData.result === 'success') {
  521. let content: any = resData?.content ?? []
  522. proxyData.buildingData = content
  523. // 设置展示的建筑名称
  524. proxyData.setBuildingName()
  525. }
  526. })
  527. },
  528. /**
  529. *
  530. * 选择建筑
  531. */
  532. checkBuilding() {
  533. proxyData.showBuilding = true
  534. },
  535. /**
  536. * 选择楼层
  537. */
  538. checkFloor() {
  539. proxyData.showFloor = true
  540. },
  541. /**
  542. * 确定选择的楼层信息
  543. */
  544. comfirmFloor(item: any, flag: boolean = true) {
  545. proxyData.floorItem = item
  546. proxyData.showFloor = false
  547. // 获取地图数据
  548. proxyData.loadingStart()
  549. proxyData.getMapInfo(flag)
  550. /**
  551. *缓存建筑对应的楼层
  552. */
  553. localStorageFloor(proxyData.buildingItem.buildingId, proxyData.floorItem.id)
  554. },
  555. /**
  556. * 确定建筑
  557. */
  558. comfirmBuilding(item: any) {
  559. proxyData.showBuilding = false
  560. proxyData.buildingItem.buildingId = item.id
  561. proxyData.buildingItem.localName = item.localName
  562. proxyData.getFloorList()
  563. },
  564. /**
  565. * 加载loading
  566. */
  567. loadingStart() {
  568. Toast.loading({
  569. duration: 0, // 持续展示 toast
  570. forbidClick: true,
  571. message: '加载中...'
  572. })
  573. },
  574. /**
  575. * 结束
  576. */
  577. loadinngEnd() {
  578. Toast.clear()
  579. },
  580. /**
  581. * 查询楼层信息
  582. */
  583. getFloorList(flag: boolean = true) {
  584. if (proxyData.buildingItem.buildingId) {
  585. let params: any = {
  586. 'criteria': {
  587. 'projectId': props.projectId,
  588. 'buildingId': proxyData.buildingItem.buildingId
  589. }
  590. }
  591. getFloorList(params).then(res => {
  592. let resData: any = res
  593. if (res.result === 'success') {
  594. proxyData.floorData = resData?.content ?? []
  595. // 设置楼层的名称
  596. proxyData.setFloorName()
  597. } else {
  598. proxyData.floorData = []
  599. }
  600. if (flag && proxyData.floorData.length) {
  601. proxyData.getHistorySelectFloor()
  602. proxyData.getMapInfo()
  603. }
  604. })
  605. }
  606. },
  607. /**
  608. * 获取地图信息
  609. */
  610. getMapInfo(flag: boolean = true, searchItem: any = null) {
  611. let params: any = {
  612. 'projectId': props.projectId,
  613. 'floorId': proxyData.floorItem.id
  614. }
  615. getMapInfo(params).then(res => {
  616. let resData: any = res
  617. if (resData.result === 'success') {
  618. proxyData.mapData = resData?.data ?? null
  619. // 切换数据的时候清楚默认样式
  620. proxyData.clearPreStyle()
  621. proxyData.formateMapData()
  622. /**
  623. * 如果是当前页面切换楼层,展示历史楼层
  624. */
  625. if (flag) {
  626. proxyData.getHistorySpace()
  627. } else { // 首次进入页面的时候展示空间来源于父div
  628. let area = proxyData.getFirstSelectSpace(searchItem)
  629. if (area) {
  630. proxyData.selectArea = area
  631. }
  632. // 搜索页面过来设置常驻空间页面
  633. if (!proxyData.isSetSpace) {
  634. proxyData.checkSpace(area)
  635. }
  636. }
  637. if (!proxyData.isSetSpace) {
  638. proxyData.checkSpace(proxyData.selectArea)
  639. }
  640. // 当没有默认空间的时候设置常驻空间页面不高量
  641. if (proxyData.isSetSpace && !props.spaceInfo.isPermanent) {
  642. proxyData.selectArea = {}
  643. } else {
  644. // proxyData.checkSpace(proxyData.selectArea)
  645. // 设置当前空间的位置
  646. proxyData.setSelectSpacePosition(proxyData.selectArea)
  647. }
  648. // 接口返回后设置地图缩放和滚动
  649. nextTick(() => {
  650. // 地图双指缩放
  651. proxyData.setMapBoxStyle()
  652. proxyData.mapScale()
  653. proxyData.mapScroll()
  654. })
  655. }
  656. proxyData.loadinngEnd()
  657. }).catch(() => {
  658. proxyData.loadinngEnd()
  659. })
  660. },
  661. /**
  662. * 获取缓存的楼层
  663. */
  664. getHistorySelectFloor() {
  665. let historyFloor: any = getLocalStorageFloor()
  666. let flag: any = false
  667. let floorId: any = historyFloor[proxyData.buildingItem.buildingId]
  668. proxyData.floorData.map((floor: any) => {
  669. if (floor.id === floorId) {
  670. flag = true
  671. proxyData.floorItem = floor
  672. }
  673. })
  674. if (!flag) {
  675. proxyData.floorItem = proxyData.floorData[0]
  676. }
  677. },
  678. /**
  679. * 获取选中的选中空间
  680. */
  681. getHistorySpace() {
  682. let data: any = proxyData.mapData
  683. let historySpace: any = getStorageSpaceId()
  684. if (data) {
  685. let flag: boolean = false
  686. let spaceList = data?.spaceList ?? []
  687. let key: any = `${proxyData.buildingItem.buildingId},${proxyData.floorItem.id}`
  688. let spaceId: any = historySpace[key]
  689. if (spaceId) {
  690. spaceList.map((space: any) => {
  691. if (spaceId === space.spaceId) {
  692. proxyData.selectArea = space
  693. flag = true
  694. }
  695. })
  696. }
  697. if (!flag) {
  698. for (let i: any = 0; i < spaceList.length; i++) {
  699. if (spaceList[i].canClick) {
  700. proxyData.selectArea = spaceList[i]
  701. break
  702. }
  703. }
  704. }
  705. }
  706. },
  707. /**
  708. * 首次进入页面设置选中的空间
  709. */
  710. getFirstSelectSpace(item: any) {
  711. let area: any = null
  712. let data: any = proxyData.mapData
  713. if (data && item) {
  714. let spaceList = data?.spaceList ?? []
  715. for (let i = 0; i < spaceList.length; i++) {
  716. if (spaceList[i].spaceId === item.spaceId) {
  717. // proxyData.selectArea = spaceList[i]
  718. area = spaceList[i]
  719. if (!proxyData.isSetSpace) {
  720. localStorageSpaceId(proxyData.buildingItem.buildingId, proxyData.floorItem.id, proxyData.selectArea.spaceId)
  721. }
  722. break
  723. }
  724. }
  725. }
  726. return area
  727. },
  728. setDefaultSpace(item: any) {
  729. if (item) {
  730. proxyData.buildingItem.buildingId = item.buildingId
  731. proxyData.buildingItem.localName = item.buildingName ? item.buildingName : ''
  732. proxyData.floorItem = {
  733. id: item.floorId,
  734. localName: item.floorName ? item.floorName : ''
  735. }
  736. }
  737. },
  738. // 设备模块初始化地图
  739. init(item: any) {
  740. proxyData.setDefaultSpace(item)
  741. /**
  742. *缓存建筑对应的楼层
  743. */
  744. if (!proxyData.isSetSpace) {
  745. localStorageFloor(proxyData.buildingItem.buildingId, proxyData.floorItem.id)
  746. }
  747. proxyData.getBuildingList()
  748. proxyData.getFloorList(false)
  749. proxyData.getMapInfo(false, item)
  750. },
  751. /**
  752. *搜索后设置建筑的localName
  753. */
  754. setBuildingName() {
  755. if (proxyData.buildingItem.buildingId) {
  756. proxyData.buildingData.map((item: any) => {
  757. if (item.id === proxyData.buildingItem.buildingId) {
  758. proxyData.buildingItem.localName = item.localName
  759. }
  760. })
  761. } else { // 设置常驻空间的时候使用
  762. proxyData.buildingItem = {
  763. buildingId: proxyData.buildingData[0].id,
  764. localName: proxyData.buildingData[0].localName
  765. }
  766. }
  767. },
  768. /**
  769. * 搜索页面回来根据id设置楼层的localName
  770. */
  771. setFloorName() {
  772. if (proxyData.floorItem.id) {
  773. proxyData.floorData.map((item: any) => {
  774. if (item.id === proxyData.floorItem.id) {
  775. proxyData.floorItem.localName = item.localName
  776. }
  777. })
  778. } else { // 设置常驻空间的时候使用
  779. proxyData.floorItem = proxyData.floorData[0]
  780. }
  781. }
  782. })
  783. // watch(
  784. // props.spaceInfo, (newVal, oldValue) => {
  785. //
  786. // }
  787. // )
  788. onMounted(() => {
  789. // proxyData.formateMapData()
  790. // proxyData.setMapBoxStyle()
  791. let item: any = props.spaceInfo
  792. proxyData.init(item)
  793. })
  794. return {
  795. ...toRefs(proxyData)
  796. }
  797. }
  798. })
  799. </script>
  800. <style lang="scss" scoped>
  801. .space-main {
  802. width: 100%;
  803. height: 100%;
  804. position: relative;
  805. background: #f7f8fa;
  806. //transform-origin: 0 0;
  807. transition: transform 0.3s;
  808. transform: scale(1);
  809. padding: 0 5px;
  810. overflow: auto;
  811. .space-box {
  812. position: absolute;
  813. padding: 5px;
  814. }
  815. .space {
  816. position: relative;
  817. width: 100%;
  818. height: 100%;
  819. box-shadow: 0px 1px 4px rgba(1, 1, 51, 0.01), 0px 16px 40px rgba(1, 1, 51, 0.03);
  820. border-radius: 4px;
  821. box-sizing: border-box;
  822. .device {
  823. position: absolute;
  824. left: 50%;
  825. top: 50%;
  826. transform: translate(-50%, -50%);
  827. text-align: center;
  828. z-index: 666;
  829. img {
  830. //margin-bottom: 6px;
  831. }
  832. span {
  833. display: block;
  834. word-break: keep-all;
  835. white-space: nowrap;
  836. //font-size: 12px;
  837. color: #8995ba;
  838. font-weight: 600;
  839. }
  840. }
  841. .select-device {
  842. transform: translate(-50%, -70%);
  843. img {
  844. margin-bottom: 6px;
  845. }
  846. }
  847. .circle {
  848. width: 4px;
  849. height: 4px;
  850. border-radius: 50%;
  851. position: absolute;
  852. top: 50%;
  853. left: 50%;
  854. transform: translateX(-50%) translateY(-50%);
  855. }
  856. }
  857. .select {
  858. border: 2px solid rgba(77, 148, 255, 0.8);
  859. }
  860. .use-select {
  861. border: 5px solid #FFE823;
  862. }
  863. &::-webkit-scrollbar {
  864. display: none;
  865. }
  866. }
  867. .map-toolbar {
  868. position: fixed;
  869. width: 44px;
  870. right: 20px;
  871. z-index: 999;
  872. top: 50%;
  873. transform: translateY(-50%);
  874. .icon-search {
  875. width: 44px;
  876. height: 44px;
  877. border-radius: 5px;
  878. background: #fff;
  879. }
  880. .toolbar-item {
  881. width: 44px;
  882. height: 44px;
  883. background: #FFFFFF;
  884. box-shadow: 0px 0px 1px rgba(0, 0, 0, 0.1), 0px 4px 8px rgba(0, 0, 0, 0.1);
  885. border-radius: 4px;
  886. margin-top: 10px;
  887. text-align: center;
  888. .toolbar-menu {
  889. width: 44px;
  890. }
  891. img {
  892. width: 12px;
  893. height: 14px;
  894. margin-top: 15px;
  895. }
  896. }
  897. .text-hidden {
  898. //font-family: Montserrat;
  899. display: block;
  900. font-style: normal;
  901. width: 44px;
  902. line-height: 44px;
  903. font-weight: 500;
  904. font-size: 16px;
  905. text-align: center;
  906. color: #4D5262;
  907. overflow: hidden;
  908. text-overflow: ellipsis;
  909. white-space: nowrap;
  910. }
  911. }
  912. .buiding-item {
  913. //font-family: 'Montserrat';
  914. width: 100%;
  915. padding: 10px;
  916. font-style: normal;
  917. font-weight: 500;
  918. font-size: 14px;
  919. text-align: left;
  920. color: rgba(13, 13, 61, 0.86);
  921. border-bottom: 1px solid rgba(2, 2, 82, 0.03)
  922. }
  923. .active {
  924. color: rgba(77, 148, 255, 0.8);
  925. }
  926. </style>