business.vue 53 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310
  1. <template>
  2. <div ref="graphyMain" class="canvasGraphy" style="width:100%;" v-loading="loading.show" :element-loading-text="loading.num + '/' + loading.total">
  3. <div v-show="hasMap" class="header-search">
  4. <!-- 初始两个按钮 -->
  5. <div v-show="type == 1">
  6. <el-button @click=" type = 2" icon="el-icon-search">查找业务空间</el-button>
  7. <el-button @click="myDialogVisible = true">创建业务空间</el-button>
  8. <span style="font-size:13px;color:#606266;margin-left:40px;display:inline-block;">
  9. 提示:
  10. <i style="color:red;">红色字体</i>的业务空间为不相邻元空间组成,请检查是否要修改
  11. </span>
  12. </div>
  13. <!-- 搜索下拉列表定位 -->
  14. <div v-show="type == 2">
  15. <el-autocomplete popper-class="my-autocomplete" v-model="search" :fetch-suggestions="querySearch" placeholder="输入平面图中已有的业务空间名称进行查找" width="180px" @select="handleSelect">
  16. <i class="el-icon-search el-input__icon" slot="suffix" @click="handleIconClick"></i>
  17. <template slot-scope="{ item }">
  18. <div class="name" style="position: relative;">
  19. {{ item.infos.RoomLocalName |cutString(8) }}
  20. <span
  21. class="addr"
  22. style="position: absolute;right:10px;color:#409EFF;"
  23. >定位</span>
  24. </div>
  25. </template>
  26. </el-autocomplete>
  27. <el-button style="margin-left:10px;" type="text" @click="clearDimension">收起</el-button>
  28. </div>
  29. <!-- 点击元空间显示 -->
  30. <div v-show="type == 3">
  31. <div class="div50">
  32. <el-button
  33. class="float-right"
  34. @click="SpaceDialog"
  35. type="primary"
  36. plain
  37. >从未关联元空间的业务空间中选择</el-button>
  38. </div>
  39. <div class="div50">
  40. <el-button @click="clearDimension" plain>取 消</el-button>
  41. <el-button @click="createSP" type="primary">创建新的业务空间</el-button>
  42. </div>
  43. </div>
  44. <!-- 点击业务空间显示 -->
  45. <div v-show="type == 4">
  46. <div class="div50">
  47. <el-button class="float-right" @click="divide" type="primary" plain>重新划分业务空间</el-button>
  48. </div>
  49. <div class="div50">
  50. <el-button @click="clearDimension" plain>取 消</el-button>
  51. <el-button @click="bussinDea" type="primary">查看详情</el-button>
  52. </div>
  53. </div>
  54. <!-- 点击业务空间后点击元空间 -->
  55. <div v-show="type == 5">
  56. <div class="div50">
  57. <el-button @click="clearDimension" class="float-right" plain>取 消</el-button>
  58. </div>
  59. <div class="div50">
  60. <el-button @click="saveChange" type="primary">保存修改</el-button>
  61. </div>
  62. </div>
  63. <el-button
  64. v-show="type == 1"
  65. @click="getPiss"
  66. style="position: absolute;top: 10px;right: 10px;"
  67. type="text"
  68. >未关联元空间的业务空间 {{num}} 条</el-button>
  69. </div>
  70. <div
  71. v-show="hasMap"
  72. ref="canvasWidth"
  73. class="canvasWidth"
  74. v-loading="myLoading"
  75. style="width:100%;"
  76. >
  77. <canvas :id="canvasId + 'canvas' " :width="canvasW" :height="canvasH"></canvas>
  78. <div
  79. style="height: 35px;overflow: hidden;z-index:99;transform: translateX(-50%);position: absolute;bottom: 10%;left: 50%;"
  80. >
  81. <el-button @click="smallSize" type="primary">- 缩小</el-button>
  82. <el-button @click="suitableSize" type="primary">合适比例</el-button>
  83. <el-button @click="bigSize" type="primary">+ 放大</el-button>
  84. </div>
  85. </div>
  86. <div
  87. v-show="!hasMap"
  88. class="center"
  89. style="height: 400px;padding-top:200px;box-sizing:border-box;"
  90. >
  91. <i class="icon-wushuju iconfont"></i>
  92. {{!!buildMess ? '请初始化平面图' : '请选择楼层'}}
  93. </div>
  94. <el-dialog title="提示" :visible.sync="dialogVisible" :before-close="clearDimension" width="30%">
  95. <p style="color:red;line-height:24px;margin-bottom: 10px;" v-show="isAbutMsg">注意:您选择的元空间并未相邻!</p>
  96. <p style="line-height:24px;margin-bottom: 10px;">请输入创建的业务空间名:</p>
  97. <!-- <p>
  98. <el-input
  99. placeholder="请输入业务空间名"
  100. v-model="name"
  101. clearable>
  102. </el-input>
  103. </p>-->
  104. <el-form
  105. :model="ruleForm"
  106. :rules="rules"
  107. ref="ruleForm"
  108. label-width="100px"
  109. class="demo-ruleForm"
  110. >
  111. <el-form-item label label-width="0" prop="name">
  112. <el-input v-model="ruleForm.name"></el-input>
  113. </el-form-item>
  114. </el-form>
  115. <span slot="footer" class="dialog-footer">
  116. <el-button @click="clearDimension">取 消</el-button>
  117. <el-button type="primary" @click="isTrue">确 定</el-button>
  118. </span>
  119. </el-dialog>
  120. <el-dialog title="提示" :visible.sync="myDialogVisible" width="30%">
  121. <p style="line-height:26px;">方法1:直接在平面图中点击单个或多个带⬇️标记的元空间创建业务空间</p>
  122. <p style="line-height:26px;">方法2:根据未关联业务空间的元空间批量创建业务空间</p>
  123. <span slot="footer" class="dialog-footer">
  124. <el-button @click="createBatchSq">批量创建业务空间</el-button>
  125. <el-button type="primary" @click="myDialogVisible = false">返回平面图手动选择</el-button>
  126. </span>
  127. </el-dialog>
  128. </div>
  129. </template>
  130. <script>
  131. import axios from "axios";
  132. //引擎的引用
  133. import {
  134. SGraphyView,
  135. SGraphyScene,
  136. SGraphyRectItem,
  137. SGraphyLineItem,
  138. SGraphyPolygonItem,
  139. SGraphyVirtualItem,
  140. SGraphyImageItem,
  141. SGraphyPillarItems
  142. } from "@/assets/graphy";
  143. import pako from '@/assets/pako/pako'
  144. //ele动画组件
  145. import tools from "@/utils/scan/tools";
  146. let data = "";
  147. let scale = 120; //缩放比例
  148. let myData = [{
  149. Id: "1221512",
  150. PointList: {
  151. X: -35146.875,
  152. Y: 40680
  153. }
  154. }];
  155. // let colorArr = [
  156. // "rgba(0,245,255,.2)",
  157. // "rgba(255,218,185,.2)",
  158. // "rgba(132,112,255,.2)",
  159. // "rgba(127,255,0,.2)",
  160. // "rgba(238,92,66,.2)",
  161. // "rgba(255,255,224,.2)",
  162. // "rgba(238,233,233,.2)",
  163. // "rgba(156,156,156,.2)",
  164. // "rgba(144,238,144,.2)",
  165. // "rgba(180,205,205,.2)"
  166. // ];
  167. let colorArr = [
  168. "#F9C3C3",
  169. "#FFD1BF",
  170. "#FFF3BF",
  171. "#D8F7C6",
  172. "#C6F2F6",
  173. "#DCE3C0",
  174. "#FAE6C9",
  175. "#E3D7F7",
  176. "#C4CBF8",
  177. "#DEC3F6"
  178. ];
  179. // function hexify(color) {
  180. // var values = color
  181. // .replace(/rgba?\(/, '')
  182. // .replace(/\)/, '')
  183. // .replace(/[\s+]/g, '')
  184. // .split(',');
  185. // var a = parseFloat(values[3] || 1),
  186. // r = Math.floor(a * parseInt(values[0]) + (1 - a) * 255),
  187. // g = Math.floor(a * parseInt(values[1]) + (1 - a) * 255),
  188. // b = Math.floor(a * parseInt(values[2]) + (1 - a) * 255);
  189. // return "#" +
  190. // ("0" + r.toString(16)).slice(-2) +
  191. // ("0" + g.toString(16)).slice(-2) +
  192. // ("0" + b.toString(16)).slice(-2);
  193. // }
  194. // colorArr = colorArr.map(item => {
  195. // return hexify(item)
  196. // })
  197. class MainScene extends SGraphyScene {
  198. constructor() {
  199. super();
  200. //资产id
  201. } // Function constructor()
  202. /**
  203. * 绘制背景
  204. *
  205. * @param canvas 画布
  206. * @param rect 更新绘制区域
  207. */
  208. // drawBackground(canvas, rect) {}
  209. }
  210. import {
  211. formBIMToPri, // 将bimId转换成物理世界id
  212. createBusiness, //添加业务空间
  213. createRelation, //添加关系
  214. getGraphyId, //获取图类型
  215. getBussines2, //获取业务空间
  216. getRelation, //获取业务空间下的元空间id
  217. deleteRelation, //删除关系
  218. isAbut
  219. } from "@/api/scan/request";
  220. import {mapGetters, mapActions} from "vuex";
  221. export default {
  222. name: "HelloWorld",
  223. props: {
  224. canvasId: {
  225. type: String
  226. }
  227. },
  228. computed: {
  229. ...mapGetters("layout", [
  230. "projectId",
  231. "secret",
  232. "userId"
  233. ])
  234. },
  235. data() {
  236. return {
  237. view: "",
  238. num: "",
  239. mainScene: new MainScene(),
  240. dataMax: "", //最大值最小值数据
  241. scene: {
  242. x: 0,
  243. y: 0
  244. },
  245. dialogVisible: false, //浮层
  246. id: null,
  247. canvasH: 600,
  248. canvasW: 800,
  249. param: {
  250. ProjId: "", //项目id
  251. UserId: "", //用户id
  252. secret: ""
  253. },
  254. myDialogVisible: false,
  255. wallList: [], //处理后的墙的线条
  256. type: 1, //1 默认显示初始按钮, 2搜索下拉, 3点击元空间, 4点击业务空间
  257. restaurants: [],
  258. search: "",
  259. idList: [],
  260. buildMess: null,
  261. loading: {
  262. show: false,
  263. num: 0,
  264. total: 0,
  265. errorNum: 0
  266. },
  267. graphyId: "",
  268. relationList: [],
  269. myLoading: false,
  270. hasMap: false,
  271. ruleForm: {
  272. name: ""
  273. },
  274. rules: {
  275. name: [{
  276. required: true,
  277. message: "请输入需要创建的业务空间名称",
  278. trigger: "blur"
  279. }]
  280. },
  281. isAbutMsg: false, //是否相邻提示
  282. businessData: "", //新建业务空间数据
  283. spaceType: {}, //space类型code
  284. };
  285. },
  286. created() {
  287. this.param.ProjId = this.projectId
  288. this.param.secret = this.secret
  289. this.param.UserId = this.userId
  290. // this.getJson("Fl110108000327d8f006c39f49feb40e24a7ef22323220181119025802bim.jsonz")
  291. // this.getJson("bim.jsonz")
  292. },
  293. mounted() {
  294. console.log(this.canvasId)
  295. // this.resetSize();
  296. // window.addEventListener("click",this.typeTo1)
  297. },
  298. methods: {
  299. //获取数据
  300. getData(floorMap, buildMess, data) {
  301. this.spaceType = data
  302. this.loading.show = false;
  303. this.type = 1;
  304. this.idList = [];
  305. this.buildMess = buildMess;
  306. if (!floorMap) {
  307. this.hasMap = false;
  308. } else {
  309. this.getJson(floorMap);
  310. this.hasMap = true;
  311. }
  312. },
  313. clearList() {
  314. this.idList = []
  315. },
  316. //未关联元空间的业务空间
  317. getPiss() {
  318. this.$emit("getSp", [{}], this.buildMess, this.graphyId);
  319. },
  320. //查询绑定了元空间的业务空间
  321. getHasSpace() {
  322. console.log(this.spaceType, "spaceType")
  323. let param = {
  324. data: {
  325. criteria: {
  326. id: this.buildMess.code,
  327. // graphId: this.graphyId,
  328. // relType: this.spaceType.rel_type,
  329. // exclude: false,
  330. // side: 1,
  331. type: [this.spaceType.code],
  332. "include": [ // 可选, 只查询指定图/关系中的对象
  333. {
  334. "graphId": this.graphyId,
  335. "graphType": this.spaceType.code,
  336. "relType": this.spaceType.rel_type,
  337. "side": "toId",
  338. // "fromId": "", // 选填
  339. // "toId": "" // 选填
  340. }
  341. ]
  342. },
  343. },
  344. ProjId: this.param.ProjId,
  345. secret: this.param.secret
  346. }
  347. getBussines2(param)
  348. .then(res => {
  349. if (res.data.Result == "success") {
  350. this.restaurants = res.data.Content;
  351. let nameList = [];
  352. if (res.data.Content && res.data.Content.length) {
  353. this.relationList = res.data.Content.map(item => {
  354. nameList.push(item.infos.RoomLocalName);
  355. return item.id;
  356. });
  357. this.locationPath(this.relationList, nameList);
  358. }
  359. } else {
  360. this.$message.error(res.data.ResultMsg);
  361. }
  362. this.myLoading = false;
  363. })
  364. .catch(() => {
  365. // console.log("请求出错");
  366. });
  367. },
  368. //确定新建
  369. isTrue() {
  370. this.$refs.ruleForm.validate(valid => {
  371. if (valid) {
  372. this.loading.show = true;
  373. this.loading.num = 0;
  374. this.loading.total = 1 * 2;
  375. this.businessData.infos.RoomLocalName[0].value = this.ruleForm.name;
  376. this.createSpace(this.businessData, this.idList, true);
  377. this.dialogVisible = false;
  378. } else {
  379. // console.log("error submit!!");
  380. return false;
  381. }
  382. });
  383. },
  384. //查询未绑定元空间的业务空间
  385. getNoSpace() {
  386. getBussines2({
  387. data: {
  388. criteria: {
  389. id: this.buildMess.code,
  390. // graphId: this.graphyId,
  391. // relType: this.spaceType.rel_type,
  392. // exclude: false,
  393. // side: 1,
  394. type: [this.spaceType.code],
  395. "exclude": [ // 可选, 只查询指定图/关系中的对象
  396. {
  397. "graphId": this.graphyId,
  398. "graphType": this.spaceType.code,
  399. "relType": this.spaceType.rel_type,
  400. "side": "toId",
  401. // "fromId": "", // 选填
  402. // "toId": "" // 选填
  403. }
  404. ]
  405. },
  406. },
  407. ProjId: this.projectId,
  408. secret: this.secret
  409. })
  410. .then(res => {
  411. if (res.data.Result == "success") {
  412. this.num = res.data.Content.length;
  413. } else {
  414. this.$message.error(res.data.ResultMsg);
  415. }
  416. })
  417. .catch(() => {
  418. // console.log("请求出错");
  419. });
  420. },
  421. //当type=2时点击变成1
  422. typeTo1() {
  423. if (this.type == 2) {
  424. this.type = 1;
  425. }
  426. },
  427. getJson(jsonId) {
  428. axios({
  429. method: 'get',
  430. url: "/image-service/common/file_get/" + jsonId + "?systemId=revit",
  431. data: {},
  432. responseType: 'blob',
  433. // contentType: "charset=utf-8"
  434. })
  435. .then(res => {
  436. // console.log(res.data, "res.data")
  437. let data = null
  438. var blob = res.data;
  439. var reader = new FileReader();
  440. reader.readAsBinaryString(blob)
  441. // console.log("获取到了数据")
  442. let _this = this
  443. reader.onload = function(readerEvt) {
  444. // console.log("reader获取完毕")
  445. var binaryString = readerEvt.target.result;
  446. // let base64Data = btoa(binaryString)
  447. //解压数据
  448. let base64Data = btoa(binaryString)
  449. let unGzipData = pako.unzip(base64Data)
  450. // console.log(unGzipData)
  451. // console.log(unGzipData, "atob")
  452. data = unGzipData
  453. _this.dataMax = tools.getPoint(data);
  454. console.log(unGzipData, data)
  455. if (data.WallList && data.WallList.length) {
  456. tools.changeMap(data.WallList, -1, "PointList");
  457. }
  458. if (data.SpaceList && data.SpaceList.length) {
  459. tools.changeMap(data.SpaceList, -1, "Paths");
  460. }
  461. if (data.ColumnList && data.ColumnList.length) {
  462. tools.changeMap(data.ColumnList, -1, "Path");
  463. }
  464. if (data.VirtualWallList && data.VirtualWallList.length) {
  465. tools.changeMap(data.VirtualWallList, -1, "PointList");
  466. }
  467. if (data.EquipmentList && data.EquipmentList.length) {
  468. tools.changeMap(data.EquipmentList, -1, "PointList");
  469. }
  470. let ids = [];
  471. if (data.SpaceList && data.SpaceList.length) {
  472. data.SpaceList.map(items => {
  473. items.BimId = _this.buildMess.code + ":" + items.BimId;
  474. ids.push(items.BimId);
  475. });
  476. } else {
  477. _this.$message("没有元空间数据")
  478. }
  479. if(!!ids && ids.length){
  480. _this.bimIdToId(ids, data);
  481. }else{
  482. //没有id没有map
  483. _this.hasMap = false
  484. }
  485. _this.myLoading = true;
  486. };
  487. // console.log(reader)
  488. });
  489. },
  490. //获取图实例关系
  491. getGraphy() {
  492. getGraphyId({
  493. type: "ElementSptoSpace",
  494. ProjId: this.projectId,
  495. secret: this.secret
  496. })
  497. .then(res => {
  498. if (res.data.Result == "success") {
  499. this.graphyId = res.data.graph_id;
  500. this.getHasSpace();
  501. this.getNoSpace();
  502. } else {
  503. this.$message.error(res.data.ResultMsg);
  504. }
  505. })
  506. .catch(() => {
  507. this.$message.error("请求错误");
  508. });
  509. },
  510. bimIdToId(ids, data) {
  511. formBIMToPri({
  512. type: ["Si"],
  513. ids: ids,
  514. ProjId: this.param.ProjId,
  515. secret: this.param.secret
  516. })
  517. .then(res => {
  518. if (res.data.Result == "success") {
  519. data.SpaceList.map((item, index) => {
  520. res.data.Content.map((i, li) => {
  521. //判断bimId是否相同
  522. if (item.BimId == i.infos.BIMID) {
  523. item.id = i.id;
  524. }
  525. });
  526. });
  527. this.createCanvas();
  528. this.initGraphy(data);
  529. console.log("请求完毕")
  530. } else {
  531. this.$message.error(res.data.ResultMsg);
  532. }
  533. })
  534. .catch(() => {
  535. this.$message.error("请求出错");
  536. });
  537. },
  538. //创建实例
  539. createCanvas() {
  540. //初始化
  541. if (this.view.scene) {
  542. this.view.scene.root.children = [];
  543. this.view = null;
  544. }
  545. this.view = new SGraphyView(this.canvasId + "canvas", this.mainScene);
  546. this.view.onDraw();
  547. // this.view.canvasView.addEventListener("mouseup", this.dataChange);
  548. // this.view.canvasView.addEventListener("mousemove", this.canvasMove);
  549. },
  550. //初始化canvas大小
  551. resetSize() {
  552. this.canvasW =
  553. document.getElementById("businessSpace").offsetWidth - 2;
  554. this.canvasH = document.getElementById("app").offsetHeight - 240;
  555. let classs = document.getElementsByClassName("canvasWidth");
  556. // for(let i = 0; i < classs.length;i++){
  557. // classs[i].style.height = this.canvasH + 'px'
  558. // }
  559. this.$refs.canvasWidth.style.height = this.canvasH + "px";
  560. },
  561. //实例化视图
  562. initGraphy(data) {
  563. this.resetSize();
  564. this.view.pos.x = this.view.pos.y = -50;
  565. let equip = data.EquipmentList,
  566. wall = data.WallList,
  567. virtual = data.VirtualWallList,
  568. space = data.SpaceList,
  569. column = data.ColumnList,
  570. spaceStr;
  571. //空间
  572. if (space && space.length) {
  573. for (let i = 0; i < space.length; i++) {
  574. if (space[i].Paths[1] && space[i].Paths[1].length >= 2) {
  575. spaceStr = new SGraphyPolygonItem(
  576. space[i].Paths[0],
  577. 1,
  578. "rgba(111,111,111,0.5)",
  579. "#fff",
  580. space[i].id, {
  581. x: space[i].LocationPoint.X,
  582. y: space[i].LocationPoint.Y * -1
  583. },
  584. space[i].Name,
  585. space[i].Paths
  586. );
  587. this.mainScene.addItem(spaceStr);
  588. }
  589. }
  590. for (let i = 0; i < space.length; i++) {
  591. if (space[i].Paths[0] && space[i].Paths[0].length >= 2 && !!!space[i].Paths[1]) {
  592. spaceStr = new SGraphyPolygonItem(
  593. space[i].Paths[0],
  594. 1,
  595. "rgba(111,111,111,0.5)",
  596. "#fff",
  597. space[i].id, {
  598. x: space[i].LocationPoint.X,
  599. y: space[i].LocationPoint.Y * -1
  600. },
  601. space[i].Name
  602. );
  603. this.mainScene.addItem(spaceStr);
  604. }
  605. }
  606. }
  607. //获取中心点
  608. let rect = this.view.scene.worldRect();
  609. //初始化画布缩放比例
  610. this.view.scale = 1;
  611. //计算缩放比例
  612. this.view.scale = Math.min(
  613. this.view.width / (rect.width * 1.2),
  614. this.view.height / (rect.height * 1.2)
  615. );
  616. this.view.minScale = this.view.scale / 10
  617. this.view.maxScale = this.view.scale * 10
  618. // 移动画布
  619. this.view.pos.x =
  620. (-(rect.right + rect.left) / 2) * this.view.scale + this.view.width / 2;
  621. this.view.pos.y =
  622. (-(rect.bottom + rect.top) / 2) * this.view.scale +
  623. this.view.height / 2;
  624. //点击事件
  625. this.view.canvasView.addEventListener("click", this.checkSpace);
  626. this.getGraphy();
  627. },
  628. /** canvas事件------------------------------------------------------------------------------------*/
  629. //点击元空间
  630. checkSpace(e) {
  631. let item = tools.mouseInElement(this.view, e);
  632. console.log(item)
  633. let items = this.mainScene.root.children;
  634. //点击业务空间
  635. if (
  636. item.falg &&
  637. item.item.businessId &&
  638. (item.item.isBusiness == 2 || item.item.isBusiness == 7)
  639. ) {
  640. // console.log("点击不可点击的业务空间", item);
  641. if (this.type == 2) {
  642. this.idList = [];
  643. items.map(i => {
  644. if (i.isBusiness == 3) {
  645. i.isBusiness = 2;
  646. }
  647. });
  648. }
  649. items.map(i => {
  650. if (i.isBusiness == 6) {
  651. i.isBusiness = 2;
  652. } else if (i.isBusiness == 3) {
  653. i.isBusiness = 1;
  654. }
  655. });
  656. this.type = 4;
  657. items.map(i => {
  658. if (i.isBusiness == 6) {
  659. i.isBusiness = 2;
  660. }
  661. if (i.businessId == item.item.businessId) {
  662. i.isBusiness = 6;
  663. }
  664. });
  665. this.idList.push({
  666. id: item.item.businessId,
  667. name: item.item.businessName || item.item.name
  668. });
  669. }
  670. //点击没有业务空间的元空间
  671. if (
  672. item.falg &&
  673. !item.item.businessId &&
  674. (item.item.isBusiness == 4 || item.item.isBusiness == 1) &&
  675. this.type != 5
  676. ) {
  677. // console.log("点击的是没有业务空间的元空间", item);
  678. if (this.type == 4) {
  679. this.idList = [];
  680. items.map(i => {
  681. if (i.isBusiness == 6) {
  682. i.isBusiness = 2;
  683. } else if (i.isBusiness == 3) {
  684. i.isBusiness = 1;
  685. }
  686. });
  687. // console.log("清空", this.idList);
  688. }
  689. this.type = 3;
  690. item.item.isBusiness = 3;
  691. this.idList.push({
  692. id: item.item.id,
  693. name: item.item.businessName || item.item.name
  694. });
  695. }
  696. //在重新编辑业务空间状态
  697. if (
  698. this.type == 5 &&
  699. item.falg &&
  700. !item.item.businessId &&
  701. (item.item.isBusiness == 4 || item.item.isBusiness == 1)
  702. ) {
  703. item.item.isBusiness = 3;
  704. this.idList.push({
  705. id: item.item.id,
  706. name: item.item.businessName || item.item.name
  707. });
  708. }
  709. //在重新编辑时的提示
  710. if (
  711. item.falg &&
  712. item.item.businessId &&
  713. (item.item.isBusiness == 4 || item.item.isBusiness == 1)
  714. ) {
  715. // console.log("44444");
  716. item.item.isBusiness = 3;
  717. this.idList.push({
  718. id: item.item.id,
  719. name: item.item.businessName || item.item.name,
  720. parentId: item.item.businessId
  721. });
  722. }
  723. if (item.falg && item.item.isBusiness == 5) {
  724. this.$message("该空间为业务空间,请勿点击");
  725. }
  726. // if(item.falg && item.item.businessId)
  727. },
  728. /** 搜索 ------------------------------------------------------------------------------ */
  729. querySearch(queryString, cb) {
  730. var restaurants = this.restaurants;
  731. var results = queryString ?
  732. restaurants.filter(this.createFilter(queryString)) :
  733. restaurants;
  734. // 调用 callback 返回建议列表的数据
  735. cb(results);
  736. },
  737. createFilter(queryString) {
  738. return restaurant => {
  739. return restaurant.infos.RoomLocalName.indexOf(queryString) > -1;
  740. };
  741. },
  742. handleSelect(item) {
  743. this.locationPath(item.id);
  744. },
  745. handleIconClick(ev) {
  746. this.locationPath(ev.id);
  747. },
  748. //定位
  749. locationPath(id, name) {
  750. let param = {
  751. criterias: {},
  752. ProjId: this.projectId,
  753. secret: this.secret
  754. },
  755. falg = false;
  756. //查询多个关系
  757. if (id instanceof Array) {
  758. falg = true;
  759. param.criterias.criterias = [];
  760. id.map(item => {
  761. param.criterias.criterias.push({
  762. to_id: item,
  763. graph_id: this.graphyId,
  764. rel_type: this.spaceType.rel_type
  765. });
  766. });
  767. } else {
  768. //查询单个关系
  769. param.criterias.criteria = {
  770. to_id: id,
  771. graph_id: this.graphyId,
  772. rel_type: this.spaceType.rel_type
  773. };
  774. }
  775. getRelation(param)
  776. .then(res => {
  777. if (res.data.Result == "success") {
  778. if (falg) {
  779. //多个关系渲染颜色
  780. this.relationList = [];
  781. id.map((item, index) => {
  782. let children = res.data.Content[index].Content.map(i => {
  783. if (!!i) {
  784. return i.from_id;
  785. } else {
  786. return undefined;
  787. }
  788. });
  789. this.relationList.push({
  790. id: item,
  791. name: name[index],
  792. children: children,
  793. isAdjacent: true
  794. });
  795. });
  796. this.relationList.reverse();
  797. // this.getColor(this.relationList);
  798. //判断相邻代码
  799. this.spaceIsAbut(this.relationList);
  800. } else {
  801. //单个是定位
  802. this.getPathToCanvas(res.data.Content[0].from_id);
  803. }
  804. } else {
  805. this.$message.error(res.data.ResultMsg);
  806. }
  807. })
  808. .catch(() => {
  809. this.$message.error("请求错误");
  810. });
  811. },
  812. //给canvas的items渲染色彩
  813. getColor(list) {
  814. let items = this.mainScene.root.children;
  815. list.map(item => {
  816. if (item.children && item.children.length) {
  817. item.children.map(space => {
  818. items.map(canvas => {
  819. if (canvas.id == space) {
  820. canvas.businessId = item.id;
  821. canvas.businessName = item.name;
  822. }
  823. });
  824. });
  825. }
  826. });
  827. this.applyColor(list);
  828. },
  829. //渲染业务空间色彩
  830. applyColor(list) {
  831. let items = this.mainScene.root.children;
  832. items.map(item => {
  833. item.businessId = null;
  834. item.businessName = null;
  835. item.businessColor = "rgba(0,0,0,0)";
  836. item.isBusiness = 1;
  837. });
  838. list.map((item, index) => {
  839. if (item.children && item.children.length) {
  840. item.children.map(space => {
  841. items.map(canvas => {
  842. if (canvas.id == space) {
  843. canvas.businessId = item.id;
  844. canvas.businessName = item.name;
  845. canvas.businessColor = colorArr[index % 10];
  846. canvas.isBusiness = 2;
  847. //判断相邻代码
  848. if (!item.isAbut) {
  849. canvas.isBusiness = 7;
  850. }
  851. }
  852. });
  853. });
  854. }
  855. });
  856. },
  857. spaceIsAbut(list) {
  858. let data = list.map(item => {
  859. return {
  860. ids: item.children
  861. };
  862. });
  863. let param = {
  864. data: {
  865. floor: this.buildMess.code,
  866. criterias: data
  867. },
  868. ProjId: this.projectId,
  869. secret: this.secret
  870. };
  871. // console.log(param);
  872. isAbut(param)
  873. .then(res => {
  874. if (res.data.Result == "success") {
  875. res.data.Content.map((item, index) => {
  876. this.relationList[index].isAbut = item.abut;
  877. });
  878. this.getColor(this.relationList);
  879. } else {
  880. this.$message.error(res.data.ResultMsg);
  881. }
  882. })
  883. .catch(() => {
  884. this.$message.error("请求出错");
  885. });
  886. },
  887. getPathToCanvas(id) {
  888. let items = this.mainScene.root.children;
  889. items.map(item => {
  890. if (item.id == id) {
  891. //定位算法
  892. this.view.pos.x = -item.centerOfGravityPoint.x * this.view.scale +
  893. this.view.width / 2;
  894. this.view.pos.y = -item.centerOfGravityPoint.y * this.view.scale +
  895. this.view.height / 2;
  896. this.view.scale = this.view.scale;
  897. item.isBusiness = 3;
  898. this.idList = [];
  899. console.log(item)
  900. this.idList.push({
  901. id: item.businessId,
  902. name: item.businessName || '--'
  903. });
  904. } else if (item.businessId) {
  905. item.isBusiness = 2;
  906. } else {
  907. item.isBusiness = 1;
  908. }
  909. });
  910. },
  911. /** 按钮事件 ---------------------------------------------------------------------- */
  912. SpaceDialog() {
  913. this.$emit("dimension", this.idList, this.buildMess, this.graphyId);
  914. },
  915. bussinDea() {
  916. this.$emit("businessDetails", this.idList[this.idList.length - 1]);
  917. },
  918. //保存修改
  919. saveChange() {
  920. let id = ""
  921. this.idList.map(item => {
  922. if (!!item.parentId) {
  923. id = item.parentId
  924. }
  925. })
  926. this.deleteRela(id);
  927. },
  928. //调整到合适比例
  929. suitableSize() {
  930. //获取中心点
  931. let rect = this.view.scene.worldRect();
  932. //计算缩放比例
  933. this.view.scale = Math.min(
  934. this.view.width / (rect.width * 1.2),
  935. this.view.height / (rect.height * 1.2)
  936. );
  937. // 移动画布
  938. this.view.pos.x =
  939. (-(rect.right + rect.left) / 2) * this.view.scale + this.view.width / 2;
  940. this.view.pos.y =
  941. (-(rect.bottom + rect.top) / 2) * this.view.scale +
  942. this.view.height / 2;
  943. },
  944. //调整到小比例
  945. smallSize() {
  946. //获取中心点
  947. let rect = this.view.scene.worldRect();
  948. //计算缩放比例
  949. this.view.scale = this.view.scale * 0.9;
  950. // 移动画布
  951. this.view.pos.x =
  952. (-(rect.right + rect.left) / 2) * this.view.scale + this.view.width / 2;
  953. this.view.pos.y =
  954. (-(rect.bottom + rect.top) / 2) * this.view.scale +
  955. this.view.height / 2;
  956. },
  957. bigSize() {
  958. //获取中心点
  959. let rect = this.view.scene.worldRect();
  960. //计算缩放比例
  961. this.view.scale = this.view.scale * 1.1;
  962. // 移动画布
  963. this.view.pos.x =
  964. (-(rect.right + rect.left) / 2) * this.view.scale + this.view.width / 2;
  965. this.view.pos.y =
  966. (-(rect.bottom + rect.top) / 2) * this.view.scale +
  967. this.view.height / 2;
  968. },
  969. //删除关系
  970. deleteRela(id) {
  971. let param = {
  972. data: {
  973. criterias: [{
  974. to_id: id, //选填
  975. graph_id: this.graphyId, //选填
  976. rel_type: this.spaceType.rel_type //选填
  977. }]
  978. },
  979. ProjId: this.projectId,
  980. secret: this.secret
  981. };
  982. if (id) {
  983. deleteRelation(param)
  984. .then(res => {
  985. if (res.data.Result == "success") {
  986. this.loading.show = true;
  987. this.loading.num = 0;
  988. this.loading.total = 1;
  989. this.addRelation(id, this.idList);
  990. } else {
  991. this.$message.error(res.data.ResultMsg);
  992. }
  993. })
  994. .catch(() => {
  995. this.$message.error("请求失败");
  996. });
  997. } else {
  998. this.$message.error("请选择包含原业务空间的区域块")
  999. }
  1000. },
  1001. //点击元空间后点击取消
  1002. clearDimension() {
  1003. this.myLoading = true;
  1004. let indexs = tools.clear(
  1005. this.mainScene.root.children,
  1006. 3,
  1007. this.idList,
  1008. "id"
  1009. );
  1010. this.myDialogVisible = false;
  1011. this.dialogVisible = false;
  1012. for (let i = 0; i < indexs.length; i++) {
  1013. this.mainScene.root.children[indexs[i]].isBusiness = 1;
  1014. }
  1015. this.idList = [];
  1016. this.type = 1;
  1017. this.getHasSpace();
  1018. },
  1019. //创建新的业务空间
  1020. createSP() {
  1021. let businessData = {
  1022. building_id: this.buildMess.buildCode,
  1023. floor_id: this.buildMess.code,
  1024. business_type: this.spaceType.code,
  1025. infos: {
  1026. RoomLocalName: [{
  1027. value: tools.getText(this.idList, "name")
  1028. }]
  1029. }
  1030. };
  1031. let data = [];
  1032. this.idList.map(i => {
  1033. data.push(i.id);
  1034. });
  1035. let param = {
  1036. data: {
  1037. floor: this.buildMess.code,
  1038. criterias: [{
  1039. ids: data
  1040. }]
  1041. },
  1042. ProjId: this.projectId,
  1043. secret: this.secret
  1044. };
  1045. // this.createSpace(businessData, this.idList, true);
  1046. //判断相邻代码
  1047. isAbut(param)
  1048. .then(res => {
  1049. if (res.data.Result == "success") {
  1050. this.dialogVisible = true;
  1051. this.ruleForm.name = businessData.infos.RoomLocalName[0].value;
  1052. this.businessData = businessData;
  1053. if (res.data.Content[0].abut) {
  1054. this.isAbutMsg = false;
  1055. // this.createSpace(businessData, this.idList, true);
  1056. } else {
  1057. this.isAbutMsg = true;
  1058. // this.$confirm(
  1059. // "您选择的元空间并未相邻,确定继续创建业务空间?",
  1060. // "提示",
  1061. // {
  1062. // confirmButtonText: "确定",
  1063. // cancelButtonText: "取消",
  1064. // type: "warning"
  1065. // }
  1066. // )
  1067. // .then(() => {
  1068. // this.loading.show = true;
  1069. // this.loading.num = 0;
  1070. // this.loading.total = 1 * 2;
  1071. // this.createSpace(businessData, this.idList, true);
  1072. // })
  1073. // .catch(() => {
  1074. // this.$message({
  1075. // type: "info",
  1076. // message: "已取消"
  1077. // });
  1078. // this.clearDimension();
  1079. // this.loading.show = false;
  1080. // });
  1081. }
  1082. } else {
  1083. this.$message.error(res.data.ResultMsg);
  1084. }
  1085. })
  1086. .catch(() => {
  1087. this.$message.error("请求失败");
  1088. });
  1089. },
  1090. //比较两个元空间是否相邻
  1091. compareSpace(ids) {
  1092. // console.log(ids);
  1093. },
  1094. //重新划分业务空间
  1095. divide() {
  1096. this.type = 5;
  1097. let id = this.idList[this.idList.length - 1],
  1098. items = this.mainScene.root.children;
  1099. items.map(item => {
  1100. if (item.businessId == id.id) {
  1101. item.isBusiness = 4;
  1102. } else if (item.businessId) {
  1103. item.isBusiness = 5;
  1104. }
  1105. });
  1106. this.idList = [];
  1107. },
  1108. //批量生成业务空间
  1109. createBatchSq() {
  1110. let items = this.mainScene.root.children;
  1111. let map = [];
  1112. items.map(item => {
  1113. if (!item.businessId) {
  1114. map.push({
  1115. id: item.id,
  1116. name: item.name
  1117. });
  1118. }
  1119. });
  1120. let text = tools.getText(map, "name");
  1121. this.$confirm(
  1122. // "您确定批量创建业务空间:" +
  1123. // tools.cutString(text, 10, "等业务空间") +
  1124. // ", 是否继续?",
  1125. "<p>确定根据未关联业务空间的元空间批量创建业务空间</p>" +
  1126. "<p>涉及的元空间:</p>" +
  1127. "<p style='line-height:20px;max-height:60px;overflow-y:auto;'>" +
  1128. text +
  1129. "</p>",
  1130. // tools.cutString(text, 60, "等业务空间")
  1131. "提示", {
  1132. dangerouslyUseHTMLString: true,
  1133. confirmButtonText: "确定",
  1134. cancelButtonText: "取消",
  1135. type: "warning"
  1136. }
  1137. )
  1138. .then(() => {
  1139. this.loading.show = true;
  1140. this.loading.num = 0;
  1141. this.loading.total = map.length * 2;
  1142. this.myDialogVisible = false;
  1143. map.map(item => {
  1144. this.createSpace({
  1145. building_id: this.buildMess.buildCode,
  1146. floor_id: this.buildMess.code,
  1147. business_type: this.spaceType.code,
  1148. infos: {
  1149. RoomLocalName: [{
  1150. value: item.name
  1151. }]
  1152. }
  1153. },
  1154. item.id,
  1155. true
  1156. );
  1157. });
  1158. })
  1159. .catch(() => {
  1160. this.$message({
  1161. type: "info",
  1162. message: "已取消批量创建"
  1163. });
  1164. });
  1165. },
  1166. //创建空间
  1167. createSpace(data, id, falg) {
  1168. let param = {
  1169. ProjId: this.projectId,
  1170. secret: this.secret,
  1171. data: data
  1172. };
  1173. createBusiness(param).then(res => {
  1174. if (res.data.Result == "success") {
  1175. if (falg) {
  1176. this.loading.num++;
  1177. this.addRelation(res.data.id, id);
  1178. } else {}
  1179. } else {
  1180. this.loading.num++;
  1181. this.$message.error("修改发生错误:" + res.data.ResultMsg);
  1182. }
  1183. });
  1184. },
  1185. //添加关系
  1186. addRelation(SpId, SiId) {
  1187. let data = {};
  1188. if (SiId instanceof Array) {
  1189. data.criterias = [];
  1190. SiId.map(item => {
  1191. data.criterias.push({
  1192. from_id: item.id,
  1193. to_id: SpId,
  1194. graph_id: this.graphyId,
  1195. rel_type: this.spaceType.rel_type
  1196. });
  1197. });
  1198. } else {
  1199. data = {
  1200. from_id: SiId,
  1201. to_id: SpId,
  1202. graph_id: this.graphyId,
  1203. rel_type: this.spaceType.rel_type
  1204. };
  1205. }
  1206. createRelation({
  1207. data: data,
  1208. ProjId: this.projectId,
  1209. secret: this.secret
  1210. })
  1211. .then(res => {
  1212. if (res.data.Result == "success") {
  1213. this.loading.num++;
  1214. if (this.loading.num == this.loading.total) {
  1215. this.loading.show = false;
  1216. this.getHasSpace();
  1217. this.idList = [];
  1218. this.$message.success("添加成功");
  1219. this.type = 1;
  1220. }
  1221. } else {
  1222. this.$message.error(res.data.ResultMsg);
  1223. this.loading.errorNum++;
  1224. }
  1225. })
  1226. .catch(() => {
  1227. this.$message.error("请求出错");
  1228. this.loading.errorNum++;
  1229. });
  1230. }
  1231. },
  1232. filters: {
  1233. cutString: function(str, len) {
  1234. //length属性读出来的汉字长度为1
  1235. if (!!str && typeof str == "string" && str.length > len) {
  1236. return str.substring(0, len) + "...";
  1237. } else {
  1238. return str || "--";
  1239. }
  1240. }
  1241. },
  1242. watch: {
  1243. projectId(){
  1244. this.buildMess = null
  1245. this.param.ProjId = this.projectId
  1246. this.param.secret = this.secret
  1247. this.param.UserId = this.userId
  1248. this.hasMap = false
  1249. }
  1250. }
  1251. };
  1252. </script>
  1253. <!-- Add "scoped" attribute to limit CSS to this component only -->
  1254. <style lang="less">
  1255. .canvasGraphy {
  1256. position: relative;
  1257. // canvas {
  1258. // border: 1px solid #ccc;
  1259. // }
  1260. .header-search {
  1261. position: absolute;
  1262. top: 0;
  1263. height: 50px;
  1264. line-height: 50px;
  1265. padding-left: 20px;
  1266. background-color: rgba(205, 197, 191, 0.4);
  1267. left: 0;
  1268. right: 0;
  1269. top: 0;
  1270. z-index: 99;
  1271. >div {
  1272. height: 50px;
  1273. }
  1274. .div50 {
  1275. float: left;
  1276. width: 50%;
  1277. height: 100%;
  1278. .float-right {
  1279. float: right;
  1280. margin-top: 11px;
  1281. margin-right: 10%;
  1282. }
  1283. }
  1284. }
  1285. .el-autocomplete {
  1286. width: 320px;
  1287. }
  1288. .my-autocomplete {
  1289. li {
  1290. line-height: normal;
  1291. padding: 7px;
  1292. .name {
  1293. text-overflow: ellipsis;
  1294. overflow: hidden;
  1295. }
  1296. .addr {
  1297. font-size: 12px;
  1298. color: #b4b4b4;
  1299. }
  1300. .highlighted .addr {
  1301. color: #ddd;
  1302. }
  1303. }
  1304. }
  1305. }
  1306. </style>