index.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  1. <template>
  2. <div id="spaceRelation">
  3. <el-row>
  4. <el-col :span="0.5">
  5. <el-button size="small" type="default" icon="el-icon-back" @click="goback"></el-button>
  6. </el-col>
  7. <el-col :span="0.5">
  8. <span style="margin:0 10px;">建筑楼层</span>
  9. <el-cascader placeholder="请选择建筑楼层" :options="options" v-model="buildFloor" filterable size="small" @change="changeCascader" :props="props">
  10. </el-cascader>
  11. </el-col>
  12. <el-col :span="0.5">
  13. <span style="margin:0 10px;">业务空间类型</span>
  14. <el-select placeholder="请选择" v-model="zoneType" @change="getBusinessSpace">
  15. <el-option v-for="item in tabsList" :key="item.Code" :label="item.Name" :value="item.Code">
  16. </el-option>
  17. </el-select>
  18. </el-col>
  19. <el-col :span="0.5" style="float:right;" v-show='0'>
  20. <span style="margin-right:10px;">当前状态 {{description}}</span>
  21. <el-button @click="cancel">取消</el-button>
  22. <el-button @click="removeRelation">清除</el-button>
  23. <el-button @click="removeAll">清除所有</el-button>
  24. <el-button @click="addRelation">添加</el-button>
  25. <el-button type="primary" @click="saveRelation">保存</el-button>
  26. </el-col>
  27. </el-row>
  28. <div class="canvas-container" v-loading="canvasLoading" ref="graphy">
  29. <div v-show="!FloorMap" style="display:flex;align-items:center;justify-content:center;height:100%;">
  30. <div class="center" style="flex:1">
  31. <i class="icon-wushuju iconfont"></i>
  32. 暂无数据
  33. </div>
  34. </div>
  35. <div v-show="FloorMap" class="canvas-box">
  36. <canvas id="floorCanvas" :width="canvasWidth" :height="canvasHeight" ref="canvas" tabindex="0"></canvas>
  37. <!-- 底部操作按钮 -->
  38. <el-row class="canvas-actions-box">
  39. <canvasFun @fit="fit" @scale="scale" :config="config" ref="canvasFun"></canvasFun>
  40. </el-row>
  41. </div>
  42. </div>
  43. </div>
  44. </template>
  45. <script>
  46. import {
  47. // buildingQuery, //数据中心-建筑查询
  48. zoneQueryOutline, // 业务空间查询
  49. queryDictionaryHead, //空间类型查询
  50. createSpaceNeighborhood, //创建邻接关系
  51. querySpaceNeighborhood, // 查询邻接关系
  52. delSpaceNeighborhood, //删除选中
  53. delFloorNeighborhood, //删除所有
  54. } from "@/api/scan/request";
  55. import { buildingQuery } from '@/api/object/build';
  56. import { SColor, SPoint } from "@saga-web/draw/lib";
  57. import { RelationScene, FloorView } from "@saga-web/cad-engine/lib";
  58. import canvasFun from "@/components/business_space/newGraphy/canvasFun"
  59. import floorCascader from "@/components/ledger/lib/floorCascader";
  60. import { colorArr } from "@/utils/spaceColor"
  61. export default {
  62. components: {
  63. floorCascader,
  64. canvasFun
  65. },
  66. data() {
  67. return {
  68. view: '',
  69. scene: '',
  70. canvasWidth: 800,
  71. canvasHeight: 600,
  72. canvasLoading: false,
  73. FloorMap: '',
  74. options: [],
  75. buildFloor: [],
  76. tabsList: [],
  77. zoneType: 'GeneralZone',
  78. props: {
  79. value: 'BuildID',
  80. label: 'BuildLocalName',
  81. children: 'floor'
  82. },
  83. idToFloor: {},
  84. config: {
  85. isEdit: false,
  86. divide: false,
  87. groupSelect: false
  88. },
  89. description: '无'
  90. }
  91. },
  92. created() {
  93. //图类型编码
  94. this.type = this.$route.query.type;
  95. this.init();
  96. },
  97. mounted() {
  98. this.canvasWidth = this.$refs.graphy.offsetWidth - 20;
  99. this.canvasHeight = this.$refs.graphy.offsetHeight - 20;
  100. },
  101. methods: {
  102. //初始化
  103. init() {
  104. this.getBuilding();
  105. this.getTypes();
  106. },
  107. changeCascader(val) {
  108. if (val.length > 1) {
  109. let floor = this.idToFloor[val[1]];
  110. if (floor.StructureInfo && floor.StructureInfo.FloorMap) {
  111. this.FloorMap = floor.StructureInfo.FloorMap;
  112. this.initGraphy();
  113. } else {
  114. this.FloorMap = '';
  115. }
  116. } else {
  117. this.FloorMap = '';
  118. }
  119. },
  120. // 保存邻接关系
  121. saveRelation() {
  122. let relationList = this.scene.relationList;
  123. let pa = {
  124. Content: []
  125. }
  126. if (relationList.length) {
  127. pa.Content = relationList.map(t => {
  128. return {
  129. FloorId: this.buildFloor[1],
  130. GraphType: this.type,
  131. LocationOne: `${t.startPoint.x},${-t.startPoint.y}`,
  132. LocationTwo: `${t.lastPoint.x},${-t.lastPoint.y}`,
  133. SpaceIdOne: t.startZone,
  134. SpaceIdTwo: t.endZone,
  135. ZoneType: this.zoneType
  136. }
  137. })
  138. }
  139. this.createRela(pa)
  140. },
  141. clearRelation() {
  142. if (this.scene) {
  143. this.scene.removeAllRelation()
  144. }
  145. },
  146. //
  147. cancel() {
  148. this.scene.removeRelationFlag = false;
  149. this.scene.createRelateFlag = false;
  150. this.scene.isAbsorbing = false;
  151. this.description = '无'
  152. },
  153. //
  154. removeRelation() {
  155. this.scene.removeRelationFlag = true;
  156. this.scene.createRelateFlag = false;
  157. this.scene.isAbsorbing = false;
  158. this.description = '清除'
  159. },
  160. //
  161. addRelation() {
  162. this.scene.createRelateFlag = true;
  163. this.scene.removeRelationFlag = false;
  164. this.scene.isAbsorbing = true;
  165. this.description = '添加'
  166. },
  167. //
  168. removeAll() {
  169. let temp = {
  170. FloorId: this.buildFloor[1],
  171. ZoneType: this.zoneType,
  172. GraphType: this.type
  173. }
  174. delFloorNeighborhood(temp, res => {
  175. this.$message.success('删除成功');
  176. this.clearRelation();
  177. })
  178. },
  179. canvasClick(item, event) {
  180. console.log(item);
  181. item.selected = false;
  182. },
  183. initGraphy() {
  184. this.clearGraphy()
  185. this.scene = new RelationScene();
  186. this.canvasLoading = true;
  187. this.scene.loadUrl(`/image-service/common/file_get?systemId=revit&key=${this.FloorMap}`).then(res => {
  188. this.canvasLoading = false;
  189. if (res == 'error') {
  190. this.FloorMap = '';
  191. console.log('数据解析异常');
  192. return;
  193. }
  194. this.view.scene = this.scene;
  195. this.view.fitSceneToView();
  196. this.scene.isSpaceSelectable = false;
  197. this.getBusinessSpace();
  198. this.view.minScale = this.view.scale;
  199. if (this.$refs.canvasFun) {
  200. this.$refs.canvasFun.everyScale = this.view.scale;
  201. }
  202. })
  203. },
  204. // 清空场景并初始化视图
  205. clearGraphy() {
  206. if (this.view) {
  207. this.view.scene = null;
  208. return
  209. }
  210. this.view = new FloorView('floorCanvas')
  211. },
  212. // canvas 获取焦点
  213. focus() {
  214. document.getElementById(`floorCanvas`).focus()
  215. },
  216. // 适配底图到窗口
  217. fit() {
  218. this.view.fitSceneToView()
  219. },
  220. // 缩放
  221. scale(val) {
  222. if (!this.view) {
  223. return;
  224. }
  225. let scale = this.view.scale;
  226. this.view.scaleByPoint(val / scale, this.canvasWidth / 2, this.canvasHeight / 2);
  227. },
  228. goback() {
  229. this.$router.push({ name: 'overView' })
  230. },
  231. // 获取项目下建筑
  232. getBuilding() {
  233. let pa = {
  234. cascade: [{ name: 'floor', orders: 'floorSequenceId desc' }],
  235. orders: "localName asc",
  236. }
  237. buildingQuery(pa, res => {
  238. this.options = res.content.map(t => {
  239. if (t.floor) {
  240. t.floor = t.floor.map(item => {
  241. item.BuildID = item.id;
  242. item.BuildLocalName = item.localName;
  243. this.idToFloor[item.id] = item;
  244. return item;
  245. })
  246. } else {
  247. t.floor = []
  248. }
  249. return t;
  250. })
  251. })
  252. },
  253. // 业务空间分区类型
  254. getTypes() {
  255. let pa = {
  256. Filters: `parentId='Space'`
  257. }
  258. queryDictionaryHead(pa, res => {
  259. this.tabsList = res.Content.map(t => {
  260. if (t.Name == "元空间") {
  261. return undefined;
  262. }
  263. return t;
  264. }).filter(item => item);
  265. })
  266. },
  267. getRelations() {
  268. let pa = {
  269. Filters: `FloorId='${this.buildFloor[1]}';GraphType='${this.type}';ZoneType='${this.zoneType}'`
  270. }
  271. querySpaceNeighborhood(pa, res => {
  272. let tempArr = res.Content.map(t => {
  273. let p1 = t.LocationOne.split(',');
  274. let p2 = t.LocationTwo.split(',');
  275. return {
  276. LocationOne: new SPoint(p1[0], -p1[1]),
  277. LocationTwo: new SPoint(p2[0], -p2[1]),
  278. SpaceIdOne: t.SpaceIdOne,
  279. SpaceIdTwo: t.SpaceIdTwo,
  280. }
  281. })
  282. this.clearRelation();
  283. this.scene.addAllRelaPoint(tempArr);
  284. this.canvasLoading = false;
  285. })
  286. },
  287. // 获取当前分区下的业务空间
  288. getBusinessSpace() {
  289. this.canvasLoading = true
  290. let pa = {
  291. Filters: `not RoomID isNull`,
  292. Orders: "createTime desc, RoomID asc",
  293. PageSize: 1000,
  294. ZoneType: this.zoneType
  295. }
  296. if (this.buildFloor.length && this.buildFloor.length > 1) {
  297. pa.BuildingId = this.buildFloor[0];
  298. pa.FloorId = this.buildFloor[1];
  299. } else {
  300. this.$message.warning("请选择建筑楼层");
  301. }
  302. zoneQueryOutline(pa, res => {
  303. // 所有业务空间
  304. this.businessSpaceList = res.Content;
  305. // 已关联元空间的业务空间
  306. this.BSPRelaISPList = [];
  307. res.Content.map(t => {
  308. if (t.Outline && t.Outline.length) {
  309. this.BSPRelaISPList.push(t)
  310. }
  311. })
  312. // 绘制业务空间
  313. let tempArr = this.BSPRelaISPList.map((t, i) => {
  314. if (t.FloorId == this.buildFloor[1] && t.ObjectType == this.zoneType) {
  315. return {
  316. RoomLocalName: t.RoomLocalName,
  317. OutLine: t.Outline,
  318. RoomID: t.RoomID,
  319. Color: colorArr[i % colorArr.length],
  320. }
  321. } else {
  322. console.log('internet slow')
  323. return undefined;
  324. }
  325. }).filter(item => item)
  326. this.scene.removeAllZone();
  327. this.scene.addZoneList(tempArr);
  328. this.scene.click(this, this.canvasClick)
  329. // 绘制关系
  330. this.getRelations();
  331. })
  332. },
  333. // 创建邻接关系
  334. createRela(param) {
  335. console.log(param)
  336. createSpaceNeighborhood(param, res => {
  337. this.$message.success('创建成功')
  338. })
  339. }
  340. },
  341. watch: {
  342. projectId() {
  343. this.FloorMap = '';
  344. this.init();
  345. },
  346. "view.scale": {
  347. handler(n) {
  348. if (this.$refs.canvasFun) {
  349. let s = n * 10 / this.view.minScale
  350. this.$refs.canvasFun.sliderVal = s > 1000 ? 1000 : s;
  351. }
  352. }
  353. },
  354. "scene.curRemoveItem": {
  355. handler(n) {
  356. if (n) {
  357. let pa = [{
  358. GraphType: this.type,
  359. ZoneType: this.zoneType,
  360. SpaceIdOne: n.startZone,
  361. SpaceIdTwo: n.endZone
  362. }]
  363. delSpaceNeighborhood(pa, res => {
  364. this.$message.success('删除成功');
  365. })
  366. }
  367. }
  368. }
  369. }
  370. }
  371. </script>
  372. <style lang="less" scoped>
  373. #spaceRelation {
  374. /deep/ .el-input__inner {
  375. vertical-align: baseline;
  376. }
  377. .canvas-container {
  378. position: relative;
  379. width: calc(100% - 22px;);
  380. height: calc(100% - 64px);
  381. margin-top: 10px;
  382. padding: 10px;
  383. background-color: #fff;
  384. border: 1px solid #e4e4e4;
  385. .canvas-box {
  386. width: 100%;
  387. height: 100%;
  388. }
  389. .canvas-actions-box {
  390. position: absolute;
  391. bottom: 20px;
  392. left: 50%;
  393. transform: translateX(-50%);
  394. z-index: 999;
  395. }
  396. }
  397. }
  398. </style>