haojianlong 5 lat temu
rodzic
commit
4fbd3fa201
100 zmienionych plików z 7011 dodań i 553 usunięć
  1. 4 2
      config/dev.env.js
  2. 8 2
      config/index.js
  3. 6 4
      config/prod.env.js
  4. 6 3
      package.json
  5. 291 0
      src/api/model/file.js
  6. 9 1
      src/api/scan/config.js
  7. 3 4
      src/api/scan/httpUtil.js
  8. 221 29
      src/api/scan/request.js
  9. 1 1
      src/assets/graphy/SGraphy/dataType.ts
  10. 26 6
      src/assets/graphy/SGraphy/mainScene.js
  11. 26 6
      src/assets/graphy/SGraphy/mainScene.ts
  12. 2 2
      src/assets/graphy/SGraphy/newItems/SGraphyCircleItem.js
  13. 2 2
      src/assets/graphy/SGraphy/newItems/SGraphyCircleItem.ts
  14. 7 3
      src/assets/graphy/SGraphy/newItems/SGraphyImgItem.js
  15. 13 4
      src/assets/graphy/SGraphy/newItems/SGraphyImgItem.ts
  16. 70 0
      src/assets/graphy/SGraphy/newItems/SGraphyPointItem.js
  17. 67 0
      src/assets/graphy/SGraphy/newItems/SGraphyPointItem.ts
  18. 3 2
      src/assets/graphy/SGraphy/newItems/SGraphyPolygonItem.js
  19. 3 2
      src/assets/graphy/SGraphy/newItems/SGraphyPolygonItem.ts
  20. 1 1
      src/assets/graphy/SGraphy/newItems/SGraphyRectItem.js
  21. 2 2
      src/assets/graphy/SGraphy/newItems/SGraphyRectItem.ts
  22. 1 2
      src/assets/graphy/SGraphy/newItems/SGraphyWallItem.js
  23. 1 2
      src/assets/graphy/SGraphy/newItems/SGraphyWallItem.ts
  24. 13 1
      src/assets/scss/point/point_config/reset.scss
  25. 62 6
      src/assets/style/iconfont/iconfont.css
  26. BIN
      src/assets/style/iconfont/iconfont.eot
  27. 42 0
      src/assets/style/iconfont/iconfont.svg
  28. BIN
      src/assets/style/iconfont/iconfont.ttf
  29. BIN
      src/assets/style/iconfont/iconfont.woff
  30. 6 0
      src/assets/style/style.scss
  31. 96 99
      src/components/business_space/business/handsontable.vue
  32. 4 2
      src/components/business_space/dialogs/detailsDialog.vue
  33. 42 8
      src/components/business_space/graphy/business.vue
  34. 272 0
      src/components/business_space/newAddDialogs/addEquipDialog.vue
  35. 111 0
      src/components/business_space/newAddDialogs/addSystemDialog.vue
  36. 150 0
      src/components/business_space/newGraphy/canvasFun.vue
  37. 34 0
      src/components/business_space/newGraphy/createBSP.vue
  38. 613 0
      src/components/business_space/newGraphy/graphy.vue
  39. 67 0
      src/components/business_space/newGraphy/unRelateBSP.vue
  40. 172 0
      src/components/business_space/newTables/eqToSpaceTable.vue
  41. 135 0
      src/components/business_space/newTables/syInSpaceTable.vue
  42. 1 1
      src/components/business_space/table/addEquip.vue
  43. 4 3
      src/components/business_space/table/businessTable.vue
  44. 3 2
      src/components/config_point/dictionaryCascader.vue
  45. 2 0
      src/components/config_point/step3_edit/index.vue
  46. 2 0
      src/components/config_point/step3_point/3_temps.vue
  47. 147 0
      src/components/dialogs/config/infoPoint.vue
  48. 179 0
      src/components/ledger/cenote/dialog/addCenoteDialog.vue
  49. 187 0
      src/components/ledger/cenote/dialog/addEquipDialog.vue
  50. 147 0
      src/components/ledger/cenote/dialog/addSystemDialog.vue
  51. 155 0
      src/components/ledger/cenote/table/cenoteTable.vue
  52. 143 0
      src/components/ledger/cenote/table/deviceTable.vue
  53. 145 0
      src/components/ledger/cenote/table/systemTable.vue
  54. 128 56
      src/components/ledger/handsontables/assets.vue
  55. 166 54
      src/components/ledger/handsontables/device.vue
  56. 49 4
      src/components/ledger/handsontables/system.vue
  57. 2 2
      src/components/ledger/lib/floorCascader.vue
  58. 319 0
      src/components/ledger/lib/linkassets.vue
  59. 19 16
      src/components/ledger/tableTransfers.vue
  60. 237 0
      src/components/model/file/addFloorDialog.vue
  61. 83 0
      src/components/model/file/addFolder.vue
  62. 97 0
      src/components/model/file/changeFolderName.vue
  63. 210 0
      src/components/model/file/floorTable.vue
  64. 127 0
      src/components/model/file/modelLog.vue
  65. 119 0
      src/components/model/file/replaceModelDialog.vue
  66. 96 0
      src/components/point/dynamicdata/applyLog.vue
  67. 107 0
      src/components/point/dynamicdata/applyRulesDialog-copy.vue
  68. 1 1
      src/components/point/dynamicdata/dataSource.vue
  69. 63 21
      src/components/point/dynamicdata/delRelationDialog.vue
  70. 2 2
      src/components/point/dynamicdata/dictionaryDevice.vue
  71. 17 15
      src/components/point/dynamicdata/equipRules.vue
  72. 70 58
      src/components/point/dynamicdata/historyDialog.vue
  73. 2 2
      src/components/point/dynamicdata/locationCascader.vue
  74. 1 1
      src/components/point/dynamicdata/locationFlag.vue
  75. 55 38
      src/components/point/dynamicdata/partsRules.vue
  76. 269 0
      src/components/point/dynamicdata/spaceRules.vue
  77. 269 0
      src/components/point/dynamicdata/systemRules.vue
  78. 33 0
      src/components/ready/buildfloor/addBuild.vue
  79. 80 0
      src/components/ready/buildfloor/addConnectivity.vue
  80. 55 0
      src/components/ready/buildfloor/buildfloorCascader.vue
  81. 94 0
      src/components/ready/buildfloor/formItems.vue
  82. 151 0
      src/framework/components/messagesever/index.vue
  83. 9 0
      src/framework/components/messagesever/mqSetting.js
  84. 22 0
      src/framework/components/messagesever/msmq.js
  85. 19 3
      src/framework/layout/PageHeader.vue
  86. 14 3
      src/framework/layout/layout-store.js
  87. 10 0
      src/framework/style/layout.scss
  88. 60 14
      src/router/system.js
  89. 0 2
      src/store/index.js
  90. 3 3
      src/store/modules/alarm.js
  91. 0 29
      src/store/modules/proMess.js
  92. 72 0
      src/utils/buildfloor/tools.js
  93. 2 0
      src/utils/bus.js
  94. 12 2
      src/utils/handsontable/fillterField.js
  95. 3 6
      src/utils/handsontable/notShow.js
  96. 10 12
      src/views/data_admin/buildAssets/index.vue
  97. 1 1
      src/views/data_admin/buildGraphy/lib/uploadImg.vue
  98. 140 0
      src/views/ledger/cenotelist/cenoteDetail/index.vue
  99. 6 6
      src/views/ledger/cenotelist/cenoteadd/index.vue
  100. 0 0
      src/views/ledger/cenotelist/index.vue

+ 4 - 2
config/dev.env.js

@@ -5,7 +5,9 @@ const prodEnv = require('./prod.env')
 module.exports = merge(prodEnv, {
     NODE_ENV: '"development"',
     BASE_URL: '"http://192.168.20.215"', //测试iframe地址
-    SSO_SERVER: '"http://192.168.20.102:8080"' //(新)测试环境
+    SSO_SERVER: '"http://192.168.20.102:8080"', //(新)测试环境
+    MQTT_SERVICE: '"ws://192.168.20.225:61614/stomp"' //MQ测试环境地址
     // SSO_SERVER: '"http://sso.sagacloud.cn"',  //正式环境
-    // BASE_URL: '"http://mbi.sagacloud.cn"' //线上iframe地址
+    // BASE_URL: '"http://mbi.sagacloud.cn"', //线上iframe地址
+    // MQTT_SERVICE: '""' //MQ正式环境地址
 })

+ 8 - 2
config/index.js

@@ -14,7 +14,6 @@ module.exports = {
                 target: 'http://192.168.20.235:8080',
                 changeOrigin: true,
                 pathRewrite: {
-                    // "^/apis": ""
                     "^/admin": "/"
                 }
             },
@@ -88,7 +87,14 @@ module.exports = {
                 ws: true,
                 // 将主机标头的原点更改为目标URL
                 changeOrigin: false
-            }
+            },
+            '/modelapi': {
+                target: 'http://192.168.20.225:8082',
+                changeOrigin: true,
+                pathRewrite: {
+                    "^/modelapi": "/"
+                }
+            },
         },
 
         // Various Dev Server settings

+ 6 - 4
config/prod.env.js

@@ -1,8 +1,10 @@
 'use strict'
 module.exports = {
     NODE_ENV: '"production"',
-    // BASE_URL: '"http://192.168.20.215"', //测试iframe地址
-    // SSO_SERVER: '"http://192.168.20.102:8080"' //(新)测试环境
-    BASE_URL: '"http://mbi.sagacloud.cn"', //线上iframe地址
-    SSO_SERVER: '"http://sso.sagacloud.cn"'  //正式环境
+    BASE_URL: '"http://192.168.20.215"', //测试iframe地址
+    SSO_SERVER: '"http://192.168.20.102:8080"', //(新)测试环境
+    MQTT_SERVICE: '"ws://192.168.20.225:61614/stomp"' //MQ测试环境地址
+    // BASE_URL: '"http://mbi.sagacloud.cn"', //线上iframe地址
+    // SSO_SERVER: '"http://sso.sagacloud.cn"',  //正式环境
+    // MQTT_SERVICE: '""' //MQ正式环境地址
 }

+ 6 - 3
package.json

