index.vue 15 KB

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