Bläddra i källkod

Merge remote-tracking branch 'origin/spaceup' into dktest

LXXXY 5 år sedan
förälder
incheckning
0a119c8ee9
30 ändrade filer med 2326 tillägg och 764 borttagningar
  1. 5 4
      package.json
  2. 7 1
      src/api/model/file.js
  3. 9 1
      src/api/scan/config.js
  4. 67 1
      src/api/scan/request.js
  5. 4 0
      src/assets/scss/point/point_config/reset.scss
  6. 62 6
      src/assets/style/iconfont/iconfont.css
  7. BIN
      src/assets/style/iconfont/iconfont.eot
  8. 42 0
      src/assets/style/iconfont/iconfont.svg
  9. BIN
      src/assets/style/iconfont/iconfont.ttf
  10. BIN
      src/assets/style/iconfont/iconfont.woff
  11. 95 103
      src/components/business_space/business/handsontable.vue
  12. 257 0
      src/components/business_space/newAddDialogs/addEquipDialog.vue
  13. 110 0
      src/components/business_space/newAddDialogs/addSystemDialog.vue
  14. 145 0
      src/components/business_space/newGraphy/canvasFun.vue
  15. 34 0
      src/components/business_space/newGraphy/createBSP.vue
  16. 566 0
      src/components/business_space/newGraphy/graphy.vue
  17. 67 0
      src/components/business_space/newGraphy/unRelateBSP.vue
  18. 172 0
      src/components/business_space/newTables/eqToSpaceTable.vue
  19. 135 0
      src/components/business_space/newTables/syInSpaceTable.vue
  20. 1 1
      src/components/business_space/table/businessTable.vue
  21. 1 1
      src/components/model/file/floorTable.vue
  22. 12 5
      src/router/system.js
  23. 156 334
      src/views/ledger/spacelist/index.vue
  24. 174 0
      src/views/ledger/spacelist/spaceDetail/index.vue
  25. 12 14
      src/views/ready/buildfloor/drawGraphy/checkGraphy.vue
  26. 132 76
      src/views/ready/buildfloor/drawGraphy/drawFloor.vue
  27. 0 112
      src/views/ready/buildfloor/drawGraphy/operateGraphyItem.vue
  28. 0 60
      src/views/ready/buildfloor/drawGraphy/repetitionGraphy.vue
  29. 11 11
      src/views/ready/buildfloor/index.vue
  30. 50 34
      src/views/ready/buildfloor/repetitionGraphy.vue

+ 5 - 4
package.json

@@ -5,14 +5,15 @@
     "author": "yaoll <yaolinlin@sagacloud.cn>",
     "private": true,
     "scripts": {
+        "i": "npm install",
         "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
         "start": "npm run dev",
         "build": "node build/build.js"
     },
     "dependencies": {
-        "@sybotan-web/base": "2.0.54",
-        "@sybotan-web/draw": "2.0.128",
-        "@sybotan-web/graphy": "2.0.93",
+        "@sybotan-web/base": "2.1.5",
+        "@sybotan-web/draw": "2.1.56",
+        "@sybotan-web/graphy": "2.1.27",
         "axios": "^0.18.0",
         "echarts": "^4.1.0",
         "element-ui": "^2.11.0",
@@ -23,7 +24,7 @@
         "vue-axios": "^2.1.4",
         "vue-router": "^3.0.1",
         "vuex": "^3.1.0",
-        "cad-engine": "2.0.56"
+        "cad-engine": "2.0.231"
     },
     "devDependencies": {
         "ajv": "^6.9.1",

+ 7 - 1
src/api/model/file.js

@@ -278,4 +278,10 @@ let api = {
     }
 
 }
-export default api
+export default api
+
+//楼层与平面图绑定
+export function bindFloorModel(param, success) {
+    let url = `${baseUrl}/model-floor/bind`;
+    httputils.postJson(url, param, success)
+}

+ 9 - 1
src/api/scan/config.js

@@ -9,5 +9,13 @@ export const zone = {
   PowerSupplyZone: 'zone-power-supply', //供电分区
   LightingZone: 'zone-lighting', //照明分区
   AirConditioningZone: 'metaspace', //空调分区
-  TenantZone: 'zone-tenant' //租赁分区
+  TenantZone: 'zone-tenant', //租赁分区
+  HeatingZone:'zone-heating', //采暖分区
+  CleanZone:'zone-clean', //洁净分区
+  DomesticWaterSupplyZone:'zone-domestic-water', //生活给水分区
+  NetworkZone:'zone-network', //网络分区
+  FunctionZone:'zone-function', //功能分区
+  FireZone:'zone-fire', //防火分区
+  SecurityZone:'zone-security', //安防分区
+  Ispace:'ispace', //元空间
 }

+ 67 - 1
src/api/scan/request.js

@@ -1194,6 +1194,13 @@ export function updateZone(param, success) {
     http.postJson(url, data, success)
 }
 
