drafts.vue 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689
  1. <template>
  2. <div id="drafts">
  3. <div class="tit">草稿箱</div>
  4. <div class="conent">
  5. <div class="left-nav">
  6. <Tree :data="treeData" @change="change" v-if="treeData.length"></Tree>
  7. <div v-else style="text-align: center;margin-top: 20px;">暂无数据</div>
  8. <!-- <el-tree ref="tree" :data="treeData" :props="defaultProps" @node-click="handleNodeClick" node-key="id" :expand-on-click-node="false"-->
  9. <!-- :current-node-key="currentNodekey"-->
  10. <!-- :default-expanded-keys="expandedkeys">-->
  11. <!-- <span class="span-ellipsis" slot-scope="{ node, data }">-->
  12. <!-- <span :title="node.label">{{ node.label }}</span>-->
  13. <!-- </span>-->
  14. <!-- </el-tree>-->
  15. </div>
  16. <div class="conent-right">
  17. <div class="conent-tit">
  18. <div class="tit-left" v-if="floorName">{{systemName}}-{{floorName}}</div>
  19. <div class="tit-right">
  20. <a-button @click="deleteBtn" :disabled="!floorName">删除</a-button>
  21. <a-button @click="publishBtn" :disabled="!floorName">发布</a-button>
  22. <a-button type="primary" @click="goToEditer" :disabled="!floorName">编辑</a-button>
  23. </div>
  24. </div>
  25. <div class="concent-bottom">
  26. <div class="map">
  27. <div class="canvas-container" ref="draftsCanvas">
  28. <div id="fengMap"></div>
  29. <canvas
  30. id="canvas"
  31. :width="canvasWidth"
  32. :height="canvasHeight"
  33. ref="canvas"
  34. tabindex="0"
  35. ></canvas>
  36. </div>
  37. </div>
  38. <div v-show="!legend" class="legend-btn" @click="legend = !legend">
  39. <a-icon type="left" style="color: #8D9399;font-size: 10px" />
  40. </div>
  41. <div v-show="legend" class="legend-btn legend-btn-close" @click="legend = !legend">
  42. <a-icon type="right" style="color: #8D9399;font-size: 10px" />
  43. </div>
  44. <div class="legend" v-if="legend">
  45. <div
  46. style="font-size:14px;color: #1F2429;padding-left: 12px;height: 40px;line-height: 40px"
  47. >可能需要补充的图例</div>
  48. <a-table
  49. v-loading="legendLoading"
  50. :columns="columns"
  51. :rowKey="(record,index)=>{return index}"
  52. :data-source="legendData"
  53. size="middle"
  54. :pagination="false"
  55. >
  56. <div slot="Url" slot-scope="text,record">
  57. <img
  58. v-if="record.Url"
  59. style=" width: 20px;height: 22px;"
  60. :src="'/serve/topology-wanda/Picture/query/'+ record.Url"
  61. alt
  62. />
  63. <span v-else>---</span>
  64. </div>
  65. <span></span>
  66. </a-table>
  67. </div>
  68. </div>
  69. </div>
  70. </div>
  71. </div>
  72. </template>
  73. <script>
  74. import Tree from "./../components/Tree/Tree.vue";
  75. import { SFengParser } from "@saga-web/feng-map";
  76. import { SFloorParser } from "@saga-web/big";
  77. import { FloorView } from "./../lib/FloorView";
  78. import { EditScence } from "@/components/mapClass/EditScence";
  79. import bus from "@/bus";
  80. import {
  81. readGroup,
  82. queryDraftGroup,
  83. queryStatistic,
  84. deleteGraph,
  85. publishGraph
  86. } from "@/api/editer.js";
  87. import { STopologyParser } from "./../lib/parsers/STopologyParser";
  88. import { uuid } from "@/components/mapClass/until";
  89. import { SImageItem } from "@saga-web/graph/lib";
  90. import store from "../store";
  91. import { Loading } from "element-ui";
  92. import { getUrlMsg } from "@/components/urlMsg.js";
  93. let fengmap = null;
  94. export default {
  95. components: { Tree },
  96. data() {
  97. return {
  98. treeData: [],
  99. columns: [
  100. {
  101. title: "名称", // 列的名称
  102. dataIndex: "Name", // 列的标识
  103. scopedSlots: { customRender: "Name" }
  104. },
  105. {
  106. title: "图例", // 列的名称
  107. dataIndex: "Url", // 列的标识
  108. scopedSlots: { customRender: "Url" }
  109. }
  110. ],
  111. legendData: [],
  112. legend: true,
  113. canvasWidth: 700,
  114. canvasHeight: 600,
  115. view: null,
  116. urlMsg: null,
  117. floorList: {},
  118. mapServerURL: "http://map.wanda.cn/editor",
  119. mapthemeUrl: `http://map.wanda.cn/editor/webtheme`,
  120. key: "23f30a832a862c58637a4aadbf50a566",
  121. appName: "万达可视化系统",
  122. defaultProps: {
  123. children: "Category",
  124. label: "Gcode"
  125. },
  126. projectId: "", //项目id
  127. fmapID: "", //蜂鸟地图id
  128. graphId: "", //绘制生成得图id
  129. legendLoading: false,
  130. systemName: "",
  131. floorName: "",
  132. floorId: "", //楼层id
  133. BuildingID: "1", // 建筑id
  134. categoryId: "", //系统类id
  135. currentNodekey: "", //默认选中的节点树
  136. expandedkeys: [] //默认展开的节点树
  137. };
  138. },
  139. methods: {
  140. // handleNodeClick(data, node) {
  141. // this.legendData = [];
  142. // this.systemName = "";
  143. // this.floorName = "";
  144. // if (data.Gname) {
  145. // this.systemName = node.parent.data.Gcode;
  146. // this.floorName = data.Gcode;
  147. // this.floorId = data.Gname;
  148. // this.categoryId = node.parent.data.Id;
  149. // this.getLegend();
  150. // this.checkFloor(data.Gname);
  151. // }
  152. // },
  153. //初始化获取蜂鸟所有底图数据
  154. init() {
  155. const loadings = Loading.service({
  156. lock: true,
  157. text: "Loading",
  158. spinner: "el-icon-loading",
  159. background: "rgba(0, 0, 0, 0.7)"
  160. });
  161. // const loadings = this.$loading({type: 'global'});
  162. document.getElementById(`canvas`).focus();
  163. if(this.fmapID.includes('null')){
  164. loadings.close();
  165. this.getTreeData();
  166. }
  167. fengmap = new SFengParser(
  168. "fengMap",
  169. this.mapServerURL + "/fmap/" + this.fmapID,
  170. this.key,
  171. this.appName,
  172. null,
  173. this.mapthemeUrl
  174. );
  175. fengmap.loadMap(this.fmapID, resp => {
  176. this.floorList = resp;
  177. fengmap
  178. .loadTheme(
  179. `${this.mapServerURL}/webtheme/${this.fmapID}/${this.fmapID}.theme`
  180. )
  181. .then(response => {
  182. // 获取楼层数据数据
  183. loadings.close();
  184. this.getTreeData();
  185. });
  186. });
  187. },
  188. clearGraphy() {
  189. if (this.view) {
  190. this.view.scene = null;
  191. return;
  192. }
  193. this.view = new FloorView("canvas");
  194. document.getElementById("canvas").focus();
  195. },
  196. parserData(floor) {
  197. if (floor == "g80") {
  198. // 屋顶
  199. if (fengmap.frImg) {
  200. const imgItem = new SImageItem(
  201. null,
  202. `${this.mapServerURL}/webtheme/${this.fmapID}/${fengmap.frImg}`
  203. );
  204. this.scene.addItem(imgItem);
  205. this.view.fitSceneToView();
  206. this.loading = false;
  207. this.isQuerying = false;
  208. }
  209. } else {
  210. if (this.floorList[floor]) {
  211. fengmap.parseData(this.floorList[floor], res => {
  212. if (res.err) {
  213. console.log(res.err);
  214. return;
  215. }
  216. this.fParser = new SFloorParser(null);
  217. this.fParser.parseData(res);
  218. this.fParser.spaceList.forEach(t => {
  219. t.selectable = true;
  220. this.scene.addItem(t);
  221. });
  222. this.fParser.wallList.forEach(t => this.scene.addItem(t));
  223. this.fParser.virtualWallList.forEach(t => this.scene.addItem(t));
  224. this.fParser.doorList.forEach(t => this.scene.addItem(t));
  225. this.fParser.columnList.forEach(t => this.scene.addItem(t));
  226. this.fParser.casementList.forEach(t => this.scene.addItem(t));
  227. this.view.scene = this.scene;
  228. this.view.fitSceneToView();
  229. this.loading = false;
  230. this.isQuerying = false;
  231. console.log("success");
  232. });
  233. } else {
  234. console.log("楼层不正确");
  235. }
  236. }
  237. },
  238. change(id) {
  239. const data = this.treeData;
  240. (function recursion(newObj) {
  241. newObj.map(function(item, index) {
  242. item.open = false;
  243. item.checked = false;
  244. if (item.Category && item.Category.length > 0) {
  245. item.children = item.Category;
  246. recursion(item.Category);
  247. }
  248. });
  249. })(data);
  250. let items = null;
  251. data.forEach(ele => {
  252. ele.children.forEach(item => {
  253. ele.open = true;
  254. if (item.children) {
  255. item.children.forEach(item1 => {
  256. item.open = true;
  257. if (item1.id == id.id) {
  258. items = item;
  259. item1.checked = "checked";
  260. }
  261. });
  262. } else {
  263. if (item.id == id.id) {
  264. items = ele;
  265. ele.open = true;
  266. item.checked = "checked";
  267. }
  268. }
  269. });
  270. });
  271. this.legendData = [];
  272. this.systemName = "";
  273. this.floorName = "";
  274. this.systemName = items.Gcode;
  275. this.floorName = id.Gcode;
  276. this.floorId = id.Gname;
  277. this.categoryId = items.Id;
  278. // this.getLegend();
  279. this.checkFloor(id.Gname);
  280. console.log(items);
  281. },
  282. getTreeData() {
  283. const loadings = Loading.service({
  284. lock: true,
  285. text: "Loading",
  286. spinner: "el-icon-loading",
  287. background: "rgba(0, 0, 0, 0.7)"
  288. });
  289. queryDraftGroup({ projectId: this.projectId })
  290. .then(res => {
  291. console.log(res);
  292. loadings.close();
  293. if (res.Result == "success") {
  294. const data = res.Data;
  295. this.systemName = "";
  296. this.floorName = "";
  297. this.floorId = "";
  298. this.categoryId = "";
  299. if (data.length) {
  300. (function recursion(newObj) {
  301. newObj.map(function(item, index) {
  302. item.id = item.Id || item.Gname;
  303. item.name = item.Gcode;
  304. item.checked = false;
  305. if (item.Category && item.Category.length > 0) {
  306. item.children = item.Category;
  307. item.open = false;
  308. recursion(item.Category);
  309. }
  310. });
  311. })(data);
  312. data.forEach(ele => {
  313. ele.children.forEach(item => {
  314. ele.open = true;
  315. if (item.children) {
  316. item.open = true;
  317. item.children.forEach(item1 => {
  318. item1.id = item.Id + item1.Gname;
  319. });
  320. } else {
  321. item.id = ele.Id + item.Gname;
  322. }
  323. });
  324. });
  325. this.treeData = data;
  326. if (this.treeData[0].children[0].children) {
  327. this.treeData[0].open = true;
  328. this.treeData[0].children[0].open = true;
  329. this.treeData[0].children[0].children[0].checked = "checked";
  330. this.systemName = this.treeData[0].children[0].Gcode;
  331. this.floorName = this.treeData[0].children[0].children[0].Gcode;
  332. this.floorId = this.treeData[0].children[0].children[0].Gname;
  333. this.categoryId = this.treeData[0].children[0].Id;
  334. // this.getLegend();
  335. this.checkFloor(this.treeData[0].children[0].children[0].Gname);
  336. } else {
  337. this.treeData[0].open = true;
  338. this.treeData[0].children[0].checked = "checked";
  339. this.systemName = this.treeData[0].Gcode;
  340. this.floorName = this.treeData[0].children[0].Gcode;
  341. this.floorId = this.treeData[0].children[0].Gname;
  342. this.categoryId = this.treeData[0].Id;
  343. // this.getLegend();
  344. this.checkFloor(this.treeData[0].children[0].Gname);
  345. }
  346. } else {
  347. this.treeData = data;
  348. }
  349. } else {
  350. this.treeData = [];
  351. this.$message.error("获取楼层结构失败");
  352. }
  353. // 如果没有楼层则底图清空
  354. if (this.treeData.length == 0) {
  355. this.checkFloor("");
  356. }
  357. })
  358. .catch(() => {
  359. loadings.close();
  360. this.$message.error("请求失败");
  361. });
  362. },
  363. //获取补充图例
  364. getLegend() {
  365. this.legendLoading = true;
  366. this.legendData = [];
  367. queryStatistic({
  368. projectId: this.projectId,
  369. graphId: this.graphId,
  370. categoryId: this.categoryId
  371. }).then(res => {
  372. console.log(res);
  373. this.legendLoading = false;
  374. if (res.data.Result == "success") {
  375. const data = res.data.Data;
  376. data.map(item => {
  377. this.legendData.push(item);
  378. });
  379. } else {
  380. this.legendData = [];
  381. this.$message.error("获取楼层结构补充图例失败");
  382. }
  383. });
  384. },
  385. //删除
  386. deleteBtn() {
  387. const loadings = Loading.service({
  388. lock: true,
  389. text: "Loading",
  390. spinner: "el-icon-loading",
  391. background: "rgba(0, 0, 0, 0.7)"
  392. });
  393. deleteGraph([{ Id: this.graphId }]).then(res => {
  394. console.log(res);
  395. loadings.close();
  396. if (res.Result == "success") {
  397. this.$message.success("删除成功");
  398. this.getTreeData();
  399. // this.init();
  400. this.legendData = [];
  401. } else {
  402. this.$message.error(res.Message);
  403. }
  404. });
  405. },
  406. //发布
  407. publishBtn() {
  408. const loadings = Loading.service({
  409. lock: true,
  410. text: "Loading",
  411. spinner: "el-icon-loading",
  412. background: "rgba(0, 0, 0, 0.7)"
  413. });
  414. console.log(this.floorId);
  415. const data = {
  416. BuildingID: this.BuildingID,
  417. CategoryID: this.categoryId,
  418. FloorID: this.floorId,
  419. GraphId: this.graphId,
  420. ProjectID: this.projectId,
  421. Pub: false,
  422. PubUser: ""
  423. };
  424. publishGraph(data).then(res => {
  425. loadings.close();
  426. if (res.Result == "success") {
  427. this.$message.success("发布成功");
  428. this.getTreeData();
  429. this.legendData = [];
  430. } else {
  431. this.$message.error(res.Message);
  432. }
  433. });
  434. },
  435. // 读取数据
  436. readGroup(floorid) {
  437. const data = {
  438. categoryId: this.categoryId,
  439. projectId: this.projectId,
  440. BuildingID: this.BuildingID, // 建筑ID
  441. FloorID: floorid, // 楼层id
  442. Pub: false
  443. };
  444. return readGroup(data);
  445. },
  446. /**
  447. * @name goToEditer
  448. * @description t跳转editer编辑器
  449. */
  450. goToEditer() {
  451. setTimeout(() => {
  452. /* const token = this.$store.getters["token"];
  453. const data = `categoryId=${this.categoryId}&projectId=${this.projectId}&BuildingID=1&FloorID=${this.floorId}&FloorName=${this.floorName}&fmapID=${this.fmapID}&token=${token}`;
  454. const url =
  455. window.location.origin +
  456. "/wandaEditer/editer?" +
  457. encodeURIComponent(data);
  458. window.open(url, true); */
  459. // 发布成功跳转草稿箱
  460. const token = this.$store.getters["token"];
  461. this.$router.push({
  462. path: "editer",
  463. query: {
  464. categoryId: this.categoryId,
  465. projectId: this.projectId,
  466. BuildingID: 1,
  467. FloorName: this.floorName,
  468. FloorID: this.floorId,
  469. fmapID: this.fmapID,
  470. token:token
  471. }
  472. });
  473. }, 1000);
  474. },
  475. // 切换草稿箱楼层
  476. checkFloor(floorid) {
  477. this.scene = new EditScence();
  478. this.scene.isEditStatus = false;
  479. this.clearGraphy();
  480. const loadings = Loading.service({
  481. lock: true,
  482. text: "Loading",
  483. spinner: "el-icon-loading",
  484. background: "rgba(0, 0, 0, 0.7)"
  485. });
  486. if(!floorid){
  487. loadings.close();
  488. this.view.fitSceneToView();
  489. return
  490. }
  491. setTimeout(() => {
  492. this.view.scene = this.scene;
  493. this.parserData(floorid);
  494. this.readGroup(floorid).then(data => {
  495. if (data.Result == "success") {
  496. this.graphId = data.Data[0].ID;
  497. if (data.Data) {
  498. loadings.close();
  499. const parserData = new STopologyParser(null);
  500. parserData.parseData(data.Data[0].Elements);
  501. // 多边形
  502. parserData.zoneLegendList.forEach(t => {
  503. this.scene.addItem(t);
  504. this.scene.Nodes.push(t);
  505. });
  506. // 增加文字
  507. parserData.textMarkerList.forEach(t => {
  508. this.scene.addItem(t);
  509. this.scene.Markers.push(t);
  510. });
  511. // 增加图片
  512. parserData.imageMarkerList.forEach(t => {
  513. this.scene.addItem(t);
  514. this.scene.Markers.push(t);
  515. });
  516. // 增加直线
  517. parserData.lineMarkerList.forEach(t => {
  518. this.scene.addItem(t);
  519. this.scene.Markers.push(t);
  520. });
  521. // 增加图标类图例
  522. parserData.imageLegendList.forEach(t => {
  523. this.scene.addItem(t);
  524. this.scene.Nodes.push(t);
  525. });
  526. // 增加管线类
  527. // 增加图标类图例
  528. parserData.relationList.forEach(t => {
  529. this.scene.addItem(t);
  530. this.scene.Relations.push(t);
  531. });
  532. this.view.fitSceneToView();
  533. this.getLegend();
  534. }
  535. } else {
  536. loadings.close();
  537. }
  538. }).catch(()=>{
  539. loadings.close();
  540. });
  541. }, 100);
  542. }
  543. },
  544. mounted() {
  545. this.canvasWidth = this.$refs.draftsCanvas.offsetWidth - 10;
  546. this.canvasHeight = this.$refs.draftsCanvas.offsetHeight - 10;
  547. const href = window.location.href;
  548. let params = href.split("?")[1];
  549. if (!params) {
  550. // 参数有问题
  551. return false;
  552. }
  553. params = decodeURIComponent(params);
  554. const paramsArr = params.split("&");
  555. const obj = {};
  556. paramsArr.map(item => {
  557. const arr = item.split("=");
  558. obj[arr[0]] = arr[1];
  559. });
  560. console.log("obj", obj);
  561. this.projectId = obj.projectId ? obj.projectId : "1000423";
  562. this.fmapID = obj.fmapID ? obj.fmapID : "1000423_120";
  563. this.init();
  564. }
  565. };
  566. </script>
  567. <style lang="less" scoped>
  568. #drafts {
  569. widows: 100%;
  570. height: 100%;
  571. background: #f7f9fa;
  572. position: relative;
  573. .tit {
  574. width: 100%;
  575. height: 48px;
  576. display: flex;
  577. justify-content: center;
  578. align-items: center;
  579. border-bottom: #e4e5e7 solid 1px;
  580. font-size: 16px;
  581. font-weight: bold;
  582. }
  583. .conent {
  584. width: 100%;
  585. height: calc(100% - 48px);
  586. display: flex;
  587. position: relative;
  588. .left-nav {
  589. width: 224px;
  590. height: 100%;
  591. overflow-y: scroll;
  592. padding: 0 12px;
  593. /deep/ .el-tree {
  594. background: #f7f9fa;
  595. .el-tree-node__content {
  596. height: 38px;
  597. }
  598. /deep/.el-tree-node:focus > .el-tree-node__content {
  599. background-color: #e1f2ff !important;
  600. color: #0091ff !important;
  601. }
  602. }
  603. .span-ellipsis {
  604. width: 100%;
  605. overflow: hidden;
  606. white-space: nowrap;
  607. text-overflow: ellipsis;
  608. }
  609. }
  610. .conent-right {
  611. flex: 1;
  612. height: 100%;
  613. background: #fff;
  614. .conent-tit {
  615. width: 100%;
  616. display: flex;
  617. height: 59px;
  618. border: 1px solid #eff0f1;
  619. align-items: center;
  620. justify-content: space-between;
  621. padding: 0 16px 0 16px;
  622. box-sizing: border-box;
  623. .tit-left {
  624. font-size: 16px;
  625. font-weight: bold;
  626. color: rgba(31, 35, 41, 1);
  627. }
  628. .tit-right {
  629. width: 198px;
  630. display: flex;
  631. justify-content: space-between;
  632. margin-left: auto;
  633. }
  634. }
  635. .concent-bottom {
  636. height: calc(100% - 61px);
  637. display: flex;
  638. position: relative;
  639. .map {
  640. flex: 1;
  641. position: relative;
  642. height: 100%;
  643. /*height: calc(100% - 61px);*/
  644. /*background: red;*/
  645. }
  646. .legend {
  647. position: absolute;
  648. right: 0;
  649. top: 0;
  650. width: 200px;
  651. border-left: 1px solid #eff0f1;
  652. background-color: #ffffff;
  653. height: 100%;
  654. overflow-y: scroll;
  655. }
  656. .legend-btn {
  657. position: absolute;
  658. right: 0px;
  659. top: 9px;
  660. width: 10px;
  661. height: 24px;
  662. background: rgba(228, 229, 231, 1);
  663. display: flex;
  664. justify-content: center;
  665. align-items: center;
  666. cursor: pointer;
  667. }
  668. .legend-btn-close {
  669. right: 200px;
  670. }
  671. }
  672. }
  673. }
  674. }
  675. #fengMap {
  676. position: absolute;
  677. width: 100px;
  678. height: 100px;
  679. z-index: -1;
  680. }
  681. .canvas-container {
  682. width: 100%;
  683. height: 100%;
  684. }
  685. </style>