index.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539
  1. <!--
  2. revit业务空间
  3. -->
  4. <template>
  5. <div id="businessSpace">
  6. <!-- 空间属于多个建筑楼层 -->
  7. <roomInFloorDialog ref="roomInFloorDialog" @relaSuc="relaSuc"></roomInFloorDialog>
  8. <!--------- 页面头部 -------------->
  9. <div class="saga-title" v-show="!needCalculate">
  10. <div class="saga-build-mess">
  11. <div style="margin-left: 10px;float: left;">
  12. <span style="color: #999999;font-size: 14px;margin-right: 12px;">建筑楼层</span>
  13. <el-cascader :options="options" @change="changeCascader" placeholder="请选择建筑楼层" ref="cascaderAddr"
  14. v-model="buildFloorSelectd">
  15. <template slot-scope="{ node, data }">
  16. <span>{{ data.label }}</span>
  17. <i class="el-icon-warning-outline" v-if="data.count" style="color:red;margin-right:10px;"></i>
  18. </template>
  19. </el-cascader>
  20. </div>
  21. <input type="hidden" v-model="zoneItemID">
  22. </div>
  23. <div class="saga-build-tab">
  24. <el-radio-group v-model="isMyTab" @change="changeRadio" style="width: 136px;">
  25. <el-radio-button label="1">平面图</el-radio-button>
  26. <el-radio-button label="2" class="space-own-radio" style="width: 68px;">列表</el-radio-button>
  27. </el-radio-group>
  28. </div>
  29. <div class="saga-build-tips" v-if="mutiCount>0" @click="getTips">有{{ mutiCount }}个空间同时属于多个建筑楼层,点击处理</div>
  30. </div>
  31. <div class="saga-business-sapce-main" v-show="!needCalculate">
  32. <el-row class="spaceTypes">
  33. <div class="types">
  34. <el-tabs v-model="activeName" type='card' @tab-click="tabClick">
  35. <template v-for="(item,index) in tabsList">
  36. <el-tab-pane :name="item.code" :key="index">
  37. <span slot="label"><i class="el-icon-warning-outline" v-if="item.count>0"
  38. style="color:red;margin-right:10px;"></i>{{ item.name }}</span>
  39. </el-tab-pane>
  40. </template>
  41. </el-tabs>
  42. </div>
  43. </el-row>
  44. <div v-show="isMyTab == 1" style="width:100%;height:100%">
  45. <graphy @getSp="checkSpace" @dimension="checkSpace" @businessDetails="getBuinessDetails" ref="graphy"
  46. @copyID="copyID"
  47. @updateState="updateStateSuc"></graphy>
  48. </div>
  49. <div v-show="isMyTab == 2">
  50. <handsontable-main @lookEqu="lookEqu" ref="handsontable" :zoneCode="activeName" :otherType="otherType"
  51. :id="`handsontable${activeName}`">
  52. </handsontable-main>
  53. </div>
  54. <div class="infectedTips" v-show="isMyTab==1&&infectedTotal>0">
  55. <p>因底图变化而受影响的业务空间{{ infectedTotal.toString() }}个<span
  56. v-show="buildFloorSelectd.length>1">,本层受影响的业务空间{{ infectedCurfloor.toString() }}个</span></p>
  57. </div>
  58. </div>
  59. <div v-show="needCalculate"
  60. style="display:flex;align-items:center;justify-content:center;height:100%;background-color:#fff;">
  61. <div class="center" style="flex:1">
  62. <i class="iconfont icon-jianzhu" style="font-size:50px;"></i>
  63. <p style="margin:10px 0;">空间关系已发生变化,请更新关系后再使用业务空间台账</p>
  64. <p style="margin:10px 0;">前往【全部关系总览】中重新计算“建筑下的空间”“楼层下的空间”关系</p>
  65. <el-button @click="jumpToAllRelation">立即跳转</el-button>
  66. </div>
  67. </div>
  68. </div>
  69. </template>
  70. <script>
  71. // import noModelDialog from "@/components/business_space/dialogs/noModelDialog";
  72. // import influenceDialog from "@/components/business_space/dialogs/influenceDialog";
  73. // import detailsDialog from "@/components/business_space/dialogs/detailsDialog";
  74. // import notRelated from "@/components/business_space/dialogs/notRelated";
  75. // import facilityDialog from "@/components/business_space/dialogs/facilityDialog";
  76. // import graphy from "@/components/business_space/graphy/business";
  77. import graphy from "@/components/business_space/newGraphy/graphy";
  78. import roomInFloorDialog from "@/components/business_space/newAddDialogs/roomInFloorDialog";
  79. import handsontableMain from "@/components/business_space/business/handsontable";
  80. import {
  81. // getDataDictionary,
  82. getrelationTypeProject,
  83. getSpaceBdFlCount,
  84. queryAllZoneType,
  85. queryBFloorWithState,
  86. zoneCount
  87. } from "@/api/scan/request";
  88. import { getDataDictionary } from "@/api/dict";
  89. import floorCascader from "@/components/ledger/lib/floorCascader";
  90. import { mapGetters } from "vuex";
  91. export default {
  92. components: {
  93. graphy,
  94. handsontableMain,
  95. roomInFloorDialog,
  96. floorCascader,
  97. },
  98. computed: {
  99. ...mapGetters('layout', ['projectId', 'userId', 'secret'])
  100. },
  101. data() {
  102. return {
  103. floor: {
  104. influence: false, //受影响的业务空间弹窗
  105. details: false, //详情弹窗
  106. notRelated: false,
  107. facility: false
  108. },
  109. param: {
  110. ProjId: this.projectId, //项目id
  111. UserId: this.userId, //用户id
  112. secret: this.secret
  113. },
  114. buildMess: {
  115. name: "--",
  116. code: "",
  117. selectd: [],
  118. map: "",
  119. isChild: true,
  120. buildName: "--",
  121. buildCode: ""
  122. },
  123. isMyTab: 1,
  124. activeName: "0",
  125. tabsList: [],
  126. activeTabType: {
  127. "code": "GeneralZone",
  128. "name": "默认分区",
  129. "rel_type": "99"
  130. },
  131. options: [], //建筑楼层级联下拉
  132. floorToMap: {}, //楼层及其对应的模型图
  133. FloorMap: "", //当前选中的楼层对象
  134. zoneItemID: '',
  135. buildFloorSelectd: [''], //当前所选的建筑楼层
  136. childBackParam: {},
  137. needCalculate: false, // 关系是否需要计算
  138. mutiCount: 0,
  139. infectedTotal: 0,
  140. infectedCurfloor: 0,
  141. otherType: ''
  142. };
  143. },
  144. created() {
  145. this.getRelations()
  146. this.childBackParam = this.$route.params;
  147. },
  148. mounted() {
  149. },
  150. methods: {
  151. // 初始化
  152. init() {
  153. this.getTypes()
  154. this.getBuilding()
  155. this.getMutiCount()
  156. this.getInfected();
  157. },
  158. // 获取项目下建筑
  159. getBuilding() {
  160. queryBFloorWithState({}, res => {
  161. this.options = res.content.map(t => {
  162. t.value = t.id;
  163. t.label = t.localName || t.localId;
  164. t.count = 0;
  165. if (t.floor) {
  166. t.children = t.floor.map(item => {
  167. item.value = item.id;
  168. item.label = item.localName || item.name;
  169. item.buildName = t.localName || t.name;
  170. this.floorToMap[item.id] = item;
  171. if (item.count > 0) {
  172. t.count++;
  173. }
  174. return item;
  175. })
  176. t.children.unshift({ value: "all", label: "全部" }, { value: 'noKnow', label: "未明确楼层" })
  177. } else {
  178. t.children = []
  179. }
  180. return t;
  181. })
  182. this.options.unshift({ value: "all", label: "全部" }, { value: "noKnow", label: "未明确建筑" })
  183. if (this.childBackParam.buildFloorSelectd) {
  184. this.buildFloorSelectd = this.childBackParam.buildFloorSelectd;
  185. }
  186. if (this.childBackParam.zone) {
  187. this.changeCascader(this.buildFloorSelectd);
  188. }
  189. })
  190. },
  191. // 获取受影响统计
  192. getInfected(floor) {
  193. let pa = {
  194. filters: `ftate=1`
  195. }
  196. if (floor) {
  197. pa.filters += `;floorId="${floor}"`
  198. }
  199. zoneCount(pa, res => {
  200. if (floor) {
  201. this.infectedCurfloor = res.count
  202. } else {
  203. this.infectedTotal = res.count
  204. }
  205. })
  206. },
  207. // 切换平面图和列表
  208. changeRadio(val) {
  209. this.changeGraphyOrTable(val)
  210. },
  211. // 获取tabs的列表
  212. getTypes(floorid) {
  213. let pa = {
  214. // Cascade: [{ Name: 'zoneType' }]
  215. }
  216. if (floorid) {
  217. pa.floorId = floorid
  218. }
  219. queryAllZoneType(pa, res => {
  220. this.tabsList = res.content.map(t => {
  221. if (t.name == "元空间") {
  222. return undefined;
  223. }
  224. return t;
  225. }).filter(item => item);
  226. if (this.childBackParam.zone) {
  227. this.activeName = this.childBackParam.zone;
  228. this.buildFloorSelectd = this.childBackParam.buildFloorSelectd;
  229. this.isMyTab = this.childBackParam.isMyTab;
  230. this.otherType = this.childBackParam.otherType;
  231. } else if (this.activeName == '0') {
  232. this.activeName = 'GeneralZone';
  233. }
  234. })
  235. },
  236. // 获取多建筑楼层统计
  237. getMutiCount() {
  238. getSpaceBdFlCount({}, res => {
  239. this.mutiCount = res.count;
  240. if (this.mutiCount > 0) {
  241. this.getTips();
  242. }
  243. })
  244. },
  245. // 获取关系是否需要计算
  246. getRelations() {
  247. let pa = {
  248. Filters: `RelationType in ["bd2sp","fl2sp"];ComputationalState>1`
  249. }
  250. // 后台暂无接口提供 todo
  251. // getrelationTypeProject(pa, res => {
  252. // if (res.Content.length) {
  253. // this.needCalculate = true;
  254. // } else {
  255. // this.needCalculate = false;
  256. this.init()
  257. // }
  258. // })
  259. },
  260. // 通过选中的tab-Code 获取选中的tab的所有数据
  261. getItemForType() {
  262. let data = {}
  263. this.tabsList.map(item => {
  264. if (item.code == this.activeName) {
  265. data.code = item.code;
  266. data.name = item.name;
  267. }
  268. })
  269. return data
  270. },
  271. // 点击tab
  272. tabClick(val) {
  273. this.changeGraphyOrTable(this.isMyTab)
  274. },
  275. //修改所选建筑楼层
  276. changeCascader(val) {
  277. this.buildFloorSelectd = val;
  278. this.$nextTick(() => {
  279. let node = this.$refs['cascaderAddr'].getCheckedNodes()
  280. let name = node[0].pathLabels
  281. name = name.join(' ')
  282. localStorage.setItem('buildingFloor', name)
  283. })
  284. // 如果选择的是全部或者未明确
  285. if (val.indexOf('noKnow') > -1 || val.indexOf('all') > -1) {
  286. this.getTypes()
  287. this.isMyTab = 2;
  288. this.FloorMap = {}
  289. } else {
  290. // 选择的是具体某个楼层
  291. if (!this.floorToMap[val[1]].infos || !this.floorToMap[val[1]].infos.floorMap) {
  292. this.isMyTab = 2;
  293. }
  294. this.getTypes(val[1]);
  295. this.FloorMap = this.floorToMap[val[1]];
  296. }
  297. this.changeGraphyOrTable(this.isMyTab)
  298. },
  299. // 判断切换至图还是表
  300. changeGraphyOrTable(num) {
  301. this.activeTabType = this.getItemForType()
  302. if (!this.buildFloorSelectd[0]) {
  303. this.$message.warning('请选择建筑楼层')
  304. return
  305. }
  306. if (num == 2) {
  307. this.initMessage();
  308. } else {
  309. this.getInfected(this.buildFloorSelectd[1]);
  310. ///
  311. this.$refs.graphy.getData(this.buildFloorSelectd, this.FloorMap, this.activeTabType);
  312. this.childBackParam = {}
  313. }
  314. },
  315. // 触发获取表头-获取初始化信息点
  316. initMessage() {
  317. let params = {
  318. orders: "sort asc, name desc",
  319. pageNumber: 1,
  320. pageSize: 1000,
  321. type: this.activeName
  322. }
  323. getDataDictionary(params, res => {
  324. this.$refs.handsontable.getHeader(res.content, this.buildFloorSelectd);
  325. })
  326. },
  327. checkSpace(list, build, graphyId) {
  328. this.floor.notRelated = true;
  329. this.$refs.notRelated.getIdList(list, build, graphyId, this.activeTabType);
  330. this.$refs["graphy"].getHasSpace();
  331. },
  332. changeShow() {
  333. this.floor.dialogVisible = true;
  334. console.log(this.buildMess, 'buildMess')
  335. },
  336. //成功关联平面图
  337. createSuccess() {
  338. this.$refs["graphy"].getHasSpace();
  339. this.$refs["graphy"].clearDimension();
  340. this.floor.notRelated = false;
  341. },
  342. //成功删除业务空间
  343. delSuccess() {
  344. this.floor.details = false;
  345. this.$refs["graphy"].getHasSpace();
  346. this.$refs["graphy"].clearDimension();
  347. },
  348. //查看业务空间详情
  349. getBuinessDetails(list) {
  350. this.floor.details = true;
  351. this.$refs.details.getData(list, this.buildMess);
  352. },
  353. lookEqu(infos) {
  354. infos.id = infos.id
  355. infos.name = infos.localName
  356. this.floor.facility = true
  357. this.$refs.facility.getData(infos, this.buildMess)
  358. },
  359. copyID(val) {
  360. this.$refs.handsontable.zoneItemID = val;
  361. },
  362. // 空间属于多个建筑楼层
  363. getTips() {
  364. this.$refs.roomInFloorDialog.showDialog();
  365. },
  366. // 跳转至关系总览
  367. jumpToAllRelation() {
  368. this.$router.push({ name: 'overView' })
  369. },
  370. relaSuc() {
  371. this.init();
  372. },
  373. // 受影响业务空间确认成功回调
  374. updateStateSuc() {
  375. this.getBuilding()
  376. this.getTypes(this.buildFloorSelectd[1]);
  377. this.infectedTotal--;
  378. this.infectedCurfloor--;
  379. }
  380. },
  381. watch: {
  382. floor: {
  383. deep: true,
  384. handler: function () {
  385. if (this.floor.notRelated) {
  386. this.$refs["graphy"].clearDimension();
  387. }
  388. }
  389. },
  390. projectId() {
  391. this.init()
  392. }
  393. }
  394. };
  395. </script>
  396. <style lang="less">
  397. #businessSpace {
  398. position: relative;
  399. display: flex;
  400. flex-direction: column;
  401. .space-own-radio {
  402. .el-radio-button__inner {
  403. padding: 9px 21px;
  404. }
  405. }
  406. .el-dialog__body {
  407. max-height: 600px;
  408. overflow-y: auto;
  409. }
  410. .saga-title {
  411. height: 54px;
  412. background-color: #fff;
  413. font-size: 14px;
  414. position: relative;
  415. line-height: 54px;
  416. margin-bottom: 10px;
  417. border: 1px solid #dfe6ec;
  418. .saga-build-mess {
  419. // position: absolute;
  420. // left: 10px;
  421. width: 500px;
  422. margin-left: 10px;
  423. i {
  424. padding-right: 5px;
  425. }
  426. p {
  427. float: left;
  428. }
  429. .saga-btn {
  430. float: left;
  431. height: 40px;
  432. line-height: 40px;
  433. padding: 0 10px;
  434. }
  435. }
  436. .saga-build-tab {
  437. position: absolute;
  438. left: 50%;
  439. transform: translateX(-50%);
  440. .tab-main {
  441. float: left;
  442. width: 120px;
  443. padding: 0 5px;
  444. margin: 5px 0;
  445. border: 1px solid #ccc;
  446. background-color: #fff;
  447. height: 30px;
  448. box-sizing: border-box;
  449. text-align: center;
  450. cursor: pointer;
  451. overflow: hidden;
  452. i {
  453. font-size: 18px;
  454. padding-right: 10px;
  455. float: left;
  456. line-height: 30px;
  457. margin-left: 10px;
  458. }
  459. span {
  460. line-height: 30px;
  461. float: left;
  462. }
  463. }
  464. .tab-active {
  465. background-color: #409eff;
  466. color: #fff;
  467. }
  468. }
  469. .saga-build-tips {
  470. float: right;
  471. margin-right: 10px;
  472. font-size: 12px;
  473. color: #409eff;
  474. cursor: pointer;
  475. }
  476. }
  477. .saga-business-sapce-main {
  478. overflow: hidden;
  479. height: 100%;
  480. background: #fff;
  481. // padding: 10px;
  482. /deep/ .el-tabs__item.is-top {
  483. border-top: 2px solid transparent;
  484. &.is-active {
  485. border-top: 2px solid #409eff;
  486. }
  487. }
  488. .infectedTips {
  489. position: absolute;
  490. bottom: 0px;
  491. box-sizing: border-box;
  492. width: 100%;
  493. padding: 0 20px;
  494. line-height: 40px;
  495. background: #ec808d;
  496. color: #fff;
  497. z-index: 9;
  498. }
  499. }
  500. .spaceTypes {
  501. padding: 10px 10px 0;
  502. .types {
  503. float: left;
  504. width: 100%;
  505. // width: calc(100% - 200px);
  506. }
  507. .groupAdd {
  508. float: left;
  509. width: 200px;
  510. text-align: right;
  511. height: 40px;
  512. border-bottom: 1px solid #e4e7ed;
  513. }
  514. }
  515. }
  516. </style>