|
@@ -0,0 +1,480 @@
|
|
|
+<template>
|
|
|
+ <div id="manageTenantZone">
|
|
|
+ <!-- 数据字典设备类型 -->
|
|
|
+ <el-row>
|
|
|
+ <el-button size="small" type="default" icon="el-icon-back" @click="goback"></el-button>
|
|
|
+ <div style="display:inline-block;margin-left:10px;">
|
|
|
+ <label style="margin-right:10px;">业务空间类型</label>
|
|
|
+ <el-select v-model="value" placeholder="请选择" @change="getBusinessSpace">
|
|
|
+ <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value">
|
|
|
+ </el-option>
|
|
|
+ </el-select>
|
|
|
+ </div>
|
|
|
+ </el-row>
|
|
|
+ <el-row class="main-container">
|
|
|
+ <el-col :span="3" class="main-left">
|
|
|
+ <div style="padding:10px;border-bottom:1px solid #e4e4e4;">
|
|
|
+ <el-input :placeholder="`请输入租户名称`" @keyup.enter.native="getTenant">
|
|
|
+ <i slot="suffix" class="el-input__icon el-icon-search" @click="getTenant"></i>
|
|
|
+ </el-input>
|
|
|
+ </div>
|
|
|
+ <div style="overflow-y:auto;height: calc(100% - 53px);">
|
|
|
+ <div v-for="(item,i) in tenantList" :key="item.id" :class="{'tenantItem':true, 'active':item.active}" @click="tenantChange(i)">{{item.Name}}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="21" style="height:100%;">
|
|
|
+ <div style="height:52px;border-bottom:1px solid #e4e4e4;">
|
|
|
+ <div v-if="onlyRead===true||onlyRead==='true'">
|
|
|
+ <div v-for="(bd,i) in buildList" :key="bd.id" :class="{'building':true,'active':bd.active}" @click="buildChange(i)">{{bd.Name}}</div>
|
|
|
+ </div>
|
|
|
+ <div v-else style="line-height: 52px;padding:0 10px;">
|
|
|
+ <label style="margin-right:10px;">所属建筑</label>
|
|
|
+ <el-select v-model="buildSelect" placeholder="请选择" @change="changeBuildSelect">
|
|
|
+ <el-option v-for="(item,i) in allBuilding" :key="item.BuildID" :label="item.BuildLocalName || item.BuildName" :value="i">
|
|
|
+ </el-option>
|
|
|
+ </el-select>
|
|
|
+ <div style="float:right;">
|
|
|
+ <el-button size="small" type="default" @click="editCanvas" v-if="!isEdit">编辑</el-button>
|
|
|
+ <el-button size="small" type="default" @click="cancel" v-if="isEdit">取消</el-button>
|
|
|
+ <el-button size="small" type="primary" @click="save" v-if="isEdit">确认</el-button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="canvas-container" ref="graphy" v-loading="canvasLoading" v-show="hasMap">
|
|
|
+ <div class="floor-container">
|
|
|
+ <div class="before">
|
|
|
+ <div><i class="el-icon-caret-top"></i></div>
|
|
|
+ </div>
|
|
|
+ <div class="floor">
|
|
|
+ <div v-for="(fl,i) in floorList" :key="fl.id" :class="{'active':fl.active}" @click="floorChange(i)">
|
|
|
+ <div class="text">
|
|
|
+ {{fl.FloorLocalID || fl.FloorLocalName}}
|
|
|
+ <span>9+</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="after">
|
|
|
+ <div><i class="el-icon-caret-bottom"></i></div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <canvas id="floorCanvas" :width="canvasWidth" :height="canvasHeight"></canvas>
|
|
|
+ <div class="canvas-fun">
|
|
|
+ <canvasFun @scale="scale" @fit="fit" @savePng="savePng" @saveSvg="saveSvg" @saveJson="saveJson" :config="config"
|
|
|
+ @groupSelect="groupSelect" ref="canvasFun">
|
|
|
+ </canvasFun>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="canvas-container" v-show="!hasMap" style="display:flex;align-items:center;justify-content:center;">
|
|
|
+ <div class="center" style="height: 100%;flex:1;">
|
|
|
+ <i class="icon-wushuju iconfont"></i>
|
|
|
+ 暂无平面图
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+<script>
|
|
|
+import canvasFun from "@/components/business_space/newGraphy/canvasFun";
|
|
|
+import { mapGetters, mapActions } from "vuex";
|
|
|
+import { SColor, SPoint } from "@saga-web/draw/lib";
|
|
|
+import { DivideFloorScene, SpaceItem, ZoneItem, FloorView } from "@saga-web/cad-engine/lib";
|
|
|
+import { colorArr } from "@/utils/spaceColor"
|
|
|
+import { buildingQuery, queryZone, tnRelateZone } from '@/api/scan/request'
|
|
|
+export default {
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ options: [{ value: 'GeneralZone', label: '默认分区' }, { value: 'TenantZone', label: '租户分区' }],
|
|
|
+ value: 'GeneralZone',
|
|
|
+ tenantList: [{ id: 1, Name: '发发发', active: false }, { id: 2, Name: '发发发', active: false }, { id: 3, Name: '发发发', active: true }],
|
|
|
+ buildList: [{ id: 1, Name: "建筑1", active: false }, { id: 2, Name: "建筑2", active: true }],
|
|
|
+ floorList: [{ id: 23, Name: 'F2', active: false }, { id: 11, Name: 'F2', active: false }, { id: 21, Name: 'F2', active: false }, { id: 13, Name: 'F2', active: false }, { id: 14, Name: 'F2', active: false }, { id: 15, Name: 'F2', active: false }, { id: 2, Name: 'F2', active: true }],
|
|
|
+ canvasWidth: 800,
|
|
|
+ canvasHeight: 800,
|
|
|
+ onlyRead: false,
|
|
|
+ allBuilding: [],
|
|
|
+ buildSelect: 0,
|
|
|
+ activeFloor: 0,
|
|
|
+ canvasLoading: true,
|
|
|
+ isEdit: false,
|
|
|
+ view: '',
|
|
|
+ scene: '',
|
|
|
+ config: {
|
|
|
+ isEdit: false,
|
|
|
+ groupSelect: true
|
|
|
+ },
|
|
|
+ hasMap: false
|
|
|
+ }
|
|
|
+ },
|
|
|
+ components: {
|
|
|
+ canvasFun
|
|
|
+ },
|
|
|
+ computed: {
|
|
|
+ ...mapGetters("layout", ["projectId"])
|
|
|
+ },
|
|
|
+ created() {
|
|
|
+ this.onlyRead = this.$route.query.onlyRead;
|
|
|
+ // if (this.onlyRead) {
|
|
|
+ // this.getTenant();
|
|
|
+ // } else {
|
|
|
+ this.getAllBuilding();
|
|
|
+ // }
|
|
|
+ },
|
|
|
+ mounted() {
|
|
|
+ this.canvasWidth = this.$refs.graphy.offsetWidth;
|
|
|
+ this.canvasHeight = this.$refs.graphy.offsetHeight;
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ init() { },
|
|
|
+ // 返回
|
|
|
+ goback() {
|
|
|
+ this.$router.push({ name: 'rentlist' })
|
|
|
+ },
|
|
|
+ // 适配底图到窗口
|
|
|
+ fit() {
|
|
|
+ this.view.fitSceneToView()
|
|
|
+ },
|
|
|
+ // 缩放
|
|
|
+ scale(val) {
|
|
|
+ if (!this.view) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ let scale = this.view.scale;
|
|
|
+ this.view.scaleByPoint(val / scale, this.canvasWidth / 2, this.canvasHeight / 2);
|
|
|
+ },
|
|
|
+ // 保存为png
|
|
|
+ savePng() {
|
|
|
+ this.view.saveImage(`${this.floorList[this.activeFloor].FloorID}.png`, 'png');
|
|
|
+ },
|
|
|
+ // 保存为svg
|
|
|
+ saveSvg() {
|
|
|
+ this.view.saveSceneSvg(`${this.floorList[this.activeFloor].FloorID}.svg`, 6400, 4800);
|
|
|
+ },
|
|
|
+ // 保存json
|
|
|
+ saveJson() {
|
|
|
+ this.view.saveFloorJson(`${this.floorList[this.activeFloor].FloorID}.json`)
|
|
|
+ },
|
|
|
+ // 框选
|
|
|
+ groupSelect() {
|
|
|
+ this.scene.isRectSelection = true;
|
|
|
+ },
|
|
|
+ // 获取列表
|
|
|
+ getTenant() { },
|
|
|
+ // 建筑修改
|
|
|
+ buildChange(index) {
|
|
|
+ this.buildList.map(t => {
|
|
|
+ t.active = false;
|
|
|
+ })
|
|
|
+ this.buildList[index].active = true;
|
|
|
+ },
|
|
|
+ // 租户修改
|
|
|
+ tenantChange(index) {
|
|
|
+ this.tenantList.map(t => {
|
|
|
+ t.active = false;
|
|
|
+ })
|
|
|
+ this.curTenantId = this.tenantList[index].TenantID;
|
|
|
+ this.tenantList[index].active = true;
|
|
|
+ },
|
|
|
+ // 楼层修改
|
|
|
+ floorChange(index) {
|
|
|
+ this.floorList.map(t => {
|
|
|
+ t.active = false;
|
|
|
+ })
|
|
|
+ this.activeFloor = index;
|
|
|
+ this.floorList[index].active = true;
|
|
|
+
|
|
|
+ this.getGraphy(index)
|
|
|
+ },
|
|
|
+ // 修改下拉选中的建筑
|
|
|
+ changeBuildSelect(val) {
|
|
|
+ if (this.allBuilding[val].Floor && this.floorList.length) {
|
|
|
+ this.floorList = this.allBuilding[val].Floor
|
|
|
+ this.floorChange(0);
|
|
|
+ } else {
|
|
|
+ this.floorList = []
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // canvas点击事件
|
|
|
+ canvasClick(item, event) {
|
|
|
+ if (!this.isEdit) {
|
|
|
+ item.selected = false;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 编辑
|
|
|
+ editCanvas() {
|
|
|
+ this.isEdit = true;
|
|
|
+ this.config.isEdit = true;
|
|
|
+ // 将已关联选中
|
|
|
+ },
|
|
|
+ // 取消
|
|
|
+ cancel() {
|
|
|
+ this.isEdit = false;
|
|
|
+ this.config.isEdit = false;
|
|
|
+ this.scene.clearZoneSelection();
|
|
|
+ },
|
|
|
+ // 清除canvas
|
|
|
+ clearGraphy() {
|
|
|
+ if (this.view) {
|
|
|
+ this.view.scene = null;
|
|
|
+ return
|
|
|
+ }
|
|
|
+ this.view = new FloorView('floorCanvas')
|
|
|
+ },
|
|
|
+ // 编辑态获取所有建筑
|
|
|
+ getAllBuilding() {
|
|
|
+ let pa = {
|
|
|
+ Cascade: [{ name: 'floor', Orders: 'SequenceId desc' }],
|
|
|
+ Orders: "BuildLocalName asc",
|
|
|
+ }
|
|
|
+ buildingQuery(pa, res => {
|
|
|
+ this.allBuilding = res.Content.map(t => {
|
|
|
+ if (t.Floor) {
|
|
|
+ t.Floor.map(item => {
|
|
|
+ item.active = false;
|
|
|
+ })
|
|
|
+ }
|
|
|
+ return t;
|
|
|
+ });
|
|
|
+ if (this.allBuilding.length) {
|
|
|
+ this.changeBuildSelect(0);
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ // 获取业务空间
|
|
|
+ getBusinessSpace() {
|
|
|
+ let buildid = this.floorList[this.activeFloor].BuildID;
|
|
|
+ let floorid = this.floorList[this.activeFloor].FloorID;
|
|
|
+ if (buildid && floorid) {
|
|
|
+ this.canvasLoading = true
|
|
|
+ let pa = {
|
|
|
+ zone: this.value,
|
|
|
+ data: {
|
|
|
+ Filters: `BuildingId='${buildid}';FloorId='${floorid}'`,
|
|
|
+ Orders: "createTime desc, RoomID asc",
|
|
|
+ PageSize: 1000
|
|
|
+ }
|
|
|
+ }
|
|
|
+ queryZone(pa, res => {
|
|
|
+ // 所有业务空间
|
|
|
+ this.businessSpaceList = res.Content;
|
|
|
+ // 已关联元空间的业务空间
|
|
|
+ this.BSPRelaISPList = [];
|
|
|
+ res.Content.map(t => {
|
|
|
+ if (t.Outline && t.Outline.length) {
|
|
|
+ this.BSPRelaISPList.push(t)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ // 绘制业务空间
|
|
|
+ let tempArr = this.BSPRelaISPList.map((t, i) => {
|
|
|
+ if (t.FloorId == this.floorList[this.activeFloor].FloorID && t.ObjectType == this.value) {
|
|
|
+ return {
|
|
|
+ RoomLocalName: t.RoomLocalName,
|
|
|
+ OutLine: t.Outline,
|
|
|
+ RoomID: t.RoomID,
|
|
|
+ Color: colorArr[i % colorArr.length],
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ console.log('internet slow')
|
|
|
+ return undefined;
|
|
|
+ }
|
|
|
+ }).filter(item => item)
|
|
|
+ this.scene.removeAllZone();
|
|
|
+ this.scene.addZoneList(tempArr);
|
|
|
+ this.scene.click(this, this.canvasClick);
|
|
|
+ this.zoneList = this.scene.zoneList;
|
|
|
+ // 将已关联的高亮
|
|
|
+ this.canvasLoading = false;
|
|
|
+ })
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 初始化底图
|
|
|
+ getGraphy(index) {
|
|
|
+ if (this.floorList[index].StructureInfo && this.floorList[index].StructureInfo.FloorMap) {
|
|
|
+ let floorMap = this.floorList[index].StructureInfo.FloorMap;
|
|
|
+ this.clearGraphy();
|
|
|
+ this.scene = new DivideFloorScene();
|
|
|
+ this.canvasLoading = true;
|
|
|
+ this.scene.loadUrl(`/image-service/common/file_get?systemId=revit&key=${floorMap}`).then(res => {
|
|
|
+ if (res == 'error') {
|
|
|
+ this.$message.warning('数据解析异常');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ this.view.scene = this.scene;
|
|
|
+ this.scene.isSpaceSelectable = false;
|
|
|
+ // 绘制业务空间
|
|
|
+ this.getBusinessSpace();
|
|
|
+ this.view.fitSceneToView();
|
|
|
+ this.view.maxScale = this.view.scale * 10;
|
|
|
+ this.view.minScale = this.view.scale;
|
|
|
+ if (this.$refs.canvasFun) {
|
|
|
+ this.$refs.canvasFun.everyScale = this.view.scale;
|
|
|
+ }
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 保存关系
|
|
|
+ save() {
|
|
|
+ let arr = this.scene.getSelectedZone();
|
|
|
+ let pa = {
|
|
|
+ SpaceIdList: [],
|
|
|
+ TenantId: this.curTenantId
|
|
|
+ }
|
|
|
+ pa.SpaceIdList = arr.map(t => {
|
|
|
+ return t.data.RoomID;
|
|
|
+ })
|
|
|
+ console.log(pa)
|
|
|
+ return
|
|
|
+ tnRelateZone(pa, res => {
|
|
|
+ this.$message.success('关联成功');
|
|
|
+ })
|
|
|
+ },
|
|
|
+ },
|
|
|
+ watch: {
|
|
|
+ projectId() {
|
|
|
+ this.init()
|
|
|
+ },
|
|
|
+ "view.scale": {
|
|
|
+ handler(n) {
|
|
|
+ if (this.$refs.canvasFun) {
|
|
|
+ this.$refs.canvasFun.sliderVal = n * 10 / this.view.minScale;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ "scene.isRectSelection": {
|
|
|
+ handler(n) {
|
|
|
+ if (!n) {
|
|
|
+ this.$refs.canvasFun.active = '';
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ }
|
|
|
+}
|
|
|
+</script>
|
|
|
+<style lang="less" scoped>
|
|
|
+@normal-border-color : #e4e4e4;
|
|
|
+@normal-border-active-color : #e8e8e8;
|
|
|
+#manageTenantZone {
|
|
|
+ height: 100%;
|
|
|
+ .main-container {
|
|
|
+ margin-top: 10px;
|
|
|
+ background: #fff;
|
|
|
+ border: 1px solid @normal-border-color;
|
|
|
+ height: calc(100% - 43px);
|
|
|
+ overflow: hidden;
|
|
|
+ .main-left {
|
|
|
+ height: 100%;
|
|
|
+ border-right: 1px solid @normal-border-color;
|
|
|
+ .tenantItem {
|
|
|
+ border-bottom: 1px solid @normal-border-color;
|
|
|
+ text-align: center;
|
|
|
+ line-height: 40px;
|
|
|
+ color: #2b2b2b;
|
|
|
+ cursor: pointer;
|
|
|
+ &.active {
|
|
|
+ background-color: @normal-border-active-color;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .building {
|
|
|
+ display: inline-block;
|
|
|
+ margin: 7px 10px;
|
|
|
+ border: 1px solid @normal-border-color;
|
|
|
+ color: #2b2b2b;
|
|
|
+ border-radius: 28px;
|
|
|
+ padding: 4px 16px;
|
|
|
+ &.active {
|
|
|
+ border: 1px solid #409eff;
|
|
|
+ color: #409eff;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .canvas-container {
|
|
|
+ position: relative;
|
|
|
+ width: 100%;
|
|
|
+ height: calc(100% - 53px);
|
|
|
+ .floor-container {
|
|
|
+ position: absolute;
|
|
|
+ width: 60px;
|
|
|
+ height: 250px;
|
|
|
+ top: 20px;
|
|
|
+ left: 20px;
|
|
|
+ z-index: 2;
|
|
|
+ background-color: #fff;
|
|
|
+ .before,
|
|
|
+ .after {
|
|
|
+ div {
|
|
|
+ width: 52px;
|
|
|
+ height: 23px;
|
|
|
+ margin: 0 auto;
|
|
|
+ text-align: center;
|
|
|
+ font-size: 24px;
|
|
|
+ line-height: 1;
|
|
|
+ color: #2b2b2b;
|
|
|
+ border: 1px solid @normal-border-color;
|
|
|
+ cursor: pointer;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .floor {
|
|
|
+ height: 210px;
|
|
|
+ overflow-y: auto;
|
|
|
+ &::-webkit-scrollbar {
|
|
|
+ display: none;
|
|
|
+ }
|
|
|
+ & > div {
|
|
|
+ cursor: pointer;
|
|
|
+ &.active {
|
|
|
+ background-image: url(~@/assets/image/floorBG.png);
|
|
|
+ div.text {
|
|
|
+ border: none;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ div.text {
|
|
|
+ position: relative;
|
|
|
+ width: 54px;
|
|
|
+ height: 30px;
|
|
|
+ line-height: 30px;
|
|
|
+ white-space: nowrap;
|
|
|
+ overflow: hidden;
|
|
|
+ text-overflow: ellipsis;
|
|
|
+ text-align: center;
|
|
|
+ color: #2b2b2b;
|
|
|
+ margin: 0 auto;
|
|
|
+ padding: 0 10px;
|
|
|
+ box-sizing: border-box;
|
|
|
+ border-left: 1px solid @normal-border-color;
|
|
|
+ border-right: 1px solid @normal-border-color;
|
|
|
+ &:hover {
|
|
|
+ background-color: #409eff1a;
|
|
|
+ }
|
|
|
+ span {
|
|
|
+ position: absolute;
|
|
|
+ display: block;
|
|
|
+ height: 10px;
|
|
|
+ border-radius: 50%;
|
|
|
+ line-height: 10px;
|
|
|
+ text-align: center;
|
|
|
+ top: 0;
|
|
|
+ right: -2px;
|
|
|
+ color: #fff;
|
|
|
+ background-color: #f56c6c;
|
|
|
+ padding: 5px;
|
|
|
+ font-size: 12px;
|
|
|
+ transform: scale(0.7, 0.7);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .canvas-fun {
|
|
|
+ position: absolute;
|
|
|
+ bottom: 20px;
|
|
|
+ left: 50%;
|
|
|
+ z-index: 3;
|
|
|
+ transform: translateX(-50%;);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|