Parcourir la source

canvas select and create businessspance

haojianlong il y a 5 ans
Parent
commit
3c21a1ef97

+ 4 - 4
package.json

@@ -10,9 +10,9 @@
         "build": "node build/build.js"
     },
     "dependencies": {
-        "@sybotan-web/base": "2.1.2",
-        "@sybotan-web/draw": "2.1.47",
-        "@sybotan-web/graphy": "2.1.13",
+        "@sybotan-web/base": "2.1.5",
+        "@sybotan-web/draw": "2.1.56",
+        "@sybotan-web/graphy": "2.1.18",
         "axios": "^0.18.0",
         "echarts": "^4.1.0",
         "element-ui": "^2.11.0",
@@ -23,7 +23,7 @@
         "vue-axios": "^2.1.4",
         "vue-router": "^3.0.1",
         "vuex": "^3.1.0",
-        "cad-engine": "2.0.198"
+        "cad-engine": "2.0.214"
     },
     "devDependencies": {
         "ajv": "^6.9.1",

+ 5 - 0
src/api/scan/request.js

@@ -1296,4 +1296,9 @@ export function notEqForSpaceQuery(param, 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)
 }

+ 6 - 6
src/components/business_space/business/handsontable.vue

@@ -465,18 +465,18 @@ export default {
       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 = "未关联"

+ 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>

+ 321 - 28
src/components/business_space/newGraphy/graphy.vue

@@ -1,22 +1,22 @@
 <template>
   <div id="graphy" ref="graphy">
     <div v-show="!FloorMap">
-      <div class="center" v-show="1" style="height: 400px;padding-top:182px;box-sizing:border-box;">
+      <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">
-      <canvas id="floorCanvas" :width="canvasWidth" :height="canvasHeight"></canvas>
+    <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="handleIconClick"></i>
+            <i class="el-icon-search el-input__icon" slot="suffix" @click="handleSelect"></i>
             <template slot-scope="{ item }">
               <div class="name" style="position: relative;">
-                {{ item.infos.RoomLocalName | cutString(8) }}
+                {{ item.RoomLocalName | cutString(8) }}
                 <span class="addr" style="position: absolute;right:10px;color:#409EFF;">定位</span>
               </div>
             </template>
@@ -25,28 +25,28 @@
         <div class="button-group">
           <!-- 默认操作模式 -->
           <div v-show="type==1">
-            <el-button @click="1">创建业务空间</el-button>
+            <el-button @click="editGraphy">编辑平面图</el-button>
           </div>
           <!-- 点击已经关联的业务空间 -->
           <div v-show="type==2">
             <el-button type="primary" plain>重新划分业务空间</el-button>
-            <el-button type="primary">编辑空间详情</el-button>
-            <el-button plain>取 消</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>创建业务空间</el-button>
-            <el-button type="primary">从未关联元空间的业务空间中选择</el-button>
+            <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 type="primary" plain>从未关联元空间的业务空间中选择</el-button>
-            <el-button plain>取 消</el-button>
+            <el-button plain @click="cancelGraphy">取 消</el-button>
             <el-button type="primary">保存</el-button>
           </div>
         </div>
         <div style="position: absolute;right: 0;">
-          <el-button type="text">未关联平面图的业务空间 {{num}} 条</el-button>
+          <el-button type="text" @click="lookUnrelatBSpace(false)">未关联平面图的业务空间 {{num}} 条</el-button>
         </div>
       </el-row>
       <!-- 底部操作按钮 -->
@@ -56,20 +56,47 @@
       </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
+  createZone,
+  createRelateInZoneAndISp
 } from "@/api/scan/request"
+const colorArr = [
+  "#F9C3C3",
+  "#FFD1BF",
+  "#FFF3BF",
+  "#D8F7C6",
+  "#C6F2F6",
+  "#DCE3C0",
+  "#FAE6C9",
+  "#E3D7F7",
+  "#C4CBF8",
+  "#DEC3F6"
+];
+//  BSP => 业务空间
 export default {
   components: {
-    canvasFun
+    canvasFun,
+    unRelateBSP,
+    createBSP
   },
   data() {
     return {
@@ -78,8 +105,21 @@ export default {
       type: 1, // 默认操作模式
       search: '',//搜索
       num: 0, // 未关联空间的业务空间条数
+      buildFloor: [],
       FloorMap: '',
-      isEdit: false
+      tab: {},
+      isEdit: false,
+      canvasLoading: false,
+      view: null,
+      scene: null,
+      Outline: [], // 当前选中的多个空间组成的轮廓线->三维数组
+      businessSpaceList: [], // 所有业务空间
+      BSPUnrelaISPList: [], // 未关联元空间的业务空间
+      BSPRelaISPList: [], // 已关联元空间的业务空间
+      // 未关联元空间的业务空间弹窗
+      isAction: false,
+      curOutline: [],
+      BIMIDToSID: {}, //bimid映射元空间id
     }
   },
   computed: {
@@ -88,22 +128,62 @@ export default {
   created() {
   },
   mounted() {
-    this.canvasWidth = this.$refs.graphy.clientWidth;
-    this.canvasHeight = this.$refs.graphy.clientHeight;
+    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() { },
-    // 选中
-    handleSelect() { },
-    // 
-    handleIconClick() { },
-    // 
+    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;
-      this.buildFloor = buildFloor;
-      this.getUnrelateCount()
+      console.log(arguments)
+      this.init();
     },
     // 获取未关联平面图的业务空间统计
     getUnrelateCount() {
@@ -117,11 +197,224 @@ export default {
         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)
+      if (item instanceof SpaceItem) {
+        this.type = 3;
+      }
+      if (item instanceof ZoneItem) {
+        this.type = 2;
+      }
+    },
+    // 编辑平面图
+    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 => {
+        let params = {
+          SpaceId: res.EntityList[0].RoomID,
+          IspaceIdList: IspaceIdList
+        }
+        createRelateInZoneAndISp(params, res => {
+          this.$message.success('创建成功');
+          this.init();
+        })
+      })
+    },
+    // 从未关联平面图的业务空间中选择--按钮返回关联信号
+    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 arr = this.scene.getSelectedSpaces();
+      console.log(arr)
+      // this.$router.push({
+      //   path: "/ledger/spaceDetail",
+      //   query: { RoomID: infos.RoomID, zone: this.zoneCode, isMyTab: 2 }
+      // })
+    },
+    // 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');
+      let canvas = document.getElementById(`floorCanvas`);
       if (move) {
         canvas.style.cursor = 'move';
       } else {
@@ -227,7 +520,7 @@ export default {
     bottom: 20px;
     left: 50%;
     transform: translateX(-50%);
-    z-index: 99999999;
+    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>

+ 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 => {

+ 2 - 2
src/router/system.js

@@ -112,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: '模型文件管理' }] }
             },
             {

+ 5 - 1
src/views/ledger/spacelist/index.vue

@@ -32,7 +32,7 @@
           </el-tabs>
         </div>
         <div class="groupAdd">
-          <el-button size="small">批量创建业务空间</el-button>
+          <el-button size="small" @click="groupCreateBSpace">批量创建业务空间</el-button>
         </div>
       </el-row>
       <div v-show="isMyTab == 1" style="width:100%;height:100%">
@@ -219,6 +219,10 @@ export default {
         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);