index.vue 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484
  1. <!-- 底图 -->
  2. <template>
  3. <div id='floor_base' v-loading='loading' ref='graphy'>
  4. <canvas :id='`canvas${id}`' :width='canvasWidth' :height='canvasHeight' tabindex='0'></canvas>
  5. <!-- 地图底部操作按钮 -->
  6. <div class='strip-bottom'>
  7. <canvasFun @fit='fit' @savePng='savePng' @saveSvg='saveSvg' @saveJson='saveJson' @scale='scale' @showText='showText' ref='canvasFun'></canvasFun>
  8. </div>
  9. <room-box ref='boxRoom'></room-box>
  10. </div>
  11. </template>
  12. <script>
  13. import { SFengParser } from '@saga-web/feng-map'
  14. import { SFloorParser, ItemOrder, ItemColor } from '@saga-web/big'
  15. import { FloorView } from '@/lib/FloorView'
  16. import { FloorScene } from '@/lib/FloorScene'
  17. import RoomBox from '@/views/room/index'
  18. import canvasFun from '@/components/floorMap/canvasFun'
  19. import { readGroup, queryStatis } from '@/api/public'
  20. import { queryShops } from '@/api/equipmentList.js'
  21. import { STopologyParser } from '@/lib/parsers/STopologyParser'
  22. import { mapGetters, mapActions } from 'vuex'
  23. import { SImageItem, SImageShowType } from '@saga-web/graph/lib'
  24. import { SColor } from '@saga-web/draw/lib'
  25. import bus from '@/utils/bus.js'
  26. // import { uuid } from "@/components/mapClass/until";
  27. export default {
  28. data() {
  29. return {
  30. appName: '万达可视化系统',
  31. key: '23f30a832a862c58637a4aadbf50a566',
  32. mapServerURL: `http://map.wanda.cn/editor`,
  33. canvasWidth: 600,
  34. canvasHeight: 800,
  35. loading: false, // 限制重复查询
  36. view: null,
  37. urlMsg: {},
  38. canvasID: 'canvas',
  39. floorid: '', //楼层id
  40. topologyParser: null, // 解析器数据
  41. fParser: null, // 底图解析器
  42. wellMap: {}, // 电井控制商铺映射
  43. }
  44. },
  45. props: {
  46. id: {
  47. default: '1',
  48. type: String,
  49. },
  50. categoryId: {
  51. default: '',
  52. type: String,
  53. },
  54. // 弹窗高度,适配底图高度使用
  55. modalHeight: {
  56. type: [Number, undefined],
  57. default: undefined,
  58. },
  59. loadName: null,
  60. type: null,
  61. },
  62. components: { RoomBox, canvasFun },
  63. computed: {
  64. ...mapGetters(['plazaId', 'fmapID', 'haveFengMap', 'bunkObj']),
  65. },
  66. methods: {
  67. ...mapActions(['getfmapID']),
  68. init(floorid) {
  69. this.loading = true
  70. this.floorid = floorid
  71. this.mapSize()
  72. this.$refs.canvasFun.isShow = false
  73. setTimeout(() => {
  74. this.clearGraphy()
  75. this.scene = new FloorScene()
  76. if (this.haveFengMap == 1) {
  77. this.scene.selectContainer.connect('listChange', this, this.listChange)
  78. if (this.canvasID != `canvas${this.id}`) {
  79. this.canvasID = `canvas${this.id}`
  80. }
  81. this.parserData(floorid)
  82. } else if (this.haveFengMap == 0) {
  83. this.view.scene = this.scene
  84. this.readGraph()
  85. } else {
  86. this.loading = false
  87. }
  88. }, 100)
  89. },
  90. parserData(floor) {
  91. if (floor == 'g80') {
  92. // 屋顶
  93. if (window.fengmapData.frImg) {
  94. let imgItem = new SImageItem(null, `${this.mapServerURL}/webtheme/${this.fmapID}/${window.fengmapData.frImg}`)
  95. imgItem.showType = SImageShowType.AutoFit
  96. imgItem.connect('imgLoadOver', this, () => {
  97. this.readGraph()
  98. })
  99. this.scene.addItem(imgItem)
  100. this.view.scene = this.scene
  101. // this.view.fitSceneToView()
  102. } else {
  103. // 屋顶图不为图片
  104. this.readBaseMap(floor);
  105. }
  106. } else {
  107. if (window.fengmapData.gnameToGid[floor]) {
  108. this.readBaseMap(floor);
  109. } else {
  110. console.log('楼层不正确')
  111. }
  112. }
  113. },// 解析底图
  114. readBaseMap(floor){
  115. window.fengmapData.parseData(window.fengmapData.gnameToGid[floor], res => {
  116. if (res.err) {
  117. console.log('errr', res.err)
  118. return
  119. }
  120. this.fParser = new SFloorParser(null)
  121. this.fParser.parseData(res)
  122. this.fParser.spaceList.forEach(t => {
  123. this.scene.addItem(t)
  124. t.nameSize = 12
  125. t.nameColor = '#2a2a2a'
  126. if (t.data.Name && this.bunkObj[t.data.Name]) {
  127. t.name = this.bunkObj[t.data.Name].brandname
  128. } else {
  129. // t.name = t.data.Name
  130. t.name = ''
  131. }
  132. })
  133. this.fParser.wallList.forEach(t => this.scene.addItem(t))
  134. this.fParser.virtualWallList.forEach(t => this.scene.addItem(t))
  135. this.fParser.doorList.forEach(t => this.scene.addItem(t))
  136. this.fParser.columnList.forEach(t => this.scene.addItem(t))
  137. this.fParser.casementList.forEach(t => this.scene.addItem(t))
  138. this.view.scene = this.scene
  139. // this.view.fitSceneToView()
  140. this.readGraph()
  141. })
  142. },
  143. readGraph() {
  144. this.readGroup(this.floorid)
  145. .then((data) => {
  146. if (data.Result == 'failure') {
  147. this.$store.commit('SETISMESSAGE', false)
  148. this.view.fitSceneToView()
  149. this.view.minScale = this.view.scale
  150. if (this.$refs.canvasFun) {
  151. this.$refs.canvasFun.everyScale = this.view.scale
  152. }
  153. this.loading = false
  154. return
  155. } else {
  156. if (
  157. data.Data[0].Elements.Nodes.length === 0 &&
  158. data.Data[0].Elements.Markers.length === 0 &&
  159. data.Data[0].Elements.Relations.length === 0
  160. ) {
  161. this.$store.commit('SETISMESSAGE', false)
  162. } else {
  163. this.$store.commit('SETISMESSAGE', true)
  164. }
  165. }
  166. // 无返回Data处理
  167. if (!(data.Data && data.Data.length)) {
  168. this.view.fitSceneToView()
  169. this.view.minScale = this.view.scale
  170. if (this.$refs.canvasFun) {
  171. this.$refs.canvasFun.everyScale = this.view.scale
  172. }
  173. return false
  174. }
  175. // 请求回来的备注
  176. if (data.Data && data.Data[0].Note) {
  177. let note = data.Data[0].Note
  178. bus.$emit('queryRemarksMethods', note)
  179. } else {
  180. bus.$emit('queryRemarksMethods', '')
  181. }
  182. //土建装饰的图例展示
  183. if (this.$cookie.get('categoryId') == 'SCPZ') {
  184. let scpzTable = [],
  185. arr = []
  186. scpzTable = data.Data[0].Elements.Nodes || []
  187. console.log(scpzTable)
  188. if (scpzTable.length > 0) {
  189. scpzTable.forEach((e) => {
  190. if (e.Properties.ItemExplain) {
  191. let obj = e
  192. arr.push(obj)
  193. }
  194. })
  195. }
  196. console.log(arr)
  197. this.$store.commit('SETSCPZTABLE', arr)
  198. }
  199. if (data.Data[0].Elements.Nodes.length > 0) {
  200. this.$store.commit('SETTYPENUM', '')
  201. let Lengd = data.Data[0].Elements.Nodes
  202. Lengd.forEach((el) => {
  203. if (el.Type == 'Image' && el.Num > 1) {
  204. console.log(el.Num)
  205. this.$store.commit('SETTYPENUM', el.Num)
  206. }
  207. })
  208. }
  209. // 放到后边 $cookie graphId
  210. this.$cookie.set('graphId', data.Data[0].ID, 3)
  211. if (this.$cookie.get('graphId')) {
  212. // 得到graphId 就请求图例
  213. // 除土建装饰之外的图例展示 包括楼层功能
  214. bus.$emit('queryViewMethods')
  215. }
  216. this.topologyParser = new STopologyParser(null)
  217. this.topologyParser.parseData(data.Data[0].Elements)
  218. // 多边形
  219. this.topologyParser.zoneLegendList.forEach((t) => {
  220. this.scene.addItem(t)
  221. })
  222. // 增加文字
  223. this.topologyParser.textMarkerList.forEach((t) => {
  224. this.scene.addItem(t)
  225. })
  226. // 增加图片
  227. this.topologyParser.imageMarkerList.forEach((t) => {
  228. this.scene.addItem(t)
  229. })
  230. // 增加直线
  231. this.topologyParser.lineMarkerList.forEach((t) => {
  232. this.scene.addItem(t)
  233. })
  234. // 增加图标类图例
  235. this.topologyParser.imageLegendList.forEach((t) => {
  236. this.scene.addItem(t)
  237. })
  238. // 增加管线类
  239. // 增加图标类图例
  240. this.topologyParser.relationList.forEach((t) => {
  241. t.selectable = true
  242. this.scene.addItem(t)
  243. })
  244. this.view.fitSceneToView()
  245. this.view.minScale = this.view.scale
  246. if (this.$refs.canvasFun) {
  247. this.$refs.canvasFun.everyScale = this.view.scale
  248. }
  249. this.loading = false
  250. })
  251. .catch(() => {
  252. this.loading = false
  253. })
  254. },
  255. clearGraphy() {
  256. if (this.view) {
  257. this.view.scene = null
  258. return
  259. }
  260. this.view = new FloorView(`canvas${this.id}`)
  261. },
  262. listChange(item, ev) {
  263. if (ev[0].length) {
  264. let selectItem1 = ev[0][0],
  265. location = selectItem1.data.AttachObjectIds[0] ? selectItem1.data.AttachObjectIds[0].id : ''
  266. // 空间类型都可打开弹窗(除防火分区 编号100131,商管办公室 编号100112,铺装石材 编号100129)
  267. if (selectItem1.data.GraphElementType == 'Zone') {
  268. if (
  269. selectItem1.data.GraphElementId != '100131' &&
  270. selectItem1.data.GraphElementId != '100112' &&
  271. selectItem1.data.GraphElementId != '100129'
  272. ) {
  273. if (location) {
  274. this.$refs.boxRoom.open({ name: selectItem1.name, type: this.type, location: location })
  275. }
  276. }
  277. }
  278. // 选中电井设置电井关联的商铺高亮
  279. this.setHightLight(ev[0])
  280. } else {
  281. this.clearHightLight()
  282. }
  283. },
  284. // 选中电井关联的商铺高亮
  285. setHightLight(arr) {
  286. this.clearHightLight()
  287. arr.forEach((item) => {
  288. let location = item.data.AttachObjectIds[0] ? item.data.AttachObjectIds[0].id : ''
  289. // 添加了位置类型并且选中的类型为电井类型
  290. if (
  291. (item.data.GraphElementId == '100050' ||
  292. item.data.GraphElementId == '100055' ||
  293. item.data.GraphElementId == '100056' ||
  294. item.data.GraphElementId == '100057') &&
  295. location
  296. ) {
  297. if (this.wellMap.hasOwnProperty(location)) {
  298. this.wellMap[location].forEach((item) => {
  299. item.highLightFlag = true
  300. item.zOrder = 30
  301. })
  302. } else {
  303. let getParams = {
  304. plazaId: this.plazaId,
  305. floor: this.floorid,
  306. keyword: `${location}:wellnum;`,
  307. }
  308. queryShops({ getParams }).then((res) => {
  309. let shopsnumList = []
  310. let shopsnumItemList = []
  311. if (res.data && res.data.length) {
  312. for (let floor in res.data[0]) {
  313. if (res.data[0][floor].length) {
  314. res.data[0][floor].forEach((v) => {
  315. shopsnumList = shopsnumList.concat(v.shopsnumList.split(','))
  316. })
  317. }
  318. }
  319. }
  320. if (shopsnumList.length) {
  321. this.fParser.spaceList.forEach((item) => {
  322. if (shopsnumList.findIndex((name) => name == item.data.Name) != -1) {
  323. item.highLightFlag = true
  324. item.zOrder = 30
  325. shopsnumItemList.push(item)
  326. }
  327. })
  328. this.wellMap[location] = shopsnumItemList
  329. }
  330. })
  331. }
  332. }
  333. })
  334. },
  335. // 清除电井关联商铺的高亮状态
  336. clearHightLight() {
  337. ItemColor.spaceHighColor = new SColor('#FBF2CC')
  338. for (let key in this.wellMap) {
  339. this.wellMap[key].forEach((item) => {
  340. item.highLightFlag = false
  341. item.zOrder = ItemOrder.spaceOrder
  342. })
  343. }
  344. },
  345. // 适配底图到窗口
  346. fit() {
  347. this.view.fitSceneToView()
  348. },
  349. // 保存为png
  350. savePng() {
  351. // this.view.saveImage(`${this.loadName}.png`, 'png')
  352. this.view.saveImageSize(`${this.loadName}.png`, 'png', 1920 * 2, 1080 * 2)
  353. //console.log(`${this.loadName}.png`)
  354. },
  355. // 保存为svg
  356. saveSvg() {
  357. this.view.saveSceneSvg(`${this.loadName}.svg`, 6400, 4800)
  358. },
  359. // 保存为json
  360. saveJson() {
  361. this.view.saveFloorJson(`${this.loadName}.json`)
  362. },
  363. // 缩放
  364. scale(val) {
  365. if (!this.view) {
  366. return
  367. }
  368. let scale = this.view.scale
  369. this.view.scaleByPoint(val / scale, this.canvasWidth / 2, this.canvasHeight / 2)
  370. },
  371. // 小眼睛控制显示铺位名称
  372. showText(val) {
  373. // this.topologyParser.zoneLegendList.forEach(t => {
  374. // t.showText = val
  375. // })
  376. this.fParser.spaceList.forEach((t) => {
  377. t.showBaseName = val
  378. })
  379. },
  380. // 读取数据
  381. readGroup(FloorID) {
  382. const data = {
  383. BuildingID: '1',
  384. FloorID: FloorID,
  385. categoryId: this.categoryId ? this.categoryId : this.$cookie.get('categoryId'),
  386. projectId: this.urlMsg.ProjectID,
  387. Pub: true,
  388. }
  389. return readGroup(data)
  390. },
  391. // 地图尺寸
  392. mapSize() {
  393. this.canvasWidth = this.$refs.graphy.offsetWidth
  394. if (window.screen.height == '768') {
  395. this.canvasHeight = this.$refs.graphy.offsetHeight - 100
  396. } else {
  397. this.canvasHeight = 900
  398. }
  399. // 弹窗中底图高度适配
  400. if (this.modalHeight) {
  401. this.canvasHeight = this.modalHeight
  402. }
  403. },
  404. getEvent() {
  405. bus.$on('changeShow', (res) => {
  406. this.topologyParser &&
  407. this.topologyParser.zoneLegendList.forEach((t) => {
  408. let id = t.data.GraphElementId
  409. t.maskFlag = !(res.indexOf(id) > -1)
  410. })
  411. // this.topologyParser.textMarkerList.forEach(t => {
  412. // let id = t.data.GraphElementId
  413. // t.maskFlag = !(res.indexOf(id) > -1)
  414. // })
  415. // this.topologyParser.imageMarkerList.forEach(t => {
  416. // let id = t.data.GraphElementId
  417. // t.maskFlag = !(res.indexOf(id) > -1)
  418. // })
  419. // this.topologyParser.lineMarkerList.forEach(t => {
  420. // let id = t.data.GraphElementId
  421. // t.maskFlag = !(res.indexOf(id) > -1)
  422. // })
  423. this.topologyParser &&
  424. this.topologyParser.imageLegendList.forEach((t) => {
  425. let id = t.data.GraphElementId
  426. t.maskFlag = !(res.indexOf(id) > -1)
  427. })
  428. this.topologyParser &&
  429. this.topologyParser.relationList.forEach((t) => {
  430. let id = t.data.GraphElementId || t.data.GraphElementID
  431. t.maskFlag = !(res.indexOf(id) > -1)
  432. })
  433. })
  434. },
  435. },
  436. watch: {
  437. 'view.scale': {
  438. handler(n) {
  439. if (this.$refs.canvasFun) {
  440. let s = (n * 10) / this.view.minScale
  441. this.$refs.canvasFun.sliderVal = s > 1000 ? 1000 : s
  442. }
  443. },
  444. },
  445. haveFengMap() {
  446. this.init(this.floorid)
  447. },
  448. },
  449. mounted() {
  450. this.mapSize()
  451. this.getEvent()
  452. },
  453. created() {
  454. this.urlMsg = {
  455. categoryId: this.$cookie.get('categoryId'),
  456. ProjectID: this.plazaId,
  457. BuildingID: '1',
  458. FloorID: this.$cookie.get('floorMapId') || 'f1',
  459. fmapID: this.fmapID,
  460. }
  461. },
  462. }
  463. </script>
  464. <style lang="less" scoped>
  465. #floor_base {
  466. position: relative;
  467. height: 100%;
  468. .fengMap {
  469. position: fixed;
  470. width: 100px;
  471. height: 100px;
  472. z-index: -1;
  473. }
  474. .strip-bottom {
  475. position: absolute;
  476. right: 0;
  477. bottom: 40px;
  478. width: 100%;
  479. }
  480. }
  481. </style>