@@ -5,11 +5,15 @@
     "author": "yaoll <yaolinlin@sagacloud.cn>",
     "private": true,
     "scripts": {
+        "i": "npm install",
         "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
         "start": "npm run dev",
         "build": "node build/build.js"
     },
     "dependencies": {
+        "@sybotan-web/base": "2.1.5",
+        "@sybotan-web/draw": "2.1.56",
+        "@sybotan-web/graphy": "2.1.27",
         "axios": "^0.18.0",
         "echarts": "^4.1.0",
         "element-ui": "^2.11.0",
@@ -20,9 +24,7 @@
         "vue-axios": "^2.1.4",
         "vue-router": "^3.0.1",
         "vuex": "^3.1.0",
-        "@sybotan-web/base": "2.0.54",
-        "@sybotan-web/draw": "2.0.114",
-        "@sybotan-web/graphy": "2.0.90"
+        "cad-engine": "2.0.250"
     },
     "devDependencies": {
         "ajv": "^6.9.1",
@@ -57,6 +59,7 @@
         "sass-loader": "^7.1.0",
         "semver": "^5.3.0",
         "shelljs": "^0.7.6",
+        "stompjs": "^2.3.3",
         "swiper": "^4.0.0",
         "uglifyjs-webpack-plugin": "^1.1.1",
         "url-loader": "^0.5.8",

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

@@ -0,0 +1,291 @@
+import httputils from '@/api/scan/httpUtil'
+import { Message } from 'element-ui';
+import axios from 'axios'
+const baseUrl = '/modelapi';
+
+let api = {
+    // 新建模型文件夹
+    /**
+     * 
+     * @param {Name:string,ProjectId:string} params 
+     */
+    createModel(params, success) {
+        let Name = params.Name;
+        this.queryModel(Name, (res) => {
+            if (res.Total == 0) {
+                let data = {
+                    Content: [params]
+                };
+                // 查询是否有该模型文件夹
+                // 创建
+                httputils.postJson(`${baseUrl}/model-folder/create`, data, success)
+            } else {
+                Message.error({ message: '该文件夹已经存在!' });
+            }
+        })
+    },
+    //删除模型文件夹
+    /**
+     * 
+     * @param {Id:string} params 
+     */
+    deleteModel(params, success) {
+        let Content = [params];
+        httputils.postJson(`${baseUrl}/model-folder/delete`, Content, success)
+    },
+    //修改模型文件夹名称
+    /**
+    * 
+    * @param {Name:string,ProjectId:string} params 
+    */
+    updateModelName(params, success) {
+        let Name = params.Name;
+        this.queryModel(Name, (res) => {
+            if (res.Total == 0) {
+                let data = {
+                    Content: [params]
+                };
+                // 更改文件夹名称
+                httputils.postJson(`${baseUrl}/model-folder/update`, data, success)
+            } else {
+                Message.error({ message: '该文件夹已经存在!' });
+            }
+        })
+    },
+    //查询模型文件夹
+    /** 
+     * @param Name string  注:查询多个 Name = '' 
+    */
+    queryModel(Name, success) {
+        let data = null;
+        if (Name) {
+            // 单个查询
+            data = {
+                Filters: `Name='${Name}'`
+            }
+        } else {
+            // 多个查询
+            data = {}
+        }
+        return httputils.postJson(`${baseUrl}/model-folder/query`, data, success)
+    },
+
+
+
+    //以下是楼层文件接口
+
+    // 查询模型文件夹下的所有模型文件
+    queryFloorList(data, success) {
+
+        let Filters = `FolderId='${data.FolderId}'`;
+        if (data.FloorName) {
+            Filters = `FolderId='${data.FolderId}';FloorName='${data.FloorName}';ProjectId='${data.ProjectId}'`;
+        }
+        let params = {
+            Filters: Filters
+        }
+        return httputils.postJson(`${baseUrl}/model-floor/query-list`, params, success)
+    },
+    // 查询模型文件夹下的单个模型文件
+    queryFloorItem(data, success) {
+
+        let Filters = `FolderId='${data.FolderId}'`;
+        if (data.FloorName) {
+            Filters = `FolderId='${data.FolderId}';FloorName='${data.FloorName}';ProjectId='${data.ProjectId}'`;
+        }
+        let params = {
+            Filters: Filters
+        }
+        return httputils.postJson(`${baseUrl}/model-floor/query`, params, success)
+    },
+    // 创建楼层
+    createFloor(params) {
+        // 判断该楼层是否存在
+
+        let data = {
+            Content: [{
+                FolderId: params.FolderId,
+                FloorName: params.FloorName,
+                ProjectId: params.ProjectId,      //项目id
+            }]
+        };
+        return new Promise((resolve, preject) => {
+            this.queryFloorItem(params, (res) => {
+                if (res.Total == 0) {
+                    // 创建楼层
+                    httputils.postJson(`${baseUrl}/model-floor/create`, data, (res) => {
+                        let modelFile = {
+                            Content: [{
+                                // ProjectId: params.ProjectId,      //项目id
+                                FloorModelId: res.EntityList[0].Id, //模型所属楼层(FloorModel外键)
+                                ModelName: params.Form.file.name,        //模型文件名
+                                UserName: params.userName,
+                                UserId: params.userId,
+                                Note: params.Form.desc
+                                // ReplaceReason: 0
+                            }]
+                        }
+                        //创建模型文件
+                        this.createModelFile(modelFile, (createModelRes) => {
+                            // 与此楼文件进行绑定
+                            let upDateModelData = {
+                                Content: [{
+                                    Id: res.EntityList[0].Id, //id
+                                    CurrentModelId: createModelRes.EntityList[0].Id //该楼层当前的模型id
+                                }]
+                            }
+                            this.updateFloorName(upDateModelData, (upDateModelSucess) => {
+                                if (upDateModelSucess.Result == "success") {
+                                    resolve({
+                                        Result: 'success',
+                                        FloorModelId: res.EntityList[0].Id,   //楼层模型文件
+                                        CurrentModelId: createModelRes.EntityList[0].Id //模型文件id
+                                    })
+                                }
+                            })
+                        })
+                    })
+                } else {
+                    let modelFile = {
+                        Content: [{
+                            // ProjectId: params.ProjectId,      //项目id
+                            FloorModelId: res.Content[0].Id, //模型所属楼层(FloorModel外键)
+                            ModelName: params.Form.file.name,        //模型文件名
+                            UserName: params.userName,
+                            UserId: params.userId,
+                            Note: params.Form.desc
+                            // ReplaceReason: 0
+                        }]
+                    }
+                    //创建模型文件
+                    this.createModelFile(modelFile, (createModelRes) => {
+                        // 与此楼文件进行绑定
+                        let upDateModelData = {
+                            Content: [{
+                                Id: res.Content[0].Id, //id
+                                CurrentModelId: createModelRes.EntityList[0].Id //该楼层当前的模型id
+                            }]
+                        }
+                        this.updateFloorName(upDateModelData, (upDateModelSucess) => {
+                            if (upDateModelSucess.Result == "success") {
+                                resolve({
+                                    Result: 'success',
+                                    FloorModelId: res.Content[0].Id,   //楼层模型文件
+                                    CurrentModelId: createModelRes.EntityList[0].Id //模型文件id
+                                })
+                            }
+                        })
+                    })
+                }
+            })
+        })
+    },
+    // 删除楼层文件
+    deleteFloor(data) {
+        return httputils.postJson(`${baseUrl}/model-floor/delete`, data)
+    },
+    //编辑楼层文件的名字
+    updateFloorName(data, success) {
+        return httputils.postJson(`${baseUrl}/model-floor/update`, data, success)
+    },
+
+
+    //以下是楼层文件接口
+
+    // 创建模型文件
+    createModelFile(data, success) {
+        return httputils.postJson(`${baseUrl}/model-file/create`, data, success)
+    },
+    //删除模型文件(只有记录,文件不动)
+    deleteModelFile(data, success) {
+        return httputils.postJson(`${baseUrl}/model-file/delete`, data, success)
+    },
+    /**
+     * info: 删除模型文件
+     * @param {*} params string 模型文件的id 
+     * @param {*} success  成功的回调函数
+     */
+    deleteModelFileList(params, success) {
+        let data = {
+            Id:params
+        } 
+        return httputils.postJson(`${baseUrl}/model-file/delete-file`, data, success)
+    },
+    //查询模型文件 
+    queryModelFile(FloorModelId, success) {
+        let params = {
+            Distince: true,
+            Filters: `FloorModelId='${FloorModelId}'`
+        }
+        return httputils.postJson(`${baseUrl}/model-file/query`, params, success)
+    },
+    // 上传模型文件
+    uploadModelFile(payload, ProjectId,callback1, callback2) {
+        axios({
+            url: baseUrl + '/model-file/upload',
+            method: 'post',
+            headers: {
+                ProjectId: ProjectId
+            },
+            onUploadProgress: function (progressEvent) { //原生获取上传进度的事件
+                if (progressEvent.lengthComputable) {
+                    //属性lengthComputable主要表明总共需要完成的工作量和已经完成的工作是否可以被测量
+                    //如果lengthComputable为false,就获取不到progressEvent.total和progressEvent.loaded
+                    callback1(progressEvent);
+                }
+            },
+            data: payload
+        }).then(res => {
+            callback2(res);
+        }).catch(error => {
+            console.log('this is a catch')
+            console.log(error)
+        })
+    },
+    // 更新模型文件
+    upDateModelFile(data, ProjectId, UserName, UserId, callback1, callback2) {
+        let modelFile = {
+            Content: [{
+                FloorModelId:data.replaceModelItem.Id, //模型id
+                ModelName: data.Form.file.name,        //模型名字
+                UserName: UserName,
+                UserId: UserId,
+                Note: data.replaceModelItem.Note,
+                ReplaceReason: data.Form.ReplaceReason
+            }]
+        }
+        // //创建模型文件
+        this.createModelFile(modelFile, (createModelRes) => {
+            // 与此楼文件进行绑定
+            let upDateModelData = {
+                Content: [{
+                    Id:data.replaceModelItem.Id, //楼层
+                    CurrentModelId: createModelRes.EntityList[0].Id
+                }]
+            }
+            this.updateFloorName(upDateModelData, (upDateModelSucess) => {
+                if (upDateModelSucess.Result == "success") {
+                    // 处理数据
+                    let formData = new FormData();
+                    formData.append(
+                      "model",
+                      JSON.stringify({
+                        FloorModelId: data.replaceModelItem.Id,
+                        Id:createModelRes.EntityList[0].Id
+                      })
+                    );
+                    formData.append("file", data.Form.file.raw);
+                    this.uploadModelFile(formData,ProjectId,callback1,callback2)
+                }
+            })
+        })
+    }
+
+}
+export default api
+
+//楼层与平面图绑定
+export function bindFloorModel(param, success) {
+    let url = `${baseUrl}/model-floor/bind`;
+    httputils.postJson(url, param, success)
+}

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

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

+ 3 - 4
src/api/scan/httpUtil.js

@@ -20,11 +20,10 @@ function successResponse(vm, response, success, failed) {
 }
 
 function errorResponse(vm, response, err) {
-    let json = JSON.stringify(response)
-    json = JSON.parse(json)
+    let json = JSON.parse(JSON.stringify(response))
     console.error(response)
-    if (err) {
-        Message.error({ message: '接口:' + json.config.url + '请求错误' })
+    if (json.response) {
+        Message.error({ message: `接口:${json.response.config.url}请求错误,错误状态为:${json.response.status}` })
     } else {
         console.error(vm, response, err)
         Message.error({ message: '请求错误' });

+ 221 - 29
src/api/scan/request.js

@@ -4,7 +4,7 @@ import http from './httpUtil'
 let arithmetic = '/arithmetic'
 
 var Comming = 'revit'
-    //获取打印标签模板test
+//获取打印标签模板test
 export function getTest() {
     return fetch({ method: 'GET', url: `${api}/service/template/note_template` })
 }
@@ -393,11 +393,11 @@ export function setHeader(param) {
 //获取头部接口
 export function getHeader(param) {
     let data = {
-            "AppType": Comming,
-            "Code": param.code,
-            "ProjId": param.perjectId
-        }
-        // return fetch({ method: 'POST', url: `${api}/service/dict/equipment_family_info_header`, data })
+        "AppType": Comming,
+        "Code": param.code,
+        "ProjId": param.perjectId
+    }
+    // return fetch({ method: 'POST', url: `${api}/service/dict/equipment_family_info_header`, data })
     return fetch({ method: 'POST', url: `${api}/service/dict/infocode_query_header`, data })
 }
 
@@ -446,7 +446,7 @@ export function getSpaceFloor(param) {
 export function createBusiness(param) {
     let data = param.data
     return fetch({ method: "POST", url: `${physics}/space/create?projectId=${param.ProjId}&secret=${param.secret}`, data })
-        // return fetch({ method: "POST", url: `/test/space/create?projectId=${param.ProjId}&secret=${param.secret}`, data })
+    // return fetch({ method: "POST", url: `/test/space/create?projectId=${param.ProjId}&secret=${param.secret}`, data })
 }
 
 //批量创建业务空间
@@ -496,7 +496,7 @@ export function getGraphyId(param) {
 export function getBussines(param) {
     let data = param.data
     return fetch({ method: "POST", url: `${physics}/object/outside_query?projectId=${param.ProjId}&secret=${param.secret}`, data })
-        // return fetch({ method: "POST", url: `/test/object/outside_query?projectId=${param.ProjId}&secret=${param.secret}`, data })
+    // return fetch({ method: "POST", url: `/test/object/outside_query?projectId=${param.ProjId}&secret=${param.secret}`, data })
 }
 
 //替代前一个接口
@@ -735,6 +735,12 @@ export function getCenoteTableData(param, success) {
     http.postJson(url, param, success)
 }
 
+//查询竖井信息
+export function queryCenoteTableData(param, success) {
+    let url = `${baseUrl}/datacenter/shaft/query`
+    http.postJson(url, param, success)
+}
+
 //添加竖井信息
 export function createCenoteTableData(param, success) {
     let url = `${baseUrl}/datacenter/shaft/create`
@@ -845,6 +851,12 @@ export function getDataDictionary(param, success) {
     http.postJson(url, data, success)
 }
 
+//批量处理字典信息操作
+export function setInfoPoint(param, success) {
+    let url = `${baseUrl}/datacenter/data-dictionary/project/dict-batch`;
+    http.postJson(url, param, success)
+}
+
 //设置项目数据字典显隐 --列表表头
 export function setDataDictionary(param, success) {
     let url = `${baseUrl}/datacenter/data-dictionary/project/setting-dic-project`;
@@ -915,10 +927,16 @@ export function equipLinkSys(param, success) {
 
 //设备清单 - 设备关联系统 系统1-n   
 export function sysLinkEquip(param, success) {
-    let url = `${baseUrl}/datacenter/sy-in-eq/link-eq`;
+    let url = `${baseUrl}/datacenter/sy-in-eq/link-sy-eq`;
     http.postJson(url, param, success)
 } 
 
+//设备清单 - 根据对象删除系统和设备的关系
+export function sysUnlinkEquip(param, success) {
+    let url = `${baseUrl}/datacenter/sy-in-eq/unlinks-sy-eq`;
+    http.postJson(url, param, success)
+}
+
 //设备清单 - 统计项目下所有设备数量
 export function countEquip(param, success) {
     let url = `${baseUrl}/datacenter/equip/count`;
@@ -931,6 +949,19 @@ export function queryEquip(param, success) {
     http.postJson(url, param, success)
 }
 
+//查询项目下的设备或部件-根据项目、建筑、楼层、设备或部件分类、业务空间实例筛选设备 然后通过计算匹配资产
+export function equipCategoryProperty(param, success) {
+    let url = `${baseUrl}/equip-component/equip-query/equip-category-property?category=${param.category}${param.spaceIdList?param.spaceIdList:''}`;
+    let data = param.data;
+    http.postJson(url, data, success)
+}
+
+//批量添加设备和资产的关系
+export function equipRproperty(param, success) {
+    let url = `${baseUrl}/equip-component/equip-query/equip-r-property`;
+    http.postJson(url, param, success)
+}
+
 //创建资产所需(Family族id3位编码)-根据设备类型(4位编码)或部件类型(6位编码)查询
 export function getEquipBelongs(param, success) {
     let url = `${baseUrl}/datacenter/data-dictionary/family-query`;
@@ -962,6 +993,12 @@ export function queryPartsDie(param, success) {
     http.postJson(url, param, success)
 }
 
+//查询项目下设备或部件的类别、以及名称
+export function TypePartsDie( success) {
+    let url = `${baseUrl}/equip-component/equip-query/equip-compon-category`;
+    http.getJson(url, {}, success)
+}
+
 //根据条件查询项目下设备部件数量
 export function countPartsDie(param, success) {
     let url = `${baseUrl}/equip-component/equip-query/count`;
@@ -1034,6 +1071,12 @@ export function queryPhysicsAllType(param, success) {
     http.postJson(url, {}, success)
 }
 
+//查询所有设备族信息
+export function queryFamilyAll( success) {
+    let url = `${baseUrl}/datacenter/data-dictionary/family-query-All`;
+    http.getJson(url, {}, success)
+}
+
 //字典头部信息查询接口
 export function queryDictionaryHead(param, success) {
     let url = `${baseUrl}/datacenter/class-def/query`;
@@ -1142,12 +1185,24 @@ export function floorQuery(param, success) {
     http.postJson(url, param, success)
 }
 
+//查询楼层信息+sign
+export function floorQueryAndSign(param, success) {
+    let url = `${baseUrl}/equip-component/floor/query`;
+    http.postJson(url, param, success)
+}
+
 //查询建筑信息
 export function buildingQuery(param, success) {
     let url = `${baseUrl}/datacenter/building/query`;
     http.postJson(url, param, success)
 }
 
+//查询建筑信息+count
+export function buildingQueryAndCount(param, success) {
+    let url = `${baseUrl}/equip-component/building/query`;
+    http.postJson(url, param, success)
+}
+
 //创建分区信息
 export function createZone(param, success) {
     let data = param.data
@@ -1176,6 +1231,13 @@ export function updateZone(param, success) {
     http.postJson(url, data, success)
 }
 
+//根据条件查询统计数量
+export function countZone(param, success) {
+    let data = param.data
+    let url = `${baseUrl}/datacenter/${zone[param.zone]}/count`;
+    http.postJson(url, data, success)
+}
+
 //动态数据关联-查询对应关系(删除提示页)
 export function dynamicQueryPrompt(param, success) {
     let url = `${baseUrl}/pointconfig/dynamic/query-prompt`;
@@ -1188,38 +1250,168 @@ export function dynamicQueryAI(param, success) {
     http.postJson(url, param, success)
 }
 
-//扫楼作业-扫楼日志查看
-export function queryUserLog(param, success) {
-    let url = `${baseUrl}/scanbuilding-2/user-log/query`;
+//动态数据关联-执行对应结果详情
+export function dynamicExecuteDetail(param, success) {
+    let url = `${baseUrl}/pointconfig/dynamic/executeDetail`;
     http.postJson(url, param, success)
 }
 
-//扫楼作业-信息点整理-查询点位标签
-export function queryLocationPoint(param, success) {
-    let url = `${baseUrl}/datacenter/location-point/query`;
+//建筑楼层管理-创建楼层
+export function manageCreateFloor(param, success) {
+    let url = `${baseUrl}/datacenter/floor/create`;
     http.postJson(url, param, success)
 }
 
-//扫楼作业-信息点整理-更新点位标签
-export function updateLocationPoint(param, success) {
-    let url = `${baseUrl}/datacenter/location-point/update`;
+//建筑楼层管理-删除楼层
+export function manageDeleteFloor(param, success) {
+    let url = `${baseUrl}/datacenter/floor/delete`;
     http.postJson(url, param, success)
 }
 
-//扫楼作业-位置标签-删除图片
-export function deleteLocationImg(param, success) {
-    let url = `${baseUrl}/datacenter/location-point/delete-image`;
+//建筑楼层管理-修改楼层
+export function manageUpdateFloor(param, success) {
+    let url = `${baseUrl}/datacenter/floor/update`;
     http.postJson(url, param, success)
 }
 
-//扫楼作业-信息点整理-资产族及个数
-export function queryPropertyTypeCount(param, success) {
-    let url = `${baseUrl}/equip-component/property/property-family`;
-    http.getJson(url, param, success)
+//建筑楼层管理-创建楼层关联关系
+export function createRelationInFloor(param, success) {
+    let url = `${baseUrl}/datacenter/fl-through-fl/link-or`;
+    http.postJson(url, param, success)
+}
+//查询底图
+export function queryBaseGraphy(param, success) {
+    let url = `/modelapi/base-graph/query`;
+    http.postJson(url, param, success)
+}
+//楼层接口-----更新楼层信息
+export function floorUpdate(param, success) {
+    let url = `${baseUrl}/datacenter/floor/update`;
+    http.postJson(url, param, success)
 }
 
-//扫楼作业-信息点整理-位置标签及对应资产数量
-export function queryPropertyPoint(param, success) {
-    let url = `${baseUrl}/equip-component/point/point-property`;
-    http.getJson(url, param, success)
+/****关系-竖井****/
+//字典查询接口 竖井所有类型
+export function queryShaftType(success) {
+    let url = `${baseUrl}/datacenter/data-dictionary/query-shaft-type`;
+    http.getJson(url, {}, success)
+}
+//根据对象删除设备所在竖井关系,只针对一个对象
+export function eqinshUnlink(param, success) {
+    let url = `${baseUrl}/datacenter/eq-in-sh/unlink`;
+    http.postJson(url, param, success)
+}
+//根据对象删除系统所在竖井关系,只针对一个对象
+export function syinshUnlink(param, success) {
+    let url = `${baseUrl}/datacenter/sy-in-sh/unlink`;
+    http.postJson(url, param, success)
+}
+//根据对象删除竖井的贯通关系,只针对一个对象
+export function shthroughshUnlink(param, success) {
+    let url = `${baseUrl}/datacenter/sh-through-sh/unlink`;
+    http.postJson(url, param, success)
+}
+//查询没有和当前竖井绑定的设备
+export function unshaftInEq(param, success) {
+    let data = param.data
+    let url = `${baseUrl}/equip-component/shaft/unshaft-in-eq?shaftId=${param.shaftId}`;
+    http.postJson(url, data, success)
+}
+//查询没有和当前竖井贯通的其它竖井
+export function unshaftThroughShaft(param, success) {
+    let data = param.data
+    let url = `${baseUrl}/equip-component/shaft/unshaft-through-shaft?shaftId=${param.shaftId}`;
+    http.postJson(url, data, success)
+}
+//查询没有和当前竖井绑定的系统
+export function unshaftInSys(param, success) {
+    let data = param.data
+    let url = `${baseUrl}/equip-component/shaft/unshaft-in-sys?shaftId=${param.shaftId}`;
+    http.postJson(url, data, success)
+}
+//设备所在的竖井,竖井一对多,此方不会覆盖以前的记录,累计添加
+export function linkEqSh(param, success) {
+    let url = `${baseUrl}/datacenter/eq-in-sh/link-eq-sh`;
+    http.postJson(url, param, success)
+}
+//竖井的贯通,竖井一对多,此方法不会覆盖以前的记录
+export function linkShaft(param, success) {
+    let url = `${baseUrl}/datacenter/sh-through-sh/link-shaft`;
+    http.postJson(url, param, success)
+}
+//系统所在的竖井,竖井一对多,累计添加,此方法不会覆盖以前记录
+export function linkSySh(param, success) {
+    let url = `${baseUrl}/datacenter/sy-in-sh/link-sy-sh`;
+    http.postJson(url, param, success)
+}
+
+//关系-----设备所在业务空间--删除关系
+export function eqInSpaceDelete(param, success) {
+    let url = `${baseUrl}/datacenter/eq-in-sp-base/unlink-list?type=${param.type}`;
+    http.postJson(url, param.data, success)
+}
+//关系-----设备所在业务空间--创建关系
+export function eqInSpaceCreate(param, success) {
+    let url = `${baseUrl}/datacenter/eq-in-sp-base/link-eq-sp?type=${param.type}`;
+    http.postJson(url, param.data, success)
+}
+//关系-----设备服务业务空间--删除关系
+export function eqForSpaceDelete(param, success) {
+    let url = `${baseUrl}/datacenter/eq-for-sp-base/unlink-list?type=${param.type}`;
+    http.postJson(url, param.data, success)
+}
+//关系-----设备服务业务空间--创建关系
+export function eqForSpaceCreate(param, success) {
+    let url = `${baseUrl}/datacenter/eq-for-sp-base/link-eq-sp?type=${param.type}`;
+    http.postJson(url, param.data, success)
+}
+//关系-----系统所在业务空间--删除关系
+export function syInSpaceDelete(param, success) {
+    let url = `${baseUrl}/datacenter/sy-in-sp-base/unlink-list?type=${param.type}`;
+    http.postJson(url, param.data, success)
+}
+//关系-----系统所在业务空间--创建关系
+export function syInSpaceCreate(param, success) {
+    let url = `${baseUrl}/datacenter/sy-in-sp-base/link-sp-sys?type=${param.type}`;
+    http.postJson(url, param.data, success)
+}
+//关系-----没有和当前空间绑定的设备
+export function notEqInSpaceQuery(param, success) {
+    let url = `${baseUrl}/equip-component/space/unspace-in-eq?type=${param.type}&spaceId=${param.spaceId}`;
+    http.postJson(url, param.data, success)
+}
+//关系-----未服务当前空间的设备
+export function notEqForSpaceQuery(param, success) {
+    let url = `${baseUrl}/equip-component/space/unspace-for-eq?type=${param.type}&spaceId=${param.spaceId}`;
+    http.postJson(url, param.data, success)
+}
+//关系-----没有和当前空间绑定的系统
+export function notSyInSpaceQuery(param, success) {
+    let url = `${baseUrl}/equip-component/space/unspace-in-sys?type=${param.type}&spaceId=${param.spaceId}`;
+    http.postJson(url, param.data, success)
+}
+//关系-----空间内没有和空间关联的设备 根据坐标计算(专用接口)
+export function getEqNotInSpace(param, success) {
+    let url = `${baseUrl}/equip-component/space/unspace-fIn-eq-point?spaceId=${param.spaceId}&type=${param.type}`;
+    http.postJson(url, param.data, success)
+}
+//关系-----空间内没有服务空间的设备 根据坐标计算(专用接口)
+export function getEqNotForSpace(param, success) {
+    let url = `${baseUrl}/equip-component/space/unspace-for-eq-point?spaceId=${param.spaceId}&type=${param.type}`;
+    http.postJson(url, param.data, success)
+}
+//关系-----未关联业务空间的元空间
+export function getIspNotInSpace(param, success) {
+    let url = `${baseUrl}/equip-component/space/unspace-ispace?objectType=${param.objectType}`;
+    http.postJson(url, param.data, success)
+}
+//关系-----业务空间内的元空间,业务空间一对多,累计添加会覆盖以前记录
+export function createRelateInZoneAndISp(param, success) {
+    let url = `${baseUrl}/datacenter/si-in-sp-base/link-sp?type=${param.type}`;
+    http.postJson(url, param.data, success)
+}
+//关系-----业务空间内的元空间,创建业务空间内的元空间关系, 累计添加不会覆盖-批量关联
+export function groupCreRelaZoneAndISp(param, success) {
+    let url = `${baseUrl}/datacenter/si-in-sp-base/link-list?type=${param.type}`;
+    http.postJson(url, param.data, success)
 }

+ 1 - 1
src/assets/graphy/SGraphy/dataType.ts

@@ -72,7 +72,7 @@ interface ImgItemInterface {
     height: number;
     img: string;
     id?: string;
-    name?: string;
+    name: string;
 }
 
 export { dataItemPath, dataItem, dataSpaceItem, dataInterface, businessDataInterface, PolygonItemInterface, ImgItemInterface }

+ 26 - 6
src/assets/graphy/SGraphy/mainScene.js

@@ -194,7 +194,7 @@ var mainScene = /** @class */ (function (_super) {
         var _this_1 = this;
         if (imageList && imageList.length) {
             imageList.map(function (t) {
-                _this_1.addItem(new SGraphyImgItem(null, t.img, t.X, t.Y, t.width, t.height, t.id, t.name));
+                _this_1.addItem(new SGraphyImgItem(null, t.img, t.X, t.Y, t.width, t.height));
             });
         }
     };
@@ -206,15 +206,35 @@ var mainScene = /** @class */ (function (_super) {
     };
     // 鼠标交互类事件
     // 点击
-    mainScene.prototype.click = function (_this, fn) { };
+    mainScene.prototype.click = function (_this, fn) {
+        this.root.children.forEach(function (item) {
+            item.connect("click", _this, fn);
+        });
+    };
     // 双击
-    mainScene.prototype.dbclick = function (_this, fn) { };
+    mainScene.prototype.dbclick = function (_this, fn) {
+        this.root.children.forEach(function (item) {
+            item.connect("doubleClick", _this, fn);
+        });
+    };
     // 按下
-    mainScene.prototype.mouseDown = function (_this, fn) { };
+    mainScene.prototype.mouseDown = function (_this, fn) {
+        this.root.children.forEach(function (item) {
+            item.connect("mouseDown", _this, fn);
+        });
+    };
     //移动
-    mainScene.prototype.mouseMove = function (_this, fn) { };
+    mainScene.prototype.mouseMove = function (_this, fn) {
+        this.root.children.forEach(function (item) {
+            item.connect("mouseMove", _this, fn);
+        });
+    };
     // 点解结束
-    mainScene.prototype.mouseUp = function (_this, fn) { };
+    mainScene.prototype.mouseUp = function (_this, fn) {
+        this.root.children.forEach(function (item) {
+            item.connect("mouseUp", _this, fn);
+        });
+    };
     return mainScene;
 }(SGraphyScene));
 export default mainScene;

+ 26 - 6
src/assets/graphy/SGraphy/mainScene.ts

@@ -182,7 +182,7 @@ export default class mainScene extends SGraphyScene {
     addImageList(imageList: ImgItemInterface[]): void {
         if (imageList && imageList.length) {
             imageList.map(t => {
-                this.addItem(new SGraphyImgItem(null, t.img, t.X, t.Y, t.width, t.height, t.id, t.name))
+                this.addItem(new SGraphyImgItem(null, t.img, t.X, t.Y, t.width, t.height))
             })
         }
     }
@@ -195,14 +195,34 @@ export default class mainScene extends SGraphyScene {
     // 鼠标交互类事件
 
     // 点击
-    click(_this: any, fn: any): void { }
+    click(_this: any, fn: any): void {
+        this.root.children.forEach(item => {
+            item.connect("click", _this, fn);
+        });
+    }
     // 双击
-    dbclick(_this: any, fn: any): void { }
+    dbclick(_this: any, fn: any): void {
+        this.root.children.forEach(item => {
+            item.connect("doubleClick", _this, fn);
+        });
+    }
     // 按下
-    mouseDown(_this: any, fn: any) { }
+    mouseDown(_this: any, fn: any) {
+        this.root.children.forEach(item => {
+            item.connect("mouseDown", _this, fn);
+        });
+    }
     //移动
-    mouseMove(_this: any, fn: any) { }
+    mouseMove(_this: any, fn: any) {
+        this.root.children.forEach(item => {
+            item.connect("mouseMove", _this, fn);
+        });
+    }
     // 点解结束
-    mouseUp(_this: any, fn: any) { }
+    mouseUp(_this: any, fn: any) {
+        this.root.children.forEach(item => {
+            item.connect("mouseUp", _this, fn);
+        });
+    }
 
 } 

+ 2 - 2
src/assets/graphy/SGraphy/newItems/SGraphyCircleItem.js

@@ -61,8 +61,8 @@ var SGraphyCircleItem = /** @class */ (function (_super) {
         // painter.pen = new SPen(new SColor("#FF0000"), 22);
         painter.pen.color = this.color;
         painter.brush.color = this.fillColor;
-        painter.drawCircle(0, 0, this.r);
+        painter.drawCircle(500, 500, this.r);
     };
     return SGraphyCircleItem;
 }(SGraphyItem)); // Class SGraphyCircleItem
-export { SGraphyCircleItem };
+export default SGraphyCircleItem;

+ 2 - 2
src/assets/graphy/SGraphy/newItems/SGraphyCircleItem.ts

@@ -7,7 +7,7 @@ import { SPen, SPainter, SColor } from "@sybotan-web/draw";
  * 圆Item类
  *
  */
-export class SGraphyCircleItem extends SGraphyItem {
+export default class SGraphyCircleItem extends SGraphyItem {
     r: number;
     fillColor: SColor = SColor.White;
     color: SColor = SColor.Black;
@@ -60,6 +60,6 @@ export class SGraphyCircleItem extends SGraphyItem {
         // painter.pen = new SPen(new SColor("#FF0000"), 22);
         painter.pen.color = this.color;
         painter.brush.color = this.fillColor;
-        painter.drawCircle(0, 0, this.r);
+        painter.drawCircle(500, 500, this.r);
     }
 } // Class SGraphyCircleItem

+ 7 - 3
src/assets/graphy/SGraphy/newItems/SGraphyImgItem.js

@@ -25,13 +25,17 @@ var SGraphyImgItem = /** @class */ (function (_super) {
      * @param width        		图片宽度
      * @param height   				图片高度
      * @param imgSource     	图片源
+     * @param X        				图片向x轴的偏移量
+     * @param Y        				图片向y轴的偏移量
      * @param parent   				指向父元素
      */
-    function SGraphyImgItem(parent, imgSource, width, height) {
+    function SGraphyImgItem(parent, imgSource, X, Y, width, height) {
         var _this = _super.call(this, parent) || this;
         _this.width = 0;
         _this.height = 0;
         _this.imgSource = imgSource;
+        _this.X = X;
+        _this.Y = Y;
         _this.width = width;
         _this.height = height;
         _this.img = new Image();
@@ -44,7 +48,7 @@ var SGraphyImgItem = /** @class */ (function (_super) {
      * @return SRect
      */
     SGraphyImgItem.prototype.boundingRect = function () {
-        return new SRect(0, 0, this.width, this.height);
+        return new SRect(this.X, this.Y, this.width, this.height);
     }; // Function boundingRect()
     // contains(x: number, y: number): boolean {
     // 	return this.boundingRect().contains(x - this.X, y - this.Y);
@@ -100,7 +104,7 @@ var SGraphyImgItem = /** @class */ (function (_super) {
      * @param   rect          绘制区域
      */
     SGraphyImgItem.prototype.onDraw = function (painter, rect) {
-        painter.drawImage(this.img, 0, 0, this.width, this.height);
+        painter.drawImage(this.img, this.X, this.Y, this.width, this.height);
     };
     return SGraphyImgItem;
 }(SGraphyItem)); // Class SGraphyImgItem

+ 13 - 4
src/assets/graphy/SGraphy/newItems/SGraphyImgItem.ts

@@ -8,25 +8,34 @@ import { SPen, SPainter, SColor } from "@sybotan-web/draw";
  */
 export class SGraphyImgItem extends SGraphyItem {
 	imgSource: string; //可以为url,base64
+	X: number;
+	Y: number;
 	width: number = 0;
 	height: number = 0;
 	img: CanvasImageSource
+
 	/**
 	 * 构造函数
 	 * 
 	 * @param width        		图片宽度
 	 * @param height   				图片高度
 	 * @param imgSource     	图片源
+	 * @param X        				图片向x轴的偏移量
+	 * @param Y        				图片向y轴的偏移量
 	 * @param parent   				指向父元素
 	 */
 	constructor(
 		parent: SGraphyItem | null,
 		imgSource: string,
+		X: number,
+		Y: number,
 		width: number,
-		height: number
+		height: number,
 	) {
 		super(parent);
 		this.imgSource = imgSource;
+		this.X = X;
+		this.Y = Y;
 		this.width = width;
 		this.height = height;
 		this.img = new Image();
@@ -40,8 +49,8 @@ export class SGraphyImgItem extends SGraphyItem {
 	 */
 	boundingRect(): SRect {
 		return new SRect(
-			0,
-			0,
+			this.X,
+			this.Y,
 			this.width,
 			this.height
 		);
@@ -102,6 +111,6 @@ export class SGraphyImgItem extends SGraphyItem {
 	 * @param   rect          绘制区域
 	 */
 	onDraw(painter: SPainter, rect?: SRect): void {
-		painter.drawImage(this.img, 0, 0, this.width, this.height);
+		painter.drawImage(this.img, this.X, this.Y, this.width, this.height);
 	}
 } // Class SGraphyImgItem

+ 70 - 0
src/assets/graphy/SGraphy/newItems/SGraphyPointItem.js

@@ -0,0 +1,70 @@
+var __extends = (this && this.__extends) || (function () {
+    var extendStatics = function (d, b) {
+        extendStatics = Object.setPrototypeOf ||
+            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+        return extendStatics(d, b);
+    };
+    return function (d, b) {
+        extendStatics(d, b);
+        function __() { this.constructor = d; }
+        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+    };
+})();
+import { SGraphyItem } from '@sybotan-web/graphy';
+import { SRect, SPoint } from "@sybotan-web/base";
+import { SColor } from "@sybotan-web/draw";
+/**
+ * 坐标点
+ *
+ */
+var SGraphyPointItem = /** @class */ (function (_super) {
+    __extends(SGraphyPointItem, _super);
+    /**
+     * 构造函数
+     *
+     * @param r          圆半径
+     * @param width      圆线的宽度
+     * @param color      圆线的颜色
+     * @param fillColor  圆填充的颜色
+     * @param parent
+     */
+    function SGraphyPointItem(parent, width, point, color, fillColor) {
+        if (width === void 0) { width = 100; }
+        if (point === void 0) { point = new SPoint(0, 0); }
+        if (color === void 0) { color = new SColor('#F56C6C'); }
+        if (fillColor === void 0) { fillColor = new SColor('#F56C6C'); }
+        var _this = _super.call(this, parent) || this;
+        _this.width = 100;
+        _this.width = width;
+        _this.point = point;
+        _this.color = color;
+        _this.fillColor = fillColor;
+        return _this;
+    } // Constructor()
+    /**
+     * Item对象边界区域
+     *
+     * @return SRect
+     */
+    SGraphyPointItem.prototype.boundingRect = function () {
+        var minX = this.point.x;
+        var miny = this.point.y;
+        var maxX = this.point.x + this.width;
+        var maxY = this.point.y + this.width;
+        return new SRect(minX, miny, maxX, maxY);
+    }; // Function boundingRect()
+    /**
+     * Item绘制操作
+     *
+     * @param   painter       painter对象
+     * @param   rect          绘制区域
+     */
+    SGraphyPointItem.prototype.onDraw = function (painter, rect) {
+        painter.pen.color = this.color;
+        painter.brush.color = this.fillColor;
+        painter.drawRect(this.point.x, this.point.y, this.width, this.width);
+    };
+    return SGraphyPointItem;
+}(SGraphyItem)); // Class SGraphyCircleItem
+export default SGraphyPointItem;

+ 67 - 0
src/assets/graphy/SGraphy/newItems/SGraphyPointItem.ts

@@ -0,0 +1,67 @@
+
+import { SGraphyItem } from '@sybotan-web/graphy';
+import { SRect, SSize, SPoint } from "@sybotan-web/base";
+import { SPen, SPainter, SColor } from "@sybotan-web/draw";
+/**
+ * 坐标点
+ *
+ */
+export default class SGraphyPointItem extends SGraphyItem {
+    width: number = 100;
+    point: SPoint;
+    color: SColor;
+    fillColor: SColor;
+
+    /**
+     * 构造函数
+     *
+     * @param r          圆半径
+     * @param width      圆线的宽度
+     * @param color      圆线的颜色
+     * @param fillColor  圆填充的颜色
+     * @param parent    
+     */
+    constructor(
+        parent: SGraphyItem | null,
+        width: number = 100,
+        point: SPoint = new SPoint(0, 0),
+        color: SColor = new SColor('#F56C6C'),
+        fillColor: SColor = new SColor('#F56C6C')
+    ) {
+        super(parent);
+        this.width = width;
+        this.point = point;
+        this.color = color;
+        this.fillColor = fillColor;
+   
+    } // Constructor()
+
+    /**
+     * Item对象边界区域
+     * 
+     * @return SRect
+     */
+    boundingRect(): SRect {
+        let minX = this.point.x;
+        let miny = this.point.y;
+        let maxX = this.point.x + this.width;
+        let maxY = this.point.y + this.width;
+        return new SRect(
+            minX,
+            miny,
+            maxX, maxY
+        );
+    } // Function boundingRect()
+
+    /**
+     * Item绘制操作
+     *
+     * @param   painter       painter对象
+     * @param   rect          绘制区域
+     */
+    onDraw(painter: SPainter, rect?: SRect): void {
+        painter.pen.color = this.color;
+        painter.brush.color = this.fillColor;
+        painter.drawRect(this.point.x,this.point.y,this.width,this.width)
+    }
+} // Class SGraphyCircleItem

+ 3 - 2
src/assets/graphy/SGraphy/newItems/SGraphyPolygonItem.js

@@ -12,7 +12,8 @@ var __extends = (this && this.__extends) || (function () {
     };
 })();
 import { SGraphyItem } from '@sybotan-web/graphy';
-import { SColor, SRect, SPoint } from "@sybotan-web/draw";
+import { SRect, SPoint } from "@sybotan-web/base";
+import { SColor } from "@sybotan-web/draw";
 /**
  * 不规则多边形Item类
  *
@@ -163,7 +164,7 @@ var SGraphyPolygonItem = /** @class */ (function (_super) {
         }
     };
     SGraphyPolygonItem.prototype.onClick = function (event) {
-        this.$emit('click', event);
+        this.$emit('click', { item: this, event: event });
         return true;
     }; // Function onClick()
     /**

+ 3 - 2
src/assets/graphy/SGraphy/newItems/SGraphyPolygonItem.ts

@@ -1,6 +1,7 @@
 
 import { SGraphyItem, SMouseEvent } from '@sybotan-web/graphy'
-import { SPen, SPainter, SColor, SFont, SRect, SPoint, SSize } from "@sybotan-web/draw";
+import { SRect, SSize, SPoint } from "@sybotan-web/base";
+import { SPen, SPainter, SColor, SFont } from "@sybotan-web/draw";
 import { dataItemPath, dataItem, dataSpaceItem, dataInterface, PolygonItemInterface } from './../dataType'   //传入参数的参数接口类型
 /**
  * 不规则多边形Item类
@@ -170,7 +171,7 @@ export default class SGraphyPolygonItem extends SGraphyItem {
 		}
 	}
 	onClick(event: SMouseEvent): boolean {
-		this.$emit('click', event);
+		this.$emit('click', { item: this, event: event });
 		return true;
 	} // Function onClick()
 	/**

+ 1 - 1
src/assets/graphy/SGraphy/newItems/SGraphyRectItem.js

@@ -71,4 +71,4 @@ var SGraphyRectItem = /** @class */ (function (_super) {
     };
     return SGraphyRectItem;
 }(SGraphyItem)); // Class SGraphyRectItem
-export { SGraphyRectItem };
+export default SGraphyRectItem;

+ 2 - 2
src/assets/graphy/SGraphy/newItems/SGraphyRectItem.ts

@@ -7,7 +7,7 @@ import { SPen, SPainter, SColor } from "@sybotan-web/draw";
  * 矩形Item类
  *
  */
-export class SGraphyRectItem extends SGraphyItem {
+export default class SGraphyRectItem extends SGraphyItem {
   startX: number;
   startY: number;
   width: number;
@@ -71,6 +71,6 @@ export class SGraphyRectItem extends SGraphyItem {
     // painter.pen = new SPen(this.color, this.width);
     painter.pen.color = this.color;
     painter.brush.color = this.fillColor;
-    painter.drawRect(this.startX,this.startY,this.width,this.height)
+    painter.drawRect(this.startX, this.startY, this.width, this.height)
   }
 } // Class SGraphyRectItem

+ 1 - 2
src/assets/graphy/SGraphy/newItems/SGraphyWallItem.js

@@ -84,10 +84,9 @@ var SGraphyWallItem = /** @class */ (function (_super) {
             // painter.pen = new SPen(this.color, this.width);
             painter.pen.color = this.color;
             painter.brush.color = this.fillColor;
-            painter.pen.lineWidth = 100;
             painter.drawPolyline(this.pointArr);
         }
     };
     return SGraphyWallItem;
 }(SGraphyItem)); // Class SGraphyPolygonItem
-export { SGraphyWallItem };
+export default SGraphyWallItem;

+ 1 - 2
src/assets/graphy/SGraphy/newItems/SGraphyWallItem.ts

@@ -7,7 +7,7 @@ import { SPen, SPainter, SColor } from "@sybotan-web/draw";
  * 墙Item类
  *
  */
-export class SGraphyWallItem extends SGraphyItem {
+export default class SGraphyWallItem extends SGraphyItem {
 	pointArr: SPoint[];
 	isVirtual: boolean = false;
 	fillColor: SColor = SColor.White;
@@ -83,7 +83,6 @@ export class SGraphyWallItem extends SGraphyItem {
 			// painter.pen = new SPen(this.color, this.width);
 			painter.pen.color = this.color;
 			painter.brush.color = this.fillColor;
-			painter.pen.lineWidth = 100;
 			painter.drawPolyline(this.pointArr)
 		}
 	}

+ 13 - 1
src/assets/scss/point/point_config/reset.scss

@@ -365,7 +365,7 @@ button,
 input,
 select,
 textarea {
-    font-family: tahoma, Helvetica, Arial, "\5FAE\8F6F\96C5\9ED1";
+    font-family: Helvetica Neue,Helvetica,PingFang SC,Hiragino Sans GB,Microsoft YaHei,SimSun,sans-serif, "\5FAE\8F6F\96C5\9ED1";
     *font-family: "\5FAE\8F6F\96C5\9ED1";
 }
 
@@ -470,4 +470,16 @@ hr {
 
 .disIne {
     display: inline-block;
+}
+
+input::-webkit-outer-spin-button,
+input::-webkit-inner-spin-button {
+    -webkit-appearance: none;
+}
+input[type="number"]{
+    -moz-appearance: textfield;
+}
+
+canvas:focus{
+    outline: none;
 }

Plik diff jest za duży
+ 62 - 6
src/assets/style/iconfont/iconfont.css


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


Plik diff jest za duży
+ 42 - 0
src/assets/style/iconfont/iconfont.svg


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


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


+ 6 - 0
src/assets/style/style.scss

@@ -1,3 +1,9 @@
+body{
+    /deep/ .el-notification.right{
+        text-align: left;
+    }
+}
+
 .icon-wushuju {
     display: block;
     width: 100px;

+ 96 - 99
src/components/business_space/business/handsontable.vue

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

+ 4 - 2
src/components/business_space/dialogs/detailsDialog.vue

@@ -156,8 +156,10 @@
                             data: [{RoomID: this.list.id}]
                         }
                         deleteZone(param, res => {
-                            this.$message({ type: "success",  message: "删除成功!" })
-                            this.$emit("del")
+                            if (res.Result == 'success') {
+                                this.$message({ type: "success",  message: "删除成功!" })
+                                this.$emit("del")
+                            }
                         })
                     })
                     .catch(() => {

+ 42 - 8
src/components/business_space/graphy/business.vue

@@ -50,6 +50,7 @@
             <div class="div50">
             <el-button @click="clearDimension" plain>取 消</el-button>
             <el-button @click="bussinDea" type="primary">查看详情</el-button>
+            <el-button @click="clearRelation" type="primary">清除关系</el-button>
             </div>
         </div>
         <!-- 点击业务空间后点击元空间 -->
@@ -141,11 +142,11 @@
         SGraphyScene,
         SGraphyRectItem,
         SGraphyLineItem,
-        SGraphyPolygonItem,
         SGraphyVirtualItem,
         SGraphyImageItem,
         SGraphyPillarItems
     } from "@/assets/graphy";
+    import SGraphyPolygonItem from "@/assets/js/items/SGraphyPolygonItem";
     import pako from '@/assets/pako/pako'
     //ele动画组件
     import tools from "@/utils/scan/tools";
@@ -540,8 +541,9 @@
                             this.$message.error(res.data.ResultMsg);
                         }
                     })
-                    .catch(() => {
-                        this.$message.error("请求出错");
+                    .catch((err) => {
+                        console.log(err)
+                        // this.$message.error("请求出错");
                     });
             },
             //创建实例
@@ -889,8 +891,9 @@
                             this.$message.error(res.data.ResultMsg);
                         }
                     })
-                    .catch(() => {
-                        this.$message.error("请求出错");
+                    .catch((err) => {
+                        console.log(err)
+                        // this.$message.error("请求出错");
                     });
             },
             getPathToCanvas(id) {
@@ -928,7 +931,7 @@
             saveChange() {
                 let id = ""
                 this.idList.map(item => {
-                    if (!!item.parentId) {
+                    if (item.parentId) {
                         id = item.parentId
                     }
                 })
@@ -1232,8 +1235,9 @@
                             this.loading.errorNum++;
                         }
                     })
-                    .catch(() => {
-                        this.$message.error("请求出错");
+                    .catch((err) => {
+                        console.log(err)
+                        // this.$message.error("请求出错");
                         this.loading.errorNum++;
                     });
             },
@@ -1251,6 +1255,36 @@
                 Link.click();
                 // 然后移除
                 document.body.removeChild(Link);
+            },
+            // 清除按钮
+            clearRelation(){
+                let spaceid = this.idList[0].id
+                let param = {
+                    data: {
+                        criterias: [{
+                            to_id: spaceid, //选填
+                            graph_id: this.graphyId, //选填
+                            rel_type: this.spaceType.rel_type //选填
+                        }]
+                    },
+                    ProjId: this.projectId,
+                    secret: this.secret
+                };
+                this.loading.show = true;
+                deleteRelation(param).then(res => {
+                    if (res.data.Result == "success") {
+                        this.loading.show = false;
+                        this.$message.success('清除成功')
+                        this.idList = [];
+                        this.type = 1;
+                        this.getHasSpace();
+                    } else {
+                        this.$message.error(res.data.ResultMsg);
+                    }
+                })
+                .catch(() => {
+                    this.$message.error("请求失败");
+                });
             }
         },
         filters: {

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

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

+ 111 - 0
src/components/business_space/newAddDialogs/addSystemDialog.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"
+        @selection-change="handleSelectionChange">
+        <el-table-column type="selection" width="55"></el-table-column>
+        <el-table-column :label="`${inSpaceType}名称`" show-overflow-tooltip min-width="100">
+          <template slot-scope="scope">
+            <div>
+              {{scope.row.SysLocalName||scope.row.SysName||''}}
+            </div>
+          </template>
+        </el-table-column>
+        <el-table-column prop="SysLocalID" :label="`${inSpaceType}本地编码`" show-overflow-tooltip min-width="100"></el-table-column>
+        <el-table-column prop="action" label="操作" min-width="100">
+          <template slot-scope="scope">
+            <el-button size="mini" @click="toDetail(scope.$index, scope.row)" type="primary" plain>查看详情</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+    </div>
+    <span slot="footer" class="dialog-footer">
+      <el-button size="small" @click="dialogVisible = false">取 消</el-button>
+      <el-button size="small" type="primary" @click="savaRelation">确 定</el-button>
+    </span>
+  </el-dialog>
+</template>
+
+
+<script>
+import {
+  notSyInSpaceQuery, //没有和当前空间绑定的系统
+  syInSpaceCreate, //系统所在业务空间--创建关系
+} from "@/api/scan/request";
+export default {
+  data() {
+    return {
+      title: '添加空间内的系统',
+      inSpaceType: '系统',
+      dialogVisible: false,
+      tableData: [],
+      loading: false,
+      headerStyle: {
+        backgroundColor: '#e1e4e5',
+        color: '#2b2b2b',
+        lineHeight: '30px'
+      }, // 列表样式
+      selections: [], // 选中项
+    }
+  },
+  props: {
+    type: {}, //equipment--equipmentFor
+    spaceId: {},
+    zone: {}, //分区类型 
+  },
+  methods: {
+    // 显示
+    showDialog() {
+      this.dialogVisible = true;
+      this.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,
+        },
+        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>

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

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

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

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

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

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

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

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

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

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

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

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

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

@@ -3,7 +3,7 @@
     <div class="search" style="margin-bottom:10px;">
       <div>
         <el-input
-          placeholder="输入设备名称或设备本地编码查询进行查询"
+          placeholder="输入设备名称或设备本地编码进行查询"
           style="width:300px;float:left;margin-right:10px;"
           v-model="search.filter"
           clearable

+ 4 - 3
src/components/business_space/table/businessTable.vue

@@ -72,7 +72,7 @@ export default {
     return {
       page: {
         size: 50,
-        sizes: [10, 30, 50, 100, 150, 200],
+        sizes: [50, 100, 150, 200],
         total: 1,
         currentPage: 1
       },
@@ -145,8 +145,9 @@ export default {
             this.$message.error(res.data.ResultMsg);
           }
         })
-        .catch(() => {
-          this.$message.error("请求出错");
+        .catch((err) => {
+          console.log(err)
+          // this.$message.error("请求出错");
         });
     },
     /**

+ 3 - 2
src/components/config_point/dictionaryCascader.vue

@@ -132,7 +132,8 @@ export default {
         data: {
           Filters: "InputMode='M' or InputMode='L'",
           PageNumber: 1,
-          PageSize: 500
+          PageSize: 500,
+          Orders: 'InfoPointName asc'
         },
         type: this.typeRelation[type] || type
       }
@@ -167,7 +168,7 @@ export default {
       })
     },
     changeSelect(val) {
-      let labels = this.$refs.dictCas.currentLabels
+      let labels = this.$refs.dictCas.getCheckedNodes()[0].pathLabels
       this.$emit('change', { val: val, labels: labels })
     },
     //减少请求次数

+ 2 - 0
src/components/config_point/step3_edit/index.vue

@@ -215,6 +215,8 @@ export default {
         basicParams.Specialty = this.dictionaryNames[1]
         basicParams.SystemCode = this.dictionaryData[2]
         basicParams.System = this.dictionaryNames[2]
+        basicParams.EquipmentTypeCode = basicParams.SystemCode  //为了配置从动参取值存储
+        basicParams.EquipmentType = basicParams.System
       }
       let updateParams = {
         data: {

+ 2 - 0
src/components/config_point/step3_point/3_temps.vue

@@ -373,6 +373,8 @@ export default {
         basicParams.Specialty = this.dictionaryNames[1]
         basicParams.SystemCode = this.dictionaryData[2]
         basicParams.System = this.dictionaryNames[2]
+        basicParams.EquipmentTypeCode = basicParams.SystemCode //为了配置从动参取值存储
+        basicParams.EquipmentType = basicParams.System
       }
       let otherParams = {}
       switch (type) {

+ 147 - 0
src/components/dialogs/config/infoPoint.vue

@@ -0,0 +1,147 @@
+<template>
+  <el-dialog title="按条件批量配置" :visible.sync="dialog.config" @close="handleClose" width="900px">
+    <el-form ref="dataForm" :model="form" label-width="90px">
+      <el-form-item label="方案:">
+        <el-radio-group v-model="form.SchemeId">
+          <el-radio label="schemeZero">全新设定</el-radio>
+          <el-radio label="schemeOne">预置方案1</el-radio>
+          <!-- <el-radio label="schemeTwo">预置方案2</el-radio> -->
+        </el-radio-group>
+      </el-form-item>
+      <el-form-item v-show="form.SchemeId == 'schemeZero'" label="优先级:">
+        <el-checkbox-group v-model="form.PriorityList">
+          <el-checkbox v-for="item in PriorityList" :key="item.Priority" :label="item.Priority" name="priority">{{ item.name }}</el-checkbox>
+        </el-checkbox-group>
+      </el-form-item>
+      <el-form-item v-show="form.SchemeId == 'schemeZero'" label="一级标签:">
+        <el-checkbox-group v-model="form.FirstNameList">
+          <el-checkbox style="width:99px;" v-for="(item, index) in FirstNameList" :key="index" :label="item.FirstName" name="firstTag"></el-checkbox>
+        </el-checkbox-group>
+      </el-form-item>
+      <el-form-item v-show="form.SchemeId == 'schemeZero'" label="二级标签:">
+        <span style="color:#bbb;font-size:12px;">二级标签暂未提供,如确实需要请联系产品添加。</span>
+      </el-form-item>
+    </el-form>
+    <div slot="footer">
+      <el-button @click="dialog.config = false">取 消</el-button>
+      <el-button type="primary" @click="onSubmit" :loading="loading">确 认</el-button>
+    </div>
+  </el-dialog>
+</template>
+<script>
+import { getDataDictionary, setInfoPoint } from "@/api/scan/request"
+import { mapGetters, mapActions } from "vuex"
+export default {
+  props: {
+    dialog: {
+      type: Object,
+      default: function () {
+        return {
+          config: false
+        };
+      }
+    }
+  },
+  data() {
+    return {
+      form: {
+        SchemeId: 'schemeZero',
+        PriorityList: [],
+        FirstNameList: []
+      },
+      FirstNameList: [],
+      PriorityList: [],
+      loading: false
+    };
+  },
+  created() {
+    this.getInfos()
+  },
+  computed: {
+    ...mapGetters("layout", ["projectId", "secret", "userId"])
+  },
+  methods: {
+    getInfos() {
+      let params1 = {
+        data: {
+          Distinct: true,
+          Filters: "FirstName != ''",
+          Orders: "FirstName desc",
+          PageNumber: 1,
+          PageSize: 1000,
+          Projection: [ "FirstName" ]
+        },
+        type: ""
+      }, params2 = {
+        data: {
+          Distinct: true,
+          Filters: "Priority != '';Priority != 'null'",
+          Orders: "Priority desc",
+          PageNumber: 1,
+          PageSize: 1000,
+          Projection: [ "Priority" ]
+        },
+        type: ""
+      };
+      let promise1 = new Promise((resolve, reject) => {
+        getDataDictionary(params1, res => {
+          resolve(res)
+        })
+      })
+      let promise2 = new Promise((resolve, reject) => {
+        getDataDictionary(params2, res => {
+          resolve(res)
+        })
+      })
+      Promise.all([promise1, promise2]).then(values => {
+        this.FirstNameList = values[0].Content
+        this.PriorityList = values[1].Content.map((item) => {
+          if (item.Priority == "S") {
+            item.name = `(${item.Priority})关键信息`
+            return item
+          } else if (item.Priority == "M") {
+            item.name = `(${item.Priority})次要信息`
+            return item
+          } else if (item.Priority == "R") {
+            item.name = `(${item.Priority})参考信息`
+            return item
+          }
+        })
+      })
+    },
+    //确定
+    onSubmit() {
+      let params = {}
+      this.loading = true
+      if (this.form.SchemeId == 'schemeZero') {
+        params = this.form
+      } else {
+        params = {
+          SchemeId: this.form.SchemeId
+        }
+      }
+      setInfoPoint(params, res => {
+        this.form.SchemeId = 'schemeZero'
+        this.form.FirstNameList = []
+        this.form.PriorityList = []
+        this.dialog.config = false
+        this.loading = false
+        this.$emit('configInfo')
+      })
+    },
+    //弹窗关闭回调
+    handleClose() {
+      this.form.SchemeId = 'schemeZero'
+      this.form.FirstNameList = []
+      this.form.PriorityList = []
+      this.loading = false
+    }
+  }
+};
+</script>
+<style lang="scss">
+  .el-dialog__body {
+    max-height: 420px;
+    overflow-y: auto;
+  }
+</style>

+ 179 - 0
src/components/ledger/cenote/dialog/addCenoteDialog.vue

@@ -0,0 +1,179 @@
+<template>
+  <el-dialog :title="title" :visible.sync="dialogVisible" width="900px" id="addEqDialog">
+    <el-row class="filters">
+      <el-col :span="9">
+        <el-input placeholder="输入竖井名称或竖井本地编码进行查询" v-model="keycode" clearable @keyup.enter.native="getTableData">
+          <i slot="suffix" class="el-input__icon el-icon-search" @click="getTableData"></i>
+        </el-input>
+      </el-col>
+      <el-col :span="15">
+        <cenote-type @change="changeCenote"></cenote-type>
+      </el-col>
+    </el-row>
+    <div class="table-box">
+      <el-table :data="tableData" style="width: 100%" height="350" v-loading="loading" :header-cell-style="headerStyle" ref="multipleTable"
+        @selection-change="handleSelectionChange">
+        <el-table-column  type="selection" width="55"></el-table-column>
+        <el-table-column :label="`${inSpaceType}名称`" show-overflow-tooltip min-width="100">
+          <template slot-scope="scope">
+            <div>
+              {{scope.row.ShaftLocalName||scope.row.ShaftName||''}}
+            </div>
+          </template>
+        </el-table-column>
+        <el-table-column prop="ShaftLocalID" :label="`${inSpaceType}本地编码`" show-overflow-tooltip min-width="100"></el-table-column>
+        <el-table-column prop="StructureInfo.ShaftFuncType" :label="`${inSpaceType}类`" show-overflow-tooltip min-width="100"></el-table-column>
+        <el-table-column prop="action" label="操作" min-width="100">
+          <template slot-scope="scope">
+            <el-button size="mini" @click="toDetail(scope.$index, scope.row)" plain>查看详情</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+      <!-- 分页 -->
+      <el-pagination class="fr" v-show="tableData && tableData.length" @size-change="handleSizeChange" @current-change="handleCurrentChange"
+        :current-page="page.pageNumber" :page-sizes="page.pageSizes" :page-size="page.pageSize" layout="total, sizes, prev, pager, next, jumper"
+        :total="page.total"></el-pagination>
+    </div>
+    <span slot="footer" class="dialog-footer">
+      <el-button size="small" @click="dialogVisible = false">取 消</el-button>
+      <el-button size="small" type="primary" @click="savaRelation">确 定</el-button>
+    </span>
+  </el-dialog>
+</template>
+
+<script>
+import { unshaftThroughShaft, queryShaftType, linkShaft } from "@/api/scan/request";
+import cenoteType from "@/components/ledger/lib/cenoteType";
+import { mapGetters } from "vuex";
+export default {
+  components: {
+    cenoteType
+  },
+  computed: {
+    ...mapGetters("layout", ["projectId"])
+  },
+  data() {
+    return {
+      title: "添加连通的其他竖井",
+      keycode: '', //输入查询条件
+      cenoteType: '', // 选中的竖井类型
+      shaftType: {}, //全部竖井类型
+      inSpaceType: '竖井',
+      dialogVisible: false,
+      tableData: [],
+      loading: false,
+      selections: [], // 选中项
+      page: {
+        pageSize: 50,
+        pageSizes: [10, 20, 50, 100],
+        pageNumber: 1,
+        total: 0
+      },
+      headerStyle: {
+        backgroundColor: '#e1e4e5',
+        color: '#2b2b2b',
+        lineHeight: '30px'
+      } // 列表样式
+    };
+  },
+  props: {
+    type: String, //选中的tab页
+    params: Object //查看的竖井关系信息
+  },
+  created() { 
+    queryShaftType(res => {
+      res.Content.forEach(item => {
+        this.shaftType[item.Code] = item.Name
+      })
+    })
+  },
+  methods: {
+    //修改竖井类型
+    changeCenote(value) {
+      this.cenoteType = value.Id
+      this.getTableData()
+    },
+    // 显示弹窗
+    showDialog() {
+      this.dialogVisible = true
+      this.page.pageNumber = 1
+      this.tableData = []
+      this.getTableData()
+    },
+    getTableData() {
+      let params = {
+        data: {
+          Filters: this.cenoteType? `ProjectId='${this.projectId}';structureInfo.ShaftFuncType='${this.cenoteType}'`: `ProjectId='${this.projectId}'`,
+          Orders: "createTime desc, ShaftID asc",
+          PageNumber: this.page.pageNumber,
+          PageSize: this.page.pageSize,
+        },
+        shaftId: this.params.ShaftID
+      }
+      if(this.keycode!=''){
+        params.data.Filters += `;ShaftName contain '${this.keycode}' or ShaftLocalName contain '${this.keycode}' or ShaftLocalID contain '${this.keycode}'`
+      }
+      unshaftThroughShaft(params, res => {
+        this.tableData = res.Content
+        this.tableData.forEach(item => {
+          if(item.StructureInfo && item.StructureInfo.ShaftFuncType){
+            item.StructureInfo.ShaftFuncType = this.shaftType[item.StructureInfo.ShaftFuncType]
+          }
+        })
+        this.page.total = res.Total
+      })
+    },
+    //选中项修改
+    handleSelectionChange(val) {
+      this.selections = val;
+    },
+    savaRelation() {
+      if(this.selections.length){
+        let params = {
+          ShaftId: this.params.ShaftID,
+          ShaftOtherIdList: this.selections.map(item => {
+            return item.ShaftID
+          })
+        }
+        linkShaft(params, res => {
+          this.dialogVisible = false
+          this.$message.success('关联成功!')
+          this.$emit('refresh')
+        })
+      }else {
+        this.$message('请选择要关联的设备')
+      }
+    },
+    //改变pagesize
+    handleSizeChange(pageSize) {
+      this.page.pageSize = pageSize;
+      this.getTableData();
+    },
+    //改变pageno
+    handleCurrentChange(pageNo) {
+      this.page.pageNumber = pageNo;
+      this.getTableData();
+    },
+    // 查看详情
+    toDetail() {
+      this.$message('开发中')
+    }
+  },
+};
+</script>
+<style lang="less" scoped>
+#addEqDialog {
+  .filters {
+    margin-bottom: 10px;
+    /deep/ .el-input__inner {
+      vertical-align: baseline;
+    }
+  }
+  .table-box {
+    height: 370px;
+    .fr{
+      margin-top: 10px;
+    }
+  }
+}
+</style>

+ 187 - 0
src/components/ledger/cenote/dialog/addEquipDialog.vue

@@ -0,0 +1,187 @@
+<template>
+  <el-dialog :title="title" :visible.sync="dialogVisible" width="900px" id="addEqDialog">
+    <el-row class="filters">
+      <el-col :span="9">
+        <el-input placeholder="输入设备名称或设备本地编码进行查询" v-model="keycode" clearable @keyup.enter.native="getTableData">
+          <i slot="suffix" class="el-input__icon el-icon-search" @click="getTableData"></i>
+        </el-input>
+      </el-col>
+      <el-col :span="15">
+        <floor-cascader @change="changeFloor"></floor-cascader>
+      </el-col>
+    </el-row>
+    <div class="table-box">
+      <el-table :data="tableData" style="width: 100%" height="350" v-loading="loading" :header-cell-style="headerStyle" ref="multipleTable"
+        @selection-change="handleSelectionChange">
+        <el-table-column  type="selection" width="55"></el-table-column>
+        <el-table-column :label="`${inSpaceType}名称`" show-overflow-tooltip min-width="100">
+          <template slot-scope="scope">
+            <div>
+              {{scope.row.EquipLocalName||scope.row.EquipName||''}}
+            </div>
+          </template>
+        </el-table-column>
+        <el-table-column prop="EquipLocalID" :label="`${inSpaceType}本地编码`" show-overflow-tooltip min-width="100"></el-table-column>
+        <el-table-column prop="EquipCategory.EquipName" :label="`${inSpaceType}类`" show-overflow-tooltip min-width="100"></el-table-column>
+        <el-table-column prop="ShaftListName" label="已关联其他竖井" show-overflow-tooltip min-width="100" max-width="200"></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)" plain>查看详情</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+      <!-- 分页 -->
+      <el-pagination class="fr" v-show="tableData && tableData.length" @size-change="handleSizeChange" @current-change="handleCurrentChange"
+        :current-page="page.pageNumber" :page-sizes="page.pageSizes" :page-size="page.pageSize" layout="total, sizes, prev, pager, next, jumper"
+        :total="page.total"></el-pagination>
+    </div>
+    <span slot="footer" class="dialog-footer">
+      <el-button size="small" @click="dialogVisible = false">取 消</el-button>
+      <el-button size="small" type="primary" @click="savaRelation">确 定</el-button>
+    </span>
+  </el-dialog>
+</template>
+
+<script>
+import { unshaftInEq, linkEqSh } from "@/api/scan/request";
+import floorCascader from "@/components/ledger/lib/floorCascader";
+import { mapGetters } from "vuex";
+export default {
+  components: {
+    floorCascader
+  },
+  computed: {
+    ...mapGetters("layout", ["projectId"])
+  },
+  data() {
+    return {
+      title: "添加竖井内的设备",
+      keycode: '', //输入查询条件
+      Buildfloor: ['all'], // 选中的建筑楼层
+      inSpaceType: '设备',
+      dialogVisible: false,
+      tableData: [],
+      loading: false,
+      selections: [], // 选中项
+      page: {
+        pageSize: 50,
+        pageSizes: [10, 20, 50, 100],
+        pageNumber: 1,
+        total: 0
+      },
+      headerStyle: {
+        backgroundColor: '#e1e4e5',
+        color: '#2b2b2b',
+        lineHeight: '30px'
+      } // 列表样式
+    };
+  },
+  props: {
+    type: String, //选中的tab页
+    params: Object //查看的竖井关系信息
+  },
+  created() { },
+  methods: {
+    //修改建筑楼层
+    changeFloor(value) {
+      this.Buildfloor = value
+      this.getTableData()
+    },
+    // 显示弹窗
+    showDialog() {
+      this.dialogVisible = true
+      this.page.pageNumber = 1
+      this.tableData = []
+      this.getTableData()
+    },
+    getTableData() {
+      let params = {
+        data: {
+          Cascade: [{ Name: 'equipCategory' }, {Name: 'shaftList'}],
+          Filters:`not EquipID isNull`,
+          Orders: "createTime desc, EquipID desc",
+          PageNumber: this.page.pageNumber,
+          PageSize: this.page.pageSize,
+        },
+        shaftId: this.params.ShaftID
+      }
+      if (this.Buildfloor[0] == "noKnow") {
+        params.data.Filters += `;buildingId isNull`
+      } else if (this.Buildfloor[0] && this.Buildfloor[0] != "all") {
+        params.data.Filters += `;buildingId='${this.Buildfloor[0]}'`
+      }
+      if (this.Buildfloor[1] == "noKnow") {
+        params.data.Filters += `;floorId isNull`
+      } else if (this.Buildfloor[1] && this.Buildfloor[1] != "all") {
+        params.data.Filters += `;floorId='${this.Buildfloor[1]}'`
+      }
+      if(this.keycode!=''){
+        params.data.Filters += `;EquipName contain '${this.keycode}' or EquipLocalName contain '${this.keycode}' or EquipLocalID contain '${this.keycode}'`
+      }
+      unshaftInEq(params, res => {
+        res.Content.forEach(item => {
+          item.ShaftListName = ""
+          if(item.ShaftList && item.ShaftList.length){
+            item.ShaftListName = item.ShaftList.map(shaft => {
+              return shaft.ShaftLocalName?shaft.ShaftLocalName:shaft.ShaftName
+            }).join("、")
+          }
+        })
+        this.tableData = res.Content
+        this.page.total = res.Total
+      })
+    },
+    //选中项修改
+    handleSelectionChange(val) {
+      this.selections = val;
+    },
+    savaRelation() {
+      if(this.selections.length){
+        let params = {
+          ShaftId: this.params.ShaftID,
+          EquipIdList: this.selections.map(item => {
+            return item.EquipID
+          })
+        }
+        linkEqSh(params, res => {
+          this.dialogVisible = false
+          this.$message.success('关联成功!')
+          this.$emit('refresh')
+        })
+      }else {
+        this.$message('请选择要关联的设备')
+      }
+    },
+    //改变pagesize
+    handleSizeChange(pageSize) {
+      this.page.pageSize = pageSize;
+      this.getTableData();
+    },
+    //改变pageno
+    handleCurrentChange(pageNo) {
+      this.page.pageNumber = pageNo;
+      this.getTableData();
+    },
+    // 查看详情
+    toDetail() {
+      this.$message('开发中')
+    }
+  },
+};
+</script>
+<style lang="less" scoped>
+#addEqDialog {
+  .filters {
+    margin-bottom: 10px;
+    /deep/ .el-input__inner {
+      vertical-align: baseline;
+    }
+  }
+  .table-box {
+    height: 370px;
+    .fr{
+      margin-top: 10px;
+    }
+  }
+}
+</style>

+ 147 - 0
src/components/ledger/cenote/dialog/addSystemDialog.vue

@@ -0,0 +1,147 @@
+<template>
+  <el-dialog :title="title" :visible.sync="dialogVisible" width="900px" id="addEqDialog">
+    <div class="table-box">
+      <el-table :data="tableData" style="width: 100%" height="350" v-loading="loading" :header-cell-style="headerStyle" ref="multipleTable"
+        @selection-change="handleSelectionChange">
+        <el-table-column  type="selection" width="55"></el-table-column>
+        <el-table-column :label="`${inSpaceType}名称`" show-overflow-tooltip min-width="100">
+          <template slot-scope="scope">
+            <div>
+              {{scope.row.SysLocalName||scope.row.SysName||''}}
+            </div>
+          </template>
+        </el-table-column>
+        <el-table-column prop="SysLocalId" :label="`${inSpaceType}本地编码`" show-overflow-tooltip min-width="100"></el-table-column>
+        <el-table-column prop="CategoryNames.CategoryName" :label="`${inSpaceType}类`" show-overflow-tooltip min-width="100"></el-table-column>
+        <el-table-column prop="action" label="操作" min-width="100">
+          <template slot-scope="scope">
+            <el-button size="mini" @click="toDetail(scope.$index, scope.row)" plain>查看详情</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+      <!-- 分页 -->
+      <el-pagination class="fr" v-show="tableData && tableData.length" @size-change="handleSizeChange" @current-change="handleCurrentChange"
+        :current-page="page.pageNumber" :page-sizes="page.pageSizes" :page-size="page.pageSize" layout="total, sizes, prev, pager, next, jumper"
+        :total="page.total"></el-pagination>
+    </div>
+    <span slot="footer" class="dialog-footer">
+      <el-button size="small" @click="dialogVisible = false">取 消</el-button>
+      <el-button size="small" type="primary" @click="savaRelation">确 定</el-button>
+    </span>
+  </el-dialog>
+</template>
+
+<script>
+import { unshaftInSys, linkSySh } from "@/api/scan/request";
+import floorCascader from "@/components/ledger/lib/floorCascader";
+import { mapGetters } from "vuex";
+export default {
+  components: {
+    floorCascader
+  },
+  computed: {
+    ...mapGetters("layout", ["projectId"])
+  },
+  data() {
+    return {
+      title: "添加竖井内的系统",
+      inSpaceType: '系统',
+      dialogVisible: false,
+      tableData: [],
+      loading: false,
+      selections: [], // 选中项
+      page: {
+        pageSize: 50,
+        pageSizes: [10, 20, 50, 100],
+        pageNumber: 1,
+        total: 0
+      },
+      headerStyle: {
+        backgroundColor: '#e1e4e5',
+        color: '#2b2b2b',
+        lineHeight: '30px'
+      } // 列表样式
+    };
+  },
+  props: {
+    type: String, //选中的tab页
+    params: Object //查看的竖井关系信息
+  },
+  created() { },
+  methods: {
+    // 显示弹窗
+    showDialog() {
+      this.dialogVisible = true
+      this.page.pageNumber = 1
+      this.tableData = []
+      this.getTableData()
+    },
+    getTableData() {
+      let params = {
+        data: {
+          Cascade: [{ Name: 'categoryNames' }],
+          Orders: "createTime desc, SysID desc",
+          PageNumber: this.page.pageNumber,
+          PageSize: this.page.pageSize,
+        },
+        shaftId: this.params.ShaftID
+      }
+      unshaftInSys(params, res => {
+        this.tableData = res.Content
+        this.page.total = res.Total
+      })
+    },
+    //选中项修改
+    handleSelectionChange(val) {
+      this.selections = val;
+    },
+    savaRelation() {
+      if(this.selections.length){
+        let params = {
+          ShaftId: this.params.ShaftID,
+          SysIdList: this.selections.map(item => {
+            return item.SysID
+          })
+        }
+        linkSySh(params, res => {
+          this.dialogVisible = false
+          this.$message.success('关联成功!')
+          this.$emit('refresh')
+        })
+      }else {
+        this.$message('请选择要关联的设备')
+      }
+    },
+    //改变pagesize
+    handleSizeChange(pageSize) {
+      this.page.pageSize = pageSize;
+      this.getTableData();
+    },
+    //改变pageno
+    handleCurrentChange(pageNo) {
+      this.page.pageNumber = pageNo;
+      this.getTableData();
+    },
+    // 查看详情
+    toDetail() {
+      this.$message('开发中')
+    }
+  },
+};
+</script>
+<style lang="less" scoped>
+#addEqDialog {
+  .filters {
+    margin-bottom: 10px;
+    /deep/ .el-input__inner {
+      vertical-align: baseline;
+    }
+  }
+  .table-box {
+    height: 370px;
+    .fr{
+      margin-top: 10px;
+    }
+  }
+}
+</style>

+ 155 - 0
src/components/ledger/cenote/table/cenoteTable.vue

@@ -0,0 +1,155 @@
+<template>
+  <div id="eqInSp">
+    <el-row>
+      <el-button type="primary" @click="add">添加{{inSpaceType}}</el-button>
+      <el-tooltip class="item" effect="dark" content="可前往“全部关系总览”中计算连通的其它竖井" placement="right">
+        <el-button>按空间计算</el-button>
+      </el-tooltip>
+    </el-row>
+    <div class="table-box">
+      <el-table :data="tableData" style="width: 100%" height="100%" v-loading="loading" :header-cell-style="headerStyle">
+        <el-table-column :label="`${inSpaceType}名称`" show-overflow-tooltip min-width="100">
+          <template slot-scope="scope">
+            <div>
+              {{scope.row.ShaftLocalName||scope.row.ShaftName||''}}
+            </div>
+          </template>
+        </el-table-column>
+        <el-table-column prop="ShaftLocalID" :label="`${inSpaceType}本地编码`" show-overflow-tooltip min-width="100"></el-table-column>
+        <el-table-column :label="`${inSpaceType}类型`" show-overflow-tooltip min-width="100">
+          <template slot-scope="scope">
+            <div>
+              {{scope.row.StructureInfo.ShaftFuncType}}
+            </div>
+          </template>
+        </el-table-column>
+        <el-table-column prop="action" label="操作" min-width="100">
+          <template slot-scope="scope">
+            <el-tooltip class="item" effect="dark" content="删除关系" placement="left">
+              <el-button size="mini" @click="handleDelete(scope.$index, scope.row)" type="danger" plain icon="el-icon-delete"></el-button>
+            </el-tooltip>
+          </template>
+        </el-table-column>
+        <template slot="empty">
+          <div style="height: 60%;transform: translateY(50%);">
+            <i class="icon-wushuju iconfont"></i>
+            可前往“全部关系总览”中计算连通的其它竖井
+          </div>
+        </template>
+      </el-table>
+    </div>
+    <!-- 添加设备弹窗 -->
+    <addCenoteDialog ref="addCenoteDialog" @refresh="getTableData" :type="type" :params="params"></addCenoteDialog>
+  </div>
+</template>
+
+<script>
+import { queryCenoteTableData, queryShaftType, shthroughshUnlink } from "@/api/scan/request";
+import { mapGetters } from "vuex";
+import addCenoteDialog from "@/components/ledger/cenote/dialog/addCenoteDialog"
+export default {
+  components: {
+    addCenoteDialog
+  },
+  computed: {
+    ...mapGetters("layout", ["projectId"])
+  },
+  data() {
+    return {
+      inSpaceType: '竖井',
+      headerStyle: {
+        backgroundColor: '#e1e4e5',
+        color: '#2b2b2b',
+        lineHeight: '30px'
+      }, // 列表样式
+      loading: false, // loading
+      tableData: [], //列表数据
+      shaftType: {} //竖井类型
+    };
+  },
+  props: {
+    params: Object,
+    type: String
+  },
+  created() {
+    queryShaftType(res => {
+      res.Content.forEach(item => {
+        this.shaftType[item.Code] = item.Name
+      })
+      this.getTableData()
+    })
+  },
+  methods: {
+    // 获取列表数据
+    getTableData() {
+      let params = {
+        Filters: `ShaftID='${this.params.ShaftID}'`,
+        Cascade: [
+          {
+            Name: 'shaftThroughList'
+          }
+        ]
+      }
+      queryCenoteTableData(params, res => {
+        this.tableData = res.Content[0].ShaftThroughList || []
+        this.tableData.forEach(item => {
+          if(item.StructureInfo && item.StructureInfo.ShaftFuncType){
+            item.StructureInfo.ShaftFuncType = this.shaftType[item.StructureInfo.ShaftFuncType]
+          }
+        })
+      })
+    },
+    // 删除关系
+    handleDelete(index, row) {
+      this.$confirm("确认删除该关系?", "提示", {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        let params = {
+          ShaftOtherId: row.ShaftID,
+          ShaftId: this.params.ShaftID
+        }
+        this.deleteShThroughSh(params);
+      }).catch(() => {
+        this.$message("取消删除")
+      })
+    },
+    // 删除设备所在空间关系
+    deleteShThroughSh(params) {
+      shthroughshUnlink(params, res => {
+        this.$message.success('删除成功')
+        this.getTableData()
+      })
+    },
+    // 改变pagesize
+    handleSizeChange(pageSize) {
+      this.page.pageSize = pageSize;
+      this.getTableData();
+    },
+    // 改变pageno
+    handleCurrentChange(pageNo) {
+      this.page.pageNumber = pageNo;
+      this.getTableData();
+    },
+    // 添加设备
+    add() {
+      this.$refs.addCenoteDialog.showDialog()
+    }
+  },
+  watch: {
+    type() {
+      this.getTableData()
+    }
+  }
+};
+</script>
+<style lang="less" scoped>
+#eqInSp {
+  height: 100%;
+  .table-box {
+    margin-top: 10px;
+    height: calc(100% - 50px);
+  }
+}
+</style>

+ 143 - 0
src/components/ledger/cenote/table/deviceTable.vue

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

+ 145 - 0
src/components/ledger/cenote/table/systemTable.vue

@@ -0,0 +1,145 @@
+<template>
+  <div id="eqInSp">
+    <el-row>
+      <el-button type="primary" @click="add">添加{{inSpaceType}}</el-button>
+      <el-tooltip class="item" effect="dark" content="可前往“全部关系总览”中计算竖井内系统" placement="right">
+        <el-button>按空间计算</el-button>
+      </el-tooltip>
+    </el-row>
+    <div class="table-box">
+      <el-table :data="tableData" style="width: 100%" height="100%" v-loading="loading" :header-cell-style="headerStyle">
+        <el-table-column :label="`${inSpaceType}名称`" show-overflow-tooltip min-width="100">
+          <template slot-scope="scope">
+            <div>
+              {{scope.row.SysLocalName||scope.row.SysName||''}}
+            </div>
+          </template>
+        </el-table-column>
+        <el-table-column prop="SysLocalID" :label="`${inSpaceType}本地编码`" show-overflow-tooltip min-width="100"></el-table-column>
+        <el-table-column :label="`${inSpaceType}类型`" show-overflow-tooltip min-width="100">
+          <template slot-scope="scope">
+            <div>
+              {{scope.row.CategoryNames.CategoryName}}
+            </div>
+          </template>
+        </el-table-column>
+        <el-table-column prop="action" label="操作" min-width="100">
+          <template slot-scope="scope">
+            <el-tooltip class="item" effect="dark" content="删除关系" placement="left">
+              <el-button size="mini" @click="handleDelete(scope.$index, scope.row)" type="danger" plain icon="el-icon-delete"></el-button>
+            </el-tooltip>
+          </template>
+        </el-table-column>
+        <template slot="empty">
+          <div style="height: 60%;transform: translateY(50%);">
+            <i class="icon-wushuju iconfont"></i>
+            可前往“全部关系总览”中计算竖井内系统
+          </div>
+        </template>
+      </el-table>
+    </div>
+    <!-- 添加设备弹窗 -->
+    <addSystemDialog ref="addEqDialog" @refresh="getTableData" :type="type" :params="params"></addSystemDialog>
+  </div>
+</template>
+
+<script>
+import { queryCenoteTableData, syinshUnlink } from "@/api/scan/request";
+import { mapGetters } from "vuex";
+import addSystemDialog from "@/components/ledger/cenote/dialog/addSystemDialog"
+export default {
+  components: {
+    addSystemDialog
+  },
+  computed: {
+    ...mapGetters("layout", ["projectId"])
+  },
+  data() {
+    return {
+      inSpaceType: '系统',
+      headerStyle: {
+        backgroundColor: '#e1e4e5',
+        color: '#2b2b2b',
+        lineHeight: '30px'
+      }, // 列表样式
+      loading: false, // loading
+      tableData: [] //列表数据
+    };
+  },
+  props: {
+    params: Object,
+    type: String
+  },
+  created() {
+    this.getTableData()
+  },
+  methods: {
+    // 获取列表数据
+    getTableData() {
+      let params = {
+        Filters: `ShaftID='${this.params.ShaftID}'`,
+        Cascade: [
+          {
+            Name: 'systemList',
+            Cascade: [{ Name: 'categoryNames' }]
+          }
+        ]
+      }
+      queryCenoteTableData(params, res => {
+        this.tableData = res.Content[0].SystemList || []
+      })
+    },
+    // 删除关系
+    handleDelete(index, row) {
+      this.$confirm("确认删除该关系?", "提示", {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        let params = {
+          SysId: row.SysID,
+          ShaftId: this.params.ShaftID
+        }
+        this.deleteSyInSh(params);
+      }).catch(() => {
+        this.$message("取消删除")
+      })
+    },
+    // 删除系统所在竖井关系
+    deleteSyInSh(params) {
+      syinshUnlink(params, res => {
+        this.$message.success('删除成功')
+        this.getTableData()
+      })
+    },
+    // 改变pagesize
+    handleSizeChange(pageSize) {
+      this.page.pageSize = pageSize;
+      this.getTableData();
+    },
+    // 改变pageno
+    handleCurrentChange(pageNo) {
+      this.page.pageNumber = pageNo;
+      this.getTableData();
+    },
+    // 添加设备
+    add() {
+      this.$refs.addEqDialog.showDialog()
+    }
+  },
+  watch: {
+    type() {
+      this.getTableData()
+    }
+  }
+};
+</script>
+<style lang="less" scoped>
+#eqInSp {
+  height: 100%;
+  .table-box {
+    margin-top: 10px;
+    height: calc(100% - 50px);
+  }
+}
+</style>

+ 128 - 56
src/components/ledger/handsontables/assets.vue

@@ -22,32 +22,47 @@
     <supply-dialog @change="supplyChange" ref="supply" :id="id" :dialog="myDialog"></supply-dialog>
     <supplier-dialog ref="supplier" @changeSupplier="supplierChange" :dialog="myDialog"></supplier-dialog>
     <guarantee-dialog @change="guaranteeChange" :id="id" ref="guarantee" :dialog="myDialog"></guarantee-dialog>
-    <upload-files-dialog :read="onlyRead ? true : false" ref="upload" @changeFile="fileChange" :keysArr="filesArr" :dialog="myDialog" ></upload-files-dialog>
-    <upload-img-dialog :read="onlyRead ? true : false" @changeFile="imgChange" :keysArr="imgsArr" :dialog="myDialog" ></upload-img-dialog>
+    <upload-files-dialog :read="onlyRead ? true : false" ref="upload" @changeFile="fileChange" :keysArr="filesArr" :dialog="myDialog">
+    </upload-files-dialog>
+    <upload-img-dialog :read="onlyRead ? true : false" @changeFile="imgChange" :keysArr="imgsArr" :dialog="myDialog"></upload-img-dialog>
     <maintainer-dialog @changeMaintainer="changeMaintainer" ref="maintainer" :dialog="myDialog"></maintainer-dialog>
     <insurer-dialog @changeInsurer="changeInsurer" ref="insurer" :dialog="myDialog"></insurer-dialog>
-    <pic-dialog :read="onlyRead ? true : false" :dialog="myDialog" :keysArr="picsArr" @change="changePics" ></pic-dialog>
+    <pic-dialog :read="onlyRead ? true : false" :dialog="myDialog" :keysArr="picsArr" @change="changePics"></pic-dialog>
     <div class="center middle_sty" style="height: 91%" v-show="!mess.deviceId && (!tableData || !tableData.length)">
-        <p>
-          <i class="icon-wushuju iconfont"></i>
+      <p>
+        <i class="icon-wushuju iconfont"></i>
         请选择设备族
-        </p>
+      </p>
     </div>
     <div class="center middle_sty" style="height: 91%" v-show="mess.deviceId && (!tableData || !tableData.length)">
-        <p>
-          <i class="icon-wushuju iconfont"></i>
+      <p>
+        <i class="icon-wushuju iconfont"></i>
         暂无数据
-        </p>
+      </p>
     </div>
     <div v-show="mess.deviceId && tableData && tableData.length" v-loading="loading" id="handsontable" ref="handsontable"></div>
     <div v-show="tableData && tableData.length" class='right'>
-        <my-pagination @change="getTableData" :page="page"></my-pagination>
+      <my-pagination @change="getTableData" :page="page"></my-pagination>
     </div>
     <!-- <dialog-assets :assetType="[this.mess.deviceId]"  @close="closeDialog" ref="assets" v-if="myDialog.addDevice" :dialog="myDialog" ></dialog-assets> -->
     <details-dialog :iframeSrc="iframeSrc" v-if="myDialog.details" :dialog="myDialog"></details-dialog>
     <look-pic :dialog="myDialog" :keysArr="picsArr"></look-pic>
+    <!-- 不支持的输入方式 -->
+    <el-dialog title="临时维护信息点" :visible.sync="myDialog.update" @close="handleCloseUpdate" width="670px">
+      <el-row>
+        该信息点未定义对应组件,现在维护数据不确定后续是否可用。如确实需要维护,请点击<el-link @click="updateInputShow = true" type="primary" :underline="false">继续维护</el-link>。
+      </el-row>
+      <el-row style="margin-top:20px;" v-show="updateInputShow">
+        <el-input type="textarea" :autosize="{ minRows: 4, maxRows: 8}" placeholder="请输入内容" v-model="updateInput"></el-input>
+      </el-row>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="myDialog.update = false">取 消</el-button>
+        <el-button type="primary" @click="handleClickUpdate">确 认</el-button>
+      </span>
+    </el-dialog>
     <!-- 新增资产 -->
-    <el-dialog class="add-assets" :title="showAddByDie?'未关联资产的设备批量创建资产':'确定新增资产类型'" @close="showAddByDie = false" :visible.sync="myDialog.addDevice" width="670px">
+    <el-dialog class="add-assets" :title="showAddByDie?'未关联资产的设备批量创建资产':'确定新增资产类型'" @close="showAddByDie = false" :visible.sync="myDialog.addDevice"
+      width="670px">
       <el-row>
         <my-cascader v-show="!showAddByDie" ref="cascader" :all="true" @change="changeCader"></my-cascader>
         <die-cascader v-show="showAddByDie" ref="dieCascader" :Family="addData.Family" @change="changeDevice"></die-cascader>
@@ -123,7 +138,7 @@ export default {
     buildFloor.getData(this.buildFloorData)
   },
   computed: {
-    ...mapGetters("layout", [ "projectId", "secret", "userId" ]),
+    ...mapGetters("layout", ["projectId", "secret", "userId"]),
     showTypes() {
       return this.onlyRead ?
         [{ value: "Visible", label: '只看采集信息' }, { value: "all", label: '全部' }] :
@@ -165,6 +180,7 @@ export default {
         details: false,//详情页
         changeRea: false,//关联资产
         lookPic: false,//图片查看
+        update: false,//临时维护信息点
       },
       row: null, //被修改的row
       filesArr: [], //保存临时的文件key
@@ -177,7 +193,7 @@ export default {
       iframeSrc: "",
       id: 0,
       onlyRead: true,
-      showType: 'all',
+      showType: 'Visible',
       linkNameFalg: false,
       qrcodeUrl: "", //二维码图片地址
       loading: false,
@@ -187,12 +203,18 @@ export default {
       showAddByDie: false,//是否显示通过设备添加资产页面
       addData: {}, //添加资产选择的资产类型
       numParams: { // 查询设备部件数量条件
-        category:'',
-        buildId:'',
-        floorId:'',
-        Family:''
+        category: '',
+        buildId: '',
+        floorId: '',
+        Family: ''
       },
-      dieNum: 0 // 查询设备部件数量
+      dieNum: 0, // 查询设备部件数量
+      inputMap: {
+        flowBuild: 'D1'
+      }, //信息点和输入方式映射表
+      updateInputShow: false, //是否显示临时维护输入框
+      updateInfoPoint: '',//临时维护信息点
+      updateInput: '', //临时维护信息点值
     };
   },
   methods: {
@@ -211,6 +233,11 @@ export default {
         };
         getDataDictionary(params, res => {
           this.tableHeader = res.Content;
+          this.tableHeader.forEach(item => {
+            if(item.Path && item.InputMode){
+              this.inputMap[item.Path] = item.InputMode
+            }
+          })
           this.getTableData()
         });
       }
@@ -381,7 +408,7 @@ export default {
       let param = this.formatFilter()
       createPropertys(param, res => {
         this.myDialog.addDevice = false
-        this.$emit('getJson',{code: this.numParams.Family})
+        this.$emit('getJson', { code: this.numParams.Family })
         this.$message.success("创建成功!")
       })
     },
@@ -401,7 +428,7 @@ export default {
     },
     //选择设备类型-添加资产
     changeCader(val) {
-      if(val.code && val.facility){
+      if (val.code && val.facility) {
         this.addData.Family = val.code
         this.addData.name = val.facility
         this.numParams.Family = val.code
@@ -409,7 +436,7 @@ export default {
     },
     //选择设备或部件
     changeDevice(val) {
-      if(val.code) {
+      if (val.code) {
         this.numParams.category = val.code
       } else {
         this.numParams.category = ''
@@ -602,7 +629,7 @@ export default {
     async removeDevice(param) {
       await deleteProperty(param, res => {
         this.$message.success("删除成功")
-        this.$emit('getJson','')
+        this.$emit('getJson', '')
         this.getTableData()
       })
     },
@@ -616,8 +643,8 @@ export default {
       change.map(item => {
         let key = item[1].split(".")[0]
         if (key == "flowBuild" && keyList.indexOf(key) == -1) {
-          keyList.push("BuildingId","FloorId")
-          param.Projection.push("BuildingId","FloorId")
+          keyList.push("BuildingId", "FloorId")
+          param.Projection.push("BuildingId", "FloorId")
         }
         if (item[1] && keyList.indexOf(key) == -1) {
           keyList.push(key)
@@ -675,6 +702,7 @@ export default {
     //获取到了正确的信息
     getInfors(infos, row, el) {
       let val = this.hot.colToProp(row.col);
+      let inputMode = this.inputMap[val];
       this.row = row.row;
       this.messKey = val;
       switch (val) {
@@ -682,7 +710,7 @@ export default {
         case 'caozuo':
           // window.open(`http://adm.sagacloud.cn:8058/spread?id=${infos.EquipID}&pid=${this.projectId}&secret=${this.secret}`,"_blank")
           this.$message("开发中...")
-          break;
+          return false
         //资产二维码图片
         case 'EquipQRCode':
           this.qrcodeUrl = this.tableData[row.row].EquipQRCode;
@@ -691,7 +719,7 @@ export default {
           } else {
             this.$message("此资产没有资产二维码");
           }
-          break;
+          return false
         //关联系统
         case 'LinkSystem':
           if (!this.onlyRead) {
@@ -699,37 +727,37 @@ export default {
             this.systemList = this.tableData[row.row].LinkSystem || [];
             this.myDialog.systemType = true;
           }
-          break;
+          return false
         //关联资产
         case 'LinkEquipLocalName':
           if (this.linkNameFalg) {
             this.myDialog.changeRea = true;
           }
-          break;
+          return false
         //品牌型号弹窗
         case 'DPManufacturerID':
           if (!this.onlyRead) {
             this.myDialog.firm = true;
           }
-          break;
+          return false
         //供应商信息弹窗
         case 'DPSupplierID':
           if (!this.onlyRead) {
             this.myDialog.supplier = true;
           }
-          break;
+          return false
         //维修商信息弹窗
         case 'DPMaintainerID':
           if (!this.onlyRead) {
             this.myDialog.maintainer = true;
           }
-          break;
+          return false
         //保险公司信息
         case 'DPInsurerID':
           if (!this.onlyRead) {
             this.myDialog.insurer = true;
           }
-          break;
+          return false
         //供应合同编号
         case 'LedgerParam.SupplyPurchase.SupplierContractID':
           if (!this.onlyRead) {
@@ -745,7 +773,7 @@ export default {
               this.$message("请先选择供应商");
             }
           }
-          break;
+          return false
         //保险单号
         case 'LedgerParam.InsuranceDoc.InsuranceNum':
           if (!this.onlyRead) {
@@ -761,7 +789,7 @@ export default {
               this.$message("请先选择保险商");
             }
           }
-          break;
+          return false
         //保险文件--资产文档--安装质检报告
         case 'LedgerParam.InsuranceDoc.InsuranceFile':
         case 'LedgerParam.PhotoDoc.Archive':
@@ -769,7 +797,7 @@ export default {
           let IPSdata = tools.dataForKey(this.tableData[row.row], val);
           this.filesArr = IPSdata ? IPSdata : [];
           this.myDialog.uploadFiles = true;
-          break;
+          return false
         //安装照片--安装图纸--资产铭牌照片--资产图纸
         case 'LedgerParam.Siteinstall.InstallPic':
         case 'LedgerParam.Siteinstall.InstallDrawing':
@@ -778,13 +806,13 @@ export default {
           let SSPPdata = tools.dataForKey(this.tableData[row.row], val);
           this.imgsArr = SSPPdata ? SSPPdata : [];
           this.myDialog.uploadImgs = true;
-          break;
+          return false
         //资产照片
         case 'LedgerParam.PhotoDoc.Pic':
           let Pdata = tools.dataForKey(this.tableData[row.row], val);
           this.picsArr = Pdata ? Pdata : [];
           this.myDialog.pic = true;
-          break;
+          return false
         //包含的部件字段
         case 'Count':
           if (this.onlyRead) {
@@ -792,10 +820,29 @@ export default {
           } else {
             this.$router.push({ path: '/ledger/partsmanage', query: { deviceId: infos.EquipID, typeId: this.mess.deviceId } });
           }
-          break;
+          return false
         default:
           break;
       }
+      if (!this.onlyRead && showTools.InputModeArr.indexOf(inputMode) == '-1') {
+        this.updateInfoPoint = val
+        this.updateInput = tools.dataForKey(this.tableData[row.row], val)
+        this.myDialog.update = true
+      }
+    },
+    //关闭临时维护弹窗回调
+    handleCloseUpdate() {
+      this.updateInputShow = false
+      this.updateInfoPoint = ''
+      this.updateInput = ''
+    },
+    //更新临时维护信息点
+    handleClickUpdate(){
+      tools.setDataForKey(this.tableData[this.row], this.updateInfoPoint, this.updateInput)
+      this.handleUpdataTable([[this.row, this.updateInfoPoint, null, this.updateInput]], "edit")
+      this.updateInputShow = false
+      this.myDialog.update = false
+      this.updateInput = ''
     },
     //获取被筛选掉的行号
     trimmedRows() {
@@ -828,8 +875,14 @@ export default {
     supplierChange(data) {
       tools.setDataForKey(this.tableData[this.row], "DPSupplierID", data.venderId)
       tools.setDataForKey(this.tableData[this.row], "LedgerParam.SupplyPurchase.Supplier", data.name)
-      this.handleUpdataTable([[this.row, "DPSupplierID", null, data.venderId]], "edit")
-      this.handleUpdataTable([[this.row, "LedgerParam.SupplyPurchase.Supplier", null, data.name]], "edit")
+      this.handleUpdataTable(
+        [
+          [this.row, "DPSupplierID", null, data.venderId],
+          [this.row, "LedgerParam.SupplyPurchase.Supplier", null, data.name]
+        ],
+        "edit"
+      )
+      // this.handleUpdataTable([[this.row, "LedgerParam.SupplyPurchase.Supplier", null, data.name]], "edit")
     },
     //供应合同编号
     supplyChange(data) {
@@ -852,23 +905,42 @@ export default {
       tools.setDataForKey(this.tableData[this.row], "DPManufacturerID", data.venderId)
       tools.setDataForKey(this.tableData[this.row], "LedgerParam.EquipManufactor.Brand", data.brand)
       tools.setDataForKey(this.tableData[this.row], "LedgerParam.EquipManufactor.Specification", data.name)
-      this.handleUpdataTable([[this.row, "DPManufacturerID", null, data.venderId]], "edit")
-      this.handleUpdataTable([[this.row, "LedgerParam.EquipManufactor.Brand", null, data.brand]], "edit")
-      this.handleUpdataTable([[this.row, "LedgerParam.EquipManufactor.Specification", null, data.name]], "edit")
+      this.handleUpdataTable(
+        [
+          [this.row, "DPManufacturerID", null, data.venderId],
+          [this.row, "LedgerParam.EquipManufactor.Brand", null, data.brand],
+          [this.row, "LedgerParam.EquipManufactor.Specification", null, data.name]
+        ],
+        "edit"
+      )
+      // this.handleUpdataTable([[this.row, "LedgerParam.EquipManufactor.Brand", null, data.brand]], "edit")
+      // this.handleUpdataTable([[this.row, "LedgerParam.EquipManufactor.Specification", null, data.name]], "edit")
     },
     //保险商变更
     changeInsurer(data) {
       tools.setDataForKey(this.tableData[this.row], "DPInsurerID", data.venderId)
       tools.setDataForKey(this.tableData[this.row], "LedgerParam.InsuranceDoc.Insurer", data.name)
-      this.handleUpdataTable([[this.row, "DPInsurerID", null, data.venderId]], "edit")
-      this.handleUpdataTable([[this.row, "LedgerParam.InsuranceDoc.Insurer", null, data.name]], "edit")
+      this.handleUpdataTable(
+        [
+          [this.row, "DPInsurerID", null, data.venderId],
+          [this.row, "LedgerParam.InsuranceDoc.Insurer", null, data.name]
+        ],
+        "edit"
+      )
+      // this.handleUpdataTable([[this.row, "LedgerParam.InsuranceDoc.Insurer", null, data.name]], "edit")
     },
     //维修商变更
     changeMaintainer(data) {
       tools.setDataForKey(this.tableData[this.row], "DPMaintainerID", data.venderId)
       tools.setDataForKey(this.tableData[this.row], "LedgerParam.OperationMainte.Maintainer", data.name)
-      this.handleUpdataTable([[this.row, "DPMaintainerID", null, data.venderId]], "edit")
-      this.handleUpdataTable([[this.row, "LedgerParam.OperationMainte.Maintainer", null, data.name]], "edit")
+      this.handleUpdataTable(
+        [
+          [this.row, "DPMaintainerID", null, data.venderId],
+          [this.row, "LedgerParam.OperationMainte.Maintainer", null, data.name]
+        ],
+        "edit"
+      )
+      // this.handleUpdataTable([[this.row, "LedgerParam.OperationMainte.Maintainer", null, data.name]], "edit")
     },
     //修改关联的资产
     changeProperty(val) {
@@ -916,11 +988,11 @@ export default {
       this.assetGroupList = assetGroupList
     },
   },
-  watch: {      
-    projectId(){
-        this.main = []
-        this.mess.deviceId = null
-        this.page.total = 0
+  watch: {
+    projectId() {
+      this.main = []
+      this.mess.deviceId = null
+      this.page.total = 0
     },
     showTypes: {
       handler(newName, oldName) {
@@ -948,16 +1020,16 @@ export default {
     font-size: 12px;
   }
 }
-.add-assets{
-  .el-dialog__body{
+.add-assets {
+  .el-dialog__body {
     height: 130px;
-    .die-text{
+    .die-text {
       margin-left: 10px;
       font-weight: bold;
       clear: both;
       padding-top: 25px;
       padding-bottom: 10px;
-      .die-num{
+      .die-num {
         width: 100px;
         text-align: center;
         display: inline-block;

+ 166 - 54
src/components/ledger/handsontables/device.vue

@@ -14,9 +14,9 @@
         <el-option v-for="item in showTypes" :key="item.value" :label="item.label" :value="item.value"></el-option>
       </el-select>
       <!-- <el-button size="small" style='width: 80px;' @click="download" icon="iconfont icon-xiazai">下载</el-button> -->
-      <el-button size="small" style='width: 80px;' @click="addDevice" icon="iconfont icon-tianjia">添加设备</el-button>
-      <el-button size="small" style='width: 80px;' @click="reset" icon="iconfont icon-shuaxin">刷新</el-button>
-      <el-button size="small" style='width: 80px;' v-show="!onlyRead" @click="undo" icon="iconfont icon-undo">撤销</el-button>
+      <el-button size="small" style='width: 80px;' @click="addDevice">添加设备</el-button>
+      <el-button size="small" style='width: 80px;' @click="reset">刷新</el-button>
+      <el-button size="small" style='width: 80px;' v-show="!onlyRead" @click="undo">撤销</el-button>
     </div>
     <!-- 二维码弹窗 -->
     <qrcode :dialog="myDialog" :qrcodeUrl="qrcodeUrl" :addBody="true" ref="qrcode"></qrcode>
@@ -54,12 +54,26 @@
     </div>
     <details-dialog :iframeSrc="iframeSrc" v-if="myDialog.details" :dialog="myDialog"></details-dialog>
     <!-- 关联的系统 -->
-    <system-type :device="mess" :curDevice="curDevice" :dialog="myDialog" :type="onlyRead?'read':'edit'" @change="changeSystemType" :list="systemList"></system-type>
+    <system-type :device="mess" :curDevice="curDevice" :dialog="myDialog" :type="onlyRead?'read':'edit'" @change="changeSystemType"
+      :list="systemList"></system-type>
     <!-- 关联资产 -->
     <change-rea @changeProperty="changeProperty" :dialog="myDialog" :category="deviceType"></change-rea>
     <look-pic :dialog="myDialog" :keysArr="picsArr"></look-pic>
+    <!-- 不支持的输入方式 -->
+    <el-dialog title="临时维护信息点" :visible.sync="myDialog.update" @close="handleCloseUpdate" width="670px">
+      <el-row>
+        该信息点未定义对应组件,现在维护数据不确定后续是否可用。如确实需要维护,请点击<el-link @click="updateInputShow = true" type="primary" :underline="false">继续维护</el-link>。
+      </el-row>
+      <el-row style="margin-top:20px;" v-show="updateInputShow">
+        <el-input type="textarea" :autosize="{ minRows: 4, maxRows: 8}" placeholder="请输入内容" v-model="updateInput"></el-input>
+      </el-row>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="myDialog.update = false">取 消</el-button>
+        <el-button type="primary" @click="handleClickUpdate">确 认</el-button>
+      </span>
+    </el-dialog>
     <!-- 新增设备 -->
-    <el-dialog title="确定新增设备的类型" :visible.sync="myDialog.addDevice" width="30%">
+    <el-dialog title="确定新增设备的类型" :visible.sync="myDialog.addDevice" width="670px">
       <el-row>
         <my-cascader ref="cascader" @change="changeAddType" :all="true"></my-cascader>
       </el-row>
@@ -84,32 +98,33 @@ import {
 } from "@/api/scan/request";
 
 
-import tools from "@/utils/scan/tools";
+import tools from "@/utils/scan/tools"
 import handsonUtils from "@/utils/hasontableUtils"
 import showTools from "@/utils/handsontable/notShow"
 import text from "@/utils/handsontable/mainText"
-import myCascader from "@/components/ledger/lib/cascader";
+import myCascader from "@/components/ledger/lib/cascader"
+import buildFloor from '@/utils/handsontable/buildFloorData'
 
-import qrcode from "@/components/ledger/lib/qrcode";
-import firm from "@/components/dialogs/list/firm";
-import supplyDialog from "@/components/dialogs/list/supplyDialog";
-import supplierDialog from "@/components/dialogs/list/supplierDialog";
-import maintainerDialog from "@/components/dialogs/list/maintainerDialog";
-import insurerDialog from "@/components/dialogs/list/insurerDialog";
-import guaranteeDialog from "@/components/dialogs/list/guaranteeDialog";
-import uploadFilesDialog from "@/components/dialogs/list/filesDialog";
-import uploadImgDialog from "@/components/dialogs/list/uploadImgDialog";
+import qrcode from "@/components/ledger/lib/qrcode"
+import firm from "@/components/dialogs/list/firm"
+import supplyDialog from "@/components/dialogs/list/supplyDialog"
+import supplierDialog from "@/components/dialogs/list/supplierDialog"
+import maintainerDialog from "@/components/dialogs/list/maintainerDialog"
+import insurerDialog from "@/components/dialogs/list/insurerDialog"
+import guaranteeDialog from "@/components/dialogs/list/guaranteeDialog"
+import uploadFilesDialog from "@/components/dialogs/list/filesDialog"
+import uploadImgDialog from "@/components/dialogs/list/uploadImgDialog"
 import picDialog from "@/components/dialogs/list/picDialog"
 import systemType from "@/components/dialogs/list/systemType"
-import myPagination from "@/components/ledger/lib/myPagination";
+import myPagination from "@/components/ledger/lib/myPagination"
 import detailsDialog from "@/components/ledger/lib/detailsDia"
 import changeRea from "@/components/dialogs/changeRea"
-import { mapGetters, mapActions } from "vuex";
+import { mapGetters, mapActions } from "vuex"
 //图片查看
 import lookPic from "@/components/ledger/lib/lookImages"
 import Handsontable from "handsontable-pro"
 import 'handsontable-pro/dist/handsontable.full.css'
-import zhCN from 'handsontable-pro/languages/zh-CN';
+import zhCN from 'handsontable-pro/languages/zh-CN'
 //下拉插件
 // import "@/assets/js/chosen.jquery.min";
 // import "@/assets/js/handsontable-chosen-editor";
@@ -134,12 +149,14 @@ export default {
     lookPic,
     myCascader
   },
-  created() { },
+  created() { 
+    buildFloor.getData(this.buildFloorData)
+  },
   computed: {
     ...mapGetters("layout", ["projectId", "secret", "userId"]),
     showTypes() {
       return this.onlyRead ?
-        [{ value: "all", label: '全部' }, { value: "Visible", label: '只看采集信息' }] :
+        [{ value: "Visible", label: '只看采集信息' }, { value: "all", label: '全部' }] :
         [{ value: "partInfo", label: '隐藏信息点' }, { value: "all", label: '全部' }, { value: "Visible", label: '只看采集信息' }]
     }
   },
@@ -152,6 +169,7 @@ export default {
         value: false,
         label: '编辑模式'
       }],
+      buildFloorData: [], //楼层数据
       tableData: [],
       mess: {},
       tableHeader: null,
@@ -177,18 +195,19 @@ export default {
         details: false,//详情页
         changeRea: false,//关联资产
         lookPic: false,//图片查看
+        update: false,//临时维护信息点
       },
       row: null, //被修改的row
       filesArr: [], //保存临时的文件key
       messKey: null,
       imgsArr: [], //临时保存的图片key数组
       picsArr: [], //临时设备图片keys数组
-      systemList:[], //关联的系统
+      systemList: [], //关联的系统
       copyMain: null,
       iframeSrc: "",
       id: 0,
       onlyRead: true,
-      showType: 'all',
+      showType: 'Visible',
       linkNameFalg: false,
       qrcodeUrl: "", //二维码图片地址
       loading: false,
@@ -196,6 +215,12 @@ export default {
       floorData: [],
       curDevice: '',//当前点击的设备id
       addData: {}, //添加设备选择的设备类型
+      inputMap: {
+        flowBuild: 'D1'
+      }, //信息点和输入方式映射表
+      updateInputShow: false, //是否显示临时维护输入框
+      updateInfoPoint: '',//临时维护信息点
+      updateInput: '', //临时维护信息点值
     };
   },
   methods: {
@@ -209,12 +234,17 @@ export default {
           data: {
             Orders: "sort asc",
             PageNumber: 1,
-            PageSize: 500
+            PageSize: 1000
           },
           type: this.mess.deviceId
         };
         getDataDictionary(params, res => {
           this.tableHeader = res.Content;
+          this.tableHeader.forEach(item => {
+            if(item.Path && item.InputMode){
+              this.inputMap[item.Path] = item.InputMode
+            }
+          })
           this.getTableData()
         });
       }
@@ -243,7 +273,14 @@ export default {
         }
         getEquipTableCon(param, res => {
           this.loading = false;
-          this.tableData = res.Content;
+          this.tableData = res.Content.map((item) => {
+            if (item.hasOwnProperty("BuildingId") && item.hasOwnProperty("FloorId")) {
+              item.flowBuild = item.BuildingId + "-" + item.FloorId
+            } else if (item.hasOwnProperty("BuildingId") && !item.hasOwnProperty("FloorId")) {
+              item.flowBuild = item.BuildingId
+            }
+            return item
+          });
           this.copyMain = tools.deepCopy(this.tableData);
           this.page.total = res.Total;
           if (this.tableData && this.tableData.length) {
@@ -384,6 +421,9 @@ export default {
       let arr = tools.copyArr(list)
       let data = showTools.headerTextFilter(arr, 'equipment', this.onlyRead, this.showType, true)
       data.unshift("操作", "当前关联的资产", "所属系统实例", "包含的部件");
+      if (this.showType == "all") {
+        data.splice(6, 0, "所属建筑楼层")
+      }
       return data;
     },
     //格式化表内容
@@ -410,9 +450,15 @@ export default {
           renderer: tools.lookDetails
         }
       );
-      if (this.onlyRead) {
-        data.map(item => {
-          item.readOnly = true
+      if (this.showType == "all") {
+        data.splice(6, 0, {
+          data: "flowBuild",
+          renderer: tools.customDropdownRenderer,
+          editor: "chosen",
+          chosenOptions: {
+            data: this.buildFloorData
+          },
+          readOnly: this.onlyRead
         })
       }
       return data;
@@ -507,7 +553,6 @@ export default {
           if (changeData.length == 1 && changeData[0][1].indexOf("/") > 0) {
             changeData[0][1] = changeData[0][1].split("/").join(".")
           }
-
           //存在data进行修改请求
           if (data && data.length) {
             this.updateBusiness(data, changeData);
@@ -555,6 +600,10 @@ export default {
       //生成要修改字段列表
       change.map(item => {
         let key = item[1].split(".")[0]
+        if (key == "flowBuild" && keyList.indexOf(key) == -1) {
+          keyList.push("BuildingId","FloorId")
+          param.Projection.push("BuildingId","FloorId")
+        }
         if (item[1] && keyList.indexOf(key) == -1 && item[1] != 'PropertyId') {
           keyList.push(key);
         }
@@ -565,8 +614,26 @@ export default {
       //生成对应修改数据
       data.map((item, index) => {
         keyList.map(value => {
-          let itemData = tools.dataForKey(item, value);
-          tools.setDataForKey(item, value, itemData == "" ? null : itemData);
+          if (value == "BuildingId") {
+            let itemData = tools.dataForKey(item, "flowBuild")
+            if (itemData == "") {
+              tools.setDataForKey(item, "BuildingId", null)
+              tools.setDataForKey(item, "FloorId", null)
+            } else {
+              let BuildingId = itemData.split("-")[0]
+              let FloorId = itemData.split("-")[1]
+              if (BuildingId && FloorId) {
+                tools.setDataForKey(item, "BuildingId", BuildingId)
+                tools.setDataForKey(item, "FloorId", FloorId)
+              } else if (BuildingId && !FloorId) {
+                tools.setDataForKey(item, "BuildingId", BuildingId)
+                tools.setDataForKey(item, "FloorId", null)
+              }
+            }
+          } else {
+            let itemData = tools.dataForKey(item, value)
+            tools.setDataForKey(item, value, itemData == "" ? null : itemData)
+          }
         });
         param.Content.push(item);
       });
@@ -593,6 +660,7 @@ export default {
     //获取到了正确的信息
     getInfors(infos, row, el) {
       let val = this.hot.colToProp(row.col);
+      let inputMode = this.inputMap[val];
       this.row = row.row;
       this.messKey = val;
       switch (val) {
@@ -600,7 +668,7 @@ export default {
         case 'caozuo':
           // window.open(`http://adm.sagacloud.cn:8058/spread?id=${infos.EquipID}&pid=${this.projectId}&secret=${this.secret}`,"_blank")
           this.$message("开发中...")
-          break;
+          return false
         //设备二维码图片
         case 'EquipQRCode':
           this.qrcodeUrl = this.tableData[row.row].EquipQRCode;
@@ -609,7 +677,7 @@ export default {
           } else {
             this.$message("此设备没有设备二维码");
           }
-          break;
+          return false
         //关联系统
         case 'LinkSystem':
           if (!this.onlyRead) {
@@ -617,37 +685,37 @@ export default {
             this.systemList = this.tableData[row.row].LinkSystem || [];
             this.myDialog.systemType = true;
           }
-          break;
+          return false
         //关联资产
         case 'LinkEquipLocalName':
           if (this.linkNameFalg) {
             this.myDialog.changeRea = true;
           }
-          break;
+          return false
         //品牌型号弹窗
         case 'DPManufacturerID':
           if (!this.onlyRead) {
             this.myDialog.firm = true;
           }
-          break;
+          return false
         //供应商信息弹窗
         case 'DPSupplierID':
           if (!this.onlyRead) {
             this.myDialog.supplier = true;
           }
-          break;
+          return false
         //维修商信息弹窗
         case 'DPMaintainerID':
           if (!this.onlyRead) {
             this.myDialog.maintainer = true;
           }
-          break;
+          return false
         //保险公司信息
         case 'DPInsurerID':
           if (!this.onlyRead) {
             this.myDialog.insurer = true;
           }
-          break;
+          return false
         //供应合同编号
         case 'LedgerParam.SupplyPurchase.SupplierContractID':
           if (!this.onlyRead) {
@@ -663,7 +731,7 @@ export default {
               this.$message("请先选择供应商");
             }
           }
-          break;
+          return false
         //保险单号
         case 'LedgerParam.InsuranceDoc.InsuranceNum':
           if (!this.onlyRead) {
@@ -679,7 +747,7 @@ export default {
               this.$message("请先选择保险商");
             }
           }
-          break;
+          return false
         //保险文件--设备文档--安装质检报告
         case 'LedgerParam.InsuranceDoc.InsuranceFile':
         case 'LedgerParam.PhotoDoc.Archive':
@@ -687,7 +755,7 @@ export default {
           let IPSdata = tools.dataForKey(this.tableData[row.row], val);
           this.filesArr = IPSdata ? IPSdata : [];
           this.myDialog.uploadFiles = true;
-          break;
+          return false
         //安装照片--安装图纸--设备铭牌照片--设备图纸
         case 'LedgerParam.Siteinstall.InstallPic':
         case 'LedgerParam.Siteinstall.InstallDrawing':
@@ -696,13 +764,13 @@ export default {
           let SSPPdata = tools.dataForKey(this.tableData[row.row], val);
           this.imgsArr = SSPPdata ? SSPPdata : [];
           this.myDialog.uploadImgs = true;
-          break;
+          return false
         //设备照片
         case 'LedgerParam.PhotoDoc.Pic':
           let Pdata = tools.dataForKey(this.tableData[row.row], val);
           this.picsArr = Pdata ? Pdata : [];
           this.myDialog.pic = true;
-          break;
+          return false
         //包含的部件字段
         case 'Count':
           if (this.onlyRead) {
@@ -710,10 +778,29 @@ export default {
           } else {
             this.$router.push({ path: '/ledger/partsmanage', query: { deviceId: infos.EquipID, typeId: this.mess.deviceId } });
           }
-          break;
+          return false
         default:
           break;
       }
+      if (!this.onlyRead && showTools.InputModeArr.indexOf(inputMode) == '-1') {
+        this.updateInfoPoint = val
+        this.updateInput = tools.dataForKey(this.tableData[row.row], val)
+        this.myDialog.update = true
+      }
+    },
+    //关闭临时维护弹窗回调
+    handleCloseUpdate() {
+      this.updateInputShow = false
+      this.updateInfoPoint = ''
+      this.updateInput = ''
+    },
+    //更新临时维护信息点
+    handleClickUpdate(){
+      tools.setDataForKey(this.tableData[this.row], this.updateInfoPoint, this.updateInput)
+      this.handleUpdataTable([[this.row, this.updateInfoPoint, null, this.updateInput]], "edit")
+      this.updateInputShow = false
+      this.myDialog.update = false
+      this.updateInput = ''
     },
     //获取被筛选掉的行号
     trimmedRows() {
@@ -746,8 +833,14 @@ export default {
     supplierChange(data) {
       tools.setDataForKey(this.tableData[this.row], "DPSupplierID", data.venderId)
       tools.setDataForKey(this.tableData[this.row], "LedgerParam.SupplyPurchase.Supplier", data.name)
-      this.handleUpdataTable([[this.row, "DPSupplierID", null, data.venderId]], "edit")
-      this.handleUpdataTable([[this.row, "LedgerParam.SupplyPurchase.Supplier", null, data.name]], "edit")
+      this.handleUpdataTable(
+        [
+          [this.row, "DPSupplierID", null, data.venderId],
+          [this.row, "LedgerParam.SupplyPurchase.Supplier", null, data.name]
+        ],
+        "edit"
+      )
+      // this.handleUpdataTable([[this.row, "LedgerParam.SupplyPurchase.Supplier", null, data.name]], "edit")
     },
     //供应合同编号
     supplyChange(data) {
@@ -770,23 +863,42 @@ export default {
       tools.setDataForKey(this.tableData[this.row], "DPManufacturerID", data.venderId)
       tools.setDataForKey(this.tableData[this.row], "LedgerParam.EquipManufactor.Brand", data.brand)
       tools.setDataForKey(this.tableData[this.row], "LedgerParam.EquipManufactor.Specification", data.name)
-      this.handleUpdataTable([[this.row, "DPManufacturerID", null, data.venderId]], "edit")
-      this.handleUpdataTable([[this.row, "LedgerParam.EquipManufactor.Brand", null, data.brand]], "edit")
-      this.handleUpdataTable([[this.row, "LedgerParam.EquipManufactor.Specification", null, data.name]], "edit")
+      this.handleUpdataTable(
+        [
+          [this.row, "DPManufacturerID", null, data.venderId],
+          [this.row, "LedgerParam.EquipManufactor.Brand", null, data.brand],
+          [this.row, "LedgerParam.EquipManufactor.Specification", null, data.name]
+        ],
+        "edit"
+      )
+      // this.handleUpdataTable([[this.row, "LedgerParam.EquipManufactor.Brand", null, data.brand]], "edit")
+      // this.handleUpdataTable([[this.row, "LedgerParam.EquipManufactor.Specification", null, data.name]], "edit")
     },
     //保险商变更
     changeInsurer(data) {
       tools.setDataForKey(this.tableData[this.row], "DPInsurerID", data.venderId)
       tools.setDataForKey(this.tableData[this.row], "LedgerParam.InsuranceDoc.Insurer", data.name)
-      this.handleUpdataTable([[this.row, "DPInsurerID", null, data.venderId]], "edit")
-      this.handleUpdataTable([[this.row, "LedgerParam.InsuranceDoc.Insurer", null, data.name]], "edit")
+      this.handleUpdataTable(
+        [
+          [this.row, "DPInsurerID", null, data.venderId],
+          [this.row, "LedgerParam.InsuranceDoc.Insurer", null, data.name]
+        ],
+        "edit"
+      )
+      // this.handleUpdataTable([[this.row, "LedgerParam.InsuranceDoc.Insurer", null, data.name]], "edit")
     },
     //维修商变更
     changeMaintainer(data) {
       tools.setDataForKey(this.tableData[this.row], "DPMaintainerID", data.venderId)
       tools.setDataForKey(this.tableData[this.row], "LedgerParam.OperationMainte.Maintainer", data.name)
-      this.handleUpdataTable([[this.row, "DPMaintainerID", null, data.venderId]], "edit")
-      this.handleUpdataTable([[this.row, "LedgerParam.OperationMainte.Maintainer", null, data.name]], "edit")
+      this.handleUpdataTable(
+        [
+          [this.row, "DPMaintainerID", null, data.venderId],
+          [this.row, "LedgerParam.OperationMainte.Maintainer", null, data.name]
+        ],
+        "edit"
+      )
+      // this.handleUpdataTable([[this.row, "LedgerParam.OperationMainte.Maintainer", null, data.name]], "edit")
     },
     //修改关联的资产
     changeProperty(val) {

+ 49 - 4
src/components/ledger/handsontables/system.vue

@@ -31,6 +31,19 @@
     <!-- <dialog-assets :assetType="[this.mess.deviceId]" @close="getClose" v-if="myDialog.addDevice" ref="assets" :dialog="myDialog"></dialog-assets> -->
     <details-dialog :iframeSrc="iframeSrc" v-if="myDialog.details" :dialog="myDialog"></details-dialog>
     <system-relevance @close="reset" :id="systemId" :dialog="myDialog"></system-relevance>
+    <!-- 不支持的输入方式 -->
+    <el-dialog title="临时维护信息点" :visible.sync="myDialog.update" @close="handleCloseUpdate" width="670px">
+      <el-row>
+        该信息点未定义对应组件,现在维护数据不确定后续是否可用。如确实需要维护,请点击<el-link @click="updateInputShow = true" type="primary" :underline="false">继续维护</el-link>。
+      </el-row>
+      <el-row style="margin-top:20px;" v-show="updateInputShow">
+        <el-input type="textarea" :autosize="{ minRows: 4, maxRows: 8}" placeholder="请输入内容" v-model="updateInput"></el-input>
+      </el-row>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="myDialog.update = false">取 消</el-button>
+        <el-button type="primary" @click="handleClickUpdate">确 认</el-button>
+      </span>
+    </el-dialog>
     <!-- 新增系统 -->
     <el-dialog title="确定新增系统的类型" :visible.sync="myDialog.addDevice" width="30%">
       <el-row>
@@ -126,6 +139,7 @@ export default {
         addDevice: false,
         details: false,//详情页
         relevance: false,//关联设备
+        update: false,//临时维护信息点
       },
       row: null,//被修改的row
       filesArr: [],//保存临时的文件key
@@ -137,11 +151,17 @@ export default {
       iframeSrc: "",
       systemId: "",
       onlyRead: true,
-      showType: 'all',
+      showType: 'Visible',
       linkNameFalg: false,
       qrcodeUrl: "",//二维码图片地址
       loading: false,
       addData: {}, //添加设备选择的设备类型
+      inputMap: {
+        flowBuild: 'D1'
+      }, //信息点和输入方式映射表
+      updateInputShow: false, //是否显示临时维护输入框
+      updateInfoPoint: '',//临时维护信息点
+      updateInput: '', //临时维护信息点值
     };
   },
   created() {
@@ -166,6 +186,11 @@ export default {
         }
         getDataDictionary(params, res => {
           this.tableHeader = res.Content;
+          this.tableHeader.forEach(item => {
+            if(item.Path && item.InputMode){
+              this.inputMap[item.Path] = item.InputMode
+            }
+          })
           this.getTableData()
         });
       }
@@ -486,6 +511,7 @@ export default {
     getInfors(infos, row) {
       //其他的开始判断
       let val = this.hot.colToProp(row.col);
+      let inputMode = this.inputMap[val];
       this.systemId = infos.SysID
       this.row = row.row
       this.messKey = val
@@ -494,7 +520,7 @@ export default {
         case 'caozuo':
           // window.open(`http://adm.sagacloud.cn:8058/system?id=${infos.id}&pid=${this.projectId}&secret=${this.secret}`,"_blank")
           this.$message("开发中...")
-          break;
+          return false
         //设备二维码图片
         case 'EquipQRCode':
           this.qrcodeUrl = this.tableData[row.row].EquipQRCode;
@@ -503,16 +529,35 @@ export default {
           } else {
             this.$message("此设备没有设备二维码");
           }
-          break;
+          return false
         //关联设备数量
         case 'Count':
           if (!this.onlyRead) {
             this.myDialog.relevance = true
           }
-          break;
+          return false
         default:
           break;
       }
+      if (!this.onlyRead && showTools.InputModeArr.indexOf(inputMode) == '-1') {
+        this.updateInfoPoint = val
+        this.updateInput = tools.dataForKey(this.tableData[row.row], val)
+        this.myDialog.update = true
+      }
+    },
+    //关闭临时维护弹窗回调
+    handleCloseUpdate() {
+      this.updateInputShow = false
+      this.updateInfoPoint = ''
+      this.updateInput = ''
+    },
+    //更新临时维护信息点
+    handleClickUpdate(){
+      tools.setDataForKey(this.tableData[this.row], this.updateInfoPoint, this.updateInput)
+      this.handleUpdataTable([[this.row, this.updateInfoPoint, null, this.updateInput]], "edit")
+      this.updateInputShow = false
+      this.myDialog.update = false
+      this.updateInput = ''
     },
     //获取被筛选掉的行号
     trimmedRows() {

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

@@ -102,7 +102,7 @@
                         label: "全部"
                     }, {
                         value: "noKnow",
-                        label: "未明确建筑的设备"
+                        label: "未明确建筑"
                     })
                     data.forEach(build => {
                         floorData.forEach(floor => {
@@ -120,7 +120,7 @@
                                         label: "全部"
                                     },{
                                         value: 'noKnow',
-                                        label: "未明确楼层的设备"
+                                        label: "未明确楼层"
                                     },{
                                         value: floor.FloorID,
                                         label: floor.FloorLocalName,

+ 319 - 0
src/components/ledger/lib/linkassets.vue

@@ -0,0 +1,319 @@
+<template>
+  <el-dialog title="批量关联资产" :visible.sync="dialog.linkAssets" @open="handleOpenReset" width="700px">
+    <el-row>
+      <span class="condition-title">设备类型:</span>
+      <el-select v-model="deviceType" filterable size="small" @change="handleChangeDevice" style="width:350px;">
+        <el-option  v-for="item in deviceTypeList" :key="item.Category" :label="item.CategoryName" :value="item.Category"></el-option>
+      </el-select>
+    </el-row>
+    <el-row style="margin-top:30px;">
+      <span class="condition-title">建筑楼层:</span>
+      <el-cascader :options="bfoptions" v-model="buildFloor" filterable size="small" @change="handleChangeBf" style="width:350px;"></el-cascader>
+    </el-row>
+    <el-row style="margin-top:30px;"  v-show="spaceShow">
+      <span class="condition-title">分区类型:</span>
+      <el-select v-model="zone" filterable size="small" @change="handleChangeZone" style="width:350px;">
+        <el-option  v-for="item in zoneList" :key="item.Code" :label="item.Name" :value="item.Code"></el-option>
+      </el-select>
+    </el-row>
+    <el-row style="margin-top:30px;" v-show="spaceShow && zone != 'all' && zone != 'noKnow'">
+      <span class="condition-title">空间实例:</span>
+      <el-select v-model="space" multiple filterable collapse-tags style="width:350px;" placeholder="请选择">
+        <el-option v-for="item in spaceList" :key="item.value" :label="item.label" :value="item.value">
+        </el-option>
+      </el-select>
+    </el-row>
+    <span slot="footer" class="dialog-footer">
+      <el-button @click="handleClickClose">取 消</el-button>
+      <el-button type="primary" @click="toLinkAssets">确 认</el-button>
+    </span>
+  </el-dialog>
+</template>
+<script>
+
+import { floorQuery, buildingQuery, queryDictionaryHead, queryZone, TypePartsDie } from '@/api/scan/request'
+
+import { mapGetters } from "vuex"
+export default {
+  props: {
+    dialog: {
+      type: Object,
+      default: function () {
+        return {
+          linkAssets: false
+        };
+      }
+    }
+  },
+  computed: {
+    ...mapGetters("layout", ["projectId", "secret", "userId"])
+  },
+  data() {
+    return {
+      bfoptions: [], //建筑楼层列表
+      buildFloor: ['all'], //选择的建筑楼层
+      deviceTypeList: [], //未关联资产的设备或部件列表
+      deviceType: '', //选择的设备类型
+      zone: 'all', //空间分区
+      zoneList: [], //空间分区列表
+      spaceList: [], //空间实例列表
+      space: [], //选择的空间实例
+      spaceShow: false
+    };
+  },
+  created() {
+    this.getPartsDieType() //获取未关联资产的设备或部件类型
+    this.getBuildFloorData() //获取建筑楼层数据
+    this.getSpaceData() //获取分区类型数据
+  },
+  mounted() { },
+  methods: {
+    //打开弹窗回调,初始化选择
+    handleOpenReset(){
+      this.deviceType = ''
+      this.buildFloor = ['all']
+      this.zone = 'all'
+      this.space = []
+      this.spaceShow = false
+    },
+    //获取未关联资产的设备或部件类型
+    getPartsDieType() {
+      TypePartsDie(res => {
+        this.deviceTypeList = res.Content.filter(item => {
+          return item.CategoryName
+        })
+      })
+    },
+    //获取建筑楼层数据
+    getBuildFloorData() {
+      let data, buildParams = {
+        PageNumber: 1,
+        PageSize: 1000,
+        Projection: [
+          "BuildID",
+          "BuildLocalName"
+        ]
+      }, floorParams = {
+        Orders: "FloorSequenceID desc",
+        PageNumber: 1,
+        PageSize: 1000,
+        Projection: [
+          "BuildID",
+          "FloorID",
+          "FloorLocalName",
+          "FloorSequenceID"
+        ]
+      }
+      let promise1 = new Promise((resolve, reject) => {
+        buildingQuery(buildParams, res => {
+          resolve(res)
+        })
+      })
+      let promise2 = new Promise((resolve, reject) => {
+        floorQuery(floorParams, res => {
+          resolve(res)
+        })
+      })
+      Promise.all([promise1, promise2]).then(values => {
+        let builData = values[0].Content, floorData = values[1].Content
+        data = builData.map(build => {
+          return {
+            value: build.BuildID,
+            label: build.BuildLocalName
+          }
+        })
+        data.unshift({
+          value: "all",
+          label: "全部"
+        }, {
+            value: "noKnow",
+            label: "不在建筑内"
+          })
+        data.forEach(build => {
+          floorData.forEach(floor => {
+            if (build.value == floor.BuildID && floor.FloorID && floor.FloorLocalName) {
+              if (build.children) {
+                build.children.push({
+                  value: floor.FloorID,
+                  label: floor.FloorLocalName,
+                  FloorSequenceID: floor.FloorSequenceID
+                })
+              } else {
+                build.children = []
+                build.children.push({
+                  value: "all",
+                  label: "全部"
+                }, {
+                    value: 'noKnow',
+                    label: "不在楼层内"
+                  }, {
+                    value: floor.FloorID,
+                    label: floor.FloorLocalName,
+                    FloorSequenceID: floor.FloorSequenceID
+                  })
+              }
+            }
+          })
+        })
+        this.bfoptions = data
+      })
+    },
+    //获取空间分区数据
+    getSpaceData(){
+      let params = {
+        Filters: "parentId = 'Space'",
+        PageNumber: 1,
+        PageSize: 1000,
+        Projection: [ "Code", "Name" ]
+      }
+      queryDictionaryHead(params, res => {
+        this.zoneList = res.Content.filter(item => {
+          if(item.Code != 'Ispace'){
+            return item
+          }
+        })
+        this.zoneList.unshift({
+          Name: '全部',
+          Code: 'all'
+        })
+        this.zoneList.push({
+          Name: '不在任何业务空间内',
+          Code: 'noKnow'
+        })
+      })
+    },
+    // 修改设备类型
+    handleChangeDevice(val) {
+      this.zoneListIsShow()
+    },
+    // 修改建筑楼层
+    handleChangeBf(val) {
+      this.zoneListIsShow()
+      // 重置空间实例选择
+      this.space = []
+      this.spaceList = []
+      this.handleChangeSpaceItem()
+    },
+    //判断是否显示空间分区选择
+    zoneListIsShow(){
+      let lastVal = this.buildFloor.slice(-1)[0]
+      if(!lastVal || lastVal == 'noKnow' || this.buildFloor[0] == 'all' || this.deviceType.length != 4) {
+        this.spaceShow = false
+      } else {
+        this.spaceShow = true
+      }
+    },
+    //修改分区类型
+    handleChangeZone() {
+      // 重置空间实例选择
+      this.space = []
+      this.spaceList = []
+      this.handleChangeSpaceItem()
+    },
+    // 获取空间实例
+    handleChangeSpaceItem() {
+      if(this.zone != 'all' && this.zone != 'noKnow') {
+        let nodes = []
+        let recursionGetData = (pageNum, zone) => {
+          pageNum = pageNum ? pageNum : 1
+          let params = {
+            zone: zone,
+            data: {
+              Orders: "CreateTime desc, RoomID asc",
+              PageNumber: pageNum,
+              PageSize: 1000,
+              Projection: ["RoomID", "RoomName", "RoomLocalName", "CreateTime"]
+            },
+          }
+          if(this.spaceShow) {
+            if(this.buildFloor.length == 2 && this.buildFloor[1] != 'all') {
+              params.data.Filters = `buildingId='${this.buildFloor[0]}';floorId='${this.buildFloor[1]}'`
+            } else {
+              params.data.Filters = `buildingId='${this.buildFloor[0]}'`
+            }
+          }
+          queryZone(params, res => {
+            nodes = nodes.concat(res.Content.map(item => ({
+              value: item.RoomID,
+              label: item.RoomLocalName?item.RoomLocalName:item.RoomName
+            })))
+            if (res.Total / (res.PageSize * res.PageNumber) > 1) {
+              recursionGetData(res.PageNumber + 1, zone)
+            } else {
+              this.spaceList = nodes
+            }
+          })
+        }
+        recursionGetData(1, this.zone)
+      }
+    },
+    // 点击取消关闭弹窗
+    handleClickClose() {
+      this.dialog.linkAssets = false
+    },
+    // 批量关联资产详情页
+    toLinkAssets() {
+      let query = {}
+      // 校验必填项
+      if(!this.deviceType) {
+        this.$message.info('请选择设备类型!')
+        return false
+      } else if (!this.buildFloor.length) {
+        this.$message.info('请选择建筑楼层!')
+        return false
+      }
+      if(this.spaceShow) { //选择了空间
+        if(this.zone == 'all'){//全部空间
+          query = {
+            deviceType: this.deviceType,
+            buildFloor: this.buildFloor
+          }
+        } else {
+          if(this.space.length){//选择了具体的空间实例
+            query = {
+              deviceType: this.deviceType,
+              buildFloor: this.buildFloor,
+              spaceList: this.space
+            }
+          } else {
+            query = {
+              deviceType: this.deviceType,
+              buildFloor: this.buildFloor,
+              spaceList: this.zone //(包含具体的业务空间分区和不在任何分区两种情况)
+            }
+          }
+        }
+      } else {
+        query = {
+          deviceType: this.deviceType,
+          buildFloor: this.buildFloor
+        }
+      }
+      this.$router.push({
+        name: "batchlinkAssets",
+        params: query
+      })
+    }
+  },
+  watch: {
+    
+  }
+};
+</script>
+
+<style lang="less" scoped>
+  .condition-title{
+    width: 100px;
+    display: inline-block;
+    text-align: right;
+    margin-left: 10px;
+    margin-right: 12px;
+    color: #999999;
+    font-size: 14px;
+    vertical-align: top;
+  }
+  /deep/ .el-dialog__body {
+    max-height: 420px;
+    overflow-y: auto;
+  }
+</style>

+ 19 - 16
src/components/ledger/tableTransfers.vue

@@ -30,7 +30,7 @@
               <template slot-scope="scope">{{ scope.row.InstallLocation || "--" }}</template>
             </el-table-column>
           </el-table>
-          <div class="right">
+          <div class="right" style="overflow:hidden;">
             <my-pagination @change="changePages1" :page="pages1"></my-pagination>
           </div>
         </div>
@@ -75,7 +75,8 @@ import {
   getEquipNotInSys,
   getEquipInSys,
   getEquipBelongs,
-  sysLinkEquip
+  sysLinkEquip,
+  sysUnlinkEquip
 } from "@/api/scan/request"
 import {
   mapGetters,
@@ -187,10 +188,12 @@ export default {
       this.getRightData()
     },
     //pages1改变
-    changePages1() {
+    changePages1(page) {
+      this.pages1.PageNumber = page
       this.getLeftData()
     },
-    changePages2() {
+    changePages2(page) {
+      this.pages2.PageNumber = page
       this.getRightData()
     },
     //修改设备类型
@@ -211,7 +214,7 @@ export default {
         sysId: this.id
       }
       if (this.search1 != '') {
-        param.data.Filters = `EquipLocalName contain "${this.search1}";`
+        param.data.Filters = `EquipLocalName contain '${this.search1}' || EquipName contain '${this.search1}';`
       }
       //建筑id
       if (this.buildingId == "noKnow") {
@@ -246,11 +249,11 @@ export default {
       let param = {
         Filters: `sysId='${this.id}'`,
         Orders: "EquipID desc",
-        PageNumber: this.pages1.currentPage,
-        PageSize: this.pages1.size
+        PageNumber: this.pages2.currentPage,
+        PageSize: this.pages2.size
       }
       if (this.search2 != '') {
-        param.Filters += `;EquipLocalName contain "${this.search2}"`
+        param.Filters += `;EquipLocalName contain '${this.search2}' || EquipName contain '${this.search2}'`
       }
       getEquipInSys(param, res => {
         this.table2Data = res.Content
@@ -268,7 +271,7 @@ export default {
     },
     //关联
     leftToRight() {
-      let relationList = this.multipleSelection.concat(this.table2Data)
+      let relationList = this.multipleSelection
       relationList = relationList.map(t => {
         return t.EquipID || t.EquipId
       })
@@ -276,16 +279,16 @@ export default {
     },
     //取消关联
     rightToLeft() {
-      let relationList = [];
       let tempIDs = this.SelectionList.map(t => {
-        return t.EquipId
-      })
-      this.table2Data.map(t => {
-        if (tempIDs.indexOf(t.EquipId) < 0) {
-          relationList.push(t.EquipId)
+        return {
+          EquipID: t.EquipId,
+          SysID: t.SysID
         }
       })
-      this.relationChange(relationList)
+      sysUnlinkEquip(tempIDs, res => {
+        this.$message.success('修改关联关系成功')
+        this.getAllTable()
+      })
     },
     //更新设备 系统关系
     relationChange(arr) {

+ 237 - 0
src/components/model/file/addFloorDialog.vue

@@ -0,0 +1,237 @@
+<template>
+  <!-- 新增楼层文件 -->
+  <div id="addFloorDialog">
+    <el-dialog
+      title="新增楼层"
+      :visible.sync="addFloorFileVisible"
+      width="900px"
+      :before-close="handleClose"
+    >
+      <el-form ref="addfloorform" :model="form" label-width="120px">
+        <el-form-item label="模型文件:">
+          <el-upload
+            class="upload-demo"
+            ref="upload"
+            :headers="headers"
+            :data="updataData"
+            action="/modelapi/model-file/upload"
+            :on-preview="handlePreview"
+            :on-remove="handleRemove"
+            :file-list="fileList"
+            :auto-upload="false"
+            :on-change="onChangeUpLoad"
+            :limit="1"
+          >
+            <el-button slot="trigger" size="small" type="primary">选取文件</el-button>
+          </el-upload>
+        </el-form-item>
+        <el-form-item label="模型所属楼层:">
+          <div class="floorModle">
+            <el-select v-model="form.floorTypeVal" placeholder="请选择">
+              <el-option
+                v-for="item in floorType"
+                :key="item.value"
+                :label="item.label"
+                :value="item.value"
+              ></el-option>
+            </el-select>
+            <!-- 计数 -->
+            <el-input-number
+              style="margin-left:10px;"
+              v-model="form.floorNum"
+              :min="1"
+              :disabled="form.floorTypeVal == 'RF'"
+              @change="handleChange"
+            ></el-input-number>
+            <!-- 是否夹层 -->
+            <el-checkbox style="margin:0 10px;" v-model="form.haveInterlayer">是否夹层</el-checkbox>
+            <!-- 夹层选择 -->
+            <el-select
+              v-model="form.interlayerTypeVal"
+              :disabled="!form.haveInterlayer"
+              placeholder="请选择"
+            >
+              <el-option
+                v-for="item in interlayerType"
+                :key="item.value"
+                :label="item.label"
+                :value="item.value"
+              ></el-option>
+            </el-select>
+          </div>
+        </el-form-item>
+        <el-form-item label="备注信息:">
+          <el-input type="textarea" v-model="form.desc"></el-input>
+        </el-form-item>
+        <el-form-item>
+          <el-button type="primary" @click="onSubmit">确认</el-button>
+          <el-button @click="handleClose">取消</el-button>
+        </el-form-item>
+      </el-form>
+    </el-dialog>
+  </div>
+</template>
+<script>
+import request from "@/api/model/file.js";
+import { mapGetters } from "vuex";
+export default {
+  props: {
+    addFloorFileVisible: Boolean,
+    FolderName: String,
+    floorList: Array,
+    FolderId: String
+  },
+  computed: {
+    ...mapGetters("layout", ["projectId", "userInfo","userId", "secret"])
+  },
+  data() {
+    return {
+      form: {
+        desc: "", //描述
+        floorTypeVal: "F", //楼层类型得值
+        interlayerTypeVal: "M1", //夹层类型得值
+        haveInterlayer: false, //是否有夹层
+        file: null, //上传文件
+        floorNum: 1 //楼层
+      },
+      fileList: [], //上传楼层列表
+      floorType: [
+        {
+          value: "F",
+          label: "正常层(F)"
+        },
+        {
+          value: "RF",
+          label: "屋顶(RF)"
+        },
+        {
+          value: "B",
+          label: "地下(B)"
+        }
+      ],
+      interlayerType: [
+        {
+          value: "M1",
+          label: "夹层M1"
+        },
+        {
+          value: "M2",
+          label: "夹层M2"
+        },
+        {
+          value: "M3",
+          label: "夹层M3"
+        }
+      ],
+      //请求头
+      headers: {
+        ProjectId: ""
+      },
+      updataData: {
+        model: {}
+      }
+    };
+  },
+  methods: {
+    onSubmit() {
+      let FloorName = null;
+      if (this.form.file == null) {
+        this.$message.error("模型文件不能为空!");
+      } else {
+        let FloorName = null;
+        // 根据是否有夹层拼接楼层名
+        if (this.form.haveInterlayer) {
+          if (this.form.floorTypeVal == "RF") {
+            FloorName = this.form.floorTypeVal + this.form.interlayerTypeVal;
+          } else {
+            FloorName =
+              this.form.floorTypeVal + this.form.floorNum + this.form.interlayerTypeVal;
+          }
+        } else {
+          if (this.form.floorTypeVal == "RF") {
+            FloorName = this.form.floorTypeVal;
+          } else {
+            FloorName = this.form.floorTypeVal + this.form.floorNum;
+          }
+        }
+        if(this.floorList.some((item) => {return item.FloorName == FloorName})) {
+          this.$message.error('该楼层名称已存在,请勿重复创建!');
+        } else {
+          let data = {
+            ProjectId: this.projectId,
+            FolderId: this.FolderId,
+            FloorName: FloorName,
+            Form: this.form,
+            userName: this.userInfo.userName,
+            userId: this.userInfo.userId
+          };
+          request.createFloor(data).then(res => {
+            if (res.Result == "success") {
+              //  创建成功
+              this.$emit("finishCreateFloor", {
+                FloorModelId: res.FloorModelId,
+                CurrentModelId:res.CurrentModelId,
+                Form: this.form
+              });
+              this.handleClose();
+              // this.submitUpload(res.FloorModelId);
+            }
+          });
+        }
+      }
+    },
+    // /上传到服务器/
+    submitUpload(FloorModelId) {
+      this.$refs.upload.submit();
+    },
+    handleClose() {
+      this.$emit("closeAddFloorDia");
+    },
+    // 删除上传文件
+    handleRemove(file, fileList) {
+      this.fileList = []
+      this.form.file = null;
+    },
+    handlePreview(file, fileList) {
+      console.log(file, fileList);
+    },
+    handleChange(file, fileList) {
+      console.log(file, fileList);
+    },
+    // 获取上传文件
+    onChangeUpLoad(file, fileList) {
+      console.log(file, fileList);
+      if (fileList.length) {
+        this.form.file = file;
+      }
+    }
+  },
+  watch: {
+    addFloorFileVisible(val) {
+      if (val) {
+        this.handleRemove();
+        this.form = {
+          desc: "", //描述
+          floorTypeVal: "F", //楼层类型得值
+          interlayerTypeVal: "M1", //夹层类型得值
+          haveInterlayer: false, //是否有夹层
+          file: null, //上传文件
+          floorNum: 1 //楼层
+        };
+      }
+    }
+  },
+  mounted() {
+    this.fileList = [];
+    this.form.file = null;
+  }
+};
+</script>
+<style lang="less">
+#addFloorDialog {
+  .floorModle {
+    display: flex;
+    justify-content: left;
+  }
+}
+</style>

+ 83 - 0
src/components/model/file/addFolder.vue

@@ -0,0 +1,83 @@
+<template>
+  <div id="addFolder">
+    <el-dialog title="提示" :visible.sync="addFolderVisible" width="30%" :before-close="closeDiaLog">
+      <div>
+        <el-form
+          :model="ruleForm"
+          :rules="rules"
+          ref="addFolderModel"
+          label-width="100px"
+          class="demo-ruleForm"
+        >
+          <el-form-item label="文件夹名称" prop="name">
+            <el-input v-model="ruleForm.name" focus></el-input>
+          </el-form-item>
+        </el-form>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="closeDiaLog">取 消</el-button>
+        <el-button type="primary" @click="addFolder">确 定</el-button>
+      </span>
+    </el-dialog>
+  </div>
+</template>
+<script>
+import request from "@/api/model/file.js";
+import { mapGetters } from "vuex";
+export default {
+  computed: {
+    ...mapGetters("layout", ["projectId", "userId", "secret"])
+  },
+  props: {
+    addFolderVisible: Boolean,
+    folderName: String
+  },
+  data() {
+    return {
+      ruleForm: {
+        name: ""
+      },
+      rules: {
+        name: [
+          { required: true, message: "文件夹名称不能为空!", trigger: "blur" }
+        ]
+      }
+    };
+  },
+  methods: {
+    closeDiaLog() {
+      this.resetForm();
+      this.$emit("closeAddFolderVisible");
+    },
+    addFolder() {
+      this.$refs["addFolderModel"].validate(valid => {
+        if (valid) {
+          request.createModel({ ProjectId: this.projectId, Name:this.ruleForm.name },res => {
+              this.$message({
+                message: "模型文件夹创建成功",
+                type: "success"
+
+              });
+              // 重新获取文件夹列表
+              this.$emit('getfolderModel')
+              this.closeDiaLog();
+            })
+        } else {
+          return false;
+        }
+      });
+    },
+    resetForm() {
+      this.$refs["addFolderModel"].resetFields();
+    },
+    createModel(Name) {
+      return request.createModel({ ProjectId: this.projectId, Name });
+    }
+  },
+  watch: {
+    folderName: function(val, oldVal) {
+      this.ruleForm.name = val;
+    }
+  }
+};
+</script>

+ 97 - 0
src/components/model/file/changeFolderName.vue

@@ -0,0 +1,97 @@
+<template>
+  <div id="changeFolderName">
+    <el-dialog
+      title="提示"
+      :visible.sync="changeFolderNameVisible"
+      width="30%"
+      :before-close="closeDiaLog"
+    >
+      <div>
+        <el-form
+          :model="ruleForm"
+          :rules="rules"
+          ref="changeFolderModelName"
+          label-width="100px"
+          class="demo-ruleForm"
+        >
+          <el-form-item label="文件夹名称" prop="name">
+            <el-input v-model="ruleForm.name" focus></el-input>
+          </el-form-item>
+        </el-form>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="closeDiaLog">取 消</el-button>
+        <el-button type="primary" @click="changeFolder">确 定</el-button>
+      </span>
+    </el-dialog>
+  </div>
+</template>
+<script>
+import request from "@/api/model/file.js";
+import { mapGetters } from "vuex";
+export default {
+  computed: {
+    ...mapGetters("layout", ["projectId", "userId", "secret"])
+  },
+  props: {
+    changeFolderNameVisible: Boolean,
+    folderName: String,
+    currentFolderId: String
+  },
+  data() {
+    return {
+      ruleForm: {
+        name: ""
+      },
+      rules: {
+        name: [
+          { required: true, message: "文件夹名称不能为空!", trigger: "blur" }
+        ]
+      }
+    };
+  },
+  methods: {
+    closeDiaLog() {
+      this.resetForm();
+      this.$emit("closeChangeFolderVisible");
+    },
+    changeFolder() {
+      this.$refs["changeFolderModelName"].validate(valid => {
+        if (valid) {
+          if (this.folderName == this.ruleForm.name) {
+            this.$message({ message: "文件夹名字不可与原来相同!",type:'error' });
+          } else {
+            request.updateModelName(
+              { Name: this.ruleForm.name, Id: this.currentFolderId },
+              () => {
+                this.$message({
+                  message: "模型文件夹创建成功",
+                  type: "success"
+                });
+                // 重新获取文件夹列表
+                this.$emit("finishChangeFolderName");
+                this.closeDiaLog();
+              }
+            );
+          }
+        } else {
+          return false;
+        }
+      });
+    },
+    resetForm() {
+      this.$refs["changeFolderModelName"].resetFields();
+    },
+  },
+  watch: {
+    folderName: function(val, oldVal) {
+      this.ruleForm.name = val;
+    }
+  }
+};
+</script>
+<style scoped >
+.dialog-footer {
+  
+}
+</style>

+ 210 - 0
src/components/model/file/floorTable.vue

@@ -0,0 +1,210 @@
+<template>
+  <div class="filterTable-container">
+    <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>
+          <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 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">
+        <template slot-scope="scope">
+          <div class="operate" v-show="!scope.row.isDown">
+            <el-button type="primary" size="mini" class="iconfont icon-download" @click="downloadModel(scope.row)"></el-button>
+            <el-button type="primary" size="mini" class="iconfont icon-replace" @click="repliaceModel(scope.row)"></el-button>
+            <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']"
+            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"
+                :color="scope.row.Status == 1 || scope.row.Status == 10 || scope.row.Status == 11?'#909399':'#67C23A'"></el-progress>
+            </div>
+            <div class="progress-right">
+              <!-- <el-button
+              v-show="!scope.row.Status"
+              type="danger"
+              class="iconfont icon-termination"
+              @click="closeUpdate(scope.row)"
+              circle
+            ></el-button>-->
+              <span v-show="!scope.row.Status && scope.row.precent == 100">上传中</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>
+            </div>
+          </div>
+        </template>
+      </el-table-column>
+    </el-table>
+  </div>
+</template>
+<script>
+import { mapGetters } from "vuex";
+export default {
+  props: {
+    tableData: Array,
+    persentList: Array,
+    modelFolderName: String
+  },
+  data() {
+    return {
+      maxHeight: 0
+    };
+  },
+  computed: {
+    ...mapGetters("layout", ["projectId", "userInfo", "userId", "secret"])
+  },
+  methods: {
+    // 查看日志
+    queryModelLog(item) {
+      this.$emit("openModelLog", item);
+    },
+    // 替换日志
+    repliaceModel(item) {
+      if (item.Status != 4 && item.Status != 21) {
+        this.$alert("正在识别模型对象,请稍后再替换。", "替换模型", {
+          confirmButtonText: "确定",
+          callback: action => {
+          }
+        });
+      } else {
+        this.$emit("replaceModel", item);
+      }
+    },
+    filterTag(Id, precent) {
+      this.$refs.filterTable.data.map(item => {
+        if (item.Id == Id) {
+          if (precent >= 100) {
+            // 如过precent == 100 不能关闭进度条,
+            if (precent == 100) {
+              item.precent = 99;
+            } else if (precent == 101) {
+              // 如过precent == 101 则返回结果为suceess 不能关闭进度条,
+              item.precent = 100;
+              item.isDown = false;
+              this.$emit("percentFinish");
+            }
+            return;
+          } else {
+            item.precent = precent;
+          }
+        }
+      });
+    },
+    // 下载模型文件
+    downloadModel(item) {
+      if (item.Url) {
+        let a = document.createElement("a");
+        a.href = item.Url;
+        a.download = `${this.modelFolderName}${item.FloorName}模型文件v${item.Version}.rvt`;
+        a.click();
+      } else {
+        this.$message({
+          message: "该文件夹下没有资源",
+          type: "error"
+        });
+      }
+    },
+    // 停止上传
+    closeUpdate(item) {
+      if (this.userInfo.userName == item.UserName) {
+        this.$emit("closeUpdateFile", item);
+      } else {
+        this.$message({
+          message: "您不是该文件的上传者,不能停止该文件上传!",
+          type: "error"
+        });
+      }
+    }
+  },
+  watch: {
+    persentList: {
+      immediate: true,
+      deep: true,
+      handler: function (val, oldVal) {
+        if (val.length != 0) {
+          val.map(item => {
+            if (item.precent != 0) {
+              this.filterTag(item.Id, item.precent);
+            }
+          });
+        }
+      }
+    }
+  }
+};
+</script>
+<style scoped lang="less">
+.box-card {
+  height: 100%;
+  .filterTable-container {
+    height: calc(100% - 80px);
+  }
+  .operate {
+    .iconfont {
+      font-size: 12px;
+      padding: 7px 12px;
+    }
+  }
+  .icon-termination {
+    color: #f56c6c;
+    background: #fff;
+    padding: 0;
+    border: 0;
+    font-size: 20px;
+    margin-left: 5px;
+  }
+  .upLoad {
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    padding: 4px 0;
+    .progress {
+      // width: 150px;
+      width: 175px;
+      height: 20px;
+    }
+    .progress-right {
+      height: 20px;
+      line-height: 20px;
+    }
+  }
+  .upLoad-loading {
+    position: relative;
+    justify-content: center;
+    .progress {
+      width: 220px;
+      height: 20px;
+    }
+    .progress-right {
+      position: absolute;
+      left: 50%;
+      top: 50%;
+      transform: translate(-50%, -50%);
+      color: #fff;
+    }
+  }
+}
+/deep/ .el-icon-warning {
+  display: none;
+  // color: transparent;
+}
+/deep/ .el-progress__text {
+  display: none;
+}
+/deep/ .upLoad-loading .el-progress-bar {
+  padding-right: 44px;
+  margin-right: -44px;
+}
+/deep/ .el-progress-bar__inner {
+  text-align: center;
+}
+</style>

+ 127 - 0
src/components/model/file/modelLog.vue

@@ -0,0 +1,127 @@
+<template>
+  <!-- 模型日志弹窗 -->
+  <div id="modelLog">
+    <el-dialog title="模型日志" :visible.sync="modelLogVisible" width="40%" :before-close="handleClose">
+      <div class="bodys">
+        <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 prop="AcceptTime" label="上传时间"></el-table-column>
+              <el-table-column prop="UserName" label="上传人"></el-table-column>
+              <el-table-column prop="address" label="操作">
+                <template slot-scope="scope">
+                  <el-button @click="handleClick(scope.row)" v-if="!scope.row.Removed" type='primary' size="mini" class="iconfont icon-download"></el-button>
+                  <!-- 需求:先不支持删除 -->
+                  <!-- <el-button @click="deleteModel(scope.row)" v-if="!scope.row.Removed" type='danger' plain size="mini">删除</el-button> -->
+                </template>
+              </el-table-column>
+            </el-table>
+          </el-tab-pane>
+          <el-tab-pane label="工程改造" name="second"></el-tab-pane>
+        </el-tabs>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+<script>
+import request from "@/api/model/file.js";
+export default {
+  props: {
+    modelLogVisible: Boolean,
+    modelFolderName: String,
+    logData: Array
+  },
+  data() {
+    return {
+      dialogVisible: false, //是否显示该弹窗
+      activeName: "first", //默认选择上传日志
+      tableData: [] //列表数据
+    };
+  },
+  computed: {
+    filterlogData: function() {
+      let newLogData = [];
+      if (this.logData.length) {
+        this.logData.forEach(item => {
+          newLogData.push(item);
+        });
+      }
+      return newLogData
+    }
+  },
+  methods: {
+    handleClose(done) {
+      this.$emit("CloseModelLogDia");
+    },
+    handleClick(item) {
+      console.log(item);
+      if (item.Url) {
+        let a = document.createElement("a");
+        a.href = item.Url;
+        a.download =`${this.modelFolderName}${item.FloorName}模型文件v${item.Version}.rvt`;
+        a.click();
+      } else {
+        this.$message({
+          message: "该文件夹下没有资源",
+          type: "error"
+        });
+      }
+    },
+    changeModel() {},
+    /**
+     * 删除模型
+     *
+     */
+    deleteModel(item) {
+      this.$confirm(
+        "此操作只可删除楼层模型文件,已经识别的对象及关系等,暂不可删除。确定删除?",
+        "提示",
+        {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning"
+        }
+      )
+        .then(() => {
+          request.deleteModelFileList(item.Id, res => {
+            if (res.Result == "success") {
+              //  刷新页面
+              this.$emit("deleteFinish");
+              this.$message({
+                type: "success",
+                message: "删除成功!"
+              });
+            } else {
+              this.$message({
+                type: "error",
+                message: res.Result
+              });
+            }
+          });
+        })
+        .catch(() => {
+          this.$message({
+            type: "info",
+            message: "已取消删除"
+          });
+        });
+    }
+  }
+};
+</script>
+<style lang="less" scoped>
+#modelLog {
+  .bodys {
+    position: relative;
+    padding-bottom: 30px;
+    .delete-model {
+      position: absolute;
+      right: 0;
+      top: 0;
+      z-index: 10;
+    }
+  }
+}
+</style>
+

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

@@ -0,0 +1,119 @@
+ <!-- 替换模型弹窗 -->
+
+<template>
+  <!-- 新增楼层 -->
+  <div id="replaceModel">
+    <el-dialog
+      title="替换模型"
+      :visible.sync="repliceModelVisible"
+      width="30%"
+      :before-close="handleClose"
+    >
+      <el-form ref="form" :model="form" label-width="100px">
+        <el-form-item label="模型文件:">
+          <el-upload
+            class="upload-demo"
+            ref="upload"
+            action="https://jsonplaceholder.typicode.com/posts/"
+            :on-preview="handlePreview"
+            :on-remove="handleRemove"
+            :file-list="fileList"
+            :auto-upload="false"
+            :on-change="onChangeUpLoad"
+            :limit="1"
+          >
+            <el-button slot="trigger" size="small" type="primary">选取文件</el-button>
+          </el-upload>
+        </el-form-item>
+        <el-form-item label="选择模型文件替换原因:">
+          <ul>
+            <li>
+              <el-radio :disabled="isChioce" v-model="form.ReplaceReason" label="0">之前模型画错要修改</el-radio>
+            </li>
+            <li>
+              <el-radio :disabled="isChioce" v-model="form.ReplaceReason" label="1">因工程改造,更新模型文件</el-radio>
+            </li>
+          </ul>
+        </el-form-item>
+        <el-form-item>
+          <div class="dateTime" v-show="form.ReplaceReason == '1'">
+            <p>工程改造竣工时间:</p>
+            <el-date-picker v-model="form.finishTime" type="date" placeholder="选择日期"></el-date-picker>
+          </div>
+        </el-form-item>
+        <el-form-item>
+          <el-button type="primary" @click="onSubmit">确认</el-button>
+          <el-button @click="handleClose">取消</el-button>
+        </el-form-item>
+      </el-form>
+    </el-dialog>
+  </div>
+</template>
+<script>
+export default {
+  props: {
+    repliceModelVisible: Boolean,
+    replaceModelItem: Object
+  },
+  data() {
+    return {
+      form: {
+        file: null, //上传文件
+        ReplaceReason: "0",
+        finishTime: ""
+      },
+      isChioce: true, //是否可以选择替换原因
+      fileList: []
+    };
+  },
+  methods: {
+    onSubmit() {
+      if (this.form.file == null) {
+        this.$message.error("模型文件不能为空!");
+      } else {
+        this.$emit("updataModel", {
+          Form: this.form,
+          replaceModelItem: this.replaceModelItem
+        });
+        this.handleClose();
+      }
+    },
+    // /上传到服务器/
+    submitUpload() {
+      this.$refs.upload.submit();
+    },
+    handleClose() {
+      this.$emit("closeReplaceModelDia");
+    },
+    handleRemove(file, fileList) {
+      this.form.file = null;
+      this.fileList = []
+    },
+    handlePreview(file) {
+      console.log(file);
+    },
+    handleChange() {},
+    // 获取上传文件
+    onChangeUpLoad(file, fileList) {
+      if (fileList.length) {
+        this.form.file = file;
+      }
+    }
+  },
+  watch: {
+    repliceModelVisible(val) {
+      if (val) {
+        this.handleRemove();
+      }
+    }
+  }
+};
+</script>
+<style lang="less">
+#addFloorDialog {
+  .floorModle {
+    display: flex;
+    justify-content: left;
+  }
+}
+</style>

+ 96 - 0
src/components/point/dynamicdata/applyLog.vue

@@ -0,0 +1,96 @@
+<template>
+  <el-dialog title="提示" :visible.sync="dialogVisible" width="40%" id="applyRules">
+    <p>按对应规则配置动态参数,已完成!</p>
+    <p>请检查并关注以下实例及相关动态参数,自动配置结果是否正确</p>
+    <div ref="message" style="max-height:400px;overflow-x:hidden;overflow-y:auto;">
+      <div v-for="item in ContentList" :key="item.code" v-show="item.children.length">
+        <p>【{{item.name}}】</p>
+        <div v-for="t in item.children" :key="t.ObjectID+t.Id">
+          <p v-if="t.TypeCode=='Eq'">
+            {{`${t.ObjectLocalName?t.ObjectLocalName:'--'}/${t.ObjectID?t.ObjectID:'--'}/${t.TypeName?t.TypeName:'--'}/${t.BuildLocalName?t.BuildLocalName:'--' }/${t.FloorLocalName?t.FloorLocalName:'--'}/${t.RoomLocalName?t.RoomLocalName:'--'}`}}
+          </p>
+          <p v-if="t.TypeCode=='Ec'">
+            {{`${t.ObjectLocalName?t.ObjectLocalName:'--'}/${t.ObjectID?t.ObjectID:'--'}/${t.TypeName?t.TypeName:'--'}/${t.CascadeEquipLocalName}/${t.BuildLocalName?t.BuildLocalName:'--' }/${t.FloorLocalName?t.FloorLocalName:'--'}/${t.RoomLocalName?t.RoomLocalName:'--'}`}}
+          </p>
+          <p v-if="t.TypeCode=='Sp'">
+            {{`${t.ObjectLocalName?t.ObjectLocalName:'--'}/${t.ObjectID?t.ObjectID:'--'}/${t.TypeName?t.TypeName:'--'}/${t.BuildLocalName?t.BuildLocalName:'--' }/${t.FloorLocalName?t.FloorLocalName:'--'}`}}
+          </p>
+          <p v-if="t.TypeCode=='Sy'">{{`${t.ObjectLocalName?t.ObjectLocalName:'--'}/${t.ObjectID?t.ObjectID:'--'}/${t.TypeName?t.TypeName:'--'}`}}</p>
+          <p>{{`${t.InfomationPoint}/${t.Old}/${t.New}`}}</p>
+          <hr style="margin:10px 0;width:50%;">
+        </div>
+      </div>
+    </div>
+    <span slot="footer" class="dialog-footer">
+      <el-button size="small" @click="copy">复制信息</el-button>
+      <el-button size="small" type="primary" @click="dialogVisible=false">关闭</el-button>
+    </span>
+  </el-dialog>
+</template>
+<script>
+
+import {
+  dynamicExecuteDetail // 查询执行日志
+} from "@/api/scan/request";
+export default {
+  data() {
+    return {
+      dialogVisible: false, //弹窗显示与隐藏
+      ContentList: [
+        { name: '人工维护过值的信息点', children: [], code: 'MeterDiff' },
+        { name: '多个表号功能号对应一个信息点,无法执行对应规则,请检查', children: [], code: 'Multiple' },
+      ],
+      typeList: ["MeterDiff", "Multiple"], //此分类索引需与上list保持一致
+    };
+  },
+  methods: {
+    showDialog(Id) {
+      this.dialogVisible = true
+      this.getApplyLog(Id)
+    },
+    handleClose() {
+      this.dialogVisible = false;
+    },
+    //复制信息
+    copy() {
+      let text = this.$refs.message.innerText;
+      let copyUrl = $('<input type="text" />').val(text);//创建一个input框获取需要复制的文本内容
+      copyUrl.appendTo('body');
+      copyUrl.select();
+      document.execCommand("Copy");
+      copyUrl.remove()
+      this.$message.success('复制成功')
+    },
+    //查询执行日志
+    getApplyLog(Id) {
+      let param = {
+        Filters: `Type='Multiple' or Type='MeterDiff';Id='${Id}'`,
+        PageNumber: 1,
+        PageSize: 50
+      }
+      dynamicExecuteDetail(param, res => {
+        res.Content.map(t => {
+          this.ContentList[this.typeList.indexOf(t.Type)].children.push(t)
+        })
+        this.ContentList[1].children = this.unique(this.ContentList[1].children)
+      })
+    },
+    //数组去重
+    unique(arr) {
+      let hash = [];
+      if (arr.length) {
+        for (var i = 0; i < arr.length; i++) {
+          for (var j = i + 1; j < arr.length; j++) {
+            if (arr[i].ObjectID === arr[j].ObjectID && arr[i].InfomationPointCode === arr[j].InfomationPointCode) {
+              ++i;
+              arr[i].New += '/' + arr[j].New
+            }
+          }
+          hash.push(arr[i]);
+        }
+      }
+      return hash;
+    }
+  }
+};
+</script>

+ 107 - 0
src/components/point/dynamicdata/applyRulesDialog-copy.vue

@@ -0,0 +1,107 @@
+<template>
+  <el-dialog title="提示" :visible.sync="dialogVisible" width="30%" @close="handleClose" id="applyRules">
+    <p>对应规则有冲突,请选择处理方式:</p>
+    <div>
+      <el-radio v-model="select" :label="'Old'">保留设备实例中人工维护的动态参数的值</el-radio>
+    </div>
+    <div>
+      <el-radio v-model="select" :label="'New'">按照规则自动覆盖动态参数的值</el-radio>
+    </div>
+    <span slot="footer" class="dialog-footer">
+      <el-button size="small" @click="handleClose">取消</el-button>
+      <el-button size="small" type="primary" @click="confirmClash">确认</el-button>
+    </span>
+  </el-dialog>
+</template>
+<script>
+
+import {
+  dynamicPromptobjs, //提示冲突
+  dynamicClashConfirm, //冲突选择确认
+  dynamicExecute, //执行规则
+} from "@/api/scan/request";
+import Vue from 'vue'
+export default {
+  data() {
+    return {
+      dialogVisible: false, //弹窗显示与隐藏
+      tableData: [],
+      activeName: "first", //当前所在tab页
+      finished: false, //未处理所有冲突提示文字
+      force: false, //请求冲突-默认false
+      select: 'New'
+    };
+  },
+  methods: {
+    showDialog(force) {
+      this.force = force
+      if (this.tableData.length) {
+        this.dialogVisible = true;
+      } else {
+        this.rulesConfirm()
+      }
+    },
+    handleClose() {
+      this.dialogVisible = false;
+      this.$emit('cancel')
+    },
+    //查询是否有冲突
+    getPromptobjs() {
+      let param = {
+        Force: this.force
+      }
+      dynamicPromptobjs(param, res => {
+        this.tableData = res.Content;
+        this.$emit('clash', this.tableData.length);
+      })
+    },
+    //确认冲突
+    confirmClash() {
+      let selectedRows = this.tableData.map(t => {
+        t.checked = this.select
+        return t
+      });
+      let param = [];
+      selectedRows.map(t => {
+        let tempObj = {
+          Objs: [t],
+          Points: [t]
+        }
+        param.push(tempObj)
+      })
+      dynamicClashConfirm(param, res => {
+        this.rulesConfirm();
+      })
+    },
+    //执行规则
+    rulesConfirm() {
+      let param = {
+        Force: this.force
+      }
+      dynamicExecute(param, res => {
+        this.$message.success('执行成功');
+        this.dialogVisible = false;
+        let missionID = res.Content[0].Id
+        this.$emit('refresh', missionID)
+      })
+    }
+  },
+  mounted() { },
+  created() {
+    this.getPromptobjs()
+  }
+};
+</script>
+<style lang="scss" scoped>
+#applyRules {
+  /deep/ td.bgf5 {
+    background-color: #f5f7fa;
+  }
+  td p {
+    text-align: center;
+  }
+  /deep/ .el-radio__input.is-checked + .el-radio__label {
+    color: #000;
+  }
+}
+</style>

+ 1 - 1
src/components/point/dynamicdata/dataSource.vue

@@ -27,7 +27,7 @@ export default {
   methods: {
     init() {
       this.Datasource = [];
-      let param = { Related: this.Related, typeName: this.typeName };
+      let param = { Related: this.Related, TypeName: this.typeName };
       //数据源
       dynamicDataSource(param, res => {
         if (res.Result == "success") {

+ 63 - 21
src/components/point/dynamicdata/delRelationDialog.vue

@@ -3,36 +3,37 @@
     <span>确定要清除对应关系?</span>
     <div v-loading="loading">
       <div v-show="ltableData.length>1">
-        <div style="margin:10px 0;">有多个设备标识对应了该设备实例,是否一并清除对应关系?</div>
+        <div style="margin:10px 0;">有多个对象标识对应了该对象实例,是否一并清除对应关系?</div>
         <el-row class="bgf5">
           <el-col :span="18">
             <el-table :data="ltableData" style="width: 100%;max-height:400px;" height="calc(100% - 160px)" @selection-change="changeSelection"
               ref="ltable">
-              <el-table-column label="设备标识" align="right" class-name="bgfff">
+              <el-table-column label="对象标识" align="right" class-name="bgfff">
                 <el-table-column label="数据源" prop="Datasource" align="right" class-name="bgfff" show-overflow-tooltip></el-table-column>
                 <el-table-column label="位置标签" prop="LocationFlag" align="right" class-name="bgfff" show-overflow-tooltip>
                   <template slot-scope="scope">
                     <div class="tool-tip">{{scope.row.LocationFlag.toString()}}</div>
                   </template>
                 </el-table-column>
-                <el-table-column label="设备标识" prop="EquipmentMark" align="right" class-name="bgf5" show-overflow-tooltip></el-table-column>
+                <el-table-column label="对象标识" prop="EquipmentMark" align="right" class-name="bgf5" show-overflow-tooltip></el-table-column>
                 <el-table-column type="selection" class-name="bgf5"></el-table-column>
               </el-table-column>
             </el-table>
           </el-col>
           <el-col :span="6">
-            <div class="singleDir pl-10 font-default">设备实例</div>
-            <div class="pl-10 font-default">{{rtableData[0]?rtableData[0].ObjectLocalName:'--'}}</div>
-            <div class="pl-10 font-default">{{rtableData[0]?rtableData[0].BuildLocalName:'--'}}-{{rtableData[0]?rtableData[0].FloorLocalName:'--'}}</div>
-            <div class="pl-10 font-default">{{rtableData[0]?rtableData[0].RoomLocalName:'--'}}</div>
+            <div class="singleDir pl-10 font-default">对象实例</div>
+            <div class="pl-10 font-default">{{rtableData[0]?rtableData[0].ObjectLocalName?rtableData[0].ObjectLocalName:'--':'--'}}</div>
+            <div class="pl-10 font-default">{{rtableData[0]?rtableData[0].BuildLocalName:'--'}}-{{rtableData[0]?rtableData[0].FloorLocalName:'--'}}
+            </div>
+            <div class="pl-10 font-default">{{rtableData[0]?rtableData[0].RoomLocalName?rtableData[0].RoomLocalName:'--':'--'}}</div>
           </el-col>
         </el-row>
       </div>
       <div v-show="rtableData.length>1">
-        <div style="margin:10px 0;">有多个设备实例对应了该设备标识,是否一并清除对应关系?</div>
+        <div style="margin:10px 0;">有多个对象实例对应了该对象标识,是否一并清除对应关系?</div>
         <el-row class="bgf5">
           <el-col :span="6">
-            <div class="singleDir pr-10 font-default tr">设备标识</div>
+            <div class="singleDir pr-10 font-default tr">对象标识</div>
             <div class="pr-10 font-default tr">{{ltableData[0]?ltableData[0].EquipmentMark:'--'}}</div>
             <div class="pr-10 font-default tr">{{ltableData[0]?ltableData[0].LocationFlag.toString():'--'}}</div>
             <div class="pr-10 font-default tr">{{ltableData[0]?ltableData[0].Datasource:'--'}}</div>
@@ -40,18 +41,28 @@
           <el-col :span="18">
             <el-table :data="rtableData" style="width: 100%;max-height:400px;" height="calc(100% - 160px)" @selection-change="changeSelection"
               ref="rtable">
-              <el-table-column label="设备实例" class-name="bgfff">
+              <el-table-column label="对象实例" class-name="bgfff">
                 <el-table-column type="selection" class-name="bgf5"></el-table-column>
-                <el-table-column label="设备实例名称" prop="ObjectLocalName" class-name="bgf5" show-overflow-tooltip></el-table-column>
-                <el-table-column label="设备实例编码" prop="ObjectID" class-name="bgfff" show-overflow-tooltip></el-table-column>
-                <el-table-column label="所在建筑楼层" class-name="bgfff">
+                <el-table-column v-for="(item,index) in rightTableHeader" :label="item.label" :key="item.prop" :class-name="index>0?'bgfff':'bgf5'">
                   <template slot-scope="scope">
-                    <el-tooltip :content="scope.row.BuildLocalName&&scope.row.FloorLocalName?scope.row.BuildLocalName+'-'+scope.row.FloorLocalName:''" placement="top">
-                      <div class="tool-tip">{{scope.row.BuildLocalName&&scope.row.FloorLocalName?scope.row.BuildLocalName+'-'+scope.row.FloorLocalName:''}}</div>
-                    </el-tooltip>
+                    <div v-if="item.prop=='BuildLocalName'">
+                      <el-tooltip
+                        :content="scope.row.BuildLocalName&&scope.row.BuildLocalName!='null'?scope.row.FloorLocalName&&scope.row.FloorLocalName!='null'?scope.row.BuildLocalName+'-'+scope.row.FloorLocalName:scope.row.BuildLocalName:''"
+                        placement="top"
+                        :disabled="!(scope.row.BuildLocalName&&scope.row.BuildLocalName!='null'?scope.row.FloorLocalName&&scope.row.FloorLocalName!='null'?scope.row.BuildLocalName+'-'+scope.row.FloorLocalName:scope.row.BuildLocalName:'')">
+                        <div class="tool-tip">
+                          {{scope.row.BuildLocalName&&scope.row.BuildLocalName!='null'?scope.row.FloorLocalName&&scope.row.FloorLocalName!='null'?scope.row.BuildLocalName+'-'+scope.row.FloorLocalName:scope.row.BuildLocalName:'--'}}
+                        </div>
+                      </el-tooltip>
+                    </div>
+                    <div v-else>
+                      <el-tooltip :content="scope.row[item.prop]?scope.row[item.prop].toString():''" placement="top"
+                        :disabled="!scope.row[item.prop]">
+                        <div class="tool-tip">{{scope.row[item.prop]?scope.row[item.prop].toString():'--'}}</div>
+                      </el-tooltip>
+                    </div>
                   </template>
                 </el-table-column>
-                <el-table-column label="所在业务空间" prop="RoomLocalName" class-name="bgfff" show-overflow-tooltip></el-table-column>
               </el-table-column>
             </el-table>
           </el-col>
@@ -76,14 +87,45 @@ export default {
       dialogWidth: "20%", //弹窗宽度
       selection: [],
       deleDisabled: true,
-      deleParam: []
+      deleParam: [],
+      allHeaderData: {
+        equip: [
+          { label: '对象实例名称', prop: "ObjectLocalName" },
+          { label: '对象实例编码', prop: "ObjectID" },
+          { label: '所在建筑楼层', prop: "BuildLocalName" },
+          { label: '所在业务空间', prop: "RoomLocalName" },
+        ],
+        parts: [
+          { label: '对象实例名称', prop: "ObjectLocalName" },
+          { label: '对象实例编码', prop: "ObjectID" },
+          { label: '所在建筑楼层', prop: "BuildLocalName" },
+          { label: '所在业务空间', prop: "RoomLocalName" },
+          { label: '所属设备实例', prop: "CascadeEquipLocalName" },
+        ],
+        system: [
+          { label: '对象实例名称', prop: "ObjectLocalName" },
+          { label: '对象实例编码', prop: "ObjectID" },
+        ],
+        space: [
+          { label: '对象实例名称', prop: "ObjectLocalName" },
+          { label: '对象实例编码', prop: "ObjectID" },
+          { label: '所在建筑楼层', prop: "BuildLocalName" },
+        ]
+      },
+      rightTableHeader: []
     };
   },
+  props: {
+    typeName: {
+      default: 'equip'
+    }
+  },
   methods: {
     //弹窗显示
     showDialog(row) {
       this.dialogVisible = true;
       this.loading = true;
+      this.rightTableHeader = this.allHeaderData[this.typeName]
       //需先用对象请求接口返回所需对象
       this.getDynamicQueryPrompt(row)
     },
@@ -123,14 +165,14 @@ export default {
         PageNumber: 1,
         PageSize: 500
       }
-      //通过标识查询设备实例
+      //通过标识查询对象实例
       let promise1 = new Promise((resolve, reject) => {
         dynamicQueryPrompt(p1, res => {
           resolve(res)
         })
       })
       let p2 = {
-        Filters: `ObjectID='${row.ObjectID}'`,
+        Filters: `ObjectID='${row.ObjectID}';TypeCode='${row.TypeCode}'`,
         PageNumber: 1,
         PageSize: 500
       }
@@ -205,7 +247,7 @@ export default {
   .tr {
     text-align: right;
   }
-  .tool-tip{
+  .tool-tip {
     white-space: nowrap;
     overflow: hidden;
     text-overflow: ellipsis;

+ 2 - 2
src/components/point/dynamicdata/dictionaryDevice.vue

@@ -1,7 +1,7 @@
 <template>
   <div>
     <el-form>
-      <el-form-item label="数据字典设备类型">
+      <el-form-item :label="`数据字典${typeName}类型`">
         <el-select v-model="SubTypeName" multiple collapse-tags placeholder="全部" filterable @change="changeType">
           <el-option v-for="item in DynEquipList" :key="item" :label="item" :value="item"></el-option>
         </el-select>
@@ -32,7 +32,7 @@ export default {
   },
   methods: {
     init() {
-      let param = { Related: this.Related, typeName: this.typeName };
+      let param = { Related: this.Related, TypeName: this.typeName };
       //数据字典
       dynamicDynEquipList(param, res => {
         if (res.Result == "success") {

+ 17 - 15
src/components/point/dynamicdata/equipRules.vue

@@ -8,7 +8,7 @@
           <el-form ref="form" :model="form" :inline="true">
             <el-row>
               <div class="query-item special">
-                <el-input placeholder="请输入设备标识关键字" v-model="form.EquipmentMark" @keyup.enter.native="queryTableData">
+                <el-input :placeholder="`请输入${typeName}标识关键字`" v-model="form.EquipmentMark" @keyup.enter.native="queryTableData">
                   <i slot="suffix" class="el-input__icon el-icon-search" @click="queryTableData"></i>
                 </el-input>
               </div>
@@ -27,20 +27,20 @@
           </el-form>
         </el-col>
         <el-col :span="1">
-          <el-tooltip class="item" effect="dark" content="填充设备标识与实例对应规则" placement="left">
+          <el-tooltip class="item" effect="dark" :content="`填充${typeName}标识与实例对应规则`" placement="left">
             <el-button size="small" type="primary" @click="toAddRelation" icon="el-icon-edit-outline" style="float:right;" :disabled="isPending"></el-button>
           </el-tooltip>
         </el-col>
       </el-row>
     </div>
     <el-row>
-      <el-col :span="12" style="padding-left:10px;font-size:13px;border-left:2px solid #000;">点位表中出现的所有设备</el-col>
-      <el-col :span="12" style="padding-left:10px;font-size:13px;border-left:2px solid #000;">对应物理世界中的设备实例</el-col>
+      <el-col :span="12" style="padding-left:10px;font-size:13px;border-left:2px solid #000;">点位表中出现的所有{{typeName}}</el-col>
+      <el-col :span="12" style="padding-left:10px;font-size:13px;border-left:2px solid #000;">对应物理世界中的{{typeName}}实例</el-col>
     </el-row>
     <!-- 列表区域 -->
     <div class="table-area">
-      <el-table :data="tableData" style="width: 100%" height="100%" v-loading="loading" :header-cell-style="{background:'#f7f9fb'}">
-        <el-table-column prop="EquipmentMark" label="设备标识" show-overflow-tooltip min-width="100"></el-table-column>
+      <el-table :data="tableData" style="width: 100%" height="100%" v-loading="loading" :header-cell-style="headerStyle">
+        <el-table-column prop="EquipmentMark" :label="`${typeName}标识`" show-overflow-tooltip min-width="100"></el-table-column>
         <el-table-column prop="LocationFlag" label="位置标签" min-width="200">
           <template slot-scope="scope">
             <el-tooltip :content="scope.row.LocationFlag.toString()" placement="top">
@@ -49,13 +49,13 @@
           </template>
         </el-table-column>
         <el-table-column prop="Datasource" label="数据源" show-overflow-tooltip min-width="100"></el-table-column>
-        <el-table-column prop="SubTypeName" label="数字字典设备类型" show-overflow-tooltip min-width="100"></el-table-column>
-        <el-table-column prop="ObjectLocalName" label="对应的设备实例" show-overflow-tooltip min-width="100" class-name="td-bl"></el-table-column>
+        <el-table-column prop="SubTypeName" :label="`数字字典${typeName}类型`" show-overflow-tooltip min-width="100"></el-table-column>
+        <el-table-column prop="ObjectLocalName" :label="`对应的${typeName}实例`" show-overflow-tooltip min-width="100" class-name="td-bl"></el-table-column>
         <el-table-column label="实例所在建筑楼层" min-width="100">
           <template slot-scope="scope">
-            <el-tooltip :content="scope.row.BuildLocalName&&scope.row.FloorLocalName?scope.row.BuildLocalName+'-'+scope.row.FloorLocalName:''"
+            <el-tooltip :content="scope.row.BuildLocalName?scope.row.FloorLocalName?scope.row.BuildLocalName+'-'+scope.row.FloorLocalName:scope.row.BuildLocalName:''"
               placement="top">
-              <div class="tool-tip">{{scope.row.BuildLocalName&&scope.row.FloorLocalName?scope.row.BuildLocalName+'-'+scope.row.FloorLocalName:''}}
+              <div class="tool-tip">{{scope.row.BuildLocalName?scope.row.FloorLocalName?scope.row.BuildLocalName+'-'+scope.row.FloorLocalName:scope.row.BuildLocalName:''}}
               </div>
             </el-tooltip>
           </template>
@@ -101,6 +101,11 @@ export default {
   },
   data() {
     return {
+      headerStyle: {
+        backgroundColor: '#e1e4e5',
+        color: '#2b2b2b',
+        lineHeight: '30px'
+      },
       sourceList: [], //数据源
       DynEquipList: [], //数据字典设备类型
       LocFlagList: [], //位置标签
@@ -242,7 +247,8 @@ export default {
   }
   /deep/ .table-area {
     width: 100%;
-    height: calc(100% - 125px);
+    height: calc(100% - 71px);
+    margin-bottom: 10px;
     td div {
       white-space: nowrap;
       text-overflow: ellipsis;
@@ -257,10 +263,6 @@ export default {
       text-overflow: ellipsis;
     }
   }
-  .fr {
-    padding-top: 10px;
-    float: right;
-  }
 }
 </style>
 

+ 70 - 58
src/components/point/dynamicdata/historyDialog.vue

@@ -2,74 +2,42 @@
   <el-dialog title="本次对应记录" :visible.sync="dialogVisible" width="70%" @close="handleClose" id="historyAction" custom-class="act-history">
     <span>提示:可使用Contorl+F 搜索关键字</span>
     <div>
-      <el-table :data="tableData" style="width: 100%;" :show-header="showheader" height="400px">
+      <el-table :data="tableData" style="width: 100%;" :show-header="showheader" height="400px" :cell-style="cellStyle">
         <el-table-column>
-          <el-table-column label="数据源" align="right">
+          <el-table-column v-for="item in showLeftHeader" :label="item.label" align="right" :key="item.prop">
             <template slot-scope="scope">
               <div v-for="t in scope.row.leftList" :key="t.id">
-                <el-tooltip :content="t.Datasource" placement="top">
-                  <div>{{t.Datasource}}</div>
-                </el-tooltip>
-              </div>
-            </template>
-          </el-table-column>
-          <el-table-column label="位置标签" align="right">
-            <template slot-scope="scope">
-              <div v-for="t in scope.row.leftList" :key="t.id">
-                <el-tooltip :content="t.LocationFlag.toString()" placement="top">
-                  <div>{{t.LocationFlag.toString()}}</div>
-                </el-tooltip>
-              </div>
-            </template>
-          </el-table-column>
-          <el-table-column label="设备标识" width="200px" class-name="bgf5" align="right">
-            <template slot-scope="scope">
-              <div v-for="t in scope.row.leftList" :key="t.id">
-                <el-tooltip :content="t.EquipmentMark" placement="top">
-                  <div>{{t.EquipmentMark}}</div>
+                <el-tooltip :content="t[item.prop]&&t[item.prop].length?t[item.prop].toString():''" placement="top" :disabled="!(t[item.prop]&&t[item.prop].length)">
+                  <div>{{t[item.prop]&&t[item.prop].length?t[item.prop].toString():'--'}}</div>
                 </el-tooltip>
               </div>
             </template>
           </el-table-column>
         </el-table-column>
         <el-table-column>
-          <el-table-column label="设备实例名称" width="200px" class-name="bgf5 border-l">
+          <el-table-column v-for="item in showRightHeader" :label="item.label" :key="item.prop">
             <template slot-scope="scope">
               <div v-for="t in scope.row.rightList" :key="t.id">
-                <el-tooltip :content="t.ObjectLocalName" placement="top">
-                  <div>{{t.ObjectLocalName}}</div>
-                </el-tooltip>
-              </div>
-            </template>
-          </el-table-column>
-          <el-table-column label="设备实例编码">
-            <template slot-scope="scope">
-              <div v-for="t in scope.row.rightList" :key="t.id">
-                <el-tooltip :content="t.ObjectID" placement="top">
-                  <div>{{t.ObjectID}}</div>
-                </el-tooltip>
-              </div>
-            </template>
-          </el-table-column>
-          <el-table-column label="所在建筑楼层">
-            <template slot-scope="scope">
-              <div v-for="t in scope.row.rightList" :key="t.id">
-                <el-tooltip
-                  :content="t.BuildLocalName&&t.FloorLocalName&&t.BuildLocalName!='null'&&t.FloorLocalName!='null'?t.BuildLocalName+'-'+t.FloorLocalName:''"
-                  placement="top">
-                  <div>
-                    {{t.BuildLocalName&&t.FloorLocalName&&t.BuildLocalName!='null'&&t.FloorLocalName!='null'?t.BuildLocalName+'-'+t.FloorLocalName:''}}
-                  </div>
-                </el-tooltip>
-              </div>
-            </template>
-          </el-table-column>
-          <el-table-column label="所在业务空间">
-            <template slot-scope="scope">
-              <div v-for="t in scope.row.rightList" :key="t.id">
-                <el-tooltip :content="t.RoomLocalName&&t.RoomLocalName!='null'?t.RoomLocalName:''" placement="top">
-                  <div>{{t.RoomLocalName&&t.RoomLocalName!='null'?t.RoomLocalName:''}}</div>
-                </el-tooltip>
+                <div v-if="item.prop=='BuildLocalName'">
+                  <el-tooltip
+                    :content="t.BuildLocalName&&t.BuildLocalName!='null'?t.FloorLocalName&&t.FloorLocalName!='null'?t.BuildLocalName+'-'+t.FloorLocalName:t.BuildLocalName:''"
+                    placement="top" :disabled="!(t.BuildLocalName&&t.BuildLocalName!='null'?t.FloorLocalName&&t.FloorLocalName!='null'?t.BuildLocalName+'-'+t.FloorLocalName:t.BuildLocalName:'')">
+                    <div>
+                      {{t.BuildLocalName&&t.BuildLocalName!='null'?t.FloorLocalName&&t.FloorLocalName!='null'?t.BuildLocalName+'-'+t.FloorLocalName:t.BuildLocalName:'--'}}
+                    </div>
+                  </el-tooltip>
+                </div>
+                <div v-else-if="item.prop=='RoomLocalName'">
+                  <el-tooltip :content="t.RoomLocalName&&t.RoomLocalName!='null'?t.RoomLocalName:''" placement="top"
+                    :disabled="!(t.RoomLocalName&&t.RoomLocalName!='null')">
+                    <div>{{t.RoomLocalName&&t.RoomLocalName!='null'?t.RoomLocalName:'--'}}</div>
+                  </el-tooltip>
+                </div>
+                <div v-else>
+                  <el-tooltip :content="t[item.prop]?t[item.prop].toString():''" placement="top" :disabled="!t[item.prop]">
+                    <div>{{t[item.prop]?t[item.prop].toString():'--'}}</div>
+                  </el-tooltip>
+                </div>
               </div>
             </template>
           </el-table-column>
@@ -90,11 +58,47 @@ export default {
     return {
       dialogVisible: false, //弹窗显示与隐藏
       showheader: false,
-      tableData: [] //数据list
+      tableData: [], //数据list
+      showLeftHeader: [
+        { label: '数据源', prop: 'Datasource' },
+        { label: '位置标签', prop: 'LocationFlag' },
+        { label: '设备标识', prop: 'EquipmentMark' }
+      ],
+      tableHeader: {
+        equip: [
+          { label: '对象实例名称', prop: 'ObjectLocalName' },
+          { label: '对象实例编码', prop: 'ObjectID' },
+          { label: '所在建筑楼层', prop: 'BuildLocalName' },
+          { label: '所在业务空间', prop: 'RoomLocalName' },
+        ],
+        parts: [
+          { label: '对象实例名称', prop: 'ObjectLocalName' },
+          { label: '对象实例编码', prop: 'ObjectID' },
+          { label: '对象所属设备', prop: 'CascadeEquipLocalName' },
+          { label: '所在建筑楼层', prop: 'BuildLocalName' },
+          { label: '所在业务空间', prop: 'RoomLocalName' },
+        ],
+        system: [
+          { label: '对象实例名称', prop: 'ObjectLocalName' },
+          { label: '对象实例编码', prop: 'ObjectID' }
+        ],
+        space:[
+          { label: '对象实例名称', prop: "ObjectLocalName" },
+          { label: '对象实例编码', prop: "ObjectID" },
+          { label: '所在建筑楼层', prop: "BuildLocalName" },
+        ]
+      }, //所有类型列表头部
+      showRightHeader: [], //实际显示的列表头部
     };
   },
+  props: {
+    typeName: {
+      default: 'equip'
+    }
+  },
   methods: {
     showDialog(data) {
+      this.showRightHeader = this.tableHeader[this.typeName]
       this.tableData = data;
       this.dialogVisible = true;
     },
@@ -114,6 +118,14 @@ export default {
           this.$emit("delSuc");
         }
       });
+    },
+    //渲染中间两列颜色
+    cellStyle(data) {
+      if (data.columnIndex == 2) {
+        return 'background-color:#f5f7fa'
+      } else if (data.columnIndex == 3) {
+        return 'background-color:#f5f7fa;border-left:2px solid #ccc;'
+      }
     }
   },
   mounted() { },

+ 2 - 2
src/components/point/dynamicdata/locationCascader.vue

@@ -1,5 +1,5 @@
 <template>
-  <el-cascader placeholder="请选择所在位置" :options="LocationList" v-model="value" filterable size="small" @change="changeCascader" change-on-select
+  <el-cascader placeholder="全部" :options="LocationList" v-model="value" filterable size="small" @change="changeCascader" change-on-select
     :props="props" clearable class="location"></el-cascader>
 </template>
 <script>
@@ -30,7 +30,7 @@ export default {
   },
   methods: {
     init() {
-      let param = { Related: this.Related, typeName: this.typeName };
+      let param = { Related: this.Related, TypeName: this.typeName };
       dynamicLocationList(param, res => {
         this.LocationList = res.Content[0].List;
         //添加未明确对象

+ 1 - 1
src/components/point/dynamicdata/locationFlag.vue

@@ -27,7 +27,7 @@ export default {
   methods: {
     init() {
       this.Datasource = [];
-      let param = { Related: this.Related, typeName: this.typeName };
+      let param = { Related: this.Related, TypeName: this.typeName };
       // 位置标签
       dynamicLocFlagList(param, res => {
         if (res.Result == "success") {

+ 55 - 38
src/components/point/dynamicdata/partsRules.vue

@@ -1,6 +1,5 @@
 
 <template>
-<!-- 部件 -->
   <div id="equipRules">
     <!-- 查询条件 -->
     <div class="query-area">
@@ -8,58 +7,65 @@
         <el-col :span="23">
           <el-form ref="form" :model="form" :inline="true">
             <el-row>
-              <div class="query-item">
-                <el-form-item>
-                  <el-input placeholder="请输入部件标识关键字" v-model="form.EquipmentMark" class="input-with-select">
-                    <el-button slot="append" icon="el-icon-search" @click="queryTableData"></el-button>
-                  </el-input>
-                </el-form-item>
+              <div class="query-item special">
+                <el-input :placeholder="`请输入${typeName}标识关键字`" v-model="form.EquipmentMark" @keyup.enter.native="queryTableData">
+                  <i slot="suffix" class="el-input__icon el-icon-search" @click="queryTableData"></i>
+                </el-input>
               </div>
               <div class="query-item">
-                <label>数据源</label>
-                <dataSource :Related="true" @change="changeDataSource"></dataSource>
+                <label style="padding-right:9px">数据源</label>
+                <dataSource :Related="null" @change="changeDataSource" :typeName="typeName"></dataSource>
               </div>
               <div class="query-item">
-                <dictionary-device @change="changeDictionary" :Related="true"></dictionary-device>
+                <dictionary-device @change="changeDictionary" :Related="null" :typeName="typeName"></dictionary-device>
               </div>
               <div class="query-item">
-                <label>位置标签</label>
-                <locationFlag :Related="true" @change="changeLocationFlag"></locationFlag>
+                <label style="padding-right:9px">位置标签</label>
+                <locationFlag :Related="null" @change="changeLocationFlag" :typeName="typeName"></locationFlag>
               </div>
             </el-row>
           </el-form>
         </el-col>
         <el-col :span="1">
-          <el-tooltip class="item" effect="dark" content="填充部件标识与实例对应规则" placement="left">
-            <el-button size="small" type="primary" @click="toAddRelation" icon="el-icon-edit-outline" style="float:right;"></el-button>
+          <el-tooltip class="item" effect="dark" :content="`填充${typeName}标识与实例对应规则`" placement="left">
+            <el-button size="small" type="primary" @click="toAddRelation" icon="el-icon-edit-outline" style="float:right;" :disabled="isPending"></el-button>
           </el-tooltip>
         </el-col>
       </el-row>
     </div>
     <el-row>
-      <el-col :span="12" style="padding-left:10px;font-size:13px;border-left:2px solid #000;">点位表中出现的所有部件</el-col>
-      <el-col :span="12" style="padding-left:10px;font-size:13px;border-left:2px solid #000;">对应物理世界中的部件实例</el-col>
+      <el-col :span="12" style="padding-left:10px;font-size:13px;border-left:2px solid #000;">点位表中出现的所有{{typeName}}</el-col>
+      <el-col :span="12" style="padding-left:10px;font-size:13px;border-left:2px solid #000;">对应物理世界中的{{typeName}}实例</el-col>
     </el-row>
     <!-- 列表区域 -->
     <div class="table-area">
-      <el-table :data="tableData" style="width: 100%" height="100%" v-loading="loading" :header-cell-style="{background:'#f7f9fb'}">
-        <el-table-column prop="EquipmentMark" label="部件标识" show-overflow-tooltip min-width="100"></el-table-column>
+      <el-table :data="tableData" style="width: 100%" height="100%" v-loading="loading" :header-cell-style="headerStyle">
+        <el-table-column prop="EquipmentMark" :label="`${typeName}标识`" show-overflow-tooltip min-width="100"></el-table-column>
         <el-table-column prop="LocationFlag" label="位置标签" min-width="200">
           <template slot-scope="scope">
             <el-tooltip :content="scope.row.LocationFlag.toString()" placement="top">
-              <span>{{scope.row.LocationFlag.toString()}}</span>
+              <div class="tool-tip">{{scope.row.LocationFlag.toString()}}</div>
             </el-tooltip>
           </template>
         </el-table-column>
         <el-table-column prop="Datasource" label="数据源" show-overflow-tooltip min-width="100"></el-table-column>
-        <el-table-column prop="SubTypeName" label="数字字典部件类型" show-overflow-tooltip min-width="100"></el-table-column>
-        <el-table-column prop="EquipLocalName" label="对应的部件实例" show-overflow-tooltip min-width="100" class-name="td-bl"></el-table-column>
-        <el-table-column prop="FloorLocalName" label="实例所在建筑楼层" show-overflow-tooltip min-width="100"></el-table-column>
-        <el-table-column prop="RoomLocalName" label="实例所在业务空间" show-overflow-tooltip min-width="200"></el-table-column>
+        <el-table-column prop="SubTypeName" :label="`${typeName}类型`" show-overflow-tooltip min-width="100"></el-table-column>
+        <el-table-column prop="ObjectLocalName" :label="`${typeName}实例`" show-overflow-tooltip min-width="100" class-name="td-bl"></el-table-column>
+        <el-table-column label="所在建筑楼层" min-width="100">
+          <template slot-scope="scope">
+            <el-tooltip :content="scope.row.BuildLocalName?scope.row.FloorLocalName?scope.row.BuildLocalName+'-'+scope.row.FloorLocalName:scope.row.BuildLocalName:''"
+              placement="top">
+              <div class="tool-tip">{{scope.row.BuildLocalName?scope.row.FloorLocalName?scope.row.BuildLocalName+'-'+scope.row.FloorLocalName:scope.row.BuildLocalName:''}}
+              </div>
+            </el-tooltip>
+          </template>
+        </el-table-column>
+        <el-table-column prop="RoomLocalName" label="所在业务空间" show-overflow-tooltip min-width="100"></el-table-column>
+        <el-table-column prop="CascadeEquipLocalName" label="所属设备实例" show-overflow-tooltip min-width="100"></el-table-column>
         <el-table-column prop="action" label="操作" min-width="100">
           <template slot-scope="scope">
             <el-tooltip class="item" effect="dark" content="清除对应规则" placement="left">
-              <el-button size="mini" @click="handleDelete(scope.$index, scope.row)" type="danger" plain :disabled="scope.row.Related=='False'"
+              <el-button size="mini" @click="handleDelete(scope.$index, scope.row)" type="danger" plain :disabled="isPending||scope.row.Related=='False'"
                 icon="el-icon-delete"></el-button>
             </el-tooltip>
           </template>
@@ -71,7 +77,7 @@
       :current-page="page.pageNumber" :page-sizes="page.pageSizes" :page-size="page.pageSize" layout="total, sizes, prev, pager, next, jumper"
       :total="page.total"></el-pagination>
     <!-- 清除对应关系弹窗 -->
-    <del-relation-dialog ref="del" @refresh="refresh"></del-relation-dialog>
+    <del-relation-dialog ref="del" @refresh="refresh" :typeName="'parts'"></del-relation-dialog>
   </div>
 </template>
 <script>
@@ -96,6 +102,11 @@ export default {
   },
   data() {
     return {
+      headerStyle: {
+        backgroundColor: '#e1e4e5',
+        color: '#2b2b2b',
+        lineHeight: '30px'
+      },
       sourceList: [], //数据源
       DynEquipList: [], //数据字典部件类型
       LocFlagList: [], //位置标签
@@ -123,7 +134,10 @@ export default {
     locationFlag
   },
   props: {
-    typeName: {}
+    typeName: {},
+    isPending: {
+      default: false
+    }
   },
   created() {
     this.init();
@@ -132,7 +146,6 @@ export default {
   methods: {
     //获取查询条件-提示信息
     init() {
-      alert(1)
       this.getTableData()
     },
     //清除对应关系
@@ -151,7 +164,7 @@ export default {
     },
     //跳转至填充对应规则
     toAddRelation() {
-      this.$router.push({ path: "equipRela", query: { typeName: this.typeName } });
+      this.$router.push({ path: "partsRela", query: { typeName: this.typeName } });
     },
     //获取表格数据
     getTableData() {
@@ -177,16 +190,15 @@ export default {
       // 查询对应关系(P1)
       dynamicQuery(param, res => {
         this.loading = false;
-        if (res.Result == "success") {
-          this.tableData = res.Content;
-          this.page.total = res.Total;
-        }
+        this.tableData = res.Content;
+        this.page.total = res.PageSize < 50 ? res.PageSize : res.Total;
       });
     },
     //刷新列表
     refresh() {
       this.page.pageNumber = 1;
-      this.getTypeNames();
+      this.$emit('refresh', this.typeName);
+      this.getTableData();
     },
     //数据字典部件类型修改
     changeDictionary(val) {
@@ -231,9 +243,13 @@ export default {
       margin-left: 10px;
     }
   }
+  /deep/ .special .el-input__inner {
+    width: 220px;
+  }
   /deep/ .table-area {
     width: 100%;
-    height: calc(100% - 125px);
+    height: calc(100% - 71px);
+    margin-bottom: 10px;
     td div {
       white-space: nowrap;
       text-overflow: ellipsis;
@@ -242,10 +258,11 @@ export default {
     .td-bl {
       border-left: 1px solid #ebeef5;
     }
-  }
-  .fr {
-    padding-top: 10px;
-    float: right;
+    .tool-tip {
+      white-space: nowrap;
+      overflow: hidden;
+      text-overflow: ellipsis;
+    }
   }
 }
 </style>

+ 269 - 0
src/components/point/dynamicdata/spaceRules.vue

@@ -0,0 +1,269 @@
+
+<template>
+  <div id="equipRules">
+    <!-- 查询条件 -->
+    <div class="query-area">
+      <el-row>
+        <el-col :span="23">
+          <el-form ref="form" :model="form" :inline="true">
+            <el-row>
+              <div class="query-item special">
+                <el-input :placeholder="`请输入${typeName}标识关键字`" v-model="form.EquipmentMark" @keyup.enter.native="queryTableData">
+                  <i slot="suffix" class="el-input__icon el-icon-search" @click="queryTableData"></i>
+                </el-input>
+              </div>
+              <div class="query-item">
+                <label style="padding-right:9px">数据源</label>
+                <dataSource :Related="null" @change="changeDataSource" :typeName="typeName"></dataSource>
+              </div>
+              <div class="query-item">
+                <dictionary-device @change="changeDictionary" :Related="null" :typeName="typeName"></dictionary-device>
+              </div>
+              <div class="query-item">
+                <label style="padding-right:9px">位置标签</label>
+                <locationFlag :Related="null" @change="changeLocationFlag" :typeName="typeName"></locationFlag>
+              </div>
+            </el-row>
+          </el-form>
+        </el-col>
+        <el-col :span="1">
+          <el-tooltip class="item" effect="dark" :content="`填充${typeName}标识与实例对应规则`" placement="left">
+            <el-button size="small" type="primary" @click="toAddRelation" icon="el-icon-edit-outline" style="float:right;" :disabled="isPending"></el-button>
+          </el-tooltip>
+        </el-col>
+      </el-row>
+    </div>
+    <el-row>
+      <el-col :span="12" style="padding-left:10px;font-size:13px;border-left:2px solid #000;">点位表中出现的所有{{typeName}}</el-col>
+      <el-col :span="12" style="padding-left:10px;font-size:13px;border-left:2px solid #000;">对应物理世界中的{{typeName}}实例</el-col>
+    </el-row>
+    <!-- 列表区域 -->
+    <div class="table-area">
+      <el-table :data="tableData" style="width: 100%" height="100%" v-loading="loading" :header-cell-style="headerStyle">
+        <el-table-column prop="EquipmentMark" :label="`${typeName}标识`" show-overflow-tooltip min-width="100"></el-table-column>
+        <el-table-column prop="LocationFlag" label="位置标签" min-width="200">
+          <template slot-scope="scope">
+            <el-tooltip :content="scope.row.LocationFlag.toString()" placement="top">
+              <div class="tool-tip">{{scope.row.LocationFlag.toString()}}</div>
+            </el-tooltip>
+          </template>
+        </el-table-column>
+        <el-table-column prop="Datasource" label="数据源" show-overflow-tooltip min-width="100"></el-table-column>
+        <el-table-column prop="SubTypeName" :label="`${typeName}类型`" show-overflow-tooltip min-width="100"></el-table-column>
+        <el-table-column prop="ObjectLocalName" :label="`${typeName}实例`" show-overflow-tooltip min-width="100" class-name="td-bl"></el-table-column>
+        <el-table-column label="所在建筑楼层" min-width="300">
+          <template slot-scope="scope">
+            <el-tooltip :content="scope.row.BuildLocalName?scope.row.FloorLocalName?scope.row.BuildLocalName+'-'+scope.row.FloorLocalName:scope.row.BuildLocalName:''"
+              placement="top">
+              <div class="tool-tip">{{scope.row.BuildLocalName?scope.row.FloorLocalName?scope.row.BuildLocalName+'-'+scope.row.FloorLocalName:scope.row.BuildLocalName:''}}
+              </div>
+            </el-tooltip>
+          </template>
+        </el-table-column>
+        <!-- <el-table-column prop="RoomLocalName" label="所在业务空间" show-overflow-tooltip min-width="100"></el-table-column>
+        <el-table-column prop="CascadeEquipLocalName" label="所属设备实例" show-overflow-tooltip min-width="100"></el-table-column> -->
+        <el-table-column prop="action" label="操作" min-width="100">
+          <template slot-scope="scope">
+            <el-tooltip class="item" effect="dark" content="清除对应规则" placement="left">
+              <el-button size="mini" @click="handleDelete(scope.$index, scope.row)" type="danger" plain :disabled="isPending||scope.row.Related=='False'"
+                icon="el-icon-delete"></el-button>
+            </el-tooltip>
+          </template>
+        </el-table-column>
+      </el-table>
+    </div>
+    <!-- 分页 -->
+    <el-pagination class="fr" v-show="tableData && tableData.length" @size-change="handleSizeChange" @current-change="handleCurrentChange"
+      :current-page="page.pageNumber" :page-sizes="page.pageSizes" :page-size="page.pageSize" layout="total, sizes, prev, pager, next, jumper"
+      :total="page.total"></el-pagination>
+    <!-- 清除对应关系弹窗 -->
+    <del-relation-dialog ref="del" @refresh="refresh" :typeName="'space'"></del-relation-dialog>
+  </div>
+</template>
+<script>
+import tools from "@/utils/tools";
+import { mapGetters, mapActions } from "vuex";
+import applyRulesDialog from "@/components/point/dynamicdata/applyRulesDialog";
+import delRelationDialog from "@/components/point/dynamicdata/delRelationDialog";
+import dictionaryDevice from "@/components/point/dynamicdata/dictionaryDevice";
+import dataSource from "@/components/point/dynamicdata/dataSource";
+import locationFlag from "@/components/point/dynamicdata/locationFlag";
+import equipRules from "@/components/point/dynamicdata/equipRules";
+import {
+  dynamicClashConfirm,
+  dynamicExecute,
+  dynamicQuery,
+  dynamicQueryPoint,
+  dynamicPointTypeList
+} from "@/api/scan/request";
+export default {
+  computed: {
+    ...mapGetters("layout", ["projectId"])
+  },
+  data() {
+    return {
+      headerStyle: {
+        backgroundColor: '#e1e4e5',
+        color: '#2b2b2b',
+        lineHeight: '30px'
+      },
+      sourceList: [], //数据源
+      DynEquipList: [], //数据字典部件类型
+      LocFlagList: [], //位置标签
+      tableData: [], //列表数据
+      page: {
+        pageSize: 50,
+        pageSizes: [10, 20, 50, 100],
+        pageNumber: 1,
+        total: 0
+      },
+      form: {
+        EquipmentMark: "", //部件标识关键字
+        SubTypeName: [], //数据字典部件类型
+        LocationFlag: [], //位置标签
+        Datasource: [] //数据源
+      }, //查询条件
+      loading: false, //列表loading
+    };
+  },
+  components: {
+    applyRulesDialog,
+    delRelationDialog,
+    dictionaryDevice,
+    dataSource,
+    locationFlag
+  },
+  props: {
+    typeName: {},
+    isPending: {
+      default: false
+    }
+  },
+  created() {
+    this.init();
+  },
+  mounted() { },
+  methods: {
+    //获取查询条件-提示信息
+    init() {
+      this.getTableData()
+    },
+    //清除对应关系
+    handleDelete(index, row) {
+      this.$refs.del.showDialog(row);
+    },
+    //改变pagesize
+    handleSizeChange(pageSize) {
+      this.page.pageSize = pageSize;
+      this.getTableData();
+    },
+    //改变pageno
+    handleCurrentChange(pageNo) {
+      this.page.pageNumber = pageNo;
+      this.getTableData();
+    },
+    //跳转至填充对应规则
+    toAddRelation() {
+      this.$router.push({ path: "spaceRela", query: { typeName: this.typeName } });
+    },
+    //获取表格数据
+    getTableData() {
+      let param = {
+        PageNumber: this.page.pageNumber,
+        PageSize: this.page.pageSize,
+        TypeNameList: [this.typeName]
+      };
+      //处理查询条件
+      if (this.form.EquipmentMark && this.form.EquipmentMark.length) {
+        param.EquipmentMark = this.form.EquipmentMark;
+      }
+      if (this.form.SubTypeName.length) {
+        param.SubTypeNameList = this.form.SubTypeName;
+      }
+      if (this.form.LocationFlag.length) {
+        param.LocationFlagList = this.form.LocationFlag;
+      }
+      if (this.form.Datasource.length) {
+        param.DatasourceList = this.form.Datasource;
+      }
+      this.loading = true;
+      // 查询对应关系(P1)
+      dynamicQuery(param, res => {
+        this.loading = false;
+        this.tableData = res.Content;
+        this.page.total = res.PageSize < 50 ? res.PageSize : res.Total;
+      });
+    },
+    //刷新列表
+    refresh() {
+      this.page.pageNumber = 1;
+      this.$emit('refresh', this.typeName);
+      this.getTableData();
+    },
+    //数据字典部件类型修改
+    changeDictionary(val) {
+      this.page.pageNumber = 1;
+      this.form.SubTypeName = val;
+      this.getTableData();
+    },
+    //数据源修改
+    changeDataSource(val) {
+      this.page.pageNumber = 1;
+      this.form.Datasource = val;
+      this.getTableData();
+    },
+    //修改位置标签
+    changeLocationFlag(val) {
+      this.page.pageNumber = 1;
+      this.form.LocationFlag = val;
+      this.getTableData();
+    },
+    //查询列表
+    queryTableData() {
+      this.page.pageNumber = 1;
+      this.getTableData();
+    }
+  },
+  watch: {
+    projectId() {
+      this.init();
+    }
+  }
+};
+</script>
+<style lang="scss" scoped>
+#equipRules {
+  height: calc(100% - 54px);
+  /deep/ .text-right {
+    text-align: right;
+  }
+  .query-item {
+    float: left;
+    & + .query-item {
+      margin-left: 10px;
+    }
+  }
+  /deep/ .special .el-input__inner {
+    width: 220px;
+  }
+  /deep/ .table-area {
+    width: 100%;
+    height: calc(100% - 71px);
+    margin-bottom: 10px;
+    td div {
+      white-space: nowrap;
+      text-overflow: ellipsis;
+      overflow: hidden;
+    }
+    .td-bl {
+      border-left: 1px solid #ebeef5;
+    }
+    .tool-tip {
+      white-space: nowrap;
+      overflow: hidden;
+      text-overflow: ellipsis;
+    }
+  }
+}
+</style>
+

+ 269 - 0
src/components/point/dynamicdata/systemRules.vue

@@ -0,0 +1,269 @@
+
+<template>
+  <div id="equipRules">
+    <!-- 查询条件 -->
+    <div class="query-area">
+      <el-row>
+        <el-col :span="23">
+          <el-form ref="form" :model="form" :inline="true">
+            <el-row>
+              <div class="query-item special">
+                <el-input :placeholder="`请输入${typeName}标识关键字`" v-model="form.EquipmentMark" @keyup.enter.native="queryTableData">
+                  <i slot="suffix" class="el-input__icon el-icon-search" @click="queryTableData"></i>
+                </el-input>
+              </div>
+              <div class="query-item">
+                <label style="padding-right:9px">数据源</label>
+                <dataSource :Related="null" @change="changeDataSource" :typeName="typeName"></dataSource>
+              </div>
+              <div class="query-item">
+                <dictionary-device @change="changeDictionary" :Related="null" :typeName="typeName"></dictionary-device>
+              </div>
+              <div class="query-item">
+                <label style="padding-right:9px">位置标签</label>
+                <locationFlag :Related="null" @change="changeLocationFlag" :typeName="typeName"></locationFlag>
+              </div>
+            </el-row>
+          </el-form>
+        </el-col>
+        <el-col :span="1">
+          <el-tooltip class="item" effect="dark" :content="`填充${typeName}标识与实例对应规则`" placement="left">
+            <el-button size="small" type="primary" @click="toAddRelation" icon="el-icon-edit-outline" style="float:right;" :disabled="isPending"></el-button>
+          </el-tooltip>
+        </el-col>
+      </el-row>
+    </div>
+    <el-row>
+      <el-col :span="12" style="padding-left:10px;font-size:13px;border-left:2px solid #000;">点位表中出现的所有{{typeName}}</el-col>
+      <el-col :span="12" style="padding-left:10px;font-size:13px;border-left:2px solid #000;">对应物理世界中的{{typeName}}实例</el-col>
+    </el-row>
+    <!-- 列表区域 -->
+    <div class="table-area">
+      <el-table :data="tableData" style="width: 100%" height="100%" v-loading="loading" :header-cell-style="headerStyle">
+        <el-table-column prop="EquipmentMark" :label="`${typeName}标识`" show-overflow-tooltip min-width="100"></el-table-column>
+        <el-table-column prop="LocationFlag" label="位置标签" min-width="200">
+          <template slot-scope="scope">
+            <el-tooltip :content="scope.row.LocationFlag.toString()" placement="top">
+              <div class="tool-tip">{{scope.row.LocationFlag.toString()}}</div>
+            </el-tooltip>
+          </template>
+        </el-table-column>
+        <el-table-column prop="Datasource" label="数据源" show-overflow-tooltip min-width="100"></el-table-column>
+        <el-table-column prop="SubTypeName" :label="`${typeName}类型`" show-overflow-tooltip min-width="100"></el-table-column>
+        <el-table-column prop="ObjectLocalName" :label="`${typeName}实例`" show-overflow-tooltip min-width="400" class-name="td-bl"></el-table-column>
+        <!-- <el-table-column label="所在建筑楼层" min-width="100">
+          <template slot-scope="scope">
+            <el-tooltip :content="scope.row.BuildLocalName?scope.row.FloorLocalName?scope.row.BuildLocalName+'-'+scope.row.FloorLocalName:scope.row.BuildLocalName:''"
+              placement="top">
+              <div class="tool-tip">{{scope.row.BuildLocalName?scope.row.FloorLocalName?scope.row.BuildLocalName+'-'+scope.row.FloorLocalName:scope.row.BuildLocalName:''}}
+              </div>
+            </el-tooltip>
+          </template>
+        </el-table-column>
+        <el-table-column prop="RoomLocalName" label="所在业务空间" show-overflow-tooltip min-width="100"></el-table-column>
+        <el-table-column prop="CascadeEquipLocalName" label="所属设备实例" show-overflow-tooltip min-width="100"></el-table-column> -->
+        <el-table-column prop="action" label="操作" min-width="100">
+          <template slot-scope="scope">
+            <el-tooltip class="item" effect="dark" content="清除对应规则" placement="left">
+              <el-button size="mini" @click="handleDelete(scope.$index, scope.row)" type="danger" plain :disabled="isPending||scope.row.Related=='False'"
+                icon="el-icon-delete"></el-button>
+            </el-tooltip>
+          </template>
+        </el-table-column>
+      </el-table>
+    </div>
+    <!-- 分页 -->
+    <el-pagination class="fr" v-show="tableData && tableData.length" @size-change="handleSizeChange" @current-change="handleCurrentChange"
+      :current-page="page.pageNumber" :page-sizes="page.pageSizes" :page-size="page.pageSize" layout="total, sizes, prev, pager, next, jumper"
+      :total="page.total"></el-pagination>
+    <!-- 清除对应关系弹窗 -->
+    <del-relation-dialog ref="del" @refresh="refresh" :typeName="'system'"></del-relation-dialog>
+  </div>
+</template>
+<script>
+import tools from "@/utils/tools";
+import { mapGetters, mapActions } from "vuex";
+import applyRulesDialog from "@/components/point/dynamicdata/applyRulesDialog";
+import delRelationDialog from "@/components/point/dynamicdata/delRelationDialog";
+import dictionaryDevice from "@/components/point/dynamicdata/dictionaryDevice";
+import dataSource from "@/components/point/dynamicdata/dataSource";
+import locationFlag from "@/components/point/dynamicdata/locationFlag";
+import equipRules from "@/components/point/dynamicdata/equipRules";
+import {
+  dynamicClashConfirm,
+  dynamicExecute,
+  dynamicQuery,
+  dynamicQueryPoint,
+  dynamicPointTypeList
+} from "@/api/scan/request";
+export default {
+  computed: {
+    ...mapGetters("layout", ["projectId"])
+  },
+  data() {
+    return {
+      headerStyle: {
+        backgroundColor: '#e1e4e5',
+        color: '#2b2b2b',
+        lineHeight: '30px'
+      },
+      sourceList: [], //数据源
+      DynEquipList: [], //数据字典部件类型
+      LocFlagList: [], //位置标签
+      tableData: [], //列表数据
+      page: {
+        pageSize: 50,
+        pageSizes: [10, 20, 50, 100],
+        pageNumber: 1,
+        total: 0
+      },
+      form: {
+        EquipmentMark: "", //部件标识关键字
+        SubTypeName: [], //数据字典部件类型
+        LocationFlag: [], //位置标签
+        Datasource: [] //数据源
+      }, //查询条件
+      loading: false, //列表loading
+    };
+  },
+  components: {
+    applyRulesDialog,
+    delRelationDialog,
+    dictionaryDevice,
+    dataSource,
+    locationFlag
+  },
+  props: {
+    typeName: {},
+    isPending: {
+      default: false
+    }
+  },
+  created() {
+    this.init();
+  },
+  mounted() { },
+  methods: {
+    //获取查询条件-提示信息
+    init() {
+      this.getTableData()
+    },
+    //清除对应关系
+    handleDelete(index, row) {
+      this.$refs.del.showDialog(row);
+    },
+    //改变pagesize
+    handleSizeChange(pageSize) {
+      this.page.pageSize = pageSize;
+      this.getTableData();
+    },
+    //改变pageno
+    handleCurrentChange(pageNo) {
+      this.page.pageNumber = pageNo;
+      this.getTableData();
+    },
+    //跳转至填充对应规则
+    toAddRelation() {
+      this.$router.push({ path: "systemRela", query: { typeName: this.typeName } });
+    },
+    //获取表格数据
+    getTableData() {
+      let param = {
+        PageNumber: this.page.pageNumber,
+        PageSize: this.page.pageSize,
+        TypeNameList: [this.typeName]
+      };
+      //处理查询条件
+      if (this.form.EquipmentMark && this.form.EquipmentMark.length) {
+        param.EquipmentMark = this.form.EquipmentMark;
+      }
+      if (this.form.SubTypeName.length) {
+        param.SubTypeNameList = this.form.SubTypeName;
+      }
+      if (this.form.LocationFlag.length) {
+        param.LocationFlagList = this.form.LocationFlag;
+      }
+      if (this.form.Datasource.length) {
+        param.DatasourceList = this.form.Datasource;
+      }
+      this.loading = true;
+      // 查询对应关系(P1)
+      dynamicQuery(param, res => {
+        this.loading = false;
+        this.tableData = res.Content;
+        this.page.total = res.PageSize < 50 ? res.PageSize : res.Total;
+      });
+    },
+    //刷新列表
+    refresh() {
+      this.page.pageNumber = 1;
+      this.$emit('refresh', this.typeName);
+      this.getTableData();
+    },
+    //数据字典部件类型修改
+    changeDictionary(val) {
+      this.page.pageNumber = 1;
+      this.form.SubTypeName = val;
+      this.getTableData();
+    },
+    //数据源修改
+    changeDataSource(val) {
+      this.page.pageNumber = 1;
+      this.form.Datasource = val;
+      this.getTableData();
+    },
+    //修改位置标签
+    changeLocationFlag(val) {
+      this.page.pageNumber = 1;
+      this.form.LocationFlag = val;
+      this.getTableData();
+    },
+    //查询列表
+    queryTableData() {
+      this.page.pageNumber = 1;
+      this.getTableData();
+    }
+  },
+  watch: {
+    projectId() {
+      this.init();
+    }
+  }
+};
+</script>
+<style lang="scss" scoped>
+#equipRules {
+  height: calc(100% - 54px);
+  /deep/ .text-right {
+    text-align: right;
+  }
+  .query-item {
+    float: left;
+    & + .query-item {
+      margin-left: 10px;
+    }
+  }
+  /deep/ .special .el-input__inner {
+    width: 220px;
+  }
+  /deep/ .table-area {
+    width: 100%;
+    height: calc(100% - 71px);
+    margin-bottom: 10px;
+    td div {
+      white-space: nowrap;
+      text-overflow: ellipsis;
+      overflow: hidden;
+    }
+    .td-bl {
+      border-left: 1px solid #ebeef5;
+    }
+    .tool-tip {
+      white-space: nowrap;
+      overflow: hidden;
+      text-overflow: ellipsis;
+    }
+  }
+}
+</style>
+

+ 33 - 0
src/components/ready/buildfloor/addBuild.vue

@@ -0,0 +1,33 @@
+<template>
+  <el-dialog :title="buildTitle" :visible.sync="buildDialogVis" width="20%" id="messageDialog">
+    <div>
+      <label>建筑名称 : </label>
+      <el-input placeholder="请输入建筑名称" v-model="buildName"></el-input>
+    </div>
+    <span slot="footer" class="dialog-footer">
+      <el-button size="small">取消</el-button>
+      <el-button size="small" type="primary" @click="save">确认</el-button>
+    </span>
+  </el-dialog>
+</template>
+<script>
+export default {
+  data() {
+    return {
+      buildName: '',
+      buildDialogVis: false
+    }
+  },
+  props: {
+    buildTitle: {
+      default: "添加建筑"
+    }
+  },
+  methods: {
+    showDialog() {
+      this.buildDialogVis = true
+    },
+    save() { }
+  }
+}
+</script>

+ 80 - 0
src/components/ready/buildfloor/addConnectivity.vue

@@ -0,0 +1,80 @@
+<template>
+  <el-dialog title="楼层贯通关系维护" :visible.sync="connectDialogVis" width="50%" id="messageDialog">
+    <el-row>
+      <div style="line-height:32px;">添加与{{floor.FloorLocalName}}层有贯通关系的楼层 : </div>
+      <div style="width:70%">
+        <bfCascader ref="bfCascader" :FloorID="floor.FloorID"></bfCascader>
+      </div>
+    </el-row>
+    <span slot="footer" class="dialog-footer">
+      <el-button size="small" @click="connectDialogVis=false">取消</el-button>
+      <el-button size="small" type="primary" @click="save">确认</el-button>
+    </span>
+  </el-dialog>
+</template>
+<script>
+import bfCascader from '@/components/ready/buildfloor/buildfloorCascader'
+import { createRelationInFloor } from "@/api/scan/request";
+export default {
+  data() {
+    return {
+      buildName: '',
+      connectDialogVis: false,
+      floor: {}
+    }
+  },
+  components: {
+    bfCascader
+  },
+  methods: {
+    showDialog() {
+      this.connectDialogVis = true
+      this.$nextTick(() => {
+        this.$refs.bfCascader.getCascader()
+        let arr = this.floor.FloorThroughList || [];
+        let value = []
+        if (arr.length) {
+          arr.map(t => {
+            value.push([t.BuildID, t.FloorID])
+          })
+        }
+        this.$refs.bfCascader.value = value
+      })
+    },
+    save() {
+      let arr = this.$refs.bfCascader.value;
+      let param = {
+        FloorId: this.floor.FloorID,
+        FloorOtherIdList: []
+      }
+      arr.map(t => {
+        param.FloorOtherIdList.push(t[1])
+      })
+      createRelationInFloor(param, res => {
+        this.connectDialogVis = false;
+        this.$message.success('关联成功');
+        this.$emit('refresh')
+      })
+    }
+  }
+}
+</script>
+<style lang="less" scoped>
+#messageDialog {
+  .el-row{
+    height: 50px;
+    max-height: 200px;
+    overflow-y: auto;
+    overflow-x: hidden;
+  }
+  .el-row > div {
+    float: left;
+  }
+  .el-row > div + div {
+    margin-left: 10px;
+  }
+  /deep/ .el-input__inner {
+    vertical-align: baseline;
+  }
+}
+</style>

+ 55 - 0
src/components/ready/buildfloor/buildfloorCascader.vue

@@ -0,0 +1,55 @@
+<template>
+  <el-cascader v-model="value" :options="options" :props="props" clearable></el-cascader>
+</template>
+<script>
+import { buildingQuery } from "@/api/scan/request";
+export default {
+  data() {
+    return {
+      value: [],
+      props: {
+        multiple: true,
+        value: 'BuildID',
+        label: 'BuildLocalName',
+        children: 'Floor'
+      },
+      options: []
+    }
+  },
+  props: {
+    FloorID: {
+      default: ''
+    }
+  },
+  created() { },
+  methods: {
+    getCascader() {
+      let param = {
+        Cascade: [
+          { Name: "floor" }
+        ],
+        PageNumber: 1,
+        PageSize: 50
+      }
+      buildingQuery(param, res => {
+        res.Content.map(t => {
+          if (t.Floor && t.Floor.length) {
+            t.Floor = t.Floor.map(item => {
+              if (item.FloorID == this.FloorID) return
+              item.BuildID = item.FloorID
+              item.BuildLocalName = item.FloorLocalName || item.FloorName
+              return item
+            }).filter(it => it)
+          }
+        })
+        this.options = res.Content
+      })
+    },
+  }
+}
+</script>
+<style lang="less" scoped>
+.el-cascader {
+  width: 100%;
+}
+</style>

+ 94 - 0
src/components/ready/buildfloor/formItems.vue

@@ -0,0 +1,94 @@
+<template>
+  <div id="inforsPoint">
+    <el-form ref="ruleForm" :model="form" label-width="150px" :rules="rules" :inline="true" :label-position="'left'">
+      <div v-for="item in InforsList" :key="item.InfoPointCode" style="width:50%;float:left;">
+        <el-form-item :label="item.InfoPointName" :prop="item.InfoPointCode" v-if="all||item.Visible"
+          :class="{FloorTypeSelect:item.InputMode == 'D1'||item.Unit}">
+          <el-input v-model="form[item.Path]" v-if="item.InputMode == 'B1'"></el-input>
+          <el-input v-model="form[item.Path]" v-else-if="item.InputMode == 'A1'||item.InputMode == 'A2'" type="number">
+            <template slot="append" v-if="item.Unit">{{item.Unit}}</template>
+          </el-input>
+          <el-select v-model="form[item.Path]" placeholder="请选择" v-else-if="item.InputMode == 'D1'">
+            <el-option v-for="op in item.options" :key="op.Code" :label="op.Name" :value="op.Code"></el-option>
+          </el-select>
+          <el-input v-model="form[item.Path]"
+            v-else-if="item.InputMode == 'L'||item.InputMode == 'L1'||item.InputMode == 'L2'||item.InputMode == 'M'">
+            <template slot="append" v-if="item.Unit">{{item.Unit}}</template>
+          </el-input>
+          <el-input v-model="form[item.Path]" v-else disabled title="暂不支持"></el-input>
+        </el-form-item>
+      </div>
+    </el-form>
+  </div>
+</template>
+<script>
+import { getDataDictionary } from "@/api/scan/request";
+
+//  v-for="item in InforsList" :key="item.InfoPointCode"
+export default {
+  props: {
+    type: {
+      default: 'Floor'
+    }
+  },
+  data() {
+    return {
+      form: {},
+      InforsList: [],
+      all: true, // 默认显示全部
+      rules: {
+        "FloorLocalName": [
+          { "required": true, "message": "请输入楼层本地名称", "trigger": "blur" }
+        ],
+        "FloorSequenceID": [
+          { "required": true, "message": "请输入楼层顺序号", "trigger": "blur" }
+        ]
+      }
+    };
+  },
+  created() {
+    this.getInforsPoint()
+  },
+  methods: {
+    getInforsPoint() {
+      let params = {
+        data: {
+          Orders: "sort asc,InfoPointCode asc",
+          PageNumber: 1,
+          PageSize: 50
+        },
+        type: this.type
+      };
+      getDataDictionary(params, res => {
+        this.InforsList = res.Content.map(item => {
+          if (item.InputMode === 'D1') {
+            item.options = JSON.parse(item.DataSource)
+          }
+          return item
+        })
+      })
+    },
+    submitForm(call) {
+      this.$refs.ruleForm.validate((valid) => {
+        if (valid) {
+          call()
+        } else {
+          return false;
+        }
+      });
+    },
+  }
+};
+</script>
+<style lang="scss" scoped>
+#inforsPoint {
+  .el-form-item {
+    /deep/ label.el-form-item__label {
+      font-size: 12px;
+    }
+  }
+  /deep/ .FloorTypeSelect .el-form-item__content {
+    width: 200px;
+  }
+}
+</style>

+ 151 - 0
src/framework/components/messagesever/index.vue

@@ -0,0 +1,151 @@
+<!--
+ * @Author: zhangyu
+ * @Date: 2019-08-26 15:22:13
+ * @Info: 
+ * @LastEditTime: 2019-09-26 20:16:41
+ -->
+<template>
+  <div class="notification-box" @click="handleClickRead">
+    <el-badge :value="unreadNum" :hidden="!unreadNum" :max="99">
+      <i class="el-icon-message-solid"></i>
+    </el-badge>
+    <!-- <el-button type="primary" @click="handleClickConnectMQ">连接MQ</el-button>
+    <el-button type="primary" @click="handleClickDisconnectMQ">断开MQ</el-button>
+    <el-button type="primary" @click="handleClickUnsubscribe">停止接收消息</el-button><br><br>
+    <el-input type="textarea" :autosize="{ minRows: 6, maxRows: 6}" v-model="sendMessage" placeholder="请输入要发送的内容"></el-input>
+    <br><br>
+    <el-button type="primary" @click="handleClickSendMessage">发送消息</el-button>
+    <el-card style="margin-top:20px;text-align:left;">
+      <div slot="header" class="clearfix">
+        <span>消息历史</span>
+      </div>
+      <div v-for="(message, index) in messageList" :key="index" class="text item">
+        {{ message }}
+      </div>
+    </el-card> -->
+  </div>
+</template>
+
+<script>
+import { mapGetters } from 'vuex'
+import Stomp from 'stompjs'
+import Msmq from './msmq'
+import { MQTT_SERVICE, MQTT_USERNAME, MQTT_PASSWORD } from './mqSetting'
+
+export default {
+  data() {
+    return {
+      client: Stomp.client(MQTT_SERVICE),
+      unreadNum: 0,
+      sendMessage: '',
+      messageList: [], // 历史消息
+      subList: [], // 订阅的消息实例
+      topics: ["/topic/model.manage"] // 订阅的消息名称
+    }
+  },
+  created () {
+    this.connect()
+    // let url = "ws://192.168.20.225:61614/stomp";
+    // let login = "admin";
+    // let passcode = "admin";
+    // let destination = "/topic/datacenter.broadcast";
+    // let client = Stomp.client(url)
+    // console.log('钩子:',client)
+    // var onconnect = function(frame) {
+    //   client.subscribe(destination, function(message) {
+    //     console.log(message.body);
+    //     alert(message.body);        
+    //   });
+    // };
+    // client.connect(login, passcode, onconnect)
+  },
+  computed: {
+    ...mapGetters('layout', ['userInfo', 'projectId', 'projects'])
+  },
+  methods:{
+    connect() {
+      this.client = Stomp.client(MQTT_SERVICE)
+      this.client.reconnect_delay = 5000
+      var clientid = `sagaMQ-${this.userInfo.userName}`
+      var headers = {
+        'login': MQTT_USERNAME,
+        'passcode': MQTT_PASSWORD,
+        'client-id': clientid
+      }
+      this.client.connect(headers, this.onConnected, this.onFailed)
+    },
+    onConnected(frame) {
+      console.log('Connected: ' + frame)
+      //订阅多个消息
+      this.topics.forEach(item => {
+        let sub = this.client.subscribe(item, this.onmessage, this.onFailed)
+        this.subList.push(sub)
+      })
+      // this.client.subscribe(topic, this.onmessage, this.onFailed) 
+    },
+    //接收到消息的回调
+    onmessage(message) {
+      this.unreadNum = Msmq.handleMsg(message, this.projects, this.unreadNum);
+    },
+    // 接收消息失败回调
+    onFailed(frame) {
+      console.log('Failed: ' + frame)
+    },
+    //停止接收消息
+    unsubscribe() {
+      this.subList.forEach((item) => {
+        item.unsubscribe()
+      })
+    },
+    //断开连接
+    disconnect() {
+      this.client.disconnect(function() {
+        console.log("连接已断开!");
+      })
+    },
+    //发送消息
+    send(destination, message, headers = {}) {
+      this.client.send(destination, headers, JSON.stringify(message))
+    },
+    
+    handleClickConnectMQ() {
+      this.connect()
+    },
+    handleClickDisconnectMQ() {
+      this.disconnect()
+    },
+    handleClickUnsubscribe() {
+      this.unsubscribe()
+    },
+    handleClickSendMessage() {
+      this.send('/topic/datacenter.broadcast',this.sendMessage)
+    }, 
+    handleClickRead() {
+      this.unreadNum = 0;
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+  .notification-box{
+    width: 100%;
+    height: 100%;
+    padding: 16px 10px 10px;
+    box-sizing: border-box;
+    color: #79869a;
+    cursor: pointer;
+    .el-icon-message-solid{
+      font-size: 22px;
+    }
+    /deep/ .el-badge__content{
+      height: 16px;
+      line-height: 16px;
+      border: 1px solid transparent;
+    }
+  }
+  .notification-box:hover{
+    color: #d3d8e2;
+    background-color: #3f4f62;
+  }
+</style>

+ 9 - 0
src/framework/components/messagesever/mqSetting.js

@@ -0,0 +1,9 @@
+/*
+ * @Author: zhangyu
+ * @Date: 2019-08-26 16:03:46
+ * @Info: 
+ * @LastEditTime: 2019-09-05 14:46:30
+ */
+export const MQTT_SERVICE = process.env.MQTT_SERVICE // mq服务地址
+export const MQTT_USERNAME = 'admin' // mq连接用户名
+export const MQTT_PASSWORD = 'admin' // mq连接密码

+ 22 - 0
src/framework/components/messagesever/msmq.js

@@ -0,0 +1,22 @@
+import { Notification } from 'element-ui';
+import Bus from '@/utils/bus.js'
+
+const MSMQ = {
+  handleMsg (message, projects, unreadNum ) {
+    let data
+    try {
+      data = JSON.parse(message.body)
+    } catch (err) {}
+    // if(projects.some((item) => {return item.id == data.projectId})) { //判断消息是否是当前用户拥有的项目
+      unreadNum++
+      if(message.headers.destination == '/topic/model.manage'){ //模型文件的消息触发模型文件列表刷新事件
+        Bus.$emit('modelStatusChange', data)
+      }
+      // Notification.info({ title: '消息',dangerouslyUseHTMLString: true, message: `项目编号:${data.projectId}<br>消息类型:${data.type}<br>描述信息:${data.description}<br>` })
+      Notification.info({ title: '消息', dangerouslyUseHTMLString: true, message: `${JSON.stringify(data)}` })
+      return unreadNum
+    // }
+  }
+}
+
+export default MSMQ

+ 19 - 3
src/framework/layout/PageHeader.vue

@@ -18,7 +18,7 @@
         <div id='page-header-user-menu' class='user-menu'>
             <el-dropdown trigger='hover' class='user-menu-dropdown' @command='userMenuCommand'>
                 <span class='el-dropdown-link'>
-                    {{userInfo.username}}
+                    {{userInfo.userName}}
                     <i class='el-icon-fa-user el-icon--right'></i>
                 </span>
                 <el-dropdown-menu slot='dropdown'>
@@ -26,12 +26,18 @@
                     <el-dropdown-item icon='el-icon-circle-plus'>修改密码</el-dropdown-item>
                 </el-dropdown-menu>
             </el-dropdown>
+            <ul class="header-nav">
+                <li class="header-nav-notification">
+                    <message-sever></message-sever>
+                </li>
+            </ul>
         </div>
     </div>
 </template>
 <script>
 import frameworkApi from '@/api/framework'
 import { mapGetters, mapMutations } from 'vuex'
+import MessageSever from '../components/messagesever/index'
 export default {
     name: 'PageHeader',
     props: [],
@@ -66,9 +72,19 @@ export default {
         }
     },
     created() {
-        this.selectedProjectId = this.projectId
+        let cacheInfo = JSON.parse(localStorage.getItem('_sagacloud_admin_store_cacheInfo'))?JSON.parse(localStorage.getItem('_sagacloud_admin_store_cacheInfo')):{}
+        if(cacheInfo[this.userInfo.userName] && 
+            cacheInfo[this.userInfo.userName].projectId && 
+            this.projects.some((item) => {return item.id == cacheInfo[this.userInfo.userName].projectId})
+        ){
+            this.selectedProjectId = cacheInfo[this.userInfo.userName].projectId
+        } else {
+            this.selectedProjectId = this.projectId
+        }
     },
     mounted() {},
-    components: {}
+    components: {
+        MessageSever
+    }
 }
 </script>

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

@@ -17,8 +17,8 @@ export default {
         projectId: '',
         projects: [],
         breadcrumb: [],
-        secret: "", //密码
-        userId: "test", //用户id
+        secret: "", //项目密码
+        userId: "", //用户id
     },
     getters: {
         sidebarClosed: state => state.sidebarClosed,
@@ -63,8 +63,16 @@ export default {
             storage.set(KEY_MENU_SELECTED, val)
         },
         setprojectId: (state, val) => {
+            let cacheInfo = JSON.parse(localStorage.getItem('_sagacloud_admin_store_cacheInfo'))?JSON.parse(localStorage.getItem('_sagacloud_admin_store_cacheInfo')):{}
             state.projectId = val
             localStorage.setItem('projectId', val)
+            if(cacheInfo[state.userInfo.userName]){
+                cacheInfo[state.userInfo.userName].projectId = val
+                localStorage.setItem('_sagacloud_admin_store_cacheInfo', JSON.stringify(cacheInfo))
+            } else {
+                cacheInfo[state.userInfo.userName] = {projectId: val}
+                localStorage.setItem('_sagacloud_admin_store_cacheInfo', JSON.stringify(cacheInfo))
+            }
             storage.set(KEY_PROJECT_SELECTED, val)
             state.projects.map((item) =>{
                 if(item.id == val) {
@@ -80,7 +88,10 @@ export default {
                 frameworkApi.loadUserInfo().then(resp => {
                     console.log(resp)
                     if (resp.Result == 'success') {
-                        state.userInfo = { username: resp.Username }
+                        state.userInfo = { userName: resp.Username, userId: resp.UserId }
+                        state.userId = resp.UserId
+                        storage.set('user_name', resp.Username)
+                        storage.set('user_id', resp.UserId)
                         state.permissions = {}
                         if (resp.Permissions) {
                             resp.Permissions.forEach(p => (state.permissions[p] = true))

+ 10 - 0
src/framework/style/layout.scss

@@ -114,6 +114,16 @@ body {
         height: 100%;
         display: inline-flex;
         flex-direction: row-reverse;
+        .header-nav{
+            margin-right: 10px;
+            >li{
+                float: left;
+                width: 50px;
+                height: 50px;
+                padding: 0 4px;
+                box-sizing: border-box;
+            }
+        }
         .user-menu-dropdown {
             height: 100%;
             line-height: $pageHeaderHeight;

+ 60 - 14
src/router/system.js

@@ -16,6 +16,7 @@ import roleAdm from '@/views/platfrom/role'
 import buildFloor from '@/views/ready/buildfloor'
 import collectsetting from '@/views/ready/collectsetting'
 import buildUser from '@/views/ready/appuser'
+import repetitionGraphy from '@/views/ready/buildfloor/repetitionGraphy'
 
 /**模型管理 */
 import modelFile from '@/views/model/file'
@@ -29,6 +30,9 @@ import objectData from '@/views/point/objectData'
 import integrateReport from '@/views/point/report'
 import dynamicdata from '@/views/point/dynamicdata'
 import equipRela from '@/views/point/dynamicdata/addRelation/equipRela'
+import partsRela from '@/views/point/dynamicdata/addRelation/partsRela'
+import systemRela from '@/views/point/dynamicdata/addRelation/systemRela'
+import spaceRela from '@/views/point/dynamicdata/addRelation/spaceRela'
 
 /** 扫楼作业 */
 import buildTask from '@/views/data_admin/buildTask'
@@ -49,13 +53,16 @@ import propertyadd from '@/views/ledger/property/addproperty'
 import propertyLedger from '@/views/ledger/property'
 import spacelist from '@/views/ledger/spacelist'//业务空间台账
 import addPropertys from '@/views/ledger/property/addpropertys'//根据未关联资产的设备或部件批量创建设备
+import batchlinkAssets from '@/views/ledger/facility/batchlink' //批量关联资产
 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 rentadd from '@/views/ledger/rentlist/rentadd' //竖井清单
+import rentadd from '@/views/ledger/rentlist/rentadd' //租户清单
 import dataReport from '@/views/ledger/report'
 import auth from '@/views/system/auth'
 import noUser from '@/views/system/nouser'
+import spaceDetail from '@/views/ledger/spacelist/spaceDetail'
 
 /**  关系维护并计算 */
 import maintain from '@/views/relation/maintain'
@@ -66,7 +73,7 @@ import supplier from '@/views/manufactor/supplier'
 
 /**市场及商务 */
 const OwnerManage = () =>
-    import ('@/views/market/owner/manage')
+    import('@/views/market/owner/manage')
 
 export default [
     { path: '/', name: '', component: LayoutMain, children: [{ path: '', name: 'blank', component: Dasboard }] },
@@ -79,10 +86,10 @@ export default [
         name: 'LayoutMain',
         component: LayoutMain,
         children: [
-            { path: 'project', name: 'projectAdm', component: projectAdm, meta: { keepAlive: false, breadcrumbs: [{ label: '项目管理' }] }},
-            { path: 'user', name: 'userAdm', component: userAdm, meta: { keepAlive: false, breadcrumbs: [{ label: '人员管理' }] }},
-            { path: 'role', name: 'roleAdm', component: roleAdm, meta: { keepAlive: false, breadcrumbs: [{ label: '角色管理' }] }}
-        ] 
+            { path: 'project', name: 'projectAdm', component: projectAdm, meta: { keepAlive: false, breadcrumbs: [{ label: '项目管理' }] } },
+            { path: 'user', name: 'userAdm', component: userAdm, meta: { keepAlive: false, breadcrumbs: [{ label: '人员管理' }] } },
+            { path: 'role', name: 'roleAdm', component: roleAdm, meta: { keepAlive: false, breadcrumbs: [{ label: '角色管理' }] } }
+        ]
     },
     // 前期准备
     {
@@ -90,10 +97,12 @@ export default [
         name: 'LayoutMain',
         component: LayoutMain,
         children: [
-            { path: 'buildfloor', name: 'buildFloor', component: buildFloor, meta: { keepAlive: false, breadcrumbs: [{ label: '建筑楼层管理' }] }},
-            { path: 'collectsetting', name: 'collectsetting', component: collectsetting, meta: { keepAlive: false, breadcrumbs: [{ label: '需采集的信息点' }] }},
-            { path: 'appuser', name: 'buildUser', component: buildUser, meta: { keepAlive: false, breadcrumbs: [{ label: '扫楼App用户管理' }] }}
-        ] 
+            { path: 'buildfloor', name: 'buildFloor', component: buildFloor, meta: { keepAlive: false, breadcrumbs: [{ label: '建筑楼层管理' }] } },
+            // { path: 'buildfloor', name: 'buildFloor', component: Dasboard, meta: { keepAlive: false, breadcrumbs: [{ label: '建筑楼层管理' }] } },
+            { path: 'collectsetting', name: 'collectsetting', component: collectsetting, meta: { keepAlive: false, breadcrumbs: [{ label: '需采集的信息点' }] } },
+            { path: 'appuser', name: 'buildUser', component: buildUser, meta: { keepAlive: false, breadcrumbs: [{ label: '扫楼App用户管理' }] } },
+            { path: 'repetitionGraphy', name: 'repetitionGraphy', component: repetitionGraphy, meta: { keepAlive: false, breadcrumbs: [{ label: '建筑楼层管理', path: '/ready/buildfloor' }, { label:'平面图维护' }] }}
+        ]
     },
     //模型管理
     {
@@ -105,6 +114,7 @@ export default [
             {
                 path: 'file',
                 name: 'modelFile',
+                // component: Dasboard,
                 component: modelFile,
                 meta: { keepAlive: false, breadcrumbs: [{ label: '模型管理', path: '/model/file' }, { label: '模型文件管理' }] }
             },
@@ -141,7 +151,25 @@ export default [
                 path: 'equipRela',
                 name: 'equipRela',
                 component: equipRela,
-                meta: { keepAlive: false, breadcrumbs: [{ label: '系统集成', path: '/point/pointsetting' }, { label: '配置动参从点位取值', path: '/point/dynamicdata' }, { label: '处理未对应实例对象标识'}] }
+                meta: { keepAlive: false, breadcrumbs: [{ label: '系统集成', path: '/point/pointsetting' }, { label: '配置动参从点位取值', path: '/point/dynamicdata' }, { label: '处理未对应实例对象标识' }] }
+            },
+            {
+                path: 'partsRela',
+                name: 'partsRela',
+                component: partsRela,
+                meta: { keepAlive: false, breadcrumbs: [{ label: '系统集成', path: '/point/pointsetting' }, { label: '配置动参从点位取值', path: '/point/dynamicdata' }, { label: '处理未对应实例对象标识' }] }
+            },
+            {
+                path: 'systemRela',
+                name: 'systemRela',
+                component: systemRela,
+                meta: { keepAlive: false, breadcrumbs: [{ label: '系统集成', path: '/point/pointsetting' }, { label: '配置动参从点位取值', path: '/point/dynamicdata' }, { label: '处理未对应实例对象标识' }] }
+            },
+            {
+                path: 'spaceRela',
+                name: 'spaceRela',
+                component: spaceRela,
+                meta: { keepAlive: false, breadcrumbs: [{ label: '系统集成', path: '/point/pointsetting' }, { label: '配置动参从点位取值', path: '/point/dynamicdata' }, { label: '处理未对应实例对象标识' }] }
             },
             {
                 path: 'objectdata',
@@ -234,6 +262,12 @@ export default [
                 meta: { keepAlive: false, breadcrumbs: [{ label: '台账管理', path: '/ledger/facility' }, { label: '设备台账', path: '/ledger/facility' }, { label: '添加设备' }] }
             },
             {
+                path: 'batchlinkAssets',
+                name: 'batchlinkAssets',
+                component: batchlinkAssets,
+                meta: { keepAlive: false, breadcrumbs: [{ label: '台账管理', path: '/ledger/facility' }, { label: '设备台账', path: '/ledger/facility' }, { label: '批量关联资产' }] }
+            },
+            {
                 path: 'property',
                 name: 'propertyLedger',
                 component: propertyLedger,
@@ -270,6 +304,12 @@ export default [
                 meta: { keepAlive: false, breadcrumbs: [{ label: '台账管理', path: '/ledger/facility' }, { label: '业务空间台账' }] }
             },
             {
+                path: 'spaceDetail',
+                name: 'spaceDetail',
+                component: spaceDetail,
+                meta: { keepAlive: false, breadcrumbs: [{ label: '台账管理', path: '/ledger/facility' }, { label: '业务空间台账',path: '/ledger/spacelist' }, {label:'业务空间详情'}] }
+            },
+            {
                 path: 'cenotelist',
                 name: 'cenotelist',
                 component: cenotelist,
@@ -282,6 +322,12 @@ export default [
                 meta: { keepAlive: false, breadcrumbs: [{ label: '台账管理', path: '/ledger/facility' }, { label: '竖井台账', path: '/ledger/cenotelist' }, { label: '添加竖井' }] }
             },
             {
+                path: 'cenoteDetail',
+                name: 'cenoteDetail',
+                component: cenoteDetail,
+                meta: { keepAlive: false, breadcrumbs: [{ label: '台账管理', path: '/ledger/facility' }, { label: '竖井台账', path: '/ledger/cenotelist' }, { label: '竖井关系详情' }] }
+            },
+            {
                 path: 'rentlist',
                 name: 'rentlist',
                 component: rentlist,
@@ -308,9 +354,9 @@ export default [
         name: 'LayoutMain',
         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: '全部关系总览' }] }}
-        ] 
+            { path: 'maintain', name: 'maintain', component: maintain, meta: { keepAlive: false, breadcrumbs: [{ label: '关系维护' }] } },
+            { path: 'overview', name: 'overView', component: overView, meta: { keepAlive: false, breadcrumbs: [{ label: '全部关系总览' }] } }
+        ]
     },
     /******************** 通用字典 ***************************/
     //厂家库

+ 0 - 2
src/store/index.js

@@ -3,7 +3,6 @@ import Vuex from 'vuex'
 import storage from '@/framework/utils/storage'
 import layout from '@/framework/layout/layout-store'
 import project from "./modules/project"
-import peojMess from "./modules/proMess"
 import alarm from './modules/alarm'
 Vue.use(Vuex)
 const KEY_LAST_ROUTE = 'last_route'
@@ -38,7 +37,6 @@ export default new Vuex.Store({
     modules: {
         layout,
         project,
-        peojMess,
         alarm
     }
 })

+ 3 - 3
src/store/modules/alarm.js

@@ -20,9 +20,9 @@ const alarm = {
           state.spaceNameObj = spaceNameObj
       },
     //   空间code值dict
-        SPACE_CODE_OBJ(state, spaceCodeObj) {
-            state.spaceCodeObj = spaceCodeObj
-        }
+      SPACE_CODE_OBJ(state, spaceCodeObj) {
+          state.spaceCodeObj = spaceCodeObj
+      }
   }
 }
 export default alarm;

+ 0 - 29
src/store/modules/proMess.js

@@ -1,29 +0,0 @@
-const project_mess = {
-    namespaced: true,
-    state: {
-        projectId: "", //项目id
-        secret: "", //数据源id
-        userId: "test", //数据源类型
-    },
-    mutations: {
-        set_project(state, val) {
-            state.projectId = val
-        },
-        set_secret(state, val) {
-            state.secret = val
-        },
-        set_userId(state, val) {
-            state.userId = val
-        }
-    },
-    actions: {
-
-    },
-    getters: {
-        projectId: state => state.projectId,
-        userId: state => state.userId,
-        secret: state => state.secret
-    }
-}
-
-export default project_mess

+ 72 - 0
src/utils/buildfloor/tools.js

@@ -0,0 +1,72 @@
+const tools = {}
+
+/**
+ * @param arr [a,b,c]
+ * 
+ * val value
+ */
+function returnNewObj(data, arr, val) {
+  if (arr.length > 1) {
+    let k = arr.shift()
+    if (!data[k]) {
+      data[k] = {}
+    }
+    returnNewObj(data[k], arr, val)
+  } else {
+    let curk = arr[0]
+    data[curk] = val;
+  }
+}
+
+/**
+ * @param key a
+ * @param val {b:{c:''}}|''|1
+ * @return a.b.c
+ */
+function rKeyStrVal(key, val) {
+  let nk = key, arr = []
+  if (val instanceof Object && !(val instanceof Array)) {
+    // for(let k in )
+    return nk + '.' + rKeyStrVal()
+  }
+  return nk
+}
+
+/**
+ * @param data Object
+ * @returns 将对象中 key 为a.b.c 转换为a:{b:{c:''}}
+ */
+tools.formatData = (data) => {
+  let newData = JSON.parse(JSON.stringify(data))
+  for (let key in newData) {
+    if (key.indexOf('.') > -1) {
+      let arr = key.split('.')
+      returnNewObj(newData, arr, newData[key])
+      delete newData[key]
+    }
+  }
+  return newData
+}
+
+/**
+ * @param data {a:{b:{c:{}}}}
+ * 
+ * @returns a.b.c
+ * 
+ */
+tools.desFormatData = (data) => {
+  let newData = {}
+  for (let key in data) {
+    if (data[key] instanceof Object && !(data[key] instanceof Array)) {
+      for (let childK in data[key]) {
+        let nk = `${key}.${childK}`
+        newData[nk] = data[key][childK]
+      }
+    } else {
+      newData[key] = data[key]
+    }
+  }
+  return newData
+}
+
+export default tools

+ 2 - 0
src/utils/bus.js

@@ -0,0 +1,2 @@
+import Vue from 'vue'
+export default new Vue

+ 12 - 2
src/utils/handsontable/fillterField.js

@@ -11,11 +11,21 @@ const data = {
   },
   tenant: { //租户
     onlyRead: [],
-    edit: []
+    edit: [
+      "TenantID",
+      "TenantName",
+      "BIMID",
+      "BIMLocation"
+    ]
   },
   shaft: { //竖井
     onlyRead: [],
-    edit: []
+    edit: [
+      "ShaftID",
+      "ShaftName",
+      "BIMID",
+      "BIMLocation"
+    ]
   },
   parts: { //部件
     onlyRead: [],

+ 3 - 6
src/utils/handsontable/notShow.js

@@ -139,6 +139,7 @@ let partsAddNoShow = [
     "InsurerFax",
 ]
 const showTools = {
+    InputModeArr: ["A1", "A2", "B1", "B2", "C5", "D1", "D1L", "D2", "E1", "E2", "L", "L1", "L2", "F1", "F2", "M"],
     addArr: () => {
         return cutArr
     },
@@ -1055,9 +1056,7 @@ const showTools = {
                 readOnly: onlyRead,
                 correctFormat: true
             };
-        } else if (item.InputMode == "A3" ||
-            item.InputMode == "A4" ||
-            item.InputMode == "B1" ||
+        } else if (item.InputMode == "B1" ||
             item.InputMode == "B2" ||
             item.InputMode == "F1" ||
             item.InputMode == "F2" ||
@@ -1166,9 +1165,7 @@ const showTools = {
                 readOnly: !item.Editable,
                 correctFormat: true
             };
-        } else if (item.InputMode == "A3" ||
-            item.InputMode == "A4" ||
-            item.InputMode == "B1" ||
+        } else if (item.InputMode == "B1" ||
             item.InputMode == "B2" ||
             item.InputMode == "F1" ||
             item.InputMode == "F2" ||

+ 10 - 12
src/views/data_admin/buildAssets/index.vue

@@ -67,18 +67,16 @@ export default {
 
 <style scoped lang='less'>
 .box {
-  .condition {
-    padding: 10px;
-    display: flex;
-    border: 1px solid #dfe6ec;
-    background: #fff;
-    margin-bottom: 10px;
-  }
-}
-</style>
-<style>
-.box .el-tabs__nav {
-  margin-left: 10px;
+    .condition {
+        padding: 10px;
+        display: flex;
+        border: 1px solid #dfe6ec;
+        background:#fff;
+        margin-bottom: 10px;
+    }
+    /deep/ .el-tabs__nav{
+        margin-left: 10px;
+    }
 }
 </style>
 

+ 1 - 1
src/views/data_admin/buildGraphy/lib/uploadImg.vue

@@ -103,7 +103,7 @@ export default {
   }
 }
 .el-dialog__body{
-  max-height: 400px;
+  max-height: 600px;
   overflow-y: auto;
 }
 </style>

+ 140 - 0
src/views/ledger/cenotelist/cenoteDetail/index.vue

@@ -0,0 +1,140 @@
+<template>
+  <div class="box">
+    <div class="condition">
+      <div class="header">
+        <el-button style="float:left;" size="small" type="default" icon="el-icon-back" @click="goBack"></el-button>
+        <span>{{params.name||''}}</span>
+      </div>
+      <el-row class="spaceTypes">
+        <div class="types">
+          <el-tabs v-model="activeTab" type='card'>
+            <template v-for="(item,index) in tabsList">
+              <el-tab-pane :name="item.Code" :key="index" :label="item.Name"></el-tab-pane>
+            </template>
+          </el-tabs>
+        </div>
+        <div class="deleBtn">
+          <el-button size="small" @click="deleteCenote">删除竖井</el-button>
+        </div>
+      </el-row>
+      <!-- 竖井内的设备 -->
+      <device-table v-if="activeTab=='device'" :params="params" :type="activeTab"></device-table>
+      <!-- 连通的其他竖井 -->
+      <cenote-table v-else-if="activeTab=='cenote'" :params="params" :type="activeTab"></cenote-table>
+      <!-- 竖井内系统 -->
+      <system-table v-else-if="activeTab=='system'" :params="params" :type="activeTab"></system-table>
+    </div>
+  </div>
+</template>
+
+<script>
+import { mapGetters } from "vuex"
+import { deleteCenoteTableData } from '@/api/scan/request'
+import cenoteTable from '@/components/ledger/cenote/table/cenoteTable'
+import deviceTable from '@/components/ledger/cenote/table/deviceTable'
+import systemTable from '@/components/ledger/cenote/table/systemTable'
+export default {
+  data() {
+    return {
+      params: {},
+      tabsList: [
+        { Code: 'device', Name: '竖井内的设备' },
+        { Code: 'cenote', Name: '连通的其它竖井' },
+        { Code: 'system', Name: '竖井内系统' },
+      ], //tab页
+      activeTab: 'device' //当前选中的tab
+    }
+  },
+  computed: {
+    ...mapGetters("layout", ["projectId", "userId", "secret"])
+  },
+  components: {
+    cenoteTable,
+    deviceTable,
+    systemTable
+  },
+  created() {
+    this.params = this.$route.query;
+  },
+  mounted() { },
+  watch: {
+    projectId() { }
+  },
+  methods: {
+    // 返回
+    goBack() {
+      this.$router.push({ name: "cenotelist" })
+    },
+    // 删除业务空间
+    deleteCenote() {
+      this.$confirm("此操作将删除竖井,是否继续?", "提示", {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        deleteCenoteTableData([{ShaftID: this.params.ShaftID}], res => {
+          this.$message.success('删除成功')
+          this.goBack()
+        })
+      }).catch(() => {
+        this.$message("取消删除")
+      })
+    }
+  }
+};
+</script>
+
+<style scoped lang='less'>
+.box {
+  .condition {
+    padding: 10px;
+    display: flex;
+    height: 100%;
+    flex-direction: column;
+    border: 1px solid #dfe6ec;
+    background: #fff;
+    margin-bottom: 10px;
+    .header {
+      padding-bottom: 10px;
+      span {
+        line-height: 33px;
+        margin-left: 15px;
+      }
+    }
+    .spaceTypes {
+      .types {
+        float: left;
+        width: calc(100% - 200px);
+        /deep/ .el-tabs__item.is-top {
+          border-top: 2px solid transparent;
+          &.is-active {
+            border-top: 2px solid #409eff;
+          }
+        }
+      }
+      .deleBtn {
+        float: left;
+        width: 200px;
+        text-align: right;
+        height: 40px;
+        border-bottom: 1px solid #e4e7ed;
+      }
+    }
+    .main {
+      margin-top: 10px;
+      height: calc(100% - 96px);
+    }
+    .footer {
+      margin-bottom: 10px;
+    }
+  }
+}
+</style>
+
+<style lang="less">
+.el-table th {
+  background-color: #d9d9d9;
+  color: #000;
+}
+</style>
+

+ 6 - 6
src/views/ledger/cenotelist/cenoteadd/index.vue

@@ -2,6 +2,9 @@
   <div id="deviceList">
     <el-row class="right">
       <!-- <span style="float:left;">当前选择的部件类型:{{page.total || '--'}}</span> -->
+      <el-select v-model="showType" @change="initTable" style="width:125px;margin-right:10px;vertical-align:bottom;">
+        <el-option v-for="item in showTypes" :key="item.value" :label="item.label" :value="item.value"></el-option>
+      </el-select>
       <span>增加</span>
       <el-input v-model="addNum" style="width:50px;" size="small"></el-input>
       <span>个竖井</span>
@@ -44,18 +47,15 @@ export default {
       isTableRightShow: false,
       relationids: "",
       onlyRead: false,
-      showType: "all",
+      showTypes: [{ value: "Visible", label: '只看采集信息' }, { value: "all", label: '全部' }],
+      showType: "Visible",
       tableHeader: [],
       tableData: session.get("cenoteAddData")? session.get("cenoteAddData").length? session.get("cenoteAddData"): [{}]: [{}],
       copyTableData: []
     };
   },
   computed: {
-    ...mapGetters("layout", [
-        "projectId",
-        "secret",
-        "userId"
-    ])
+    ...mapGetters("layout", [ "projectId", "secret", "userId" ])
   },
   created() {
     this.getTableHeader()

+ 0 - 0
src/views/ledger/cenotelist/index.vue


Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików