Pārlūkot izejas kodu

Merge branch 'dev' of http://39.106.8.246:3003/web/ibms into dev

yangjunjing 5 gadi atpakaļ
vecāks
revīzija
1dfaf893f7
46 mainītis faili ar 2833 papildinājumiem un 408 dzēšanām
  1. 8 0
      README.md
  2. 3 3
      package.json
  3. 6 0
      src/api/model/file.js
  4. 119 18
      src/api/relation/api.js
  5. 48 0
      src/api/scan/request.js
  6. BIN
      src/assets/image/floorBG.png
  7. 62 6
      src/assets/style/iconfont/iconfont.css
  8. BIN
      src/assets/style/iconfont/iconfont.eot
  9. 42 0
      src/assets/style/iconfont/iconfont.svg
  10. BIN
      src/assets/style/iconfont/iconfont.ttf
  11. BIN
      src/assets/style/iconfont/iconfont.woff
  12. 111 0
      src/components/business_space/newAddDialogs/roomInFloorDialog.vue
  13. 2 1
      src/components/business_space/newGraphy/canvasFun.vue
  14. 40 13
      src/components/business_space/newGraphy/graphy.vue
  15. 71 28
      src/components/data_admin/buildTask/detail/deviceDetail.vue
  16. 2 2
      src/components/data_admin/buildTask/draw/drawModel.vue
  17. 3 2
      src/components/data_admin/zoneInput.vue
  18. 39 24
      src/components/globaluploader/index.vue
  19. 2 0
      src/components/ledger/handsontables/device.vue
  20. 2 2
      src/components/ledger/lib/cenoteGraphy.vue
  21. 334 0
      src/components/ledger/rentList/roomCountDrawer.vue
  22. 3 1
      src/components/model/file/addFloorDialog.vue
  23. 27 7
      src/components/model/file/floorTable.vue
  24. 19 2
      src/components/model/file/modelLog.vue
  25. 6 0
      src/components/model/file/replaceModelDialog.vue
  26. 54 0
      src/components/model/file/versionDialog.vue
  27. 32 11
      src/components/relation/overview/CardList.vue
  28. 155 62
      src/components/relation/overview/Modal/RelationMaintain.vue
  29. 11 0
      src/data/menus.js
  30. 12 3
      src/framework/layout/layout-store.js
  31. 15 2
      src/router/system.js
  32. 2 2
      src/views/data_admin/buildGraphy/graphyCanvas.vue
  33. 37 38
      src/views/ledger/cenotelist/index.vue
  34. 17 15
      src/views/ledger/cenotelist/relatedSpace.vue
  35. 73 82
      src/views/ledger/rentlist/index.vue
  36. 634 0
      src/views/ledger/rentlist/manageTenantZone.vue
  37. 31 22
      src/views/ledger/spacelist/index.vue
  38. 9 3
      src/views/model/file/index.vue
  39. 4 4
      src/views/point/config_point/steps/step1.vue
  40. 2 2
      src/views/ready/buildfloor/drawGraphy/drawFloor.vue
  41. 18 4
      src/views/ready/buildfloor/repetitionGraphy.vue
  42. 211 0
      src/views/relation/data/index.vue
  43. 313 0
      src/views/relation/datatable/index.vue
  44. 111 49
      src/views/relation/overview/index.vue
  45. 138 0
      src/views/screen/splitscreen/equipledger/index.vue
  46. 5 0
      src/views/screen/splitscreen/index.vue

+ 8 - 0
README.md