+//根据条件查询统计数量
+export function countZone(param, success) {
+    let data = param.data
+    let url = `${baseUrl}/datacenter/${zone[param.zone]}/count`;
+    http.postJson(url, data, success)
+}
+
 //动态数据关联-查询对应关系(删除提示页)
 export function dynamicQueryPrompt(param, success) {
     let url = `${baseUrl}/pointconfig/dynamic/query-prompt`;
@@ -1245,4 +1252,63 @@ export function floorUpdate(param, success) {
     let url = `${baseUrl}/datacenter/floor/update`;
     http.postJson(url, param, success)
 }
-
+//关系-----设备所在业务空间--删除关系
+export function eqInSpaceDelete(param, success) {
+    let url = `${baseUrl}/datacenter/eq-in-sp-base/unlink-list?type=${param.type}`;
+    http.postJson(url, param.data, success)
+}
+//关系-----设备所在业务空间--创建关系
+export function eqInSpaceCreate(param, success) {
+    let url = `${baseUrl}/datacenter/eq-in-sp-base/link-eq-sp?type=${param.type}`;
+    http.postJson(url, param.data, success)
+}
+//关系-----设备服务业务空间--删除关系
+export function eqForSpaceDelete(param, success) {
+    let url = `${baseUrl}/datacenter/eq-for-sp-base/unlink-list?type=${param.type}`;
+    http.postJson(url, param.data, success)
+}
+//关系-----设备服务业务空间--创建关系
+export function eqForSpaceCreate(param, success) {
+    let url = `${baseUrl}/datacenter/eq-for-sp-base/link-eq-sp?type=${param.type}`;
+    http.postJson(url, param.data, success)
+}
+//关系-----系统所在业务空间--删除关系
+export function syInSpaceDelete(param, success) {
+    let url = `${baseUrl}/datacenter/sy-in-sp-base/unlink-list?type=${param.type}`;
+    http.postJson(url, param.data, success)
+}
+//关系-----系统所在业务空间--创建关系
+export function syInSpaceCreate(param, success) {
+    let url = `${baseUrl}/datacenter/sy-in-sp-base/link-sp-sys?type=${param.type}`;
+    http.postJson(url, param.data, success)
+}
+//关系-----没有和当前空间绑定的设备
+export function notEqInSpaceQuery(param, success) {
+    let url = `${baseUrl}/equip-component/space/unspace-in-eq?type=${param.type}&spaceId=${param.spaceId}`;
+    http.postJson(url, param.data, success)
+}
+//关系-----未服务当前空间的设备
+export function notEqForSpaceQuery(param, success) {
+    let url = `${baseUrl}/equip-component/space/unspace-for-eq?type=${param.type}&spaceId=${param.spaceId}`;
+    http.postJson(url, param.data, success)
+}
+//关系-----没有和当前空间绑定的系统
+export function notSyInSpaceQuery(param, success) {
+    let url = `${baseUrl}/equip-component/space/unspace-in-sys?type=${param.type}&spaceId=${param.spaceId}`;
+    http.postJson(url, param.data, success)
+}
+//关系-----业务空间和元空间关系(业务空间一对多,并且会覆盖之前记录)
+export function createRelateInZoneAndISp(param, success) {
+    let url = `${baseUrl}/datacenter/sp-in-si-zone-general/link-sp`;
+    http.postJson(url, param, success)
+}
+//关系-----空间内没有和空间关联的设备 根据坐标计算(专用接口)
+export function getEqNotInSpace(param, success) {
+    let url = `${baseUrl}/equip-component/space/unspace-fIn-eq-point?spaceId=${param.spaceId}&type=${param.type}`;
+    http.postJson(url, param.data, success)
+}
+//关系-----空间内没有服务空间的设备 根据坐标计算(专用接口)
+export function getEqNotForSpace(param, success) {
+    let url = `${baseUrl}/equip-component/space/unspace-for-eq-point?spaceId=${param.spaceId}&type=${param.type}`;
+    http.postJson(url, param.data, success)
+}

+ 4 - 0
src/assets/scss/point/point_config/reset.scss

@@ -478,4 +478,8 @@ input::-webkit-inner-spin-button {
 }
 input[type="number"]{
     -moz-appearance: textfield;
+}
+
+canvas:focus{
+    outline: none;
 }

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 62 - 6
src/assets/style/iconfont/iconfont.css


BIN
src/assets/style/iconfont/iconfont.eot


Filskillnaden har hållts tillbaka eftersom den är för stor
+ 42 - 0
src/assets/style/iconfont/iconfont.svg


BIN
src/assets/style/iconfont/iconfont.ttf


BIN
src/assets/style/iconfont/iconfont.woff


+ 95 - 103
src/components/business_space/business/handsontable.vue

@@ -1,6 +1,6 @@
 <template>
   <div id="handsontable" v-loading="isLoading">
-		<el-row class="left">
+    <el-row class="left">
       <el-select v-model="onlyRead" @change="getData(false)" style="width:100px;margin-right:20px;vertical-align:bottom;">
         <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"></el-option>
       </el-select>
@@ -8,8 +8,8 @@
         <el-option v-for="item in showTypes" :key="item.value" :label="item.label" :value="item.value"></el-option>
       </el-select>
       <el-button v-show="!onlyRead" @click="addSp">添加</el-button>
-			<el-button @click="reset">刷新</el-button>
-			<el-button v-show="!onlyRead" @click="undo">撤销</el-button>
+      <el-button @click="reset">刷新</el-button>
+      <el-button v-show="!onlyRead" @click="undo">撤销</el-button>
     </el-row>
     <div v-show="main &&main.length" :id="id"></div>
     <div class="center" v-show="!main || !main.length" style="height: 400px;padding-top:140px;box-sizing:border-box;">
@@ -17,9 +17,9 @@
       暂无数据
     </div>
     <!-- <add-business :buildMess="buildMess" :dialog="dialog"></add-business> -->
-    <el-pagination class="right" v-show="main && main.length" @size-change="handleSizeChange"
-      @current-change="handleCurrentChange" :current-page="page.pageNumber" :page-sizes="page.pageSizes"
-      :page-size="page.pageSize" layout="total, sizes, prev, pager, next, jumper" :total="page.total">
+    <el-pagination class="right" v-show="main && main.length" @size-change="handleSizeChange" @current-change="handleCurrentChange"
+      :current-page="page.pageNumber" :page-sizes="page.pageSizes" :page-size="page.pageSize" layout="total, sizes, prev, pager, next, jumper"
+      :total="page.total">
     </el-pagination>
     <!-- <div class="right" v-show="main && main.length">
       <my-pagination :page="page" @change="pageChange"></my-pagination>
@@ -45,12 +45,8 @@ import { queryZone, updateZone, deleteZone, createZone, BeatchQueryParam } from
 import { mapGetters, mapActions } from "vuex";
 export default {
   props: {
-    id: {
-      type: String
-		},
-		zoneObj: {
-			type: Object
-		}
+    id: {},
+    zoneCode: {}
   },
   components: {
     qrcode, //二维码页面
@@ -58,11 +54,11 @@ export default {
     addBusiness
   },
   computed: {
-		...mapGetters("layout", ["projectId", "secret", "userId"]),
-		showTypes () {
-      return this.onlyRead?
-        [{value: "Visible", label: '只看采集信息'}, {value: "all", label: '全部'}]: 
-        [{value: "partInfo", label: '隐藏信息点'}, {value: "Visible", label: '只看采集信息'}, {value: "all", label: '全部'} ]
+    ...mapGetters("layout", ["projectId", "secret", "userId"]),
+    showTypes() {
+      return this.onlyRead ?
+        [{ value: "Visible", label: '只看采集信息' }, { value: "all", label: '全部' }] :
+        [{ value: "partInfo", label: '隐藏信息点' }, { value: "all", label: '全部' }]
     }
   },
   data() {
@@ -76,15 +72,15 @@ export default {
       main: [],
       hot: null,
       isLoading: true,
-			options: [{
+      options: [{
         value: true,
         label: '只读模式'
       }, {
         value: false,
         label: '编辑模式'
       }],
-			onlyRead: true,
-			showType: "",
+      onlyRead: true,
+      showType: "",
       page: {
         pageSize: 50,
         pageSizes: [10, 20, 50, 100],
@@ -99,7 +95,6 @@ export default {
       buildMess: null,
       filtersArr: [], //表格数据被过滤后的下标
       copyMain: [], //深拷贝数组
-      activeType: {}
     };
   },
   created() {
@@ -113,43 +108,39 @@ export default {
       this.param.secret = this.secret
     },
     //获取表头
-    getHeader(headers, activeTabType) {
+    getHeader(headers, buildFloorSelectd) {
       this.headers = headers
-      this.activeType = activeTabType
+      this.buildFloorSelectd = buildFloorSelectd
+      this.getData()
     },
-    getData(buildMess) {
+    getData() {
       this.isLoading = true
-      if (buildMess) {
-        this.buildMess = buildMess
-			}
       let params = {
-				zone: this.zoneObj.code,
-				data: {
-					Filters: ``,
-					Orders: "createTime desc, RoomID asc",
-					PageNumber: this.page.pageNumber,
-					PageSize: this.page.pageSize
-				}
-			}
-			if (this.buildMess.selectd && this.buildMess.selectd[0] && this.buildMess.selectd[1]) {
-				params.data.Filters = `BuildingId='${this.buildMess.selectd[0]}';FloorId='${this.buildMess.selectd[1]}'`
-			} else if (this.buildMess.selectd && this.buildMess.selectd[0] && !this.buildMess.selectd[1]) {
-				params.data.Filters = `BuildingId='${this.buildMess.selectd[0]}'`
-			} else {
-				params.data.Filters = `BuildingId='';FloorId=''`
-			}
-			queryZone(params, res => {
-				this.page.total = res.Total
-				this.main = res.Content
-				if (this.main && this.main.length && this.main[0].RoomID) {
+        zone: this.zoneCode,
+        data: {
+          Filters: ``,
+          Orders: "createTime desc, RoomID asc",
+          PageNumber: this.page.pageNumber,
+          PageSize: this.page.pageSize
+        }
+      }
+      if (this.buildFloorSelectd.length && this.buildFloorSelectd[0] && this.buildFloorSelectd[1]) {
+        params.data.Filters = `BuildingId='${this.buildFloorSelectd[0]}';FloorId='${this.buildFloorSelectd[1]}'`
+      }
+      // else if (buildFloorSelectd.length && buildFloorSelectd[0] && !buildFloorSelectd[1]) {
+      //   params.data.Filters = `BuildingId='${buildFloorSelectd[0]}'`
+      // } else {
+      //   params.data.Filters = `BuildingId='';FloorId=''`
+      // }
+      queryZone(params, res => {
+        this.page.total = res.Total
+        this.main = res.Content
+        if (this.main && this.main.length && this.main[0].RoomID) {
           this.copyMain = tools.deepCopy(this.main);
-          if (this.onlyRead) {
-            this.getBatch(this.main)
-          }
         }
         this.isLoading = false
-				this.getMain()
-			})
+        this.getMain()
+      })
     },
     //获取表格主体内容
     getMain() {
@@ -163,7 +154,6 @@ export default {
     },
     //初始化handsontable组件
     initHot() {
-      let id = this.id
       var container = document.getElementById(this.id);
       let winHeight = document.documentElement.clientHeight;
       this.hot = new Handsontable(container, {
@@ -171,6 +161,7 @@ export default {
         colHeaders: this.delHeader(this.headers), //表头文案
         columns: this.getType(this.headers), //数据显示格式
         filters: true,
+        fixedColumnsLeft: 4,
         maxRows: this.main.length,
         height: winHeight - 100 - 50 - 176,
         columnSorting: true, //添加排序
@@ -232,7 +223,10 @@ export default {
     getInfors(infos, row) {
       let val = this.hot.colToProp(row.col);
       if (val == "point") {
-        this.$emit("lookEqu", infos);
+        this.$router.push({
+          path: "/ledger/spaceDetail",
+          query: { RoomID: infos.RoomID, zone: this.zoneCode, isMyTab: 2 }
+        })
       } else if (val == "RoomQRCode") {
         this.qrcodeUrl = this.main[row.row].RoomQRCode
         if (!!this.qrcodeUrl) {
@@ -246,7 +240,7 @@ export default {
     },
     //表格发生更改
     tdChange(changeData, source) {
-			if (!this.onlyRead) {
+      if (!this.onlyRead) {
         if (changeData) {
           let trimmedArr = this.trimmedRows();
           let param = handsonUtils.getParam(changeData, source, this.hot, trimmedArr);
@@ -272,17 +266,17 @@ export default {
     },
     //右键删除
     romoveFm() {
-			let params = tools.differenceArr(this.main, this.copyMain)
+      let params = tools.differenceArr(this.main, this.copyMain)
       if (params.length < 1 || this.main > this.copyMain) {
         return
       }
       let param = {
-				data: [],
-				zone: this.zoneObj.code
-			}
+        data: [],
+        zone: this.zoneCode
+      }
       params.map(item => {
-        if(item.RoomID)
-        param.data.push({RoomID: item.RoomID})
+        if (item.RoomID)
+          param.data.push({ RoomID: item.RoomID })
       })
       this.$confirm("此操作将删除业务空间,是否继续?", "提示", {
         confirmButtonText: '确定',
@@ -290,9 +284,9 @@ export default {
         type: 'warning'
       }).then(() => {
         deleteZone(param, res => {
-					this.$message.success("删除成功!")
-        	this.getData()
-				})
+          this.$message.success("删除成功!")
+          this.getData()
+        })
       }).catch(() => {
         this.getData()
         this.$message("取消删除")
@@ -302,7 +296,7 @@ export default {
     handleCreateZone(param) {
       let keys = Object.keys(param)
       keys.map((key) => { //将值为空字符串的属性删除
-        if(param[key] == "") {
+        if (param[key] == "") {
           delete param[key]
         }
       })
@@ -314,40 +308,37 @@ export default {
         this.$message("新添加业务空间内容不能为空!")
         return
       }
-      if (this.buildMess.selectd && this.buildMess.selectd[0] && this.buildMess.selectd[1]) {
-        param.BuildingId = this.buildMess.selectd[0]
-        param.FloorId = this.buildMess.selectd[1]
-			} else if (this.buildMess.selectd && this.buildMess.selectd[0] && !this.buildMess.selectd[1]) {
-				param.BuildingId = this.buildMess.selectd[0]
-			}
+      if (this.buildFloorSelectd && this.buildFloorSelectd[0] && this.buildFloorSelectd[1]) {
+        param.BuildingId = this.buildFloorSelectd[0]
+        param.FloorId = this.buildFloorSelectd[1]
+      }
+      //  else if (this.buildMess.selectd && this.buildMess.selectd[0] && !this.buildMess.selectd[1]) {
+      //   param.BuildingId = this.buildMess.selectd[0]
+      // }
       let params = {
-        zone: this.zoneObj.code,
+        zone: this.zoneCode,
         data: {
           Content: [param]
         }
       }
-      createZone(params,(res) => {
+      createZone(params, res => {
         this.$message.success("添加成功!")
         this.getData()
       })
     },
     // 修改
     updateBusiness(data, change) {
-			let param = {
-				data: {
-					Content: [],
-        	Projection: []
-				},
-        zone: this.zoneObj.code
-      }, keyList = [];
+      let param = {
+        data: {
+          Content: [],
+          Projection: []
+        },
+        zone: this.zoneCode
+      };
       //生成要修改字段列表
       change.map((item) => {
-        let key = item[1].split(".")[0]
-        if(item[1] && keyList.indexOf(key) == -1) {
-          keyList.push(key)
-        }
-        if(item[1] && item[3] == "" && param.data.Projection.indexOf(key) == -1) {
-          param.data.Projection.push(key)
+        if (item[1] && param.data.Projection.indexOf(item[1]) == -1) {
+          param.data.Projection.push(item[1])
         }
       })
       //生成对应修改数据
@@ -357,8 +348,9 @@ export default {
           tools.setDataForKey(item, value, itemData == "" ? null : itemData)
         })
         param.data.Content.push(item);
-			})
-			updateZone(param, (res) => {})
+      })
+      param.Projection = []
+      updateZone(param, (res) => { })
     },
     //获取被筛选掉的行号
     trimmedRows() {
@@ -470,21 +462,21 @@ export default {
      * @return 处理好的数据格式
      */
     getType(list) {
-			let arr = tools.copyArr(list)
-			let data = showTools.headerTypeFilter(arr, "space", this.onlyRead, this.showType)
+      let arr = tools.copyArr(list)
+      let data = showTools.headerTypeFilter(arr, "space", this.onlyRead, this.showType)
       data.unshift({
-        data: "hasSi",
+        data: "Outline",
         renderer: this.myRenderer,
         readOnly: true
       }, {
-				data: "point",
-				renderer: this.facilityRender,
-				readOnly: true
-			});
+        data: "point",
+        renderer: this.facilityRender,
+        readOnly: true
+      });
       return data;
     },
     myRenderer(instance, td, row, col, prop, value, cellProperties) {
-      if (value) {
+      if (value && value.length) {
         td.innerHTML = "已关联"
       } else {
         td.innerHTML = "未关联"
@@ -521,8 +513,8 @@ export default {
     undo() {
       this.hot.undo()
     },
-		/**  分页事件------------------------ */
-		//切换每页显示多少条数据
+    /**  分页事件------------------------ */
+    //切换每页显示多少条数据
     handleSizeChange(val) {
       this.page.pageSize = val
       this.getData()
@@ -537,8 +529,8 @@ export default {
     projectId() {
       this.setData()
       this.main = null
-		},
-		showTypes: {
+    },
+    showTypes: {
       handler(newName, oldName) {
         if (newName && newName[0] && newName[0].value) {
           this.showType = newName[0].value
@@ -554,10 +546,10 @@ export default {
 </script>
 <style lang="less" scoped>
 #handsontable {
-	.left{
-		padding-top: 0;
-		padding-bottom: 10px;
-	}
+  .left {
+    padding-top: 0;
+    padding-bottom: 10px;
+  }
   .no-data {
     height: 150px;
     line-height: 150px;

+ 257 - 0
src/components/business_space/newAddDialogs/addEquipDialog.vue

@@ -0,0 +1,257 @@
+<template>
+  <el-dialog :title="title" :visible.sync="dialogVisible" width="900px" id="addEqDialog">
+    <el-row class="filters">
+      <el-col :span="9">
+        <el-input placeholder="输入设备名称或设备本地编码查询进行查询" v-model="keycode" clearable @keyup.enter.native="getTableData">
+          <i slot="suffix" class="el-input__icon el-icon-search" @click="getTableData"></i>
+        </el-input>
+      </el-col>
+      <el-col :span="15">
+        <span style="margin-left:10px;">所属楼层</span>
+        <el-cascader @change="getTableData" v-model="floor" :options="options" :props="props"></el-cascader>
+        <el-checkbox style="margin-left:10px;" @change="getTableData" v-model="showType" label="只显示在当前业务空间中的设备"></el-checkbox>
+      </el-col>
+    </el-row>
+    <div class="table-box">
+      <el-table :data="tableData" style="width: 100%" height="100%" v-loading="loading" :header-cell-style="headerStyle" ref="multipleTable"
+        @selection-change="handleSelectionChange">
+        <el-table-column type="selection" width="55"></el-table-column>
+        <el-table-column :label="`${inSpaceType}名称`" show-overflow-tooltip min-width="100">
+          <template slot-scope="scope">
+            <div>
+              {{scope.row.EquipLocalName||scope.row.EquipName||''}}
+            </div>
+          </template>
+        </el-table-column>
+        <el-table-column prop="EquipLocalID" :label="`${inSpaceType}本地编码`" show-overflow-tooltip min-width="100"></el-table-column>
+        <el-table-column prop="EquipCategory.EquipName" :label="`${inSpaceType}类`" show-overflow-tooltip min-width="100"></el-table-column>
+        <el-table-column prop="linkOtherSpace" label="已关联其他业务空间" show-overflow-tooltip min-width="100"></el-table-column>
+        <el-table-column prop="action" label="操作" min-width="100">
+          <template slot-scope="scope">
+            <el-button size="mini" @click="toDetail(scope.$index, scope.row)" type="primary" plain>查看详情</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+      <!-- 分页 -->
+      <el-pagination class="fr" v-show="tableData && tableData.length" @size-change="handleSizeChange" @current-change="handleCurrentChange"
+        :current-page="page.pageNumber" :page-sizes="page.pageSizes" :page-size="page.pageSize" layout="total, sizes, prev, pager, next, jumper"
+        :total="page.total"></el-pagination>
+    </div>
+    <span slot="footer" class="dialog-footer">
+      <el-button size="small" @click="dialogVisible = false">取 消</el-button>
+      <el-button size="small" type="primary" @click="savaRelation">确 定</el-button>
+    </span>
+  </el-dialog>
+</template>
+
+<script>
+import {
+  getSpaceEquip,
+  buildingQuery, //数据中心-建筑查询
+  notEqInSpaceQuery, //没有和当前空间绑定的设备
+  notEqForSpaceQuery, //未服务当前空间的设备
+  eqInSpaceCreate, //设备所在业务空间--创建关系
+  eqForSpaceCreate, //设备服务业务空间--创建关系
+  getEqNotInSpace, //空间内没有和空间关联的设备
+  getEqNotForSpace, //空间内没有服务空间的设备
+} from "@/api/scan/request";
+import { mapGetters } from "vuex";
+export default {
+  components: {
+
+  },
+  computed: {
+    ...mapGetters("layout", ["projectId"])
+  },
+  data() {
+    return {
+      title: "添加设备",
+      keycode: '', //输入查询条件
+      options: [], //建筑楼层级联
+      floor: [], // 选中的建筑楼层
+      showType: false, //是否只显示在当前业务空间中的设备
+      inSpaceType: '设备',
+      dialogVisible: false,
+      tableData: [],
+      loading: false,
+      headerStyle: {
+        backgroundColor: '#e1e4e5',
+        color: '#2b2b2b',
+        lineHeight: '30px'
+      }, // 列表样式
+      selections: [], // 选中项
+      page: {
+        pageSize: 50,
+        pageSizes: [10, 20, 50, 100],
+        pageNumber: 1,
+        total: 0
+      },
+      props: { //自定义字段
+        value: "BuildID",
+        label: "BuildLocalName",
+        children: "Floor"
+      },
+    };
+  },
+  props: {
+    type: {}, //Equipment--EquipmentFor
+    spaceId: {},
+    zone: {}, //分区类型 
+  },
+  created() {
+    this.getBuilding();
+  },
+  methods: {
+    // 获取项目下建筑
+    getBuilding() {
+      let pa = {
+        Cascade: [{ name: 'floor', Orders: 'SequenceId desc' }],
+        Orders: "BuildLocalName asc",
+      }
+      buildingQuery(pa, res => {
+        this.options = res.Content.map(t => {
+          if (t.Floor) {
+            t.Floor = t.Floor.map(item => {
+              item.BuildID = item.FloorID;
+              item.BuildLocalName = item.FloorLocalName;
+              return item;
+            })
+          } else {
+            t.Floor = []
+          }
+          t.Floor.unshift({ BuildID: 'isNull', BuildLocalName: '未明确楼层' })
+          return t;
+        })
+      })
+    },
+    // 显示弹窗
+    showDialog() {
+      this.dialogVisible = true;
+      this.getTableData();
+    },
+    // 获取列表数据
+    getTableData() {
+      let pa = {
+        data: {
+          Cascade: [{ Name: "equipCategory" }],
+          Filters: `BuildingId='${this.floor[0]}';FloorId='${this.floor[1]}'`,
+          PageNumber: this.page.pageNumber,
+          PageSize: this.page.pageSize,
+        },
+        type: this.zone,
+        spaceId: this.spaceId
+      }
+      if (this.keycode != '') {
+        pa.data.Filters += `;EquipName contain "${this.keycode}" or EquipLocalName contain "${this.keycode}" or EquipLocalID contain "${this.keycode}"`
+      }
+      console.log(this.showType)
+      if (this.showType) {
+        if (this.type == "Equipment") {
+          // pa.data.Cascade.push({ Name: "zoneSpaceInBase" })
+          delete pa.data.Cascade;
+          getEqNotInSpace(pa, res => {
+            this.getDataSuc(res, 'ZoneSpaceBaseIn')
+          })
+        } else {
+          // pa.data.Cascade.push({ Name: "zoneSpaceForBase" })
+          delete pa.data.Cascade;
+          getEqNotForSpace(pa, res => {
+            this.getDataSuc(res, 'ZoneSpaceBaseFor')
+          })
+        }
+      } else {
+        if (this.type == "Equipment") {
+          pa.data.Cascade.push({ Name: "zoneSpaceInBase" })
+          notEqInSpaceQuery(pa, res => {
+            this.getDataSuc(res, 'ZoneSpaceBaseIn')
+          })
+        } else {
+          pa.data.Cascade.push({ Name: "zoneSpaceForBase" })
+          notEqForSpaceQuery(pa, res => {
+            this.getDataSuc(res, 'ZoneSpaceBaseFor')
+          })
+        }
+      }
+    },
+    // 获取列表成功回调
+    getDataSuc(res, zonespacebase) {
+      let response = res.Content.map(t => {
+        let otherSpace = [];
+        if (t[zonespacebase] && t[zonespacebase].length) {
+          t[zonespacebase].map(item => {
+            otherSpace.push(item.RoomLocalName || item.RoomName)
+          })
+        }
+        t.linkOtherSpace = otherSpace.join(',');
+        return t;
+      })
+      this.tableData = res.Content;
+      this.page.total = res.Total;
+    },
+    //选中项修改
+    handleSelectionChange(val) {
+      this.selections = val;
+    },
+    // 确认 保存关系
+    savaRelation() {
+      let pa = {
+        data: {
+          SpaceId: this.spaceId,
+          EquipIdList: []
+        },
+        type: this.zone
+      }
+      this.selections.map(t => {
+        pa.data.EquipIdList.push(t.EquipID)
+      })
+      if (this.type == "Equipment") {
+        eqInSpaceCreate(pa, res => {
+          this.successCallback()
+        })
+      } else {
+        eqForSpaceCreate(pa, res => {
+          this.successCallback()
+        })
+      }
+    },
+    // 关联成功回调
+    successCallback() {
+      this.$message.success('关联成功');
+      this.$emit('refresh');
+      this.dialogVisible = false;
+    },
+    // 改变pagesize
+    handleSizeChange(pageSize) {
+      this.page.pageSize = pageSize;
+      this.getTableData();
+    },
+    // 改变pageno
+    handleCurrentChange(pageNo) {
+      this.page.pageNumber = pageNo;
+      this.getTableData();
+    },
+    // 查看详情
+    toDetail() {
+      this.$message('开发中')
+    }
+  },
+  watch: {
+    showType(n) {
+
+    }
+  }
+};
+</script>
+<style lang="less" scoped>
+#addEqDialog {
+  .filters {
+    margin-bottom: 10px;
+    /deep/ .el-input__inner {
+      vertical-align: baseline;
+    }
+  }
+  .table-box {
+    height: 350px;
+  }
+}
+</style>

+ 110 - 0
src/components/business_space/newAddDialogs/addSystemDialog.vue

@@ -0,0 +1,110 @@
+<template>
+  <el-dialog :title="title" :visible.sync="dialogVisible" width="800px" id="addSyDialog">
+    <div class="table-box">
+      <el-table :data="tableData" style="width: 100%" height="100%" v-loading="loading" :header-cell-style="headerStyle" ref="multipleTable"
+        @selection-change="handleSelectionChange">
+        <el-table-column type="selection" width="55"></el-table-column>
+        <el-table-column :label="`${inSpaceType}名称`" show-overflow-tooltip min-width="100">
+          <template slot-scope="scope">
+            <div>
+              {{scope.row.SysLocalName||scope.row.SysName||''}}
+            </div>
+          </template>
+        </el-table-column>
+        <el-table-column prop="SysLocalID" :label="`${inSpaceType}本地编码`" show-overflow-tooltip min-width="100"></el-table-column>
+        <el-table-column prop="action" label="操作" min-width="100">
+          <template slot-scope="scope">
+            <el-button size="mini" @click="toDetail(scope.$index, scope.row)" type="primary" plain>查看详情</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+    </div>
+    <span slot="footer" class="dialog-footer">
+      <el-button size="small" @click="dialogVisible = false">取 消</el-button>
+      <el-button size="small" type="primary" @click="savaRelation">确 定</el-button>
+    </span>
+  </el-dialog>
+</template>
+
+
+<script>
+import {
+  notSyInSpaceQuery, //没有和当前空间绑定的系统
+  syInSpaceCreate, //系统所在业务空间--创建关系
+} from "@/api/scan/request";
+export default {
+  data() {
+    return {
+      title: '添加空间内的系统',
+      inSpaceType: '系统',
+      dialogVisible: false,
+      tableData: [],
+      loading: false,
+      headerStyle: {
+        backgroundColor: '#e1e4e5',
+        color: '#2b2b2b',
+        lineHeight: '30px'
+      }, // 列表样式
+      selections: [], // 选中项
+    }
+  },
+  props: {
+    type: {}, //equipment--equipmentFor
+    spaceId: {},
+    zone: {}, //分区类型 
+  },
+  methods: {
+    // 显示
+    showDialog() {
+      this.dialogVisible = true;
+      this.getTableData();
+    },
+    // 选中项修改
+    handleSelectionChange(val) {
+      this.selections = val;
+    },
+    // 确认
+    savaRelation() {
+      let pa = {
+        data: {
+          SpaceId: this.spaceId,
+          SysIdList: []
+        },
+        type: this.zone
+      }
+      this.selections.map(t => {
+        pa.data.SysIdList.push(t.SysID)
+      })
+      syInSpaceCreate(pa, res => {
+        this.$message.success('关联成功');
+        this.$emit('refresh');
+        this.dialogVisible = false;
+      })
+    },
+    // 获取表格数据
+    getTableData() {
+      let pa = {
+        data: {
+          PageSize: 200,
+        },
+        type: this.zone,
+        spaceId: this.spaceId
+      }
+      notSyInSpaceQuery(pa, res => {
+        this.tableData = res.Content;
+      })
+    },
+    // 查看详情
+    toDetail() {
+      this.$message('开发中')
+    }
+  }
+}
+</script>
+<style lang="less" scoped>
+#addSyDialog {
+  .table-box {
+    height: 350px;
+  }
+}
+</style>

+ 145 - 0
src/components/business_space/newGraphy/canvasFun.vue

@@ -0,0 +1,145 @@
+<template>
+  <el-row id="canvas-actions-box" :class="{'isEdit':isEdit}">
+    <div :class="{'active':active=='move'}">
+      <i class="iconfont icon-move" @click="moveCanvas"></i>
+    </div>
+    <div>
+      <i class="iconfont icon-maximize" @click="fitToWindow"></i>
+    </div>
+    <div>
+      <el-dropdown size="mini" placement="top-start" @command="handleCommand">
+        <i class="el-icon-download" style="font-size:20px;color:#fff;"></i>
+        <el-dropdown-menu slot='dropdown'>
+          <el-dropdown-item command="savePng">保存为png</el-dropdown-item>
+          <el-dropdown-item command="saveSvg">保存为svg</el-dropdown-item>
+        </el-dropdown-menu>
+      </el-dropdown>
+    </div>
+    <div v-if="isEdit" :class="{'active':active=='divide'}">
+      <i class="iconfont icon-edit1" @click="divide"></i>
+    </div>
+    <div v-if="isEdit">
+      <i class="iconfont icon-Erase" @click="clearDivide"></i>
+    </div>
+    <div v-if="isEdit">
+      <i class="iconfont icon-Cancel" @click="undo"></i>
+    </div>
+    <div v-if="isEdit">
+      <i class="iconfont icon-Anti-cancel" @click="redo"></i>
+    </div>
+    <div>
+      <i class="iconfont icon-narrow" @click="reduce"></i>
+    </div>
+    <div class="line">
+      <el-slider tooltip-class="tooltip-class" :min="min" :max="maxScale" v-model="sliderVal" :show-tooltip="false" @input="scale"></el-slider>
+    </div>
+    <div>
+      <i class="iconfont icon-zoom" @click="plus"></i>
+    </div>
+  </el-row>
+</template>
+<script>
+export default {
+  data() {
+    return {
+      sliderVal: 0.004, // 滑块值
+      active: '',
+      min: 0.004,
+      maxScale: 1,
+    }
+  },
+  props: {
+    isEdit: {
+      default: false
+    }
+  },
+  methods: {
+    // 移动画布
+    moveCanvas() {
+      this.active = this.active != "move" ? "move" : '';
+      this.$emit('move', this.active == 'move');
+    },
+    // 适配大小
+    fitToWindow() {
+      this.$emit('fit');
+    },
+    // 下拉菜单
+    handleCommand(command) {
+      this.$emit(command)
+    },
+    // 切割编辑
+    divide() {
+      this.active = 'divide';
+      this.$emit('divide');
+    },
+    // 清除编辑
+    clearDivide() {
+      this.active = '';
+      this.$emit('clearDivide');
+    },
+    // 撤销
+    undo() {
+      this.$emit('undo');
+    },
+    // 反撤销
+    redo() {
+      this.$emit('redo');
+    },
+    // 减
+    reduce() {
+      this.sliderVal /= 1.1;
+      if (this.sliderVal < this.min) {
+        this.sliderVal = this.min;
+      }
+      this.scale(this.sliderVal);
+    },
+    // 缩放
+    scale(val) {
+      this.$emit('scale', val);
+    },
+    // 加
+    plus() {
+      this.sliderVal *= 1.1;
+      if (this.sliderVal > this.maxScale) {
+        this.sliderVal = this.maxScale;
+      }
+      this.scale(this.sliderVal);
+    }
+  }
+}
+</script>
+<style lang="less" scoped>
+#canvas-actions-box {
+  min-width: 542px;
+  & > div {
+    float: left;
+    font-size: 20px;
+    padding: 0 10px;
+    color: #fff;
+    background-color: #6da60f;
+    i {
+      cursor: pointer;
+    }
+  }
+  & > div.active {
+    background-color: #4b7902;
+  }
+  &.isEdit > div {
+    background-color: #02a7f0;
+  }
+  &.isEdit > div.active {
+    background-color: #027db4;
+  }
+  & > div.line {
+    width: 200px;
+    height: 40px;
+    padding: 0;
+    /deep/.el-slider__runway {
+      margin: 17px 0;
+      .el-slider__bar {
+        background-color: #fff;
+      }
+    }
+  }
+}
+</style>

+ 34 - 0
src/components/business_space/newGraphy/createBSP.vue

@@ -0,0 +1,34 @@
+<template>
+  <el-dialog :title="title" :visible.sync="dialogVisible" width="400px" id="createBSP">
+    <div>请输入创建的业务空间名:</div>
+    <el-input :placeholder="`请输入业务空间名称`" v-model="roomName"></el-input>
+    <span slot="footer" class="dialog-footer">
+      <el-button size="small" @click="dialogVisible=false">取 消</el-button>
+      <el-button size="small" type="primary" @click="confirm">确 定</el-button>
+    </span>
+  </el-dialog>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      title: '提示',
+      dialogVisible: false,
+      roomName: '',
+    };
+  },
+  methods: {
+    // 显示弹窗
+    showDialog(val) {
+      this.roomName = val;
+      this.dialogVisible = true;
+    },
+    // 确认
+    confirm() {
+      this.$emit('createRoom', this.roomName);
+      this.dialogVisible = false;
+    }
+  },
+};
+</script>

+ 566 - 0
src/components/business_space/newGraphy/graphy.vue

@@ -0,0 +1,566 @@
+<template>
+  <div id="graphy" ref="graphy">
+    <div v-show="!FloorMap">
+      <div class="center" style="height: 400px;padding-top:182px;box-sizing:border-box;">
+        <i class="icon-wushuju iconfont"></i>
+        暂无数据
+      </div>
+    </div>
+    <div class="canvas-box" v-show="FloorMap" v-loading="canvasLoading">
+      <canvas id="floorCanvas" :width="canvasWidth" :height="canvasHeight" ref="canvas" tabindex="0"></canvas>
+      <!-- 初始两个按钮 -->
+      <el-row class="buttons-box">
+        <div>
+          <el-autocomplete popper-class="my-autocomplete" v-model="search" :fetch-suggestions="querySearch" placeholder="输入平面图中已有的业务空间名称进行查找"
+            width="180px" @select="handleSelect">
+            <i class="el-icon-search el-input__icon" slot="suffix" @click="handleSelect"></i>
+            <template slot-scope="{ item }">
+              <div class="name" style="position: relative;">
+                {{ item.RoomLocalName | cutString(8) }}
+                <span class="addr" style="position: absolute;right:10px;color:#409EFF;">定位</span>
+              </div>
+            </template>
+          </el-autocomplete>
+        </div>
+        <div class="button-group">
+          <!-- 默认操作模式 -->
+          <div v-show="type==1">
+            <el-button @click="editGraphy">编辑平面图</el-button>
+          </div>
+          <!-- 点击已经关联的业务空间 -->
+          <div v-show="type==2">
+            <el-button type="primary" plain @click="refactorBSP">重新划分业务空间</el-button>
+            <el-button type="primary" @click="editeSpaceDetail">编辑空间详情</el-button>
+            <el-button plain @click="cancelGraphy">取 消</el-button>
+          </div>
+          <!-- 点击未关联的业务空间 -->
+          <div v-show="type==3">
+            <el-button plain @click="createNewZone">创建新的业务空间</el-button>
+            <el-button type="primary" @click="lookUnrelatBSpace(true)">从未关联平面图的业务空间中选择</el-button>
+            <el-button plain @click="cancelGraphy">取 消</el-button>
+          </div>
+          <!-- 重新划分业务空间 -->
+          <div v-show="type==4">
+            <el-button plain @click="cancelGraphy">取 消</el-button>
+            <el-button type="primary" @click="saveRefactorBSP">保存</el-button>
+          </div>
+        </div>
+        <div style="position: absolute;right: 0;">
+          <el-button type="text" @click="lookUnrelatBSpace(false)">未关联平面图的业务空间 {{num}} 条</el-button>
+        </div>
+      </el-row>
+      <!-- 底部操作按钮 -->
+      <el-row class="canvas-actions-box">
+        <canvasFun @move="moveCanvas" @fit="fit" @savePng="savePng" @saveSvg="saveSvg" @divide="divide" @clearDivide="clearDivide" @undo="undo"
+          @redo="redo" @scale="scale" :isEdit="isEdit" ref="canvasFun"></canvasFun>
+      </el-row>
+    </div>
+    <!--  -->
+    <!-- 未关联元空间的业务空间 -->
+    <unRelateBSP ref="unRelateBSP" :tableData="BSPUnrelaISPList" :isAction="isAction" @createFromUnrelated="createFromUnrelated"></unRelateBSP>
+    <!-- 创建新的业务空间 -->
+    <createBSP ref="createBSP" @createRoom="createRoom"></createBSP>
+  </div>
+</template>
+<script>
+import canvasFun from "./canvasFun"
+import { mapGetters, mapActions } from "vuex";
+import { SGraphyView } from "@sybotan-web/graphy/lib";
+import { DivideFloorScene, } from "cad-engine"
+import { SColor, SPoint } from "@sybotan-web/draw/lib";
+import { SpaceItem } from "cad-engine/lib/items/SpaceItem";
+import { ZoneItem } from "cad-engine/lib/items/ZoneItem";
+import unRelateBSP from "./unRelateBSP";
+import createBSP from "./createBSP";
+import {
+  countZone,
+  queryZone,
+  updateZone,
+  createZone,
+  createRelateInZoneAndISp
+} from "@/api/scan/request"
+const colorArr = [
+  "#F9C3C3",
+  "#FFD1BF",
+  "#FFF3BF",
+  "#D8F7C6",
+  "#C6F2F6",
+  "#DCE3C0",
+  "#FAE6C9",
+  "#E3D7F7",
+  "#C4CBF8",
+  "#DEC3F6"
+];
+//  BSP => 业务空间
+export default {
+  components: {
+    canvasFun,
+    unRelateBSP,
+    createBSP
+  },
+  data() {
+    return {
+      canvasWidth: 800,
+      canvasHeight: 600,
+      type: 1, // 默认操作模式
+      search: '',//搜索
+      num: 0, // 未关联空间的业务空间条数
+      buildFloor: [],
+      FloorMap: '',
+      tab: {},
+      isEdit: false,
+      canvasLoading: false,
+      view: null,
+      scene: null,
+      Outline: [], // 当前选中的多个空间组成的轮廓线->三维数组
+      businessSpaceList: [], // 所有业务空间
+      BSPUnrelaISPList: [], // 未关联元空间的业务空间
+      BSPRelaISPList: [], // 已关联元空间的业务空间
+      // 未关联元空间的业务空间弹窗
+      isAction: false,
+      curOutline: [],
+      BIMIDToSID: {}, //bimid映射元空间id
+      curZoneItem: {}, //当前选中的业务空间item
+    }
+  },
+  computed: {
+    ...mapGetters('layout', ['projectId'])
+  },
+  created() {
+  },
+  mounted() {
+    this.canvasWidth = this.$refs.graphy.offsetWidth;
+    this.canvasHeight = this.$refs.graphy.offsetHeight;
+  },
+  methods: {
+    // 初始化
+    init() {
+      this.type = 1;
+      // 获取当前分区下的业务空间
+      this.getBusinessSpace();
+      // 获取未关联平面图的业务空间统计
+      this.getUnrelateCount();
+      // 获取当前楼层的元空间
+      this.getFloorISpace();
+    },
+    // 获取当前楼层的元空间
+    getFloorISpace() {
+      let pa = {
+        zone: 'Ispace',
+        data: {
+          Filters: `FloorId='${this.buildFloor[1]}'`,
+          PageSize: 1000
+        }
+      }
+      queryZone(pa, res => {
+        this.BIMIDToSID = {}
+        res.Content.map(t => {
+          this.BIMIDToSID[t.BIMID.split(":")[1]] = t.RoomID;
+        })
+      })
+    },
+    // 搜索
+    querySearch(queryString, cb) {
+      var restaurants = this.BSPRelaISPList;
+      var results = queryString ?
+        restaurants.filter(this.createFilter(queryString)) :
+        restaurants;
+      // 调用 callback 返回建议列表的数据
+      cb(results);
+    },
+    // 过滤器
+    createFilter(queryString) {
+      return restaurant => {
+        return restaurant.RoomLocalName.indexOf(queryString) > -1;
+      };
+    },
+    // 查询选中
+    handleSelect(BSP) {
+      console.log(arguments)
+    },
+    // 父组件调用
+    getData(buildFloor, FloorMap, tab) {
+      this.buildFloor = buildFloor;
+      this.FloorMap = FloorMap;
+      this.tab = tab;
+      console.log(arguments)
+      this.init();
+    },
+    // 获取未关联平面图的业务空间统计
+    getUnrelateCount() {
+      let pa = {
+        data: {
+          Filters: `BuildingId='${this.buildFloor[0]}';FloorId='${this.buildFloor[1]}';Outline isNull`
+        },
+        zone: this.tab.code
+      }
+      countZone(pa, res => {
+        this.num = res.Count
+      })
+    },
+    // 获取未绑定业务空间的元空间
+    getISPSPUnrelaBSP() {
+
+    },
+    // 获取底图
+    getGraphy() {
+      let that = this;
+      that.clearGraphy()
+      that.view = new SGraphyView('floorCanvas')
+      that.scene = new DivideFloorScene();
+      that.canvasLoading = true;
+      that.scene.loadUrl(`/image-service/common/file_get?systemId=revit&key=${this.FloorMap}`).then(() => {
+        that.canvasLoading = false;
+        that.view.scene = that.scene;
+        let tempArr = this.BSPRelaISPList.map((t, i) => {
+          return {
+            RoomLocalName: t.RoomLocalName,
+            OutLine: t.Outline,
+            RoomID: t.RoomID,
+            Color: new SColor(colorArr[i % colorArr.length]),
+          }
+        })
+        that.scene.addZoneList(tempArr);
+        that.scene.click(that, that.canvasClick)
+        that.view.fitSceneToView();
+      })
+    },
+    // 获取当前分区下的业务空间
+    getBusinessSpace() {
+      this.isLoading = true
+      let pa = {
+        zone: this.tab.code,
+        data: {
+          Filters: ``,
+          Orders: "createTime desc, RoomID asc",
+          PageSize: 500
+        }
+      }
+      if (this.buildFloor.length && this.buildFloor.length > 1) {
+        pa.data.Filters = `BuildingId='${this.buildFloor[0]}';FloorId='${this.buildFloor[1]}'`
+      }
+      queryZone(pa, res => {
+        // 所有业务空间
+        this.businessSpaceList = res.Content;
+        // 未关联元空间的业务空间
+        this.BSPUnrelaISPList = [];
+        // 已关联元空间的业务空间
+        this.BSPRelaISPList = [];
+        res.Content.map(t => {
+          if (t.Outline && t.Outline.length) {
+            this.BSPRelaISPList.push(t)
+          } else {
+            this.BSPUnrelaISPList.push(t)
+          }
+        })
+        // 获取底图
+        this.getGraphy();
+        this.isLoading = false;
+      })
+    },
+    // canvas点击事件
+    canvasClick(item, event) {
+      console.log(arguments)
+      this.scene.setSpaceSelectable(true);
+      this.scene.setZoneSelectable(true);
+      if (this.type == 4) {
+
+      } else {
+        if (item instanceof SpaceItem) {
+          this.type = 3;
+          this.curZoneItem = {};
+          this.scene.setZoneSelectable(false);
+        }
+        if (item instanceof ZoneItem) {
+          this.type = 2;
+          this.curZoneItem = item;
+          this.scene.setSpaceSelectable(false);
+        }
+      }
+    },
+    // 编辑平面图
+    editGraphy() {
+      this.type = 3;
+    },
+    // 查看未关联的业务空间--flag--查看-or-选择
+    lookUnrelatBSpace(flag) {
+      this.isAction = flag;
+      let arr = this.scene.getSelectedSpaces();
+      if (flag && !arr.length) {
+        this.$message.warning('请至少选择一个空间');
+        return;
+      }
+      this.$refs.unRelateBSP.showDialog();
+    },
+    // 取消(所有取消公用)
+    cancelGraphy() {
+      this.type = 1;
+      this.init();
+    },
+    // 批量创建业务空间
+    groupCreateBSpace() {
+      let text = []
+      let Spaces = this.scene.spaceList.map(t => {
+        text.push(t.data.Name)
+        return {
+          RoomLocalName: t.data.Name,
+          Outline: [t.data.OutLine]
+        }
+      });
+      console.log(Spaces)
+      console.log(this.scene.spaceList)
+      // return
+      this.$confirm(
+        "<p>确定根据未关联业务空间的空间批量创建业务空间</p>" +
+        "<p>涉及的空间:</p>" +
+        "<p style='line-height:20px;max-height:60px;overflow-y:auto;'>" +
+        text.toString() +
+        "</p>",
+        "提示", {
+        dangerouslyUseHTMLString: true,
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning"
+      }
+      ).then(() => {
+        console.log()
+        let pa = {
+          zone: this.zoneCode,
+          data: {
+            Content: Spaces
+          }
+        }
+        createZone(pa, res => {
+
+        })
+      }).catch(() => {
+        this.$message({
+          type: "info",
+          message: "已取消批量创建"
+        });
+      });
+    },
+    // 创建新的业务空间
+    createNewZone() {
+      let arr = this.scene.getSelectedSpaces();
+      if (arr.length) {
+        let tempArr = [];
+        arr.map(t => {
+          tempArr.push(t.data.Name);
+        })
+        this.$refs.createBSP.showDialog(tempArr.toString());
+      } else {
+        this.$message.warning('请至少选择一个空间');
+      }
+    },
+    // 创建新的业务空间-弹窗返回确认创建
+    createRoom(val) {
+      let arr = this.scene.getSelectedSpaces();
+      let zoneObj = { Outline: [] }, IspaceIdList = [];
+      arr.map(t => {
+        zoneObj.Outline.push(t.data.OutLine);
+        IspaceIdList.push(this.BIMIDToSID[t.data.SourceId])
+      })
+      zoneObj.RoomLocalName = val;
+      zoneObj.BuildingId = this.buildFloor[0];
+      zoneObj.FloorId = this.buildFloor[1];
+      let pa = {
+        zone: this.tab.code,
+        data: {
+          Content: [zoneObj]
+        }
+      }
+      createZone(pa, res => {
+        this.relationInBSPandISP(res.EntityList[0].RoomID, IspaceIdList)
+      })
+    },
+    // 从未关联平面图的业务空间中选择--按钮返回关联信号
+    createFromUnrelated(BSP) {
+      BSP.Outline = []
+      let arr = this.scene.getSelectedSpaces();
+      arr.map(t => {
+        BSP.Outline.push(t.data.OutLine);
+      })
+      let pa = {
+        zone: BSP.ObjectType,
+        data: {
+          Content: [BSP],
+          Projection: ['Outline']
+        }
+      }
+      updateZone(pa, res => {
+        this.$message.success('更新成功');
+        this.init();
+      })
+    },
+    // 编辑空间详情
+    editeSpaceDetail() {
+      let item = this.curZoneItem.data;
+      this.$router.push({
+        path: "/ledger/spaceDetail",
+        query: { RoomID: item.RoomID, zone: this.zoneCode, isMyTab: 1 }
+      })
+    },
+    // 重新划分业务空间
+    refactorBSP() {
+      this.type = 4;
+      // 设置空间可选
+      this.scene.setSpaceSelectable(true);
+      // 将已关联的设置不可选,并将当前选的隐藏
+      this.scene.changeSelectZone(this.curZoneItem);
+    },
+    // 重新划分--保存
+    saveRefactorBSP() {
+      let arr = this.scene.getSelectedSpaces();
+      //更新业务空间
+      let zoneObj = { Outline: [] }, IspaceIdList = [];
+      arr.map(t => {
+        zoneObj.Outline.push(t.data.OutLine);
+        IspaceIdList.push(this.BIMIDToSID[t.data.SourceId])
+      })
+      zoneObj.RoomID = this.curZoneItem.data.RoomID;
+      let pa = {
+        zone: this.tab.code,
+        data: {
+          Content: [zoneObj]
+        },
+        Projection: ['Outline']
+      }
+      updateZone(pa, res => {
+        this.relationInBSPandISP(zoneObj.RoomID, IspaceIdList)
+      })
+    },
+    // 更新业务空间和元空间的关系
+    relationInBSPandISP(SpaceId, IspaceIdList) {
+      let pa = { SpaceId: SpaceId, IspaceIdList: IspaceIdList }
+      createRelateInZoneAndISp(pa, res => {
+        this.$message.success('创建成功');
+        this.init();
+      })
+    },
+    // canvas 获取焦点
+    focus() {
+      document.getElementById(`floorCanvas`).focus()
+    },
+    // 清除canvas
+    clearGraphy() {
+      if (this.view) {
+        this.view = null;
+        this.scene.root.children = null;
+        this.scene = null;
+      }
+    },
+    // 工具栏操作
+    // 移动底图
+    moveCanvas(move) {
+      // todo
+      let canvas = document.getElementById(`floorCanvas`);
+      if (move) {
+        canvas.style.cursor = 'move';
+      } else {
+        canvas.style.cursor = 'default';
+      }
+    },
+    // 适配底图到窗口
+    fit() {
+      this.view.fitSceneToView()
+    },
+    // 保存为png
+    savePng() {
+      this.view.saveImage(`${this.floor}.png`, 'png');
+    },
+    // 保存为svg
+    saveSvg() {
+      this.view.saveSceneSvg(`${this.floor}.png`, 6400, 4800);
+    },
+    // 切割划分
+    divide() {
+      this.drawMainScene.isMarking = true;
+    },
+    // 清除切割划分
+    clearDivide() {
+      this.drawMainScene.clearSceneMark()
+    },
+    // 撤销
+    undo() {
+
+    },
+    // 反撤销
+    redo() { },
+    // 缩放
+    scale(val) {
+      // let scale = this.view.scale
+      // this.view.scaleByPoint(val / scale, this.cadWidth / 2, this.cadHeight / 2)
+    },
+  },
+  filters: {
+    cutString: function (str, len) {
+      //length属性读出来的汉字长度为1
+      if (!!str && typeof str == "string" && str.length > len) {
+        return str.substring(0, len) + "...";
+      } else {
+        return str || "--";
+      }
+    }
+  },
+  watch: {
+    projectId() {
+      this.FloorMap = '';
+      this.tab = {};
+    }
+  }
+}
+</script>
+<style lang="less" scoped>
+#graphy {
+  position: relative;
+  width: 100%;
+  height: calc(100% - 56px);
+  .canvas-box {
+    width: 100%;
+    height: 100%;
+  }
+  .buttons-box {
+    position: absolute;
+    top: 0;
+    width: 100%;
+    z-index: 999;
+    & > div {
+      float: left;
+    }
+    /deep/ .el-autocomplete {
+      display: block;
+      width: 320px;
+      margin-right: 10px;
+    }
+    .button-group button {
+      display: block;
+      float: left;
+    }
+    .my-autocomplete {
+      li {
+        line-height: normal;
+        padding: 7px;
+        .name {
+          text-overflow: ellipsis;
+          overflow: hidden;
+        }
+        .addr {
+          font-size: 12px;
+          color: #b4b4b4;
+        }
+        .highlighted .addr {
+          color: #ddd;
+        }
+      }
+    }
+  }
+  .canvas-actions-box {
+    position: absolute;
+    bottom: 20px;
+    left: 50%;
+    transform: translateX(-50%);
+    z-index: 999;
+  }
+}
+</style>

+ 67 - 0
src/components/business_space/newGraphy/unRelateBSP.vue

@@ -0,0 +1,67 @@
+<template>
+  <el-dialog :title="title" :visible.sync="dialogVisible" width="600px" id="lookUnrelatBSpace">
+    <el-input :placeholder="`请输入业务空间名称`" v-model="queryString" @keyup.enter.native="queryTableData">
+      <i slot="suffix" class="el-input__icon el-icon-search" @click="queryTableData"></i>
+    </el-input>
+    <div style="margin-top:10px;height:300px;">
+      <el-table :data="data" style="width: 100%" height="100%" v-loading="loading" :header-cell-style="headerStyle">
+        <el-table-column prop="RoomLocalName" label="业务空间名称" show-overflow-tooltip min-width="200"></el-table-column>
+        <el-table-column prop="action" label="操作" min-width="100" v-if="isAction">
+          <template slot-scope="scope">
+            <el-button @click="createRelation(scope.row)">关联平面图</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+    </div>
+  </el-dialog>
+</template>
+
+<script>
+export default {
+  name: "unRelateBSP",
+  data() {
+    return {
+      title: '未关联平面图的业务空间',
+      dialogVisible: false,
+      loading: false,
+      headerStyle: {
+        backgroundColor: '#e1e4e5',
+        color: '#2b2b2b',
+        lineHeight: '30px'
+      },
+      queryString: '',
+      data: []
+    };
+  },
+  props: {
+    tableData: {
+      default: []
+    }, //列表数据
+    isAction: false, //是否显示操作按钮
+  },
+  methods: {
+    // 显示弹窗
+    showDialog() {
+      this.data = this.tableData;
+      this.dialogVisible = true;
+    },
+    // 搜索
+    queryTableData() {
+      var restaurants = this.tableData;
+      this.data = this.queryString ?
+        restaurants.filter(this.createFilter(this.queryString)) :
+        restaurants;
+    },
+    createFilter(queryString) {
+      return restaurant => {
+        return restaurant.RoomLocalName.indexOf(queryString) > -1;
+      };
+    },
+    // 关联平面图
+    createRelation(row) {
+      this.$emit('createFromUnrelated', row);
+      this.dialogVisible = false;
+    }
+  },
+};
+</script>

+ 172 - 0
src/components/business_space/newTables/eqToSpaceTable.vue

@@ -0,0 +1,172 @@
+<template>
+  <div id="eqInSp">
+    <el-row>
+      <el-button type="primary" @click="add">添加{{inSpaceType}}</el-button>
+      <el-tooltip class="item" effect="dark" :content="`可前往“全部关系总览”中,按坐标计算${typeToTips[type]}`" placement="right">
+        <el-button>按空间计算</el-button>
+      </el-tooltip>
+    </el-row>
+    <div class="table-box">
+      <el-table :data="tableData" style="width: 100%" height="100%" v-loading="loading" :header-cell-style="headerStyle">
+        <el-table-column :label="`${inSpaceType}名称`" show-overflow-tooltip min-width="100">
+          <template slot-scope="scope">
+            <div>
+              {{scope.row.EquipLocalName||scope.row.EquipName||''}}
+            </div>
+          </template>
+        </el-table-column>
+        <el-table-column prop="EquipLocalID" :label="`${inSpaceType}本地编码`" show-overflow-tooltip min-width="100"></el-table-column>
+        <el-table-column :label="`${inSpaceType}类`" show-overflow-tooltip min-width="100">
+          <template slot-scope="scope">
+            <div>
+              {{scope.row.EquipCategory.EquipName}}
+            </div>
+          </template>
+        </el-table-column>
+        <el-table-column prop="action" label="操作" min-width="100">
+          <template slot-scope="scope">
+            <el-tooltip class="item" effect="dark" content="删除关系" placement="left">
+              <el-button size="mini" @click="handleDelete(scope.$index, scope.row)" type="danger" plain icon="el-icon-delete"></el-button>
+            </el-tooltip>
+          </template>
+        </el-table-column>
+        <template slot="empty">
+          <div style="height: 60%;transform: translateY(50%);">
+            <i class="icon-wushuju iconfont"></i>
+            可前往“全部关系总览”中,按坐标计算{{typeToTips[type]}}
+          </div>
+        </template>
+      </el-table>
+    </div>
+    <!-- 添加设备弹窗 -->
+    <addEquipDialog ref="addEqDialog" :type="type" :spaceId="params.RoomID" :zone="params.zone" @refresh='getTableData'></addEquipDialog>
+  </div>
+</template>
+
+<script>
+import {
+  queryZone,
+  eqInSpaceDelete, //设备所在业务空间--删除关系
+  eqForSpaceDelete, //设备服务业务空间--删除关系
+} from "@/api/scan/request";
+import { mapGetters } from "vuex";
+import addEquipDialog from "@/components/business_space/newAddDialogs/addEquipDialog"
+export default {
+  components: {
+    addEquipDialog
+  },
+  computed: {
+    ...mapGetters("layout", ["projectId"])
+  },
+  data() {
+    return {
+      inSpaceType: '设备',
+      headerStyle: {
+        backgroundColor: '#e1e4e5',
+        color: '#2b2b2b',
+        lineHeight: '30px'
+      }, // 列表样式
+      loading: false, // loading
+      tableData: [], //列表数据
+      typeToTips: {
+        Equipment: '空间内的设备',
+        EquipmentFor: '服务于空间的设备',
+      }
+    };
+  },
+  props: {
+    params: {},
+    type: {}
+  },
+  created() {
+    this.getTableData()
+  },
+  methods: {
+    // 删除关系
+    handleDelete(index, row) {
+      this.$confirm("确认删除该关系?", "提示", {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        let pa = {
+          data: [row],
+          type: this.params.zone
+        }
+        if (this.type == 'Equipment') {
+          this.deleteEqInSpace(pa);
+        } else {
+          this.deleteEqForSpace(pa);
+        }
+      }).catch(() => {
+        this.$message("取消删除")
+      })
+    },
+    // 删除设备所在空间关系
+    deleteEqInSpace(pa) {
+      eqInSpaceDelete(pa, res => {
+        this.$message.success('删除成功')
+        this.getTableData()
+      })
+    },
+    // 删除设备服务空间关系
+    deleteEqForSpace(pa) {
+      eqForSpaceDelete(pa, res => {
+        this.$message.success('删除成功')
+        this.getTableData()
+      })
+    },
+    // 改变pagesize
+    handleSizeChange(pageSize) {
+      this.page.pageSize = pageSize;
+      this.getTableData();
+    },
+    // 改变pageno
+    handleCurrentChange(pageNo) {
+      this.page.pageNumber = pageNo;
+      this.getTableData();
+    },
+    // 获取列表数据
+    getTableData() {
+      let pa = {
+        data: {
+          Filters: `RoomID='${this.params.RoomID}'`,
+          Cascade: [
+            {
+              Name: this.type.replace(this.type[0], this.type[0].toLowerCase()),
+              Cascade: [{ Name: 'equipCategory' }]
+            }
+          ]
+        },
+        zone: this.params.zone
+      }
+      queryZone(pa, res => {
+        this.tableData = res.Content[0][this.type] || []
+        this.tableData.map(t => {
+          t.SpaceId = res.Content[0].RoomID
+          return t;
+        })
+      })
+    },
+    // 添加设备
+    add() {
+      this.$refs.addEqDialog.floor = [this.params.BuildingId, this.params.FloorId];
+      this.$refs.addEqDialog.showDialog()
+    }
+  },
+  watch: {
+    type() {
+      this.getTableData()
+    }
+  }
+};
+</script>
+<style lang="less" scoped>
+#eqInSp {
+  height: 100%;
+  .table-box {
+    margin-top: 10px;
+    height: calc(100% - 50px);
+  }
+}
+</style>

+ 135 - 0
src/components/business_space/newTables/syInSpaceTable.vue

@@ -0,0 +1,135 @@
+<template>
+  <div id="eqInSp">
+    <el-row>
+      <el-button type="primary" @click="add">添加{{inSpaceType}}</el-button>
+      <el-tooltip class="item" effect="dark" :content="`可前往“全部关系总览”中,按坐标计算${typeToTips[type]}`" placement="right">
+        <el-button>按空间计算</el-button>
+      </el-tooltip>
+    </el-row>
+    <div class="table-box">
+      <el-table :data="tableData" style="width: 100%" height="100%" v-loading="loading" :header-cell-style="headerStyle">
+        <el-table-column :label="`${inSpaceType}名称`" show-overflow-tooltip min-width="100">
+          <template slot-scope="scope">
+            <div>
+              {{scope.row.SysLocalName||scope.row.SysName}}
+            </div>
+          </template>
+        </el-table-column>
+        <el-table-column prop="SysLocalID" :label="`${inSpaceType}本地编码`" show-overflow-tooltip min-width="100"></el-table-column>
+        <el-table-column prop="action" label="操作" min-width="100">
+          <template slot-scope="scope">
+            <el-tooltip class="item" effect="dark" content="删除关系" placement="left">
+              <el-button size="mini" @click="handleDelete(scope.$index, scope.row)" type="danger" plain icon="el-icon-delete"></el-button>
+            </el-tooltip>
+          </template>
+        </el-table-column>
+        <template slot="empty">
+          <div style="height: 60%;transform: translateY(50%);">
+            <i class="icon-wushuju iconfont"></i>
+            可前往“全部关系总览”中,按坐标计算{{typeToTips[type]}}
+          </div>
+        </template>
+      </el-table>
+    </div>
+    <addSystemDialog ref="addSyDialog" :type="type" :spaceId="params.RoomID" :zone="params.zone" @refresh='getTableData'></addSystemDialog>
+  </div>
+</template>
+
+<script>
+import {
+  queryZone,
+  syInSpaceDelete
+} from "@/api/scan/request";
+import { mapGetters } from "vuex";
+import addSystemDialog from "@/components/business_space/newAddDialogs/addSystemDialog";
+export default {
+  components: {
+    addSystemDialog
+  },
+  computed: {
+    ...mapGetters("layout", ["projectId"])
+  },
+  data() {
+    return {
+      inSpaceType: '系统',
+      headerStyle: {
+        backgroundColor: '#e1e4e5',
+        color: '#2b2b2b',
+        lineHeight: '30px'
+      }, // 列表样式
+      loading: false, // loading
+      tableData: [], //列表数据
+      typeToTips: {
+        generalSystem: '空间内的系统',
+      }
+    };
+  },
+  props: {
+    params: {},
+    type: {}
+  },
+  created() {
+    this.getTableData()
+  },
+  methods: {
+    // 删除关系
+    handleDelete(index, row) {
+      this.$confirm("确认删除该关系?", "提示", {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        let pa = {
+          data: [row],
+          type: this.params.zone
+        }
+        this.deleteSyInSpace(pa)
+      }).catch(() => {
+        this.$message("取消删除")
+      })
+    },
+    // 删除关系
+    deleteSyInSpace(pa){
+      syInSpaceDelete(pa, res => {
+        this.$message.success('删除成功');
+        this.getTableData();
+      })
+    },
+    // 获取列表数据
+    getTableData() {
+      let pa = {
+        data: {
+          Cascade: [{ Name: "generalSystem" }],
+          Filters: `RoomID="${this.params.RoomID}"`,
+        },
+        zone: this.params.zone
+      }
+      queryZone(pa, res => {
+        this.tableData = res.Content[0].GeneralSystem || [];
+        this.tableData.map(t => {
+          t.SpaceId = res.Content[0].RoomID;
+          return t;
+        })
+      })
+    },
+    // 添加系统
+    add() {
+      this.$refs.addSyDialog.showDialog()
+    }
+  },
+  watch: {
+    type() {
+      this.getTableData()
+    }
+  }
+};
+</script>
+<style lang="less" scoped>
+#eqInSp {
+  height: 100%;
+  .table-box {
+    margin-top: 10px;
+    height: calc(100% - 50px);
+  }
+}
+</style>

+ 1 - 1
src/components/business_space/table/businessTable.vue

@@ -72,7 +72,7 @@ export default {
     return {
       page: {
         size: 50,
-        sizes: [10, 30, 50, 100, 150, 200],
+        sizes: [50, 100, 150, 200],
         total: 1,
         currentPage: 1
       },

+ 1 - 1
src/components/model/file/floorTable.vue

@@ -91,7 +91,7 @@ export default {
     },
     // 替换日志
     repliaceModel(item) {
-      if (item.Status != 4) {
+      if (item.Status != 4 && item.Status != 21) {
         this.$alert("正在识别模型对象,请稍后再替换。", "替换模型", {
           confirmButtonText: "确定",
           callback: action => {

+ 12 - 5
src/router/system.js

@@ -60,6 +60,7 @@ import rentadd from '@/views/ledger/rentlist/rentadd' //竖井清单
 import dataReport from '@/views/ledger/report'
 import auth from '@/views/system/auth'
 import noUser from '@/views/system/nouser'
+import spaceDetail from '@/views/ledger/spacelist/spaceDetail'
 
 /**  关系维护并计算 */
 import maintain from '@/views/relation/maintain'
@@ -94,11 +95,11 @@ export default [
         name: 'LayoutMain',
         component: LayoutMain,
         children: [
-            // { path: 'buildfloor', name: 'buildFloor', component: buildFloor, meta: { keepAlive: false, breadcrumbs: [{ label: '建筑楼层管理' }] } },
-            { path: 'buildfloor', name: 'buildFloor', component: Dasboard, meta: { keepAlive: false, breadcrumbs: [{ label: '建筑楼层管理' }] } },
+            { path: 'buildfloor', name: 'buildFloor', component: buildFloor, meta: { keepAlive: false, breadcrumbs: [{ label: '建筑楼层管理' }] } },
+            // { path: 'buildfloor', name: 'buildFloor', component: Dasboard, meta: { keepAlive: false, breadcrumbs: [{ label: '建筑楼层管理' }] } },
             { path: 'collectsetting', name: 'collectsetting', component: collectsetting, meta: { keepAlive: false, breadcrumbs: [{ label: '需采集的信息点' }] } },
             { path: 'appuser', name: 'buildUser', component: buildUser, meta: { keepAlive: false, breadcrumbs: [{ label: '扫楼App用户管理' }] } },
-            { path: 'buildfloor/repetitionGraphy', name: 'repetitionGraphy', component: repetitionGraphy, meta: { keepAlive: false, breadcrumbs: [{ label: '建筑楼层管理', path: '/ready/buildfloor' }, { label:'平面图维护' }] }}
+            { path: 'repetitionGraphy', name: 'repetitionGraphy', component: repetitionGraphy, meta: { keepAlive: false, breadcrumbs: [{ label: '建筑楼层管理', path: '/ready/buildfloor' }, { label:'平面图维护' }] }}
         ]
     },
     //模型管理
@@ -111,8 +112,8 @@ export default [
             {
                 path: 'file',
                 name: 'modelFile',
-                component: Dasboard,
-                // component: modelFile,
+                // component: Dasboard,
+                component: modelFile,
                 meta: { keepAlive: false, breadcrumbs: [{ label: '模型管理', path: '/model/file' }, { label: '模型文件管理' }] }
             },
             {
@@ -295,6 +296,12 @@ export default [
                 meta: { keepAlive: false, breadcrumbs: [{ label: '台账管理', path: '/ledger/facility' }, { label: '业务空间台账' }] }
             },
             {
+                path: 'spaceDetail',
+                name: 'spaceDetail',
+                component: spaceDetail,
+                meta: { keepAlive: false, breadcrumbs: [{ label: '台账管理', path: '/ledger/facility' }, { label: '业务空间台账',path: '/ledger/spacelist' }, {label:'业务空间详情'}] }
+            },
+            {
                 path: 'cenotelist',
                 name: 'cenotelist',
                 component: cenotelist,

+ 156 - 334
src/views/ledger/spacelist/index.vue

@@ -4,80 +4,67 @@
 <template>
   <div id="businessSpace">
     <!------------------------    头部弹窗,选择楼层信息     -------------->
-    <!-- <no-model-dialog :param="param" title="选择要进行空间管理的楼层" :isShow="floor" @close="close"></no-model-dialog> -->
     <influence-dialog ref="influence" :param="param" :tabsList="tabsList" title="受元空间变化影响的业务空间" :isShow="floor"></influence-dialog>
-    <details-dialog ref="details" @del="delSuccess" :param="param" :tabsList="tabsList" title="业务空间详情" :isShow="floor" :activeTabType="activeTabType"></details-dialog>
+    <details-dialog ref="details" @del="delSuccess" :param="param" :tabsList="tabsList" title="业务空间详情" :isShow="floor" :activeTabType="activeTabType">
+    </details-dialog>
     <not-related ref="notRelated" @createSuccess="createSuccess" :isShow="floor"></not-related>
     <facility-dialog ref="facility" :activeTabType="activeTabType" :isShow="floor"></facility-dialog>
     <!--------- 页面头部   -------------->
     <div class="saga-title">
-      <!-- <div class="saga-build-mess">
-                <p>
-                    <i class="iconfont icon-jianzhu"></i> {{buildMess.buildName}} - {{buildMess.name}}
-                </p>
-                <el-button class="saga-btn" type="text" @click="changeShow">切换楼层</el-button>
-            </div> -->
       <div class="saga-build-mess">
         <span style="padding-right:12px;color:#999999;">建筑楼层</span>
-        <el-cascader :options="options" v-model="buildMess.selectd" :props="props" @change="close"></el-cascader>
+        <el-cascader :options="options" v-model="buildFloorSelectd" :props="props" @change="changeCascader"></el-cascader>
       </div>
       <div class="saga-build-tab">
-        <!-- <div class="tab-main" @click="tabList(1)" :class="isMyTab == 1 ? 'tab-active' : ''">
-                    <i class="iconfont icon-tupian"></i>
-                    <span>平面图</span>
-                </div>
-                <div class="tab-main" @click="tabList(2)" :class="isMyTab == 2 ? 'tab-active' : ''">
-                    <i class="iconfont icon-liebiao"></i>
-                    <span>列表</span>
-                </div> -->
         <el-radio-group v-model="isMyTab" @change="changeRadio" style="width: 136px;">
           <el-radio-button label="1">平面图</el-radio-button>
           <el-radio-button label="2" class="space-own-radio" style="width: 68px;">列表</el-radio-button>
         </el-radio-group>
       </div>
     </div>
-    <div v-show="isMyTab == 1" class="saga-business-sapce-main">
-      <el-tabs v-model="activeName" @tab-click="tab1Click">
-        <template v-for="(item,index) in tabsList">
-          <el-tab-pane :name="item.code" :key="index" :disabled="item.code > 3">
-            <span slot="label">{{item.name}}</span>
-            <graphy @getSp="checkSpace" @dimension="checkSpace" @businessDetails="getBuinessDetails"
-              :ref="'graphy' + item.code" :canvasId="item.code"></graphy>
-          </el-tab-pane>
-        </template>
-      </el-tabs>
-      <!-- <space-graphy @dimension="checkSpace" :tabsList="tabsList" ref="graphy" :param="param"></space-graphy> -->
-    </div>
-    <div v-show="isMyTab == 2" class="saga-business-sapce-main">
-      <el-tabs v-model="activeName" @tab-click="handleClick">
-        <template v-for="(item,index) in tabsList">
-          <el-tab-pane :name="item.code" :key="index" :disabled="item.code > 3">
-            <span slot="label">{{item.name}}</span>
-            <handsontable-main @lookEqu="lookEqu" :ref="'handsontable' + item.code" :zoneObj="item" :id="'handsontable' + item.code" :param="param"></handsontable-main>
-          </el-tab-pane>
-        </template>
-      </el-tabs>
-      <!-- <space-handsontable :tabsList="tabsList" ref="spaceTable" :param="param"></space-handsontable> -->
+    <div class="saga-business-sapce-main">
+      <el-row class="spaceTypes">
+        <div class="types">
+          <el-tabs v-model="activeName" type='card' @tab-click="tabClick">
+            <template v-for="(item,index) in tabsList">
+              <el-tab-pane :name="item.Code" :key="index" :label="item.Name"></el-tab-pane>
+            </template>
+          </el-tabs>
+        </div>
+        <div class="groupAdd">
+          <el-button size="small" @click="groupCreateBSpace">批量创建业务空间</el-button>
+        </div>
+      </el-row>
+      <div v-show="isMyTab == 1" style="width:100%;height:100%">
+        <graphy @getSp="checkSpace" @dimension="checkSpace" @businessDetails="getBuinessDetails" ref="graphy"></graphy>
+      </div>
+      <div v-show="isMyTab == 2">
+        <handsontable-main @lookEqu="lookEqu" ref="handsontable" :zoneCode="activeName" :id="`handsontable${activeName}`"></handsontable-main>
+      </div>
     </div>
   </div>
 </template>
-
 <script>
 import noModelDialog from "@/components/business_space/dialogs/noModelDialog";
 import influenceDialog from "@/components/business_space/dialogs/influenceDialog";
 import detailsDialog from "@/components/business_space/dialogs/detailsDialog";
 import notRelated from "@/components/business_space/dialogs/notRelated";
 import facilityDialog from "@/components/business_space/dialogs/facilityDialog";
-// import spaceHandsontable from "@/components/business_space/business/spaceHandsontable";
-import graphy from "@/components/business_space/graphy/business";
+// import graphy from "@/components/business_space/graphy/business";
+import graphy from "@/components/business_space/newGraphy/graphy";
 import handsontableMain from "@/components/business_space/business/handsontable";
-import { getDataDictionary, getAllbusiness, getBussTypes, getSpaceFloor, buildingQuery, floorQuery } from "@/api/scan/request";
+import {
+  getDataDictionary,
+  getAllbusiness,
+  getSpaceFloor,
+  buildingQuery, //数据中心-建筑查询
+  queryDictionaryHead, //数据中心-字典头部信息查询接口
+} from "@/api/scan/request";
 import tools from '@/utils/scan/tools'
 import { mapGetters, mapActions } from "vuex";
 export default {
   components: {
     noModelDialog,
-    // spaceHandsontable,
     influenceDialog,
     detailsDialog,
     notRelated,
@@ -91,7 +78,6 @@ export default {
   data() {
     return {
       floor: {
-        // dialogVisible: true, //选择楼层弹窗
         influence: false, //受影响的业务空间弹窗
         details: false, //详情弹窗
         notRelated: false,
@@ -112,203 +98,138 @@ export default {
         buildCode: ""
       },
       isMyTab: 1,
-      activeName: "GeneralZone",
+      activeName: "0",
       tabsList: [],
       activeTabType: {
         "code": "GeneralZone",
         "name": "默认分区",
         "rel_type": "99"
       },
-      options: [],
-      props: {
-        value: "code",
-        label: "name",
-        children: "children"
-      }
+      options: [], //建筑楼层级联下拉
+      props: { //自定义字段
+        value: "BuildID",
+        label: "BuildLocalName",
+        children: "Floor"
+      },
+      floorToMap: {}, //楼层及其对应的模型图
+      FloorMap: "", //当前选中的楼层平面图
+      buildFloorSelectd: [], //当前所选的建筑楼层
     };
   },
   created() {
-    this.changeData()
+    this.init();
+    let params = this.$route.params;
+    if (params.BuildingId) {
+      this.buildFloorSelectd = [params.BuildingId, params.FloorId];
+      this.activeName = params.zone;
+      this.isMyTab = params.isMyTab;
+      this.changeRadio(this.isMyTab)
+    }
   },
   mounted() { },
   methods: {
-    changeData() {
-      this.param.ProjId = this.projectId
-      this.param.UserId = this.userId
-      this.param.secret = this.secret
-      this.getFloor()
+    // 初始化
+    init() {
       this.getTypes()
+      this.getBuilding()
     },
-    changeRadio() {
-      if (!this.buildMess.selectd.length) {
-        this.$message("请选择楼层")
-        return false
+    // 获取项目下建筑
+    getBuilding() {
+      let pa = {
+        Cascade: [{ name: 'floor', Orders: 'SequenceId desc' }],
+        Orders: "BuildLocalName asc",
       }
-      this.tabClick(this.isMyTab)
+      buildingQuery(pa, res => {
+        this.options = res.Content.map(t => {
+          if (t.Floor) {
+            t.Floor = t.Floor.map(item => {
+              item.BuildID = item.FloorID;
+              item.BuildLocalName = item.FloorLocalName;
+              this.floorToMap[item.FloorID] = item.StructureInfo ? item.StructureInfo.FloorMap : '';
+              return item;
+            })
+          } else {
+            t.Floor = []
+          }
+          return t;
+        })
+      })
     },
-    //获取楼层
-    getFloor() {
-      // let data, buildParams = {
-      //   PageNumber: 1,
-      //   PageSize: 500
-      // }, floorParams = {
-      //   Orders: "FloorSequenceID desc",
-      //   PageNumber: 1,
-      //   PageSize: 500
-      // }
-      // let promise1 = new Promise((resolve, reject) => {
-      //   buildingQuery(buildParams, res => {
-      //     resolve(res)
-      //   })
-      // })
-      // let promise2 = new Promise((resolve, reject) => {
-      //   floorQuery(floorParams, res => {
-      //     resolve(res)
-      //   })
-      // })
-      // Promise.all([promise1, promise2]).then(values => {
-      //   let builData = values[0].Content, floorData = values[1].Content
-      //   data = builData.map(build => {
-      //     return {
-      //       code: build.BuildID,
-      //       name: build.BuildLocalName
-      //     }
-      //   })
-      //   data.forEach(build => {
-      //     floorData.forEach(floor => {
-      //       if (build.code == floor.BuildID && floor.FloorID && floor.FloorLocalName) {
-      //         if (build.children) {
-      //           build.children.push({
-      //             code: floor.FloorID,
-      //             name: (floor.FloorLocalName || floor.FloorName || "未知") + this.myMess(floor),
-      //             map: floor.StructureInfo?floor.StructureInfo.FloorMap?floor.StructureInfo.FloorMap:null:null,
-      //             affected: floor.affected,
-      //             buildCode: build.BuildID,
-      //             buildName: build.BuildLocalName,
-      //             FloorSequenceID: floor.FloorSequenceID
-      //           })
-      //         } else {
-      //           build.children = []
-      //           build.children.push({
-      //             code: floor.FloorID,
-      //             name: (floor.FloorLocalName || floor.FloorName || "未知") + this.myMess(floor),
-      //             map: floor.StructureInfo?floor.StructureInfo.FloorMap?floor.StructureInfo.FloorMap:null:null,
-      //             affected: floor.affected,
-      //             buildCode: build.BuildID,
-      //             buildName: build.BuildLocalName,
-      //             FloorSequenceID: floor.FloorSequenceID
-      //           })
-      //         }
-      //       }
-      //     })
-      //   })
-      //   this.options = data
-      // })
-
-      let param = {
-        ProjId: this.projectId,
-        UserId: this.UserId,
-        secret: this.secret
-      };
-      getSpaceFloor(param).then(res => {
-        console.log(res, 'res')
-        if (res.data.Result == 'success') {
-          let data = this.changeArr(res.data.Content).map(item => {
-            if (item.children && item.children.length) {
-              item.children = tools.sortArr(item.children, "shunxu", false)
-            }
-            return item
-          })
-          console.log(data, 'res.data')
-          this.options = data
-        } else {
-          this.$message.error(res.data.ResultMsg)
-        }
-      }).catch(() => {
-        this.$message.error("请求出错")
+    // 切换平面图和列表
+    changeRadio(val) {
+      this.changeGraphyOrTable(val)
+    },
+    // 获取tabs的列表
+    getTypes() {
+      let pa = {
+        Filters: `parentId = 'Space'`
+      }
+      queryDictionaryHead(pa, res => {
+        this.tabsList = res.Content;
+        console.log(this.activeName == '0')
+        console.log(this.activeName == '0' ? 'GeneralZone' : this.activeName)
+        this.activeName = this.activeName == '0' ? 'GeneralZone' : this.activeName;
       })
     },
-
-    //修改已有数组
-    changeArr(arr) {
-      return arr.map(item => {
-        console.log(item.floors)
-        if (item.floors && item.floors.length) {
-          return {
-            code: item.id,
-            name: item.infos.BuildLocalName,
-            children: item.floors.map(i => {
-              return {
-                code: i.id,
-                name: (i.infos.FloorLocalName || i.infos.FloorName || "未知") + this.myMess(i),
-                map: i.infos.FloorMap || null,
-                affected: i.affected,
-                isChilren: 2,
-                buildCode: item.id,
-                buildName: item.infos.BuildLocalName,
-                shunxu: i.infos.FloorSequenceID || 0
-              }
-            })
-          }
-        } else {
-          return {
-            code: item.id,
-            name: item.infos.BuildLocalName,
-            children: null,
-            isChilren: 1,
-          }
+    // 通过选中的tab-Code 获取选中的tab的所有数据
+    getItemForType() {
+      let data = {}
+      this.tabsList.map(item => {
+        if (item.Code == this.activeName) {
+          data.code = item.Code;
+          data.name = item.Name;
         }
       })
+      return data
     },
-    myMess(i) {
-      if (i.affected) {
-        return "(该业务空间受元空间变化影响)"
+    // 点击tab
+    tabClick(val) {
+      this.changeGraphyOrTable(this.isMyTab)
+    },
+    //修改所选建筑楼层
+    changeCascader(val) {
+      // val[0]->建筑 val[1]->楼层
+      if (!this.floorToMap[val[1]]) {
+        this.isMyTab = 2;
+      }
+      this.FloorMap = this.floorToMap[val[1]];
+      this.changeGraphyOrTable(this.isMyTab)
+    },
+    // 判断切换至图还是表
+    changeGraphyOrTable(num) {
+      if (!this.buildFloorSelectd.length) {
+        this.$message("请选择楼层")
+        return false
+      }
+      this.activeTabType = this.getItemForType()
+      if (num == 2) {
+        this.initMessage();
       } else {
-        if (i.infos.FloorMap) {
-        // if (i.StructureInfo && i.StructureInfo.FloorMap) {
-          return ''
-        } else {
-          return "(请初始化平面图)"
-        }
+        this.$refs.graphy.getData(this.buildFloorSelectd, this.FloorMap, this.activeTabType);
       }
     },
-    //获取tabs的列表
-    getTypes() {
-      getBussTypes(res => {
-        let arr = [{
-          "code": "GeneralZone",
-          "name": "默认分区",
-          "rel_type": "99"
-        },
-        {
-          "name": "供电分区",
-          "rel_type": "1",
-          "code": "PowerSupplyZone"
-        },
-        {
-          "name": "照明分区",
-          "rel_type": "2",
-          "code": "LightingZone"
+    // 触发获取表头-获取初始化信息点
+    initMessage() {
+      let params = {
+        data: {
+          Orders: "sort asc",
+          PageNumber: 1,
+          PageSize: 500
         },
-        {
-          "name": "空调分区",
-          "rel_type": "4",
-          "code": "AirConditioningZone"
-        }, {
-          "name": '租赁分区',
-          'rel_type': '10',
-          "code": 'TenantZone'
-        }
-        ]
-        this.tabsList = arr
-        // console.log(res)
-        // this.tabsList = res.Content
+        type: this.activeName
+      }
+      getDataDictionary(params, res => {
+        this.$refs.handsontable.getHeader(res.Content, this.buildFloorSelectd);
       })
     },
+    // 批量创建业务空间
+    groupCreateBSpace() {
+      this.$refs.graphy.groupCreateBSpace()
+    },
     checkSpace(list, build, graphyId) {
       this.floor.notRelated = true;
       this.$refs.notRelated.getIdList(list, build, graphyId, this.activeTabType);
-      this.$refs["graphy" + this.activeName][0].getHasSpace();
+      this.$refs["graphy"].getHasSpace();
     },
     changeShow() {
       this.floor.dialogVisible = true;
@@ -316,50 +237,15 @@ export default {
     },
     //成功关联平面图
     createSuccess() {
-      this.$refs["graphy" + this.activeName][0].getHasSpace();
-      this.$refs["graphy" + this.activeName][0].clearDimension();
+      this.$refs["graphy"].getHasSpace();
+      this.$refs["graphy"].clearDimension();
       this.floor.notRelated = false;
     },
     //成功删除业务空间
     delSuccess() {
       this.floor.details = false;
-      this.$refs["graphy" + this.activeName][0].getData(this.buildMess.map, this.buildMess, this.activeTabType);
-      // this.$refs["graphy" + this.activeName][0].getHasSpace();
-      // this.$refs["graphy" + this.activeName][0].clearDimension();
-    },
-    close() {
-      this.buildMess = this.changeBuildMess(this.buildMess, this.options)
-      console.log(this.buildMess, 'this.buildMess')
-      if (this.buildMess.affected) {
-        this.floor.influence = true;
-        this.$nextTick(() => {
-          this.$refs.influence.getData(this.buildMess);
-        });
-      }
-      if (!this.buildMess.map) {
-        this.isMyTab = 2;
-      }
-      if (this.isMyTab == 2) {
-        this.initTabs(this.buildMess);
-      } else {
-        let data = this.getItemForType()
-        this.$refs["graphy" + this.activeName][0].getData(this.buildMess.map, this.buildMess, this.activeTabType);
-      }
-    },
-
-    //通过code查询options中的其他参数
-    changeBuildMess(mess, options) {
-      options.map(item => {
-        if (!!item.children && item.children.length) {
-          item.children.map(child => {
-            if (child.code == mess.selectd[1]) {
-              console.log(child, mess)
-              mess = Object.assign(mess, child)
-            }
-          })
-        }
-      })
-      return mess
+      this.$refs["graphy"].getHasSpace();
+      this.$refs["graphy"].clearDimension();
     },
     //查看业务空间详情
     getBuinessDetails(list) {
@@ -372,87 +258,18 @@ export default {
       this.floor.facility = true
       this.$refs.facility.getData(infos, this.buildMess)
     },
-    tabClick(num) {
-      console.log(this.$refs)
-      this.isMyTab = num;
-      if (num == 2) {
-        this.initTabs(this.buildMess);
-      } else {
-        let data = this.getItemForType()
-        this.$refs["graphy" + this.activeName][0].getData(this.buildMess.map, this.buildMess, this.activeTabType);
-      }
-    },
-    //获取初始化信息点
-    initMessage() {
-      let params = {
-        data: {
-          Orders: "sort asc",
-          PageNumber: 1,
-          PageSize: 500
-        },
-        type: this.activeTabType.code
-      }
-      getDataDictionary(params, res => {
-        let refFlag = "handsontable" + this.activeName;
-        this.$refs[refFlag][0].getHeader(res.Content, this.activeTabType);
-        this.getTableMain()
-      })
-    },
-    getItemForType() {
-      let data = {}
-      this.tabsList.map(item => {
-        if (item.code == this.activeName) {
-          data = item
-        }
-      })
-      return data
-    },
-    tab1Click() {
-      this.activeTabType = this.getItemForType()
-      this.$refs["graphy" + this.activeName][0].getData(this.buildMess.map, this.buildMess, this.activeTabType);
-    },
-    /**
-     * tab标签被点击触发后的函数
-     * @param tab   tab实例
-     * @param event tab的dom
-     *
-     */
-    handleClick(tab, event) {
-      this.activeTabType = this.getItemForType()
-      this.initMessage();
-    },
-    /**
-     * 选择楼层后初始化tabs
-     * 由父级页面调用
-     *
-     * @param  floorParam  父级传入的楼层信息
-     */
-    initTabs(floorParam) {
-      // this.floor = floorParam;
-      this.initMessage();
-    },
-    getTableMain() {
-      let refFlag = "handsontable" + this.activeName;
-      this.$nextTick(() => {
-        this.$refs[refFlag][0].getData(this.buildMess);
-      });
-      //   for (let i = 0; i < this.tabsList.length; i++) {
-      //     if (i == 0) {
-      //     }
-      //   }
-    }
   },
   watch: {
     floor: {
       deep: true,
       handler: function () {
         if (this.floor.notRelated) {
-          this.$refs["graphy" + this.activeName][0].clearDimension();
+          this.$refs["graphy"].clearDimension();
         }
       }
     },
     projectId() {
-      this.changeData()
+      this.init()
     }
   }
 };
@@ -534,23 +351,28 @@ export default {
     }
   }
   .saga-business-sapce-main {
-    flex: 1;
-    top: 40px;
-    left: 0;
-    right: 0;
-    bottom: 0;
     overflow: hidden;
-    overflow-y: auto;
+    height: 100%;
     background: #fff;
     padding: 10px;
-    .el-tabs__nav {
-      padding-left: 10px;
+    /deep/ .el-tabs__item.is-top {
+      border-top: 2px solid transparent;
+      &.is-active {
+        border-top: 2px solid #409eff;
+      }
     }
-    .el-tabs__header{
-      margin-bottom: 10px;
+  }
+  .spaceTypes {
+    .types {
+      float: left;
+      width: calc(100% - 200px);
     }
-    .el-tabs__active-bar {
-      padding-left: 24px;
+    .groupAdd {
+      float: left;
+      width: 200px;
+      text-align: right;
+      height: 40px;
+      border-bottom: 1px solid #e4e7ed;
     }
   }
 }

+ 174 - 0
src/views/ledger/spacelist/spaceDetail/index.vue

@@ -0,0 +1,174 @@
+<template>
+  <div class="box">
+    <div class="condition">
+      <div class="header">
+        <el-button style="float:left;" size="small" type="default" icon="el-icon-back" @click="goBack"></el-button>
+        <span>{{spaceDetails.RoomLocalName||spaceDetails.RoomName||''}}</span>
+      </div>
+      <el-row class="spaceTypes">
+        <div class="types">
+          <el-tabs v-model="activeTab" type='card'>
+            <template v-for="(item,index) in tabsList">
+              <el-tab-pane :name="item.Code" :key="index" :label="item.Name"></el-tab-pane>
+            </template>
+          </el-tabs>
+        </div>
+        <div class="deleBtn">
+          <el-button size="small" @click="deleteSpace">删除业务空间</el-button>
+        </div>
+      </el-row>
+      <div v-if="activeTab=='detail'" style="height:calc(100% - 110px)">
+        <iframe height="100%" width="100%" :src="iframeSrc"></iframe>
+      </div>
+      <!-- 空间内设备列表--服务于空间的设备 -->
+      <eqToSpaceTable v-else-if="activeTab=='Equipment' || activeTab=='EquipmentFor'" :params="params" :type="activeTab"></eqToSpaceTable>
+      <!-- 空间内系统 -->
+      <syInSpaceTable v-else-if="activeTab=='generalSystem'" :params="params" :type="activeTab"></syInSpaceTable>
+
+    </div>
+  </div>
+</template>
+
+<script>
+import { mapGetters } from "vuex"
+import { queryZone, deleteZone } from '@/api/scan/request'
+import eqToSpaceTable from '@/components/business_space/newTables/eqToSpaceTable'
+import syInSpaceTable from '@/components/business_space/newTables/syInSpaceTable'
+export default {
+  data() {
+    return {
+      params: {}, //参数-包含空间id 分区类型 进入方式(1-平面图 2-列表)
+      tabsList: [
+        { Code: 'detail', Name: '空间详情' },
+        { Code: 'Equipment', Name: '空间内设备' },
+        { Code: 'EquipmentFor', Name: '服务于空间的设备' },
+        { Code: 'generalSystem', Name: '空间内系统' },
+      ], //tab页
+      activeTab: 'detail', //当前选中的tab
+      spaceDetails: {}, //空间信息
+      iframeSrc: '', //空间详情iframe
+    }
+  },
+  computed: {
+    ...mapGetters("layout", ["projectId", "userId", "secret"])
+  },
+  components: {
+    eqToSpaceTable,
+    syInSpaceTable
+  },
+  created() {
+    this.params = this.$route.query;
+    this.getSpaceDetails();
+    this.setFrame()
+  },
+  mounted() { },
+  watch: {
+    projectId() { }
+  },
+  methods: {
+    // 返回
+    goBack() {
+      this.$router.push({
+        name: "spacelist",
+        params: this.params
+      })
+    },
+    // 查询空间详情
+    getSpaceDetails() {
+      let pa = {
+        data: {
+          Filters: `RoomID="${this.params.RoomID}"`
+        },
+        zone: this.params.zone
+      }
+      queryZone(pa, res => {
+        this.spaceDetails = res.Content[0];
+        this.params.BuildingId = this.spaceDetails.BuildingId;
+        this.params.FloorId = this.spaceDetails.FloorId;
+      })
+    },
+    // 设置iframe
+    setFrame() {
+      this.iframeSrc =
+        `${process.env.BASE_URL}:8889/#/details?perjectId=${this.projectId}&secret=${this.secret}&FmId=${this.params.RoomID}&type=0&code=${this.params.zone}`;
+    },
+    // 删除业务空间
+    deleteSpace() {
+      this.$confirm("此操作将删除业务空间,是否继续?", "提示", {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        let pa = {
+          data: [{
+            RoomID: this.spaceDetails.RoomID
+          }],
+          zone: this.params.zone
+        }
+        deleteZone(pa, res => {
+          this.$message.success('删除成功')
+          this.goBack()
+        })
+      }).catch(() => {
+        this.getData()
+        this.$message("取消删除")
+      })
+    }
+  }
+};
+</script>
+
+<style scoped lang='less'>
+.box {
+  .condition {
+    padding: 10px;
+    display: flex;
+    height: 100%;
+    flex-direction: column;
+    border: 1px solid #dfe6ec;
+    background: #fff;
+    margin-bottom: 10px;
+    .header {
+      padding-bottom: 10px;
+      span {
+        line-height: 33px;
+        margin-left: 15px;
+      }
+    }
+    .spaceTypes {
+      .types {
+        float: left;
+        width: calc(100% - 200px);
+        /deep/ .el-tabs__item.is-top {
+          border-top: 2px solid transparent;
+          &.is-active {
+            border-top: 2px solid #409eff;
+          }
+        }
+      }
+      .deleBtn {
+        float: left;
+        width: 200px;
+        text-align: right;
+        height: 40px;
+        border-bottom: 1px solid #e4e7ed;
+      }
+    }
+    .main {
+      margin-top: 10px;
+      height: calc(100% - 96px);
+    }
+    .footer {
+      margin-bottom: 10px;
+    }
+  }
+}
+</style>
+
+<style lang="less">
+.el-table th {
+  background-color: #d9d9d9;
+  color: #000;
+}
+</style>
+

+ 12 - 14
src/views/ready/buildfloor/drawGraphy/checkGraphy.vue

@@ -1,7 +1,7 @@
 <template>
   <el-dialog id="checkGraphy" title="添加平面图" :visible.sync="checkGraphyVisible" width="900px" @close="handleClose">
     <div class="bodys">
-      <el-cascader :options="options" :show-all-levels="false" :props="props" @change="handleChange" @active-item-change='handleItemChange' clearable
+      <el-cascader :options="options" :show-all-levels="false" @change="handleChange" @active-item-change='handleItemChange' clearable
         placeholder="请选择模型文件" v-model="casVal"></el-cascader>
       <div>
@@ -9,7 +9,7 @@
       </div>
       <!-- 展示框 -->
       <div class="showBox">
-        <drawFloor ref="drawFloor"></drawFloor>
+        <drawFloor ref="drawFloorDialog" :showTools="false" :id="0"></drawFloor>
       </div>
     </div>
     <span slot="footer" class="dialog-footer">
@@ -22,7 +22,7 @@
 import drawFloor from "./drawFloor";
 import { mapGetters, mapActions } from "vuex";
 import request from "@/api/model/file.js";
-import { floorUpdate } from "@/api/scan/request";
+import { bindFloorModel } from "@/api/model/file";
 export default {
   components: {
     drawFloor
@@ -32,11 +32,12 @@ export default {
   },
   data() {
     return {
-      casVal:[],
+      casVal: [],
       jsonKey: "", //map.josn
       checkGraphyVisible: false,
       options: [],
       floor: {}, // 当前选中的楼层数据
+      modelIdToFloorId: {}
     };
   },
   methods: {
@@ -49,7 +50,7 @@ export default {
     handleClose() {
       this.checkGraphyVisible = false;
       this.casVal = []
-      this.$refs.drawFloor.clearGraphy()
+      this.$refs.drawFloorDialog.clearGraphy()
     },
     // 更新楼层 平面图文件
     bindGraphy() {
@@ -57,22 +58,18 @@ export default {
         this.$message.warning("请选择模型文件");
         return
       }
-      if (!this.floor.StructureInfo) {
-        this.floor.StructureInfo = {}
-      }
-      this.floor.StructureInfo.FloorMap = this.jsonKey
       let pa = {
-        Content: [this.floor]
+        Content: [{ FloorId: this.floor.FloorID, Id: this.modelIdToFloorId[this.jsonKey] }]
       };
-      floorUpdate(pa, res => {
-        this.$message.success("添加成功");
+      bindFloorModel(pa, res => {
+        this.$message.success("更新成功");
         this.handleClose()
         this.$emit('refresh')
       });
     },
     // 点击多级联动
     handleChange(val) {
-      this.$refs.drawFloor.initGraphy(val[1])
+      this.$refs.drawFloorDialog.initGraphy(val[1])
       this.jsonKey = val[1]
     },
     // 通过id查询文件夹下模型文件
@@ -83,6 +80,7 @@ export default {
       };
       request.queryFloorList(data, res => {
         let tempArr = res.Content.map(t => {
+          this.modelIdToFloorId[t.CurrentModelId] = t.Id;
           return {
             value: t.CurrentModelId,
             label: t.FloorName
@@ -118,7 +116,7 @@ export default {
       });
     },
   },
-  created(){
+  created() {
     this.init()
   },
   watch: {

+ 132 - 76
src/views/ready/buildfloor/drawGraphy/drawFloor.vue

@@ -1,15 +1,24 @@
 <template>
-  <div id="drawFloor" v-loading="canvasLoading">
-    <canvas id="floorCanvas" :width="cadWidth" :height="cadHeight" ref="canvas"></canvas>
+  <div :id="`drawFloor${id}`" class="drawFloor" v-loading="canvasLoading">
+    <canvas :id="`floorCanvas${id}`" :width="cadWidth" :height="cadHeight" ref="canvas" tabindex="0"></canvas>
+    <div class="operate" v-if="showTools">
+      <canvasFun @move="moveCanvas" @fit="fit" @savePng="savePng" @saveSvg="saveSvg" @divide="divide" @clearDivide="clearDivide" @undo="undo"
+        @redo="redo" @scale="scale" :isEdit="isEdit" ref="canvasFun"></canvasFun>
+    </div>
   </div>
 </template>
 
 <script>
 import eventBus from "./bus.js";
 import { SGraphyView } from "@sybotan-web/graphy/lib";
-import { FloorScene } from "cad-engine";
-import { SColor } from "@sybotan-web/draw/lib";
+import { DivideFloorScene } from "cad-engine"
+import { SColor, SPoint } from "@sybotan-web/draw/lib";
+import canvasFun from "@/components/business_space/newGraphy/canvasFun"
+import { floorQuery } from "@/api/scan/request";
 export default {
+  components: {
+    canvasFun
+  },
   data() {
     return {
       drawMainScene: null,
@@ -17,102 +26,149 @@ export default {
       dataKey: '',
       cadWidth: 800,
       cadHeight: 600,
-      canvasLoading: false
+      canvasLoading: false,
+      modelId: '',
+      FloorID: '',
+      Outline: [],
     };
   },
+  props: {
+    isEdit: {
+      default: false
+    },
+    showTools: {
+      default: false
+    },
+    id: {
+      default: 0
+    }
+  },
+  created() {
+    this.modelId = this.$route.query.modelId;
+    this.FloorID = this.$route.query.FloorID;
+    this.OutlineFlag = this.$route.query.OutlineFlag;
+  },
   mounted() {
-    // this.initGraphy('3af6d175c34e11e993ac85337be80696');
-    // let that = this;
-    // eventBus.$on("suitableRatios", function () {
-    //   that.view.fitSceneToView();
-    // });
-    // eventBus.$on("changeRatios", function (val) {
-    //   that.changeRatios(val);
-    // });
-    // eventBus.$on("downImgs", function (val) {
-    //   that.view.saveImage("saveImage" + new Date(), "png");
-    // });
-    // eventBus.$on("openDrags", function (val) {
-    //   if (val) {
-
-    //   }
-    // });
-    this.cadWidth = document.getElementById("drawFloor").offsetWidth;
-    this.cadHeight = document.getElementById("drawFloor").offsetHeight;
+    this.cadWidth = document.getElementById(`drawFloor${this.id}`).offsetWidth;
+    this.cadHeight = document.getElementById(`drawFloor${this.id}`).offsetHeight;
   },
   methods: {
-    clickItem(item) {
-      this.$emit("clickGraphyItem", item);
-    },
-    // 单个个体绘制颜色
-    drawItemColor(item, color) {
-      item.fillColor = new SColor(color); //需要缓存的边框
-      item.cacheFillColor = new SColor(color); //需要
-    },
-    // 绘制所有的item
-    drawAllItemColor() {
-      this.drawMainScene.root.children.forEach((item, index) => {
-        let color = this.initColor[index % 10];
-        this.drawItemColor(item, color);
-      });
-    },
     initGraphy(ModelId) {
-      this.dataKey = ModelId
-      if (!this.dataKey) {
-        return;
-      }
-      this.canvasLoading = true
-      this.clearGraphy()
-      // 初始化view类
-      this.view = new SGraphyView("floorCanvas");
-      this.drawMainScene = new FloorScene(null);
       let that = this;
-      this.drawMainScene.getFloorData('/modelapi/base-graph/query', { ModelId: ModelId }).then(res => {
-        that.view.scene = that.drawMainScene
-        that.view.fitSceneToView();
-        this.canvasLoading = false
+      that.clearGraphy()
+      let id = `floorCanvas${that.id}`;
+      that.view = new SGraphyView(id)
+      that.drawMainScene = new DivideFloorScene();
+      that.canvasLoading = true;
+      that.drawMainScene.getFloorData('/modelapi/base-graph/query', { ModelId: ModelId }).then(res => {
+        let Elements = res.EntityList[0].Elements;
+        let flag = false;
+        for (let key in Elements) {
+          if (Elements[key].length > 0) {
+            flag = true;
+          }
+        }
+        if (flag) {
+          that.view.scene = that.drawMainScene
+          that.view.fitSceneToView();
+          that.canvasLoading = false;
+          that.view.maxScale = that.view.scale * 1000;
+          that.$refs.canvasFun.maxScale = that.view.maxScale;
+          if (that.OutlineFlag) {
+            this.getFloorData()
+          }
+        }
       })
-      if (this.isScale) {
-        this.cancelScale(this.view);
-      }
     },
-    // 单个item 高亮
-    heightLightitem(item, highlightColor) {
-      // this.drawItemColor(item, highlightColor);
-    },
-    // 取消放大缩小
-    cancelScale(view) {
-      // view.wheelZoom = 1;
-    },
-    // 左键长按控制canvas的坐标
-    leftClickMove(a, b) {
-      //  console.log('move',a,b)
-    },
-    changeRatios(val) {
-      //计算缩放比例
-      this.view.scale = val;
+    getFloorData() {
+      let pa = {
+        Filters: `FloorID='${this.FloorID}'`
+      }
+      floorQuery(pa, res => {
+        let newArr = res.Content[0].Outline.map(t => {
+          return new SPoint(t.X, t.Y);
+        })
+        this.drawMainScene.addSceneMark(newArr)
+      })
     },
+    // 清空平面图
     clearGraphy() {
-      if(this.drawMainScene){
-        this.drawMainScene.root.children = null
+      if (this.view) {
+        this.drawMainScene.root.children = null;
         this.drawMainScene = null;
         this.view = null;
       }
-    }
+    },
+    // canvas 获取焦点
+    focus() {
+      document.getElementById(`floorCanvas${this.id}`).focus()
+    },
+    // 工具栏操作
+    // 移动底图
+    moveCanvas(move) {
+      // todo
+      let canvas = document.getElementById(`floorCanvas${this.id}`);
+      if (move) {
+        canvas.style.cursor = 'move';
+      } else {
+        canvas.style.cursor = 'default';
+      }
+    },
+    // 适配底图到窗口
+    fit() {
+      this.view.fitSceneToView()
+    },
+    // 保存为png
+    savePng() {
+      this.view.saveImage(`${this.floor}.png`, 'png');
+    },
+    // 保存为svg
+    saveSvg() {
+      this.view.saveSceneSvg(`${this.floor}.png`, 6400, 4800);
+    },
+    // 切割划分
+    divide() {
+      this.drawMainScene.isMarking = true;
+    },
+    // 清除切割划分
+    clearDivide() {
+      console.log(this.drawMainScene)
+      this.drawMainScene.clearSceneMark()
+    },
+    // 撤销
+    undo() {
+
+    },
+    // 反撤销
+    redo() { },
+    // 缩放
+    scale(val) {
+      let scale = this.view.scale
+      this.view.scaleByPoint(val / scale, this.cadWidth / 2, this.cadHeight / 2)
+    },
   },
   watch: {
-    findGraphyItemId(n) {
-      if (n) {
-        this.heightLightitem();
+    "view.scale": {
+      handler(n) {
+        if (this.$refs.canvasFun) {
+          this.$refs.canvasFun.sliderVal = n;
+        }
       }
     }
   }
 };
 </script>
 <style scoped lang="less">
-#drawFloor {
+.drawFloor {
   width: 100%;
   height: 100%;
   position: relative;
+  .operate {
+    position: absolute;
+    left: 50%;
+    bottom: 20px;
+    transform: translateX(-50%);
+    z-index: 99;
+  }
 }
 </style>

+ 0 - 112
src/views/ready/buildfloor/drawGraphy/operateGraphyItem.vue

@@ -1,112 +0,0 @@
-<template>
-  <div id="operateGraphyItem">
-    <div class="div-box" @click="openDrag">
-      <i class="el-icon-rank"></i>
-    </div>
-    <div class="div-box" @click="suitableRatio">
-      <i class="el-icon-rank"></i>
-    </div>
-    <div class="div-box" @click="downImg">
-      <i class="el-icon-download"></i>
-    </div>
-    <div class="div-box" @click="removeRatio">
-      <i class="el-icon-remove-outline"></i>
-    </div>
-    <div class="line">
-      <el-slider tooltip-class="tooltip-class"  :max="0.02" :min="0.004" v-model="sliderValue" @change="adjustRatio"></el-slider>
-    </div>
-    <div class="div-box" @click="addRatio">
-      <i class="el-icon-circle-plus-outline"></i>
-    </div>
-  </div>
-</template>
-<script>
-import eventBus from "./bus.js";
-export default {
-  data() {
-    return {
-      sliderValue: 0.004,
-      isopenDrags:false ,//是否鼠标左键移动图片
-    };
-  },
-  methods: {
-    // 开启拖动
-    openDrag() {
-      this.isopenDrags = !this.isopenDrags;
-      eventBus.$emit('openDrags',this.isopenDrags)
-    },
-    //合适比例
-    suitableRatio() {
-      eventBus.$emit("suitableRatios");
-    },
-    // 滑块调整比例
-    adjustRatio(val) {
-      this.sliderValue = val;
-      eventBus.$emit("changeRatios", this.sliderValue);
-    },
-    //增加比例
-    addRatio() {
-      if (this.sliderValue >= 0.02) {
-        this.sliderValue = 0.02;
-      } else {
-        this.sliderValue = this.sliderValue + 0.001;
-      }
-      eventBus.$emit("changeRatios", this.sliderValue);
-    },
-    //减少比例
-    removeRatio() {
-      if (this.sliderValue <=0.004) {
-        this.sliderValue = 0.004;
-      } else {
-        this.sliderValue = this.sliderValue - 0.001;
-      }
-      eventBus.$emit("changeRatios", this.sliderValue);
-    },
-    // 下载图片
-    downImg(){
-      eventBus.$emit("downImgs");
-    }
-  },
-  mounted() {
-    let that = this;
-     eventBus.$on('viewScale',function(scale){
-       console.log(scale,'scalescale')
-       that.sliderValue = scale;
-
-     })
-  },
-};
-</script>
-<style lang="less">
-#operateGraphyItem {
-  display: flex;
-  position: relative;
-  border: 1px #ddd solid;
-  border-radius: 5px;
-  overflow: hidden;
-  z-index: 999;
-  .div-box {
-    font-size: 24px;
-    width: 40px;
-    height: 40px;
-    background: #67c23a;
-    display: flex;
-    justify-content: center;
-    align-items: center;
-    color: #fff;
-    cursor: pointer;
-    border-right: 1px #ddd solid;
-  }
-  .line {
-    width: 200px;
-    font-size: 12px;
-    display: block;
-    background: #67c23a;
-    border-right: 1px #ddd solid;
-    .tooltip-class {
-      width: 100%;
-      background-color: #409eff;
-    }
-  }
-}
-</style>

+ 0 - 60
src/views/ready/buildfloor/drawGraphy/repetitionGraphy.vue

@@ -1,60 +0,0 @@
-<template>
-  <el-dialog id="checkdrawimg" title="前期准备/建筑楼层管理/平面图维护" :visible.sync="repetitionGraphyVisible" width="60%" :before-close="handleClose">
-    <div class="bodys">
-      <div class="buttons">
-        <el-button icon="el-icon-back" size="mini"></el-button>
-        <el-button size="mini">替换平面图</el-button>
-        <el-button size="mini">编辑平面图</el-button>
-      </div>
-      <!-- 展示图片 -->
-      <div class="drawImg">
-        <drawFloor ref="drawFloor" :findGraphyItemId="findGraphyItemId" :point="point" :pointWidth="pointWidth" :cadWidth="1000" :cadHeight="500"
-          :isScale="true"></drawFloor>
-      </div>
-    </div>
-    <span slot="footer" class="dialog-footer">
-      <el-button @click="dialogVisible = false">取 消</el-button>
-      <el-button type="primary" @click="dialogVisible = false">确 定</el-button>
-    </span>
-  </el-dialog>
-</template>
-<script>
-import drawFloor from "./drawFloor";
-export default {
-  components: {
-    drawFloor
-  },
-  props: {
-    repetitionGraphyVisible: Boolean
-  },
-  data() {
-    return {
-      modelId: "04153a22ce3111e9b1c7318645437bfe", // key
-      point: [40703.54760591985, 42678.14510522981], //坐标
-      pointWidth: 2000,
-      findGraphyItemId: "" //高亮的id
-    };
-  },
-  methods: {
-    handleClose() {
-      this.$emit("closeRepeatVisible");
-    }
-  },
-  mounted(){
-    // this.modelId = this.$router.query.modelId
-    console.log(22222)
-    let modelId = this.modelId
-    this.$refs.drawFloor.initGraphy(modelId)
-  }
-};
-</script>
-<style lang="less">
-#checkdrawimg {
-  .drawImg {
-    width: 100%;
-    height: 500px;
-    margin-top: 12px;
-    border: 1px solid #ccc;
-  }
-}
-</style>

+ 11 - 11
src/views/ready/buildfloor/index.vue

@@ -38,16 +38,16 @@
             </el-table-column>
             <el-table-column prop="Datasource" label="平面图">
               <template slot-scope="scope">
-                <p v-if="scope.row.StructureInfo&&scope.row.StructureInfo.FloorMap" @click="checfDrawImg(scope.row,1)">
+                <p v-if="scope.row.ModelId" @click="checkDrawImg(scope.row,1)">
                   <i class="iconfont icon-floorplan"></i>
                   查看平面图
                 </p>
-                <p v-else-if="scope.row.type==2" @click="checfDrawImg(scope.row,2)">
+                <p v-else-if="scope.row.type==2" @click="checkDrawImg(scope.row,2)">
                   <el-badge is-dot>
                     <i class="iconfont icon-floorplan"></i>
                   </el-badge>平面图重复
                 </p>
-                <p v-else @click="checfDrawImg(scope.row,3)">
+                <p v-else @click="checkDrawImg(scope.row,3)">
                   <i class="iconfont icon-nopicture"></i>
                   暂无平面图
                 </p>
@@ -114,11 +114,7 @@ export default {
         lineHeight: "30px"
       },
       buildList: [],
-      tableData: [
-        {
-          EquipmentMark: 1
-        }
-      ],
+      tableData: [],
       page: {
         pageSize: 500,
         pageSizes: [10, 20, 50, 100],
@@ -235,13 +231,17 @@ export default {
       this.$refs.addConnectivity.floor = row;
     },
     // 查看平面图
-    checfDrawImg(row, index) {
+    checkDrawImg(row, index) {
       if (3 == index) {
         this.$refs.checkGraphy.showDialog(row)
         this.modelId = "";
       } else {
-        this.modelId = row.StructureInfo.FloorMap;
-        this.$router.push({ name: "repetitionGraphy", query: { modelId: this.modelId } });
+        this.modelId = row.ModelId;
+        let pa = { modelId: this.modelId, FloorID: row.FloorID }
+        if (row.Outline && row.Outline.length) {
+          pa.OutlineFlag = true;
+        }
+        this.$router.push({ name: "repetitionGraphy", query: pa });
       }
     }
   },

+ 50 - 34
src/views/ready/buildfloor/repetitionGraphy.vue

@@ -3,59 +3,81 @@
   <div id="repetitionGraphy">
     <div class="buttons">
       <el-button icon="el-icon-back" size="mini" @click="backRouter"></el-button>
-      <el-button size="mini" @click="changeGraphy">替换平面图</el-button>
-      <el-button size="mini">编辑平面图</el-button>
+      <el-button v-if="!isEdit" size="mini" @click="changeGraphy">替换平面图</el-button>
+      <el-button v-if="!isEdit" size="mini" @click="editGraphy">编辑平面图</el-button>
+      <el-button v-if="isEdit" size="mini" @click="cancel">取消</el-button>
+      <el-button v-if="isEdit" size="mini" @click="confirm" type="primary">确认</el-button>
     </div>
     <!-- 展示图片 -->
     <div class="drawImg">
-      <drawFloor ref="drawFloor"></drawFloor>
+      <drawFloor ref="drawFloor" :isEdit="isEdit" :showTools="true" :id="1"></drawFloor>
     </div>
     <!-- 查看图片弹窗 -->
-    <checkGraphy :checkGraphyVisible="checkGraphyVisible" @handleCloseCGraphy="checkGraphyVisible=false"></checkGraphy>
-    <div id="operateList">
-      <operateGraphyItem></operateGraphyItem>
-    </div>
+    <checkGraphy ref="checkGraphy" @refresh="refresh"></checkGraphy>
   </div>
 </template>
 <script>
 import drawFloor from "./drawGraphy/drawFloor";
 import checkGraphy from "./drawGraphy/checkGraphy"; //查看图片
-import operateGraphyItem from "./drawGraphy/operateGraphyItem" //各个item
+import { floorUpdate } from "@/api/scan/request";
 export default {
   components: {
     drawFloor,
-    checkGraphy,
-    operateGraphyItem
+    checkGraphy
   },
   data() {
     return {
-      checkGraphyVisible: false, //查看平面图弹窗
-      modelId: "04153a22ce3111e9b1c7318645437bfe", // key
-      point: [40703.54760591985, 42678.14510522981], //坐标
-      pointWidth: 2000,
-      findGraphyItemId: "", //高亮的id
-      slidervalue: 0
+      modelId: "", // 
+      isEdit: false, // 是否编辑模式
     };
   },
+  created() {
+    this.modelId = this.$route.query.modelId;
+    this.FloorID = this.$route.query.FloorID;
+  },
+  mounted() {
+    this.$refs.drawFloor.initGraphy(this.modelId)
+  },
   methods: {
-    handleClose() {
-      this.$emit("closeRepeatVisible");
-    },
     // 返回路由
     backRouter() {
-      this.$router.go(-1);
+      this.$router.push({ name: 'buildFloor' })
     },
     // 替换模型文件
     changeGraphy() {
-      this.checkGraphyVisible = true;
+      this.$refs.checkGraphy.showDialog({ FloorID: this.FloorID })
     },
-  },
-  mounted() {
-    // this.dataKey = `/image-service/common/file_get/${this.$route.query.jsonKey}?systemId=revit`;
-    // this.modelId = this.$router.query.modelId
-    let modelId = this.modelId
-    console.log(this.$refs.drawFloor)
-    this.$refs.drawFloor.initGraphy(modelId)
+    // 确认保存
+    confirm() {
+      let grabitem = this.$refs.drawFloor.drawMainScene.grabItem;
+      if (!grabitem || grabitem.outLine.length < 3) {
+        this.$message.warning('请添加轮廓线');
+        return;
+      }
+      if (!grabitem.closeFlag) {
+        this.$message.warning('请按回车闭合轮廓线');
+        this.$refs.drawFloor.focus();
+        return;
+      }
+      let pa = {
+        Content: [{ FloorID: this.FloorID, Outline: this.$refs.drawFloor.drawMainScene.grabItem.outLine }],
+        Projection: ['Outline']
+      }
+      floorUpdate(pa, res => {
+        this.isEdit = false;
+        this.$message.success("更新成功");
+      })
+    },
+    // 取消
+    cancel() {
+      this.isEdit = false;
+      this.$refs.drawFloor.initGraphy(this.modelId)
+    },
+    // 编辑平面图
+    editGraphy() {
+      this.isEdit = true;
+    },
+    refresh() { }
   },
 };
 </script>
@@ -72,11 +94,5 @@ export default {
     margin-top: 10px;
     height: calc(100% - 40px);
   }
-  #operateList {
-    position: absolute;
-    left: 50%;
-    bottom: 100px;
-    // margin-left:
-  }
 }
 </style>