index.vue 38 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210
  1. <!-- 底图 -->
  2. <template>
  3. <div id="floor_base" v-loading="loading" ref="graphy">
  4. <canvas
  5. :id="`canvas${id}`"
  6. :width="canvasWidth"
  7. :height="canvasHeight"
  8. tabindex="0"
  9. ></canvas>
  10. <!-- 地图底部操作按钮 -->
  11. <div class="strip-bottom">
  12. <canvasFun
  13. @fit="fit"
  14. @savePng="savePng"
  15. @saveSvg="saveSvg"
  16. @saveJson="saveJson"
  17. @scale="scale"
  18. @showText="showText"
  19. ref="canvasFun"
  20. ></canvasFun>
  21. </div>
  22. <room-box :key="`rommBox${roomKey}`" ref="boxRoom"></room-box>
  23. <equip-detail ref="equipDetail" :key="equipKey"></equip-detail>
  24. <el-popover
  25. ref="popover"
  26. id="popovers"
  27. placement="right"
  28. trigger="manual"
  29. v-model="visible"
  30. width="380"
  31. >
  32. <!-- <div style="text-align: right;margin-bottom: 10px;">
  33. <span style="float: left;">对应的工程信息化信息</span>
  34. <el-link icon="el-icon-close" :underline="false" @click="visible = false"></el-link>
  35. </div>-->
  36. <!-- 点击图标,出现的弹窗 -->
  37. <div
  38. v-if="equipIds.length && !tabData.pointData.length"
  39. style="margin-top: 10px"
  40. >
  41. <el-table
  42. :data="tabData.tableData"
  43. max-height="235"
  44. style="width: 100%"
  45. @row-click="handleClickEquipDetail"
  46. v-loading="eqLoading"
  47. :cell-class-name="tableCellClassName"
  48. >
  49. <el-table-column
  50. prop="sbjc"
  51. label="设备简称"
  52. width="144"
  53. :show-overflow-tooltip="true"
  54. ></el-table-column>
  55. <el-table-column
  56. prop="sl"
  57. width="50"
  58. label="数量"
  59. :show-overflow-tooltip="true"
  60. ></el-table-column>
  61. <el-table-column
  62. prop="sb_status"
  63. width="80"
  64. label="设备状态"
  65. :show-overflow-tooltip="true"
  66. ></el-table-column>
  67. <el-table-column
  68. prop="sbglgs"
  69. width="80"
  70. label="管理归属"
  71. :show-overflow-tooltip="true"
  72. ></el-table-column>
  73. <!-- <el-table-column prop="assetnum" width="80" label="设备内码" :show-overflow-tooltip='true'></el-table-column>
  74. <el-table-column label="" width="80" :show-overflow-tooltip='true'>
  75. <template slot-scope="scope">
  76. <span class="equip-detail-btn">台账详情</span>
  77. </template>
  78. </el-table-column>-->
  79. </el-table>
  80. <!-- <div style="text-align: right; margin-top: 10px;">
  81. <el-button size="mini" type="primary" @click="visible = false">关闭</el-button>
  82. </div>-->
  83. </div>
  84. <!-- 点击空间,出现的弹窗 -->
  85. <div
  86. v-else-if="!equipIds.length && tabData.pointData.length"
  87. style="margin-top: 10px"
  88. >
  89. <ul class="pointList">
  90. <li
  91. v-for="point in tabData.pointData"
  92. :key="point.id"
  93. @click="handleClickPointDeatil(point)"
  94. >
  95. <span :title="point.name">{{ point.name }}</span>
  96. <a>查看</a>
  97. </li>
  98. </ul>
  99. <!-- 提示文本 -->
  100. <div class="wellTooltip" v-show="isclickShopName">该电井为{{isclickShopName}}商铺提供供电</div>
  101. <div style="text-align: right; margin-top: 10px">
  102. <el-button
  103. v-show="showBtnWell"
  104. size="mini"
  105. type="primary"
  106. @click="handleClickHightLight(tabData.pointData)"
  107. >查看控制商铺范围</el-button
  108. >
  109. <!-- <el-button size="mini" type="primary" @click="visible = false">关闭</el-button> -->
  110. </div>
  111. </div>
  112. <!-- 既有空间,又有设备的弹窗 -->
  113. <el-tabs
  114. v-else-if="equipIds.length && tabData.pointData.length"
  115. v-model="activeName"
  116. >
  117. <el-tab-pane label="设备设施" name="equip">
  118. <el-table
  119. :data="tabData.tableData"
  120. max-height="235"
  121. style="width: 100%"
  122. @row-click="handleClickEquipDetail"
  123. :cell-class-name="tableCellClassName"
  124. v-loading="eqLoading"
  125. >
  126. <el-table-column
  127. prop="sbjc"
  128. label="设备简称"
  129. width="164"
  130. :show-overflow-tooltip="true"
  131. ></el-table-column>
  132. <el-table-column
  133. prop="sl"
  134. width="50"
  135. label="数量"
  136. :show-overflow-tooltip="true"
  137. align="right"
  138. ></el-table-column>
  139. <el-table-column
  140. prop="sb_status"
  141. width="70"
  142. label="设备状态"
  143. :show-overflow-tooltip="true"
  144. ></el-table-column>
  145. <el-table-column
  146. prop="sbglgs"
  147. width="70"
  148. label="管理归属"
  149. :show-overflow-tooltip="true"
  150. ></el-table-column>
  151. <!-- <el-table-column prop="assetnum" width="80" label="设备内码" :show-overflow-tooltip='true'></el-table-column>
  152. <el-table-column label="" width="80" :show-overflow-tooltip='true'>
  153. <template slot-scope="scope">
  154. <span class="equip-detail-btn">台账详情</span>
  155. </template>
  156. </el-table-column>-->
  157. </el-table>
  158. <div style="text-align: right; margin-top: 10px">
  159. <!-- <el-button size="mini" type="primary" @click="visible = false">关闭</el-button> -->
  160. </div>
  161. </el-tab-pane>
  162. <el-tab-pane label="位置" name="point">
  163. <ul class="pointList">
  164. <li
  165. v-for="point in tabData.pointData"
  166. :key="point.id"
  167. @click="handleClickPointDeatil(point)"
  168. >
  169. <span :title="point.name">{{ point.name }}</span>
  170. <a>查看</a>
  171. </li>
  172. </ul>
  173. <div style="text-align: right; margin-top: 10px">
  174. <el-button
  175. v-show="showBtnWell"
  176. size="mini"
  177. type="primary"
  178. @click="handleClickHightLight(tabData.pointData)"
  179. >查看控制商铺范围</el-button
  180. >
  181. <!-- <el-button size="mini" type="primary" @click="visible = false">关闭</el-button> -->
  182. </div>
  183. </el-tab-pane>
  184. </el-tabs>
  185. </el-popover>
  186. <span class="popStyle" :style="popoverPosition" v-popover:popover></span>
  187. </div>
  188. </template>
  189. <script>
  190. /**
  191. * @author yunxing
  192. * @date 2020年08月21日11:04
  193. * @description 停用,已拆除的状态,使用message进行提示
  194. */
  195. import { SFengParser, ProjectRf } from "@saga-web/feng-map";
  196. import {
  197. SFloorParser,
  198. ItemOrder,
  199. ItemColor,
  200. SPolygonItem,
  201. SBoardItem,
  202. } from "@saga-web/big";
  203. import { FloorView } from "@/lib/FloorView";
  204. import { FloorScene } from "@/lib/FloorScene";
  205. import RoomBox from "@/views/room/index";
  206. import canvasFun from "@/components/floorMap/canvasFun";
  207. import { readGroup, queryStatis, graphQuery } from "@/api/public";
  208. import { queryShops, queryAssetAll } from "@/api/equipmentList.js";
  209. import { STopologyParser } from "@/lib/parsers/STopologyParser";
  210. import { mapGetters, mapActions } from "vuex";
  211. import { SImageItem, SImageShowType, SGraphItem } from "@saga-web/graph/lib";
  212. import { SColor, SPoint } from "@saga-web/draw/lib";
  213. import bus from "@/utils/bus.js";
  214. import { TipelineItem } from "../../lib/items/TipelineItem";
  215. import { SImageLegendItem } from "../../lib/items/SImageLegendItem";
  216. import equipDetail from "../../views/equipment/table/equipDetail";
  217. import { debounce } from "lodash";
  218. import { Message } from "element-ui";
  219. // import { uuid } from "@/components/mapClass/until";
  220. export default {
  221. data() {
  222. return {
  223. appName: "万达可视化系统",
  224. key: "23f30a832a862c58637a4aadbf50a566",
  225. mapServerURL: `http://mapapp.wanda.cn/editor`,
  226. canvasWidth: 600,
  227. canvasHeight: 800,
  228. loading: false, // 限制重复查询
  229. view: null,
  230. urlMsg: {},
  231. canvasID: "canvas",
  232. floorid: "", //楼层id
  233. topologyParser: null, // 解析器数据
  234. fParser: null, // 底图解析器
  235. wellMap: {}, // 电井控制商铺映射
  236. activeName: "equip",
  237. popoverPosition: {
  238. top: 0,
  239. left: 0,
  240. },
  241. statusTextPosition: {
  242. top: 0,
  243. left: 0,
  244. },
  245. visible: false,
  246. eqLoading: true,
  247. equipIds: [],
  248. tabData: {
  249. tableData: [],
  250. pointData: [],
  251. },
  252. activeItem: null,
  253. showBtnWell: false,
  254. count: 0, // 顶楼为多张图时计数器
  255. equipKey: 1, //设备弹窗使用key值,解决打开弹窗数据为上次弹窗的数据
  256. statusDisabled: ["已拆除"], //禁止跳转的设备状态
  257. roomKey: 1,
  258. shopsList: [], //所有强电井对应的店铺
  259. isclickShopName:'', //是否是点击商铺后电井高亮
  260. };
  261. },
  262. props: {
  263. id: {
  264. default: "1",
  265. type: String,
  266. },
  267. categoryId: {
  268. default: "",
  269. type: String,
  270. },
  271. // 弹窗高度,适配底图高度使用
  272. modalHeight: {
  273. type: [Number, undefined],
  274. default: undefined,
  275. },
  276. loadName: null,
  277. type: null,
  278. },
  279. components: { RoomBox, canvasFun, equipDetail },
  280. computed: {
  281. ...mapGetters(["plazaId", "fmapID", "haveFengMap", "bunkObj"]),
  282. },
  283. methods: {
  284. /**
  285. * 点击图标事件
  286. *
  287. * item 点击的实例
  288. * events 鼠标事件
  289. * isShopToWell 是否是点击商铺促发电井高亮
  290. */
  291. handleClickLegendItem(item, events, isShopToWell = false) {
  292. this.tabData = { tableData: [], pointData: [] };
  293. this.equipIds = [];
  294. this.showBtnWell = false;
  295. this.visible = false;
  296. this.activeItem = null;
  297. this.isLoading = true;
  298. if (item.data.AttachObjectIds && item.data.AttachObjectIds.length) {
  299. const e = events[0];
  300. this.activeItem = item;
  301. item.data.AttachObjectIds.forEach((v) => {
  302. if (v.type == "Image") {
  303. if (v.id) {
  304. this.equipIds.push(v.id);
  305. }
  306. // this.tabData.tableData.push(v);
  307. } else if (v.type == "Zone") {
  308. this.tabData.pointData.push(v);
  309. }
  310. });
  311. if (this.equipIds.length) {
  312. this.eqLoading = true;
  313. let data = {
  314. plazaId: this.$store.state.plazaId,
  315. page: 1,
  316. size: this.equipIds.length,
  317. };
  318. let postParams = {
  319. assetnumList: this.equipIds,
  320. };
  321. queryAssetAll({ data, postParams }).then((res) => {
  322. this.tabData.tableData = res.data.data;
  323. this.eqLoading = false;
  324. });
  325. }
  326. if (isShopToWell) {
  327. this.popoverPosition.top = `${e.clientY + 70}px`;
  328. this.popoverPosition.left = `${e.clientX + 20}px`;
  329. } else {
  330. this.popoverPosition.top = `${e.clientY}px`;
  331. this.popoverPosition.left = `${e.clientX + 30}px`;
  332. }
  333. this.$nextTick(() => {
  334. if (
  335. item.data.GraphElementId == "100050" ||
  336. item.data.GraphElementId == "100055" ||
  337. item.data.GraphElementId == "100056" ||
  338. item.data.GraphElementId == "100057"
  339. ) {
  340. //判断是否为电井
  341. this.showBtnWell = true;
  342. setTimeout(()=>{
  343. item.selected = true
  344. },300)
  345. }
  346. setTimeout(() => {
  347. this.visible = true;
  348. });
  349. });
  350. }
  351. },
  352. // 点击底图商铺高亮对应的电井
  353. shopLisghtWell() {
  354. const getParams = {
  355. plazaId: this.plazaId,
  356. floor: this.floorid,
  357. };
  358. queryShops({ getParams }).then((res) => {
  359. let shopsnumList = [];
  360. if (res.data && res.data.length) {
  361. for (let floor in res.data[0]) {
  362. shopsnumList = res.data[0][floor].map((obj) => {
  363. const shoplist = obj.shopsnumList.split(",");
  364. return Object.assign(obj, {
  365. shopList: shoplist,
  366. });
  367. });
  368. }
  369. }
  370. this.shopsList = shopsnumList;
  371. });
  372. },
  373. // 查看浮层设备详情
  374. handleClickEquipDetail: debounce(function (row, column, event) {
  375. // 设备状态为停用或已拆除时,弹出消息
  376. if (this.statusDisabled.includes(row?.sb_status)) {
  377. let message = `当前设备状态为“${row.sb_status}”,请复核现场情况,如有需要请前往编辑器删除。`; // `当前设备为“${row.sb_status}”状态,请前往编辑器重新编辑`
  378. // 防止出现多条message
  379. // 已经有 message时,并且this.message的message字段与message一致时, 不进行提示
  380. if (
  381. this.message &&
  382. this.message.visible &&
  383. this.message.message === message
  384. ) {
  385. return true;
  386. }
  387. this.message = Message({
  388. showClose: true,
  389. message,
  390. type: "warning",
  391. duration: 0,
  392. iconClass: "el-icon-warning-outline",
  393. customClass: "floor-map-warning",
  394. });
  395. // this.message = this.$message({
  396. // message,
  397. // type: 'warning',
  398. // })
  399. return true;
  400. }
  401. if (row.assetnum) {
  402. this.equipKey++;
  403. this.$nextTick(() => {
  404. this.$refs.equipDetail.open({ row: JSON.stringify(row) });
  405. });
  406. }
  407. }, 0),
  408. // handleClickEquipDetail(row) {
  409. // if (row.assetuid) {
  410. // window.open(`http://gcgl.wanda.cn/maximo/ui/?event=loadapp&value=assetdevic&uniqueid=${row.assetuid}`)
  411. // }
  412. // },
  413. // 查看浮层位置详情
  414. handleClickPointDeatil(point) {
  415. if (point.id && this.activeItem) {
  416. this.roomKey++;
  417. this.$nextTick(() => {
  418. this.$refs.boxRoom.open({
  419. name: this.activeItem.name,
  420. type: this.type,
  421. location: point.id,
  422. });
  423. });
  424. }
  425. },
  426. handleClickHightLight(pointData) {
  427. this.clearHightLight();
  428. pointData.forEach((point) => {
  429. let location = point.id ? point.id : "";
  430. // if (this.wellMap.hasOwnProperty(location)) {
  431. // this.wellMap[location].forEach((item) => {
  432. // item.highLightFlag = true
  433. // item.zOrder = 30
  434. // })
  435. // } else {
  436. let getParams = {
  437. plazaId: this.plazaId,
  438. floor: this.floorid,
  439. keyword: `${location}:wellnum;`,
  440. };
  441. queryShops({ getParams }).then((res) => {
  442. let shopsnumList = [];
  443. // let shopsnumItemList = []
  444. if (res.data && res.data.length) {
  445. for (let floor in res.data[0]) {
  446. if (res.data[0][floor].length) {
  447. res.data[0][floor].forEach((v) => {
  448. shopsnumList = shopsnumList.concat(v.shopsnumList.split(","));
  449. });
  450. }
  451. }
  452. }
  453. if (shopsnumList.length) {
  454. this.fParser.spaceList.forEach((item) => {
  455. if (
  456. shopsnumList.findIndex((name) => name == item.data.Name) != -1
  457. ) {
  458. item.highLightFlag = true;
  459. // item.zOrder = 30;
  460. // shopsnumItemList.push(item)
  461. }
  462. });
  463. // this.wellMap[location] = shopsnumItemList
  464. }
  465. });
  466. // }
  467. });
  468. this.visible = false;
  469. },
  470. ...mapActions(["getfmapID"]),
  471. init(floorid) {
  472. this.loading = true;
  473. this.floorid = floorid;
  474. this.mapSize();
  475. this.$refs.canvasFun.isShow = false;
  476. setTimeout(() => {
  477. this.clearGraphy();
  478. this.scene = new FloorScene();
  479. if (this.haveFengMap == 1) {
  480. this.scene.selectContainer.connect(
  481. "listChange",
  482. this,
  483. this.listChange
  484. );
  485. if (this.canvasID != `canvas${this.id}`) {
  486. this.canvasID = `canvas${this.id}`;
  487. }
  488. this.getGraphDetail().then((res) => {
  489. if (res.Content.length == 1) {
  490. const data = res.Content[0];
  491. if (data.MaxY && data.MinX) {
  492. window.fengmapData.maxY = data.MaxY;
  493. window.fengmapData.minX = data.MinX;
  494. }
  495. }
  496. this.parserData(floorid);
  497. });
  498. // this.parserData(floorid);
  499. } else if (this.haveFengMap == 0) {
  500. this.view.scene = this.scene;
  501. this.readGraph();
  502. } else {
  503. this.loading = false;
  504. }
  505. }, 100);
  506. },
  507. parserData(floor) {
  508. if (floor == "g80") {
  509. // 屋顶
  510. if (window.fengmapData.frImg) {
  511. const pj = this.fmapID.split("_")[0];
  512. // 单张图片
  513. if (!ProjectRf[pj]) {
  514. let imgItem = new SImageItem(
  515. null,
  516. `${this.mapServerURL}/webtheme/${this.fmapID}/${window.fengmapData.frImg}`
  517. );
  518. imgItem.showType = SImageShowType.AutoFit;
  519. imgItem.connect("imgLoadOver", this, () => {
  520. this.readGraph();
  521. });
  522. this.scene.addItem(imgItem);
  523. this.view.scene = this.scene;
  524. // this.view.fitSceneToView()
  525. } else {
  526. // 多张图
  527. try {
  528. // 初始化0
  529. this.count = 0;
  530. ProjectRf[pj].forEach((t) => {
  531. const item = new SImageItem(
  532. null,
  533. `${this.mapServerURL}/webtheme/${this.fmapID}/${t.name}`
  534. );
  535. item.width = t.width;
  536. item.height = t.height;
  537. item.moveTo(t.x, t.y);
  538. item.connect("imgLoadOver", this, () => {
  539. this.countRf(ProjectRf[pj].length);
  540. });
  541. this.scene.addItem(item);
  542. });
  543. this.view.scene = this.scene;
  544. } catch (e) {
  545. console.log(e);
  546. }
  547. }
  548. } else {
  549. // 屋顶图不为图片
  550. this.readBaseMap(floor);
  551. }
  552. } else {
  553. if (window.fengmapData.gnameToGid[floor]) {
  554. this.readBaseMap(floor);
  555. } else {
  556. console.log("楼层不正确");
  557. }
  558. }
  559. }, // 解析底图
  560. // 解析楼地板
  561. loadBoard(floor) {
  562. window.fengmapData.loadFloor(floor, (res) => {
  563. const zone = new SBoardItem(null, res);
  564. this.scene.addItem(zone);
  565. });
  566. },
  567. readBaseMap(floor) {
  568. this.loadBoard(window.fengmapData.gnameToGid[floor]);
  569. window.fengmapData.parseData(
  570. window.fengmapData.gnameToGid[floor],
  571. (res) => {
  572. if (res.err) {
  573. console.log("errr", res.err);
  574. return;
  575. }
  576. this.fParser = new SFloorParser(null);
  577. this.fParser.parseData(res);
  578. this.fParser.spaceList.forEach((t) => {
  579. this.scene.addItem(t);
  580. t.nameSize = 12;
  581. t.nameColor = "#2a2a2a";
  582. if (t.data.Name && this.bunkObj[t.data.Name]) {
  583. t.name = this.bunkObj[t.data.Name].brandname;
  584. } else {
  585. // t.name = t.data.Name
  586. t.name = "";
  587. }
  588. t.connect("onMouseDown", this, this.clickMapPlace);
  589. });
  590. this.fParser.wallList.forEach((t) => this.scene.addItem(t));
  591. this.fParser.virtualWallList.forEach((t) => this.scene.addItem(t));
  592. this.fParser.doorList.forEach((t) => this.scene.addItem(t));
  593. this.fParser.columnList.forEach((t) => this.scene.addItem(t));
  594. this.fParser.casementList.forEach((t) => this.scene.addItem(t));
  595. this.view.scene = this.scene;
  596. // this.view.fitSceneToView()
  597. this.readGraph();
  598. }
  599. );
  600. },
  601. // 点击底图空间
  602. clickMapPlace(item, e) {
  603. let wellId = null;
  604. let wellItem = null; //;对应的强电井
  605. if (item.data.Name) {
  606. this.shopsList.forEach((equip) => {
  607. equip.shopList.forEach((shop) => {
  608. if (item.data.Name == shop) {
  609. wellId = equip.wellnum;
  610. }
  611. });
  612. });
  613. }
  614. this.topologyParser.imageLegendList.forEach((eqItem) => {
  615. eqItem.data.AttachObjectIds.forEach((objId) => {
  616. if (objId.id == wellId) {
  617. // 点击空间高亮
  618. wellItem = eqItem;
  619. }
  620. });
  621. });
  622. if (wellItem) {
  623. setTimeout(() => {
  624. this.clearHightLight();
  625. item.highLightFlag = true;
  626. // item.zOrder = 30;
  627. wellItem.selected = true;
  628. const point = this.view.mapFromScene(wellItem.x, wellItem.y);
  629. const event = [
  630. {
  631. clientX: point.x,
  632. clientY: point.y,
  633. },
  634. ];
  635. this.isclickShopName = item.name ? item.name + '—'+ item.data.Name :'xxx —'+ item.data.Name ;
  636. this.handleClickLegendItem(wellItem, event, true);
  637. });
  638. } else {
  639. this.clearHightLight();
  640. }
  641. },
  642. readGraph() {
  643. this.readGroup(this.floorid)
  644. .then((data) => {
  645. if (data.Result == "failure") {
  646. this.$store.commit("SETISMESSAGE", false);
  647. this.view.fitSceneToView();
  648. this.view.minScale = this.view.scale;
  649. if (this.$refs.canvasFun) {
  650. this.$refs.canvasFun.everyScale = this.view.scale;
  651. }
  652. this.loading = false;
  653. return;
  654. } else {
  655. if (
  656. data.Data[0].Elements.Nodes.length === 0 &&
  657. data.Data[0].Elements.Markers.length === 0 &&
  658. data.Data[0].Elements.Relations.length === 0
  659. ) {
  660. this.$store.commit("SETISMESSAGE", false);
  661. } else {
  662. this.$store.commit("SETISMESSAGE", true);
  663. }
  664. }
  665. // 无返回Data处理
  666. if (!(data.Data && data.Data.length)) {
  667. this.view.fitSceneToView();
  668. this.view.minScale = this.view.scale;
  669. if (this.$refs.canvasFun) {
  670. this.$refs.canvasFun.everyScale = this.view.scale;
  671. }
  672. return false;
  673. }
  674. // 请求回来的备注
  675. if (data.Data && data.Data[0].Note) {
  676. let note = data.Data[0].Note;
  677. bus.$emit("queryRemarksMethods", note);
  678. } else {
  679. bus.$emit("queryRemarksMethods", "");
  680. }
  681. //土建装饰的图例展示
  682. if (this.$cookie.get("categoryId") == "SCPZ") {
  683. let scpzTable = [],
  684. arr = [];
  685. scpzTable = data.Data[0].Elements.Nodes || [];
  686. if (scpzTable.length > 0) {
  687. scpzTable.forEach((e) => {
  688. if (e.Properties.ItemExplain) {
  689. let obj = e;
  690. arr.push(obj);
  691. }
  692. });
  693. }
  694. console.log(arr);
  695. this.$store.commit("SETSCPZTABLE", arr);
  696. }
  697. if (data.Data[0].Elements.Nodes.length > 0) {
  698. this.$store.commit("SETTYPENUM", "");
  699. let Lengd = data.Data[0].Elements.Nodes;
  700. Lengd.forEach((el) => {
  701. if (el.Type == "Image" && el.Num > 1) {
  702. console.log(el.Num);
  703. this.$store.commit("SETTYPENUM", el.Num);
  704. }
  705. });
  706. }
  707. // 放到后边 $cookie graphId
  708. this.$cookie.set("graphId", data.Data[0].ID, 3);
  709. if (this.$cookie.get("graphId")) {
  710. // 得到graphId 就请求图例
  711. // 除土建装饰之外的图例展示 包括楼层功能
  712. bus.$emit("queryViewMethods");
  713. }
  714. this.topologyParser = new STopologyParser(null);
  715. this.topologyParser.parseData(data.Data[0].Elements);
  716. // 多边形
  717. this.topologyParser.zoneLegendList.forEach((t) => {
  718. this.scene.addItem(t);
  719. t.connect("legendItemClick", t, this.handleClickLegendItem);
  720. });
  721. // 增加文字
  722. this.topologyParser.textMarkerList.forEach((t) => {
  723. this.scene.addItem(t);
  724. });
  725. // 增加图片
  726. this.topologyParser.imageMarkerList.forEach((t) => {
  727. this.scene.addItem(t);
  728. });
  729. // 增加直线
  730. this.topologyParser.lineMarkerList.forEach((t) => {
  731. this.scene.addItem(t);
  732. });
  733. // 增加图标类图例
  734. this.topologyParser.imageLegendList.forEach((t) => {
  735. this.scene.addItem(t);
  736. t.connect("legendItemClick", t, this.handleClickLegendItem);
  737. });
  738. // 获取本层楼所有电井对应的商铺 id
  739. this.shopLisghtWell();
  740. // 增加管线类
  741. // 增加图标类图例
  742. this.topologyParser.relationList.forEach((t) => {
  743. t.selectable = true;
  744. this.scene.addItem(t);
  745. t.connect("legendItemClick", t, this.handleClickLegendItem);
  746. });
  747. this.view.fitSceneToView();
  748. this.view.minScale = this.view.scale;
  749. if (this.$refs.canvasFun) {
  750. this.$refs.canvasFun.everyScale = this.view.scale;
  751. }
  752. this.loading = false;
  753. })
  754. .catch(() => {
  755. this.loading = false;
  756. });
  757. },
  758. // 顶楼为多张图时计数器
  759. countRf(len) {
  760. this.count++;
  761. if (len == this.count) {
  762. this.readGraph();
  763. } else {
  764. console.log("所有图片未加载完成");
  765. }
  766. },
  767. clearGraphy() {
  768. if (this.view) {
  769. this.view.scene = null;
  770. return;
  771. }
  772. this.view = new FloorView(`canvas${this.id}`);
  773. },
  774. listChange(item, ev) {
  775. // if (ev[0].length) {
  776. // let selectItem1 = ev[0][0],
  777. // location = selectItem1.data.AttachObjectIds[0] ? selectItem1.data.AttachObjectIds[0].id : ''
  778. // // 空间类型都可打开弹窗(除防火分区 编号100131,商管办公室 编号100112,铺装石材 编号100129)
  779. // if (selectItem1.data.GraphElementType == 'Zone') {
  780. // if (
  781. // selectItem1.data.GraphElementId != '100131' &&
  782. // selectItem1.data.GraphElementId != '100112' &&
  783. // selectItem1.data.GraphElementId != '100129'
  784. // ) {
  785. // if (location) {
  786. // this.$refs.boxRoom.open({ name: selectItem1.name, type: this.type, location: location })
  787. // }
  788. // }
  789. // }
  790. // // // 选中电井设置电井关联的商铺高亮
  791. // // this.setHightLight(ev[0])
  792. // }
  793. // else {
  794. // this.clearHightLight()
  795. // }
  796. if (ev[0].length) {
  797. if (
  798. !(
  799. ev[0][0] instanceof SPolygonItem ||
  800. ev[0][0] instanceof TipelineItem ||
  801. ev[0][0] instanceof SImageLegendItem
  802. )
  803. ) {
  804. this.visible = false;
  805. }
  806. } else {
  807. this.visible = false;
  808. }
  809. this.clearHightLight();
  810. },
  811. // 选中电井关联的商铺高亮
  812. setHightLight(arr) {
  813. this.clearHightLight();
  814. arr.forEach((item) => {
  815. let location = item.data.AttachObjectIds[0]
  816. ? item.data.AttachObjectIds[0].id
  817. : "";
  818. // 添加了位置类型并且选中的类型为电井类型
  819. if (
  820. (item.data.GraphElementId == "100050" ||
  821. item.data.GraphElementId == "100055" ||
  822. item.data.GraphElementId == "100056" ||
  823. item.data.GraphElementId == "100057") &&
  824. location
  825. ) {
  826. if (this.wellMap.hasOwnProperty(location)) {
  827. this.wellMap[location].forEach((item) => {
  828. item.highLightFlag = true;
  829. // item.zOrder = 30;
  830. });
  831. } else {
  832. let getParams = {
  833. plazaId: this.plazaId,
  834. floor: this.floorid,
  835. keyword: `${location}:wellnum;`,
  836. };
  837. queryShops({ getParams }).then((res) => {
  838. let shopsnumList = [];
  839. let shopsnumItemList = [];
  840. if (res.data && res.data.length) {
  841. for (let floor in res.data[0]) {
  842. if (res.data[0][floor].length) {
  843. res.data[0][floor].forEach((v) => {
  844. shopsnumList = shopsnumList.concat(
  845. v.shopsnumList.split(",")
  846. );
  847. });
  848. }
  849. }
  850. }
  851. if (shopsnumList.length) {
  852. this.fParser.spaceList.forEach((item) => {
  853. if (
  854. shopsnumList.findIndex((name) => name == item.data.Name) !=
  855. -1
  856. ) {
  857. item.highLightFlag = true;
  858. // item.zOrder = 30;
  859. shopsnumItemList.push(item);
  860. }
  861. });
  862. this.wellMap[location] = shopsnumItemList;
  863. }
  864. });
  865. }
  866. }
  867. });
  868. },
  869. // 清除电井关联商铺的高亮状态
  870. clearHightLight() {
  871. this.isclickShopName = '';
  872. // 所有电井置为 select = false
  873. this.topologyParser.imageLegendList.forEach((eqItem) => {
  874. eqItem.selected = false;
  875. });
  876. ItemColor.spaceHighColor = new SColor("#FBF2CC");
  877. // for (let key in this.wellMap) {
  878. // this.wellMap[key].forEach((item) => {
  879. // item.highLightFlag = false
  880. // item.zOrder = ItemOrder.spaceOrder
  881. // })
  882. // }
  883. this.fParser.spaceList.forEach((item) => {
  884. item.highLightFlag = false;
  885. item.zOrder = ItemOrder.spaceOrder;
  886. });
  887. },
  888. // 适配底图到窗口
  889. fit() {
  890. this.view.fitSceneToView();
  891. },
  892. // 保存为png
  893. savePng() {
  894. // this.view.saveImage(`${this.loadName}.png`, 'png')
  895. this.view.saveImageSize(
  896. `${this.loadName}.png`,
  897. "png",
  898. 1920 * 2,
  899. 1080 * 2
  900. );
  901. //console.log(`${this.loadName}.png`)
  902. },
  903. // 保存为svg
  904. saveSvg() {
  905. this.view.saveSceneSvg(`${this.loadName}.svg`, 6400, 4800);
  906. },
  907. // 保存为json
  908. saveJson() {
  909. this.view.saveFloorJson(`${this.loadName}.json`);
  910. },
  911. // 缩放
  912. scale(val) {
  913. if (!this.view) {
  914. return;
  915. }
  916. let scale = this.view.scale;
  917. this.view.scaleByPoint(
  918. val / scale,
  919. this.canvasWidth / 2,
  920. this.canvasHeight / 2
  921. );
  922. },
  923. // 小眼睛控制显示铺位名称
  924. showText(val) {
  925. // this.topologyParser.zoneLegendList.forEach(t => {
  926. // t.showText = val
  927. // })
  928. this.fParser.spaceList.forEach((t) => {
  929. t.showBaseName = val;
  930. });
  931. },
  932. // 读取数据
  933. readGroup(FloorID) {
  934. const data = {
  935. BuildingID: "1",
  936. FloorID: FloorID,
  937. categoryId: this.categoryId
  938. ? this.categoryId
  939. : this.$cookie.get("categoryId"),
  940. projectId: this.urlMsg.ProjectID,
  941. Pub: true,
  942. };
  943. return readGroup(data);
  944. },
  945. // 获取图最大最小值
  946. getGraphDetail() {
  947. const categoryId = this.categoryId
  948. ? this.categoryId
  949. : this.$cookie.get("categoryId");
  950. const data = {
  951. Filters: `categoryId='${categoryId}';projectId='${this.urlMsg.ProjectID}';BuildingID='1';FloorID='${this.floorid}';isPub=true`,
  952. };
  953. return graphQuery(data);
  954. },
  955. // 地图尺寸
  956. mapSize() {
  957. this.canvasWidth = this.$refs.graphy.offsetWidth;
  958. if (window.screen.height == "768") {
  959. this.canvasHeight = this.$refs.graphy.offsetHeight - 100;
  960. } else {
  961. this.canvasHeight = 900;
  962. }
  963. // 弹窗中底图高度适配
  964. if (this.modalHeight) {
  965. this.canvasHeight = this.modalHeight;
  966. }
  967. },
  968. getEvent() {
  969. bus.$on("changeShow", (res) => {
  970. this.topologyParser &&
  971. this.topologyParser.zoneLegendList.forEach((t) => {
  972. let id = t.data.GraphElementId;
  973. t.maskFlag = !(res.indexOf(id) > -1);
  974. });
  975. // this.topologyParser.textMarkerList.forEach(t => {
  976. // let id = t.data.GraphElementId
  977. // t.maskFlag = !(res.indexOf(id) > -1)
  978. // })
  979. // this.topologyParser.imageMarkerList.forEach(t => {
  980. // let id = t.data.GraphElementId
  981. // t.maskFlag = !(res.indexOf(id) > -1)
  982. // })
  983. // this.topologyParser.lineMarkerList.forEach(t => {
  984. // let id = t.data.GraphElementId
  985. // t.maskFlag = !(res.indexOf(id) > -1)
  986. // })
  987. this.topologyParser &&
  988. this.topologyParser.imageLegendList.forEach((t) => {
  989. let id = t.data.GraphElementId;
  990. t.maskFlag = !(res.indexOf(id) > -1);
  991. });
  992. this.topologyParser &&
  993. this.topologyParser.relationList.forEach((t) => {
  994. let id = t.data.GraphElementId || t.data.GraphElementID;
  995. t.maskFlag = !(res.indexOf(id) > -1);
  996. });
  997. });
  998. },
  999. /**
  1000. * @description 处理popover显隐
  1001. * 当点击位置不在canvas内部时 ( 如点击 页面空白,图例,楼层,设备设施左侧列表项时),将visible置为false,隐藏popover
  1002. */
  1003. handlePopover(e) {
  1004. this.$nextTick(() => {
  1005. if (!this.$refs.graphy.contains(e.target)) {
  1006. this.visible = false;
  1007. }
  1008. this.showStatusText = false;
  1009. this.statusText = "";
  1010. // 关闭message提示
  1011. if (this.message) {
  1012. this.message.close();
  1013. this.message = null;
  1014. }
  1015. });
  1016. },
  1017. /**
  1018. * @description 设备状态列, 状态为停用或已拆除时,样式红色
  1019. */
  1020. tableCellClassName({ row, column, rowIndex, columnIndex }) {
  1021. if (columnIndex === 2 && this.statusDisabled.includes(row.sb_status)) {
  1022. return "status-disabled";
  1023. }
  1024. },
  1025. },
  1026. watch: {
  1027. "view.scale": {
  1028. handler(n) {
  1029. if (this.$refs.canvasFun) {
  1030. let s = (n * 10) / this.view.minScale;
  1031. this.$refs.canvasFun.sliderVal = s > 1000 ? 1000 : s;
  1032. }
  1033. },
  1034. },
  1035. haveFengMap() {
  1036. this.init(this.floorid);
  1037. },
  1038. },
  1039. mounted() {
  1040. this.mapSize();
  1041. this.getEvent();
  1042. // 添加监听点击事件,处理popover显隐
  1043. window.addEventListener("click", this.handlePopover, false);
  1044. this.$once("hook:beforeDestroy", () => {
  1045. window.removeEventListener("click", this.handlePopover);
  1046. });
  1047. },
  1048. created() {
  1049. // document.addEventListener("mousedown", () => {
  1050. // this.visible = false;
  1051. // })
  1052. this.urlMsg = {
  1053. categoryId: this.$cookie.get("categoryId"),
  1054. ProjectID: this.plazaId,
  1055. BuildingID: "1",
  1056. FloorID: this.$cookie.get("floorMapId") || "f1",
  1057. fmapID: this.fmapID,
  1058. };
  1059. },
  1060. };
  1061. </script>
  1062. <style lang="less" scoped>
  1063. #floor_base {
  1064. position: relative;
  1065. height: 100%;
  1066. .fengMap {
  1067. position: fixed;
  1068. width: 100px;
  1069. height: 100px;
  1070. z-index: -1;
  1071. }
  1072. .strip-bottom {
  1073. position: absolute;
  1074. right: 0;
  1075. bottom: 40px;
  1076. width: 100%;
  1077. }
  1078. .popStyle {
  1079. position: fixed;
  1080. }
  1081. }
  1082. </style>
  1083. <style lang="less">
  1084. a:hover {
  1085. text-decoration: none;
  1086. }
  1087. .el-popover {
  1088. .el-table {
  1089. tr {
  1090. .equip-detail-btn {
  1091. display: none;
  1092. }
  1093. }
  1094. tr:hover {
  1095. cursor: pointer;
  1096. .equip-detail-btn {
  1097. cursor: pointer;
  1098. display: inline-block;
  1099. color: #025baa;
  1100. }
  1101. }
  1102. }
  1103. .pointList {
  1104. max-height: 235px;
  1105. overflow-y: auto;
  1106. text-align: right;
  1107. li {
  1108. height: 38px;
  1109. line-height: 38px;
  1110. padding: 0 12px;
  1111. cursor: pointer;
  1112. border-bottom: 1px solid rgba(0, 0, 0, 0.06);
  1113. span {
  1114. float: left;
  1115. width: 260px;
  1116. text-align: left;
  1117. overflow: hidden;
  1118. text-overflow: ellipsis;
  1119. white-space: nowrap;
  1120. }
  1121. a {
  1122. display: none;
  1123. color: #025baa;
  1124. font-size: 13px;
  1125. }
  1126. }
  1127. li:hover {
  1128. background-color: #f5f6f7;
  1129. a {
  1130. display: inline-block;
  1131. }
  1132. }
  1133. }
  1134. .el-button--primary {
  1135. background: linear-gradient(180deg, #369cf7 0%, #025baa 100%);
  1136. }
  1137. .el-tabs--bottom .el-tabs__item.is-bottom:nth-child(2),
  1138. .el-tabs--bottom .el-tabs__item.is-top:nth-child(2),
  1139. .el-tabs--top .el-tabs__item.is-bottom:nth-child(2),
  1140. .el-tabs--top .el-tabs__item.is-top:nth-child(2) {
  1141. padding-left: 16px;
  1142. }
  1143. .el-tabs--bottom .el-tabs__item.is-bottom:last-child,
  1144. .el-tabs--bottom .el-tabs__item.is-top:last-child,
  1145. .el-tabs--top .el-tabs__item.is-bottom:last-child,
  1146. .el-tabs--top .el-tabs__item.is-top:last-child {
  1147. padding-right: 16px;
  1148. }
  1149. .el-tabs__nav-wrap::after {
  1150. height: 0;
  1151. }
  1152. .is-active {
  1153. color: #025baa !important;
  1154. border-color: #025baa !important;
  1155. background: rgba(2, 91, 170, 0.15);
  1156. }
  1157. .el-tabs__item {
  1158. padding: 5px 16px;
  1159. height: 30px;
  1160. line-height: 20px;
  1161. font-size: 14px;
  1162. font-family: MicrosoftYaHei;
  1163. color: rgba(31, 36, 41, 1);
  1164. border: 1px solid rgba(195, 199, 203, 1);
  1165. }
  1166. .el-tabs__active-bar {
  1167. background-color: transparent !important;
  1168. }
  1169. /deep/ .el-tabs__item:last-child {
  1170. border-radius: 0px 4px 4px 0px;
  1171. }
  1172. /deep/ .el-tabs__item:nth-child(2) {
  1173. border-radius: 4px 0px 0px 4px;
  1174. }
  1175. // 设备状态
  1176. .status-disabled {
  1177. color: #c0c4cc !important;
  1178. text-decoration: line-through;
  1179. }
  1180. }
  1181. // 警告message样式修改
  1182. .floor-map-warning {
  1183. background-color: #ffa53d;
  1184. color: #fff;
  1185. font-size: 14px;
  1186. /deep/ .el-icon-warning-outline {
  1187. font-weight: 600 !important;
  1188. margin-right: 5px;
  1189. }
  1190. /deep/.el-icon-close {
  1191. color: #fff;
  1192. opacity: 0.5;
  1193. }
  1194. }
  1195. .wellTooltip{
  1196. background: #FEEAD2;
  1197. margin-left: 12px;
  1198. height: 22px;
  1199. line-height: 22px;
  1200. display: inline-block;
  1201. padding: 0px 12px 0 12px;
  1202. color: #B26206;
  1203. }
  1204. </style>