index.vue 37 KB

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