@@ -145,3 +145,11 @@ export default {
 this.$store.dispatch('setBreadcrumb', [{ label: 'Demo' }, { label: 'Form'  ])
 this.$store.dispatch('setBreadcrumb', [{ label: 'Demo', path: '' }, { label: 'Form' , path: ''}])
 ```
+#### 上传管理器调用方法(上传较大文件时使用)
+
+```
+在组件中引入Bus中央时间总线
+    Bus.$emit('openUploader', query, file)    //添加文件到上传管理器中, query为参数, file为H5原生的文件对象
+    Bus.$on('fileAdded', () => {})            //文件选择后的回调
+    Bus.$on('fileSuccess', () => {})          //文件上传成功后的回调
+```

+ 3 - 3
package.json

@@ -26,9 +26,9 @@
         "vuex": "^3.1.0",
         "cad-engine": "2.0.250",
         "@saga-web/base": "2.1.9",
-        "@saga-web/draw": "2.1.58",
-        "@saga-web/graphy": "2.1.30",
-        "@saga-web/cad-engine": "2.0.406"
+        "@saga-web/draw": "2.1.61",
+        "@saga-web/graphy": "2.1.34",
+        "@saga-web/cad-engine": "2.0.423"
     },
     "devDependencies": {
         "ajv": "^6.9.1",

+ 6 - 0
src/api/model/file.js

@@ -301,4 +301,10 @@ export default api
 export function bindFloorModel(param, success) {
     let url = `${baseUrl}/model-floor/bind`;
     httputils.postJson(url, param, success)
+}
+
+//根据模型id 获取模型文件夹及文件名
+export function getFileNameById(param, success) {
+    let url = `${baseUrl}/model-folder/get-name`;
+    httputils.postJson(url, param, success)
 }

+ 119 - 18
src/api/relation/api.js

@@ -1,25 +1,126 @@
 import httpUtil from "../scan/httpUtil";
+import fetch from "../scan/fetch";
+import storage from '@/framework/utils/storage'
+
+
+//查询总览
+export function graphic(param, success) {
+    let url = '/api/datacenter/graphic/page-query'
+    httpUtil.postJson(url, param, success)
+}
 
-export default {
-    //查询总览
-    graphic: function (param,success) {
-        let url = '/api/datacenter/graphic/page-query'
-        httpUtil.postJson(url, param, success)
-    },
 // 查询总览数量
-    graphicNumber: function (param, success) {
-        let url = '/api/datacenter/graphic/query-count'
-        httpUtil.postJson(url, param, success)
+export function graphicNumber(param, success) {
+    let url = '/api/datacenter/graphic/query-count'
+    httpUtil.postJson(url, param, success)
+
+}
+
+//导入excel
+export function graphicUpload(param, success) {
+    let url = '/api/datacenter/graphic/import'
+    httpUtil.postJson(url, param, success)
+}
 
-    },
 // 下载报告
-    reportDownloads: function (param, success) {
-        let url = '/api/datacenter/graphic/report-downloads'
-        httpUtil.getJson(url, param, success)
-    },
+export function reportDownload(param, success) {
+    let url = '/api/datacenter/graphic/report-downloads'
+    httpUtil.getJson(url, param, success)
+}
+
 // 下载模板
-    templateDownloads: function (param, success) {
-        let url = '/api/datacenter/graphic/template-downloads'
-        httpUtil.getJson(url, param, success)
-    }
+export function templateDownloads(param, success) {
+    let url = '/api/datacenter/graphic/template-downloads'
+    httpUtil.getJson(url, param, success)
+}
+
+
+//    建筑下的业务空间
+export function buildSpace(param, success) {
+    let url = '/api/datacenter/calc_building/space'
+    httpUtil.postJson(url, param, success)
+}
+
+
+// 管网系统设备分块 1
+export function calcSpecial(param, success) {
+    let url = ` /api/datacenter/calc_special/sys-block?Domain=${param.Domain}&SystemName=${param.SystemName}`
+    httpUtil.postJson(url, param, success)
+}
+
+
+//    获取源末端 2
+export function blockQuery(param, success) {
+    let url = '/api/datacenter/graphic/connected-block-query'
+    httpUtil.postJson(url, param, success)
+}
+
+
+// 覆盖源末端 3
+export function blockSource(param, success) {
+    let url = '/api/datacenter/graphic/replace-connected-block-source'
+    httpUtil.postJson(url, param, success)
+}
+
+//    管网系统确定流向 4
+export function sysDirection(param, success) {
+    let buildId = param.BuildingId ? `BuildingId=${param.BuildingId}&` : ''
+    let url = `/api/datacenter/calc_special/sys-direction?BlockId=${param.BlockId}&${buildId}Domain=${param.Domain}&SystemName=${param.SystemName}&isSource=${param.isSource}`
+    httpUtil.postJson(url, param, success)
+}
+
+//************************数据转换********************************//
+
+// 项目化字典-统计数量
+export function dictCount(param, success) {
+    let url = '/api/equip-component/dict-custom/project-dict-count'
+    httpUtil.postJson(url, param, success)
 }
+
+// 项目化字典-需补充转换规则数量
+export function dictSwitchCount(param, success) {
+    let url = '/api/equip-component/dict-custom/project-dict-switch-count'
+    httpUtil.postJson(url, param, success)
+}
+
+//项目化字典 - 内容
+// export function dectInfo(param, success) {
+//     let url = '/api/equip-component/dict-custom/project-dict-info'
+//     httpUtil.postJson(url, param, success)
+// }
+
+export function dectInfo(param) {
+    let data = param
+    let userName = storage.get("user_name")
+    let ProjectId = localStorage.getItem("projectId")
+    return fetch({
+        method: 'POST',
+        url: `/api/equip-component/dict-custom/project-dict-info`,
+        data,
+        headers: {'ProjectId': ProjectId, 'Comming': 'adm', 'Account': userName}
+    })
+}
+
+//数据中心-物理世界数据转换
+export function dictDataCenter(param, success) {
+    let url = '/api/equip-component/dict-custom/project-dict-datacenter'
+    httpUtil.postJson(url, param, success)
+}
+
+//物理世界-数据中心数据转换
+export function dictDataPlatFrom(param, success) {
+    let url = '/api/equip-component/dict-custom/project-dict-dataplatfrom'
+    httpUtil.postJson(url, param, success)
+}
+
+// 同步设备
+export function createEquip(param, success) {
+    let url = `/api/dataplatform-sync/project-sync/create-equip?projectId=${param.projectId}`
+    httpUtil.postJson(url, {}, success)
+}
+
+//更新自定义自定脚本
+export function dictUpdate(param, success) {
+    let url = '/api/equip-component/dict-custom/update'
+    httpUtil.postJson(url, param, success)
+}

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

@@ -881,6 +881,12 @@ export function queryTenantCompletion(param, success) {
 }
 
 //创建租户信息
+export function queryRentTableData(param, success) {
+    let url = `${baseUrl}/datacenter/tenant/query`
+    http.postJson(url, param, success)
+}
+
+//创建租户信息
 export function createRentTableData(param, success) {
     let url = `${baseUrl}/datacenter/tenant/create`
     http.postJson(url, param, success)
@@ -898,6 +904,42 @@ export function deleteRentTableData(param, success) {
     http.postJson(url, param, success)
 }
 
+//租户关联租户业务空间,租户一对多,覆盖
+export function tnRelateTenantZone(param, success) {
+    let url = `${baseUrl}/datacenter/tn-in-sp-zone-Tenant/link-sp`
+    http.postJson(url, param, success)
+}
+
+//租户关联默认业务空间,租户一对多,覆盖
+export function tnRelateGeneralZone(param, success) {
+    let url = `${baseUrl}/datacenter/tn-in-sp-zone-general/link-sp`
+    http.postJson(url, param, success)
+}
+
+//租户关联默认业务空间,租户一对多,覆盖
+export function tnRelateZone(param, success) {
+    let url = `${baseUrl}/datacenter/tn-in-sp-base/link-sp?type=${param.type}`
+    http.postJson(url, param.data, success)
+}
+
+//租户关联业务空间,累加
+export function tnRelateOneZone(param, success) {
+    let url = `${baseUrl}/datacenter/tn-in-sp-base/link?type=${param.type}`
+    http.postJson(url, param.data, success)
+}
+
+//删除租户业务空间关系
+export function delTnRelateZone(param, success) {
+    let url = `${baseUrl}/datacenter/tn-in-sp-base/unlink?type=${param.type}`
+    http.postJson(url, param.data, success)
+}
+
+//查询租户关联的业务空间所在的建筑楼层
+export function queryTnRelateFloor(param, success) {
+    let url = `${baseUrl}/equip-component/tenant/tenant-building-floor?objectType=${param.objectType}&tenantId=${param.tenantId}`
+    http.postJson(url, {}, success)
+}
+
 //关联分区空间
 export function saveRentRelateSpace(param, success) {
     let url = `${baseUrl}/datacenter/tenant/relate-space`
@@ -1419,6 +1461,12 @@ export function countZone(param, success) {
     http.postJson(url, data, success)
 }
 
+//查询空间信息父类
+export function queryParentZone(param, success) {
+    let url = `${baseUrl}/datacenter/zonespacebase/query`;
+    http.postJson(url, param, success)
+}
+
 //动态数据关联-查询对应关系(删除提示页)
 export function dynamicQueryPrompt(param, success) {
     let url = `${baseUrl}/pointconfig/dynamic/query-prompt`;

BIN
src/assets/image/floorBG.png


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 62 - 6
src/assets/style/iconfont/iconfont.css


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


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 42 - 0
src/assets/style/iconfont/iconfont.svg


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


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


+ 111 - 0
src/components/business_space/newAddDialogs/roomInFloorDialog.vue

@@ -0,0 +1,111 @@
+<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">
+        <el-table-column label="业务空间名称" 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="所属建筑" show-overflow-tooltip min-width="100"></el-table-column>
+        <el-table-column prop="SysLocalID" 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>
+    </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.tableData = [];
+      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,
+          Orders: 'SysID asc'
+        },
+        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>

+ 2 - 1
src/components/business_space/newGraphy/canvasFun.vue

@@ -42,7 +42,7 @@
       <i class="iconfont icon-narrow" @click="reduce"></i>
     </div>
     <div class="line">
-      <el-slider tooltip-class="tooltip-class" :min="min" v-model="sliderVal" :show-tooltip="false" @input="scale"></el-slider>
+      <el-slider tooltip-class="tooltip-class" :min="min" v-model="sliderVal" :show-tooltip="false" @input="scale" :max="max"></el-slider>
     </div>
     <div>
       <i class="iconfont icon-zoom" @click="plus"></i>
@@ -56,6 +56,7 @@ export default {
       sliderVal: 1, // 滑块值
       active: '',
       min: 1,
+      max: 1000,
       everyScale: 1, // 每份的放大倍数
       isSwitch: false, // 是否开启吸附
     }

+ 40 - 13
src/components/business_space/newGraphy/graphy.vue

@@ -286,7 +286,6 @@ export default {
         // 绘制业务空间
         that.getBusinessSpace();
         that.view.fitSceneToView();
-        that.view.maxScale = that.view.scale * 10;
         that.view.minScale = that.view.scale;
         if (that.$refs.canvasFun) {
           that.$refs.canvasFun.everyScale = that.view.scale;
@@ -604,21 +603,48 @@ export default {
     // 根据图批量创建所选业务空间
     groupCreateZone() {
       let arr = this.scene.getSelectedSpaces();
-      let spaces = arr.map(t => {
-        return {
-          IspaceId: this.BIMIDToSID[t.data.SourceId],
-          RoomLocalName: t.data.Name,
-          Outline: [t.data.OutLine],
-          BuildingId: this.buildFloor[0],
-          FloorId: this.buildFloor[1],
-          Height: t.data.Height > 100 ? (t.data.Height / 1000).toFixed(2) : t.data.Height || 0
+      let spaces = [];
+      // 如果有划分,求交集
+      if (this.scene.cutItem || this.scene.sceneMark) {
+        let outlines = this.scene.getIntersectInSpace();
+        for (let k in outlines) {
+          outlines[k] = outlines[k].map(t => {
+            t = t.map(item => {
+              item = item.map(j => {
+                return { X: j.x, Y: -j.y, Z: 0 }
+              })
+              return item
+            })
+            return t;
+          })
         }
-      })
+        spaces = arr.map(t => {
+          return {
+            IspaceId: this.BIMIDToSID[t.data.SourceId],
+            RoomLocalName: t.data.Name,
+            Outline: outlines[t.data.SourceId],
+            BuildingId: this.buildFloor[0],
+            FloorId: this.buildFloor[1],
+            Height: t.data.Height > 100 ? (t.data.Height / 1000).toFixed(2) : t.data.Height || 0
+          }
+        }).filter(item => item.Outline && item.Outline.length)
+      } else {
+        spaces = arr.map(t => {
+          return {
+            IspaceId: this.BIMIDToSID[t.data.SourceId],
+            RoomLocalName: t.data.Name,
+            Outline: [t.data.OutLine],
+            BuildingId: this.buildFloor[0],
+            FloorId: this.buildFloor[1],
+            Height: t.data.Height > 100 ? (t.data.Height / 1000).toFixed(2) : t.data.Height || 0
+          }
+        })
+      }
       if (spaces.length) {
         this.canvasLoading = true;
         this.groupCreateBSP(spaces)
       } else {
-        this.$message.warning('未选择空间');
+        this.$message.warning('未选择本层空间');
       }
     },
     // 更新业务空间和元空间的关系
@@ -753,7 +779,7 @@ export default {
     },
     // 框选
     groupSelect() {
-      this.scene.isRectSelection = true;
+      this.scene.isRectSelection = 1;
     },
     // 适配底图到窗口
     fit() {
@@ -812,7 +838,8 @@ export default {
     "view.scale": {
       handler(n) {
         if (this.$refs.canvasFun) {
-          this.$refs.canvasFun.sliderVal = n * 10 / this.view.minScale;
+          let s = n * 10 / this.view.minScale
+          this.$refs.canvasFun.sliderVal = s > 1000 ? 1000 : s;
         }
       }
     },

+ 71 - 28
src/components/data_admin/buildTask/detail/deviceDetail.vue

@@ -31,7 +31,7 @@
                     </el-form-item>
                 </el-form>
             </div>
-            <div class="implement-detail detail-item" v-if="detail.TaskState == '未找到'">
+            <div class="implement-detail detail-item" v-if="detail.TaskState === '未找到'">
                 <el-form :model="detail" label-width="150px">
                     <el-form-item label="执行任务人:">{{ detail.WorkerName || '--' }}</el-form-item>
                     <el-form-item label="执行时间:">{{ detail.ProcessTime || '--' }}</el-form-item>
@@ -51,8 +51,8 @@
                     <el-form-item label="全景图:" v-show="panoramaList && panoramaList.length">
                         <div class="img-item" @click="dialogVisible = true" v-for="item in panoramaList"
                              :key="item.Key">
-                            <img :src="`/image-service/common/image_get?systemId=dataPlatform&key=${item.Key}`"
-                                 style="width:100%;" :alt="item.Name">
+                            4 <img :src="`/image-service/common/image_get?systemId=dataPlatform&key=${item.Key}`"
+                                   style="width:100%;" :alt="item.Name">
                         </div>
                     </el-form-item>
                     <el-form-item label="资产照片:" v-show="imgList && imgList.length">
@@ -78,27 +78,32 @@
                     <el-form-item label="备注信息:">{{ detail.Note || '--' }}</el-form-item>
                 </el-form>
             </div>
-            <div class="operation-detail detail-item">
+            <div class="operation-detail detail-item" v-if="detail.TaskState === '未找到'">
                 <el-form>
                     <el-form-item label="操作信息:"></el-form-item>
                     <div class="block">
                         <el-timeline>
-                            <el-timeline-item timestamp="2018/4/12" placement="top">
+                            <el-timeline-item
+                                placement="top"
+                                v-for="(item,index) in arr"
+                                :key="index"
+                                :timestamp="item.timestamp"
+                            >
                                 <el-card>
-                                    <h4>更新 Github 模板</h4>
-                                    <p>王小虎 提交于 2018/4/12 20:46</p>
-                                </el-card>
-                            </el-timeline-item>
-                            <el-timeline-item timestamp="2018/4/3" placement="top">
-                                <el-card>
-                                    <h4>更新 Github 模板</h4>
-                                    <p>王小虎 提交于 2018/4/3 20:46</p>
-                                </el-card>
-                            </el-timeline-item>
-                            <el-timeline-item timestamp="2018/4/2" placement="top">
-                                <el-card>
-                                    <h4>更新 Github 模板</h4>
-                                    <p>王小虎 提交于 2018/4/2 20:46</p>
+                                    <small>{{item.content}}</small>
+                                    <p>{{item.title}}</p>
+                                    <img
+                                        v-for="isImg in item.imgs"
+                                        :key="isImg.Key"
+                                        :src="`/image-service/common/image_get?systemId=dataPlatform&key=${isImg.Key}`">
+
+                                    <video controls style="width:100%;" v-for="v in videoList" :key="index"
+                                           :title="v.Name">
+                                        <source
+                                            :src="`/image-service/common/image_get?systemId=dataPlatform&key=${v.Key}`"
+                                            type="video/mp4">
+                                        您的浏览器不支持 HTML5 video ,暂无法播放。
+                                    </video>
                                 </el-card>
                             </el-timeline-item>
                         </el-timeline>
@@ -116,16 +121,53 @@
     import {mapGetters} from "vuex"
 
     export default {
-        components: {
-
-  },
+        components: {},
         created() {
-            console.log(this.detail)
-            // ConfirmTime 确认信息时间
-            //    PositivePhotoTime	string 正面照片时间
-            //    QrCodeTime	打印二维码时间
-            //     RegionPhotoTime	string 局部照片时间
-            //     SidePhotoTime	string 侧面照片时间
+            let {ConfirmTime, PositivePhotoTime, QrCodeTime, NameplateTime, SidePhotoTime, VideoTime, EquipProblemTime, EquipProblem, TaskPicList} = this.detail;
+            let arr = []
+            QrCodeTime && arr.push({
+                timestamp: QrCodeTime,
+                time: new Date(QrCodeTime).getTime(),
+                content: '黏贴二维码',
+                imgs: TaskPicList.length && TaskPicList.filter(i => i.Name.includes('带二维码的设备近景照片'))
+            })
+            PositivePhotoTime && arr.push({
+                timestamp: PositivePhotoTime,
+                time: new Date(PositivePhotoTime).getTime(),
+                content: '拍摄正面照片',
+                imgs: TaskPicList.length && TaskPicList.filter(i => i.Name.includes('设备正面照片'))
+            })
+            NameplateTime && arr.push({
+                timestamp: NameplateTime,
+                time: new Date(NameplateTime).getTime(),
+                content: '拍摄铭牌照片',
+                imgs: TaskPicList.length && TaskPicList.filter(i => i.Name.includes('铭牌照片'))
+            })
+            SidePhotoTime && arr.push({
+                timestamp: SidePhotoTime,
+                time: new Date(SidePhotoTime).getTime(),
+                content: '拍摄侧面照片',
+                imgs: TaskPicList.length && TaskPicList.filter(i => i.Name.includes('设备左侧照片' || '设备右侧照片'))
+            })
+            VideoTime && arr.push({
+                timestamp: VideoTime,
+                time: new Date(VideoTime).getTime(),
+                content: '拍摄30s视频',
+                videoList: TaskPicList.length && TaskPicList.filter(i => i.Name.includes('视频资料'))
+            })
+            EquipProblemTime && arr.push({
+                timestamp: EquipProblemTime,
+                time: new Date(EquipProblemTime).getTime(),
+                content: '记录设备问题',
+                title: EquipProblem
+            })
+            ConfirmTime && arr.push({
+                timestamp: ConfirmTime,
+                time: new Date(ConfirmTime).getTime(),
+                content: '确认信息',
+                title: '已确认的设备信息'
+            })
+            this.arr = arr.map(i => ({...i})).sort((a, b) => b.time - a.time)
         },
         computed: {
             ...mapGetters("layout", ["projectId"]),
@@ -198,6 +240,7 @@
             return {
                 dialogVisible: false,//全景图弹出框
                 nowUrl: '',//当前正在显示的图
+                arr: [],
             };
         },
         methods: {},

+ 2 - 2
src/components/data_admin/buildTask/draw/drawModel.vue

@@ -118,7 +118,6 @@ export default {
       this.view.fitSceneToView();
       this.drawMainScene.click(this, this.canvasClick);
       if (this.$refs.canvasFun) {
-        this.view.maxScale = this.view.scale * 10;
         this.view.minScale = this.view.scale;
         this.$refs.canvasFun.everyScale = this.view.scale;
       }
@@ -211,7 +210,8 @@ export default {
     "view.scale": {
       handler(n) {
         if (this.$refs.canvasFun) {
-          this.$refs.canvasFun.sliderVal = n * 10 / this.view.minScale;
+          let s = n * 10 / this.view.minScale
+          this.$refs.canvasFun.sliderVal = s > 1000 ? 1000 : s;
         }
       }
     },

+ 3 - 2
src/components/data_admin/zoneInput.vue

@@ -22,6 +22,7 @@
 </template>
 
 <script>
+import tools from "@/utils/scan/tools";
 export default {
   data() {
     return {
@@ -107,10 +108,10 @@ export default {
         this.inputTypeList[key].map(item => {
           if (item.inputValue != '' && item.inputValue != null) {
             if (item.inputValue instanceof Array) {
-              f[item.InfoPointCode] = item.inputValue.pop();
+              tools.setDataForKey(f, item.Path, item.inputValue.pop());
             }
             else {
-              f[item.InfoPointCode] = item.inputValue;
+              tools.setDataForKey(f, item.Path, item.inputValue);
             }
           }
         })

+ 39 - 24
src/components/globaluploader/index.vue

@@ -2,7 +2,7 @@
  * @Author: zhangyu
  * @Date: 2019-11-28 10:05:28
  * @Info: 
- * @LastEditTime: 2019-11-30 18:28:18
+ * @LastEditTime: 2019-12-11 10:50:07
  -->
 <template>
   <div id="global-uploader">
@@ -63,6 +63,7 @@ import Bus from '@/utils/bus.js';
 import SparkMD5 from 'spark-md5';
 import { getUploadId, mergeMultipart } from '@/api/uploader';
 import request from "@/api/model/file.js";
+import { mapGetters, mapMutations } from 'vuex'
 
 export default {
   data() {
@@ -93,32 +94,44 @@ export default {
       panelShow: false,   //选择文件后,展示上传panel
       collapse: false,
     }
-  },   
+  },
   mounted() {
     Bus.$on('openUploader', (query, file) => {
-      if(query.uploadId){
+      if(!this.uploaderList.some(item => {return item.name === file.name})){
+        if(query.uploadId){
         // this.params = query || {};
-        file.uploadId = query.uploadId
-        file.modelId = query.modelId? query.modelId: ''
-        this.uploader.addFile(file)
-      } else {
-        getUploadId({
-          systemId: query.systemId?query.systemId:'revit', 
-          secret: query.secret?query.secret:'63afbef6906c342b', 
-          overwrite: query.overwrite? query.overwrite: false,
-          key: file.name
-        }, res => {
-          if(res.UploadId){
-            // this.params = Object.assign(query, { uploadId: res.UploadId }) || {};
-            file = Object.assign(file, {
-              ...query,
-              uploadId: res.UploadId 
-            })
-            this.uploader.addFile(file)
-          } else {
-            this.$message.error(`请求分片上传接口失败!`);
-          }
-        })
+          file.uploadId = query.uploadId
+          file.modelId = query.modelId? query.modelId: ''
+          this.uploader.addFile(file)
+          this.setUploaderList(this.uploader.files.map(item => {
+            item.modelId = item.file.modelId?item.file.modelId:''
+            return item
+          }))
+        } else {
+          getUploadId({
+            systemId: query.systemId?query.systemId:'revit', 
+            secret: query.secret?query.secret:'63afbef6906c342b', 
+            overwrite: query.overwrite? query.overwrite: false,
+            key: file.name
+          }, res => {
+            if(res.UploadId){
+              // this.params = Object.assign(query, { uploadId: res.UploadId }) || {};
+              file = Object.assign(file, {
+                ...query,
+                uploadId: res.UploadId 
+              })
+              this.uploader.addFile(file)
+              this.setUploaderList(this.uploader.files.map(item => {
+                item.modelId = item.file.modelId?item.file.modelId:''
+                return item
+              }))
+            } else {
+              this.$message.error(`请求分片上传接口失败!`);
+            }
+          })
+        }
+      }else {
+        this.$message.error(`该文件在上传列表中已存在!`);
       }
 
       // if (this.$refs.uploadBtn) {
@@ -128,12 +141,14 @@ export default {
     });
   },
   computed: {
+    ...mapGetters('layout', ['uploaderList']),
     //Uploader实例
     uploader() {
       return this.$refs.uploader.uploader;
     }
   },
   methods: {
+    ...mapMutations('layout', ['setUploaderList']),
     onFileAdded(file) {
       this.panelShow = true;
       this.collapse = true;

+ 2 - 0
src/components/ledger/handsontables/device.vue

@@ -170,6 +170,7 @@
     import lookPic from "@/components/ledger/lib/lookImages"
     import Handsontable from "handsontable-pro"
     import 'handsontable-pro/dist/handsontable.full.css'
+    import lStorage from '@/utils/localStorage'
     //下拉插件
 // import "@/assets/js/chosen.jquery.min";
 // import "@/assets/js/handsontable-chosen-editor";
@@ -918,6 +919,7 @@ export default {
             this.row = row.row;
             this.messKey = val;
             this.firmDataType = 'row'
+            lStorage.set('screen_data', { path: this.$route.path, data: { equip: infos } })
             switch (val) {
                 //操作
                 case 'caozuo':

+ 2 - 2
src/components/ledger/lib/cenoteGraphy.vue

@@ -99,7 +99,6 @@ export default {
         // 绘制业务空间
         that.getBusinessSpace();
         that.view.fitSceneToView();
-        that.view.maxScale = that.view.scale * 10;
         that.view.minScale = that.view.scale;
         if (that.$refs.canvasFun) {
           that.$refs.canvasFun.everyScale = that.view.scale;
@@ -276,7 +275,8 @@ export default {
     "view.scale": {
       handler(n) {
         if (this.$refs.canvasFun) {
-          this.$refs.canvasFun.sliderVal = n * 10 / this.view.minScale;
+          let s = n * 10 / this.view.minScale
+          this.$refs.canvasFun.sliderVal = s > 1000 ? 1000 : s;
         }
       }
     }

+ 334 - 0
src/components/ledger/rentList/roomCountDrawer.vue

@@ -0,0 +1,334 @@
+<template>
+  <el-drawer title="关联的业务空间" :visible.sync="drawer" :direction="direction" :before-close="handleClose" size="20%" custom-class="room-count">
+    <div class="drawer-body" :style="{height:drawerBodyHeight}">
+      <div class="default-zone zone">
+        <p>默认业务空间</p>
+        <div v-if="!(readonly&&!zoneList.GeneralZone.length)">
+          <div v-for="(item,index) in zoneList.GeneralZone" :key="item.RoomID" class="zoneItem">
+            {{item.BuildLocalName}}-{{item.FloorLocalName}}-{{item.RoomLocalName || item.RoomName}}
+            <i size="mini" class="el-icon-delete" title="删除" @click="deleteZoneItem('GeneralZone',index)" v-if="!readonly"></i>
+          </div>
+          <div class="zoneItem" style="border:none;padding:0;" v-if="!readonly">
+            <el-cascader placeholder="请选择" v-model="GeneralVal" :options="option.GeneralZone" :props="props" filterable @expand-change="expandChange"
+              @change="change" style="width:100%;">
+            </el-cascader>
+          </div>
+        </div>
+        <div v-else class="center">
+          <i class="icon-wushuju iconfont"></i>
+          暂无数据
+        </div>
+      </div>
+      <div class="tenant-zone zone">
+        <p>租户业务空间</p>
+        <div v-if="!(readonly&&!zoneList.TenantZone.length)">
+          <div v-for="(item,index) in zoneList.TenantZone" :key="item.RoomID" class="zoneItem">
+            {{item.BuildLocalName}}-{{item.FloorLocalName}}-{{item.RoomLocalName || item.RoomName}}
+            <i size="mini" class="el-icon-delete" title="删除" @click="deleteZoneItem('TenantZone',index)" v-if="!readonly"></i>
+          </div>
+          <div class="zoneItem" style="border:none;padding:0;" v-if="!readonly">
+            <el-cascader placeholder="请选择" v-model="TenantVal" :options="option.TenantZone" :props="props" filterable
+              @expand-change="expandChangeTenantZone" @change="changeTenantZone" style="width:100%;">
+            </el-cascader>
+          </div>
+        </div>
+        <div v-else class="center">
+          <i class="icon-wushuju iconfont"></i>
+          暂无数据
+        </div>
+      </div>
+    </div>
+    <div class="btn" v-if="!readonly">
+      <el-button type="primary" @click="save">保存</el-button>
+    </div>
+  </el-drawer>
+</template>
+<script>
+import {
+  tnRelateTenantZone, //关联租户空间
+  tnRelateGeneralZone, //关联默认空间
+  tnRelateOneZone,// 关联业务空间
+  delTnRelateZone, // 删除关系业务空间与租户
+  buildingQuery, //建筑查询
+  queryParentZone, //业务空间查询GeneralZone-TenantZone
+} from '@/api/scan/request'
+import { mapGetters } from "vuex";
+export default {
+  data() {
+    return {
+      drawer: false,
+      direction: 'rtl',
+      zoneList: {
+        GeneralZone: [],
+        TenantZone: []
+      },
+      option: {
+        GeneralZone: [],
+        TenantZone: []
+      },
+      props: {
+        children: 'Floor'
+      },
+      GeneralVal: [],
+      TenantVal: [],
+      curTenantId: '',
+      drawerBodyHeight: ''
+    }
+  },
+  props: {
+    readonly: {
+      default: true
+    }
+  },
+  computed: {
+    ...mapGetters("layout", ["projectId"])
+  },
+  watch: {
+    projectId() {
+      this.init();
+    }
+  },
+  mounted() {
+    this.drawerBodyHeight = document.body.clientHeight - 152 + 'px'
+  },
+  created() {
+    this.init();
+  },
+  methods: {
+    init() {
+      this.getBuilding()
+    },
+    getBuilding() {
+      let pa = {
+        Cascade: [{ Name: 'floor', Orders: 'FloorSequenceID desc' }],
+        Order: 'BuildLocalName asc'
+      }
+      buildingQuery(pa, res => {
+        this.option.GeneralZone = res.Content.map(build => {
+          build.value = build.BuildID;
+          build.label = build.BuildLocalName;
+          build.Floor = build.Floor.map(floor => {
+            floor.value = floor.FloorID;
+            floor.label = floor.FloorLocalName;
+            floor.Floor = [];
+            return floor;
+          });
+          build.Floor.unshift({ value: 'noknowFloor', label: '未明确楼层', Floor: [] })
+          return build;
+        })
+        this.option.GeneralZone.unshift({ value: 'noknowBuild', label: '未明确建筑', Floor: [] });
+        this.option.TenantZone = JSON.parse(JSON.stringify(this.option.GeneralZone));
+      })
+    },
+    expandChange(val) {
+      this.middleware(val, "GeneralZone")
+    },
+    expandChangeTenantZone(val) {
+      this.middleware(val, "TenantZone")
+    },
+    middleware(val, type) {
+      let filters = '';
+      if (val[0] == 'noknowBuild') { //未明确建筑
+        filters = `buildingId isNull`
+        this.getZone(filters, type, val)
+      } else if (val[1]) {
+        if (val[1] == "noknowFloor") {
+          filters = `buildingId='${val[0]}';floorId isNull`
+        } else {
+          filters = `buildingId='${val[0]}';floorId='${val[1]}'`
+        }
+        this.getZone(filters, type, val)
+      }
+    },
+    getZone(filters, type, selected) {
+      if (!filters) return;
+      let params = {
+        Cascade: [{ Name: 'building' }, { Name: 'floor' }],
+        Filters: `${filters};ObjectType='${type}'`,
+        Orders: "RoomID asc",
+        PageSize: 1000,
+        Projection: ["RoomID", "RoomLocalName", "RoomName", "ObjectType", "BuildingId", "FloorId"]
+      }
+      queryParentZone(params, res => {
+        if (res.Content.length) {
+          let tempArr = res.Content.map(t => {
+            t.BuildLocalName = t.Building ? t.Building.BuildLocalName : '未明确建筑';
+            t.FloorLocalName = t.Floor ? t.Floor.FloorLocalName : '未明确楼层';
+            delete t.Floor;
+            t.value = JSON.parse(JSON.stringify(t));
+            t.label = t.RoomLocalName || t.RoomName;
+            return t;
+          })
+          if (selected.length == 1) {
+            this.option[type][0].Floor = tempArr;
+          } else {
+            for (let i = 0; i < this.option[type].length; i++) {
+              if (this.option[type][i].value == selected[0]) {
+                for (let j = 0; j < this.option[type][i].Floor.length; j++) {
+                  if (this.option[type][i].Floor[j].value == selected[1]) {
+                    this.option[type][i].Floor[j].Floor = tempArr;
+                  }
+                }
+              }
+            }
+          }
+        }
+      })
+    },
+    change(val) {
+      let zoneObj = val[val.length - 1];
+      if (zoneObj.BuildLocalName == '未明确建筑') {
+        zoneObj.FloorLocalName = ''
+      }
+      if (this.zoneList.GeneralZone.findIndex((item) => (item.RoomID == zoneObj.RoomID)) == -1) {
+        this.zoneList.GeneralZone.push(zoneObj);
+        this.relateGeneral('GeneralZone', zoneObj.RoomID)
+      } else {
+        this.$message.warning('已有业务空间,请重新选择')
+      }
+      this.GeneralVal = [];
+    },
+    changeTenantZone(val) {
+      let zoneObj = val[val.length - 1];
+      if (zoneObj.BuildLocalName == '未明确建筑') {
+        zoneObj.FloorLocalName = ''
+      }
+      if (this.zoneList.TenantZone.findIndex((item) => (item.RoomID == zoneObj.RoomID)) == -1) {
+        this.zoneList.TenantZone.push(zoneObj);
+        this.relateGeneral('TenantZone', zoneObj.RoomID)
+      } else {
+        this.$message.warning('已有业务空间,请重新选择')
+      }
+      this.TenantVal = [];
+    },
+    showDrawer(tenant) {
+      this.curTenantId = tenant.TenantID;
+      if (tenant.ZoneGeneraltList) {
+        this.zoneList.GeneralZone = tenant.ZoneGeneraltList.map(t => {
+          if (t.Building) {
+            t.BuildLocalName = t.Building.BuildLocalName || t.Building.BuildName;
+          } else {
+            t.BuildLocalName = '未明确建筑'
+          }
+          if (t.Floor) {
+            t.FloorLocalName = t.Floor.FloorLocalName || t.Floor.FloorName;
+          } else {
+            t.FloorLocalName = '未明确楼层'
+          }
+          if (t.BuildLocalName == '未明确建筑') {
+            t.FloorLocalName = ''
+          }
+          return t;
+        });
+      } else {
+        this.zoneList.GeneralZone = [];
+      }
+      if (tenant.ZoneTenantList) {
+        this.zoneList.TenantZone = tenant.ZoneTenantList.map(t => {
+          if (t.Building) {
+            t.BuildLocalName = t.Building.BuildLocalName || t.Building.BuildName;
+          } else {
+            t.BuildLocalName = '未明确建筑'
+          }
+          if (t.Floor) {
+            t.FloorLocalName = t.Floor.FloorLocalName || t.Floor.FloorName;
+          } else {
+            t.FloorLocalName = '未明确楼层'
+          }
+          if (t.BuildLocalName == '未明确建筑') {
+            t.FloorLocalName = ''
+          }
+          return t;
+        });
+      } else {
+        this.zoneList.TenantZone = [];
+      }
+      this.drawer = true;
+    },
+    handleClose(done) {
+      this.zoneList.GeneralZone = [];
+      this.zoneList.GeneralZone = [];
+      this.$emit('refresh');
+      done();
+    },
+    // 删除
+    deleteZoneItem(type, index) {
+      let pa = {
+        type: type,
+        data: [
+          {
+            SpaceID: this.zoneList[type][index].RoomID,
+            TenantID: this.curTenantId
+          }
+        ]
+      }
+      this.zoneList[type].splice(index, 1);
+      delTnRelateZone(pa, res => { })
+    },
+    // 关联默认空间
+    relateGeneral(type, SpaceId) {
+      let pa = {
+        type: type,
+        data: {
+          Content: [
+            {
+              SpaceId: SpaceId,
+              TenantID: this.curTenantId
+            }
+          ]
+        }
+      }
+      tnRelateOneZone(pa, res => { })
+    },
+    save() {
+      this.$emit('refresh');
+      this.drawer = false;
+    }
+  }
+}
+</script>
+<style lang="less" scoped>
+.room-count {
+  .drawer-body {
+    position: relative;
+    padding: 10px 10px 30px;
+    overflow-y: auto;
+    .zone {
+      padding: 6px 14px 22px;
+      box-shadow: 0 0 3px #cacaca;
+      p {
+        margin-bottom: 4px;
+      }
+      .zoneItem {
+        position: relative;
+        padding: 2px 34px 2px 10px;
+        border: 1px solid #ccc;
+        border-radius: 4px;
+        white-space: nowrap;
+        overflow: hidden;
+        text-overflow: ellipsis;
+        i {
+          position: absolute;
+          right: 10px;
+          top: 50%;
+          transform: translateY(-50%);
+          cursor: pointer;
+        }
+      }
+      .zoneItem + .zoneItem {
+        margin-top: 6px;
+      }
+    }
+    .zone + .zone {
+      margin-top: 10px;
+    }
+  }
+  .btn {
+    position: absolute;
+    width: calc(100% - 20px);
+    bottom: 20px;
+    right: 20px;
+    text-align: right;
+  }
+}
+</style>

+ 3 - 1
src/components/model/file/addFloorDialog.vue

@@ -82,7 +82,7 @@ export default {
     FolderId: String
   },
   computed: {
-    ...mapGetters("layout", ["projectId", "userInfo","userId", "secret"])
+    ...mapGetters("layout", ["projectId", "userInfo","userId", "secret", "uploaderList"])
   },
   data() {
     return {
@@ -137,6 +137,8 @@ export default {
       let FloorName = null;
       if (this.form.file == null) {
         this.$message.error("模型文件不能为空!");
+      } else if (this.uploaderList.some(item => {return item.name === this.form.file.name})) {
+        this.$message.error("该文件在上传列表中已存在!");
       } else {
         let FloorName = null;
         // 根据是否有夹层拼接楼层名

+ 27 - 7
src/components/model/file/floorTable.vue

@@ -3,12 +3,20 @@
     <el-table ref="filterTable" :data="tableData" style="width: 100%" height="100%" :header-cell-style="{background:'#d9d9d9',color:'#2b2b2b'}">
       <el-table-column prop="FloorName" label="模型文件" width="180">
         <template slot-scope="scope">
-          <i class="el-icon-document-checked icon_font"></i>
+          <i v-if="scope.row.Status == 4" class="iconfont icon-yun--tianchong" style="color:#67C23A;cursor:pointer;fontSize:18px;" title="模型校验完成..."></i>
+          <i v-else-if="scope.row.Status == 31" class="iconfont icon-yun--tianchong1" style="color:#F56C6C;cursor:pointer;fontSize:18px;" title="同步到数据中心出问题..."></i>
+          <i v-else-if="scope.row.Status == 21" class="iconfont icon-yun--tianchong1" style="color:#F56C6C;cursor:pointer;fontSize:18px;" title="模型数据导出出问题..."></i>
+          <i v-else class="iconfont icon-yun--tianchong2" style="color:#E6A23C;cursor:pointer;fontSize:18px;" title="模型校验进行中..."></i>
           <span style="margin-left: 10px">{{ scope.row.FloorName }}</span>
         </template>
       </el-table-column>
       <el-table-column prop="Note" label="备注" width="180"></el-table-column>
-      <el-table-column prop="Version" label="版本号"></el-table-column>
+      <el-table-column label="版本号">
+        <template slot-scope="scope">
+          <span style="margin-right: 5px">{{ scope.row.Version }}</span>
+          <i v-show="scope.row.Version" class="iconfont icon-warn" style="cursor:pointer;" title="查看版本更新信息" @click="handleClickVersion(scope.row)"></i>
+        </template>
+      </el-table-column>
       <el-table-column prop="AcceptTime" label="上传时间"></el-table-column>
       <el-table-column prop="UserName" label="上传人"></el-table-column>
       <el-table-column prop="address" align="center" label="操作" width="240">
@@ -19,16 +27,16 @@
             <el-button type="primary" size="mini" class="iconfont icon-Log" @click="queryModelLog(scope.row)"></el-button>
           </div>
           <div
-            :class="[scope.row.Status == 1 || scope.row.Status == 10 || scope.row.Status == 11 || (!scope.row.Status && scope.row.precent == 100)? 'upLoad-loading':'','upLoad']"
+            :class="['upLoad-loading']"
             v-show="scope.row.isDown">
             <div class="progress">
               <el-progress
-                :text-inside="scope.row.Status == 1 || scope.row.Status == 10 || scope.row.Status == 11 || (!scope.row.Status && scope.row.precent == 100)?false:true"
-                :stroke-width="20" :percentage="scope.row.precent"
+                :text-inside="false"
+                :stroke-width="20" :percentage="100"
                 :color="scope.row.Status == 1 || scope.row.Status == 10 || scope.row.Status == 11?'#909399':'#67C23A'"></el-progress>
             </div>
             <div class="progress-right">
-              <span v-show="!scope.row.Status && scope.row.precent == 100">上传中</span>
+              <span v-show="!scope.row.Status">上传中</span>
               <span v-show="scope.row.Status == 1">等待检查...</span>
               <span v-show="scope.row.Status == 10">模型检查中</span>
               <span v-show="scope.row.Status == 11">未通过检查</span>
@@ -37,11 +45,16 @@
         </template>
       </el-table-column>
     </el-table>
+    <version-dialog :dialogVisible.sync="dialogVisible" :modelFile="modelFile" ref="addSpaceDialog"></version-dialog>
   </div>
 </template>
 <script>
 import { mapGetters } from "vuex";
+import versionDialog from "@/components/model/file/versionDialog";
 export default {
+  components: {
+    versionDialog
+  },
   props: {
     tableData: Array,
     persentList: Array,
@@ -49,7 +62,9 @@ export default {
   },
   data() {
     return {
-      maxHeight: 0
+      maxHeight: 0,
+      dialogVisible: false,
+      modelFile: null
     };
   },
   computed: {
@@ -60,6 +75,11 @@ export default {
     queryModelLog(item) {
       this.$emit("openModelLog", item);
     },
+    // 查看版本信息
+    handleClickVersion(item) {
+      this.modelFile = item;
+      this.dialogVisible = true;
+    },
     // 替换日志
     repliaceModel(item) {
       if (item.Status != 4 && item.Status != 21) {

+ 19 - 2
src/components/model/file/modelLog.vue

@@ -6,7 +6,12 @@
         <el-tabs v-model="activeName" type="card" @tab-click="changeModel">
           <el-tab-pane label="上传日志" name="first">
             <el-table :data="filterlogData" stripe height="300px" style="width: 100%">
-              <el-table-column prop="Version" label="版本"></el-table-column>
+              <el-table-column label="版本">
+                <template slot-scope="scope">
+                  <span style="margin-right: 5px">{{ scope.row.Version }}</span>
+                  <i v-show="scope.row.Version" class="iconfont icon-warn" style="cursor:pointer;" title="查看版本更新信息" @click="handleClickVersion(scope.row)"></i>
+                </template>
+              </el-table-column>
               <el-table-column prop="AcceptTime" label="上传时间"></el-table-column>
               <el-table-column prop="UserName" label="上传人"></el-table-column>
               <el-table-column prop="address" label="操作">
@@ -22,11 +27,16 @@
         </el-tabs>
       </div>
     </el-dialog>
+    <version-dialog :dialogVisible.sync="dialog" :modelFile="modelFile" ref="addSpaceDialog"></version-dialog>
   </div>
 </template>
 <script>
 import request from "@/api/model/file.js";
+import versionDialog from "@/components/model/file/versionDialog";
 export default {
+  components: {
+    versionDialog
+  },
   props: {
     modelLogVisible: Boolean,
     modelFolderName: String,
@@ -36,7 +46,9 @@ export default {
     return {
       dialogVisible: false, //是否显示该弹窗
       activeName: "first", //默认选择上传日志
-      tableData: [] //列表数据
+      tableData: [], //列表数据
+      dialog: false,
+      modelFile: null,
     };
   },
   computed: {
@@ -51,6 +63,11 @@ export default {
     }
   },
   methods: {
+    // 查看版本信息
+    handleClickVersion(item) {
+      this.modelFile = item;
+      this.dialog = true;
+    },
     handleClose(done) {
       this.$emit("CloseModelLogDia");
     },

+ 6 - 0
src/components/model/file/replaceModelDialog.vue

@@ -50,6 +50,7 @@
   </div>
 </template>
 <script>
+import { mapGetters } from "vuex";
 export default {
   props: {
     repliceModelVisible: Boolean,
@@ -66,10 +67,15 @@ export default {
       fileList: []
     };
   },
+  computed: {
+    ...mapGetters("layout", ["uploaderList"])
+  },
   methods: {
     onSubmit() {
       if (this.form.file == null) {
         this.$message.error("模型文件不能为空!");
+      } else if (this.uploaderList.some(item => {return item.name === this.form.file.name})) {
+        this.$message.error("该文件在上传列表中已存在!");
       } else {
         this.$emit("updataModel", {
           file: this.form.file,

+ 54 - 0
src/components/model/file/versionDialog.vue

@@ -0,0 +1,54 @@
+<template>
+  <el-dialog :title="title" :visible.sync="dialog" :before-close="handleClose" width="900px" id="">
+    <span slot="footer" class="dialog-footer">
+      <el-button size="small" @click="handleClose">取 消</el-button>
+      <el-button size="small" type="primary">确 定</el-button>
+    </span>
+  </el-dialog>
+</template>
+
+<script>
+import { mapGetters } from "vuex";
+import request from "@/api/model/file.js";
+export default {
+  components: {
+
+  },
+  computed: {
+    ...mapGetters("layout", ["projectId"]),
+    dialog() {
+      return this.dialogVisible;
+    }
+  },
+  data() {
+    return {
+      title: "版本文件信息",
+    }
+  },
+  props: {
+    dialogVisible: Boolean,
+    modelFile: Object,
+  },
+  mounted() { },
+  methods: {
+    // 关闭弹窗
+    handleClose() {
+      this.$emit("update:dialogVisible", false);
+    },
+  },
+  watch: {
+    dialogVisible: {
+      handler() {
+        if (this.dialogVisible) {
+          // this.tableData = [];
+          // this.getTableData();
+        }
+      },
+      immediate: true
+    }
+  }
+};
+</script>
+<style lang="less" scoped>
+
+</style>

+ 32 - 11
src/components/relation/overview/CardList.vue

@@ -12,7 +12,7 @@
             >
                 <p class="relation-text">
                     {{child.GraphTypeName}}
-                    <span class="pic-code">图编码{{child.GraphTypeCode}}</span>
+                    <span class="pic-code">图类型编码{{child.GraphTypeCode}}</span>
                     <el-tooltip
                         :content="child.Note"
                         placement="top">
@@ -38,7 +38,7 @@
                             <!--<div class="mask"></div>-->
                             <p class="relation-title">
                                 {{relation.RelationTypeName}}
-                                <span class="asc">{{relation.RelationTypeCode}}</span>
+                                <span class="asc">边类型编码:{{relation.RelationTypeCode}}</span>
                                 <el-tooltip
                                     :content="relation.Note"
                                     placement="top"
@@ -68,6 +68,8 @@
                                 </el-col>
                             </article>
                             <p class="last-computed">
+                                <span v-show="relation.ComputationalState === 3 || relation.ComputationalState === 4">关系计算中...</span>
+                                <span v-show="relation.ComputationalState === 5">计算失败</span>
                                 <span v-show="relation.ComputingTime">最后一次计算时间 {{relation.ComputingTime}}</span>
                                 <el-tooltip
                                     content="启动计算"
@@ -75,10 +77,10 @@
                                 >
                                     <el-badge
                                         class="item float-right"
-                                        is-dot
+                                        :is-dot="relation.ComputationalState === 2"
                                     >
                                         <el-button
-                                            @click="computed"
+                                            @click="computed(relation)"
                                             circle
                                             type="primary"
                                             plain
@@ -130,8 +132,12 @@
         </div>
         <RelationMaintain
             :values="values"
+            :source="source"
             ref="maintain"
+            :isComputed="isComputed"
+            :TableVisibleMoreLoading="TableVisibleMoreLoading"
             @template="templateDown"
+            @openComputed="openComputed"
         />
     </div>
 
@@ -143,7 +149,9 @@
     export default {
         name: "cardList",
         props: {
-            content: Array
+            content: Array,
+            source: Array,
+            TableVisibleMoreLoading: Boolean
         },
         data() {
             return {
@@ -157,8 +165,8 @@
                     download: '下载模板(含数据)',
                     done: '完成',
                     underDesign: '高级配置页面正在设计中。。。',
-                    autoComputed: '根据现有数据自动计算xxx',
-                    existComputed: '根据现有数据自动计算xxx',
+                    autoComputed: '根据现有数据自动计算',
+                    existComputed: '根据现有数据自动计算',
                     existTitle: '计算方向使用的源端和末端如下:',
                     originEquipment: '源端设备类:',
                     endEquipment: '末端设备类:',
@@ -174,17 +182,27 @@
                     allUpdateSuccess: 'xxxx全部更新成功',
                     portionUpdateSuccess: ' xxxx关系部分更新成功',
                     downloadFile: ' 下载报告文件'
-                }
+                },
+                isComputed: {}, // 当前要计算的对象
             }
         },
         computed: {},
+
         methods: {
             explain() {
                 // alert('explain click')
             },
-            computed() {
-                // this.$refs.maintain.dialogTableVisible = true
-                this.$refs.maintain.dialogTableVisibleMore = true
+            computed(relation) {
+                this.isComputed = relation // 当前要计算的对象
+                this.$emit('calcSpecial', relation)
+                if (relation.IsSource) { //提示引导
+                    this.values.autoComputed = `根据现有数据自动计算 <${relation.RelationTypeName}>`
+                    this.$refs.maintain.dialogTableVisible = true
+                } else {
+                    this.values.existComputed = `根据现有数据自动计算 <${relation.RelationTypeName}>`
+                    this.$refs.maintain.dialogTableVisibleMore = true
+
+                }
             },
             equipment() {
                 this.$refs.maintain.dialogEquipment = true
@@ -207,6 +225,9 @@
             },
             templateDown() { //下载模板
                 this.$emit('template')
+            },
+            openComputed(result) {
+                this.$emit('openComputed', result)
             }
         },
         components: {RelationMaintain}

+ 155 - 62
src/components/relation/overview/Modal/RelationMaintain.vue

@@ -13,8 +13,8 @@
                 <el-button @click="dialogTableVisible = false">{{values.cancel}}</el-button>
                 <el-button
                     type="primary"
-                    @click="dialogTableVisible = false"
-                >{{values.confirm}}
+                    @click="promptly"
+                >{{values.promptly}}
                 </el-button>
             </footer>
         </el-dialog>
@@ -23,39 +23,50 @@
             :title="values.title"
             :visible.sync="dialogTableVisibleMore"
         >
-            <p class="font-big">{{values.existComputed}}</p>
-            <p class="exist-title">{{values.existTitle}}</p>
-            <el-row :span="24">
-                <el-col :span="8">
-                    <span class="demonstration">{{values.originEquipment}}</span>
-                    <el-cascader
-                        :options="options"
-                        :props="props"
-                        collapse-tags
-                        clearable
-                    />
-                </el-col>
-                <el-col :span="8">
-                    <span class="demonstration">{{values.endEquipment}}</span>
-                    <el-cascader
-                        :options="options"
-                        :props="props"
-                        collapse-tags
-                        clearable
-                    />
-                </el-col>
-            </el-row>
-            <footer
-                slot="footer"
-                class="dialog-footer "
+            <div
+                v-loading="TableVisibleMoreLoading"
+                style="overflow:hidden"
             >
-                <el-button @click="dialogTableVisibleMore = false">{{values.cancel}}</el-button>
-                <el-button
-                    type="primary"
-                    @click="dialogTableVisibleMore = false"
-                >{{values.promptly}}
-                </el-button>
-            </footer>
+                <p class="font-big">{{values.existComputed}}</p>
+                <p class="exist-title">{{values.existTitle}}</p>
+                <el-row :span="24">
+                    <el-col :span="8">
+                        <span class="demonstration">{{values.originEquipment}}</span>
+                        <el-cascader
+                            :options="newOptions"
+                            :key="isResouceShow"
+                            v-model="ops"
+                            :props="props"
+                            @change="sourceOptions"
+                            collapse-tags
+                            clearable
+                        />
+                    </el-col>
+                    <el-col :span="8">
+                        <span class="demonstration">{{values.endEquipment}}</span>
+<!--                                                    v-model="filterOps"
+-->
+                        <el-cascader
+                            :options="disOptions"
+                            :props="props"
+                            collapse-tags
+                            clearable
+                        />
+                    </el-col>
+                </el-row>
+                <footer
+                    slot="footer"
+                    class="dialog-footer "
+                    style="float: right"
+                >
+                    <el-button @click="dialogTableVisibleMore = false">{{values.cancel}}</el-button>
+                    <el-button
+                        type="primary"
+                        @click="computedUpdate"
+                    >{{values.promptly}}
+                    </el-button>
+                </footer>
+            </div>
         </el-dialog>
         <!--设定设备对象源/末端-->
         <el-dialog
@@ -123,6 +134,7 @@
                 action="/api/datacenter/graphic/import"
                 multiple
                 name="fileName"
+                :before-upload="beforeUpload"
                 :on-progress="progress"
                 :on-success="success"
                 :on-error="error"
@@ -177,10 +189,12 @@
 
     export default {
         name: "RelationMaintain",
-        props:['values'],
+        props: ['values', 'isComputed', 'source', 'TableVisibleMoreLoading'],
         created() {
-        },
 
+        },
+        mounted() {
+        },
         data() {
             return {
                 dialogTableVisible: false,
@@ -191,31 +205,13 @@
                 dialogProcess: false,
                 originEquipment: [],
                 endEquipment: [],
-                props:{multiple:true}, // 级联
-                options: [{
-                    value: 1,
-                    label: '东南',
-                    children: [{
-                        value: 2,
-                        label: '上海',
-                    }, {
-                        value: 7,
-                        label: '江苏',
-                    }, {
-                        value: 12,
-                        label: '浙江',
-                    }]
-                }, {
-                    value: 17,
-                    label: '西北',
-                    children: [{
-                        value: 18,
-                        label: '陕西',
-                    }, {
-                        value: 21,
-                        label: '新疆维吾尔族自治区',
-                    }]
-                }],
+                props: {
+                    multiple: true,
+                    label: 'FamilyName',
+                    value: 'lId',
+                    children: 'Items',
+
+                }, // 级联
                 activities: [{
                     content: '数据文件处理中..',
                     size: 'large',
@@ -228,15 +224,61 @@
                     icon: 'el-icon-check',
                     size: 'large',
                     type: 'primary',
-                }]
+                }],
+                vals: [],
+                val: [],
+                idArr: [],//存储所有选择的id
+                secondary: [],//单独存储二级数据
+                list: [],//获取后台数据,重新组合,添加唯一标识和源端标识
+                isResouceShow: 0,
+                result: [],//最终传给后台的数据
+                ops: [],//第一个选择器model
+                filterOps: [],//为清空第二个选择器
             }
         },
         computed:{
             fileHeaders() {
                 return  {'Content-Type': 'multipart/form-data'}
+            },
+            newOptions() {
+                ++this.isResouceShow
+                let allList = []
+                this.deepCopy(this.source).forEach(item => allList.push(...item.Items))
+                this.list = allList.map((item, index) => {
+                    item = {
+                        ...item,
+                        lId: index
+                    }
+                    item.Items.map(i => {
+                        i.lId = i.Id + i.BlockId //添加唯一标识
+                        i.Source = true //判断源末端
+                        return i
+                    })
+                    return item
+                })
+                this.ops = this.list
+                return this.list
+            },
+            //    末端数据添加disabled
+            disOptions() {
+                let arr = this.deepCopy(this.list).map(item => {
+                    item.Items.map(i => {
+                        if (this.idArr.includes(i.lId)) {
+                            i.disabled = true
+                        }
+                        return i
+                    })
+                    return item
+                })
+                this.filterOps = arr
+                return arr
             }
+
         },
         methods: {
+            deepCopy(obj) {
+                return JSON.parse(JSON.stringify(obj))
+            },
             progress(event, file, fileList) {
                 // console.log(event.file, fileList)
             },
@@ -261,6 +303,57 @@
             },
             templateDownload() {
                 this.$emit('template')
+            },
+            promptly() {
+                console.log(this.isComputed, 'child isComputed')
+                this.dialogTableVisible = false
+            },
+            sourceOptions(val) {
+                //把所有id组装到一个数组
+                this.idArr = val.map(item => item[1])
+                //提取后台二级数据
+                this.secondary = []
+                this.deepCopy(this.list).forEach(item => this.secondary.push(...item.Items))
+                //最终过滤
+                let filterList = this.secondary.filter(item => this.idArr.includes(item.lId))
+                //    组合成接口需要的数据格式
+                let result = []
+                filterList.forEach(item => {
+                    let {BlockId, BuildingId, Domain, Id, MepSystemType, ProjectId, Source, SourceId, Type, Statistics} = item
+                    result.push({
+                        BlockId,
+                        BuildingId,
+                        Domain,
+                        // Id,
+                        MepSystemType,
+                        ProjectId,
+                        Source,
+                        SourceId,
+                        SourceType: Type,
+                        Statistics
+                    })
+                })
+                this.result = result
+
+            },
+            computedUpdate() {
+                if (!this.result.length) {
+                    this.$message({
+                        showClose: true,
+                        message: '请选择源端设备类',
+                        type: 'warning'
+                    });
+                    return false
+                } else {
+                    this.$emit('openComputed', this.result)
+                    this.dialogTableVisibleMore = false
+
+                }
+            },
+            beforeUpload(file) {
+                let fd = new FormData()
+                fd.append('files',file)
+
             }
         }
     }

+ 11 - 0
src/data/menus.js

@@ -287,6 +287,17 @@ export default [
 			permission: 'system:role:query'
 		}]
 	},
+	// 项目数据转换
+	{
+		path: '/relation/data',
+		name: '项目数据转换',
+		icon: 'icon-view',
+		opts: [{
+			name: '查看',
+			basic: true,
+			permission: 'system:role:query'
+		}]
+	},
 	/******************** 通用字典 ***************************/
 	// {
 	// 	path: '/dictionaries',

+ 12 - 3
src/framework/layout/layout-store.js

@@ -1,8 +1,6 @@
 import frameworkApi from '@/api/framework'
 import storage from '@/framework/utils/storage'
 import lStorage from '@/utils/localStorage'
-import axios from 'axios'
-import authutils from '../../utils/authutils'
 
 const KEY_MENU_SELECTED = 'menu_selected'
 const KEY_PROJECT_SELECTED = 'global_project_selected'
@@ -18,8 +16,10 @@ export default {
         projectId: '',
         projects: [],
         breadcrumb: [],
+        uploaderList: [], //当前上传文件列表
         secret: "", //项目密码
         userId: "", //用户id
+        rowEdit: false,//表格数据变化
     },
     getters: {
         sidebarClosed: state => state.sidebarClosed,
@@ -38,6 +38,7 @@ export default {
         userInfo: state => state.userInfo,
         permissions: state => state.permissions,
         projects: state => state.projects,
+        uploaderList: state => state.uploaderList,
         projectId: state => {
             if (!state.projectId) {
                 let pid = storage.get(KEY_PROJECT_SELECTED)
@@ -58,6 +59,7 @@ export default {
         }
     },
     mutations: {
+        setRowEdit: (state, val) => (state.rowEdit = val),
         setSidebarClosed: (state, val) => (state.sidebarClosed = val),
         setSidebarSelected: (state, val) => {
             state.sidebarSelected = val
@@ -82,9 +84,16 @@ export default {
                     localStorage.setItem('secret', item.pwd)
                 }
             })
-        }
+        },
+        setUploaderList: (state, val) => {
+            state.uploaderList = val?val:[]
+        },
+
     },
     actions: {
+        setRowEdit(contentx, value) {
+            contentx.commit('setRowEdit', value)
+        },
         loadUserInfo({ state }) {
             console.log(state)
             return new Promise((resolve, reject) => {

+ 15 - 2
src/router/system.js

@@ -71,6 +71,7 @@ import cenotelist from '@/views/ledger/cenotelist' //竖井清单
 import cenoteadd from '@/views/ledger/cenotelist/cenoteadd' //添加竖井
 import cenoteDetail from '@/views/ledger/cenotelist/cenoteDetail' //竖井关系详情
 import rentlist from '@/views/ledger/rentlist' //租户清单
+import manageTenantZone from '@/views/ledger/rentlist/manageTenantZone' //租户清单
 import rentadd from '@/views/ledger/rentlist/rentadd' //租户清单
 import dataReport from '@/views/ledger/report'
 import auth from '@/views/system/auth'
@@ -81,6 +82,8 @@ import relatedSpace from '@/views/ledger/cenotelist/relatedSpace'
 /**  关系维护并计算 */
 import maintain from '@/views/relation/maintain'
 import overView from '@/views/relation/overview'
+import data from '@/views/relation/data'
+import datatable from '@/views/relation/datatable'
 
 /**  厂家库 */
 import supplier from '@/views/manufactor/supplier'
@@ -88,6 +91,7 @@ import supplier from '@/views/manufactor/supplier'
 /**  辅助屏 */
 import splitScreen from '@/views/screen/splitScreen'
 import spaceLedger from '@/views/screen/splitScreen/spaceledger'
+import equipLedger from '@/views/screen/splitScreen/equipledger'
 import integrateResults from '@/views/screen/splitScreen/integrateresults'
 
 /**  业务空间数据导入工具 */
@@ -127,6 +131,7 @@ export default [{
         component: splitScreen,
         children: [
             { path: 'spaceledger', name: 'spaceLedger', component: spaceLedger },
+            { path: 'equipledger', name: 'equipLedger', component: equipLedger },
             { path: 'integrateresults', name: 'integrateResults', component: integrateResults }
         ]
     },
@@ -457,6 +462,12 @@ export default [{
                 meta: { keepAlive: false, breadcrumbs: [{ label: '台账管理', path: '/ledger/facility' }, { label: '租户台账', path: '/ledger/rentlist' }, { label: '添加租户' }] }
             },
             {
+                path: 'manageTenantZone',
+                name: 'manageTenantZone',
+                component: manageTenantZone,
+                meta: { keepAlive: false, breadcrumbs: [{ label: '台账管理', path: '/ledger/facility' }, { label: '租户台账', path: '/ledger/rentlist' }, { label: '管理租赁空间' }] }
+            },
+            {
                 path: 'datareport',
                 name: 'dataReport',
                 component: dataReport,
@@ -472,8 +483,10 @@ export default [{
         component: LayoutMain,
         children: [
             { path: 'maintain', name: 'maintain', component: maintain, meta: { keepAlive: false, breadcrumbs: [{ label: '关系维护' }] } },
-            { path: 'overview', name: 'overView', component: overView, meta: { keepAlive: false, breadcrumbs: [{ label: '关系维护计算' },{ label: '全部关系总览' }] } }
-        ]
+            { path: 'overview', name: 'overView', component: overView, meta: { keepAlive: false, breadcrumbs: [{ label: '关系维护计算' },{ label: '全部关系总览' }] } },
+            { path: 'data', name: 'data', component: data, meta: { keepAlive: false, breadcrumbs: [{ label: '项目数据转换',path:'/relation/data' },{ label: '项目数据转换',path:'/relation/data' }] } },
+            { path: 'datatable', name: 'datatable', component: datatable}
+            ]
     },
     /******************** 通用字典 ***************************/
     //厂家库

+ 2 - 2
src/views/data_admin/buildGraphy/graphyCanvas.vue

@@ -100,7 +100,6 @@ export default {
         that.scene.markerClick(that, that.markClick);
         that.scene.spaceClick(that, that.spaceClick);
         that.view.fitSceneToView();
-        that.view.maxScale = that.view.scale * 10;
         that.view.minScale = that.view.scale;
         // that.view.minScale = 0.000001;
         if (that.$refs.canvasFun) {
@@ -307,7 +306,8 @@ export default {
     "view.scale": {
       handler(n, o) {
         if (this.$refs.canvasFun) {
-          this.$refs.canvasFun.sliderVal = n * 10 / this.view.minScale;
+          let s = n * 10 / this.view.minScale
+          this.$refs.canvasFun.sliderVal = s > 1000 ? 1000 : s;
         }
       }
     }

+ 37 - 38
src/views/ledger/cenotelist/index.vue

@@ -26,15 +26,8 @@
         <handson-table ref="table"></handson-table>
       </div>
     </div>
-    <el-pagination
-      class="right"
-      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"
+    <el-pagination class="right" 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>
     <!-- 不支持的输入方式 -->
@@ -59,7 +52,7 @@ import showTools from "@/utils/handsontable/notShow"
 import text from "@/utils/handsontable/mainText"
 import cenoteType from "@/components/ledger/lib/cenoteType";
 import handsonTable from "@/components/common/handsontable";
-import { getDataDictionary, getCenoteTableData, updataCenoteTableData, deleteCenoteTableData, saveCenoteRelateSpace, BeatchQueryParam } from "@/api/scan/request"
+import { getDataDictionary, queryCenoteTableData, updataCenoteTableData, deleteCenoteTableData, saveCenoteRelateSpace, BeatchQueryParam } from "@/api/scan/request"
 import { mapGetters, mapActions } from "vuex";
 export default {
   components: {
@@ -90,11 +83,11 @@ export default {
       },
       tableData: [],
       copyTableData: [],
-      tableExample:null,
+      tableExample: null,
       myDialog: {
         update: false,//临时维护信息点
       },
-      inputMap: { }, //信息点和输入方式映射表
+      inputMap: {}, //信息点和输入方式映射表
       updateInputShow: false, //是否显示临时维护输入框
       updateInfoPoint: '',//临时维护信息点
       updateInput: '', //临时维护信息点值
@@ -102,14 +95,14 @@ export default {
   },
   computed: {
     ...mapGetters("layout", [
-        "projectId",
-        "secret",
-        "userId"
+      "projectId",
+      "secret",
+      "userId"
     ]),
-    showTypes () {
-      return this.onlyRead?
-        [{value: "Visible", label: '只看采集信息'}, {value: "all", label: '全部'}]:
-        [{value: "Visible", label: '只看采集信息'}, {value: "all", label: '全部'}]
+    showTypes() {
+      return this.onlyRead ?
+        [{ value: "Visible", label: '只看采集信息' }, { value: "all", label: '全部' }] :
+        [{ value: "Visible", label: '只看采集信息' }, { value: "all", label: '全部' }]
     }
   },
   created() {
@@ -142,7 +135,7 @@ export default {
       await getDataDictionary(param, res => {
         this.tableHeader = res.Content;
         this.tableHeader.forEach(item => {
-          if(item.Path && item.InputMode){
+          if (item.Path && item.InputMode) {
             this.inputMap[item.Path] = item.InputMode
           }
         })
@@ -151,17 +144,18 @@ export default {
     },
     async getTableData() {//获取表格数据
       let params = {
-        Filters: this.cenoteId? `ProjectId='${this.projectId}';structureInfo.ShaftFuncType='${this.cenoteId}'`: `ProjectId='${this.projectId}'`,
+        Cascade: [{ Name: 'spaceList' }],
+        Filters: this.cenoteId ? `ProjectId='${this.projectId}';structureInfo.ShaftFuncType='${this.cenoteId}'` : `ProjectId='${this.projectId}'`,
         Orders: "createTime desc, ShaftID asc",
         PageNumber: this.page.pageNumber,
         PageSize: this.page.pageSize
       }
-      await getCenoteTableData(params, (res) => {
+      await queryCenoteTableData(params, (res) => {
         this.tableData = res.Content
         this.copyTableData = tools.deepCopy(res.Content)
         this.page.pageNumber = res.PageNumber
         this.page.total = res.Total
-        if(this.tableData && this.tableData.length){
+        if (this.tableData && this.tableData.length) {
           if (this.onlyRead) {
             this.getBatch(res.Content)
           }
@@ -175,7 +169,7 @@ export default {
         Content: [],
         Projection: []
       }, keyList = [];
-       //生成要修改字段列表
+      //生成要修改字段列表
       change.map(item => {
         let key = item[1].split(".")[0]
         if (item[1] && keyList.indexOf(key) == -1) {
@@ -223,7 +217,7 @@ export default {
     },
     // 添加竖井
     handleCreateTableData() {
-      this.$router.push({ name: 'cenoteadd'})
+      this.$router.push({ name: 'cenoteadd' })
     },
     // 删除表格行
     handleDeleteTableRow() {
@@ -233,7 +227,7 @@ export default {
       }
       let param = []
       params.map(item => {
-        param.push({ShaftID: item.ShaftID})
+        param.push({ ShaftID: item.ShaftID })
       })
       this.$confirm("此操作将删除竖井,是否继续?", "提示", {
         confirmButtonText: '确定',
@@ -297,10 +291,14 @@ export default {
       let arr = tools.copyArr(list);
       let data = showTools.headerTypeFilter(arr, "shaft", this.onlyRead, this.showType)
       data.unshift({
-        data: "SpaceCount",
-        renderer: tools.num,
+        data: "SpaceList",
+        renderer: (instance, td, row, col, prop, value, cellProperties) => {
+          td.style.color = "#409EFF";
+          td.innerHTML = `<span>${value?value.length:0}</span>`
+          return td;
+        },
         readOnly: true
-      },{
+      }, {
         data: "OtheRelations",
         renderer: (instance, td, row, col, prop, value, cellProperties) => {
           td.style.color = "#409EFF";
@@ -343,13 +341,13 @@ export default {
       //其他的开始判断
       let val = this.tableExample.colToProp(row.col)
       let inputMode = this.inputMap[val]
-      let name = infos.ShaftLocalName?infos.ShaftLocalName:infos.ShaftName
+      let name = infos.ShaftLocalName ? infos.ShaftLocalName : infos.ShaftName
       this.shaftId = infos.ShaftID //要操作的数据id
       //点击关联的元空间
-      if (val === "SpaceCount") {
+      if (val === "SpaceList") {
         this.$router.push({
-          path:'/ledger/relatedSpace',
-          query:{ShaftId: this.shaftId,name:name,onlyRead:this.onlyRead}
+          path: '/ledger/relatedSpace',
+          query: { ShaftId: this.shaftId, name: name, onlyRead: this.onlyRead }
         })
         return false
       } else if (val === "OtheRelations") {
@@ -375,7 +373,7 @@ export default {
       this.updateInput = ''
     },
     //更新临时维护信息点
-    handleClickUpdate(){
+    handleClickUpdate() {
       tools.setDataForKey(this.tableData[this.row], this.updateInfoPoint, this.updateInput)
       this.handleUpdataTable([[this.row, this.updateInfoPoint, null, this.updateInput]], "edit")
       this.updateInputShow = false
@@ -489,7 +487,7 @@ export default {
                         item,
                         head.Path,
                         // child.error ? "表号功能号格式错误" : "表号功能号不存在"
-                        child.error ? child.value? "表号功能号格式错误" : "表号功能号不存在" : "暂未采集到实时数据"
+                        child.error ? child.value ? "表号功能号格式错误" : "表号功能号不存在" : "暂未采集到实时数据"
                       );
                     }
                   });
@@ -535,7 +533,7 @@ export default {
       padding: 5px 15px;
       margin-right: 5px;
       box-shadow: 0px 1px 5px 0px rgba(59, 66, 84, 0.15);
-      .table_right_box::after{
+      .table_right_box::after {
         display: block;
         content: "";
         clear: both;
@@ -547,7 +545,8 @@ export default {
     }
   }
 }
-.el-pagination button, .el-pagination span:not([class*=suffix]) {
-    vertical-align: middle;
+.el-pagination button,
+.el-pagination span:not([class*="suffix"]) {
+  vertical-align: middle;
 }
 </style>

+ 17 - 15
src/views/ledger/cenotelist/relatedSpace.vue

@@ -7,7 +7,7 @@
           <el-button v-if="isMyTab == 2" size="small" style="float:right" @click="dialogVisible = true">添加</el-button>
           <div v-else>
             <el-button v-show="!isEdit" @click="isEdit = true" size="small" style="float:right">编辑</el-button>
-            <el-button v-show="isEdit" size="small" @click="saveEdit" style="float:right">保存</el-button>
+            <el-button v-show="isEdit" size="small" type="primary" @click="saveEdit" style="float:right">保存</el-button>
             <el-button v-show="isEdit" size="small" @click="cancelEdit" style="float:right">取消</el-button>
           </div>
           <addSpaceDialog :dialogVisible.sync="dialogVisible" ref="addSpaceDialog" @refresh="refresh" :params="cenoteObj" :spaceType="spaceType"
@@ -34,20 +34,22 @@
             <el-option v-for="item in buildingList" :key="item.value" :label="item.BuildLocalName" :value="item.BuildID"></el-option>
           </el-select>
         </el-badge>
-        <div style="height:calc(100% - 42px);margin:10px 0 0 0;width:100%;position:relative;">
-          <el-scrollbar style="height:100%;width:148px;border:1px solid rgb(201,201,201);margin:0px;float:left;">
-            <div class="floor" style="width:149px;height:100%;">
-              <span class="floor-item" style="border-bottom:1px solid rgb(201,201,201)">楼 层</span>
-              <div v-if="building" v-loading="buildingLoading">
-                <span class="floor-item" @click="changeFloor(item.FloorID)" :class="{floorItemChoose:(item.FloorID == floor)}"
-                  v-for="item in buildingObj.Floor" :key="item.FloorID">{{ item.FloorLocalName }}</span>
+        <el-row style="height:calc(100% - 42px);margin:10px 0 0 0;width:100%;position:relative;">
+          <el-col :span="3" style="height:100%;border:1px solid #e4e4e4;">
+            <el-scrollbar style="height:100%;">
+              <div class="floor" style="height:100%;text-align:center;">
+                <span class="floor-item" style="border-bottom:1px solid #e4e4e4;">楼 层</span>
+                <div v-if="building" v-loading="buildingLoading">
+                  <span class="floor-item" @click="changeFloor(item.FloorID)" :class="{floorItemChoose:(item.FloorID == floor)}"
+                    v-for="item in buildingObj.Floor" :key="item.FloorID">{{ item.FloorLocalName }}</span>
+                </div>
               </div>
-            </div>
-          </el-scrollbar>
-          <div style="float:right;height:100%;width:calc(100% - 151px);border:1px solid rgb(201,201,201);border-left:none;">
+            </el-scrollbar>
+          </el-col>
+          <el-col :span="21" style="height:100%;border:1px solid #e4e4e4;border-left:none;">
             <cenote-graphy ref="cenotegraphy"></cenote-graphy>
-          </div>
-        </div>
+          </el-col>
+        </el-row>
 
       </div>
       <div v-show="isMyTab == 2" class="data-item">
@@ -312,7 +314,7 @@ export default {
   background: #fff;
   .header {
     padding-bottom: 10px;
-    border-bottom: 1px solid rgba(0, 0, 0, 0.5);
+    border-bottom: 1px solid #e4e4e4;
     span {
       line-height: 33px;
       margin-left: 15px;
@@ -389,7 +391,7 @@ export default {
   cursor: pointer;
 }
 .floorItemChoose {
-  background: rgba(0, 0, 0, 0.2);
+  background: #e4e4e4;
 }
 /deep/ .el-scrollbar__wrap {
   overflow-x: hidden;

+ 73 - 82
src/views/ledger/rentlist/index.vue

@@ -6,19 +6,11 @@
     <el-row class="left">
       <span style="float:right;">当前筛选条件下共{{page.total || '--'}}租户</span>
       <el-select v-model="onlyRead" @change="getTableHeader" style="width:100px;margin-right:10px;vertical-align:bottom;">
-        <el-option
-          v-for="item in options"
-          :key="item.value"
-          :label="item.label"
-          :value="item.value">
+        <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value">
         </el-option>
       </el-select>
       <el-select v-model="showType" @change="initTable" style="width:100px;margin-right:10px;vertical-align:bottom;">
-        <el-option
-          v-for="item in showTypes"
-          :key="item.value"
-          :label="item.label"
-          :value="item.value">
+        <el-option v-for="item in showTypes" :key="item.value" :label="item.label" :value="item.value">
         </el-option>
       </el-select>
       <!-- <div v-show="onlyRead" style="width:200px;display:inline-block;text-align:left;color:gray;font-size:12px;">
@@ -27,10 +19,11 @@
       </div> -->
       <el-button @click="handleCreateTableData">添加租户</el-button>
       <el-button @click="getTableHeader">刷新</el-button>
+      <el-button @click="mangeTenantZone">管理租赁空间</el-button>
       <el-button v-show="!onlyRead" @click="undo">撤销</el-button>
     </el-row>
     <div class="tableBox">
-      <div class="center middle_sty" style="flex:2;" v-show="tableData && !tableData.length">
+      <div class="center middle_sty" style="flex:1;" v-show="tableData && !tableData.length">
         <p>
           <i class="icon-wushuju iconfont"></i>
           暂无数据
@@ -39,34 +32,9 @@
       <div class="tableLeft" v-show="tableData && tableData.length">
         <handson-table ref="table"></handson-table>
       </div>
-      <div class="tableRight">
-        <div v-show="isTableRightShow">
-          <div class="table_right_box"><span class="iconfont close_right" @click="handleCloseRight">&#xe66b;</span></div>
-          <h5>管理租赁空间</h5>
-          <p style="margin-bottom: 10px;">以下为关联的业务空间id</p>
-          <el-input
-            type="textarea"
-            :autosize="{ minRows: 6, maxRows: 10}"
-            :disabled="onlyRead"
-            placeholder="请输入业务空间id,以“,”分割"
-            v-model="roomId">
-          </el-input>
-          <el-row class="right" v-show="!onlyRead">
-            <el-button @click="handleCloseRight">取消</el-button>
-            <el-button type="primary" @click="saveSpaceList">保存</el-button>
-          </el-row>
-        </div>
-      </div>
     </div>
-    <el-pagination
-      class="right"
-      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"
+    <el-pagination class="right" 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>
     <!-- 不支持的输入方式 -->
@@ -82,6 +50,8 @@
         <el-button type="primary" @click="handleClickUpdate">确 认</el-button>
       </span>
     </el-dialog>
+    <!-- 右侧关联的业务空间抽屉 -->
+    <roomCountDrawer ref="roomCountDrawer" :readonly="onlyRead" @refresh="getTableData"></roomCountDrawer>
   </div>
 </template>
 <script>
@@ -89,15 +59,16 @@ import tools from "@/utils/scan/tools"
 import handsonUtils from "@/utils/hasontableUtils"
 import showTools from "@/utils/handsontable/notShow"
 import text from "@/utils/handsontable/mainText"
-
+import roomCountDrawer from "@/components/ledger/rentList/roomCountDrawer"
 import floorCascader from "@/components/ledger/lib/floorCascader"
 import handsonTable from "@/components/common/handsontable"
-import { getDataDictionary, getRentTableHeader, getRentTableData, updataRentTableData, deleteRentTableData, saveRentRelateSpace, BeatchQueryParam } from "@/api/scan/request"
+import { getDataDictionary, getRentTableHeader, queryRentTableData, updataRentTableData, deleteRentTableData, saveRentRelateSpace, BeatchQueryParam } from "@/api/scan/request"
 import { mapGetters, mapActions } from "vuex";
 export default {
   components: {
     floorCascader,
-    handsonTable
+    handsonTable,
+    roomCountDrawer
   },
   data() {
     return {
@@ -137,35 +108,31 @@ export default {
     };
   },
   computed: {
-    ...mapGetters("layout", [
-        "projectId",
-        "secret",
-        "userId"
-    ]),
-    showTypes () {
-      return this.onlyRead?
-        [{value: "Visible", label: '只看采集信息'}, {value: "all", 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: '全部' }, { value: "Visible", label: '只看采集信息' }]
     }
   },
   created() {
     this.getTableHeader()
   },
   watch: {
-      projectId() {
-        this.getTableHeader()
+    projectId() {
+      this.getTableHeader()
+    },
+    showTypes: {
+      handler(newName, oldName) {
+        if (newName && newName[0] && newName[0].value) {
+          this.showType = newName[0].value
+        } else {
+          this.showType = ""
+        }
       },
-      showTypes: {
-        handler(newName, oldName) {
-          if (newName && newName[0] && newName[0].value) {
-            this.showType = newName[0].value
-          } else {
-            this.showType = ""
-          }
-        },
-        immediate: true,
-        deep: true
-      }
+      immediate: true,
+      deep: true
+    }
   },
   methods: {
     // 获取表头数据(初始化表格)
@@ -181,7 +148,7 @@ export default {
       await getDataDictionary(param, res => {
         this.tableHeader = res.Content;
         this.tableHeader.forEach(item => {
-          if(item.Path && item.InputMode){
+          if (item.Path && item.InputMode) {
             this.inputMap[item.Path] = item.InputMode
           }
         })
@@ -190,16 +157,20 @@ export default {
     },
     async getTableData() {//获取表格数据
       let params = {
+        Cascade: [
+          { Name: 'zoneTenantList', Cascade: [{ Name: 'building' }, { Name: 'floor' }] },
+          { Name: 'zoneGeneraltList', Cascade: [{ Name: 'building' }, { Name: 'floor' }] }
+        ],
         Orders: "createTime desc, TenantID asc",
         PageNumber: this.page.pageNumber,
         PageSize: this.page.pageSize
       }
-      await getRentTableData(params, (res) => {
+      await queryRentTableData(params, (res) => {
         this.tableData = res.Content
         this.copyTableData = tools.deepCopy(res.Content)
         this.page.pageNumber = res.PageNumber
         this.page.total = res.Total
-        if(this.tableData && this.tableData.length){
+        if (this.tableData && this.tableData.length) {
           if (this.onlyRead) {
             this.getBatch(res.Content)
           }
@@ -213,7 +184,7 @@ export default {
         Content: [],
         Projection: []
       }, keyList = [];
-       //生成要修改字段列表
+      //生成要修改字段列表
       change.map(item => {
         let key = item[1].split(".")[0]
         if (item[1] && keyList.indexOf(key) == -1) {
@@ -271,7 +242,7 @@ export default {
       }
       let param = []
       params.map(item => {
-        param.push({TenantID: item.TenantID})
+        param.push({ TenantID: item.TenantID })
       })
       this.$confirm("此操作将删除租户,是否继续?", "提示", {
         confirmButtonText: '确定',
@@ -339,7 +310,7 @@ export default {
     formatHeaderData(list) {//格式化表头显示的数据
       let arr = tools.copyArr(list)
       let data = showTools.headerTextFilter(arr, "tenant", this.onlyRead, this.showType)
-      data.unshift("操作","所属楼层","租赁空间");
+      data.unshift("操作", "所属楼层", "租赁空间");
       return data;
     },
     formatHeaderType(list) {//格式化表头头映射的数据
@@ -354,7 +325,21 @@ export default {
         readOnly: true
       }, {
         data: "RoomCount",
-        renderer: tools.num,
+        renderer: (instance, td, row, col, prop, value, cellProperties) => {
+          td.style.color = "#409EFF";
+          td.style.cursor = "pointer";
+          let num = 0;
+          let a = instance.getDataAtRowProp(row, 'ZoneGeneraltList')
+          let b = instance.getDataAtRowProp(row, 'ZoneTenantList')
+          if (a && a.length) {
+            num += a.length
+          }
+          if (b && b.length) {
+            num += b.length
+          }
+          td.innerHTML = num;
+          return td;
+        },
         readOnly: true
       })
       return data;
@@ -400,12 +385,13 @@ export default {
       }
       //点击关联的元空间
       if (val === "RoomCount") {
-        if(infos && infos.RoomID) {
-          this.roomId = infos.RoomID
-        } else {
-          this.roomId = ""
-        }
-        this.isTableRightShow = true;
+        // if (infos && infos.RoomID) {
+        //   this.roomId = infos.RoomID
+        // } else {
+        //   this.roomId = ""
+        // }
+        // this.isTableRightShow = true;
+        this.$refs.roomCountDrawer.showDrawer(infos)
         return false
       }
       if (!this.onlyRead && showTools.InputModeArr.indexOf(inputMode) == '-1') {
@@ -421,7 +407,7 @@ export default {
       this.updateInput = ''
     },
     //更新临时维护信息点
-    handleClickUpdate(){
+    handleClickUpdate() {
       tools.setDataForKey(this.tableData[this.row], this.updateInfoPoint, this.updateInput)
       this.handleUpdataTable([[this.row, this.updateInfoPoint, null, this.updateInput]], "edit")
       this.updateInputShow = false
@@ -535,7 +521,7 @@ export default {
                         item,
                         head.Path,
                         // child.error ? "表号功能号格式错误" : "表号功能号不存在"
-                        child.error ? child.value? "表号功能号格式错误" : "表号功能号不存在" : "暂未采集到实时数据"
+                        child.error ? child.value ? "表号功能号格式错误" : "表号功能号不存在" : "暂未采集到实时数据"
                       );
                     }
                   });
@@ -547,6 +533,10 @@ export default {
           this.tableExample.loadData(this.tableData);
         });
       }
+    },
+    // 跳转至管理租赁空间
+    mangeTenantZone() {
+      this.$router.push({ name: 'manageTenantZone', query: { onlyRead: this.onlyRead } })
     }
   }
 };
@@ -563,7 +553,7 @@ export default {
   }
   .search-header {
     overflow: hidden;
-    padding:0 10px 10px 10px;
+    padding: 0 10px 10px 10px;
     border-bottom: 1px solid #bcbcbc;
   }
   .tableBox {
@@ -581,7 +571,7 @@ export default {
       padding: 5px 15px;
       margin-right: 5px;
       box-shadow: 0px 1px 5px 0px rgba(59, 66, 84, 0.15);
-      .table_right_box::after{
+      .table_right_box::after {
         display: block;
         content: "";
         clear: both;
@@ -593,7 +583,8 @@ export default {
     }
   }
 }
-.el-pagination button, .el-pagination span:not([class*=suffix]) {
-    vertical-align: middle;
+.el-pagination button,
+.el-pagination span:not([class*="suffix"]) {
+  vertical-align: middle;
 }
 </style>

+ 634 - 0
src/views/ledger/rentlist/manageTenantZone.vue

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

+ 31 - 22
src/views/ledger/spacelist/index.vue

@@ -3,18 +3,12 @@
  -->
 <template>
   <div id="businessSpace">
-    <!------------------------    头部弹窗,选择楼层信息     -------------->
-    <!-- <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>
-    <not-related ref="notRelated" @createSuccess="createSuccess" :isShow="floor"></not-related>
-    <facility-dialog ref="facility" :activeTabType="activeTabType" :isShow="floor"></facility-dialog>
+    <!-- 空间属于多个建筑楼层 -->
+    <!-- <roomInFloorDialog ref="roomInFloorDialog"></roomInFloorDialog> -->
     <!--------- 页面头部   -------------->
-    <div class="saga-title">
+    <div class="saga-title" v-show="1">
       <div class="saga-build-mess">
-        <!-- <span style="padding-right:12px;color:#999999;">建筑楼层</span> -->
         <floorCascader @change="changeCascader" ref="floorCascader"></floorCascader>
-        <!-- <el-cascader :options="options" v-model="buildFloorSelectd" :props="props" @change="changeCascader"></el-cascader> -->
       </div>
       <div class="saga-build-tab">
         <el-radio-group v-model="isMyTab" @change="changeRadio" style="width: 136px;">
@@ -22,8 +16,9 @@
           <el-radio-button label="2" class="space-own-radio" style="width: 68px;">列表</el-radio-button>
         </el-radio-group>
       </div>
+      <!-- <div class="saga-build-tips" v-if="1" @click="getTips">有25个空间同时属于多个建筑楼层,点击处理</div> -->
     </div>
-    <div class="saga-business-sapce-main">
+    <div class="saga-business-sapce-main" v-show="1">
       <el-row class="spaceTypes">
         <div class="types">
           <el-tabs v-model="activeName" type='card' @tab-click="tabClick">
@@ -40,16 +35,24 @@
         <handsontable-main @lookEqu="lookEqu" ref="handsontable" :zoneCode="activeName" :id="`handsontable${activeName}`"></handsontable-main>
       </div>
     </div>
+    <div v-show="0" style="display:flex;align-items:center;justify-content:center;height:100%;background-color:#fff;">
+      <div class="center" style="flex:1">
+        <i class="iconfont icon-jianzhu" style="font-size:50px;"></i>
+        <p style="margin:10px 0;">设备空间关系已产生变化,请请前往关系总览重新计算</p>
+        <el-button>立即跳转</el-button>
+      </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 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 graphy from "@/components/business_space/graphy/business";
 import graphy from "@/components/business_space/newGraphy/graphy";
+import roomInFloorDialog from "@/components/business_space/newAddDialogs/roomInFloorDialog";
 import handsontableMain from "@/components/business_space/business/handsontable";
 import {
   getDataDictionary,
@@ -63,13 +66,9 @@ import floorCascader from "@/components/ledger/lib/floorCascader";
 import { mapGetters, mapActions } from "vuex";
 export default {
   components: {
-    noModelDialog,
-    influenceDialog,
-    detailsDialog,
-    notRelated,
     graphy,
     handsontableMain,
-    facilityDialog,
+    roomInFloorDialog,
     floorCascader,
   },
   computed: {
@@ -215,7 +214,7 @@ export default {
     // 判断切换至图还是表
     changeGraphyOrTable(num) {
       this.activeTabType = this.getItemForType()
-      if(!this.buildFloorSelectd[0]) {
+      if (!this.buildFloorSelectd[0]) {
         this.$message.warning('请选择建筑楼层')
         return
       };
@@ -271,6 +270,10 @@ export default {
       this.floor.facility = true
       this.$refs.facility.getData(infos, this.buildMess)
     },
+    // 空间属于多个建筑楼层
+    getTips() {
+      this.$refs.roomInFloorDialog.showDialog();
+    }
   },
   watch: {
     floor: {
@@ -308,7 +311,6 @@ export default {
     font-size: 14px;
     position: relative;
     line-height: 54px;
-    width: 99.5%;
     margin-bottom: 10px;
     border: 1px solid #dfe6ec;
     .saga-build-mess {
@@ -362,6 +364,13 @@ export default {
         color: #fff;
       }
     }
+    .saga-build-tips {
+      float: right;
+      margin-right: 10px;
+      font-size: 12px;
+      color: #409eff;
+      cursor: pointer;
+    }
   }
   .saga-business-sapce-main {
     overflow: hidden;

+ 9 - 3
src/views/model/file/index.vue

@@ -83,7 +83,7 @@ import changeFolderName from "@/components/model/file/changeFolderName"; //编
 import floorTable from "@/components/model/file/floorTable"; //右侧list表
 export default {
   computed: {
-    ...mapGetters("layout", ["projectId", "userInfo", "userId", "secret"])
+    ...mapGetters("layout", ["projectId", "userInfo", "userId", "secret", "uploaderList"])
   },
   components: {
     dasBoard,
@@ -242,6 +242,12 @@ export default {
                   });
                 }
               }
+
+              //删除错误模型(多人登录会有问题)
+              /****状态为0,上传人为本人并且上传列表无对应的模型文件 */
+              // if (item.Status == 0 && item.UserName == this.userInfo.userName && !this.uploaderList.some(file => {return file.modelId == item.CurrentModelId})) {
+              //   request.deleteModelFileList(item.CurrentModelId, res => {console.log('删除错误模型:',item.CurrentModelId)})
+              // }
             });
             this.tableData = res.Content;
             this.loading = false;
@@ -306,8 +312,8 @@ export default {
         });
         this.queryFloorFile(this.currentFolderId);
         Bus.$emit('openUploader', { 
-          uploadId: res.uploadId, 
-          modelId: res.modelId,
+          uploadId: res.UploadId, 
+          modelId: res.ModelId,
           systemId: 'revit', //系统名称
           secret: '63afbef6906c342b', //系统密码
         }, data.file.raw)

+ 4 - 4
src/views/point/config_point/steps/step1.vue

@@ -22,8 +22,8 @@
         <own-dialog :width="'500px'" :index="true" title="导出excel模板" :dialogVisible="downloadExcel" :footer="footer" @cancel="close" @confirm="download">
             <span>请选择要导出的模板</span>
             <el-select v-model="exportTemplate" placeholder="请选择模板">
-                <el-option label="模板一" value="0"></el-option>
-                <el-option label="模板二" value="1" :disabled="protocolType!='common'"></el-option>
+                <el-option label="标准模版" value="0"></el-option>
+                <el-option label="设备采集多个参数模版" value="1" :disabled="protocolType!='common'"></el-option>
             </el-select>
         </own-dialog>
         <own-dialog :width="'500px'" :index="true" :footer="footer" title="导入excel" :dialogVisible="updateExcel" @confirm="sureOfUpload" @cancel="close">
@@ -34,8 +34,8 @@
             <div>
                 <span>请选择要导入的模板</span>
                 <el-select v-model="importTemplate" placeholder="请选择模板">
-                    <el-option label="模板一" value="0"></el-option>
-                    <el-option label="模板二" value="1" :disabled="protocolType!='common'"></el-option>
+                    <el-option label="标准模版" value="0"></el-option>
+                    <el-option label="设备采集多个参数模版" value="1" :disabled="protocolType!='common'"></el-option>
                 </el-select>
             </div>
             <div>

+ 2 - 2
src/views/ready/buildfloor/drawGraphy/drawFloor.vue

@@ -104,7 +104,6 @@ export default {
       this.drawMainScene.isSpaceSelectable = false;
 
       if (this.$refs.canvasFun) {
-        this.view.maxScale = this.view.scale * 10;
         this.view.minScale = this.view.scale;
         this.$refs.canvasFun.everyScale = this.view.scale;
       }
@@ -206,7 +205,8 @@ export default {
     "view.scale": {
       handler(n) {
         if (this.$refs.canvasFun) {
-          this.$refs.canvasFun.sliderVal = n * 10 / this.view.minScale;
+          let s = n * 10 / this.view.minScale
+          this.$refs.canvasFun.sliderVal = s > 1000 ? 1000 : s;
         }
       }
     },

+ 18 - 4
src/views/ready/buildfloor/repetitionGraphy.vue

@@ -7,6 +7,7 @@
       <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>
+      <span style="float:right;" v-if="file.FolderName">当前对应的模型文件:{{file.FolderName}}{{file.FloorName}}</span>
     </div>
     <!-- 展示图片 -->
     <div class="drawImg">
@@ -20,6 +21,7 @@
 import drawFloor from "./drawGraphy/drawFloor";
 import checkGraphy from "./drawGraphy/checkGraphy"; //查看图片
 import { floorUpdate } from "@/api/scan/request";
+import { getFileNameById } from "@/api/model/file";
 export default {
   components: {
     drawFloor,
@@ -27,14 +29,16 @@ export default {
   },
   data() {
     return {
-      // modelId: "", // 
+      modelId: "", // 
       isEdit: false, // 是否编辑模式
+      file: {}
     };
   },
   created() {
-    // this.modelId = this.$route.query.modelId;
+    this.modelId = this.$route.query.modelId;
     this.FloorID = this.$route.query.FloorID;
     this.BuildID = this.$route.query.BuildID;
+    this.getFileName(this.modelId)
   },
   mounted() { },
   methods: {
@@ -87,8 +91,18 @@ export default {
     },
     // 替换模型文件成功
     refresh(modelId) {
-      // this.modelId = modelId
-      this.$refs.drawFloor.init();
+      this.modelId = modelId;
+      this.getFileName(this.modelId)
+    },
+    // 获取文件夹名称
+    getFileName(modelId) {
+      if (!modelId) return
+      let pa = {
+        Id: modelId
+      }
+      getFileNameById(pa, res => {
+        this.file = res;
+      })
     }
   },
   watch: {

+ 211 - 0
src/views/relation/data/index.vue

@@ -0,0 +1,211 @@
+<template>
+  <div class="container">
+    <div class="banner">
+      <section class="table-text">
+        <span>共有项目化字典类型:{{allCount}}</span>
+        <span>需从物理世界补全“继承”规则的:{{filterCount}}</span>
+        <el-button
+            type="primary"
+            @click="resetTransformation"
+            :disabled="isDisabled"
+        >重新转换
+        </el-button>
+        <span
+            class="iconfont icon-guizeyingyong"
+            @click="dataTable"
+        ></span>
+        <span>需补充转换规则的:{{replenishCount}}</span>
+      </section>
+    </div>
+    <el-row :gutter="24">
+      <el-col :span="12">
+        <p class="border-left-8">标准数字化交付数据(数据中心)→(物理世界)项目实际数据</p>
+        <el-table
+            :data="margeData(dataCenter)"
+            stripe
+            style="width: 100%"
+            :header-cell-style="{background:'#d9d9d9',color:'#606266'}"
+        >
+          <el-table-column
+              prop="title"
+              label="标准字典类型"
+              align="center"
+          />
+          <el-table-column
+              prop="Count"
+              label="不能项目化的实例数量"
+              align="center"
+          />
+        </el-table>
+      </el-col>
+      <el-col :span="12" style="padding-left: 0">
+        <p class="border-left-8">项目实际数据(物理世界)→(数据中心)标准数字化交付数据</p>
+        <el-table
+            :data="margeData(dataPlatForm)"
+            stripe
+            style="width: 100%"
+            :header-cell-style="{background:'#d9d9d9',color:'#606266'}"
+        >
+          <el-table-column
+              prop="title"
+              align="center"
+              label="项目化字典类型"
+          />
+          <el-table-column
+              prop="Count"
+              align="center"
+              label="不能标准化的实例数量"
+          />
+        </el-table>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+  import {createEquip, dictCount, dictDataCenter, dictDataPlatFrom, dictSwitchCount} from '../../../api/relation/api'
+  import {mapActions, mapGetters, mapState} from 'vuex'
+
+  export default {
+    name: "index",
+    data() {
+      return {
+        allCount: '',
+        filterCount: '',
+        replenishCount: '',
+        dataCenter: [],
+        dataPlatForm: [],
+        isDisabled: true,
+      }
+    },
+    computed: {
+      ...mapGetters('layout', ['projectId']),
+      ...mapState('layout', ['rowEdit'])
+
+    },
+    watch: {
+      projectId() {
+        this.init();
+      }
+    },
+    created() {
+      this.init()
+    },
+    methods: {
+      ...mapActions('layout', ['setRowEdit']),
+      init() {
+        //  统计数量
+        let count = {
+          projectId: this.projectId
+        }
+        dictCount(count, res => {
+          this.allCount = res.Count
+        })
+        //需要转换数量
+        dictSwitchCount(count, res => {
+          this.replenishCount = res.Count
+          if (res.Count === 0) {
+            this.isDisabled = true
+            return
+          }
+        })
+        //数据中心-物理世界数据转换
+        dictDataCenter(count, res => {
+          this.dataCenter = res.Content
+        })
+        // 物理世界-数据中心数据转换
+        dictDataPlatFrom(count, res => {
+          this.dataPlatForm = res.Content
+        })
+        //条件查询数量
+        let filterCount = {
+          projectId: this.projectId,
+          "Filters": "type!=1;dcCategory isnull"
+        }
+        dictCount(filterCount, res => {
+          this.filterCount = res.Count
+        })
+        this.diss()
+      },
+      diss() {
+        this.isDisabled = this.rowEdit ? false : true
+      },
+      dataTable() {
+        this.$router.push({
+          path: "datatable",
+          // query: {
+          //   id: 1,
+          //   qq: 2
+          // }
+        })
+      },
+
+      margeData(arr) {
+        if (arr.length) {
+          let arrList = arr.map(item => {
+            let title = item.CategoryName ? item.CategoryName : '未知'
+            item = {
+              ...item,
+              title: `${title}(编码${item.Category})`
+            }
+            return item
+          })
+          return arrList
+        } else {
+          return []
+        }
+
+      },
+      resetTransformation() {
+        this.isDisabled = true
+        this.setRowEdit(false)
+        let param = {
+          projectId: this.projectId
+        }
+        createEquip(param, res => {
+        })
+      }
+    },
+
+  }
+</script>
+
+<style scoped lang="less">
+  .container {
+    overflow-x: hidden;
+    .border-left-8 {
+      border-left: 8px solid black;
+      margin: 10px 0;
+      font-weight: 600;
+      text-indent: 10px;
+    }
+
+    .banner {
+      border: 1px solid #dfe6ec;
+      background: #fff;
+
+      .table-text {
+        height: 30px;
+        line-height: 30px;
+        margin: 8px;
+        font-weight: 600;
+        cursor: default;
+
+        span:nth-child(2) {
+          margin-left: 40px;
+        }
+
+        span:nth-child(4), span:nth-child(5), button {
+          float: right;
+          margin-left: 20px;
+        }
+
+        span:nth-child(4) {
+          font-size: 25px;
+          cursor: pointer;
+        }
+      }
+    }
+  }
+
+</style>

+ 313 - 0
src/views/relation/datatable/index.vue

@@ -0,0 +1,313 @@
+<template>
+  <div class="data-table">
+    <div style="margin-top: 20px">
+      <el-button
+          style="padding: 10px"
+          icon="el-icon-back"
+          @click="back"
+      />
+      <label>维护对象类型:</label>
+<!--      <el-select-->
+<!--          v-model="value"-->
+<!--          clearable-->
+<!--          placeholder="请选择"-->
+<!--          @change="changOptions"-->
+
+<!--      >-->
+<!--        <el-option-->
+<!--            v-for="(item,index) in options"-->
+<!--            :key=index-->
+<!--            :label="item.label"-->
+<!--            :value="item.value"-->
+<!--        />-->
+        <el-select disabled v-model="deviceCls">
+        <el-option :value="deviceCls"/>
+      </el-select>
+    </div>
+    <el-table
+        :data="tableList"
+        style="width: 100%;margin-top: 30px"
+        v-loading="loading"
+    >
+      <el-table-column
+          label="L1(专业)"
+          align="center"
+      >
+        <el-table-column
+            prop="major"
+            label="编码"
+            width="120"
+            align="center"
+        >
+        </el-table-column>
+        <el-table-column
+            prop="majorName"
+            label="名称"
+            width="120"
+            align="center"
+        >
+        </el-table-column>
+      </el-table-column>
+      <el-table-column
+          label="L2(系统)"
+          align="center"
+      >
+        <el-table-column
+            prop="sys"
+            label="编码"
+            width="120"
+            align="center"
+        >
+        </el-table-column>
+        <el-table-column
+            prop="sysName"
+            label="名称"
+            width="120"
+            align="center"
+        >
+        </el-table-column>
+      </el-table-column>
+      <el-table-column
+          label="L3(设备)"
+          align="center"
+      >
+        <el-table-column
+            prop="device"
+            label="编码"
+            width="120"
+            align="center"
+        >
+        </el-table-column>
+        <el-table-column
+            prop="deviceName"
+            label="名称"
+            width="120"
+            align="center"
+        >
+        </el-table-column>
+      </el-table-column>
+      <el-table-column
+          label="L4(部件)"
+          align="center"
+      >
+        <el-table-column
+            prop="unit"
+            label="编码"
+            width="120"
+            align="center"
+        >
+        </el-table-column>
+        <el-table-column
+            prop="unitName"
+            label="名称"
+            width="120"
+            align="center"
+        >
+        </el-table-column>
+      </el-table-column>
+      <el-table-column
+          label="继承标准设备类"
+          align="center"
+      >
+        <el-table-column
+            prop="dc"
+            label="编码"
+            width="120"
+            align="center"
+        >
+        </el-table-column>
+        <el-table-column
+            prop="dcName"
+            label="名称"
+            width="120"
+            align="center"
+        >
+        </el-table-column>
+
+      </el-table-column>
+      <el-table-column
+          label="手动维护转换规则"
+          align="center"
+      >
+        <el-table-column
+            label="数据中心转物理世界"
+            align="center"
+        >
+          <template slot-scope="scope">
+            <el-input
+                v-model="scope.row.SwitchRule"
+                :disabled="scope.row.type != 1"
+                @change="dataAndGlobal(scope.$index,scope.row,1)"
+            ></el-input>
+
+          </template>
+        </el-table-column>
+        <el-table-column
+            label="物理世界转数据中心"
+            align="center"
+        >
+          <template slot-scope="scope">
+            <el-input
+                v-model="scope.row.SwitchRuleDataplatform"
+                :disabled="scope.row.type != 1"
+                @change="dataAndGlobal(scope.$index,scope.row,2)"
+            ></el-input>
+          </template>
+        </el-table-column>
+
+      </el-table-column>
+    </el-table>
+  </div>
+</template>
+
+<script>
+  import {dectInfo, dictUpdate} from '../../../api/relation/api'
+  import {mapActions, mapGetters, mapState} from 'vuex'
+
+  export default {
+    name: "index",
+    data() {
+      return {
+        deviceCls:'项目设备类',
+        value: '',
+        loading: false,
+        dataValue: '',
+        tableList: []
+      }
+    },
+    created() {
+      this.$store.dispatch('setBreadcrumb', [{
+        label: '项目数据转换',
+        path: '/relation/data'
+      }, {
+        label: '项目数据转换',
+        path: '/relation/data'
+      }, {
+        label: '手动维护转换规则'
+      }])
+      //    获取表单数据
+      let param = {
+          projectId: this.projectId,
+          "Filters": "DatacenterSign = 1",
+          "Orders": "dcCategory",
+          "PageNumber": 1,
+          "PageSize": 1000,
+      }
+      this.loading = true
+      dectInfo(param).then(res=> {
+        this.loading = false
+        if(res.data.Result === 'success') {
+          res.data.Content.length && res.data.Content.forEach(i => {
+            this.tableList.push({
+              majorName: i.CustomCategoryName,
+              major: i.CustomCategory,
+              dcName: i.DcCategoryName,
+              dc: i.DcCategory,
+              SwitchRule: '',
+              SwitchRuleDataplatform: '',
+              DatacenterSign: '',
+              DataplatformSign: '',
+            })
+            i.Content.length && i.Content.forEach(j => {
+              this.tableList.push({
+                sysName: j.CustomCategoryName,
+                sys: j.CustomCategory,
+                dcName: j.DcCategoryName,
+                dc: j.DcCategory,
+                SwitchRule: '',
+                SwitchRuleDataplatform: '',
+                DatacenterSign: '',
+                DataplatformSign: '',
+              })
+              j.Content.length && j.Content.forEach(k => {
+                this.tableList.push({
+                  type: 1,
+                  deviceName: k.CustomCategoryName,
+                  device: k.CustomCategory,
+                  dcName: k.DcCategoryName,
+                  dc: k.DcCategory,
+                  DatacenterSign: k.DatacenterSign,
+                  DataplatformSign: k.DataplatformSign,
+                  SwitchRule: k.SwitchRule,
+                  SwitchRuleDataplatform: k.SwitchRuleDataplatform,
+                  SchemeId: k.SchemeId
+                })
+                k.Content.length && k.Content.forEach(l => {
+                  this.tableList.push({
+                    type: 1,
+                    unitName: l.CustomCategoryName,
+                    Unit: l.CustomCategory,
+                    dcName: l.DcCategoryName,
+                    dc: l.DcCategory,
+                    DatacenterSign: l.DatacenterSign,
+                    DataplatformSign: l.DataplatformSign,
+                    SwitchRule: l.SwitchRule,
+                    SwitchRuleDataplatform: l.SwitchRuleDataplatform,
+                    SchemeId: l.SchemeId
+                  })
+                })
+              })
+            })
+          })
+        } else {
+          this.$message({
+            message: res.data.Message,
+            type: 'error'
+          })
+          this.back()
+        }
+      })
+    },
+    computed: {
+      ...mapGetters('layout', ['projectId']),
+      ...mapState('layout', ['rowEdit'])
+    },
+    methods: {
+      ...mapActions('layout', ['setRowEdit']),
+      back() {
+        this.$router.go(-1)
+      },
+      changOptions(val) {
+        console.log(val)
+      },
+      dataAndGlobal(index, val, type) {
+        let param = []
+        if (type === 1) {
+          param.push({
+            projectId: this.projectId,
+            SchemeId: val.SchemeId,
+            CustomCategory: val.device,
+            SwitchRule: val.SwitchRule
+          })
+        }
+        if (type === 2) {
+          param.push({
+            projectId: this.projectId,
+            SchemeId: val.SchemeId,
+            CustomCategory: val.device,
+            SwitchRuleDataplatform: val.SwitchRuleDataplatform
+          })
+        }
+        dictUpdate(param, res => {
+          this.setRowEdit(true)
+        })
+      }
+    },
+
+  }
+</script>
+
+<style scoped lang="less">
+  .data-table {
+
+
+    .danger-color {
+      /deep/ .el-input__inner {
+        border-color: #f56c6c !important;
+      }
+    }
+    label {
+      margin-left: 20px;
+    }
+  }
+</style>

+ 111 - 49
src/views/relation/overview/index.vue

@@ -1,15 +1,29 @@
 <template>
-    <div style="overflow-x: hidden">
+    <div
+        style="overflow-x: hidden"
+        v-loading="loading"
+    >
         <cardList
             :content="content"
+            :source="source"
+            :TableVisibleMoreLoading="TableVisibleMoreLoading"
             @template="templateDown"
+            @calcSpecial="calcSpecial"
+            @openComputed="openComputed"
         />
     </div>
 </template>
 
 <script>
     import CardList from "@/components/relation/Overview/CardList"
-    import api from "../../../api/relation/api";
+    import {
+        blockQuery,
+        blockSource,
+        calcSpecial,
+        graphic,
+        graphicNumber,
+        sysDirection
+    } from "../../../api/relation/api";
     import {mapGetters} from 'vuex'
 
     export default {
@@ -91,53 +105,14 @@
                     //     ]
                     // }
                 ],
+                loading: false,
+                source: [],//源端数据
+                currentRelationTypeName: '',//当前点击图片的RelationTypeName
+                TableVisibleMoreLoading: false,
             }
         },
         created() {
-            let data = {
-                "Cascade": [{
-                    "Cascade": [{
-                        "Filters": `projectId = '${this.projectId}'`,
-                        "Name": "relationTypeProjectList"
-                    }],
-                    "Filters": " not parentId isnull",
-                    "Name": "childGraphicTypeList"
-                }],
-                "Filters": " parentId isnull ",
-                "PageNumber": 1,
-                "PageSize": 1000
-            }
-            let dataNumber = {
-                projectId: this.projectId
-            }
-            api.graphicNumber(dataNumber, resCount => {
-                this.countNumber = resCount.Content
-            })
-            api.graphic(data, res => {
-                this.content = res.Content.map(item => {
-                    // 二级从属关系
-                    (item.ChildGraphicTypeList != null) && item.ChildGraphicTypeList.forEach(child => {
-
-                        this.countNumber.forEach(number => {
-                            if (number.GraphTypeName === child.GraphTypeName) { //二级名字
-                                number.RelationTypeProjectList.forEach(counts => {
-                                    //对应子集
-                                    (child.RelationTypeProjectList != null) && child.RelationTypeProjectList.forEach(relation => {
-                                        if (relation.Id === counts.Id) {
-                                            relation.count = counts.Count
-                                        }
-                                    })
-                                })
-                            }
-                        })
-                    })
-                    return item
-                })
-                this.content = res.Content
-                console.log(this.content)
-                // this.transform(this.content, this.countNumber)
-
-            })
+            this.init()
 
         },
         computed: {
@@ -147,6 +122,36 @@
         },
         components: {CardList},
         methods: {
+            init() {
+                this.loading = true
+                let data = {
+                    "Cascade": [{
+                        "Cascade": [{
+                            "Filters": `projectId = '${this.projectId}'`,
+                            "Name": "relationTypeProjectList"
+                        }],
+                        "Filters": " not parentId isnull",
+                        "Name": "childGraphicTypeList"
+                    }],
+                    "Filters": " parentId isnull ",
+                    "PageNumber": 1,
+                    "PageSize": 1000
+                }
+                let dataNumber = {
+                    projectId: this.projectId
+                }
+                graphic(data, res => {
+
+                    graphicNumber(dataNumber, resCount => {
+                        this.countNumber = resCount.Content
+                        this.loading = false
+                        this.transform(res.Content, this.countNumber)
+                        this.content = res.Content
+                    })
+                })
+
+
+            },
             transform(list1, list2) {
                 let countInfo = {} // { GraphTypeName: { Id: count } }
                 list2.forEach(item => {
@@ -156,22 +161,79 @@
                         countInfo[item.GraphTypeName][r.Id] = r.Count
                     })
                 })
-
                 let changeList = []
                 list1.forEach(item => {
                     // 这里保存的是引用
-                    changeList.push(...item.ChildGraphicTypeList)
+                    if (item.ChildGraphicTypeList) {
+                        changeList.push(...item.ChildGraphicTypeList)
+                    }
                 })
-                changeList.forEach(item => {
+                changeList.length && changeList.forEach(item => {
                     let name = item.GraphTypeName
                     let rList = item.RelationTypeProjectList
                     rList.forEach(r => {
                         r.count = countInfo[name][r.Id]
                     })
                 })
+
+
             },
             templateDown() { //下载模板
+            },
+            calcSpecial(relation) {
+                this.TableVisibleMoreLoading = true//可能会很慢,加loading
+                this.currentRelationTypeName = relation.RelationTypeName
+                let param = {
+                    BuildingId: '',
+                    Domain: 'DomainPiping',
+                    ProjectId: this.projectId,
+                    SystemName: relation.RelationTypeName
+                }
+                calcSpecial(param, res => {
+                    let data = {
+                        projectId: this.projectId,
+                    }
+                    blockQuery(data, res => {
+                        //    获取源端数据
+                        this.TableVisibleMoreLoading = false
+                        this.source = res.Content
+                    })
+                })
+            },
+
+            openComputed(result) {
+                let param = {
+                    // BuildingId: '',
+                    Domain: 'DomainPiping',
+                    MepSystemType: '冷冻水供水管',
+                    ProjectId: this.projectId,
+                    SourceList: result
+                }
+                blockSource(param, res => { //覆盖源端数据
+                    //确定流向
+                    result.forEach(i => {
+                        let {BlockId, BuildingId, Domain, Source} = i
+                        this.DataSorting(
+                            BlockId,
+                            BuildingId,
+                            Domain,
+                            Source,
+                        )
+                    })
+                })
+            },
+            DataSorting(BlockId, BuildingId, Domain, isSource) {
+                let param = {
+                    BlockId,
+                    Domain,
+                    isSource,
+                    BuildingId,
+                    SystemName: this.currentRelationTypeName
+                }
+                sysDirection(param, res => {
+                })
             }
+
         }
     }
 </script>

+ 138 - 0
src/views/screen/splitscreen/equipledger/index.vue

@@ -0,0 +1,138 @@
+<template>
+  <div>
+    <div class='page-bar'>
+      <span>设备名称:</span>
+      <span>{{equip.EquipLocalName || equip.EquipName}}</span>
+      <span>(位置图片)</span>
+    </div>
+    <div class="page-content" id="page-content">
+      <div v-show="showCanvas">
+        <p>{{file.FolderName}}{{file.FloorName}}</p>
+        <canvas :height="cadHeight" :width="cadWidth" id="floorCanvas" :k="refreshCanvas"></canvas>
+      </div>
+      <div class="no-data" v-show="!showCanvas">
+        <div class="position-icon">
+          <i class="icon-wushuju iconfont"></i>
+          数据暂无
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { LocationPointScene, FloorView } from "@saga-web/cad-engine";
+import { getFileNameById } from "@/api/model/file";
+
+export default {
+  data() {
+    return {
+      equip: {},
+      file: {},
+      view: '',
+      scene: {},
+      cadWidth: 800,
+      cadHeight: 800,
+      showCanvas: true
+    }
+  },
+  mounted() {
+    this.cadWidth = document.getElementById('page-content').offsetWidth;
+    this.cadHeight = document.getElementById('page-content').offsetHeight;
+    this.equip = this.$route.query.equip;
+    this.init();
+  },
+  methods: {
+    init() {
+      if (this.equip.ModelId && this.equip.BIMLocation) {
+        this.showCanvas = true;
+        this.getGraphy();
+        this.getFileName();
+      } else {
+        this.showCanvas = false;
+      }
+    },
+    // 获取底图
+    getGraphy() {
+      this.clearGraphy();
+      this.scene = new LocationPointScene()
+      this.scene.getFloorData('/modelapi/base-graph/query', { ModelId: this.equip.ModelId }).then(res => {
+        this.getGraphtSuc(res)
+      })
+    },
+    getGraphtSuc(res) {
+      this.view.scene = this.scene;
+      this.view.fitSceneToView();
+      this.scene.isSpaceSelectable = false;
+      let obj = {
+        X: this.equip.LocationJson.X,
+        Y: -this.equip.LocationJson.Y
+      }
+      this.scene.addMarker(obj);
+    },
+    refreshCanvas() {
+      return new Date().getTime();
+    },
+    // 获取文件夹及文件名称
+    getFileName() {
+      let pa = { Id: this.equip.ModelId }
+      getFileNameById(pa, res => {
+        this.file = res
+      })
+    },
+    // 清空平面图
+    clearGraphy() {
+      if (this.view) {
+        this.view.scene = null;
+        return
+      }
+      let id = `floorCanvas`;
+      this.view = new FloorView(id)
+    },
+  },
+  watch: {
+    $route(to, from) {
+      let equip = this.$route.query.equip || {};
+      if (equip.EquipID && equip.EquipID != this.equip.EquipID) {
+        this.equip = equip;
+        this.init()
+      }
+    }
+  },
+}
+</script>
+
+<style lang="scss" scoped>
+$borderColor: rgba(201, 201, 201, 1);
+.page-bar {
+  flex-grow: 0;
+  flex-shrink: 0;
+  height: 24px;
+  padding: 0 10px;
+  margin-bottom: 10px;
+  border-bottom: 1px solid $borderColor;
+}
+.page-content {
+  position: relative;
+  height: 100%;
+  border: 1px solid $borderColor;
+  p {
+    padding: 10px 16px;
+  }
+  canvas {
+    top: 0;
+  }
+  .no-data {
+    height: 100%;
+    text-align: center;
+    box-sizing: border-box;
+    position: relative;
+    .position-icon {
+      position: absolute;
+      top: 50%;
+      left: 50%;
+      transform: translate(-50%, -50%);
+    }
+  }
+}
+</style>

+ 5 - 0
src/views/screen/splitscreen/index.vue

@@ -62,6 +62,11 @@ export default {
           path:'/splitScreen/integrateresults',
           query: data.data
         })
+      }  else if (data.path && data.path == '/ledger/facility') {//设备位置图
+        this.$router.push({
+          path:'/splitScreen/equipledger',
+          query: data.data
+        })
       } else {
         this.$router.push({
           path:'/splitScreen'