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. queryZone, // 业务空间查询
  49. queryDictionaryHead, //空间类型查询
  50. createSpaceNeighborhood, //创建邻接关系
  51. querySpaceNeighborhood, // 查询邻接关系
  52. delSpaceNeighborhood, //删除选中
  53. delFloorNeighborhood, //删除所有
  54. } from "@/api/scan/request";
  55. import { SColor, SPoint } from "@saga-web/draw/lib";
  56. import { RelationScene, FloorView } from "@saga-web/cad-engine/lib";
  57. import canvasFun from "@/components/business_space/newGraphy/canvasFun"
  58. import floorCascader from "@/components/ledger/lib/floorCascader";
  59. import { colorArr } from "@/utils/spaceColor"
  60. export default {
  61. components: {
  62. floorCascader,
  63. canvasFun
  64. },
  65. data() {
  66. return {
  67. view: '',
  68. scene: '',
  69. canvasWidth: 800,
  70. canvasHeight: 600,
  71. canvasLoading: false,
  72. FloorMap: '',
  73. options: [],
  74. buildFloor: [],
  75. tabsList: [],
  76. zoneType: 'GeneralZone',
  77. props: {
  78. value: 'BuildID',
  79. label: 'BuildLocalName',
  80. children: 'Floor'
  81. },
  82. idToFloor: {},
  83. config: {
  84. isEdit: false,
  85. divide: false,
  86. groupSelect: false
  87. },
  88. description: '无'
  89. }
  90. },
  91. created() {
  92. //图类型编码
  93. this.type = this.$route.query.type;
  94. this.init();
  95. },
  96. mounted() {
  97. this.canvasWidth = this.$refs.graphy.offsetWidth - 20;
  98. this.canvasHeight = this.$refs.graphy.offsetHeight - 20;
  99. },
  100. methods: {
  101. //初始化
  102. init() {
  103. this.getBuilding();
  104. this.getTypes();
  105. },
  106. changeCascader(val) {
  107. if (val.length > 1) {
  108. let floor = this.idToFloor[val[1]];
  109. if (floor.StructureInfo && floor.StructureInfo.FloorMap) {
  110. this.FloorMap = floor.StructureInfo.FloorMap;
  111. this.initGraphy();
  112. } else {
  113. this.FloorMap = '';
  114. }
  115. } else {
  116. this.FloorMap = '';
  117. }
  118. },
  119. // 保存邻接关系
  120. saveRelation() {
  121. let relationList = this.scene.relationList;
  122. let pa = {
  123. Content: []
  124. }
  125. if (relationList.length) {
  126. pa.Content = relationList.map(t => {
  127. return {
  128. FloorId: this.buildFloor[1],
  129. GraphType: this.type,
  130. LocationOne: `${t.startPoint.x},${-t.startPoint.y}`,
  131. LocationTwo: `${t.lastPoint.x},${-t.lastPoint.y}`,
  132. SpaceIdOne: t.startZone,
  133. SpaceIdTwo: t.endZone,
  134. ZoneType: this.zoneType
  135. }
  136. })
  137. }
  138. this.createRela(pa)
  139. },
  140. clearRelation() {
  141. if (this.scene) {
  142. this.scene.removeAllRelation()
  143. }
  144. },
  145. //
  146. cancel() {
  147. this.scene.removeRelationFlag = false;
  148. this.scene.createRelateFlag = false;
  149. this.scene.isAbsorbing = false;
  150. this.description = '无'
  151. },
  152. //
  153. removeRelation() {
  154. this.scene.removeRelationFlag = true;
  155. this.scene.createRelateFlag = false;
  156. this.scene.isAbsorbing = false;
  157. this.description = '清除'
  158. },
  159. //
  160. addRelation() {
  161. this.scene.createRelateFlag = true;
  162. this.scene.removeRelationFlag = false;
  163. this.scene.isAbsorbing = true;
  164. this.description = '添加'
  165. },
  166. //
  167. removeAll() {
  168. let temp = {
  169. FloorId: this.buildFloor[1],
  170. ZoneType: this.zoneType,
  171. GraphType: this.type
  172. }
  173. delFloorNeighborhood(temp, res => {
  174. this.$message.success('删除成功');
  175. this.clearRelation();
  176. })
  177. },
  178. canvasClick(item, event) {
  179. console.log(item);
  180. item.selected = false;
  181. },
  182. initGraphy() {
  183. this.clearGraphy()
  184. this.scene = new RelationScene();
  185. this.canvasLoading = true;
  186. this.scene.loadUrl(`/image-service/common/file_get?systemId=revit&key=${this.FloorMap}`).then(res => {
  187. this.canvasLoading = false;
  188. if (res == 'error') {
  189. this.FloorMap = '';
  190. this.$message.warning('数据解析异常');
  191. return;
  192. }
  193. this.view.scene = this.scene;
  194. this.view.fitSceneToView();
  195. this.scene.isSpaceSelectable = false;
  196. this.getBusinessSpace();
  197. this.view.minScale = this.view.scale;
  198. if (this.$refs.canvasFun) {
  199. this.$refs.canvasFun.everyScale = this.view.scale;
  200. }
  201. })
  202. },
  203. // 清空场景并初始化视图
  204. clearGraphy() {
  205. if (this.view) {
  206. this.view.scene = null;
  207. return
  208. }
  209. this.view = new FloorView('floorCanvas')
  210. },
  211. // canvas 获取焦点
  212. focus() {
  213. document.getElementById(`floorCanvas`).focus()
  214. },
  215. // 适配底图到窗口
  216. fit() {
  217. this.view.fitSceneToView()
  218. },
  219. // 缩放
  220. scale(val) {
  221. if (!this.view) {
  222. return;
  223. }
  224. let scale = this.view.scale;
  225. this.view.scaleByPoint(val / scale, this.canvasWidth / 2, this.canvasHeight / 2);
  226. },
  227. goback() {
  228. this.$router.push({ name: 'overView' })
  229. },
  230. // 获取项目下建筑
  231. getBuilding() {
  232. let pa = {
  233. Cascade: [{ name: 'floor', Orders: 'SequenceId desc' }],
  234. Orders: "BuildLocalName asc",
  235. }
  236. buildingQuery(pa, res => {
  237. this.options = res.Content.map(t => {
  238. if (t.Floor) {
  239. t.Floor = t.Floor.map(item => {
  240. item.BuildID = item.FloorID;
  241. item.BuildLocalName = item.FloorLocalName;
  242. this.idToFloor[item.FloorID] = item;
  243. return item;
  244. })
  245. } else {
  246. t.Floor = []
  247. }
  248. return t;
  249. })
  250. })
  251. },
  252. // 业务空间分区类型
  253. getTypes() {
  254. let pa = {
  255. Filters: `parentId='Space'`
  256. }
  257. queryDictionaryHead(pa, res => {
  258. this.tabsList = res.Content.map(t => {
  259. if (t.Name == "元空间") {
  260. return undefined;
  261. }
  262. return t;
  263. }).filter(item => item);
  264. })
  265. },
  266. getRelations() {
  267. let pa = {
  268. Filters: `FloorId='${this.buildFloor[1]}';GraphType='${this.type}';ZoneType='${this.zoneType}'`
  269. }
  270. querySpaceNeighborhood(pa, res => {
  271. let tempArr = res.Content.map(t => {
  272. let p1 = t.LocationOne.split(',');
  273. let p2 = t.LocationTwo.split(',');
  274. return {
  275. LocationOne: new SPoint(p1[0], -p1[1]),
  276. LocationTwo: new SPoint(p2[0], -p2[1]),
  277. SpaceIdOne: t.SpaceIdOne,
  278. SpaceIdTwo: t.SpaceIdTwo,
  279. }
  280. })
  281. this.clearRelation();
  282. this.scene.addAllRelaPoint(tempArr);
  283. this.canvasLoading = false;
  284. })
  285. },
  286. // 获取当前分区下的业务空间
  287. getBusinessSpace() {
  288. this.canvasLoading = true
  289. let pa = {
  290. zone: this.zoneType,
  291. data: {
  292. Filters: ``,
  293. Orders: "createTime desc, RoomID asc",
  294. PageSize: 1000
  295. }
  296. }
  297. if (this.buildFloor.length && this.buildFloor.length > 1) {
  298. pa.data.Filters = `BuildingId='${this.buildFloor[0]}';FloorId='${this.buildFloor[1]}'`
  299. } else {
  300. this.$message.warning("请选择建筑楼层");
  301. }
  302. queryZone(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>