|
@@ -0,0 +1,502 @@
|
|
|
+<template>
|
|
|
+ <div id="distribution" class="distribution-index">
|
|
|
+ <div :id="'previewBim'+_uid" class="previewBim"></div>
|
|
|
+ <div id="distribution-drap" class="distribution-drap" v-show="drapShow" @mousedown="dragStart"
|
|
|
+ @touchstart="dragStart">
|
|
|
+ <div class="distribution-drap-title">
|
|
|
+ <div id="title" class="distribution-drap-title-content">{{detail.title}}</div>
|
|
|
+ <i id="close" class="el-icon-circle-close" @click="drapShow = false"></i>
|
|
|
+ </div>
|
|
|
+ <div class="distribution-drap-content">
|
|
|
+ <organization v-if="type === 'organizationDetail'" :detail="detail"></organization>
|
|
|
+ <house v-else-if="type === 'roomDetail'" :detail="detail"></house>
|
|
|
+ </div>
|
|
|
+ <div class="image-box" v-if="detail.imageBox">
|
|
|
+ <el-carousel trigger="click" height="130px">
|
|
|
+ <el-carousel-item v-for="item in detail.imageBox" :key="item.id">
|
|
|
+ <img :src="item.url" :alt="item.url" />
|
|
|
+ </el-carousel-item>
|
|
|
+ </el-carousel>
|
|
|
+ </div>
|
|
|
+ <div style="padding: 5px;" v-else></div>
|
|
|
+ </div>
|
|
|
+ <el-dialog :close-on-click-modal="false" :title="type === '1' ? '企业看板':'设备看板'" :visible.sync="modelVisible"
|
|
|
+ width="1100px" :append-to-body="true">
|
|
|
+ <notice-board v-if="modelVisible" :type="type"></notice-board>
|
|
|
+ </el-dialog>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+ import {
|
|
|
+ getIntegrateViewToken,
|
|
|
+ } from '@/httpApi/bim'
|
|
|
+ import {
|
|
|
+ getHouseListByPage
|
|
|
+ } from '@/httpApi/space'
|
|
|
+ import {
|
|
|
+ getOrganizationListByPage
|
|
|
+ } from '@/httpApi/business'
|
|
|
+ import bimView from '@/uitls/controls'
|
|
|
+ import noticeBoard from '@/components/work/common/noticeBoard'
|
|
|
+ import organization from '@/components/work/bim/modelDetail/organization'
|
|
|
+ import house from '@/components/work/bim/modelDetail/house'
|
|
|
+ export default {
|
|
|
+ props: ['item'],
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ bimViewer: null,
|
|
|
+ type: '1',
|
|
|
+ modelVisible: false,
|
|
|
+ drapShow: false,
|
|
|
+ detail: {},
|
|
|
+ roomList: [],
|
|
|
+ organizationObj: {},
|
|
|
+ type: ''
|
|
|
+ }
|
|
|
+ },
|
|
|
+ mounted() {
|
|
|
+ let width = document.getElementById('distribution').clientWidth;
|
|
|
+ document.getElementById('distribution-drap').style.left = (width - 330) + 'px';
|
|
|
+ document.getElementById('distribution-drap').style.top = '30px';
|
|
|
+ getOrganizationListByPage({
|
|
|
+ currPage: 1,
|
|
|
+ pageSize: 100,
|
|
|
+ organizationId: this.$store.getters.organization.id,
|
|
|
+ projectId: this.$store.getters.project.id
|
|
|
+ }).then(res => {
|
|
|
+ if (res.state) {
|
|
|
+ let list = res.data.dataList,
|
|
|
+ obj = {};
|
|
|
+ for (let i = 0; i < list.length; i++) {
|
|
|
+ if (list[i].roomIds) {
|
|
|
+ let roomIds = list[i].roomIds.split(',');
|
|
|
+ for (let k = 0; k < roomIds.length; k++) {
|
|
|
+ obj[roomIds[k]] = list[i];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ this.organizationObj = obj;
|
|
|
+ this.init();
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ beforeDestroy() {
|
|
|
+ if (this.bimViewer) this.bimViewer.destroy();
|
|
|
+ },
|
|
|
+ components: {
|
|
|
+ noticeBoard,
|
|
|
+ organization,
|
|
|
+ house
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ init() {
|
|
|
+ this.$loading();
|
|
|
+ let postData = {
|
|
|
+ currPage: 1,
|
|
|
+ pageSize: 100,
|
|
|
+ projectItemTargetId: this.item.id
|
|
|
+ }
|
|
|
+ getHouseListByPage(postData).then(res => {
|
|
|
+ if (res.state) {
|
|
|
+ this.roomList = res.data.dataList.filter(node => node.dataValue).map(node => {
|
|
|
+ let nodes = JSON.parse(node.dataValue);
|
|
|
+ nodes['name'] = node.roomNumber;
|
|
|
+ nodes['id'] = node.roomNumber;
|
|
|
+ nodes['data'] = node;
|
|
|
+ return nodes;
|
|
|
+ });
|
|
|
+ getIntegrateViewToken(this.item.bimIntegrateId).then(this.successFunc);
|
|
|
+ } else {
|
|
|
+ this.$loading.close();
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ successFunc(res) {
|
|
|
+ if (res.state) {
|
|
|
+ this.bimViewer = new bimView({
|
|
|
+ dom: document.getElementById('previewBim' + this._uid),
|
|
|
+ viewToken: res.data,
|
|
|
+ renderSuccess: () => {
|
|
|
+ this.$loading.close();
|
|
|
+ if (this.item.bimIntegrateId === '3102248339366592') this.modelRenderSuccess();
|
|
|
+ this.initFloor();
|
|
|
+ this.setFloor();
|
|
|
+ }
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ this.$loading.close();
|
|
|
+ }
|
|
|
+ },
|
|
|
+ modelRenderSuccess() {
|
|
|
+ this.bimViewer.hideComponentsByObjectData([{
|
|
|
+ categoryId: "-2000038",
|
|
|
+ levelName: "标高 1"
|
|
|
+ }])
|
|
|
+ this.bimViewer.overrideComponentsColorByObjectData([{
|
|
|
+ family: "楼板",
|
|
|
+ levelName: "标高 1"
|
|
|
+ }], "#cecece")
|
|
|
+ this.bimViewer.overrideComponentsColorByObjectData([{
|
|
|
+ family: "基本墙",
|
|
|
+ levelName: "标高 1"
|
|
|
+ }], "#afa6ab");
|
|
|
+
|
|
|
+ },
|
|
|
+ initFloor() {
|
|
|
+ for (var i = 0; i < this.roomList.length; i++) {
|
|
|
+ this.bimViewer.insertRooms({
|
|
|
+ id: this.roomList[i].roomId,
|
|
|
+ boundary: {
|
|
|
+ "outer": this.roomList[i].boundary
|
|
|
+ },
|
|
|
+ height: this.roomList[i].height,
|
|
|
+ roomColor: this.returnRGBA(this.roomList[i].roomColor)
|
|
|
+ })
|
|
|
+ }
|
|
|
+ },
|
|
|
+ dragStart(evt) {
|
|
|
+ let oEvent = evt || event; //获取事件对象,这个是兼容写法
|
|
|
+ if (oEvent.target.id !== 'title') return;
|
|
|
+ let div = document.getElementById('distribution-drap');
|
|
|
+ let disX = oEvent.clientX - parseInt(div.style.left || 0);
|
|
|
+ let disY = oEvent.clientY - parseInt(div.style.top || 0);
|
|
|
+ div.style.left = oEvent.clientX - disX + 'px';
|
|
|
+ div.style.top = oEvent.clientY - disY + 'px';
|
|
|
+ document.onmousemove = function(evt) { //实时改变目标元素obox的位置
|
|
|
+ let oEvent = evt || event;
|
|
|
+ div.style.left = oEvent.clientX - disX + 'px';
|
|
|
+ div.style.top = oEvent.clientY - disY + 'px';
|
|
|
+ }
|
|
|
+ //停止拖动
|
|
|
+ document.onmouseup = function() {
|
|
|
+ document.onmousemove = null;
|
|
|
+ document.onmouseup = null;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ showDrap(type, data) {
|
|
|
+ this.type = type;
|
|
|
+ this.detail = data;
|
|
|
+ this.drapShow = true;
|
|
|
+ },
|
|
|
+ setFloor() { //设置房间
|
|
|
+ for (var i = 0; i < this.roomList.length; i++) {
|
|
|
+ let boundary = this.roomList[i].boundary;
|
|
|
+ let arrX = boundary.map(node => node.x);
|
|
|
+ let arrY = boundary.map(node => node.y);
|
|
|
+ let maxX = Math.max(...arrX);
|
|
|
+ let minX = Math.min(...arrX);
|
|
|
+ let maxY = Math.max(...arrY);
|
|
|
+ let minY = Math.min(...arrY);
|
|
|
+ let x = (maxX - minX) / 2 + minX;
|
|
|
+ let y = (maxY - minY) / 2 + minY;
|
|
|
+ if (this.roomList[i].name) {
|
|
|
+ let house = this.roomList[i].data;
|
|
|
+ house['title'] = this.roomList[i].name;
|
|
|
+ house['imageBox'] = house.picture ? JSON.parse(house.picture) : [];
|
|
|
+ this.bimViewer.addDrawable({
|
|
|
+ position: {
|
|
|
+ x: x,
|
|
|
+ y: y,
|
|
|
+ z: boundary[0].z + this.roomList[i].height
|
|
|
+ },
|
|
|
+ offsetX: -30,
|
|
|
+ offsetY: 5,
|
|
|
+ html: ` <div class="floor-name">${this.roomList[i].name}</div>`,
|
|
|
+ id: 'floor' + this.roomList[i].roomId
|
|
|
+ }, data => {
|
|
|
+ this.showDrap('roomDetail', house);
|
|
|
+ })
|
|
|
+ }
|
|
|
+ if (this.organizationObj[this.roomList[i].roomId]) {
|
|
|
+ let organization = this.organizationObj[this.roomList[i].roomId];
|
|
|
+ organization['title'] = this.roomList[i].name;
|
|
|
+ this.bimViewer.addDrawable({
|
|
|
+ position: {
|
|
|
+ x: x,
|
|
|
+ y: y,
|
|
|
+ z: boundary[0].z + this.roomList[i].height
|
|
|
+ },
|
|
|
+ offsetX: -75,
|
|
|
+ offsetY: -40,
|
|
|
+ html: ` <div class="tips-4">${organization.name}<i class="iconfont huifont-sanjiaojiantou-xia"></i></div>`,
|
|
|
+ id: 'room' + this.roomList[i].roomId
|
|
|
+ }, data => {
|
|
|
+ this.showDrap('organizationDetail', organization);
|
|
|
+ })
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ open(type) {
|
|
|
+ this.type = type;
|
|
|
+ this.modelVisible = true;
|
|
|
+ },
|
|
|
+ returnRGBA(color) {
|
|
|
+ let [r, g, b, a] = color.match(/\d+(\.\d+)?/g).map(Number);
|
|
|
+ return {
|
|
|
+ r,
|
|
|
+ g,
|
|
|
+ b,
|
|
|
+ a
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss">
|
|
|
+ .distribution-index {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ position: relative;
|
|
|
+ overflow: hidden;
|
|
|
+ background: $--box-background;
|
|
|
+
|
|
|
+ .video-toggle {
|
|
|
+ position: fixed;
|
|
|
+ width: 700px;
|
|
|
+ height: 500px;
|
|
|
+ background: #000;
|
|
|
+ left: 50%;
|
|
|
+ top: 50%;
|
|
|
+ transform: translate(-50%, -50%);
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ z-index: 999;
|
|
|
+
|
|
|
+ .chart-title {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ width: 100%;
|
|
|
+ background-size: contain;
|
|
|
+ position: relative;
|
|
|
+ background-color: $--background;
|
|
|
+ padding-left: 15px;
|
|
|
+ align-items: center;
|
|
|
+
|
|
|
+ .el-icon-close {
|
|
|
+ padding: 8px;
|
|
|
+ font-size: 24px;
|
|
|
+ cursor: pointer;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .chart-title:before {
|
|
|
+ content: "";
|
|
|
+ position: absolute;
|
|
|
+ height: 2px;
|
|
|
+ left: 0px;
|
|
|
+ right: 0;
|
|
|
+ border-bottom: 2px solid;
|
|
|
+ -o-border-image: linear-gradient(315deg, rgba(167, 208, 255, 0), rgba(110, 163, 255, .3)) 2 2;
|
|
|
+ border-image: linear-gradient(315deg, rgba(167, 208, 255, 0), rgba(110, 163, 255, .3)) 2 2;
|
|
|
+ bottom: .5px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .video-toggle-box {
|
|
|
+ flex: 1;
|
|
|
+ height: 0;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ padding: 20px;
|
|
|
+ box-sizing: border-box;
|
|
|
+ }
|
|
|
+
|
|
|
+ video {
|
|
|
+ max-height: 100%;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .tips-4 {
|
|
|
+ cursor: pointer;
|
|
|
+ }
|
|
|
+
|
|
|
+ .floor-name {
|
|
|
+ cursor: pointer;
|
|
|
+ width: 60px;
|
|
|
+ text-align: center;
|
|
|
+ color: #fff;
|
|
|
+ }
|
|
|
+
|
|
|
+ .left-button {
|
|
|
+ position: absolute;
|
|
|
+ z-index: 998;
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ left: 0;
|
|
|
+ bottom: 30px;
|
|
|
+ width: 100%;
|
|
|
+ }
|
|
|
+
|
|
|
+ .menu-item {
|
|
|
+ width: 100px;
|
|
|
+ height: 32px;
|
|
|
+ font-size: 16px;
|
|
|
+ color: #AAB5C7;
|
|
|
+ line-height: 30px;
|
|
|
+ letter-spacing: 2px;
|
|
|
+ text-align: center;
|
|
|
+ background-image: url(../../../assets/image/common/tab.png);
|
|
|
+ background-size: 100% 100%;
|
|
|
+ margin: 0 15px;
|
|
|
+ cursor: pointer;
|
|
|
+ }
|
|
|
+
|
|
|
+ .menu-item.active,
|
|
|
+ .menu-item:hover {
|
|
|
+ color: #fff;
|
|
|
+ background-image: url(../../../assets/image/common/tab_active.png);
|
|
|
+ }
|
|
|
+
|
|
|
+ .previewBim {
|
|
|
+ flex: 1;
|
|
|
+ height: 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ .distribution-drap {
|
|
|
+ position: absolute;
|
|
|
+ top: 30px;
|
|
|
+ right: 30px;
|
|
|
+ background: $--color-background;
|
|
|
+ width: 300px;
|
|
|
+ border-radius: 8px;
|
|
|
+ z-index: 998;
|
|
|
+ right: 30px;
|
|
|
+ top: 30px;
|
|
|
+
|
|
|
+ .distribution-drap-title {
|
|
|
+ height: 40px;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+
|
|
|
+ .distribution-drap-title-content {
|
|
|
+ flex: 1;
|
|
|
+ width: 0;
|
|
|
+ font-weight: 500;
|
|
|
+ cursor: move;
|
|
|
+ padding-left: 10px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .el-icon-circle-close {
|
|
|
+ font-size: 20px;
|
|
|
+ cursor: pointer;
|
|
|
+ padding-right: 10px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .user-list {
|
|
|
+ padding: 0 10px 0px 10px;
|
|
|
+ font-size: 13px;
|
|
|
+
|
|
|
+ .user-item {
|
|
|
+ display: flex;
|
|
|
+ margin-bottom: 2px;
|
|
|
+
|
|
|
+ .user-key {
|
|
|
+ width: 84px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .user-value {
|
|
|
+ flex: 1;
|
|
|
+ width: 0;
|
|
|
+ margin-left: 2px;
|
|
|
+ overflow: hidden;
|
|
|
+ white-space: nowrap;
|
|
|
+ text-overflow: ellipsis;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .user-item>div {
|
|
|
+ background: #232A37;
|
|
|
+ line-height: 34px;
|
|
|
+ padding: 0 16px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .user-item:last-child {
|
|
|
+ margin-bottom: 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .image-box {
|
|
|
+ width: 100%;
|
|
|
+ height: 150px;
|
|
|
+ padding: 10px;
|
|
|
+ box-sizing: border-box;
|
|
|
+ position: relative;
|
|
|
+
|
|
|
+ img {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ object-fit: cover;
|
|
|
+ user-select: none;
|
|
|
+ -webkit-user-drag: none;
|
|
|
+ }
|
|
|
+
|
|
|
+ .video-mask {
|
|
|
+ position: absolute;
|
|
|
+ top: 0;
|
|
|
+ left: 0;
|
|
|
+ right: 0;
|
|
|
+ bottom: 0;
|
|
|
+ background: rgba(0, 0, 0, 0.5);
|
|
|
+ z-index: 2;
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
+ opacity: 0;
|
|
|
+ transition: 300ms;
|
|
|
+ cursor: pointer;
|
|
|
+
|
|
|
+ i {
|
|
|
+ font-size: 24px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .image-box:hover {
|
|
|
+ .video-mask {
|
|
|
+ opacity: 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .walk-box {
|
|
|
+ position: absolute;
|
|
|
+ bottom: 30px;
|
|
|
+ left: 50%;
|
|
|
+ margin-left: -80px;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ z-index: 998;
|
|
|
+
|
|
|
+ .walk-box-item {
|
|
|
+ width: 80px;
|
|
|
+ height: 80px;
|
|
|
+ border-radius: 80px;
|
|
|
+ background: #232A37;
|
|
|
+ text-align: center;
|
|
|
+ line-height: 80px;
|
|
|
+ cursor: pointer;
|
|
|
+ margin-right: 20px;
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ opacity: 0.7;
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ .iconfont {
|
|
|
+ font-size: 36px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // .bf-house,
|
|
|
+ // .bf-tree-toolbar {
|
|
|
+ // display: none;
|
|
|
+ // }
|
|
|
+ }
|
|
|
+</style>
|