index.vue 9.7 KB

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