index.vue 37 KB

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