Browse Source

添加业务空间

chuwu 6 years ago
parent
commit
be7dc3e6c5
65 changed files with 9370 additions and 1343 deletions
  1. 16 0
      config/index.js
  2. 2 1
      src/api/scan/config.js
  3. 12 12
      src/api/scan/request.js
  4. 44 0
      src/assets/graphy/SGraphy/SCanvas.js
  5. 30 0
      src/assets/graphy/SGraphy/SGraphyEnums.js
  6. 396 0
      src/assets/graphy/SGraphy/SGraphyItem.js
  7. 201 0
      src/assets/graphy/SGraphy/SGraphyScene.js
  8. 280 0
      src/assets/graphy/SGraphy/SGraphyView.js
  9. 53 0
      src/assets/graphy/SGraphy/SMouseEvent.js
  10. 70 0
      src/assets/graphy/SGraphy/items/SGraphyCircleItem.js
  11. 201 0
      src/assets/graphy/SGraphy/items/SGraphyClockItem.js
  12. 59 0
      src/assets/graphy/SGraphy/items/SGraphyImageItem.js
  13. 66 0
      src/assets/graphy/SGraphy/items/SGraphyLineItem.js
  14. 76 0
      src/assets/graphy/SGraphy/items/SGraphyPillarItems.js
  15. 257 0
      src/assets/graphy/SGraphy/items/SGraphyPolygonItem.js
  16. 100 0
      src/assets/graphy/SGraphy/items/SGraphyRectItem.js
  17. 51 0
      src/assets/graphy/SGraphy/items/SGraphyTextItems.js
  18. 66 0
      src/assets/graphy/SGraphy/items/SGraphyVirtualItem.js
  19. 40 0
      src/assets/graphy/SGraphy/types/SPoint.js
  20. 169 0
      src/assets/graphy/SGraphy/types/SRect.js
  21. 13 0
      src/assets/graphy/index.js
  22. 37 0
      src/assets/pako/pako.js
  23. 627 0
      src/components/business_space/business/handsontable.vue
  24. 15 15
      src/components/business_space/dialogs/addDialog/businessDialog.vue
  25. 1 1
      src/components/business_space/dialogs/addDialog/dialogAssets.vue
  26. 1 1
      src/components/business_space/dialogs/addDialog/dialogDevice.vue
  27. 1 1
      src/components/business_space/dialogs/addDialog/dialogSystem.vue
  28. 188 185
      src/components/business_space/dialogs/detailsDialog.vue
  29. 18 13
      src/components/business_space/dialogs/facilityDialog.vue
  30. 140 130
      src/components/business_space/dialogs/influenceDialog.vue
  31. 1 1
      src/components/business_space/dialogs/list/filesDialog.vue
  32. 3 3
      src/components/business_space/dialogs/list/firm.vue
  33. 4 4
      src/components/business_space/dialogs/list/guaranteeDialog.vue
  34. 3 3
      src/components/business_space/dialogs/list/insurerDialog.vue
  35. 3 3
      src/components/business_space/dialogs/list/maintainerDialog.vue
  36. 1 1
      src/components/business_space/dialogs/list/paramDetails.vue
  37. 2 2
      src/components/business_space/dialogs/list/picDialog.vue
  38. 3 3
      src/components/business_space/dialogs/list/supplierDialog.vue
  39. 3 3
      src/components/business_space/dialogs/list/supplyDialog.vue
  40. 3 3
      src/components/business_space/dialogs/list/systemType.vue
  41. 1 1
      src/components/business_space/dialogs/list/uploadImgDialog.vue
  42. 1 1
      src/components/business_space/dialogs/notRelated.vue
  43. 1292 0
      src/components/business_space/graphy/business.vue
  44. 114 0
      src/components/business_space/lib/cascaders/assets.vue
  45. 120 0
      src/components/business_space/lib/cascaders/system.vue
  46. 75 0
      src/components/business_space/lib/detailsDia.vue
  47. 119 0
      src/components/business_space/lib/floorCascader.vue
  48. 315 0
      src/components/business_space/lib/formInput.vue
  49. 181 0
      src/components/business_space/lib/lookImages.vue
  50. 58 0
      src/components/business_space/lib/myPagination.vue
  51. 57 0
      src/components/business_space/lib/qrcode.vue
  52. 207 0
      src/components/business_space/lib/uploadFiles.vue
  53. 109 0
      src/components/business_space/lib/uploadImg.vue
  54. 321 0
      src/components/business_space/lib/uploadImgs.vue
  55. 365 0
      src/components/business_space/lib/uploadImgsName.vue
  56. 569 0
      src/components/business_space/table/addEquip.vue
  57. 246 0
      src/components/business_space/table/businessTable.vue
  58. 365 0
      src/components/business_space/table/equipTable.vue
  59. 58 0
      src/components/common/myPagination.vue
  60. 1 1
      src/router/sagacloud.js
  61. 84 0
      src/utils/handsontable/mainText.js
  62. 541 0
      src/utils/handsontable/notShow.js
  63. 1 1
      src/utils/scan/tools.js
  64. 22 19
      src/views/business_space/admin/index.vue
  65. 892 935
      src/views/data_admin/buildAssets/index.vue

+ 16 - 0
config/index.js

@@ -25,6 +25,14 @@ module.exports = {
                 // 将主机标头的原点更改为目标URL
                 // 将主机标头的原点更改为目标URL
                 changeOrigin: false
                 changeOrigin: false
             },
             },
+            '/business-space': {
+                // 目标 API 地址
+                target: 'http://192.168.20.225:8080/',
+                // 如果要代理 websockets
+                ws: true,
+                // 将主机标头的原点更改为目标URL
+                changeOrigin: false
+            },
             '/pointconfig': {
             '/pointconfig': {
                 // 目标 API 地址
                 // 目标 API 地址
                 target: 'http://172.16.0.141:8080/',
                 target: 'http://172.16.0.141:8080/',
@@ -41,6 +49,14 @@ module.exports = {
                 // 将主机标头的原点更改为目标URL
                 // 将主机标头的原点更改为目标URL
                 changeOrigin: false
                 changeOrigin: false
             },
             },
+            '/image-service': {
+                // 目标 API 地址
+                target: 'http://192.168.20.225:8080/',
+                // 如果要代理 websockets
+                ws: true,
+                // 将主机标头的原点更改为目标URL
+                changeOrigin: false
+            }
         },
         },
 
 
         // Various Dev Server settings
         // Various Dev Server settings

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

@@ -1,3 +1,4 @@
 export const api = '/ScanBuilding';
 export const api = '/ScanBuilding';
 export const sass = 'sass';
 export const sass = 'sass';
-export const physics = '/data-platform-3';
+export const physics = '/data-platform-3';
+export const business = '/business-space'

+ 12 - 12
src/api/scan/request.js

@@ -1,5 +1,5 @@
 import fetch from './fetch'
 import fetch from './fetch'
-import { api, physics } from './config'
+import { api, physics, business } from './config'
 import http from './httpUtil'
 import http from './httpUtil'
 let arithmetic = '/arithmetic'
 let arithmetic = '/arithmetic'
 
 
@@ -437,7 +437,7 @@ export function formBIMToPri(param) {
 
 
 //获取业务空间楼层的关系
 //获取业务空间楼层的关系
 export function getSpaceFloor(param) {
 export function getSpaceFloor(param) {
-    return fetch({ method: "POST", url: `${physics}/business-space/floor/tree?projectId=${param.ProjId}&secret=${param.secret}` })
+    return fetch({ method: "POST", url: `${business}/floor/tree?projectId=${param.ProjId}&secret=${param.secret}` })
 }
 }
 
 
 //创建业务空间
 //创建业务空间
@@ -512,7 +512,7 @@ export function getRelation(param) {
 //查询业务空间下的设备
 //查询业务空间下的设备
 export function getSpaceEquip(param) {
 export function getSpaceEquip(param) {
     let data = param.data
     let data = param.data
-    return fetch({ method: 'POST', url: `${physics}/business-space/space/equip/query?projectId=${param.ProjId}&secret=${param.secret}`, data })
+    return fetch({ method: 'POST', url: `${business}/space/equip/query?projectId=${param.ProjId}&secret=${param.secret}`, data })
 }
 }
 
 
 //删除关系实例
 //删除关系实例
@@ -524,7 +524,7 @@ export function deleteRelation(param) {
 //查询是否关联元空间的业务空间
 //查询是否关联元空间的业务空间
 export function isSpaceBuss(param) {
 export function isSpaceBuss(param) {
     let data = param.data
     let data = param.data
-    return fetch({ method: 'POST', url: `${physics}/business-space/floor/space/query?projectId=${param.ProjId}&secret=${param.secret}`, data })
+    return fetch({ method: 'POST', url: `${business}/floor/space/query?projectId=${param.ProjId}&secret=${param.secret}`, data })
 }
 }
 
 
 //查询所有提示
 //查询所有提示
@@ -542,7 +542,7 @@ export function deleteNotice(param) {
 //模糊查询楼层下的设备
 //模糊查询楼层下的设备
 export function getEquipSearch(param) {
 export function getEquipSearch(param) {
     let data = param.data
     let data = param.data
-    return fetch({ method: 'POST', url: `${physics}/business-space/floor/equip/query?projectId=${param.ProjId}&secret=${param.secret}`, data })
+    return fetch({ method: 'POST', url: `${business}/floor/equip/query?projectId=${param.ProjId}&secret=${param.secret}`, data })
 }
 }
 
 
 export function getBussTypes(success) {
 export function getBussTypes(success) {
@@ -559,7 +559,7 @@ export function getBussTypes2() {
 //验证元空间是否相邻
 //验证元空间是否相邻
 export function isAbut(param) {
 export function isAbut(param) {
     let data = param.data
     let data = param.data
-    return fetch({ method: 'POST', url: `${physics}/business-space/space/abut?projectId=${param.ProjId}&secret=${param.secret}`, data })
+    return fetch({ method: 'POST', url: `${business}/space/abut?projectId=${param.ProjId}&secret=${param.secret}`, data })
 }
 }
 
 
 /**算法接口 */
 /**算法接口 */
@@ -632,14 +632,14 @@ export function createProperty(param, success) {
 
 
 //获取项目内[岗位]和[绑定岗位的资产]的数量
 //获取项目内[岗位]和[绑定岗位的资产]的数量
 export function getNumber(param, success) {
 export function getNumber(param, success) {
-    let url = `${physics}/business-space/equip/count?projectId=${param.ProjId}&secret=${param.secret}`
+    let url = `${business}/equip/count?projectId=${param.ProjId}&secret=${param.secret}`
     let data = param.data
     let data = param.data
     http.postJson(url, data, success)
     http.postJson(url, data, success)
 }
 }
 
 
 //获取项目内有实例的所有种族
 //获取项目内有实例的所有种族
 export function getFamilyList(param, success) {
 export function getFamilyList(param, success) {
-    let url = `${physics}/business-space/equip/type/list?projectId=${param.ProjId}&secret=${param.secret}`
+    let url = `${business}/equip/type/list?projectId=${param.ProjId}&secret=${param.secret}`
     let data = param.data
     let data = param.data
     http.postJson(url, data, success)
     http.postJson(url, data, success)
 }
 }
@@ -662,7 +662,7 @@ export function createSystem(param, success) {
 
 
 //获取台账资产列表
 //获取台账资产列表
 export function getBillPropList(param, success) {
 export function getBillPropList(param, success) {
-    let url = `${physics}/business-space/property/list?projectId=${param.ProjId}&secret=${param.secret}`
+    let url = `${business}/property/list?projectId=${param.ProjId}&secret=${param.secret}`
     let data = param.data
     let data = param.data
     http.postJson(url, data, success)
     http.postJson(url, data, success)
 }
 }
@@ -676,14 +676,14 @@ export function updateProperty(param, success) {
 
 
 //台账获取设备列表
 //台账获取设备列表
 export function getBillEquipList(param, success) {
 export function getBillEquipList(param, success) {
-    let url = `${physics}/business-space/equip/list?projectId=${param.ProjId}&secret=${param.secret}`
+    let url = `${business}/equip/list?projectId=${param.ProjId}&secret=${param.secret}`
     let data = param.data
     let data = param.data
     http.postJson(url, data, success)
     http.postJson(url, data, success)
 }
 }
 
 
 //台账获取系统列表
 //台账获取系统列表
 export function getBillSystemList(param, success) {
 export function getBillSystemList(param, success) {
-    let url = `${physics}/business-space/system/list?projectId=${param.ProjId}&secret=${param.secret}`
+    let url = `${business}/system/list?projectId=${param.ProjId}&secret=${param.secret}`
     let data = param.data
     let data = param.data
     http.postJson(url, data, success)
     http.postJson(url, data, success)
 }
 }
@@ -745,7 +745,7 @@ export function createAssetsList(param, success) {
 }
 }
 
 
 export function getListForBuss(param, success) {
 export function getListForBuss(param, success) {
-    let url = `${physics}/business-space/space/ispace/equip/query?projectId=${param.ProjId}&secret=${param.secret}`
+    let url = `${business}/space/ispace/equip/query?projectId=${param.ProjId}&secret=${param.secret}`
     let data = param.data
     let data = param.data
     http.postJson(url, data, success)
     http.postJson(url, data, success)
 }
 }

+ 44 - 0
src/assets/graphy/SGraphy/SCanvas.js

@@ -0,0 +1,44 @@
+/*
+ * ********************************************************************************************************************
+ *
+ *               iFHS7.
+ *              ;BBMBMBMc                  rZMBMBR              BMB
+ *              MBEr:;PBM,               7MBMMEOBB:             BBB                       RBW
+ *     XK:      BO     SB.     :SZ       MBM.       c;;     ir  BBM :FFr       :SSF:    ;xBMB:r   iuGXv.    i:. iF2;
+ *     DBBM0r.  :D     S7   ;XMBMB       GMBMu.     MBM:   BMB  MBMBBBMBMS   WMBMBMBBK  MBMBMBM  BMBRBMBW  .MBMBMBMBB
+ *      :JMRMMD  ..    ,  1MMRM1;         ;MBMBBR:   MBM  ;MB:  BMB:   MBM. RMBr   sBMH   BM0         UMB,  BMB.  KMBv
+ *     ;.   XOW  B1; :uM: 1RE,   i           .2BMBs  rMB. MBO   MBO    JMB; MBB     MBM   BBS    7MBMBOBM:  MBW   :BMc
+ *     OBRJ.SEE  MRDOWOR, 3DE:7OBM       .     ;BMB   RMR7BM    BMB    MBB. BMB    ,BMR  .BBZ   MMB   rMB,  BMM   rMB7
+ *     :FBRO0D0  RKXSXPR. JOKOOMPi       BMBSSWBMB;    BMBB:    MBMB0ZMBMS  .BMBOXRBMB    MBMDE RBM2;SMBM;  MBB   xBM2
+ *         iZGE  O0SHSPO. uGZ7.          sBMBMBDL      :BMO     OZu:BMBK,     rRBMB0;     ,EBMB  xBMBr:ER.  RDU   :OO;
+ *     ,BZ, 1D0  RPSFHXR. xWZ .SMr                  . .BBB
+ *      :0BMRDG  RESSSKR. 2WOMBW;                   BMBMR
+ *         i0BM: SWKHKGO  MBDv
+ *           .UB  OOGDM. MK,                                          Copyright (c) 2015-2018.  斯伯坦机器人世界
+ *              ,  XMW  ..
+ *                  r                                                                     All rights reserved.
+ *
+ * ********************************************************************************************************************
+ */
+
+/**
+ * Canvas功能扩展
+ *
+ * @author  Andy
+ */
+Object.assign(CanvasRenderingContext2D.prototype, {
+  /**
+   * 绘制线段
+   *
+   * @param   x0    起点x坐标
+   * @param   y0    起点y坐标
+   * @param   x1    终点x坐标
+   * @param   y1    终点y坐标
+   */
+  drawLine (x0, y0, x1, y1) {
+    this.beginPath()
+    this.moveTo(x0, y0)
+    this.lineTo(x1, y1)
+    this.stroke()
+  } // Function drawLine()
+}) // Class CanvasRenderingContext2D

+ 30 - 0
src/assets/graphy/SGraphy/SGraphyEnums.js

@@ -0,0 +1,30 @@
+/*
+ * ********************************************************************************************************************
+ *
+ *               iFHS7.
+ *              ;BBMBMBMc                  rZMBMBR              BMB
+ *              MBEr:;PBM,               7MBMMEOBB:             BBB                       RBW
+ *     XK:      BO     SB.     :SZ       MBM.       c;;     ir  BBM :FFr       :SSF:    ;xBMB:r   iuGXv.    i:. iF2;
+ *     DBBM0r.  :D     S7   ;XMBMB       GMBMu.     MBM:   BMB  MBMBBBMBMS   WMBMBMBBK  MBMBMBM  BMBRBMBW  .MBMBMBMBB
+ *      :JMRMMD  ..    ,  1MMRM1;         ;MBMBBR:   MBM  ;MB:  BMB:   MBM. RMBr   sBMH   BM0         UMB,  BMB.  KMBv
+ *     ;.   XOW  B1; :uM: 1RE,   i           .2BMBs  rMB. MBO   MBO    JMB; MBB     MBM   BBS    7MBMBOBM:  MBW   :BMc
+ *     OBRJ.SEE  MRDOWOR, 3DE:7OBM       .     ;BMB   RMR7BM    BMB    MBB. BMB    ,BMR  .BBZ   MMB   rMB,  BMM   rMB7
+ *     :FBRO0D0  RKXSXPR. JOKOOMPi       BMBSSWBMB;    BMBB:    MBMB0ZMBMS  .BMBOXRBMB    MBMDE RBM2;SMBM;  MBB   xBM2
+ *         iZGE  O0SHSPO. uGZ7.          sBMBMBDL      :BMO     OZu:BMBK,     rRBMB0;     ,EBMB  xBMBr:ER.  RDU   :OO;
+ *     ,BZ, 1D0  RPSFHXR. xWZ .SMr                  . .BBB
+ *      :0BMRDG  RESSSKR. 2WOMBW;                   BMBMR
+ *         i0BM: SWKHKGO  MBDv
+ *           .UB  OOGDM. MK,                                          Copyright (c) 2015-2018.  斯伯坦机器人世界
+ *              ,  XMW  ..
+ *                  r                                                                     All rights reserved.
+ *
+ * ********************************************************************************************************************
+ */
+
+const SGraphyItemFlag = {
+  ItemIsMovable: 1,
+  ItemIsSelectable: 2
+}
+
+if (Object.freeze)
+  Object.freeze(SGraphyItemFlag)

+ 396 - 0
src/assets/graphy/SGraphy/SGraphyItem.js

@@ -0,0 +1,396 @@
+/*
+ * ********************************************************************************************************************
+ *
+ *               iFHS7.
+ *              ;BBMBMBMc                  rZMBMBR              BMB
+ *              MBEr:;PBM,               7MBMMEOBB:             BBB                       RBW
+ *     XK:      BO     SB.     :SZ       MBM.       c;;     ir  BBM :FFr       :SSF:    ;xBMB:r   iuGXv.    i:. iF2;
+ *     DBBM0r.  :D     S7   ;XMBMB       GMBMu.     MBM:   BMB  MBMBBBMBMS   WMBMBMBBK  MBMBMBM  BMBRBMBW  .MBMBMBMBB
+ *      :JMRMMD  ..    ,  1MMRM1;         ;MBMBBR:   MBM  ;MB:  BMB:   MBM. RMBr   sBMH   BM0         UMB,  BMB.  KMBv
+ *     ;.   XOW  B1; :uM: 1RE,   i           .2BMBs  rMB. MBO   MBO    JMB; MBB     MBM   BBS    7MBMBOBM:  MBW   :BMc
+ *     OBRJ.SEE  MRDOWOR, 3DE:7OBM       .     ;BMB   RMR7BM    BMB    MBB. BMB    ,BMR  .BBZ   MMB   rMB,  BMM   rMB7
+ *     :FBRO0D0  RKXSXPR. JOKOOMPi       BMBSSWBMB;    BMBB:    MBMB0ZMBMS  .BMBOXRBMB    MBMDE RBM2;SMBM;  MBB   xBM2
+ *         iZGE  O0SHSPO. uGZ7.          sBMBMBDL      :BMO     OZu:BMBK,     rRBMB0;     ,EBMB  xBMBr:ER.  RDU   :OO;
+ *     ,BZ, 1D0  RPSFHXR. xWZ .SMr                  . .BBB
+ *      :0BMRDG  RESSSKR. 2WOMBW;                   BMBMR
+ *         i0BM: SWKHKGO  MBDv
+ *           .UB  OOGDM. MK,                                          Copyright (c) 2015-2018.  斯伯坦机器人世界
+ *              ,  XMW  ..
+ *                  r                                                                     All rights reserved.
+ *
+ * ********************************************************************************************************************
+ */
+import SPoint from './types/SPoint'
+import SRect from './types/SRect'
+import SMouseEvent from './SMouseEvent'
+
+const sortItemZOrder = Symbol('sortItemZOrder')
+const toChildMouseEvent = Symbol('toChildMouseEvent')
+const grabItem = Symbol('grabItem')
+const releaseItem = Symbol('releaseItem')
+
+/**
+ * SGraphyItem
+ *
+ * @author  Andy
+ */
+export default class SGraphyItem {
+    /**
+     * 构造函数
+     */
+    constructor(parent) {
+            this.name = 'item'
+            this._scene = null
+            this._parent = parent
+            this.children = []
+
+            /** Z轴顺序 */
+            this.zOrder = 0
+                /** item位置 */
+            this._pos = new SPoint(0, 0)
+                /** 缩放比例 */
+            this._scale = new SPoint(1, 1)
+                /** 是否可见 */
+            this._isVisible = true
+
+            /** 鼠标按下时位置 */
+            this._mouseDownPos = new SPoint(4, 21)
+            this._isMove = false
+            this.canMove = false
+        } // Function constructor()
+
+    // ===================================================================================================================
+    // 属性
+    /** parent属性存值函数 */
+    get parent() {
+        return this._parent
+    }
+    set parent(value) {
+            if (this._parent === value) {
+                return
+            }
+            if (this._parent != null) { // 如果原parent不为空
+                // 将节点从原parent节点中摘除
+                let i = this._parent.children.indexOf(this)
+                this._parent.children.splice(i, 1)
+            }
+            this._parent = value
+
+            if (this._parent != null) { // 如果新parent不为空
+                // 将节点加入到新parent节点中
+                this._parent.children.push(this)
+                this._parent.children.sort(this[sortItemZOrder])
+            }
+            this._parent = value
+        } // Function set Parent()
+
+    /** scene属性 */
+    get scene() {
+        if (this._parent != null) {
+            return this._parent.scene
+        } else {
+            return this._scene
+        }
+    }
+
+    /** pos属性 */
+    get pos() {
+        return this._pos
+    }
+    set pos(value) {
+        this._pos = value
+    }
+
+    /** scale属性 */
+    get scale() {
+        return this._scale
+    }
+    set scale(value) {
+        this._scale = value
+    }
+
+    /** visible属性 */
+    get visible() {
+        return this._isVisible
+    }
+    set visible(value) {
+        this._isVisible = value
+    }
+
+    // ===================================================================================================================
+    // 函数
+    /**
+     * Item对象边界区域
+     *
+     * @return  SRect
+     */
+    boundingRect() {
+            return new SRect(0, 0, 10, 10)
+        } // Function boundingRect()
+
+    /**
+     * Item绘制操作
+     *
+     * @param   canvas        画布对象
+     * @param   rect          绘制区域
+     */
+    onDraw(canvas, rect) {
+            for (let item of this.children) {
+                // 保存画布状态
+                canvas.save()
+                    // item位移到指定位置绘制
+                canvas.translate(item.pos.x, item.pos.y)
+                    // 设置绘制区域
+                    // canvas.clip(item.boundingRect())
+                    // 绘制item
+                item.onDraw(canvas, rect)
+                    // 恢复画布状态
+                canvas.restore()
+            }
+        } // Function onDraw()
+
+    /**
+     * 更新Item
+     */
+    update() {
+            // TODO: PLX
+            // scene?.update()
+        } // Function update()
+
+    /**
+     * 移动item到指定位置
+     *
+     * @param   x           新位置的x坐标
+     * @param   y           新位置的y坐标
+     */
+    moveTo(x, y) {
+            this.pos = new SPoint(x, y)
+        } // moveTo()
+
+    /**
+     * 判断item是否包含点x,y
+     *
+     * @param   x       横坐标(当前item)
+     * @param   y       纵坐标(当前item)
+     *
+     * @return  boolean
+     */
+    contains(x, y) {
+            return this.boundingRect().contains(x - this.pos.x, y - this.pos.y)
+        } // Function contains()
+
+    /**
+     * 获得item的路径节点列表。(该节点被加载到场景中,如果未被加载到场景中,计算会出错)
+     *
+     * @return  *[]
+     */
+    itemPath() {
+            if (this.parent != null) {
+                let list = this.parent.itemPath()
+                list.push(this)
+                return list
+            }
+
+            return [this]
+        } // Function itemPath()
+
+    /**
+     * 将场景中的xy坐标转换成item坐标。(该节点被加载到场景中,如果未被加载到场景中,计算会出错)
+     *
+     * @param   x       场景中的横坐标
+     * @param   y       场景中的纵坐标
+     *
+     * @return  在item中的坐标
+     */
+    mapFromScene(x, y) {
+            let list = this.itemPath()
+            let x0 = x
+            let y0 = y
+            for (let item of list) {
+                x0 = (x0 - item.pos.x) / item.scale.x
+                y0 = (y0 - item.pos.y) / item.scale.y
+            }
+
+            return new SPoint(x0, y0)
+        } // Function mapFromScene()
+
+    /**
+     * 将item中的xy坐标转换成场景坐标。(该节点被加载到场景中,如果未被加载到场景中,计算会出错)
+     *
+     * @param   x       item中的横坐标
+     * @param   y       item中的纵坐标
+     *
+     * @return  在场景中的坐标
+     */
+    mapToScene(x, y) {
+            if (this.parent == null) {
+                return new SPoint(x, y)
+            }
+
+            return this.parent.mapToScene(x * this.scale.x + this.pos.x, y * this.scale.y + this.pos.y)
+        } // Function mapToScene()
+
+    // ===================================================================================================================
+    // 事件
+    /**
+     * 鼠标单击事件
+     *
+     * @param   e   保存事件参数
+     * @return  boolean
+     */
+    onClick(e) {
+            for (let item of this.children) {
+                if (!item.visible) { // 如果项目不可见
+                    continue
+                }
+                let ce = this[toChildMouseEvent](item, e)
+                if (item.contains(e.x, e.y) && item.onClick(ce)) { // 如果点在子项目上且子项目处理了事件
+                    return true
+                }
+            }
+
+            return false
+        } // Function onClick()
+
+    /**
+     * 鼠标双击事件
+     *
+     * @param   e   保存事件参数
+     * @return  boolean
+     */
+    onDbClick(e) {
+            for (let item of this.children) {
+                if (!item.visible) { // 如果项目不可见
+                    continue
+                }
+                let ce = this[toChildMouseEvent](item, e)
+                if (item.contains(e.x, e.y) && item.onDbClick(ce)) { // 如果点在子项目上且子项目处理了事件
+                    return true
+                }
+            }
+
+            return false
+        } // Function onClick()
+
+    /**
+     * 鼠标按下事件
+     *
+     * @param   e   保存事件参数
+     * @return  boolean
+     */
+    onMouseDown(e) {
+            // console.log(e)
+
+            for (let item of this.children) {
+                if (!item.visible) { // 如果项目不可见
+                    continue
+                }
+                let ce = this[toChildMouseEvent](item, e)
+                if (item.contains(e.x, e.y) && item.onMouseDown(ce)) { // 如果点在子项目上且子项目处理了事件
+                    return true
+                }
+            }
+
+            if (this.canMove) {
+                this._mouseDownPos = new SPoint(e.x, e.y)
+                this._isMove = true
+                this[grabItem](this)
+                    // console.log(this.scene.grabItem)
+                return true
+            }
+            return false
+        } // Function onMouseDown()
+
+    /**
+     * 鼠标移动事件
+     *
+     * @param   e   保存事件参数
+     * @return  boolean
+     */
+    onMouseMove(e) {
+            for (let item of this.children) {
+                if (!item.visible) { // 如果项目不可见
+                    continue
+                }
+                let ce = this[toChildMouseEvent](item, e)
+                if (item.contains(e.x, e.y) && item.onMouseMove(ce)) { // 如果点在子项目上且子项目处理了事件
+                    return true
+                }
+            }
+
+            if (e.buttons & SMouseEvent.LEFT_BUTTON && this.canMove && this._isMove) {
+                this.moveTo(this.pos.x + e.x - this._mouseDownPos.x, this.pos.y + e.y - this._mouseDownPos.y)
+            }
+
+            return false
+        } // Function onMouseMove()
+
+    /**
+     * 释放鼠标事件
+     *
+     * @param   e   保存事件参数
+     * @return  boolean
+     */
+    onMouseUp(e) {
+            for (let item of this.children) {
+                if (!item.visible) { // 如果项目不可见
+                    continue
+                }
+                let ce = this[toChildMouseEvent](item, e)
+                if (item.contains(e.x, e.y) && item.onMouseUp(ce)) { // 如果点在子项目上且子项目处理了事件
+                    return true
+                }
+            }
+
+            this._isMove = false
+            this[releaseItem]()
+            return false
+        } // Function onMouseUp()
+
+    // ===================================================================================================================
+    // 私有方法
+    /**
+     * 按ZOrder排序
+     *
+     * @param   a   比较元素1
+     * @param   b   比较元素2
+     * @return {number}
+     */
+    [sortItemZOrder](a, b) {
+        return a.zOrder - b.zOrder
+    } // Function sortItemZOrder()
+
+    /**
+     * 鼠标事件转子对象鼠标事件
+     *
+     * @param   child   子对象e
+     * @param   e       事件参数
+     * @return  {}
+     */
+    [toChildMouseEvent](child, e) {
+        let ce = {...e }
+        ce.x = (e.x - child.pos.x) / child.scale.x
+        ce.y = (e.y - child.pos.y) / child.scale.y
+        return ce
+    } // Function toChildMouseEvent()
+
+    /**
+     * 锁定item
+     *
+     * @param   item    被锁定的item
+     */
+    [grabItem](item) {
+        if (this.scene != null) {
+            this.scene.grabItem = item
+        }
+    } // Function grabItem
+
+    /**
+     * 释放被锁定的item
+     */
+    [releaseItem]() {
+        if (this.scene != null) {
+            this.scene.grabItem = null
+        }
+    } // Function grabItem
+} // Class SGraphyItem

+ 201 - 0
src/assets/graphy/SGraphy/SGraphyScene.js

@@ -0,0 +1,201 @@
+/*
+ * ********************************************************************************************************************
+ *
+ *               iFHS7.
+ *              ;BBMBMBMc                  rZMBMBR              BMB
+ *              MBEr:;PBM,               7MBMMEOBB:             BBB                       RBW
+ *     XK:      BO     SB.     :SZ       MBM.       c;;     ir  BBM :FFr       :SSF:    ;xBMB:r   iuGXv.    i:. iF2;
+ *     DBBM0r.  :D     S7   ;XMBMB       GMBMu.     MBM:   BMB  MBMBBBMBMS   WMBMBMBBK  MBMBMBM  BMBRBMBW  .MBMBMBMBB
+ *      :JMRMMD  ..    ,  1MMRM1;         ;MBMBBR:   MBM  ;MB:  BMB:   MBM. RMBr   sBMH   BM0         UMB,  BMB.  KMBv
+ *     ;.   XOW  B1; :uM: 1RE,   i           .2BMBs  rMB. MBO   MBO    JMB; MBB     MBM   BBS    7MBMBOBM:  MBW   :BMc
+ *     OBRJ.SEE  MRDOWOR, 3DE:7OBM       .     ;BMB   RMR7BM    BMB    MBB. BMB    ,BMR  .BBZ   MMB   rMB,  BMM   rMB7
+ *     :FBRO0D0  RKXSXPR. JOKOOMPi       BMBSSWBMB;    BMBB:    MBMB0ZMBMS  .BMBOXRBMB    MBMDE RBM2;SMBM;  MBB   xBM2
+ *         iZGE  O0SHSPO. uGZ7.          sBMBMBDL      :BMO     OZu:BMBK,     rRBMB0;     ,EBMB  xBMBr:ER.  RDU   :OO;
+ *     ,BZ, 1D0  RPSFHXR. xWZ .SMr                  . .BBB
+ *      :0BMRDG  RESSSKR. 2WOMBW;                   BMBMR
+ *         i0BM: SWKHKGO  MBDv
+ *           .UB  OOGDM. MK,                                          Copyright (c) 2015-2018.  斯伯坦机器人世界
+ *              ,  XMW  ..
+ *                  r                                                                     All rights reserved.
+ *
+ * ********************************************************************************************************************
+ */
+
+import SPoint from './types/SPoint'
+import SRect from './types/SRect'
+import SGraphyItem from './SGraphyItem'
+
+const toGrabItemMotionEvent = Symbol('toGrabItemMotionEvent')
+
+/**
+ * SGraphy图形引擎场景类
+ *
+ * @author  Andy
+ */
+export default class SGraphyScene {
+    /**
+     * 构造函数
+     */
+    constructor() {
+            this.view = null
+            console.log(this, 'this')
+            this.root = new SGraphyItem(null)
+            this.root._scene = this
+            this.pos = new SPoint(0, 0)
+            this.scale = new SPoint(1, 1)
+            this.grabItem = null
+        } // Function constructor()
+
+    /**
+     * 添加item对象到场景。
+     *
+     * @param   item        添加的对象
+     */
+    addItem(item) {
+            item.parent = this.root
+        } // Function addItem()
+
+    /**
+     * 从场景中移除Item。
+     *
+     * @param   item        被移除的对象
+     */
+    removeItem(item) {
+            item.parent = null
+        } // Function removeItem()
+
+    /**
+     * 绘制场景
+     *
+     * @param   canvas      画布
+     * @param   rect        更新绘制区域
+     */
+    drawScene(canvas, rect) {
+            this.root.onDraw(canvas, rect)
+        } // Function drawScene()
+
+    /**
+     * 绘制背景
+     *
+     * @param   canvas      画布
+     * @param   rect        更新绘制区域
+     */
+    drawBackground(canvas, rect) {
+            // DO NOTHING
+        } // Function drawBackground()
+
+    /**
+     * 绘制前景
+     *
+     * @param   canvas      画布
+     * @param   rect        更新绘制区域
+     */
+    drawForeground(canvas, rect) {
+            // DO NOTHING
+        } // Function drawForeground()
+
+    /**
+     * 返回场景的item边界。即所有item边界的并集。
+     *
+     * @return  SRect
+     */
+    worldRect() {
+            let rect = null
+
+            for (let item of this.root.children) { // 依次取item列中的所有item。将所有item的边界做并焦处理。
+                if (rect == null) {
+                    rect = item.boundingRect().adjusted(item.pos)
+                } else {
+                    rect.union(item.boundingRect().adjusted(item.pos))
+                }
+            }
+
+            return rect
+        } // Function worldsRect()
+
+    /**
+     * 更新
+     */
+    update() {} // Function update()
+        // ===================================================================================================================
+        // 事件
+        /**
+         * 鼠标单击事件
+         *
+         * @param   e   保存事件参数
+         * @return  boolean
+         */
+    onClick(e) {
+            if (this.grabItem != null) {
+                return this.grabItem.onClick(this[toGrabItemMotionEvent](this.grabItem, e))
+            }
+            return this.root.onClick(e)
+        } // onClick
+
+    /**
+     * 鼠标双击事件
+     *
+     * @param   e   保存事件参数
+     * @return  boolean
+     */
+    onDbClick(e) {
+            if (this.grabItem != null) {
+                return this.grabItem.onDbClick(this[toGrabItemMotionEvent](this.grabItem, e))
+            }
+            return this.root.onDbClick(e)
+        } // onClick
+
+    /**
+     * 鼠标按下事件
+     *
+     * @param   e   保存事件参数
+     * @return  boolean
+     */
+    onMouseDown(e) {
+            if (this.grabItem != null) {
+                return this.grabItem.onMouseDown(this[toGrabItemMotionEvent](this.grabItem, e))
+            }
+            return this.root.onMouseDown(e)
+        } // onMouseDown
+
+    /**
+     * 鼠标移动事件
+     *
+     * @param   e   保存事件参数
+     * @return  boolean
+     */
+    onMouseMove(e) {
+            if (this.grabItem != null) {
+                return this.grabItem.onMouseMove(this[toGrabItemMotionEvent](this.grabItem, e))
+            }
+            return this.root.onMouseMove(e)
+        } // onMouseMove
+
+    /**
+     * 释放鼠标事件
+     *
+     * @param   e   保存事件参数
+     * @return  boolean
+     */
+    onMouseUp(e) {
+            if (this.grabItem != null) {
+                return this.grabItem.onMouseUp(this[toGrabItemMotionEvent](this.grabItem, e))
+            }
+            return this.root.onMouseUp(e)
+        } // onMouseUp
+
+    /**
+     * 转换场景事件坐标到指定Item坐标事件
+     *
+     * @param   item        指定的item对象
+     * @param   e           场景事件
+     * @return  {}
+     */
+    [toGrabItemMotionEvent](item, e) {
+        let se = {...e }
+        let p = item.mapFromScene(e.x, e.y)
+        se.x = p.x
+        se.y = p.y
+        return se
+    } // Function toGrabItemMotionEvent()
+} // Class SGraphyScene

+ 280 - 0
src/assets/graphy/SGraphy/SGraphyView.js

@@ -0,0 +1,280 @@
+/*
+ * ********************************************************************************************************************
+ *
+ *               iFHS7.
+ *              ;BBMBMBMc                  rZMBMBR              BMB
+ *              MBEr:;PBM,               7MBMMEOBB:             BBB                       RBW
+ *     XK:      BO     SB.     :SZ       MBM.       c;;     ir  BBM :FFr       :SSF:    ;xBMB:r   iuGXv.    i:. iF2;
+ *     DBBM0r.  :D     S7   ;XMBMB       GMBMu.     MBM:   BMB  MBMBBBMBMS   WMBMBMBBK  MBMBMBM  BMBRBMBW  .MBMBMBMBB
+ *      :JMRMMD  ..    ,  1MMRM1;         ;MBMBBR:   MBM  ;MB:  BMB:   MBM. RMBr   sBMH   BM0         UMB,  BMB.  KMBv
+ *     ;.   XOW  B1; :uM: 1RE,   i           .2BMBs  rMB. MBO   MBO    JMB; MBB     MBM   BBS    7MBMBOBM:  MBW   :BMc
+ *     OBRJ.SEE  MRDOWOR, 3DE:7OBM       .     ;BMB   RMR7BM    BMB    MBB. BMB    ,BMR  .BBZ   MMB   rMB,  BMM   rMB7
+ *     :FBRO0D0  RKXSXPR. JOKOOMPi       BMBSSWBMB;    BMBB:    MBMB0ZMBMS  .BMBOXRBMB    MBMDE RBM2;SMBM;  MBB   xBM2
+ *         iZGE  O0SHSPO. uGZ7.          sBMBMBDL      :BMO     OZu:BMBK,     rRBMB0;     ,EBMB  xBMBr:ER.  RDU   :OO;
+ *     ,BZ, 1D0  RPSFHXR. xWZ .SMr                  . .BBB
+ *      :0BMRDG  RESSSKR. 2WOMBW;                   BMBMR
+ *         i0BM: SWKHKGO  MBDv
+ *           .UB  OOGDM. MK,                                          Copyright (c) 2015-2018.  斯伯坦机器人世界
+ *              ,  XMW  ..
+ *                  r                                                                     All rights reserved.
+ *
+ * ********************************************************************************************************************
+ */
+import './SCanvas'
+import SPoint from './types/SPoint'
+import SMouseEvent from './SMouseEvent'
+
+const bindEvent = Symbol('bindEvent')
+const toSceneMotionEvent = Symbol('toSceneMotionEvent')
+    /**
+     * Graphy图形引擎视图类
+     *
+     * @author  Andy
+     */
+export default class SGraphyView {
+    /**
+     * 构造函数
+     *
+     * @param   id    Canvas对象ID
+     */
+    constructor(id, scene) {
+            this.canvasView = document.getElementById(id)
+            this.canvas = this.canvasView.getContext('2d')
+            this[bindEvent](this.canvasView)
+            this.scene = scene
+            this.pos = new SPoint(10, 0)
+            this.scale = 1
+            this.minScale = 0.004
+            this.maxScale = 0.5
+            this._midKeyX = 0
+            this._midKeyY = 0
+            this.wheelZoom = 1.05
+
+            window.requestAnimationFrame(this.onDraw.bind(this))
+        } // Function constructor()
+
+    /**
+     * 绑定canvas事件
+     *
+     * @param   canvas      canvas对象
+     * @private
+     */
+    [bindEvent](canvasView) {
+        canvasView.onclick = this.onClick.bind(this)
+        canvasView.ondblclick = this.onDbClick.bind(this)
+        canvasView.onmousedown = this.onMouseDown.bind(this)
+        canvasView.onmousemove = this.onMouseMove.bind(this)
+        canvasView.onmouseup = this.onMouseUp.bind(this)
+        canvasView.onmousewheel = this.onMouseWheel.bind(this)
+        canvasView.onresize = this.onResize.bind(this)
+    } // Function [bindEvent]()
+
+    /**
+     * 获取canvas的宽度  
+     */
+
+    get width() {
+        return this.canvasView.width
+    }
+
+    get height() {
+        return this.canvasView.height
+    }
+
+    /**
+     * 将场景中的xy坐标转换成视图坐标。
+     *
+     * @param   x       场景中的横坐标
+     * @param   y       场景中的纵坐标
+     *
+     * @return  SPoint
+     */
+    mapFromScene(x, y = null) {
+            if (typeof(x) === 'object') { // 如果传入的是SPoint对象
+                return new SPoint(x.x * this.scale + this.pos.x, x.y * this.scale + this.pos.y)
+            }
+
+            return new SPoint(x * this.scale + this.pos.x, y * this.scale + this.pos.y)
+        } // Function mapFromScene()
+
+    /**
+     * 将item中的xy坐标转换成场景坐标。
+     *
+     * @param   x       item中的横坐标
+     * @param   y       item中的纵坐标
+     * @return  SPoint
+     */
+    mapToScene(x, y = null) {
+            if (typeof(x) === 'object') { // 如果传入的是SPoint对象
+                return new SPoint((x.x - this.pos.x) / this.scale, (x.y - this.pos.y) / this.scale)
+            }
+
+            return new SPoint((x - this.pos.x) / this.scale, (y - this.pos.y) / this.scale)
+        } // Function mapToScene()
+
+    /**
+     * 缩放视图时计算视图的位置与缩放比例
+     *
+     * @param   zoom        缩放比例
+     * @param   x0          缩放计算的中心点X坐标
+     * @param   y0          缩放计算的中心点Y坐标
+     */
+    scaleByPoint(zoom, x0, y0) {
+            let z = zoom
+                /**
+                 * 缩放比例在最小比例和最大比例范围内
+                 */
+            if (this.scale * zoom >= this.maxScale) { // 大于最大缩放比例
+                z = this.maxScale / this.scale
+                this.scale = this.maxScale
+            } else if (this.scale * zoom <= this.minScale) { // 小于最小绽放比例
+                z = this.minScale / this.scale
+                this.scale = this.minScale
+            } else {
+                this.scale *= zoom
+            }
+
+            this.pos.x = x0 - (x0 - this.pos.x) * z
+            this.pos.y = y0 - (y0 - this.pos.y) * z
+
+            // EventBus.getDefault().post(SGraphyViewZoomEvent(this, scale))
+            // EventBus.getDefault().post(SGraphyViewMoveEvent(this, pos.x, pos.y))
+            // return
+        } // Function scaleByPoint()
+        // ===================================================================================================================
+        // 事件
+    onDraw() {
+            this.canvas.save()
+            this.canvas.clearRect(0, 0, this.canvasView.width, this.canvasView.height)
+            this.canvas.restore()
+
+            if (this.scene != null) {
+                // 绘制背景
+                this.canvas.save()
+                this.scene.drawBackground(this.canvas)
+                this.canvas.restore()
+
+                // 绘制场景
+                this.canvas.save()
+                this.canvas.translate(this.pos.x, this.pos.y)
+                this.canvas.scale(this.scale, this.scale)
+                this.scene.drawScene(this.canvas)
+                this.canvas.restore()
+
+                // 绘制前景
+                this.canvas.save()
+                this.scene.drawForeground(this.canvas)
+                this.canvas.restore()
+            }
+
+            window.requestAnimationFrame(this.onDraw.bind(this))
+        } // Function onDraw()
+
+    /**
+     * 鼠标单击事件
+     *
+     * @param   e   保存事件参数
+     */
+    onClick(e) {
+            if (this.scene != null) {
+                let se = this[toSceneMotionEvent](e)
+                this.scene.onClick(se)
+            }
+        } // Function onClick()
+
+    /**
+     * 鼠标双击事件
+     *
+     * @param   e   保存事件参数
+     */
+    onDbClick(e) {
+            if (this.scene != null) {
+                let ce = this[toSceneMotionEvent](e)
+                this.scene.onDbClick(ce)
+            }
+        } // Function onDbClick()
+
+    /**
+     * 鼠标按下事件
+     *
+     * @param   e   保存事件参数
+     */
+    onMouseDown(e) {
+            let se = new SMouseEvent(e)
+            if (se.buttons & SMouseEvent.MIDDLE_BUTTON) { // 如果按下中键
+                this._midKeyX = e.x
+                this._midKeyY = e.y
+            }
+
+            if (this.scene != null) {
+                let ce = this[toSceneMotionEvent](e)
+                this.scene.onMouseDown(ce)
+            }
+        } // Function onMouseDown()
+
+    /**
+     * 鼠标移动事件
+     *
+     * @param   e   保存事件参数
+     */
+    onMouseMove(e) {
+            let se = new SMouseEvent(e)
+            if (se.buttons & SMouseEvent.MIDDLE_BUTTON) { // 如果按下中键,则移动视图
+                this.pos.x += e.x - this._midKeyX
+                this.pos.y += e.y - this._midKeyY
+                this._midKeyX = e.x
+                this._midKeyY = e.y
+                return
+            }
+            if (this.scene != null) {
+                let ce = this[toSceneMotionEvent](e)
+                this.scene.onMouseMove(ce)
+            }
+        } // Function onMouseMove()
+
+    /**
+     * 释放鼠标事件
+     *
+     * @param   e   保存事件参数
+     */
+    onMouseUp(e) {
+            if (this.scene != null) {
+                let ce = this[toSceneMotionEvent](e)
+                this.scene.onMouseUp(ce)
+            }
+        } // Function onMouseUp()
+
+    /**
+     * 鼠标滚轮事件
+     *
+     * @param   e   保存事件参数
+     */
+    onMouseWheel(e) {
+            let se = new SMouseEvent(e)
+            if (e.wheelDelta < 0) {
+                this.scaleByPoint(1 / this.wheelZoom, se.x, se.y)
+            } else {
+                this.scaleByPoint(this.wheelZoom, se.x, se.y)
+            }
+        } // Function onMouseWheel()
+
+    /**
+     * View大小发生变化事件
+     *
+     * @param   e   保存事件参数
+     */
+    onResize(e) {} // Function onResize()
+
+    /**
+     * MotionEvent转场景对象MotionEvent
+     *
+     * @param   e       MotionEvent
+     * @return  子对象MotionEvent
+     */
+    [toSceneMotionEvent](e) {
+        let se = new SMouseEvent(e)
+        se.x = (se.x - this.pos.x) / this.scale
+        se.y = (se.y - this.pos.y) / this.scale
+        return se
+    } // Function toSceneMotionEvent()
+} // Class SGraphyView

+ 53 - 0
src/assets/graphy/SGraphy/SMouseEvent.js

@@ -0,0 +1,53 @@
+/*
+ * ********************************************************************************************************************
+ *
+ *               iFHS7.
+ *              ;BBMBMBMc                  rZMBMBR              BMB
+ *              MBEr:;PBM,               7MBMMEOBB:             BBB                       RBW
+ *     XK:      BO     SB.     :SZ       MBM.       c;;     ir  BBM :FFr       :SSF:    ;xBMB:r   iuGXv.    i:. iF2;
+ *     DBBM0r.  :D     S7   ;XMBMB       GMBMu.     MBM:   BMB  MBMBBBMBMS   WMBMBMBBK  MBMBMBM  BMBRBMBW  .MBMBMBMBB
+ *      :JMRMMD  ..    ,  1MMRM1;         ;MBMBBR:   MBM  ;MB:  BMB:   MBM. RMBr   sBMH   BM0         UMB,  BMB.  KMBv
+ *     ;.   XOW  B1; :uM: 1RE,   i           .2BMBs  rMB. MBO   MBO    JMB; MBB     MBM   BBS    7MBMBOBM:  MBW   :BMc
+ *     OBRJ.SEE  MRDOWOR, 3DE:7OBM       .     ;BMB   RMR7BM    BMB    MBB. BMB    ,BMR  .BBZ   MMB   rMB,  BMM   rMB7
+ *     :FBRO0D0  RKXSXPR. JOKOOMPi       BMBSSWBMB;    BMBB:    MBMB0ZMBMS  .BMBOXRBMB    MBMDE RBM2;SMBM;  MBB   xBM2
+ *         iZGE  O0SHSPO. uGZ7.          sBMBMBDL      :BMO     OZu:BMBK,     rRBMB0;     ,EBMB  xBMBr:ER.  RDU   :OO;
+ *     ,BZ, 1D0  RPSFHXR. xWZ .SMr                  . .BBB
+ *      :0BMRDG  RESSSKR. 2WOMBW;                   BMBMR
+ *         i0BM: SWKHKGO  MBDv
+ *           .UB  OOGDM. MK,                                          Copyright (c) 2015-2018.  斯伯坦机器人世界
+ *              ,  XMW  ..
+ *                  r                                                                     All rights reserved.
+ *
+ * ********************************************************************************************************************
+ */
+
+/**
+ * 鼠标事件
+ *
+ * @author  Andy
+ */
+export default class SMouseEvent {
+  /**
+   * 构造函数
+   *
+   * @param   e       系统鼠标事件
+   */
+  constructor(e) {
+    let bbox          = e.srcElement.getBoundingClientRect()
+    this.type         = e.type
+    this.x            = e.clientX - bbox.left
+    this.y            = e.clientY - bbox.top
+    this.screenX      = e.screenX
+    this.screenY      = e.screenY
+    this.clientX      = e.clientX
+    this.clientY      = e.clientY
+    this.altKey       = e.altKey
+    this.ctrlKey      = e.ctrlKey
+    this.buttons      = e.buttons
+    this.wheelDelta   = e.wheelDelta
+  } // Function constructor()
+} // Class MouseEvent
+
+SMouseEvent.LEFT_BUTTON   = 0x01
+SMouseEvent.RIGHT_BUTTON  = 0x02
+SMouseEvent.MIDDLE_BUTTON = 0x04

+ 70 - 0
src/assets/graphy/SGraphy/items/SGraphyCircleItem.js

@@ -0,0 +1,70 @@
+/**
+ * 线条
+ */
+import SGraphyItem from '../SGraphyItem'
+import SRect from '../types/SRect';
+
+export default class SGraphyCircleItem extends SGraphyItem {
+    /**
+     * 构造函数
+     * 
+     * @param X  圆中心点X
+     * @param Y  圆中心点Y
+     * @param Radius   圆的半径
+     * 
+     * @param color  线的颜色
+     * @param isVirtual    是否为虚线
+     */
+    constructor(X, Y, color, Radius, isSolid, name, parent = null) {
+        super(parent)
+        this.X = X
+        this.Y = Y
+        this.color = color
+        this.Radius = Radius
+        this.isSolid = isSolid
+        this.minX = this.X - this.Radius
+        this.minY = this.Y - this.Radius
+        this.maxX = this.X + this.Radius
+        this.maxY = this.Y + this.Radius
+        this.sAngle = null || 0
+        this.eAngle = null || 2 * Math.PI
+        this.name = name
+        this.type = 6
+        this.lineWidth = null
+    }
+
+    /**
+     * Item对象边界区域
+     * 
+     * @return SRect
+     */
+    boundingRect() {
+        return new SRect(this.minX, this.minY, this.maxX - this.minX, this.maxY - this.minY)
+    }
+
+    /**
+     * 绘制线条
+     * 
+     * @param canvas 画布
+     * @param rect   绘制区域
+     */
+
+    onDraw(canvas, rect) {
+        canvas.lineWidth = this.lineWidth || 240
+        canvas.strokeStyle = this.color || '#000'
+        canvas.fillStyle = this.color || '#000'
+        canvas.beginPath();
+        canvas.arc(this.X, this.Y, this.Radius, this.sAngle, this.eAngle);
+        if (!!this.isSolid) {
+            canvas.fillStyle = this.color; //填充颜色,默认是黑色
+            canvas.fill(); //画实心圆
+        }
+        canvas.stroke()
+        if (!!this.name) {
+            canvas.font = "oblique small-caps bold " + this.lineWidth * 10 + "px Arial";
+            // canvas.font = "oblique small-caps bold " + 10 + "px Arial";
+            canvas.fillStyle = 'green'
+            canvas.fillText(this.name, this.X, this.Y);
+        }
+    }
+}

+ 201 - 0
src/assets/graphy/SGraphy/items/SGraphyClockItem.js

@@ -0,0 +1,201 @@
+/*
+ * ********************************************************************************************************************
+ *
+ *               iFHS7.
+ *              ;BBMBMBMc                  rZMBMBR              BMB
+ *              MBEr:;PBM,               7MBMMEOBB:             BBB                       RBW
+ *     XK:      BO     SB.     :SZ       MBM.       c;;     ir  BBM :FFr       :SSF:    ;xBMB:r   iuGXv.    i:. iF2;
+ *     DBBM0r.  :D     S7   ;XMBMB       GMBMu.     MBM:   BMB  MBMBBBMBMS   WMBMBMBBK  MBMBMBM  BMBRBMBW  .MBMBMBMBB
+ *      :JMRMMD  ..    ,  1MMRM1;         ;MBMBBR:   MBM  ;MB:  BMB:   MBM. RMBr   sBMH   BM0         UMB,  BMB.  KMBv
+ *     ;.   XOW  B1; :uM: 1RE,   i           .2BMBs  rMB. MBO   MBO    JMB; MBB     MBM   BBS    7MBMBOBM:  MBW   :BMc
+ *     OBRJ.SEE  MRDOWOR, 3DE:7OBM       .     ;BMB   RMR7BM    BMB    MBB. BMB    ,BMR  .BBZ   MMB   rMB,  BMM   rMB7
+ *     :FBRO0D0  RKXSXPR. JOKOOMPi       BMBSSWBMB;    BMBB:    MBMB0ZMBMS  .BMBOXRBMB    MBMDE RBM2;SMBM;  MBB   xBM2
+ *         iZGE  O0SHSPO. uGZ7.          sBMBMBDL      :BMO     OZu:BMBK,     rRBMB0;     ,EBMB  xBMBr:ER.  RDU   :OO;
+ *     ,BZ, 1D0  RPSFHXR. xWZ .SMr                  . .BBB
+ *      :0BMRDG  RESSSKR. 2WOMBW;                   BMBMR
+ *         i0BM: SWKHKGO  MBDv
+ *           .UB  OOGDM. MK,                                          Copyright (c) 2015-2018.  斯伯坦机器人世界
+ *              ,  XMW  ..
+ *                  r                                                                     All rights reserved.
+ *
+ * ********************************************************************************************************************
+ */
+
+import SGraphyItem from '../SGraphyItem'
+import SRect from '../types/SRect'
+
+/** 定义符号,用于定义私有成员变晴儿 */
+const drawScale     = Symbol('drawScale')
+const drawScaleText = Symbol('drawScaleText')
+const drawHour      = Symbol('drawHour')
+const drawMinute    = Symbol('drawMinute')
+const drawSecond    = Symbol('drawSecond')
+
+/**
+ * SGraphy引擎时钟Item
+ *
+ * @author  Andy
+ */
+export default class SGraphyClockItem extends SGraphyItem {
+  /**
+   * 构造函数
+   *
+   * @param   parent    指向父对象
+   */
+  constructor(width, height, parent = null) {
+    super(parent)
+    this.name = 'ClockItem'
+    this.width = width
+    this.height = height
+    /** 是否显示刻度 */
+    this.isShowScale = true
+    /** 刻度颜色 */
+    this.scaleColor = '#000'
+    /** 刻度文本颜色 */
+    this.textColor = '#000'
+    /** 时针颜色 */
+    this.hourColor = '#000'
+    /** 分针颜色 */
+    this.minuteColor = '#000'
+    /** 秒针颜色 */
+    this.secondColor = '#F00'
+    /** 是否显示钞针 */
+    this.isShowSecond = true
+    /** 是否平滑移动秒针 */
+    this.isSmooth = true
+    /** 边缘宽度 */
+    this.padding = 100.0
+  } // Function constructor()
+
+  /**
+   * Item对象边界区域
+   *
+   * @return  SRect
+   */
+  boundingRect() {
+    return new SRect(0, 0, this.width / 2, this.height / 2)
+  } // Function boundingRect()
+
+  /**
+   * 时钟半径,只读属性
+   *
+   * @return  number
+   */
+  get radius() {
+    return Math.min(this.width, this.height) / 2.0
+  } // getter radius()
+
+  /**
+   * 绘制时钟
+   *
+   * @param   canvas      画布
+   * @param   rect        绘制区域
+   */
+  onDraw(canvas, rect) {
+    canvas.translate(this.width / 2, this.height / 2)
+    canvas.arc(0, 0, this.radius, 0, 2 * Math.PI)
+    let t = new Date()
+
+    this[drawScale](canvas)
+    this[drawHour](canvas, t.getHours(), t.getMinutes(), t.getSeconds())
+    this[drawMinute](canvas, t.getMinutes(), t.getSeconds())
+    this[drawSecond](canvas, t.getSeconds() + t.getMilliseconds() / 1000.0)
+  } // Function onDraw()
+
+  /**
+   * 绘制刻度
+   *
+   * @param   canvas      画布
+   */
+  [drawScale](canvas) {
+    let scaleLength = Math.max(this.radius / 10.0, 2.0)
+    let scaleLength1 = scaleLength * 1.2
+    let strokeWidth = Math.max(this.radius / 100.0, 2.0)
+    let strokeWidth1 = strokeWidth * 2.0
+
+    canvas.save()
+    canvas.strokeStyle = this.scaleColor
+
+    for (let i = 1; i <= 12; i++) {          // 12小时刻度
+      canvas.lineWidth = strokeWidth1
+      canvas.drawLine(0, -this.radius, 0, -this.radius + scaleLength1)
+
+      if (this.radius >= 40) {              // 如果半度大于40显示分钟刻度
+        canvas.rotate(6 * Math.PI / 180)
+        for (let j = 1; j <= 4; j++) {       // 分钟刻度
+          canvas.lineWidth = strokeWidth
+          canvas.drawLine(0, -this.radius, 0, -this.radius + scaleLength)
+          canvas.rotate(6 * Math.PI / 180)
+        }
+      } else {
+        canvas.rotate(30 * Math.PI / 180)
+      }
+    }
+
+    canvas.restore()
+  } // Function drawScale()
+
+  /**
+   * 绘制刻度数字
+   *
+   * @param   canvas      画布
+   */
+  [drawScaleText](canvas) {
+
+  } // Function drawScaleText()
+
+  /**
+   * 绘制时针
+   *
+   * @param   canvas      画布
+   * @param   hour        时
+   * @param   minute      分
+   * @param   second      秒
+   */
+  [drawHour](canvas, hour, minute, second) {
+    canvas.save()
+    canvas.lineCap = 'round'
+    canvas.lineWidth = Math.max(this.radius / 30.0, 4.0)
+    canvas.strokeStyle = this.hourColor
+    canvas.rotate((hour * 30.0 + minute * 30.0 / 60 + second * 30.0 / 60 / 60) * Math.PI / 180)
+    canvas.drawLine(0, this.radius / 10.0, 0, -this.radius / 2.0)
+    canvas.restore()
+  } // Function drawHour()
+
+  /**
+   * 绘制分针
+   *
+   * @param   canvas      画布
+   * @param   minute      分
+   * @param   second      秒
+   */
+  [drawMinute](canvas, minute, second) {
+    canvas.save()
+    canvas.lineCap = 'round'
+    canvas.lineWidth = Math.max(this.radius / 40.0, 4.0)
+    canvas.strokeStyle = this.minuteColor
+    canvas.rotate((minute * 6 + second * 6 / 60.0) * Math.PI / 180.0)
+    canvas.drawLine(0, this.radius / 10.0, 0, -this.radius * 2.0 / 3.0)
+    canvas.restore()
+  } // Function drawMinute()
+
+  /**
+   * 绘制秒针
+   *
+   * @param   canvas      画布
+   * @param   second      秒
+   */
+  [drawSecond](canvas, second) {
+    canvas.save()
+    canvas.lineCap = 'round'
+    canvas.lineWidth = Math.max(this.radius / 100.0, 3.0)
+    canvas.strokeStyle = this.secondColor
+    canvas.rotate(second * 6 * Math.PI / 180)
+    canvas.drawLine(0, this.radius / 5.0, 0, -this.radius + this.radius / 10.0)
+    // canvas.drawCircle(0, 0, this.radius / 30.0)
+    // canvas.drawCircle(0, -this.radius + this.radius / 5.0, this.radius / 60.0)
+    // canvas.strokeStyle = Color.YELLOW
+    // canvas.drawCircle(0, 0, this.radius / 100.0)
+    canvas.restore()
+  } // Function drawSecond()
+} // Class SGraphyClockItem

+ 59 - 0
src/assets/graphy/SGraphy/items/SGraphyImageItem.js

@@ -0,0 +1,59 @@
+/**
+ * 图片
+ * 
+ * 
+ */
+import SGraphyItem from '../SGraphyItem'
+import SRect from '../types/SRect'
+export default class SGraphyImageItem extends SGraphyItem {
+    /**
+     * 构造函数
+     * 
+     * @param width  图片宽度
+     * @param height  图片高度
+     * @param url    图片url
+     * @param id     point的Id
+     * @param X      图片向x轴的偏移量
+     * @param Y      图片向y轴的偏移量
+     * @param downUrl 图片按下时的url
+     * @param parent  指向父元素
+     */
+    constructor(width, height, url, id, X, Y, downUrl, parent = null) {
+            super(parent)
+            this.width = width
+            this.height = height
+            this.url = url
+            this.id = id
+            this.X = X
+            this.Y = Y
+            this.downUrl = downUrl
+            this.imgFalg = false
+            this.img = new Image()
+            this.img.src = this.url
+            this.img.style.width = this.width
+            this.img.style.height = this.height
+            this.canMove = true
+            this.type = 1
+        } //constructor
+
+    /**
+     * Item对象边界区域
+     *
+     * @return  SRect
+     */
+    boundingRect() {
+            return new SRect(0, 0, this.width * 100, this.height * 100)
+        } // Function boundingRect()
+
+    /**
+     * 绘制图片
+     * 
+     * @param canvas 画布
+     * @param rect   绘制区域
+     */
+    onDraw(canvas, rect) {
+        // canvas.moveTo(this.X, this.Y)
+        // canvas.drawImage(this.img, 0, 0, this.width, this.height, this.X, this.Y, this.width * 100, this.height * 100)
+        canvas.drawImage(this.img, 0, 0, this.width, this.height, 0, 0, this.width * 100, this.height * 100)
+    }
+}

+ 66 - 0
src/assets/graphy/SGraphy/items/SGraphyLineItem.js

@@ -0,0 +1,66 @@
+/**
+ * 线条
+ */
+import SGraphyItem from '../SGraphyItem'
+import SRect from '../types/SRect';
+
+export default class SGraphyLineItem extends SGraphyItem {
+    /**
+     * 构造函数
+     * 
+     * @param startX  线的起始x坐标
+     * @param startY  线的起始y坐标
+     * @param endX    线的终止x坐标
+     * @param endY    线的终止y坐标
+     * @param width   线的宽度
+     * 
+     * @param color  线的颜色
+     * @param isVirtual    是否为虚线
+     */
+    constructor(startX, startY, endX, endY, color, width, isVirtual, parent = null) {
+        super(parent)
+        this.startX = startX
+        this.startY = startY
+        this.endX = endX
+        this.endY = endY
+        this.color = color
+        this.width = width
+        this.isVirtual = isVirtual
+        this.minX = Math.min(this.startX, this.endX)
+        this.minY = Math.min(this.startY, this.endY)
+        this.maxX = Math.max(this.startX, this.endX)
+        this.maxY = Math.max(this.startY, this.endY)
+        this.name = null
+        this.type = 2
+        this.lineWidth = null
+    }
+
+    /**
+     * Item对象边界区域
+     * 
+     * @return SRect
+     */
+    boundingRect() {
+        return new SRect(this.minX, this.minY, this.maxX - this.minX, this.maxY - this.minY)
+    }
+
+    /**
+     * 绘制线条
+     * 
+     * @param canvas 画布
+     * @param rect   绘制区域
+     */
+
+    onDraw(canvas, rect) {
+        canvas.lineWidth = this.lineWidth || this.width || 240
+        canvas.strokeStyle = this.color || '#000'
+        if (this.isVirtual) {
+            canvas.setLineDash([100, 80])
+            canvas.strokeStyle = 'green'
+        }
+        canvas.beginPath();
+        canvas.moveTo(this.startX, this.startY)
+        canvas.lineTo(this.endX, this.endY)
+        canvas.stroke()
+    }
+}

+ 76 - 0
src/assets/graphy/SGraphy/items/SGraphyPillarItems.js

@@ -0,0 +1,76 @@
+/**
+ * 不规则多边形,元空间
+ */
+import SGraphyItem from '../SGraphyItem'
+import SRect from '../types/SRect';
+
+function getItem(arr, name) {
+    if (arr && arr.length) {
+        return arr.map(item => {
+            return item[name]
+        })
+    } else {
+        return [0]
+    }
+}
+
+
+export default class SGraphyPolygonItem extends SGraphyItem {
+    /**
+     * 
+     * 构造函数
+     * 
+     * @param jsonArr  空间线条数组
+     * @param lineWidth    空间线条的宽度
+     * @param color    空间线条的颜色
+     * @param fillColor  空间的填充颜色
+     * 
+     */
+    constructor(jsonArr, lineWidth, color, fillColor, parent = null) {
+            super(parent)
+            this.jsonArr = jsonArr
+            this.lineWidth = lineWidth
+            this.color = color
+            this.fillColor = fillColor
+            let xArr = getItem(this.jsonArr, 'X')
+            let yArr = getItem(this.jsonArr, 'Y')
+            this.minX = Math.min.apply(null, xArr) || 0
+            this.minY = Math.min.apply(null, yArr) || 0
+            this.width = Math.max.apply(null, xArr) - this.minX || 0
+            this.height = Math.max.apply(null, yArr) - this.minY || 0
+            this.type = 5
+        } //constructor
+
+    /**
+     * Item的边界区域
+     * 
+     * @return SRect
+     */
+    boundingRect() {
+        return new SRect(this.minX, this.minY, this.width, this.height)
+    }
+
+    /**
+     * 绘制不规则多边形
+     * 
+     * @param canvas 画布
+     * @param rect   绘制区域
+     */
+    onDraw(canvas, rect) {
+        if (this.jsonArr && this.jsonArr.length) {
+            canvas.beginPath();
+            canvas.lineWidth = 240
+            canvas.lineCap = 'butt';
+            canvas.strokeStyle = this.color || '#000'
+            canvas.fillStyle = this.fillColor || '#fff'
+            canvas.moveTo(this.jsonArr[0].X, this.jsonArr[0].Y)
+            for (let i = 1; i < this.jsonArr.length; i++) {
+                canvas.lineTo(this.jsonArr[i].X, this.jsonArr[i].Y)
+            }
+            canvas.lineTo(this.jsonArr[0].X, this.jsonArr[0].Y)
+            canvas.closePath()
+            canvas.fill()
+            canvas.stroke()
+        }
+    }
+}

+ 257 - 0
src/assets/graphy/SGraphy/items/SGraphyPolygonItem.js

@@ -0,0 +1,257 @@
+/**
+ * 不规则多边形,元空间
+ */
+import SGraphyItem from '../SGraphyItem'
+import SRect from '../types/SRect';
+
+function getItem(arr, name) {
+    if (arr && arr.length) {
+        return arr.map(item => {
+            return item[name]
+        })
+    } else {
+        return [0]
+    }
+}
+
+function changeArr(arr) {
+    if (arr && arr.length) {
+        return arr.map(item => {
+            return [
+                item.X, item.Y
+            ]
+        })
+    } else {
+        return [0]
+    }
+}
+/**
+ * 求不规则多边形重点
+ * @param {points} 数组,多个点位坐标
+ *  
+ * @return {x, y} 重点点位坐标
+ */
+// function getCenterOfGravityPoint(points) {
+//     let area = 0,
+//         gx = 0,
+//         gy = 0,
+//         i = 1,
+//         px1, px2, py1, py2, temp, length = points.length;
+//     for (i; i <= length; i++) {
+//         px1 = points[(i % length)].X;
+//         px2 = points[(i - 1)].X;
+//         py1 = points[(i % length)].Y;
+//         py2 = points[(i - 1)].Y;
+//         temp = (px1 * py2 - py1 * px2) / 2
+//         area += temp;
+//         gx += temp * (px1 + px2) / 3
+//         gy += temp * (py1 + py2) / 3
+//     }
+
+//     gx = gx / area
+//     gy = gy / area
+
+//     return {
+//         x: gx,
+//         y: gy
+//     }
+// }
+
+
+export default class SGraphyPolygonItem extends SGraphyItem {
+    /**
+     * 
+     * 构造函数
+     * 
+     * @param jsonArr  空间线条数组
+     * @param lineWidth    空间线条的宽度
+     * @param color    空间线条的颜色
+     * @param fillColor  空间的填充颜色
+     * 
+     */
+    constructor(jsonArr, lineWidth, color, fillColor, id, centerOfGravityPoint, name, paths, faceColor, businessColor, isBusiness, parent = null) {
+            super(parent)
+            this.jsonArr = jsonArr
+            this.lineWidth = lineWidth
+            this.color = color
+            this.id = id
+            this.name = name //实际渲染名字
+            this.fillColor = fillColor
+            let xArr = getItem(this.jsonArr, 'X')
+            let yArr = getItem(this.jsonArr, 'Y')
+            this.minX = Math.min.apply(null, xArr) || 0
+            this.maxX = Math.max.apply(null, xArr) || 0
+            this.maxY = Math.max.apply(null, yArr) || 0
+            this.minY = Math.min.apply(null, yArr) || 0
+            this.width = this.maxX - this.minX || 0
+            this.height = this.maxY - this.minY || 0
+            this.type = 3
+            this.businessName = null
+            this.faceColor = faceColor || '#cacaca' //颜色
+            this.businessId = null //业务空间id
+            this.isBusiness = isBusiness || 1 //状态
+            this.businessColor = businessColor || 'rgba(68,161,140,.4)' //业务空间颜色
+            this.businessFaceColor = "#333"
+            this.containsArr = changeArr(this.jsonArr)
+            this.paths = null
+            if (paths && paths.length > 1) {
+                this.paths = paths.map(item => {
+                    if (item && item.length) {
+                        return changeArr(item)
+                    } else {
+                        return undefined
+                    }
+                }).filter(d => d)
+            }
+            this.centerOfGravityPoint = centerOfGravityPoint
+        } //constructor
+
+    /**
+     * Item的边界区域
+     * 
+     * @return SRect
+     */
+    boundingRect() {
+        return new SRect(this.minX, this.minY, this.width, this.height)
+    }
+
+
+    /**
+     * 判断item是否包含点x,y
+     *
+     * @param   x       横坐标(当前item)
+     * @param   y       纵坐标(当前item)
+     *
+     * @return  boolean
+     */
+    contains(x, y) {
+        let falg = false,
+            isFullIn = false //是否在镂空图形内
+        if (this.paths instanceof Array) {
+            for (let i = 1; i < this.paths.length; i++) {
+                if (this.isIn(x, y, this.paths[i])) {
+                    //位置信息在镂空图形内
+                    isFullIn = true
+                    break
+                }
+            }
+            // //如果鼠标在大图形内切在镂空图形中返回false
+            if (this.isIn(x, y, this.containsArr) && isFullIn) {
+                falg = false
+            } else if (this.isIn(x, y, this.containsArr) && !isFullIn) {
+                falg = true
+            } else {
+                falg = this.isIn(x, y, this.containsArr)
+            }
+        } else {
+            falg = this.isIn(x, y, this.containsArr)
+        }
+        return falg
+    }
+
+
+    isIn(x, y, json) {
+        let nCross = 0,
+            point = typeof(x) == 'object' ? [x.x, x.y] : [x, y],
+            APoints = json,
+            length = APoints.length,
+            p1, p2, i, xinters;
+        p1 = APoints[0];
+        for (i = 1; i <= length; i++) {
+            p2 = APoints[i % length];
+            if (
+                point[0] > Math.min(p1[0], p2[0]) &&
+                point[0] <= Math.max(p1[0], p2[0])
+            ) {
+                if (point[1] <= Math.max(p1[1], p2[1])) {
+                    if (p1[0] != p2[0]) {
+                        //计算位置信息
+                        xinters = (point[0] - p1[0]) * (p2[1] - p1[1]) / (p2[0] - p1[0]) + p1[1];
+                        if (p1[1] == p2[1] || point[1] <= xinters) {
+                            nCross++
+                        }
+                    }
+                }
+            }
+            p1 = p2;
+        }
+        if (nCross % 2 == 0) {
+            return false
+        } else {
+            return true
+        }
+
+    }
+
+    /**
+     * 绘制不规则多边形
+     * 
+     * @param canvas 画布
+     * @param rect   绘制区域
+     */
+    onDraw(canvas, rect) {
+        if (this.jsonArr && this.jsonArr.length) {
+            canvas.beginPath();
+            canvas.lineWidth = 220
+            canvas.lineCap = 'butt';
+            if (this.isBusiness == 1) {
+                canvas.strokeStyle = this.color || '#000'
+                canvas.fillStyle = this.fillColor
+            } else if (this.isBusiness == 2) {
+                //已有id 的业务空间
+                canvas.strokeStyle = this.color || '#000'
+                canvas.fillStyle = this.businessColor || '#fff'
+            } else if (this.isBusiness == 3) {
+                //被选择的元空间
+                canvas.strokeStyle = this.color || '#000'
+                canvas.lineWidth = 800
+                canvas.fillStyle = '#1abc9c'
+            } else if (this.isBusiness == 4) {
+                canvas.strokeStyle = 'rgba(251,226,1,.8)' || '#000'
+                canvas.fillStyle = '#fff' || '#fff'
+            } else if (this.isBusiness == 5) {
+                canvas.fillStyle = 'rgba(11,12,12,.2)' || '#fff'
+            } else if (this.isBusiness == 6) {
+                canvas.fillStyle = '#1abc9c'
+                canvas.lineWidth = 800
+                canvas.strokeStyle = 'rgba(68,161,140,.4)' || '#fff'
+            } else if (this.isBusiness == 7) {
+                canvas.strokeStyle = this.color || '#000'
+                canvas.fillStyle = this.businessColor || '#fff'
+            }
+            canvas.moveTo(this.jsonArr[0].X, this.jsonArr[0].Y)
+            for (let i = 1; i < this.jsonArr.length; i++) {
+                canvas.lineTo(this.jsonArr[i].X, this.jsonArr[i].Y)
+            }
+            canvas.lineTo(this.jsonArr[0].X, this.jsonArr[0].Y)
+            canvas.closePath()
+            canvas.fill()
+            canvas.stroke()
+            if (!!this.name) {
+                canvas.font = "normal small-caps bold 500px Arial";
+                if (this.isBusiness == 1) {
+                    canvas.fillStyle = this.faceColor
+                } else if (this.isBusiness == 2) {
+                    canvas.fillStyle = this.businessFaceColor;
+                } else if (this.isBusiness == 3) {
+                    //业务空间异常状态
+                    canvas.fillStyle = '#fff'
+                } else if (this.isBusiness == 4) {
+                    canvas.fillStyle = '#cacaca'
+                } else if (this.isBusiness == 6) {
+                    canvas.fillStyle = '#fff'
+                } else if (this.isBusiness == 7) {
+                    canvas.fillStyle = 'red'
+                }
+                if (!!this.businessName || !!this.businessId) {
+                    name = '👇   ' + this.businessName
+                } else {
+                    name = '⬇️   ' + this.name
+                }
+                canvas.fillText(name, this.centerOfGravityPoint.x, this.centerOfGravityPoint.y);
+                // canvas.fillText(this.name, (this.maxX - this.minX) / 2 + this.minX, (this.maxY - this.minY) / 2 + this.minY);
+            }
+            // canvas.fillText(this.name, this.jsonArr[0].X, this.jsonArr[0].Y);
+        }
+    }
+}

+ 100 - 0
src/assets/graphy/SGraphy/items/SGraphyRectItem.js

@@ -0,0 +1,100 @@
+/**
+ * 线条
+ */
+import SGraphyItem from '../SGraphyItem'
+import SRect from '../types/SRect';
+
+export default class SGraphyRectItem extends SGraphyItem {
+    /**
+     * 构造函数
+     * 
+     * @param X  矩形的开始点X
+     * @param Y  矩形的开始点Y
+     * @param width   矩形的宽度
+     * @param height  矩形的高度
+     * 
+     * @param isFill  矩形的是否填充
+     * @param fillColor  矩形的填充色彩
+     * @param text  矩形的文字
+     * @param textSize  矩形的文字大小
+     * @param color  矩形的颜色
+     * @param Tip   提示
+     */
+    constructor(X, Y, width, height, isFill, fillColor, text, textSize, color, Tip, parent = null) {
+        super(parent)
+        this.X = X
+        this.Y = Y
+        this.width = width
+        this.height = height
+        this.isFill = isFill
+        this.fillColor = fillColor
+        this.color = color
+        this.textSize = textSize || 6
+        this.type = 10
+        this.hoverColor = null
+        this.text = text.split(",")
+        this.fontStart = this.X
+        this.Tip = Tip
+    }
+
+    /**
+     * Item对象边界区域
+     * 
+     * @return SRect
+     */
+    boundingRect() {
+        return new SRect(this.X, this.Y, this.width, this.height)
+    }
+
+    /**
+     * 判断item是否包含点x,y
+     *
+     * @param   x       横坐标(当前item)
+     * @param   y       纵坐标(当前item)
+     *
+     * @return  boolean
+     */
+    contains(x) {
+        if (this.X + this.width > x.x && x.x > this.X && this.Y + this.height > x.y && x.y > this.Y) {
+            return true
+        } else {
+            return false
+        }
+    }
+
+    /**
+     * 绘制线条
+     * 
+     * @param canvas 画布
+     * @param rect   绘制区域
+     */
+
+    onDraw(canvas, rect) {
+        canvas.beginPath();
+        canvas.lineWidth = "1";
+        if (this.isFill) {
+            if (!!this.hoverColor) {
+                canvas.fillStyle = this.hoverColor
+            } else {
+                canvas.fillStyle = this.fillColor
+            }
+            canvas.fillRect(this.X, this.Y, this.width, this.height);
+        } else {
+            canvas.rect(this.X, this.Y, this.width, this.height);
+        }
+        canvas.stroke();
+        if (!!this.text && this.text.length <= 1) {
+            canvas.font = this.textSize + "px 宋体";
+            canvas.fillStyle = this.color
+            canvas.fillText(this.text[0], this.fontStart, this.Y + this.height / 2);
+        } else if (!!this.text && this.text.length > 1) {
+            canvas.font = this.textSize + "px 宋体";
+            canvas.fillStyle = this.color
+            for (let i = 0; i < this.text.length; i++) {
+                canvas.fillText(this.text[i], this.fontStart, this.Y + this.height / 2 - this.textSize * i);
+            }
+        } else {
+            return
+        }
+    }
+}

+ 51 - 0
src/assets/graphy/SGraphy/items/SGraphyTextItems.js

@@ -0,0 +1,51 @@
+/**
+ * 线条
+ */
+import SGraphyItem from '../SGraphyItem'
+import SRect from '../types/SRect';
+
+export default class SGraphyTextItem extends SGraphyItem {
+    /**
+     * 构造函数
+     * 
+     * @param X  文字的开始点X
+     * @param Y  文字的开始点Y
+     * @param width   文字的宽度
+     * 
+     * @param color  文字的颜色
+     * @param text   文字的文字
+     */
+    constructor(X, Y, width, color, text, falg, font, parent = null) {
+        super(parent)
+        this.X = X
+        this.Y = Y
+        this.lineWidth = width
+        this.color = color
+        this.font = font ? font : "6px 宋体"
+        this.text = falg ? text + '→' : text
+    }
+
+    /**
+     * Item对象边界区域
+     * 
+     * @return SRect
+     */
+    boundingRect() {
+        return new SRect(this.X, this.Y, 0, 0)
+    }
+
+    /**
+     * 绘制线条
+     * 
+     * @param canvas 画布
+     * @param rect   绘制区域
+     */
+
+    onDraw(canvas, rect) {
+        if (!!this.text) {
+            canvas.font = this.font;
+            canvas.fillStyle = this.color
+            canvas.fillText(this.text, this.X, this.Y);
+        }
+    }
+}

+ 66 - 0
src/assets/graphy/SGraphy/items/SGraphyVirtualItem.js

@@ -0,0 +1,66 @@
+/**
+ * 线条
+ */
+import SGraphyItem from '../SGraphyItem'
+import SRect from '../types/SRect';
+
+export default class SGraphyLineItem extends SGraphyItem {
+    /**
+     * 构造函数
+     * 
+     * @param startX  线的起始x坐标
+     * @param startY  线的起始y坐标
+     * @param endX    线的终止x坐标
+     * @param endY    线的终止y坐标
+     * @param width   线的宽度
+     * 
+     * @param color  线的颜色
+     * @param isVirtual    是否为虚线
+     * 
+     * @param canMove  移动
+     */
+    constructor(startX, startY, endX, endY, color, width, isVirtual, canMove, parent = null) {
+        super(parent)
+        this.startX = startX
+        this.startY = startY
+        this.endX = endX
+        this.endY = endY
+        this.color = color
+        this.width = width
+        this.isVirtual = isVirtual
+        this.minX = Math.min(this.startX, this.endX)
+        this.minY = Math.min(this.startY, this.endY)
+        this.maxX = Math.max(this.startX, this.endX)
+        this.maxY = Math.max(this.startY, this.endY)
+        this.type = 4
+            // this.canMove = true
+    }
+
+    /**
+     * Item对象边界区域
+     * 
+     * @return SRect
+     */
+    boundingRect() {
+        return new SRect(this.minX, this.minY, (this.maxX - this.minX), (this.maxY - this.minY))
+    }
+
+    /**
+     * 绘制线条
+     * 
+     * @param canvas 画布
+     * @param rect   绘制区域
+     */
+
+    onDraw(canvas, rect) {
+        if (this.isVirtual) {
+            canvas.setLineDash([240, 240])
+        }
+        canvas.lineWidth = 240
+        canvas.strokeStyle = this.color || '#000'
+        canvas.beginPath();
+        canvas.moveTo(this.startX, this.startY)
+        canvas.lineTo(this.endX, this.endY)
+        canvas.stroke()
+    }
+}

+ 40 - 0
src/assets/graphy/SGraphy/types/SPoint.js

@@ -0,0 +1,40 @@
+/*
+ * ********************************************************************************************************************
+ *
+ *               iFHS7.
+ *              ;BBMBMBMc                  rZMBMBR              BMB
+ *              MBEr:;PBM,               7MBMMEOBB:             BBB                       RBW
+ *     XK:      BO     SB.     :SZ       MBM.       c;;     ir  BBM :FFr       :SSF:    ;xBMB:r   iuGXv.    i:. iF2;
+ *     DBBM0r.  :D     S7   ;XMBMB       GMBMu.     MBM:   BMB  MBMBBBMBMS   WMBMBMBBK  MBMBMBM  BMBRBMBW  .MBMBMBMBB
+ *      :JMRMMD  ..    ,  1MMRM1;         ;MBMBBR:   MBM  ;MB:  BMB:   MBM. RMBr   sBMH   BM0         UMB,  BMB.  KMBv
+ *     ;.   XOW  B1; :uM: 1RE,   i           .2BMBs  rMB. MBO   MBO    JMB; MBB     MBM   BBS    7MBMBOBM:  MBW   :BMc
+ *     OBRJ.SEE  MRDOWOR, 3DE:7OBM       .     ;BMB   RMR7BM    BMB    MBB. BMB    ,BMR  .BBZ   MMB   rMB,  BMM   rMB7
+ *     :FBRO0D0  RKXSXPR. JOKOOMPi       BMBSSWBMB;    BMBB:    MBMB0ZMBMS  .BMBOXRBMB    MBMDE RBM2;SMBM;  MBB   xBM2
+ *         iZGE  O0SHSPO. uGZ7.          sBMBMBDL      :BMO     OZu:BMBK,     rRBMB0;     ,EBMB  xBMBr:ER.  RDU   :OO;
+ *     ,BZ, 1D0  RPSFHXR. xWZ .SMr                  . .BBB
+ *      :0BMRDG  RESSSKR. 2WOMBW;                   BMBMR
+ *         i0BM: SWKHKGO  MBDv
+ *           .UB  OOGDM. MK,                                          Copyright (c) 2015-2018.  斯伯坦机器人世界
+ *              ,  XMW  ..
+ *                  r                                                                     All rights reserved.
+ *
+ * ********************************************************************************************************************
+ */
+
+/**
+ * 坐标点
+ *
+ * @author  Andy
+ */
+export default class SPoint {
+  /**
+   * 构造函数
+   *
+   * @param   x     X坐标
+   * @param   y     Y坐标
+   */
+  constructor(x, y) {
+    this.x = x
+    this.y = y
+  } // constructor
+} // Class SPoint

+ 169 - 0
src/assets/graphy/SGraphy/types/SRect.js

@@ -0,0 +1,169 @@
+/*
+ * ********************************************************************************************************************
+ *
+ *               iFHS7.
+ *              ;BBMBMBMc                  rZMBMBR              BMB
+ *              MBEr:;PBM,               7MBMMEOBB:             BBB                       RBW
+ *     XK:      BO     SB.     :SZ       MBM.       c;;     ir  BBM :FFr       :SSF:    ;xBMB:r   iuGXv.    i:. iF2;
+ *     DBBM0r.  :D     S7   ;XMBMB       GMBMu.     MBM:   BMB  MBMBBBMBMS   WMBMBMBBK  MBMBMBM  BMBRBMBW  .MBMBMBMBB
+ *      :JMRMMD  ..    ,  1MMRM1;         ;MBMBBR:   MBM  ;MB:  BMB:   MBM. RMBr   sBMH   BM0         UMB,  BMB.  KMBv
+ *     ;.   XOW  B1; :uM: 1RE,   i           .2BMBs  rMB. MBO   MBO    JMB; MBB     MBM   BBS    7MBMBOBM:  MBW   :BMc
+ *     OBRJ.SEE  MRDOWOR, 3DE:7OBM       .     ;BMB   RMR7BM    BMB    MBB. BMB    ,BMR  .BBZ   MMB   rMB,  BMM   rMB7
+ *     :FBRO0D0  RKXSXPR. JOKOOMPi       BMBSSWBMB;    BMBB:    MBMB0ZMBMS  .BMBOXRBMB    MBMDE RBM2;SMBM;  MBB   xBM2
+ *         iZGE  O0SHSPO. uGZ7.          sBMBMBDL      :BMO     OZu:BMBK,     rRBMB0;     ,EBMB  xBMBr:ER.  RDU   :OO;
+ *     ,BZ, 1D0  RPSFHXR. xWZ .SMr                  . .BBB
+ *      :0BMRDG  RESSSKR. 2WOMBW;                   BMBMR
+ *         i0BM: SWKHKGO  MBDv
+ *           .UB  OOGDM. MK,                                          Copyright (c) 2015-2018.  斯伯坦机器人世界
+ *              ,  XMW  ..
+ *                  r                                                                     All rights reserved.
+ *
+ * ********************************************************************************************************************
+ */
+
+/**
+ * 矩形
+ *
+ * @author  Andy
+ */
+export default class SRect {
+  /**
+   * 构造函数
+   *
+   * @param   x       X坐标
+   * @param   y       Y坐标
+   * @param   width   宽度
+   * @param   height  高度
+   */
+  constructor(x = 0, y = 0, width = 0, height = 0) {
+    this._x = x
+    this._y = y
+    this._width = Math.max(width, 0)
+    this._height = Math.max(height, 0)
+  } // constructor
+
+  /**
+   * left属性
+   */
+  get left() {
+    return this._x
+  }
+  set left(value) {
+    this._x = value
+  }
+
+  /**
+   * right属性
+   */
+  get right() {
+    return this._x + this._width
+  }
+  set right(value) {
+    this._width = Math.max(value - this._x, 0)
+  }
+
+  /**
+   * top属性
+   */
+  get top() {
+    return this._y
+  }
+  set top(value) {
+    this._y = value
+  }
+
+  /**
+   * top属性
+   */
+  get bottom() {
+    return this._y + this._height
+  }
+  set bottom(value) {
+    this._height = Math.max(value - this._y, 0)
+  }
+
+  /**
+   * x属性
+   *
+   * @return {*}
+   */
+  get x() {
+    return this._x
+  }
+  set x(value) {
+    this._x = value
+  }
+
+  /**
+   * x属性
+   *
+   * @return {*}
+   */
+  get y() {
+    return this._y
+  }
+  set y(value) {
+    this._y = value
+  }
+
+  /**
+   * width 属性
+   *
+   * @return {number}
+   */
+  get width() {
+    return this._width
+  }
+  set width(value) {
+    this._width = Math.max(value, 0)
+  }
+
+  /**
+   * height 属性
+   * @return {number}
+   */
+  get height() {
+    return this._height
+  }
+  set height(value) {
+    this._height = Math.max(value, 0)
+  }
+
+  /**
+   * 判断矩形空间是否包含点x,y
+   *
+   * @param   x       横坐标(当前item)
+   * @param   y       纵坐标(当前item)
+   * @return  boolean
+   */
+  contains(x, y) {
+    return (x >= this.x && x <= this.right) && (y >= this.top && y <= this.bottom)
+  } // Function contains()
+
+  /**
+   * 调整Rect位置
+   *
+   * @param x
+   * @param y
+   * @return  SRect
+   */
+  adjusted(x, y = null) {
+    if (typeof (x) === 'object') {     // 如果传入的是SPoint对象
+      return new SRect(this.x + x.x, this.y + x.y, this.width, this.height)
+    }
+
+    return new SRect(this.x + x, this.y + y, this.width, this.height)
+  } // Function adjusted()
+
+  /**
+   * 合并rect
+   *
+   * @param   rect
+   */
+  union(rect) {
+    this.left = Math.min(this.left, rect.left)
+    this.top = Math.min(this.top, rect.top)
+    this.right = Math.max(this.right, rect.right)
+    this.bottom = Math.max(this.bottom, rect.bottom)
+  } // Function union()
+} // Class SRect

+ 13 - 0
src/assets/graphy/index.js

@@ -0,0 +1,13 @@
+import SGraphyView from './SGraphy/SGraphyView'
+import SGraphyScene from './SGraphy/SGraphyScene'
+import SGraphyClockItem from './SGraphy/items/SGraphyClockItem'
+import SGraphyRectItem from './SGraphy/items/SGraphyRectItem'
+import SGraphyLineItem from './SGraphy/items/SGraphyLineItem'
+import SGraphyPolygonItem from './SGraphy/items/SGraphyPolygonItem'
+import SGraphyCircleItem from './SGraphy/items/SGraphyCircleItem'
+import SGraphyImageItem from './SGraphy/items/SGraphyImageItem'
+import SGraphyPillarItems from './SGraphy/items/SGraphyPillarItems'
+import SGraphyTextItems from './SGraphy/items/SGraphyTextItems'
+import SGraphyVirtualItem from './SGraphy/items/SGraphyVirtualItem'
+
+export { SGraphyView, SGraphyScene, SGraphyClockItem, SGraphyRectItem, SGraphyLineItem, SGraphyPolygonItem, SGraphyCircleItem, SGraphyImageItem, SGraphyPillarItems, SGraphyTextItems, SGraphyVirtualItem }

+ 37 - 0
src/assets/pako/pako.js

@@ -0,0 +1,37 @@
+import pako from 'pako'
+
+let funcTo = atob
+console.log(funcTo)
+
+const pakoObj = {
+    unzip: function unzip(b64Data) {
+        // console.log(b64Data)
+        var strData = funcTo(b64Data);
+
+        // Convert binary string to character-number array
+        var charData = strData.split('').map(function(x) { return x.charCodeAt(0); });
+        // console.log("charData", charData)
+
+        // Turn number array into byte-array
+        var binData = new Uint8Array(charData);
+
+
+        // // unzip
+        var data = pako.inflate(binData, { to: 'string' });
+        // console.log(data)
+        // strData = new Uint16Array(data).reduce(function(data, byte) {
+        //     return data + String.fromCharCode(byte);
+        // })
+        // console.log(strData)
+        return eval("(" + data + ")");
+    },
+    // 压缩
+    zip: function(str) {
+        //escape(str)  --->压缩前编码,防止中午乱码
+        var binaryString = pako.gzip(escape(str), { to: 'string' });
+        console.log(binaryString)
+        return binaryString;
+    }
+}
+
+export default pakoObj

+ 627 - 0
src/components/business_space/business/handsontable.vue

@@ -0,0 +1,627 @@
+<template>
+    <div id="handsontable" v-loading="isLoading">
+        <div style="overflow:hidden;margin-bottom:10px;margin-right:20px;height:50px;">
+            <el-button @click="undo" size="small" style="float:right;margin-top:5px;margin-right:10px;" icon="iconfont icon-undo" circle></el-button>
+            <el-button @click="reset" size="small" style="float:right;margin-top:5px;margin-right:10px;" icon="iconfont icon-shuaxin" circle></el-button>
+            <el-button @click="addSp" size="small" style="float:right;margin-top:5px;margin-right:10px;" icon="iconfont icon-tianjia" circle></el-button>
+        </div>
+        <div v-show="main &&main.length" :id="id"></div>
+        <div class="no-data" v-show="!main || !main.length">暂无数据</div>
+        <!-- <add-business :buildMess="buildMess" :dialog="dialog"></add-business> -->
+        <my-pagination v-show="main &&main.length" :page="page" @change="pageChange"></my-pagination>
+    </div>
+</template>
+<script>
+     // 引用handsontable插件
+     // import "@/assets/js/chosen.jquery.min";
+     import tools from "@/utils/scan/tools";
+     // import "@/assets/js/handsontable-chosen-editor";
+     import myPagination from "@/components/common/myPagination";
+     import addBusiness from "@/components/business_space/dialogs/addDialog/businessDialog"
+     import showTools from "@/utils/handsontable/notShow"
+     import Handsontable from "handsontable-pro"
+     import 'handsontable-pro/dist/handsontable.full.css'
+     import zhCN from 'handsontable-pro/languages/zh-CN';
+     console.log(Handsontable,"Handsontable")
+     import {
+         updateBusiness,
+         createBusiness,
+         createBusinessList,
+         delManySpace,
+         isSpaceBuss
+     } from "@/api/scan/request";
+     import {
+         mapGetters,
+         mapActions
+     } from "vuex";
+     export default {
+         props: {
+             id: {
+                 type: String
+             }
+         },
+         components: {
+             myPagination,
+             addBusiness
+         },
+         computed: {
+             ...mapGetters("peojMess", [
+                 "projectId",
+                 "secret",
+                 "userId"
+             ])
+         },
+         data() {
+             return {
+                 dialog: {
+                     addDevice: false
+                 },
+                 headers: null,
+                 main: null,
+                 hot: null,
+                 tableData: [],
+                 isLoading: true,
+                 allData: null,
+                 page: {
+                     size: 50,
+                     sizes: [10, 30, 50, 100, 150, 200],
+                     total: 2,
+                     currentPage: 1
+                 },
+                 param: {
+                     ProjId: this.projectId, //项目id
+                     UserId: this.userId, //用户id
+                     secret: this.secret
+                 },
+                 buildMess: null,
+                 filtersArr: [], //表格数据被过滤后的下标
+                 copyMain: null, //深拷贝数组
+                 activeType: {}
+             };
+         },
+         created() {
+             this.param.ProjId = this.projectId
+             this.param.UserId = this.userId
+             this.param.secret = this.secret
+         },
+         mounted() {},
+         methods: {
+             //获取表头
+             getHeader(headers, activeTabType) {
+                 this.headers = headers.map(item => {
+                     let dataSoucse = item.DataSource
+                     console.log(dataSoucse)
+                     if (!dataSoucse) {
+                         return item
+                     }
+                     dataSoucse.map(keys => {
+                         if (!!keys.Content && keys.Content.length) {
+                             keys.Content.map(child => {
+                                 dataSoucse.push({
+                                     Code: child.Code,
+                                     Name: child.Name,
+                                 })
+                                 if (!!child.Content && child.Content.length) {
+                                     child.Content.map(node => {
+                                         dataSoucse.push({
+                                             Code: node.Code,
+                                             Name: node.Name,
+                                         })
+                                     })
+                                 }
+                             })
+                         }
+                     })
+                     return item
+                 });
+                 console.log(this.headers, "headers")
+                 this.activeType = activeTabType
+             },
+             getData(buildMess) {
+                 if (!!buildMess) {
+                     this.buildMess = buildMess;
+                 }
+                 let param = {
+                     id: this.buildMess.code,
+                     type: ["Sp"],
+                     data: {
+                         customInfo: true,
+                         criteria: {
+                             floor: this.buildMess.code, // 必填, 指定楼层id
+                             business_type: this.activeType.code, // 必填, 楼层下某个类型的业务空间PowerSupplyZone, 默认是空字符串
+                             rel_type: this.activeType.rel_type, // 必填, 指定业务类型的关系类型(参考数据平台),
+                             // 数字型字符串, 例如: 通用是99
+                         }
+                     },
+                     ProjId: this.param.ProjId,
+                     secret: this.param.secret
+                 };
+                 isSpaceBuss(param).then(res => {
+                     if (res.data.Result == "success") {
+                         this.allData = res.data.Content;
+                         this.page.total = res.data.Count;
+                         this.getMain(
+                             this.pagination(this.page.currentPage, this.page.size, this.allData)
+                         );
+                     } else {
+                         this.$message.error("请求错误");
+                     }
+                 });
+             },
+             //获取表格主体内容
+             getMain(main) {
+                 this.main = main;
+                 if (this.main && this.main.length && this.main[0].id) {
+                     this.copyMain = tools.deepCopy(this.main);
+                 }
+                 this.isLoading = true;
+                 if (!!this.hot) {
+                     this.hot.destroy();
+                     this.hot = null;
+                 }
+                 this.$nextTick(() => {
+                     this.initHot();
+                 });
+             },
+             //初始化handsontable组件
+             initHot() {
+                 let id = this.id
+                 console.log(id)
+                 var container = document.getElementById(this.id);
+                 let winHeight = document.documentElement.clientHeight;
+                 this.hot = new Handsontable(container, {
+                     data: this.main,
+                     colHeaders: this.delHeader(this.headers), //表头文案
+                     columns: this.getType(this.headers), //数据显示格式
+                     filters: true,
+                     maxRows: this.main.length,
+                     height: winHeight - 100 - 50 - 80,
+                     columnSorting: true, //添加排序
+                     sortIndicator: true, //添加排序
+                     renderAllRows: true,
+                     autoColumnSize: true,
+                     language: "zh-CN",
+                     manualColumnResize: true,
+                     manualColumnMove: true,
+                     dropdownMenu: [
+                         "filter_by_condition",
+                         "filter_by_value",
+                         "filter_action_bar"
+                     ],
+                     contextMenu: {
+                         items: {
+                             remove_row: {
+                                 name: "删除该业务空间"
+                             }
+                         }
+                     },
+                     // 事件
+                     afterChange: this.tdChange, //修改后
+                     afterFilter: this.trimmedRows, //排序前
+                     beforeRemoveRow: this.romoveFm, //右键删除
+                     afterOnCellMouseDown: this.eventClick //鼠标点击
+                 });
+                 let pro = document.getElementById("hot-display-license-info");
+                 if (!!pro) {
+                     pro.parentNode.removeChild(pro);
+                 }
+                 this.isLoading = false;
+             },
+             //表格中的查看详情
+             eventClick(el, rowArr) {
+                 let filter = this.filtersArr;
+                 //被筛选过后的数组
+                 let trimmedArr = this.trimmedRows();
+                 //是否启用了排序
+                 let isSort = this.hot.getPlugin("columnSorting").isSorted();
+                 // debugger
+                 if (trimmedArr.length && isSort) {
+                     let sortArr = this.myHotArr.getPlugin("columnSorting").rowsMapper
+                         .__arrayMap;
+                     let infos = this.main[trimmedArr[sortArr[rowArr.row]]];
+                     this.getInfors(infos, rowArr);
+                 } else if (isSort) {
+                     //排序后的数组
+                     let sortArr = this.hot.getPlugin("columnSorting").rowsMapper.__arrayMap;
+                     let infos = this.main[sortArr[rowArr.row]];
+                     this.getInfors(infos, rowArr);
+                 } else if (trimmedArr.length) {
+                     let infos = this.main[trimmedArr[rowArr.row]];
+                     this.getInfors(infos, rowArr);
+                 } else {
+                     let infos = this.main[rowArr.row];
+                     this.getInfors(infos, rowArr);
+                 }
+             },
+             getInfors(infos, row) {
+                 if (row.col == 1) {
+                     this.$emit("lookEqu", infos);
+                 } else {
+                     return false;
+                 }
+             },
+             //表格发生更改
+             tdChange(changeData, source) {
+                 let filter = this.filtersArr;
+                 if (changeData) {
+                     let param = this.getParam(changeData, source);
+                     let data = [];
+                     for (let i = 0; i < param.length; i++) {
+                         if (!!param[i].id) {
+                             data.push(param[i]);
+                         } else {
+                             this.createSq(param[i], changeData);
+                         }
+                     }
+                     if (data && data.length) {
+                         this.updateBusiness(data, changeData);
+                     }
+                 }
+             },
+             //右键删除
+             romoveFm(index, amout, physicalRows, source) {
+                 if (physicalRows && physicalRows.length) {
+                     let items = [],
+                         text = null;
+                     physicalRows.map(item => {
+                         text = text ?
+                             this.copyMain[item].infos.RoomName + "、" + text :
+                             this.copyMain[item].infos.RoomName;
+                         items.push(this.copyMain[item].id);
+                     });
+                     this.$confirm("您正在删除" + text + ", 是否继续?", "提示", {
+                             confirmButtonText: "确定",
+                             cancelButtonText: "取消",
+                             type: "warning"
+                         })
+                         .then(() => {
+                             this.delBusiness(items);
+                         })
+                         .catch(() => {
+                             this.hot.loadData(tools.deepCopy(this.copyMain));
+                         });
+                 }
+             },
+             delBusiness(items) {
+                 let param = {
+                     ProjId: this.param.ProjId,
+                     secret: this.param.secret,
+                     data: {
+                         criteria: {
+                             ids: items
+                         }
+                     }
+                 };
+                 delManySpace(param)
+                     .then(res => {
+                         if (res.data.Result == "success") {
+                             this.$message.success("删除成功");
+                             this.getData();
+                         } else {
+                             this.$message.error("删除失败");
+                         }
+                     })
+                     .catch(() => {
+                         this.$message.error("请求发生错误");
+                     });
+             },
+             // 新建
+             createSq(param, change) {
+                 let seedData = {
+                     building_id: this.buildMess.buildCode,
+                     floor_id: this.buildMess.code,
+                     business_type: this.activeType.code == "GeneralZone" ? null : this.activeType.code,
+                     infos: {}
+                 };
+                 for (let i = 0; i < change.length; i++) {
+                     let arr = change[i][1].split(".");
+                     seedData[arr[0]][arr[1]] = [{
+                         value: change[i][3] != "" ? change[i][3] : null
+                     }];
+                 }
+                 this.createSpace(seedData);
+             },
+             // 修改
+             updateBusiness(data, change) {
+                 let param = {
+                     ProjId: this.param.ProjId,
+                     secret: this.param.secret,
+                     data: {
+                         criterias: []
+                     }
+                 };
+                 data.map((item, index) => {
+                     console.log(change[index][1]);
+                     let arr = change[index][1].split(".");
+                     let info = {};
+                     info[arr[1]] = [{
+                         value: change[index][3] != "" ? change[index][3] : null
+                     }];
+                     param.data.criterias.push({
+                         id: item.id,
+                         infos: info
+                     });
+                 });
+                 updateBusiness(param).then(res => {
+                     console.log(res);
+                 });
+             },
+             /**    请求部分 ------------------------------------ */
+             createSpace(data) {
+                 let param = {
+                     ProjId: this.param.ProjId,
+                     secret: this.param.secret,
+                     data: {
+                         criterias: [data]
+                     }
+                 };
+                 createBusinessList(param).then(res => {
+                     if (res.data.Result == "success") {
+                         console.log(this.main);
+                         this.main.map(item => {
+                             if (!item.id) {
+                                 item.id = res.data.id;
+                                 item.infos.RoomID = res.data.id;
+                                 item.infos.RoomName = res.data.RoomName;
+                             }
+                         });
+                         this.hot.loadData(this.main);
+                         this.reset()
+                     } else {
+                         this.$message.error("创建发生错误:" + res.data.ResultMsg);
+                     }
+                 });
+             },
+             /**
+              * 获取被排序后的数组
+              *
+              * @param changeData 发生改变的数据
+              * @param source     数组
+              *
+              * @return array     经过排序后或者经过搜索后的数组
+              */
+             getParam(changeData, source) {
+                 let param = "";
+                 //被筛选过后的数组
+                 let trimmedArr = this.trimmedRows();
+                 //是否启用了排序
+                 let isSort = this.hot.getPlugin("columnSorting").isSorted();
+                 if (trimmedArr.length && isSort) {
+                     //排序后的数组
+                     let sortArr = this.hot.getPlugin("columnSorting").rowsMapper.__arrayMap;
+                     param = changeData.map(item => {
+                         return this.hot.getSourceDataAtRow(trimmedArr[sortArr[item[0]]]);
+                     });
+                 } else if (isSort) {
+                     //排序后的数组
+                     let sortArr = this.hot.getPlugin("columnSorting").rowsMapper.__arrayMap;
+                     param = changeData.map(item => {
+                         return this.hot.getSourceDataAtRow(sortArr[item[0]]);
+                     });
+                 } else if (trimmedArr.length) {
+                     param = changeData.map(item => {
+                         return this.hot.getSourceDataAtRow(trimmedArr[item[0]]);
+                     });
+                 } else {
+                     param = changeData.map(item => {
+                         return this.hot.getSourceDataAtRow(item[0]);
+                     });
+                 }
+                 return param;
+             },
+             //获取被筛选掉的行号
+             trimmedRows() {
+                 // var plugin = hot.getPlugin('trimRows').trimmedRows;//获取被筛选掉的行号
+                 var plugin = this.hot.getPlugin("trimRows").trimmedRows;
+                 let dataLength = this.main.length;
+                 let dataArr = new Array();
+                 for (let i = 0; i < dataLength; i++) {
+                     dataArr.push(i);
+                 }
+                 if (plugin.length <= 0) {
+                     dataArr = undefined;
+                 } else {
+                     dataArr = this.array_diff(dataArr, plugin);
+                 }
+                 this.filtersArr = dataArr;
+                 return dataArr || [];
+                 // var DataArray = new Array();
+                 // for (var i = 0; i < plugin.length; i++) {
+                 //     // 通过行号获取数据
+                 //     DataArray.push(this.hot.getSourceDataAtRow(plugin[i]));
+                 // }
+             },
+             //去除数组中相同的元素
+             array_diff(a, b) {
+                 for (var i = 0; i < b.length; i++) {
+                     for (var j = 0; j < a.length; j++) {
+                         if (a[j] == b[i]) {
+                             a.splice(j, 1);
+                             j = j - 1;
+                         }
+                     }
+                 }
+                 return a;
+             },
+             /**
+              * 表头文案处理函数
+              * @param list header数组数据
+              *
+              * @return 处理好的文案
+              */
+             delHeader(list) {
+                 let arr = tools.copyArr(list)
+                 // 如果不是只读状态,添加四大厂商选择
+                 let readArr = ["A1", "A2", "B1", "C5", "D1", "D2", "X", "L", "L1", "L2"]
+                 if (!this.onlyRead) {
+                     arr = showTools.arrToArr(arr)
+                     readArr.push("Own")
+                 }
+                 let data = showTools.changeHeader(arr, readArr, false, false, true, true, true)
+                 data.unshift("是否关联平面图", "与空间相关联的设备");
+                 console.log("header", data)
+                 return data;
+             },
+             /**
+              * 表头数据处理函数
+              * @param arr header数组数据
+              *
+              * @return 处理好的数据格式
+              */
+             getType(list) {
+                 let arr = tools.copyArr(list)
+                 let data = showTools.showTypes(arr, false, false, true, true, ["F1", "F2"])
+                 data.unshift({
+                     data: "hasSi",
+                     renderer: this.myRenderer,
+                     readOnly: true
+                 }, {
+                     data: "point",
+                     renderer: this.facilityRender,
+                     readOnly: true
+                 });
+                 data = data.filter(item => item);
+                 console.log(data)
+                 return data;
+             },
+             myRenderer(instance, td, row, col, prop, value, cellProperties) {
+                 if (value) {
+                     td.innerHTML = "已关联";
+                 } else {
+                     td.innerHTML = "未关联";
+                 }
+                 return td;
+             },
+             facilityRender(instance, td, row, col, prop, value, cellProperties) {
+                 td.style.color = "#409EFF";
+                 td.style.cursor = "pointer";
+                 td.innerHTML = "点击查看";
+                 return td;
+             },
+             //下拉插件修改
+             customDropdownRenderer(
+                 instance,
+                 td,
+                 row,
+                 col,
+                 prop,
+                 value,
+                 cellProperties
+             ) {
+                 var selectedId;
+                 var optionsList = cellProperties.chosenOptions.data;
+                 if (
+                     typeof optionsList === "undefined" ||
+                     typeof optionsList.length === "undefined" ||
+                     !optionsList.length
+                 ) {
+                     Handsontable.renderers.TextRenderer(
+                         instance,
+                         td,
+                         row,
+                         col,
+                         prop,
+                         value,
+                         cellProperties
+                     );
+                     return td;
+                 }
+                 var values = (value + "").split(",");
+                 value = [];
+                 for (var index = 0; index < optionsList.length; index++) {
+                     if (optionsList[index].content && optionsList[index].content.length) {
+                         for (let i = 0; i < optionsList[index].content.length; i++) {
+                             if (
+                                 optionsList[index].content[i] &&
+                                 optionsList[index].content[i].length
+                             ) {
+                                 for (let j = 0; j < optionsList[index].content[i].length; j++) {
+                                     if (
+                                         values.indexOf(
+                                             optionsList[index].content[i].content[j].code + ""
+                                         ) > -1
+                                     ) {
+                                         selectedId = optionsList[index].content[i].content[j].code;
+                                         value.push(optionsList[index].content[i].content[j].name);
+                                     }
+                                 }
+                             } else {
+                                 if (
+                                     values.indexOf(optionsList[index].content[i].code + "") > -1
+                                 ) {
+                                     selectedId = optionsList[index].content[i].code;
+                                     value.push(optionsList[index].content[i].name);
+                                 }
+                             }
+                         }
+                     } else {
+                         if (values.indexOf(optionsList[index].code + "") > -1) {
+                             selectedId = optionsList[index].code;
+                             value.push(optionsList[index].name);
+                         }
+                     }
+                 }
+                 value = value.join(", ");
+                 Handsontable.renderers.TextRenderer(
+                     instance,
+                     td,
+                     row,
+                     col,
+                     prop,
+                     value,
+                     cellProperties
+                 );
+                 return td;
+             },
+             /**  页面中的按钮事件--------------------------- */
+             addSp() {
+                 //   this.dialog.addDevice = true
+                 //   this.hot.downloadFile()
+                 //   this.hot.getPlugin('exportFile').downloadFile("csv", { columnHeaders: true, exportHiddenRows: true, exportHiddenColumns: true, rowHeaders: true })
+                 if (this.main && this.main.length && !!this.main[0].id) {
+                     this.hot.destroy();
+                     this.hot = null;
+                     this.main.unshift([]);
+                     this.getMain(this.main);
+                 } else {
+                     if (this.main && this.main.length) {
+                         this.$message.error("请添加完成后继续添加");
+                     } else {
+                         this.main.unshift([]);
+                         this.getMain(this.main);
+                     }
+                 }
+             },
+             //刷新
+             reset() {
+                 this.getData();
+             },
+             //撤回操作
+             undo() {
+                 this.hot.undo();
+             },
+             /**  分页事件------------------------ */
+             pageChange() {
+                 this.getMain(
+                     this.pagination(this.page.currentPage, this.page.size, this.allData)
+                 );
+             },
+             pagination(pageNo, pageSize, array) {
+                 let offset = (pageNo - 1) * pageSize;
+                 return offset + pageSize >= array.length ?
+                     array.slice(offset, array.length) :
+                     array.slice(offset, offset + pageSize);
+             }
+         }
+     };
+</script>
+<style lang="less" scoped>
+    #handsontable {
+        .no-data {
+            height: 150px;
+            line-height: 150px;
+            text-align: center;
+            color: gray;
+        }
+    }
+</style>

+ 15 - 15
src/components/business_space/dialogs/addDialog/businessDialog.vue

@@ -65,20 +65,20 @@
 </template>
 </template>
 <script>
 <script>
 
 
-import myCascader from "@/components/lib/cascaders/assets";
-import hansonTable from "@/components/dialogHanson/addDevice";
-import { getSpaceHeader } from "@/api/request";
-import tools from "@/assets/js/tools";
-import qrcode from "@/components/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 myCascader from "@/components/business_space/lib/cascaders/assets";
+// import hansonTable from "@/components/business_space/dialogHanson/addDevice";
+import { getSpaceHeader } from "@/api/scan/request";
+import tools from "@/utils/tools";
+import qrcode from "@/components/business_space/lib/qrcode";
+import firm from "@/components/business_space/dialogs/list/firm";
+import supplyDialog from "@/components/business_space/dialogs/list/supplyDialog";
+import supplierDialog from "@/components/business_space/dialogs/list/supplierDialog";
+import maintainerDialog from "@/components/business_space/dialogs/list/maintainerDialog";
+import insurerDialog from "@/components/business_space/dialogs/list/insurerDialog";
+import guaranteeDialog from "@/components/business_space/dialogs/list/guaranteeDialog";
+import uploadFilesDialog from "@/components/business_space/dialogs/list/filesDialog";
+import uploadImgDialog from "@/components/business_space/dialogs/list/uploadImgDialog";
+import picDialog from "@/components/business_space/dialogs/list/picDialog"
 
 
 let table = function (num) {
 let table = function (num) {
   let main = []
   let main = []
@@ -90,7 +90,7 @@ let table = function (num) {
 export default {
 export default {
   components: {
   components: {
     myCascader,
     myCascader,
-    hansonTable,
+    // hansonTable,
     qrcode, //二维码页面
     qrcode, //二维码页面
     firm, //
     firm, //
     supplyDialog,
     supplyDialog,

+ 1 - 1
src/components/business_space/dialogs/addDialog/dialogAssets.vue

@@ -76,7 +76,7 @@
 
 
 import myCascader from "@/components/lib/cascaders/assets";
 import myCascader from "@/components/lib/cascaders/assets";
 import hansonTable from "@/components/dialogHanson/addDevice";
 import hansonTable from "@/components/dialogHanson/addDevice";
-import tools from "@/assets/js/tools";
+import tools from "@/utils/scan/tools";
 import qrcode from "@/components/lib/qrcode";
 import qrcode from "@/components/lib/qrcode";
 import firm from "@/components/dialogs/list/firm";
 import firm from "@/components/dialogs/list/firm";
 import supplyDialog from "@/components/dialogs/list/supplyDialog";
 import supplyDialog from "@/components/dialogs/list/supplyDialog";

+ 1 - 1
src/components/business_space/dialogs/addDialog/dialogDevice.vue

@@ -93,7 +93,7 @@
 import myCascader from "@/components/cascader";
 import myCascader from "@/components/cascader";
 import hansonTable from "@/components/dialogHanson/addDevice";
 import hansonTable from "@/components/dialogHanson/addDevice";
 import { getTableHeader, getSpaceFloor, getEquipmentFamily, BatchCreateSome, createAssetsList, createSystem, EqToAssets, createRelation } from "@/api/request";
 import { getTableHeader, getSpaceFloor, getEquipmentFamily, BatchCreateSome, createAssetsList, createSystem, EqToAssets, createRelation } from "@/api/request";
-import tools from "@/assets/js/tools";
+import tools from "@/utils/scan/tools";
 import showTools from "@/utils/hansontable/notShow"
 import showTools from "@/utils/hansontable/notShow"
 import text from "@/utils/hansontable/mainText"
 import text from "@/utils/hansontable/mainText"
 
 

+ 1 - 1
src/components/business_space/dialogs/addDialog/dialogSystem.vue

@@ -61,7 +61,7 @@
 
 
 import myCascader from "@/components/lib/cascaders/system";
 import myCascader from "@/components/lib/cascaders/system";
 import hansonTable from "@/components/dialogHanson/addDevice";
 import hansonTable from "@/components/dialogHanson/addDevice";
-import tools from "@/assets/js/tools";
+import tools from "@/utils/scan/tools";
 import qrcode from "@/components/lib/qrcode";
 import qrcode from "@/components/lib/qrcode";
 import firm from "@/components/dialogs/list/firm";
 import firm from "@/components/dialogs/list/firm";
 import supplyDialog from "@/components/dialogs/list/supplyDialog";
 import supplyDialog from "@/components/dialogs/list/supplyDialog";

+ 188 - 185
src/components/business_space/dialogs/detailsDialog.vue

@@ -1,200 +1,203 @@
 <template>
 <template>
-  <el-dialog :visible.sync="isShow.details" :width="width">
-    <span slot="title">
-      <span v-show="step == 1">{{title}}</span>
-      <span v-show="step == 1" style="float:right;margin-right:40px;">
-        <el-button class="saga-padding0" @click="step = 3" type="text">编辑信息</el-button>
-        <!-- <el-button class="saga-padding0" @click="addMyEquip" type="text">添加设备</el-button> -->
-        <el-dropdown @command="addMyEquip" trigger="click">
-          <span class="el-dropdown-link" style="color: #409EFF">添加设备</span>
-          <el-dropdown-menu slot="dropdown">
+    <el-dialog :visible.sync="isShow.details" :width="width">
+        <span slot="title">
+          <span v-show="step == 1">{{title}}</span>
+        <span v-show="step == 1" style="float:right;margin-right:40px;">
+            <el-button class="saga-padding0" @click="step = 3" type="text">编辑信息</el-button>
+            <!-- <el-button class="saga-padding0" @click="addMyEquip" type="text">添加设备</el-button> -->
+            <el-dropdown @command="addMyEquip" trigger="click">
+              <span class="el-dropdown-link" style="color: #409EFF">添加设备</span>
+        <el-dropdown-menu slot="dropdown">
             <el-dropdown-item command="EquipinSpace">空间内的设备</el-dropdown-item>
             <el-dropdown-item command="EquipinSpace">空间内的设备</el-dropdown-item>
             <el-dropdown-item command="EquipforSpace">服务于空间的设备</el-dropdown-item>
             <el-dropdown-item command="EquipforSpace">服务于空间的设备</el-dropdown-item>
             <el-dropdown-item command="EquipXSpace">其他关系的设备</el-dropdown-item>
             <el-dropdown-item command="EquipXSpace">其他关系的设备</el-dropdown-item>
-          </el-dropdown-menu>
+        </el-dropdown-menu>
         </el-dropdown>
         </el-dropdown>
         <el-button class="saga-padding0" @click="delSpace" type="text">删除该业务空间</el-button>
         <el-button class="saga-padding0" @click="delSpace" type="text">删除该业务空间</el-button>
-      </span>
-      <span v-show="step == 2 || step == 3">
-        <el-button type="text" @click="goBack" icon="el-icon-arrow-left"></el-button>
-      </span>
-    </span>
-    <div id="detailsDialog" v-show="step == 1">
-      <p class="influence-p">{{list.name}}</p>
-      <el-tabs type="border-card">
-        <el-tab-pane label="空间详情">
-          <div class="saga-details">
-            <iframe height="400px" v-if="isShow.details" width="100%" :src="iframeSrc"></iframe>
-          </div>
-        </el-tab-pane>
-        <el-tab-pane label="与空间相关联的设备">
-          <div>
-            <equip-table ref="myEquip"></equip-table>
-          </div>
-        </el-tab-pane>
-      </el-tabs>
-    </div>
-    <div v-show="step == 2">
-      <add-equip :activeTabType="activeTabType" ref="addEquip"></add-equip>
-    </div>
-    <div id="detailsDialog" v-if="step == 3">
-      <iframe v-if="step == 3" height="400px" width="100%" :src="iframeSrc2"></iframe>
-    </div>
-  </el-dialog>
+        </span>
+        <span v-show="step == 2 || step == 3">
+            <el-button type="text" @click="goBack" icon="el-icon-arrow-left"></el-button>
+          </span>
+        </span>
+        <div id="detailsDialog" v-show="step == 1">
+            <p class="influence-p">{{list.name}}</p>
+            <el-tabs type="border-card">
+                <el-tab-pane label="空间详情">
+                    <div class="saga-details">
+                        <iframe height="400px" v-if="isShow.details" width="100%" :src="iframeSrc"></iframe>
+                    </div>
+                </el-tab-pane>
+                <el-tab-pane label="与空间相关联的设备">
+                    <div>
+                        <equip-table ref="myEquip"></equip-table>
+                    </div>
+                </el-tab-pane>
+            </el-tabs>
+        </div>
+        <div v-show="step == 2">
+            <add-equip :activeTabType="activeTabType" ref="addEquip"></add-equip>
+        </div>
+        <div id="detailsDialog" v-if="step == 3">
+            <iframe v-if="step == 3" height="400px" width="100%" :src="iframeSrc2"></iframe>
+        </div>
+    </el-dialog>
 </template>
 </template>
 
 
 <script>
 <script>
-import Vue from "vue"
-import {
-  Dropdown,
-  DropdownMenu,
-  DropdownItem} from "element-ui"
-Vue.use(Dropdown)
-Vue.use(DropdownMenu)
-Vue.use(DropdownItem)
-
-import { delManySpace } from "@/api/request";
-import equipTable from "@/components/table/equipTable";
-import addEquip from "@/components/table/addEquip";
-
-export default {
-  components: {
-    equipTable,
-    addEquip
-  },
-  props: {
-    width: {
-      type: String,
-      default: "70%"
-    },
-    title: {
-      type: String,
-      default: "头部信息"
-    },
-    isShow: {
-      type: Object
-    },
-    param: {
-      type: Object
-    },
-    activeTabType: {
-      type: Object,
-      default: function () {
-        return {
-          "code": "GeneralZone",
-          "name": "默认分区",
-          "rel_type": "99"
-        }
-      }
-    }
-  },
-  data() {
-    return {
-      step: 1,
-      data: null,
-      proj: null,
-      activeName: "1",
-      list: {},
-      iframeSrc: "",
-      iframeSrc2: "",
-      buildMess: ""
-    };
-  },
-  created() { },
-  methods: {
-    handleClick() { },
-    getData(list, buildMess) {
-      this.step = 1;
-      this.list = list;
-      this.buildMess = buildMess;
-      this.$nextTick(() => {
-        this.$refs.myEquip.getData(list, this.activeTabType);
-      });
-      let perjectId = this.$route.query.projId,
-        secret = this.$route.query.secret;
-      this.iframeSrc =
-        process.env.BASE_URL +
-        ":8889/#/details?perjectId=" +
-        perjectId +
-        "&secret=" +
-        secret +
-        "&FmId=" +
-        list.id +
-        "&type=0&code=" + this.activeTabType.code;
-      this.iframeSrc2 =
-        process.env.BASE_URL +
-        ":8889/#/changeMess?perjectId=" +
-        perjectId +
-        "&secret=" +
-        secret +
-        "&id=" +
-        list.id +
-        "&type=" + this.activeTabType.code;
-    },
-    addMyEquip(str) {
-      this.step = 2;
-      this.$nextTick(() => {
-        console.log(this.activeTabType)
-        this.$refs.addEquip.getData(this.list, this.buildMess, str, this.activeTabType);
-      });
-    },
-    goBack() {
-      this.step = 1;
-      this.$refs.myEquip.getData(this.list, this.activeTabType);
-    },
-    delSpace() {
-      this.$confirm("此操作将永久删除该业务空间, 是否继续?", "删除", {
-        confirmButtonText: "确定",
-        cancelButtonText: "取消",
-        type: "warning"
-      })
-        .then(() => {
-          let param = {
-            ProjId: this.$route.query.projId,
-            secret: this.$route.query.secret,
-            data: {
-              criteria: {
-                ids: [this.list.id]
-              }
+    import {
+        delManySpace
+    } from "@/api/scan/request";
+    import equipTable from "@/components/business_space/table/equipTable";
+    import addEquip from "@/components/business_space/table/addEquip";
+    import {
+        mapGetters,
+        mapActions
+    } from "vuex";
+    export default {
+        components: {
+            equipTable,
+            addEquip
+        },
+        computed: {
+            ...mapGetters("peojMess", [
+                "projectId",
+                "secret",
+                "userId"
+            ])
+        },
+        props: {
+            width: {
+                type: String,
+                default: "70%"
+            },
+            title: {
+                type: String,
+                default: "头部信息"
+            },
+            isShow: {
+                type: Object
+            },
+            param: {
+                type: Object
+            },
+            activeTabType: {
+                type: Object,
+                default: function() {
+                    return {
+                        "code": "GeneralZone",
+                        "name": "默认分区",
+                        "rel_type": "99"
+                    }
+                }
             }
             }
-          };
-          delManySpace(param)
-            .then(res => {
-              if (res.data.Result == "success") {
-                this.$message({
-                  type: "success",
-                  message: "删除成功!"
+        },
+        data() {
+            return {
+                step: 1,
+                data: null,
+                proj: null,
+                activeName: "1",
+                list: {},
+                iframeSrc: "",
+                iframeSrc2: "",
+                buildMess: ""
+            };
+        },
+        created() {},
+        methods: {
+            handleClick() {},
+            getData(list, buildMess) {
+                this.step = 1;
+                this.list = list;
+                this.buildMess = buildMess;
+                this.$nextTick(() => {
+                    this.$refs.myEquip.getData(list, this.activeTabType);
                 });
                 });
-                this.$emit("del");
-              } else {
-                this.$message.error(res.data.ResultMsg);
-              }
-            })
-            .catch(() => {
-              this.$message.error("请求发生错误");
-            });
-        })
-        .catch(() => {
-          this.$message({
-            type: "info",
-            message: "已取消删除"
-          });
-        });
-    }
-  }
-};
+                let perjectId = this.projectId,
+                    secret = this.secret;
+                this.iframeSrc =
+                    process.env.BASE_URL +
+                    ":8889/#/details?perjectId=" +
+                    perjectId +
+                    "&secret=" +
+                    secret +
+                    "&FmId=" +
+                    list.id +
+                    "&type=0&code=" + this.activeTabType.code;
+                this.iframeSrc2 =
+                    process.env.BASE_URL +
+                    ":8889/#/changeMess?perjectId=" +
+                    perjectId +
+                    "&secret=" +
+                    secret +
+                    "&id=" +
+                    list.id +
+                    "&type=" + this.activeTabType.code;
+            },
+            addMyEquip(str) {
+                this.step = 2;
+                this.$nextTick(() => {
+                    console.log(this.activeTabType)
+                    this.$refs.addEquip.getData(this.list, this.buildMess, str, this.activeTabType);
+                });
+            },
+            goBack() {
+                this.step = 1;
+                this.$refs.myEquip.getData(this.list, this.activeTabType);
+            },
+            delSpace() {
+                this.$confirm("此操作将永久删除该业务空间, 是否继续?", "删除", {
+                        confirmButtonText: "确定",
+                        cancelButtonText: "取消",
+                        type: "warning"
+                    })
+                    .then(() => {
+                        let param = {
+                            ProjId: this.projectId,
+                            secret: this.secret,
+                            data: {
+                                criteria: {
+                                    ids: [this.list.id]
+                                }
+                            }
+                        };
+                        delManySpace(param)
+                            .then(res => {
+                                if (res.data.Result == "success") {
+                                    this.$message({
+                                        type: "success",
+                                        message: "删除成功!"
+                                    });
+                                    this.$emit("del");
+                                } else {
+                                    this.$message.error(res.data.ResultMsg);
+                                }
+                            })
+                            .catch(() => {
+                                this.$message.error("请求发生错误");
+                            });
+                    })
+                    .catch(() => {
+                        this.$message({
+                            type: "info",
+                            message: "已取消删除"
+                        });
+                    });
+            }
+        }
+    };
 </script>
 </script>
 
 
 <style lang="less">
 <style lang="less">
-#detailsDialog {
-  .el-tabs__content {
-    max-height: 400px;
-  }
-  .influence-p {
-    height: 40px;
-    line-height: 40px;
-    font-size: 17px;
-    margin-bottom: 10px;
-  }
-}
+    #detailsDialog {
+        .el-tabs__content {
+            max-height: 400px;
+        }
+        .influence-p {
+            height: 40px;
+            line-height: 40px;
+            font-size: 17px;
+            margin-bottom: 10px;
+        }
+    }
 </style>
 </style>

+ 18 - 13
src/components/business_space/dialogs/facilityDialog.vue

@@ -30,22 +30,24 @@
 </template>
 </template>
 
 
 <script>
 <script>
-import Vue from "vue"
+import equipTable from "@/components/business_space/table/equipTable";
+import addEquip from "@/components/business_space/table/addEquip";
 import {
 import {
-  Dropdown,
-  DropdownMenu,
-  DropdownItem} from "element-ui"
-Vue.use(Dropdown)
-Vue.use(DropdownMenu)
-Vue.use(DropdownItem)
-import equipTable from "@/components/table/equipTable";
-import addEquip from "@/components/table/addEquip";
-
+        mapGetters,
+        mapActions
+    } from "vuex";
 export default {
 export default {
   components: {
   components: {
     equipTable,
     equipTable,
     addEquip
     addEquip
   },
   },
+  computed: {
+            ...mapGetters("peojMess", [
+                "projectId",
+                "secret",
+                "userId"
+            ])
+        },
   props: {
   props: {
     width: {
     width: {
       type: String,
       type: String,
@@ -80,13 +82,16 @@ export default {
       activeName: "1",
       activeName: "1",
       myDia: {
       myDia: {
         id: 'Sp11010800034c251365d66111e8bf0a15b159c8e729',
         id: 'Sp11010800034c251365d66111e8bf0a15b159c8e729',
-        ProjId: this.$route.query.projId,
-        secret: this.$route.query.secret
+        ProjId: this.projectId,
+        secret: this.secret
       },
       },
       buildMess: {},
       buildMess: {},
     };
     };
   },
   },
-  created() { },
+  created() { 
+      this.myDia.ProjId = this.projectId
+      this.myDia.secret = this.secret
+  },
   methods: {
   methods: {
     handleClick() { },
     handleClick() { },
     getData(data, buildMess) {
     getData(data, buildMess) {

+ 140 - 130
src/components/business_space/dialogs/influenceDialog.vue

@@ -1,140 +1,150 @@
 <template>
 <template>
-    <el-dialog
-    :visible.sync="isShow.influence"
-    :center="true"
-    :width="width">
-    <span slot="title">{{title}}</span>
-    <div id="influenceDialog">
-        <p class="influence-p">受元空间变化影响,部分业务空间需重新划分</p>
-        <el-tabs type="border-card">
-          <el-tab-pane v-for="(item,index) in tabsList" v-if="index == 0">
-            <span slot="label">{{item.name}}</span>
-            <p style="line-height:30px;font-size:20px;margin-bottom: 20px;">受影响的业务空间</p>
-            <div v-for="i in mess">
-              <p style="line-height:20px;margin-left:10px;">{{i.RoomLocalName || '--'}} - {{i.RoomLocalID || '--'}}</p>
-            </div>
-          </el-tab-pane>
-        </el-tabs>
-    </div>
-    <span slot="footer" class="dialog-footer center">
-        <el-button type="primary" @click="confirm">我知道了</el-button>
-    </span>
+    <el-dialog :visible.sync="isShow.influence" :center="true" :width="width">
+        <span slot="title">{{title}}</span>
+        <div id="influenceDialog">
+            <p class="influence-p">受元空间变化影响,部分业务空间需重新划分</p>
+            <el-tabs type="border-card">
+                <el-tab-pane v-for="(item,index) in tabsList" v-if="index == 0" :key="index">
+                    <span slot="label">{{item.name}}</span>
+                    <p style="line-height:30px;font-size:20px;margin-bottom: 20px;">受影响的业务空间</p>
+                    <div v-for="(i,iIndex) in mess" :key="iIndex">
+                        <p style="line-height:20px;margin-left:10px;">{{i.RoomLocalName || '--'}} - {{i.RoomLocalID || '--'}}</p>
+                    </div>
+                </el-tab-pane>
+            </el-tabs>
+        </div>
+        <span slot="footer" class="dialog-footer center">
+            <el-button type="primary" @click="confirm">我知道了</el-button>
+        </span>
     </el-dialog>
     </el-dialog>
 </template>
 </template>
 <script>
 <script>
-import { getAllMess, deleteNotice } from "@/api/request";
-export default {
-  props: {
-    width: {
-      type: String,
-      default: "40%"
-    },
-    title: {
-      type: String,
-      default: "提示"
-    },
-    isShow: {
-      type: Object
-    },
-    param: {
-      type: Object
-    },
-    tabsList: {
-      type: Array,
-      default: []
-    }
-  },
-  data() {
-    return {
-      data: null,
-      proj: null,
-      activeName: "1",
-      allMess: [], //所有提示
-      mess: [], //实际提示
-      build: {}
-    };
-  },
-  created() {
-    this.getAllMess();
-  },
-  methods: {
-    //我知道了
-    confirm() {
-      let ids = [];
-      if (!!this.allMess[this.build.code]) {
-        this.allMess[this.build.code].map(item => {
-          ids.push(item.RoomID);
-        });
-      }
-      let param = {
-        data: {
-          ids: ids
+    import {
+        getAllMess,
+        deleteNotice
+    } from "@/api/scan/request";
+    import {
+        mapGetters,
+        mapActions
+    } from "vuex";
+    export default {
+        props: {
+            width: {
+                type: String,
+                default: "40%"
+            },
+            title: {
+                type: String,
+                default: "提示"
+            },
+            isShow: {
+                type: Object
+            },
+            param: {
+                type: Object
+            },
+            tabsList: {
+                type: Array,
+                default: []
+            }
         },
         },
-        ProjId: this.$route.query.projId,
-        secret: this.$route.query.secret
-      };
-      deleteNotice(param)
-        .then(res => {
-          if (res.data.Result == "success") {
-            this.isShow.influence = false;
-          } else {
-            this.$message.error(res.data.ResultMsg);
-          }
-        })
-        .catch(() => {
-          this.$message.error("请求失败");
-        });
-    },
-    getData(build) {
-      this.build = build;
-      this.mess = this.allMess[build.code];
-    },
-    getAllMess() {
-      getAllMess({
-        ProjId: this.$route.query.projId,
-        secret: this.$route.query.secret
-      })
-        .then(res => {
-          if (res.data.Result == "success") {
-            // this.allMess = res.data.Content
-            this.changeMsg(res.data.Content);
-            console.log(this.allMess);
-          } else {
-            this.$message.error(res.data.ResultMsg);
-          }
-        })
-        .catch(() => {
-          this.$message.error("请求错误");
-        });
-    },
-
-    //获取楼层信息
-    changeMsg(arr) {
-      arr.map(item => {
-        if (!!this.allMess[item.location.floor]) {
-          this.allMess[item.location.floor].push(item.infos);
-        } else {
-          this.allMess[item.location.floor] = [];
-          this.allMess[item.location.floor].push(item.infos);
+        computed: {
+            ...mapGetters("peojMess", [
+                "projectId",
+                "secret",
+                "userId"
+            ])
+        },
+        data() {
+            return {
+                data: null,
+                proj: null,
+                activeName: "1",
+                allMess: [], //所有提示
+                mess: [], //实际提示
+                build: {}
+            };
+        },
+        created() {
+            this.getAllMess();
+        },
+        methods: {
+            //我知道了
+            confirm() {
+                let ids = [];
+                if (!!this.allMess[this.build.code]) {
+                    this.allMess[this.build.code].map(item => {
+                        ids.push(item.RoomID);
+                    });
+                }
+                let param = {
+                    data: {
+                        ids: ids
+                    },
+                    ProjId: this.projectId,
+                    secret: this.secret
+                };
+                deleteNotice(param)
+                    .then(res => {
+                        if (res.data.Result == "success") {
+                            this.isShow.influence = false;
+                        } else {
+                            this.$message.error(res.data.ResultMsg);
+                        }
+                    })
+                    .catch(() => {
+                        this.$message.error("请求失败");
+                    });
+            },
+            getData(build) {
+                this.build = build;
+                this.mess = this.allMess[build.code];
+            },
+            getAllMess() {
+                getAllMess({
+                        ProjId: this.projectId,
+                        secret: this.secret
+                    })
+                    .then(res => {
+                        if (res.data.Result == "success") {
+                            // this.allMess = res.data.Content
+                            this.changeMsg(res.data.Content);
+                            console.log(this.allMess);
+                        } else {
+                            this.$message.error(res.data.ResultMsg);
+                        }
+                    })
+                    .catch(() => {
+                        this.$message.error("请求错误");
+                    });
+            },
+            //获取楼层信息
+            changeMsg(arr) {
+                arr.map(item => {
+                    if (!!this.allMess[item.location.floor]) {
+                        this.allMess[item.location.floor].push(item.infos);
+                    } else {
+                        this.allMess[item.location.floor] = [];
+                        this.allMess[item.location.floor].push(item.infos);
+                    }
+                });
+            },
+            handleClick() {}
         }
         }
-      });
-    },
-    handleClick() {}
-  }
-};
+    };
 </script>
 </script>
 
 
 <style lang="less">
 <style lang="less">
-#influenceDialog {
-  .el-tabs__content {
-    max-height: 200px;
-    overflow-y: auto;
-  }
-  .influence-p {
-    height: 40px;
-    line-height: 40px;
-    font-size: 17px;
-    margin-bottom: 10px;
-  }
-}
+    #influenceDialog {
+        .el-tabs__content {
+            max-height: 200px;
+            overflow-y: auto;
+        }
+        .influence-p {
+            height: 40px;
+            line-height: 40px;
+            font-size: 17px;
+            margin-bottom: 10px;
+        }
+    }
 </style>
 </style>

+ 1 - 1
src/components/business_space/dialogs/list/filesDialog.vue

@@ -8,7 +8,7 @@
   </el-dialog>
   </el-dialog>
 </template>
 </template>
 <script>
 <script>
-import uploadFiles from "@/components/lib/uploadFiles";
+import uploadFiles from "@/components/business_space/lib/uploadFiles";
 export default {
 export default {
   components: {
   components: {
     uploadFiles
     uploadFiles

+ 3 - 3
src/components/business_space/dialogs/list/firm.vue

@@ -49,9 +49,9 @@
   </el-dialog>
   </el-dialog>
 </template>
 </template>
 <script>
 <script>
-import myPagination from "@/components/lib/myPagination";
-import paramDetails from "@/components/dialogs/list/paramDetails"
-import { getSpecList } from "@/api/request"
+import myPagination from "@/components/common/myPagination";
+import paramDetails from "@/components/business_space/dialogs/list/paramDetails"
+import { getSpecList } from "@/api/scan/request"
 
 
 export default {
 export default {
   components: {
   components: {

+ 4 - 4
src/components/business_space/dialogs/list/guaranteeDialog.vue

@@ -58,10 +58,10 @@
   </el-dialog>
   </el-dialog>
 </template>
 </template>
 <script>
 <script>
-import myPagination from "@/components/lib/myPagination";
-import uploadFiles from '@/components/lib/uploadFiles'
-import { getListForGuarantee, createGuarantee } from "@/api/request"
-import tools from "@/assets/js/tools"
+import myPagination from "@/components/business_space/lib/myPagination";
+import uploadFiles from '@/components/business_space/lib/uploadFiles'
+import { getListForGuarantee, createGuarantee } from "@/api/scan/request"
+import tools from "@/utils/scan/tools"
 export default {
 export default {
   components: {
   components: {
     myPagination,
     myPagination,

+ 3 - 3
src/components/business_space/dialogs/list/insurerDialog.vue

@@ -49,9 +49,9 @@
   </el-dialog>
   </el-dialog>
 </template>
 </template>
 <script>
 <script>
-import myPagination from "@/components/lib/myPagination";
-import { getLib } from "@/api/request"
-import tools from "@/assets/js/tools"
+import myPagination from "@/components/common/myPagination";
+import { getLib } from "@/api/scan/request"
+import tools from "@/utils/scan/tools"
 
 
 export default {
 export default {
   components: {
   components: {

+ 3 - 3
src/components/business_space/dialogs/list/maintainerDialog.vue

@@ -49,9 +49,9 @@
   </el-dialog>
   </el-dialog>
 </template>
 </template>
 <script>
 <script>
-import myPagination from "@/components/lib/myPagination";
-import { getLib } from "@/api/request"
-import tools from "@/assets/js/tools"
+import myPagination from "@/components/common/myPagination";
+import { getLib } from "@/api/scan/request"
+import tools from "@/utils/scan/tools"
 
 
 export default {
 export default {
   components: {
   components: {

+ 1 - 1
src/components/business_space/dialogs/list/paramDetails.vue

@@ -12,7 +12,7 @@
 </template>
 </template>
 <script>
 <script>
 
 
-import { getSpaceHeader } from "@/api/request"
+import { getSpaceHeader } from "@/api/scan/request"
 
 
 export default {
 export default {
   props: {
   props: {

+ 2 - 2
src/components/business_space/dialogs/list/picDialog.vue

@@ -25,8 +25,8 @@
   </el-dialog>
   </el-dialog>
 </template>
 </template>
 <script>
 <script>
-import uploadImgs from "@/components/lib/uploadImgsName";
-import tools from "@/assets/js/tools"
+import uploadImgs from "@/components/business_space/lib/uploadImgsName";
+import tools from "@/utils/scan/tools"
 export default {
 export default {
   components: {
   components: {
     uploadImgs
     uploadImgs

+ 3 - 3
src/components/business_space/dialogs/list/supplierDialog.vue

@@ -49,9 +49,9 @@
   </el-dialog>
   </el-dialog>
 </template>
 </template>
 <script>
 <script>
-import myPagination from "@/components/lib/myPagination";
-import { getLib } from "@/api/request"
-import tools from "@/assets/js/tools"
+import myPagination from "@/components/common/myPagination";
+import { getLib } from "@/api/scan/request"
+import tools from "@/utils/scan/tools"
 
 
 export default {
 export default {
   components: {
   components: {

+ 3 - 3
src/components/business_space/dialogs/list/supplyDialog.vue

@@ -46,9 +46,9 @@
   </el-dialog>
   </el-dialog>
 </template>
 </template>
 <script>
 <script>
-import myPagination from "@/components/lib/myPagination";
-import { getListForSupplier } from "@/api/request"
-import tools from "@/assets/js/tools"
+import myPagination from "@/components/common/myPagination";
+import { getListForSupplier } from "@/api/scan/request"
+import tools from "@/utils/scan/tools"
 
 
 export default {
 export default {
   components: {
   components: {

+ 3 - 3
src/components/business_space/dialogs/list/systemType.vue

@@ -78,9 +78,9 @@
   </el-dialog>
   </el-dialog>
 </template>
 </template>
 <script>
 <script>
-import myPagination from "@/components/lib/myPagination";
-import { getLib, getAllbusiness, getEqCode, getRelation } from "@/api/request"
-import tools from "@/assets/js/tools"
+import myPagination from "@/components/common/myPagination";
+import { getLib, getAllbusiness, getEqCode, getRelation } from "@/api/scan/request"
+import tools from "@/utils/scan/tools"
 
 
 export default {
 export default {
   components: {
   components: {

+ 1 - 1
src/components/business_space/dialogs/list/uploadImgDialog.vue

@@ -8,7 +8,7 @@
   </el-dialog>
   </el-dialog>
 </template>
 </template>
 <script>
 <script>
-import uploadImgs from "@/components/lib/uploadImgsName";
+import uploadImgs from "@/components/business_space/lib/uploadImgsName";
 export default {
 export default {
   components: {
   components: {
     uploadImgs
     uploadImgs

+ 1 - 1
src/components/business_space/dialogs/notRelated.vue

@@ -10,7 +10,7 @@
 </template>
 </template>
 
 
 <script>
 <script>
-import businessTable from "@/components/table/businessTable";
+import businessTable from "@/components/business_space/table/businessTable";
 
 
 export default {
 export default {
   components: {
   components: {

File diff suppressed because it is too large
+ 1292 - 0
src/components/business_space/graphy/business.vue


+ 114 - 0
src/components/business_space/lib/cascaders/assets.vue

@@ -0,0 +1,114 @@
+<template>
+  <div id="cascaderMap">
+    <span class="buildFloor">设备族:</span>
+    <el-cascader
+      placeholder="请选择"
+      :options="options"
+      v-model="value"
+      :props="props"
+      filterable
+      :style="isWidth ? '' : 'width:160px;'"
+      size="small"
+      @change="changeVal"
+      change-on-select
+    ></el-cascader>
+  </div>
+</template>
+<script>
+import { getEquipmentFamily } from "@/api/scan/request";
+export default {
+  name: "getCode",
+  props: {
+    isWidth: {
+      type: Boolean,
+      default: true
+    }
+  },
+  data() {
+    return {
+      value: [],
+      options: [],
+      props: {
+        value: "code",
+        label: "facility"
+      },
+      falg: true,
+      content: []
+    };
+  },
+  created() {
+    this.getData();
+  },
+  mounted() { },
+  methods: {
+    setValue(val) {
+      this.value = val
+    },
+    //修改val
+    changeVal(val) {
+      let value = {}
+      this.options.map(item => {
+        if (item.code == val) {
+          value = item
+        }
+      })
+      this.value = val
+      this.$emit("change", value)
+    },
+    async getData() {
+      let _this = this
+      await getEquipmentFamily(res => {
+        _this.options = _this.changeArr(res.Content)
+        if (!!this.value && this.value.length) {
+          let value = {}
+          this.options.map(item => {
+            if (item.code == this.value[0]) {
+              value = item
+            }
+          })
+          this.$emit("change", value)
+        }
+        if (!_this.falg) {
+          _this.changeList()
+        }
+      })
+    },
+    changeArr(arr) {
+      let data = [];
+      arr.map(item => {
+        data.push({ code: item.code, facility: item.name, disabled: false })
+      });
+      return data;
+    },
+    pushData(content) {
+      this.content = content
+      if (this.options.length) {
+        this.falg = true
+        this.changeList()
+      } else {
+        this.falg = false
+      }
+    },
+    changeList() {
+      this.options.map(item => {
+        item.disabled = true
+        this.content.map(child => {
+          if (item.code == child) {
+            item.disabled = false
+          }
+        })
+      })
+    }
+  }
+};
+</script>
+<style lang="less" scoped>
+#cascaderMap {
+  float: left;
+  margin-left: 10px;
+  .buildFloor {
+    color: #999999;
+    font-size: 14px;
+  }
+}
+</style>

+ 120 - 0
src/components/business_space/lib/cascaders/system.vue

@@ -0,0 +1,120 @@
+<template>
+  <div id="cascaderMap">
+    <span class="buildFloor">所属专业系统类型:</span>
+    <el-cascader
+      placeholder="请选择"
+      :options="options"
+      v-model="value"
+      :props="props"
+      filterable
+      :style="isWidth ? '' : 'width:160px;'"
+      size="small"
+      @change="changeVal"
+      change-on-select
+    ></el-cascader>
+  </div>
+</template>
+<script>
+import { getEqCode } from "@/api/scan/request";
+export default {
+  name: "getCode",
+  props: {
+    isWidth: {
+      type: Boolean,
+      default: true
+    }
+  },
+  data() {
+    return {
+      value: [],
+      options: [],
+      props: {
+        value: "code",
+        label: "facility"
+      },
+      falg: true,
+      content: []
+    };
+  },
+  created() {
+    this.getData();
+  },
+  mounted() { },
+  methods: {
+    setValue(val) {
+      this.value = val
+    },
+    //修改val
+    changeVal(val) {
+      let value = {}
+      this.options.map(item => {
+        if (item.code == val) {
+          value = item
+        }
+      })
+      this.$emit("change", value)
+    },
+    getData() {
+      getEqCode().then(res => {
+        console.log(res.data)
+        this.options = this.changeArr(res.data.Content);
+        if (!!this.value && this.value.length) {
+          let value = {}
+          this.options.map(item => {
+            if (item.code == this.value[0]) {
+              value = item
+            }
+          })
+          this.$emit("change", value)
+        }
+        if (!this.falg) {
+          this.changeList()
+        }
+      });
+    },
+    changeArr(arr) {
+      let data = [];
+      arr.map(item => {
+        if (item.content && item.content.length) {
+          return item.content.map(children => {
+            data.push({ code: children.code, facility: children.system });
+          });
+        }
+      });
+      return data;
+    },
+    //上级页面传入content
+    pushData(content) {
+      this.content = content
+      if (this.options.length) {
+        this.falg = true
+        this.changeList()
+      } else {
+        this.falg = false
+      }
+    },
+
+    //修改list
+    changeList() {
+      this.options.map(item => {
+        item.disabled = true
+        this.content.map(child => {
+          if (item.code == child) {
+            item.disabled = false
+          }
+        })
+      })
+    }
+  }
+};
+</script>
+<style lang="less" scoped>
+#cascaderMap {
+  float: left;
+  margin-left: 10px;
+  .buildFloor {
+    color: #999999;
+    font-size: 14px;
+  }
+}
+</style>

+ 75 - 0
src/components/business_space/lib/detailsDia.vue

@@ -0,0 +1,75 @@
+<template>
+  <el-dialog
+    :title="title"
+    append-to-body
+    class="iframe"
+    :visible.sync="dialog.details"
+    width="500px"
+  >
+    <iframe
+      id="google_ads_frame2"
+      name="google_ads_frame2"
+      frameborder="0"
+      width="100%"
+      height="600px"
+      :src="iframeSrc"
+      marginwidth="0"
+      marginheight="0"
+      vspace="0"
+      hspace="0"
+      allowtransparency="true"
+      scrolling="no"
+      allowfullscreen="true"
+    ></iframe>
+  </el-dialog>
+</template>
+
+<script>
+export default {
+  props: {
+    iframeSrc: {
+      type: String,
+      default: ""
+    },
+    title: {
+      type: String,
+      default: "详情"
+    },
+    dialog: {
+      type: Object,
+      default: function () {
+        return {
+          details: false
+        }
+      }
+    },
+    setData: {
+      type: [Array, String],
+      default: function () {
+        return []
+      }
+    }
+  },
+  methods: {
+    setMess() {
+      this.$nextTick(_ => {
+        let iframe = document.getElementById("google_ads_frame2")
+        iframe.onload = () => {
+          iframe.contentWindow.postMessage(this.setData, "*")
+        }
+      })
+    }
+  },
+  watch: {
+    dialog: {
+      deep: true,
+      handler: function () {
+        if (this.dialog.details) {
+          this.setMess()
+        }
+      }
+    }
+  }
+}
+</script>
+

+ 119 - 0
src/components/business_space/lib/floorCascader.vue

@@ -0,0 +1,119 @@
+<template>
+  <div id="buildFloor">
+    <span class="buildFloor">所属建筑楼层:</span>
+    <el-cascader
+      placeholder="请选择建筑楼层"
+      :options="options"
+      v-model="value"
+      filterable
+      size="small"
+      :style="isWidth ? '' : 'width:160px;'"
+      @change="changeCascader"
+    ></el-cascader>
+  </div>
+</template>
+<script>
+
+import { getSpaceFloor } from '@/api/request'
+
+export default {
+  props: {
+    isWidth: {
+      type: Boolean,
+      default: true
+    },
+    type: {
+      type: String,
+      default: "yes"
+    }
+  },
+  data() {
+    return {
+      options: [
+      ],
+      param: {
+        ProjId: this.$route.query.projId,
+        secret: this.$route.query.secret
+      },
+      value: ['all']
+    };
+  },
+  created() {
+    this.getData()
+  },
+  mounted() { },
+  methods: {
+    //获取数据
+    getData() {
+      getSpaceFloor(this.param).then(res => {
+        if (res.data.Result == 'success') {
+          let data = this.changeArr(res.data.Content)
+          data.unshift({
+            value: "all",
+            label: "全部"
+          }, {
+              value: "noKnow",
+              label: "未明确建筑的设备"
+            })
+          data.map(item => {
+            if (!!item.children) {
+              item.children.unshift({
+                value: 'noKnow',
+                label: "未明确楼层的设备"
+              })
+              item.children.unshift({
+                value: "all",
+                label: "全部"
+              })
+            }
+            return item
+          })
+          this.options = data
+        } else {
+          this.$message.error(res.data.ResultMsg)
+        }
+      }).catch(() => {
+        this.$message.error("请求出错")
+      })
+    },
+    //将数组转换成optiosn格式
+    changeArr(arr) {
+      return arr.map(item => {
+        if (item.floors && item.floors.length && this.type == "yes") {
+          return {
+            value: item.id,
+            label: item.infos.BuildLocalName,
+            children: item.floors.map(i => {
+              return {
+                value: i.id,
+                label: i.infos.FloorLocalName,
+              }
+            })
+          }
+        } else {
+          return {
+            value: item.id,
+            label: item.infos.BuildLocalName,
+            children: null,
+            isChilren: 1,
+          }
+        }
+      })
+    },
+
+    //改变item
+    changeCascader(value) {
+      this.$emit("change", value)
+    }
+  }
+};
+</script>
+<style lang="less" scoped>
+#buildFloor {
+  float: left;
+  .buildFloor {
+    color: #999999;
+    font-size: 14px;
+  }
+}
+</style>

+ 315 - 0
src/components/business_space/lib/formInput.vue

@@ -0,0 +1,315 @@
+<!--
+A1	手工填写-单个-数字-无单位
+A2	手工填写-单个-数字-有单位
+A3	手工填写-多个-数字-无单位
+A4	手工填写-多个-数字-有单位
+A5	手工填写-单个-数字范围-无单位
+A6	手工填写-单个-数字范围-有单位
+A7	手工填写-多个-数字范围-无单位
+A8	手工填写-多个-数字范围-有单位
+B1	手工填写-单个-文本
+B2	手工填写-多个-文本
+C1	手工填写-单个-日期时间值
+C2	手工填写-单个-日期时间段
+C3	手工填写-多个-日期时间值
+C4	手工填写-多个-日期时间段
+C5	手工填写-单个-日期值
+C6	手工填写-单个-日期段
+C7	手工填写-多个-日期值
+C8	手工填写-多个-日期段
+C9	手工填写-单个-时间值
+C10	手工填写-单个-时间段
+C11	手工填写-多个-时间值
+C12	手工填写-多个-时间段
+D1	字典选择-单个-单选
+D2	字典选择-单个-多选
+D3	字典选择-多个-单选
+D4	字典选择-多个-多选
+E1	字典布尔选择-单个
+E2	字典布尔选择-多个
+F1	上传-单个文件 -->
+
+<template>
+  <el-form
+    :label-position="'right'"
+    :labelWidth="width + 'px'"
+    :model="formLabelAlign"
+    ref="form"
+    @submit.native.prevent
+  >
+    <el-form-item :label="label" :rules="isRule ? { required: true, message: '不能为空'} : {}">
+      <!-- 普通输入类型 -->
+      <el-input
+        size="small"
+        v-if="!isShow && (type == 'default' || type == 'B1')"
+        v-model="formLabelAlign.name"
+        style="width: 9rem;"
+        @change="onSubmit"
+        @keyup.enter.native="onSubmit"
+      >
+        <template slot="append" v-if="unit">{{unit}}</template>
+      </el-input>
+      <el-input
+        type="number"
+        v-if="!isShow && (type == 'A1' || type == 'A2')"
+        v-model="formLabelAlign.name"
+        style="width: 9rem;"
+        @change="onSubmit"
+        @keyup.enter.native="onSubmit"
+      >
+        <template slot="append" v-if="unit">{{unit}}</template>
+      </el-input>
+      <!-- date类型 -->
+      <el-date-picker
+        v-if="!isShow && (type == 'year' || type == 'C5')"
+        v-model="formLabelAlign.name"
+        type="date"
+        value-format="yyyy-MM-dd"
+        @change="onSubmit"
+        :clearable="false"
+        placeholder="选择日期"
+      ></el-date-picker>
+      <!-- 级联选择 -->
+      <el-cascader
+        v-if="!isShow && (type == 'cascader' || type == 'D1')"
+        :options="typeArr"
+        v-model="formLabelAlign.name"
+        @change="onSubmit"
+        :props="props"
+      ></el-cascader>
+      <!-- 日期到分 -->
+      <el-date-picker
+        v-if="!isShow && type == 'C1'"
+        v-model="formLabelAlign.name"
+        type="datetime"
+        value-format="yyyy-MM-dd HH:MM"
+        @change="onSubmit"
+        :clearable="false"
+        placeholder="选择日期"
+      ></el-date-picker>
+      <!-- 输入文本框 -->
+      <el-input
+        v-if="!isShow && type == 'B2'"
+        type="textarea"
+        :rows="2"
+        @change="onSubmit"
+        @keyup.enter.native="onSubmit"
+        placeholder="请输入内容"
+        v-model="formLabelAlign.name"
+      ></el-input>
+      <!-- 日期 -->
+      <el-date-picker
+        v-if="!isShow && type == 'C6'"
+        v-model="formLabelAlign.name"
+        type="datetimerange"
+        range-separator="至"
+        start-placeholder="开始日期"
+        end-placeholder="结束日期"
+        value-format="yyyy-MM-dd HH:MM"
+        @change="onSubmit"
+        :clearable="false"
+        placeholder="选择日期"
+      ></el-date-picker>
+      <!-- 点击确定 -->
+      <i
+        v-if="!isShow  && (type == 'default' || type == 'B1')"
+        class="el-input__icon el-icon-check hover"
+        @click="onSubmit"
+      ></i>
+      <!-- 显示基本内容 -->
+      <span v-if="isShow" @click="changeItem" class="hover">
+        {{ filterArr(formLabelAlign.name) }} {{unit}}
+        <i class="el-icon-edit" v-if="type != 'X'"></i>
+      </span>
+      <slot name="mess"></slot>
+    </el-form-item>
+  </el-form>
+</template>
+
+<script>
+export default {
+  name: "ownerInput",
+  props: {
+    type: {
+      type: String,
+      default: "default"
+    }, //类型
+    value: [String, Number, Array], //value值
+    label: String, //label值,从父级传入
+    isRule: Boolean, //是否需要规则
+    keys: [String, Number], //
+    typeArr: [Array, String], //当其为级联或者下拉时传入
+    unit: {
+      //单位
+      type: String,
+      default: ""
+    },
+    width: {
+      type: Number,
+      default: 100
+    }
+  },
+
+  data() {
+    return {
+      formLabelAlign: {
+        name: ""
+      },
+      key: "",
+      isShow: true,
+      props: {
+        label: "name",
+        value: "code",
+        children: "content"
+      } //修改默认数据格式
+    };
+  },
+
+  methods: {
+    //点击确定或者url
+    onSubmit() {
+      if (this.formLabelAlign.name == "" || this.formLabelAlign.name == []) {
+        this.$message.error("请确定值不为空");
+      } else {
+        this.isShow = true;
+        if (this.type == 'cascader' || this.type == 'D1') {
+          let data = this.formLabelAlign.name
+          this.$emit("change", data[data.length - 1], this.keys);
+        } else {
+          this.$emit("change", this.formLabelAlign.name, this.keys);
+        }
+      }
+    },
+
+    //点击文案出现输入
+    changeItem() {
+      if (this.type == "X") {
+        this.$message('该信息点不支持编辑')
+        return;
+      } else {
+        this.isShow = false;
+      }
+    },
+
+    //对数组中的空数组去除
+    toMyNeed(arr) {
+      return arr.map(res => {
+        let param = {};
+        if (res.content && res.content.length != 0) {
+          param.content = this.toMyNeed(res.content);
+        }
+        param.name = res.name;
+        param.code = res.code;
+        return param;
+      });
+    },
+
+    //获取级联选中的值
+    getCascaderObj(val, opt) {
+      let data = this.getMyVal(val, opt, 'name')
+      data.length > 1 ? data = data.join('/') : data = data.join('')
+      return data
+    },
+
+    getMyVal(val, content, code) {
+      let data = []
+      if (content && content.length) {
+        for (let i = 0; i < content.length; i++) {
+          if (content[i].code == val) {
+            data.push(content[i][code])
+            break
+          } else {
+            if (content[i].content && content.length) {
+              for (let j = 0; j < content[i].content.length; j++) {
+                if (content[i].content[j].code == val) {
+                  data.push(content[i][code])
+                  data.push(content[i].content[j][code])
+                  break
+                } else {
+                  if (content[i].content[j].content && content[i].content[j].content.length) {
+                    for (let k = 0; k < content[i].content[j].content.length; k++) {
+                      if (content[i].content[j].content[k].code == val) {
+                        data.push(content[i][code])
+                        data.push(content[i].content[j][code])
+                        data.push(content[i].content[j].content[k][code])
+                        break
+                      } else {
+                      }
+                    }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+      if (!data.length) {
+        data = null
+      }
+      return data
+    },
+
+    getMap(val, opt) {
+      return opt.map(function (value, index, array) {
+        for (var itm of opt) {
+          if (itm.code == value.code) {
+            opt = itm.content;
+            return itm;
+          }
+        }
+        return null;
+      });
+    },
+
+    //数组过滤
+    filterArr(val) {
+      let value = ""; //最后输出的文案
+      let isNeedType = this.type == 'cascader' || this.type == 'D1'
+      if (this.type == 'C6') {
+        value = value != "" ? val[0] + '至' + val[1] : "--"
+      } else if (this.type == 'cascader' || this.type == 'D1') {
+        if (val && val.length) {
+          value = this.getCascaderObj(val[val.length - 1], this.typeArr, 'name') || "--";
+        }
+      } else {
+        value = val || "--";
+      }
+      return value;
+    }
+  },
+
+  created() {
+    if (typeof (this.typeArr) == Object) {
+      this.typeArr = this.toMyNeed(this.typeArr)
+    }
+    if (this.type == 'cascader' || this.type == 'D1') {
+      if (this.value == '' || this.value == undefined) {
+        this.formLabelAlign.name = []
+      } else {
+        this.formLabelAlign.name = this.getMyVal(this.value, this.typeArr, 'code');
+      }
+    } else {
+      this.formLabelAlign.name = this.value;
+    }
+    this.key = this.label;
+  },
+
+  watch: {
+    label() { }
+  }
+};
+</script>
+
+<style lang="less">
+.hover:hover {
+  cursor: pointer;
+  color: #409eff;
+}
+input::-webkit-outer-spin-button,
+input::-webkit-inner-spin-button {
+  -webkit-appearance: none;
+}
+input[type="number"] {
+  -moz-appearance: textfield;
+}
+</style>

+ 181 - 0
src/components/business_space/lib/lookImages.vue

@@ -0,0 +1,181 @@
+<!--
+    上传图片的弹窗
+-->
+
+<template>
+  <el-dialog title="上传图片" :visible.sync="dialog.lookPic" v-if="dialog.lookPic" width="600px">
+    <div style="max-height:700px;overflow-y:auto;">
+      <el-tabs type="border-card">
+        <el-tab-pane>
+          <span slot="label">图片</span>
+          <div style="width:500px;max-height:500px;">
+            <div v-if="picArrs.length">
+              <iframe
+                id="google_ads_frame3"
+                name="google_ads_frame3"
+                frameborder="0"
+                width="100%"
+                height="500px"
+                :src="iframeSrc"
+                marginwidth="0"
+                marginheight="0"
+                vspace="0"
+                hspace="0"
+                allowtransparency="true"
+                scrolling="no"
+                allowfullscreen="true"
+              ></iframe>
+            </div>
+            <div v-if="!picArrs.length">暂无图片</div>
+          </div>
+        </el-tab-pane>
+        <el-tab-pane v-if="videoArr.length">
+          <span slot="label">视频</span>
+          <div style="width:500px;">
+            <div
+              v-for=" (item,index) in videoArr "
+              :key="index"
+              style="width:200px;height:200px;float:left;margin: 5px;"
+            >
+              <video
+                width="100%"
+                height="100%"
+                :src="
+                '/img/image-service/common/image_get?systemId=dataPlatform&key='+item.key"
+                controls
+                :poster="'img/image-service/common/image_get?systemId=dataPlatform&key='+ item.key +'&width=200'"
+              ></video>
+            </div>
+          </div>
+        </el-tab-pane>
+      </el-tabs>
+    </div>
+  </el-dialog>
+</template>
+<script>
+import uploadImgs from "@/components/lib/uploadImgsName";
+import tools from "@/utils/scan/tools"
+export default {
+  components: {
+    uploadImgs
+  },
+  props: {
+    dialog: {
+      type: Object,
+      default: function () {
+        return {
+          lookPic: true
+        };
+      }
+    },
+    keysArr: {
+      type: Array,
+      default: function () {
+        return []
+      }
+    },
+    read: {
+      type: Boolean,
+      default: false
+    }
+  },
+  data() {
+    return {
+      picArrs: [],
+      panoramaArr: [],
+      videoArr: [],
+      videoPicArr: [],
+      changeKeys: [],
+      iframeSrc: ""
+    };
+  },
+  created() { },
+  mounted() { },
+  methods: {
+    imageItem(images) {
+      this.picArrs = images
+      this.change()
+    },
+
+    panoramaItem(images) {
+      this.panoramaArr = images
+      this.change()
+    },
+
+    videoItem(videos, pe, pics) {
+      this.videoArr = videos
+      this.videoPicArr = pics
+      this.change()
+    },
+
+    change() {
+      //   let picsArr = this.getArr(this.picArrs, "设备图片", "image")
+      //   let videos = this.getArr(this.videoArr, "视频", "video")
+      //   let videoPics = this.getArr(this.videoPicArr, "视频资料", "image_video")
+      //   let panoramas = this.getArr(this.panoramaArr, "全景照片", "panorama")
+      let picsArr = this.picArrs
+      let videos = this.videoArr
+      let videoPics = this.videoPicArr
+      let panoramas = this.panoramaArr
+      this.changeKeys = picsArr.concat(videos).concat(videoPics).concat(panoramas)
+      console.log(this.changeKeys)
+      this.$emit("change", this.changeKeys)
+    },
+
+    getArr(arr, name, type) {
+      return arr.map(item => {
+        return { "systemId": "dataPlatform", "name": name, "type": type, "key": item }
+      })
+    },
+
+    //将父组件传来的数据进行分组
+    fatherTochild() {
+      this.panoramaArr = []
+      this.videoArr = []
+      this.videoPicArr = []
+      this.picArrs = []
+      if (this.keysArr instanceof Array) {
+        this.keysArr.map(item => {
+          if (item.type == 'panorama') {
+            this.panoramaArr.push(item)
+          } else if (item.type == "video") {
+            this.videoArr.push(item)
+          } else if (item.type == 'image_video') {
+            this.videoPicArr.push(item)
+          } else {
+            this.picArrs.push(item)
+          }
+        })
+      } else {
+        this.panoramaArr = []
+        this.videoArr = []
+        this.videoPicArr = []
+        this.picArrs = []
+      }
+      if (this.picArrs.length) {
+        this.$nextTick(_ => {
+          this.iframeSrc = process.env.BASE_URL + ":8890/photo-View.html"
+          let iframe = document.getElementById("google_ads_frame3")
+          console.log(iframe)
+          iframe.onload = () => {
+            console.log("onload")
+            iframe.contentWindow.postMessage(this.picArrs, "*")
+          }
+        })
+      }
+    }
+  },
+  watch: {
+    dialog: {
+      deep: true,
+      handler: function () {
+        if (this.dialog.lookPic) {
+          this.fatherTochild()
+        }
+      }
+    }
+  }
+};
+</script>
+<style>
+</style>

+ 58 - 0
src/components/business_space/lib/myPagination.vue

@@ -0,0 +1,58 @@
+<!--
+    props:{
+        size: 当前页的页数,
+        sizes: 下拉的条数,
+        total: 总条数,
+        currentPage: 当前页
+    }
+    @change 发生改变
+-->
+<template>
+    <div class="block">
+        <el-pagination
+        @size-change="handleSizeChange"
+        @current-change="handleCurrentChange"
+        :current-page.sync="page.currentPage"
+        :page-sizes="page.sizes"
+        :page-size="page.size"
+        :small="true"
+        :layout=" isSmall ? 'total, sizes, prev, pager, next, jumper' : 'prev, pager, next'"
+        :total="page.total">
+        </el-pagination>
+    </div>
+</template>
+<script>
+export default {
+  name: "pagination",
+  props: {
+    page: {
+      type: Object
+    },
+    isSmall:{
+      type:Boolean,
+      default: true
+    }
+  },
+  methods: {
+    //当前条数发生改变
+    handleSizeChange(val) {
+      this.page.size = val;
+      this.change()
+    },
+    //当前页发生改变
+    handleCurrentChange(val) {
+      this.page.currentPage = val;
+      this.change()
+    },
+    //发生改变
+    change() {
+      this.$emit("change");
+    }
+  }
+};
+</script>
+<style>
+.block{
+  margin-top: 5px;
+}
+</style>

+ 57 - 0
src/components/business_space/lib/qrcode.vue

@@ -0,0 +1,57 @@
+<template>
+  <el-dialog
+    title="二维码"
+    v-if="dialog.qrcode"
+    custom-class="custom-dialog"
+    :visible.sync="dialog.qrcode"
+    width="300px"
+  >
+    <div>
+      <div id="qrcode">
+        <img
+          style="width:200px;height:200px;margin:auto;display:block;"
+          :src="'image-service/common/file_get/'+ qrcodeUrl +'?systemId=dataPlatform'"
+          alt="二维码"
+        >
+      </div>
+    </div>
+  </el-dialog>
+</template>
+<script>
+// import { qrcanvas } from "qrcanvas";
+export default {
+  props: {
+    dialog: {
+      type: Object,
+      default: function () {
+        return {
+          qrcode: false
+        };
+      }
+    },
+    qrcodeUrl: {
+      default: ""
+    }
+  },
+  data() {
+    return {};
+  },
+  created() { },
+  mounted() {
+  },
+  methods: {
+    // getCanvas(id) {
+    //     let canvas = qrcanvas({
+    //         cellSize: 8,
+    //         data: 'http://service.sagacloud.cn/qrcode/' + 'Pea3a31168a30d4056acda3a56e557940b'
+    //     });
+    //     canvas.style.margin = "auto"
+    //     canvas.style.display = "block"
+    //     this.$nextTick(() => {
+    //         document.getElementById("qrcode").innerHTML = null;
+    //         document.getElementById("qrcode").appendChild(canvas);
+    //     });
+    // }
+  }
+};
+</script>

+ 207 - 0
src/components/business_space/lib/uploadFiles.vue

@@ -0,0 +1,207 @@
+<!--
+  上传组件
+  type: 类型,默认image
+  identify: key值,通过val获取
+  disabled: 是否可用
+  index: 父组件的下标
+  imageIndex: 图片下标
+  isShow: 图片的显示
+ -->
+<template>
+  <div id="saga-upload">
+    <div id="uploadFile">
+      <div v-if="item && filesArr.length" v-for="(item,index) in filesArr">
+        <el-button type="text" @click="download(item)">{{delFile(item)}}</el-button>
+        <i
+          v-if="!readOnly"
+          class="el-icon-close delete-icon"
+          style="margin-left:10px; cursor:pointer"
+          @click="deleteFile(index,item)"
+        ></i>
+      </div>
+      <el-upload
+        v-if="filesArr.length < max"
+        class="upload-file"
+        action
+        :http-request="uploadAndSubmit"
+        :show-file-list="false"
+        drag
+      >
+        <el-button size="small" type="primary" v-if="!readOnly">点击上传</el-button>
+        <div slot="tip" class="el-upload__tip" v-if="!readOnly">请上传文件</div>
+      </el-upload>
+    </div>
+  </div>
+</template>
+
+<script>
+import tools from "@/utils/scan/tools";
+export default {
+  props: {
+    keysArr: {
+      type: [Array, String],
+      default: function () {
+        return []
+      }
+    },
+    readOnly: {
+      type: Boolean,
+      default: false
+    },
+    max: {
+      type: [Number, String],
+      default: 6
+    },
+    defined: null
+  },
+  data() {
+    return {
+      filesArr: []
+    };
+  },
+  created() {
+    let type = typeof (this.keysArr)
+    this.fileFalg()
+  },
+  methods: {
+    //判断是否为空
+    fileFalg() {
+      let type = typeof (this.keysArr)
+      console.log(this.keysArr, "keysAee")
+      if (type == 'string') {
+        this.filesArr = [this.keysArr]
+      } else {
+        this.filesArr = tools.deepCopy(this.keysArr)
+      }
+
+      if (!this.keysArr) {
+        this.filesArr = []
+      }
+    },
+    //处理地址
+    delFile(name) {
+      console.log(name, "name")
+      return name.length > 20 ? name.substring(0, 20) + "..." : ""
+    },
+
+    resetFile() {
+      this.filesArr = []
+    },
+
+
+    //点击下载
+    download(key) {
+      console.log(key)
+      window.open("/img/image-service/common/file_get/" + key + "?systemId=dataPlatform")
+    },
+
+    //删除图片
+    deleteFile(i, key) {
+      this.filesArr.splice(i, 1);
+      this.$emit("change", this.filesArr, this.defined);
+    },
+
+    //上传
+    uploadAndSubmit(item) {
+      // var form = document.forms["demoForm"];
+
+      // if (form["file"].files.length > 0) {
+      // 寻找表单域中的 <input type="file" ... /> 标签
+      // var file = form["file"].files[0];
+
+      let file = item.file;
+      // try sending
+      let reader = new FileReader();
+
+      let vm = this;
+
+      let fileType = file.name.split(".");
+      let type = fileType[fileType.length - 1];
+      let key = "&key=" + fileType[0] + file.uid + "." + type
+
+      reader.onloadstart = function () {
+        // 这个事件在读取开始时触发
+      };
+      reader.onprogress = function (p) {
+        // 这个事件在读取进行中定时触发
+      };
+
+      reader.onload = function () {
+        // 这个事件在读取成功结束后触发
+      };
+      reader.onloadend = function () {
+        // 这个事件在读取结束后,无论成功或者失败都会触发
+        if (reader.error) {
+        } else {
+          // document.getElementById("bytesRead").textContent = file.size;
+          // 构造 XMLHttpRequest 对象,发送文件 Binary 数据
+          var xhr = new XMLHttpRequest();
+          xhr.open(
+            /* method */
+            "POST",
+            /* target url */
+            "/img/image-service/common/file_upload?systemId=dataPlatform&secret=9e0891a7a8c8e885&overwrite=true" + key
+            /*, async, default to true */
+          );
+          //xhr.overrideMimeType("application/octet-stream");
+          xhr.send(reader.result);
+          xhr.onreadystatechange = function () {
+            if (xhr.readyState == 4) {
+              console.log(xhr)
+              if (xhr.status == 200) {
+                vm.filesArr.push(
+                  key.split("=")[1]
+                );
+                console.log(vm.filesArr)
+                vm.$emit("change", vm.filesArr, vm.defined);
+              } else {
+                this.$message.error(res.data.ResultMsg)
+              }
+            }
+          };
+        }
+      };
+      reader.readAsArrayBuffer(file);
+    }
+  },
+  watch: {
+    keysArr: function (val) {
+      this.fileFalg()
+    }
+  }
+};
+</script>
+
+<style lang="less">
+#saga-upload {
+  .dill-image {
+    position: absolute;
+    right: 0px;
+    top: 0px;
+    font-size: 20px;
+  }
+  .el-upload-dragger {
+    width: 180px;
+    height: 180px;
+  }
+  img {
+    position: absolute;
+    top: 0;
+    bottom: 0;
+    left: 0;
+    right: 0;
+    width: 100%;
+    height: 100%;
+  }
+  #uploadFile {
+    .upload-file {
+      overflow: hidden;
+      .el-upload-dragger {
+        width: inherit;
+        height: inherit;
+        border: none;
+      }
+    }
+  }
+}
+</style>

+ 109 - 0
src/components/business_space/lib/uploadImg.vue

@@ -0,0 +1,109 @@
+<template>
+    <el-upload
+    class="avatar-uploader"
+    :http-request="uploadAndSubmit"
+    :show-file-list="false"
+    accept="image/*"
+    action=""
+    drag
+    style="position: relation"
+    >
+        <i class="el-icon-plus avatar-uploader-icon"></i>
+    </el-upload>
+</template>
+
+<script>
+export default {
+  props: {
+    keyName: {
+      type: String,
+      default: ""
+    }
+  },
+  methods: {
+    uploadAndSubmit(item) {
+      // var form = document.forms["demoForm"];
+
+      // if (form["file"].files.length > 0) {
+      // 寻找表单域中的 <input type="file" ... /> 标签
+      // var file = form["file"].files[0];
+
+      let file = item.file;
+      // try sending
+      let reader = new FileReader();
+
+      let vm = this;
+
+      let fileType = file.name.split('.')
+      let type = fileType[fileType.length -1]
+
+      reader.onloadstart = function() {
+        // 这个事件在读取开始时触发
+      };
+      reader.onprogress = function(p) {
+        // 这个事件在读取进行中定时触发
+      };
+
+      reader.onload = function() {
+        // 这个事件在读取成功结束后触发
+      };
+
+      reader.onloadend = function() {
+        // 这个事件在读取结束后,无论成功或者失败都会触发
+        if (reader.error) {
+        } else {
+          // document.getElementById("bytesRead").textContent = file.size;
+          // 构造 XMLHttpRequest 对象,发送文件 Binary 数据
+          var xhr = new XMLHttpRequest();
+          xhr.open(
+            /* method */ "POST",
+            /* target url */
+            "/img/image-service/common/image_upload?systemId=dataPlatform&secret=9e0891a7a8c8e885&overwrite=true&key=" +
+              file.uid + '.' + type
+            /*, async, default to true */
+          );
+          //xhr.overrideMimeType("application/octet-stream");
+          xhr.send(reader.result);
+          xhr.onreadystatechange = function() {
+            if (xhr.readyState == 4) {
+              if (xhr.status == 200) {
+                vm.$emit("getKey", file.uid + '.' + type, vm.keyName);
+              }
+            }
+          };
+        }
+      };
+      reader.readAsArrayBuffer(file);
+    }
+  }
+};
+</script>
+
+<style lang="less">
+.point-pic {
+  .avatar-uploader {
+    height: 180px;
+    width: 180px;
+    overflow: hidden;
+    .el-upload {
+      width: 100%;
+      height: 100%;
+      .el-upload-dragger{
+        width: 100%;
+        height: 100%;
+        .el-icon-plus{
+          display: block;
+          width: 20px;
+          height: 20px;
+          font-size: 20px;
+          margin: 80px;
+        }
+      }
+    }
+  }
+}
+.el-dialog__body{
+  max-height: 600px;
+  overflow-y: auto;
+}
+</style>

+ 321 - 0
src/components/business_space/lib/uploadImgs.vue

@@ -0,0 +1,321 @@
+<!--
+    @param keysArr 承接数组
+    @param readOnly  删除按钮是否显示,上传是否显示
+    @param max     上传最大数限制
+    @click change  承接数组发生变化时触发函数
+-->
+<template>
+  <div id="sagaUploads">
+    <div class="saga-upload-images">
+      <div v-if="type != 'video'" class="point-image" v-for="(item,index) in imagesArr">
+        <i v-if="!readOnly" class="el-icon-delete" @click="delImage(index,item)"></i>
+        <img :src="imageGetUrl + '&key=' +item" alt v-load>
+      </div>
+      <div v-if="type == 'video'" class="point-image" v-for="(item,index) in imagesArr">
+        <i v-if="!readOnly" class="el-icon-delete" @click="delImage(index,item)"></i>
+        <video
+          width="100%"
+          height="100%;"
+          :src="imageGetUrl + '&key=' +item"
+          controls="controls"
+        >您的浏览器不支持 video 标签。</video>
+      </div>
+      <div v-if="!readOnly && imagesArr.length < max" style="float:left;">
+        <el-upload
+          class="avatar-uploader"
+          :http-request="uploadAndSubmit"
+          :show-file-list="false"
+          :accept="accept"
+          action
+          drag
+          style="position: relation"
+        >
+          <i class="el-icon-plus avatar-uploader-icon"></i>
+        </el-upload>
+        <video style="display:none;" id="video" controls/>
+      </div>
+    </div>
+  </div>
+</template>
+<script>
+import tools from "@/utils/scan/tools";
+export default {
+  props: {
+    keysArr: {
+      type: [Array, String]
+    },
+    readOnly: {
+      type: Boolean,
+      default: false
+    },
+    max: {
+      type: [Number, String],
+      default: 6
+    },
+    accept: {
+      type: String,
+      default: "image/*"
+    },
+    type: {
+      type: String,
+      default: "image"
+    },
+    defined: null,
+    videoPicArr: {
+      type: Array,
+      default: function () {
+        return []
+      }
+    }
+  },
+  data() {
+    return {
+      baseUrl: "",
+      imageGetUrl: "/img/image-service/common/image_get?systemId=dataPlatform",
+      imageUploadUrl: "/img/image-service/common/image_upload?systemId=dataPlatform&secret=9e0891a7a8c8e885&overwrite=true",
+      imagesArr: []
+    };
+  },
+  created() {
+    this.imageFalg();
+  },
+  methods: {
+    //判断是否为空
+    imageFalg() {
+      let type = typeof this.keysArr;
+      console.log(this.keysArr)
+      if (type == "string") {
+        this.imagesArr = [this.keysArr];
+      } else {
+        this.imagesArr = tools.deepCopy(this.keysArr);
+      }
+
+      if (!this.keysArr) {
+        this.imagesArr = [];
+      }
+    },
+
+    //删除图片
+    delImage(i, key) {
+      if (this.type == "video") {
+        this.videoPicArr = this.videoPicArr.map(item => {
+          if (item.substring(0, item.length - 3) == this.imagesArr[i].substring(0, this.imagesArr[i].length - 3)) {
+            return undefined
+          } else {
+            return item
+          }
+        }).filter(p => p)
+      }
+      this.imagesArr.splice(i, 1);
+      this.$emit("change", this.imagesArr, this.defined, this.videoPicArr);
+    },
+
+    //上传
+    uploadAndSubmit(item, key) {
+      // var form = document.forms["demoForm"];
+
+      // if (form["file"].files.length > 0) {
+      // 寻找表单域中的 <input type="file" ... /> 标签
+      // var file = form["file"].files[0];
+
+      console.log("lalala", item)
+      let file = item.file;
+      // try sending
+      let reader = new FileReader();
+
+      let vm = this;
+
+      let fileType = file.name.split(".");
+      let type = fileType[fileType.length - 1];
+
+      let uploadKey = file.uid
+      if (!!key) {
+        uploadKey = key
+      }
+
+      reader.onloadstart = function () {
+        // 这个事件在读取开始时触发
+      };
+      reader.onprogress = function (p) {
+        // 这个事件在读取进行中定时触发
+      };
+
+      reader.onload = function () {
+        // 这个事件在读取成功结束后触发
+      };
+      reader.onloadend = function () {
+        // 这个事件在读取结束后,无论成功或者失败都会触发
+        if (reader.error) {
+        } else {
+          // document.getElementById("bytesRead").textContent = file.size;
+          // 构造 XMLHttpRequest 对象,发送文件 Binary 数据
+          var xhr = new XMLHttpRequest();
+          xhr.open(
+            /* method */
+            "POST",
+            /* target url */
+            vm.imageUploadUrl + "&key=" + uploadKey + "." + type
+            /*, async, default to true */
+          );
+          //xhr.overrideMimeType("application/octet-stream");
+          xhr.send(reader.result);
+          xhr.onreadystatechange = function () {
+            if (xhr.readyState == 4) {
+              if (xhr.status == 200) {
+                if (vm.type == 'image') {
+                  vm.imagesArr.push(
+                    uploadKey + "." + type
+                  );
+                }
+                if (type == 'mp4') {
+                  vm.imagesArr.push(
+                    uploadKey + "." + type
+                  );
+                  vm.creatImg(vm.imageGetUrl + "&key=" + uploadKey + "." + type, uploadKey)
+                }
+                console.log(vm.type, type)
+                if (vm.type == "video" && type == "png") {
+                  console.log("触发时评上传图片回调")
+                  vm.videoPicArr.push(uploadKey + "." + type)
+                }
+                vm.$emit("change", vm.imagesArr, vm.defined, vm.videoPicArr);
+              }
+            }
+          };
+        }
+      };
+      reader.readAsArrayBuffer(file);
+    },
+    dataURLtoBlob: function (dataURI, type) {
+      var binary = atob(dataURI.split(',')[1]);
+      var array = [];
+      for (var i = 0; i < binary.length; i++) {
+        array.push(binary.charCodeAt(i));
+      }
+      return new Blob([new Uint8Array(array)], { type: type });
+    },
+
+    creatImg(reader, key) {
+      var videoDom = document.getElementById('video');
+      videoDom.src = reader;
+      let vm = this
+      videoDom.onloadeddata = function () {
+        // 这里可以打印视频时长
+        // 这里取得视频封面
+        var canvas = document.createElement('canvas');
+        canvas.width = 300;
+        canvas.height = 300 * this.videoHeight / this.videoWidth;
+        canvas.getContext('2d').drawImage(this, 0, 0, canvas.width, canvas.height);
+        //将canvas的base64位图片转换成图片png的file
+        var blob = vm.dataURLtoBlob(canvas.toDataURL('image/png'), "image/png")
+        //将其转换成file对象
+        var file = new File([blob], "video_image.png", { type: "image/png", lastModified: Date.now() })//blob转file
+        vm.uploadAndSubmit({ file: file }, key)
+      }
+    },
+  },
+  watch: {
+    keysArr: function (val) {
+      this.imageFalg();
+    }
+  },
+  //自定义指令
+  directives: {
+    load: function (el) {
+      let imgDom = document.createElement("img");
+      imgDom.style.position = "absolute";
+      imgDom.style.top = "-999px";
+      imgDom.style.opacity = 0;
+      imgDom.src = el.src;
+      el.src = "";
+      imgDom.onload = () => {
+        let width = imgDom.width;
+        let height = imgDom.height;
+        if (width > height) {
+          el.style.height = "100%";
+          el.style.width = "auto";
+          el.style.position = "absolute";
+          el.style.left = "50%";
+          el.style.top = "0";
+          el.style.transform = "translateX(-50%)";
+          el.style.webkitTransform = "translateX(-50%) translateY(0)";
+          el.style.MozTransform = "translateX(-50%) translateY(0)";
+          el.style.msTransform = "translateX(-50%) translateY(0)";
+          el.style.OTransform = "translateX(-50%) translateY(0)";
+        } else if (width < height) {
+          el.src = imgDom.src;
+          el.style.width = "100%";
+          el.style.height = "auto";
+          el.style.position = "absolute";
+          el.style.top = "50%";
+          el.style.left = "0";
+          el.style.transform = "translateY(-50%) translateX(0)";
+          el.style.webkitTransform = "translateY(-50%) translateX(0)";
+          el.style.MozTransform = "translateY(-50%) translateX(0)";
+          el.style.msTransform = "translateY(-50%) translateX(0)";
+          el.style.OTransform = "translateY(-50%) translateX(0)";
+        } else {
+          el.style.width = "100%";
+          el.style.height = "100%";
+          el.style.position = "absolute";
+          el.style.top = "0";
+          el.style.left = "0";
+          el.style.transform = "translateY(0) translateX(0)";
+          el.style.webkitTransform = "translateY(0) translateX(0)";
+          el.style.MozTransform = "translateY(0) translateX(0)";
+          el.style.msTransform = "translateY(0) translateX(0)";
+          el.style.OTransform = "translateY(0) translateX(0)";
+        }
+        el.src = imgDom.src;
+      };
+    }
+  }
+};
+</script>
+<style lang="less">
+#sagaUploads {
+  overflow: hidden;
+  .avatar-uploader {
+    height: 180px;
+    width: 180px;
+    overflow: hidden;
+    .el-upload {
+      width: 180px;
+      height: 180px;
+      .el-upload-dragger {
+        width: 180px;
+        height: 180px;
+        .el-icon-plus {
+          display: block;
+          width: 20px;
+          height: 20px;
+          font-size: 20px;
+          margin: 80px;
+        }
+      }
+    }
+  }
+  .point-image {
+    width: 180px;
+    height: 180px;
+    float: left;
+    position: relative;
+    margin-right: 10px;
+    margin-bottom: 10px;
+    border: 1px solid #ccc;
+    overflow: hidden;
+    image {
+      z-index: 11;
+    }
+    i {
+      position: absolute;
+      bottom: 10px;
+      right: 10px;
+      background-color: #fff;
+      padding: 5px;
+      cursor: pointer;
+      z-index: 66;
+    }
+  }
+}
+</style>

+ 365 - 0
src/components/business_space/lib/uploadImgsName.vue

@@ -0,0 +1,365 @@
+<!--
+    @param keysArr 承接数组
+    @param readOnly  删除按钮是否显示,上传是否显示
+    @param max     上传最大数限制
+    @click change  承接数组发生变化时触发函数
+-->
+<template>
+  <div id="sagaUploads">
+    <div class="saga-upload-images">
+      <div v-if="type != 'video'" class="point-view" v-for="(item,index) in imagesArr">
+        <div class="point-image">
+          <i v-if="!readOnly" class="el-icon-delete" @click="delImage(index,item)"></i>
+          <img @click="lookImg" :src="imageGetUrl + '&key=' +item.key" alt v-load>
+        </div>
+        <form-input :label="''" @change="getName" :keys="index" :value="item.name" :width="10"></form-input>
+      </div>
+      <div v-if="type == 'video'" class="point-view" v-for="(item,index) in imagesArr">
+        <div class="point-image">
+          <i v-if="!readOnly" class="el-icon-delete" @click="delImage(index,item)"></i>
+          <video
+            width="100%"
+            height="100%;"
+            :src="imageGetUrl + '&key=' +item.key"
+            controls="controls"
+          >您的浏览器不支持 video 标签。</video>
+        </div>
+        <form-input :label="''" @change="getName" :keys="index" :value="item.name" :width="10"></form-input>
+      </div>
+      <div v-if="!readOnly && imagesArr.length < max" style="float:left;">
+        <el-upload
+          class="avatar-uploader"
+          :http-request="uploadAndSubmit"
+          :show-file-list="false"
+          :accept="accept"
+          action
+          drag
+          style="position: relation"
+        >
+          <i class="el-icon-plus avatar-uploader-icon"></i>
+        </el-upload>
+        <video style="display:none;" id="video" controls/>
+      </div>
+    </div>
+    <details-dialog :title="'图片'" :iframeSrc="iframeSrc" :dialog="dialog" :setData="imagesArr"></details-dialog>
+  </div>
+</template>
+<script>
+import tools from "@/utils/scan/tools";
+import formInput from "@/components/business_space/lib/formInput"
+import detailsDialog from "@/components/business_space/lib/detailsDia"
+
+export default {
+  components: {
+    formInput,
+    detailsDialog
+  },
+  props: {
+    keysArr: {
+      type: [Array, String]
+    },
+    readOnly: {
+      type: Boolean,
+      default: false
+    },
+    max: {
+      type: [Number, String],
+      default: 6
+    },
+    accept: {
+      type: String,
+      default: "image/*"
+    },
+    type: {
+      type: String,
+      default: "image"
+    },
+    defined: null,
+    videoPicArr: {
+      type: Array,
+      default: function () {
+        return []
+      }
+    }
+  },
+  data() {
+    return {
+      baseUrl: "",
+      imageGetUrl: "/img/image-service/common/image_get?systemId=dataPlatform",
+      imageUploadUrl: "/img/image-service/common/image_upload?systemId=dataPlatform&secret=9e0891a7a8c8e885&overwrite=true",
+      imagesArr: [],
+      iframeSrc: "",
+      dialog: {
+        details: false
+      }
+    };
+  },
+  created() {
+    this.imageFalg();
+  },
+  methods: {
+    getName(name, index) {
+      console.log(this.imagesArr, "imagesArr")
+      this.imagesArr[index].name = name
+      this.$emit("change", this.imagesArr, this.defined, this.videoPicArr);
+    },
+    //判断是否为空
+    imageFalg() {
+      let type = typeof this.keysArr;
+      if (type == "string") {
+        this.imagesArr = [this.keysArr];
+      } else {
+        this.imagesArr = tools.copyArr(this.keysArr);
+      }
+
+      if (!this.keysArr) {
+        this.imagesArr = [];
+      }
+    },
+
+    //查看图片
+    lookImg() {
+      this.dialog.details = true
+      this.iframeSrc = process.env.BASE_URL + ":8890/photo-View.html"
+    },
+
+    //删除图片
+    delImage(i, key) {
+      if (this.type == "video") {
+        this.videoPicArr = this.videoPicArr.map(item => {
+          if (item.key.substring(0, item.length - 3) == this.imagesArr[i].key.substring(0, this.imagesArr[i].length - 3)) {
+            return undefined
+          } else {
+            return item
+          }
+        }).filter(p => p)
+      }
+      this.imagesArr.splice(i, 1);
+      this.$emit("change", this.imagesArr, this.defined, this.videoPicArr);
+    },
+
+    //上传
+    uploadAndSubmit(item, key) {
+      // var form = document.forms["demoForm"];
+
+      // if (form["file"].files.length > 0) {
+      // 寻找表单域中的 <input type="file" ... /> 标签
+      // var file = form["file"].files[0];
+
+      console.log("lalala", item)
+      let file = item.file;
+      // try sending
+      let reader = new FileReader();
+
+      let vm = this;
+
+      let fileType = file.name.split(".");
+      let type = fileType[fileType.length - 1];
+
+      let uploadKey = file.uid
+      if (!!key) {
+        uploadKey = key
+      }
+
+      reader.onloadstart = function () {
+        // 这个事件在读取开始时触发
+      };
+      reader.onprogress = function (p) {
+        // 这个事件在读取进行中定时触发
+      };
+
+      reader.onload = function () {
+        // 这个事件在读取成功结束后触发
+      };
+      reader.onloadend = function () {
+        // 这个事件在读取结束后,无论成功或者失败都会触发
+        if (reader.error) {
+        } else {
+          // document.getElementById("bytesRead").textContent = file.size;
+          // 构造 XMLHttpRequest 对象,发送文件 Binary 数据
+          var xhr = new XMLHttpRequest();
+          xhr.open(
+            /* method */
+            "POST",
+            /* target url */
+            vm.imageUploadUrl + "&key=" + uploadKey + "." + type
+            /*, async, default to true */
+          );
+          //xhr.overrideMimeType("application/octet-stream");
+          xhr.send(reader.result);
+          xhr.onreadystatechange = function () {
+            if (xhr.readyState == 4) {
+              if (xhr.status == 200) {
+                if (vm.type == 'image') {
+                  vm.imagesArr.push(
+                    {
+                      name: uploadKey,
+                      key: uploadKey + "." + type,
+                      systemId: "dataPlatform",
+                      type: "image"
+                    }
+                  );
+                }
+                if (type == 'mp4') {
+                  vm.imagesArr.push({
+                    name: uploadKey,
+                    key: uploadKey + "." + type,
+                    systemId: "dataPlatform",
+                    type: "video"
+                  }
+                  );
+                  vm.creatImg(vm.imageGetUrl + "&key=" + uploadKey + "." + type, uploadKey)
+                }
+                if (vm.type == "video" && type == "png") {
+                  vm.videoPicArr.push({
+                    name: uploadKey,
+                    key: uploadKey + "." + type,
+                    systemId: "dataPlatform",
+                    type: "image_video"
+                  })
+                }
+                vm.$emit("change", vm.imagesArr, vm.defined, vm.videoPicArr);
+              }
+            }
+          };
+        }
+      };
+      reader.readAsArrayBuffer(file);
+    },
+    dataURLtoBlob(dataURI, type) {
+      var binary = atob(dataURI.split(',')[1]);
+      var array = [];
+      for (var i = 0; i < binary.length; i++) {
+        array.push(binary.charCodeAt(i));
+      }
+      return new Blob([new Uint8Array(array)], { type: type });
+    },
+
+    creatImg(reader, key) {
+      var videoDom = document.getElementById('video');
+      videoDom.src = reader;
+      let vm = this
+      videoDom.onloadeddata = function () {
+        // 这里可以打印视频时长
+        // 这里取得视频封面
+        var canvas = document.createElement('canvas');
+        canvas.width = 300;
+        canvas.height = 300 * this.videoHeight / this.videoWidth;
+        canvas.getContext('2d').drawImage(this, 0, 0, canvas.width, canvas.height);
+        //将canvas的base64位图片转换成图片png的file
+        var blob = vm.dataURLtoBlob(canvas.toDataURL('image/png'), "image/png")
+        //将其转换成file对象
+        var file = new File([blob], "video_image.png", { type: "image/png", lastModified: Date.now() })//blob转file
+        vm.uploadAndSubmit({ file: file }, key)
+      }
+    },
+  },
+  watch: {
+    keysArr: function (val) {
+      this.imageFalg();
+    }
+  },
+  //自定义指令
+  directives: {
+    load: function (el) {
+      let imgDom = document.createElement("img");
+      imgDom.style.position = "absolute";
+      imgDom.style.top = "-999px";
+      imgDom.style.opacity = 0;
+      imgDom.src = el.src;
+      el.src = "";
+      imgDom.onload = () => {
+        let width = imgDom.width;
+        let height = imgDom.height;
+        if (width > height) {
+          el.style.height = "100%";
+          el.style.width = "auto";
+          el.style.position = "absolute";
+          el.style.left = "50%";
+          el.style.top = "0";
+          el.style.transform = "translateX(-50%)";
+          el.style.webkitTransform = "translateX(-50%) translateY(0)";
+          el.style.MozTransform = "translateX(-50%) translateY(0)";
+          el.style.msTransform = "translateX(-50%) translateY(0)";
+          el.style.OTransform = "translateX(-50%) translateY(0)";
+        } else if (width < height) {
+          el.src = imgDom.src;
+          el.style.width = "100%";
+          el.style.height = "auto";
+          el.style.position = "absolute";
+          el.style.top = "50%";
+          el.style.left = "0";
+          el.style.transform = "translateY(-50%) translateX(0)";
+          el.style.webkitTransform = "translateY(-50%) translateX(0)";
+          el.style.MozTransform = "translateY(-50%) translateX(0)";
+          el.style.msTransform = "translateY(-50%) translateX(0)";
+          el.style.OTransform = "translateY(-50%) translateX(0)";
+        } else {
+          el.style.width = "100%";
+          el.style.height = "100%";
+          el.style.position = "absolute";
+          el.style.top = "0";
+          el.style.left = "0";
+          el.style.transform = "translateY(0) translateX(0)";
+          el.style.webkitTransform = "translateY(0) translateX(0)";
+          el.style.MozTransform = "translateY(0) translateX(0)";
+          el.style.msTransform = "translateY(0) translateX(0)";
+          el.style.OTransform = "translateY(0) translateX(0)";
+        }
+        el.src = imgDom.src;
+      };
+    }
+  }
+};
+</script>
+<style lang="less">
+#sagaUploads {
+  overflow: hidden;
+  .avatar-uploader {
+    height: 180px;
+    width: 180px;
+    overflow: hidden;
+    .el-upload {
+      width: 180px;
+      height: 180px;
+      .el-upload-dragger {
+        width: 180px;
+        height: 180px;
+        .el-icon-plus {
+          display: block;
+          width: 20px;
+          height: 20px;
+          font-size: 20px;
+          margin: 80px;
+        }
+      }
+    }
+  }
+  .point-view {
+    float: left;
+    margin-right: 10px;
+    margin-bottom: 10px;
+    overflow: hidden;
+    height: 240px;
+  }
+  .point-image {
+    width: 180px;
+    height: 180px;
+    position: relative;
+    border: 1px solid #ccc;
+    overflow: hidden;
+    image {
+      z-index: 11;
+    }
+    i {
+      position: absolute;
+      bottom: 10px;
+      right: 10px;
+      background-color: #fff;
+      padding: 5px;
+      cursor: pointer;
+      z-index: 66;
+    }
+  }
+}
+</style>

+ 569 - 0
src/components/business_space/table/addEquip.vue

@@ -0,0 +1,569 @@
+<template>
+  <div>
+    <div class="search" style="margin-bottom:10px;">
+      <div>
+        <el-input
+          placeholder="输入设备名称或设备本地编码查询进行查询"
+          size="small"
+          style="width:300px;float:left;margin-right:10px;"
+          v-model="search.filter"
+          clearable
+        ></el-input>
+        <el-button @click="filterBox" plain size="small">查 找</el-button>
+      </div>
+      <div style="margin-top:10px;">
+        <span>所属楼层:</span>
+        <el-cascader
+          size="small"
+          @change="filterBox"
+          v-model="search.floor"
+          :options="optionsWithDisabled"
+        ></el-cascader>
+        <el-checkbox
+          style="margin-left:20px;"
+          @change="filterBox"
+          :checked="search.checkbox"
+          label="只显示在当前业务空间中的设备"
+        ></el-checkbox>
+      </div>
+    </div>
+    <el-table
+      ref="multipleTable"
+      :data="tableData"
+      v-loading="isLoading"
+      tooltip-effect="dark"
+      size="small"
+      height="300"
+      style="width: 100%"
+      @selection-change="handleSelectionChange"
+    >
+      <el-table-column type="selection" width="55"></el-table-column>
+      <el-table-column width="180" label="设备名称">
+        <template slot-scope="scope">
+          <span style="margin-left: 10px">
+            <el-tooltip
+              :content="scope.row.infos.EquipLocalName ||scope.row.infos.EquipName"
+              placement="top"
+            >
+              <span>{{scope.row.infos.EquipLocalName || scope.row.infos.EquipName | cutString(15)}}</span>
+            </el-tooltip>
+          </span>
+        </template>
+      </el-table-column>
+      <el-table-column width="180" label="设备本地编码">
+        <template slot-scope="scope">
+          <span style="margin-left: 10px">
+            <el-tooltip :content="scope.row.infos.EquipLocalID || '--'" placement="top">
+              <span>{{scope.row.infos.EquipLocalID || "--" | cutString(15)}}</span>
+            </el-tooltip>
+          </span>
+        </template>
+      </el-table-column>
+      <el-table-column width="160" label="设备类">
+        <template slot-scope="scope">
+          <span style="margin-left: 10px">
+            <span>{{getName(scope.row.category)}}</span>
+          </span>
+        </template>
+      </el-table-column>
+      <el-table-column width="160" label="已关联其他业务空间">
+        <template slot-scope="scope">
+          <span style="margin-left: 10px">
+            <el-tooltip :content="changeArray(scope.row.spaceName)" placement="top">
+              <span>{{changeArray(scope.row.spaceName) | cutString(6)}}</span>
+            </el-tooltip>
+          </span>
+        </template>
+      </el-table-column>
+      <el-table-column label="操作">
+        <template slot-scope="scope">
+          <el-button type="info" size="mini" @click="lockDetails(scope.row)">设备详情</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+    <el-dialog width="40%" title="设备详情" :visible.sync="innerVisible" append-to-body>
+      <iframe height="400px" width="100%" :src="iframeSrc"></iframe>
+    </el-dialog>
+    <my-pagination :page="page" @change="pageChange"></my-pagination>
+    <div style="width:100%;overflow:hidden;margin-top:20px;">
+      <div style="height:50px;width:50%;float:left;">
+        <el-button style="float:right;margin-right:20px;" @click="clearBox">取 消</el-button>
+      </div>
+      <div style="height:50px;width:50%;float:left;">
+        <el-button type="primary" @click="addReal">确 定</el-button>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import {
+  getSpaceEquip,
+  searchCode,
+  getEqCode,
+  getSpaceFloor,
+  createRelation,
+  getGraphyId,
+  getEquipSearch,
+  getListForBuss
+} from "@/api/scan/request";
+import myPagination from "@/components/common/myPagination.vue";
+import tools from "@/utils/scan/tools";
+import {
+    mapGetters,
+    mapActions
+} from "vuex";
+export default {
+  name: "equip-table",
+  components: {
+    myPagination
+  },
+  computed: {
+        ...mapGetters("peojMess", [
+            "projectId",
+            "secret",
+            "userId"
+        ])
+    },
+  data() {
+    return {
+      search: {
+        filter: "",
+        checkbox: false,
+        floor: [],
+        leiArr: []
+      },
+      innerVisible: false,
+      iframeSrc: "",
+      page: {
+        size: 10,
+        sizes: [10, 30, 50, 100, 150, 200],
+        total: 400,
+        currentPage: 1
+      },
+      optionsWithDisabled: [],
+      tableData: [],
+      allData: [], //全部的数据
+      multipleSelection: [],
+      list: {},
+      build: {},
+      graphyId: "",
+      isLoading: false,
+      activeTabType: null,
+    };
+  },
+  created() {
+    // this.getData();
+    this.getEqCode();
+    this.getFloor();
+  },
+  methods: {
+    getEqCode() {
+      getEqCode()
+        .then(res => {
+          if (res.data.Result == "success") {
+            this.EqCode = res.data.Content;
+          } else {
+            this.$message.error(res.data.ResultMsg);
+          }
+        })
+        .catch(() => {
+          this.$message.error("请求失败");
+        });
+    },
+    changeArray(val) {
+      if (val instanceof Array) {
+        return val.join(",");
+      } else {
+        return "--";
+      }
+    },
+    clearBox() {
+      this.$refs.multipleTable.clearSelection();
+    },
+    //获取设备关系
+    getGraphyId() {
+      let param = {
+        type: this.type,
+        ProjId: this.projectId, //项目id
+        secret: this.secret
+      };
+      getGraphyId(param)
+        .then(res => {
+          if (res.data.Result == "success") {
+            this.graphyId = res.data.graph_id;
+            this.getEquip()
+          } else {
+            this.$message.error(res.data.ResultMsg);
+          }
+        })
+        .catch(() => {
+          this.$message.error("请求错误");
+        });
+    },
+    //获取楼层
+    getFloor() {
+      let param = {
+        ProjId: this.projectId,
+        UserId: this.userId,
+        secret: this.secret
+      };
+      getSpaceFloor(param)
+        .then(res => {
+          if (res.data.Result == "success") {
+            this.optionsWithDisabled = this.changeArr(res.data.Content);
+            this.optionsWithDisabled = this.optionsWithDisabled.map(item => {
+              if (item.children && item.children.length) {
+                item.children.unshift({
+                  value: "no",
+                  label: "未指定楼层的设备"
+                });
+              } else {
+                item.children = [{
+                  value: "no",
+                  label: "未指定楼层的设备"
+                }];
+              }
+              return item;
+            });
+          } else {
+            this.$message.error(res.data.ResultMsg);
+          }
+        })
+        .catch(() => {
+          this.$message.error("请求出错");
+        });
+    },
+    getName(code) {
+      let text = "",
+        myClass = code.substring(0, 2),
+        system = code.substring(2, 4),
+        last = code.substring(2, 6);
+      if (this.EqCode && this.EqCode.length) {
+        this.EqCode.map(item => {
+          if (item.code == myClass) {
+            item.content.map(i => {
+              if (i.code == system) {
+                i.content.map(e => {
+                  if ((e.code == last)) {
+                    text = e.facility;
+                  }
+                });
+              }
+            });
+          }
+        });
+      }
+      return text;
+    },
+    //工具函数,获取下拉列表
+    changeArr(arr) {
+      return arr.map(item => {
+        if (item.floors && item.floors.length) {
+          return {
+            value: item.id,
+            label: item.infos.BuildLocalName || "--",
+            children: item.floors.map(i => {
+              return {
+                value: i.id,
+                label: i.infos.FloorLocalName || "--"
+              };
+            })
+          };
+        } else {
+          return {
+            value: item.id,
+            label: item.infos.BuildLocalName || "--",
+            children: null
+          };
+        }
+      });
+    },
+    /**
+     * 过滤条件
+     */
+    filterBox(val) {
+      if (typeof val == "boolean") {
+        this.search.checkbox = val;
+      }
+      if (this.search.checkbox) {
+        this.getEquip()
+      } else {
+        if (!!this.search.filter) {
+          searchCode({
+            key: this.search.filter
+          })
+            .then(res => {
+              if (res.data.Result == "success") {
+                this.search.leiArr = res.data.Content;
+                this.getEquip();
+              } else {
+                this.$message.error(res.data.ResultMsg);
+              }
+            })
+            .catch(() => {
+              this.$message.error("请求出错");
+            });
+        } else {
+          this.getEquip();
+        }
+      }
+    },
+    /**
+     * 删除
+     * @param row 点击的当条数据
+     */
+    deleteSpace(row) { },
+    /**
+     * 获取数据
+     * @param data 由上级页面传入,初始化table表格
+     */
+    getData(list, build, type, activeTabType) {
+      this.activeTabType = activeTabType
+      this.list = list;
+      this.build = build;
+      this.search.floor = [build.buildCode, build.code];
+      this.type = type
+      this.getGraphyId();
+      this.page = {
+        size: 50,
+        sizes: [10, 30, 50, 100, 150, 200],
+        total: 0,
+        currentPage: 1
+      };
+      this.getEquip();
+    },
+    //获取数据
+    getEquip() {
+      this.isLoading = true;
+      let relType = ""
+      if (this.activeTabType.rel_type == 99) {
+        relType = "1"
+      } else {
+        if (this.activeTabType.rel_type > 9) {
+          relType = (this.activeTabType.rel_type * 100).toString()
+        } else {
+          relType = '0' + this.activeTabType.rel_type * 100
+        }
+      }
+      if (this.type == "EquipinSpace" && this.activeTabType.rel_type == 99) {
+        if (this.search.checkbox) {
+          this.isLoading = false
+          this.tableData = []
+          this.page.total = 0
+        } else {
+          if (!this.search.filter) {
+            this.search.leiArr = []
+          }
+          let param = {
+            data: {
+              limit: {
+                // 可选
+                skip: this.page.size * (this.page.currentPage - 1), // 跳过多少数据
+                count: this.page.size // 查询跳过300条数据之后的50条 (默认按照创建时间从大-->小排序)
+              },
+              criteria: {
+                building: this.search.floor[0], //建筑
+                floor: this.search.floor[1] == "no" ? null : this.search.floor[1], // 选填, 指定楼层id
+                name: this.search.filter, // 选填, 模糊搜索指定信息点的值
+                type: this.search.leiArr.length ? this.search.leiArr : ["Eq"],
+                space: this.list.id, // 必填, 指定业务空间id
+                excludeGraphType: this.type,
+                excludeRelType: relType,
+                isGeneralZone: true,
+                type: ["Eq"] // 必填, 查询类型, 允许四位编码的详细设备类
+              }
+            },
+            ProjId: this.projectId, //项目id
+            secret: this.secret
+          };
+          getEquipSearch(param)
+            .then(res => {
+              if (res.data.Result == "success") {
+                this.page.total = res.data.TotalCount;
+                this.tableData = res.data.Content;
+                this.isLoading = false;
+              } else {
+                this.$message.error(res.data.ResultMsg);
+              }
+            })
+            .catch(() => this.$message.error("请求失败"));
+        }
+      } else {
+        if (this.search.checkbox) {
+          let param = {
+            data: {
+              limit: {
+                // 可选
+                skip: this.page.size * (this.page.currentPage - 1), // 跳过多少数据
+                count: this.page.size // 查询跳过300条数据之后的50条 (默认按照创建时间从大-->小排序)
+              },
+              criteria: {
+                building: this.search.floor[0], //建筑
+                floor: this.search.floor[1] == "no" ? null : this.search.floor[1], // 选填, 指定楼层id
+                name: this.search.filter, // 选填, 模糊搜索指定信息点的值
+                type: this.search.leiArr.length ? this.search.leiArr : ["Eq"],
+                space: this.list.id, // 必填, 指定业务空间id
+                excludeGraphType: this.type,
+                excludeRelType: relType
+              }
+            },
+            ProjId: this.projectId, //项目id
+            secret: this.secret
+          };
+          getListForBuss(param, res => {
+            this.page.total = res.TotalCount;
+            this.tableData = res.Content;
+            this.isLoading = false;
+          })
+        } else {
+          let param = {
+            data: {
+              limit: {
+                // 可选
+                skip: this.page.size * (this.page.currentPage - 1), // 跳过多少数据
+                count: this.page.size // 查询跳过300条数据之后的50条 (默认按照创建时间从大-->小排序)
+              },
+              criteria: {
+                building: this.search.floor[0], //建筑
+                floor: this.search.floor[1] == "no" ? null : this.search.floor[1], // 选填, 指定楼层id
+                name: this.search.filter, // 选填, 模糊搜索指定信息点的值
+                type: this.search.leiArr.length ? this.search.leiArr : ["Eq"],
+                space: this.list.id, // 必填, 指定业务空间id
+                excludeGraphType: this.type,
+                excludeRelType: relType,
+                type: ["Eq"] // 必填, 查询类型, 允许四位编码的详细设备类
+              }
+            },
+            ProjId: this.projectId, //项目id
+            secret: this.secret
+          };
+          getEquipSearch(param)
+            .then(res => {
+              if (res.data.Result == "success") {
+                this.page.total = res.data.TotalCount;
+                this.tableData = res.data.Content;
+                this.isLoading = false;
+              } else {
+                this.$message.error(res.data.ResultMsg);
+              }
+            })
+            .catch(() => this.$message.error("请求失败"));
+        }
+      }
+    },
+    /**
+     * 分页函数
+     * @param pageNo   当前页数
+     * @param pageSize 当前条数
+     * @param array    全部数据
+     */
+    pagination(pageNo, pageSize, array) {
+      let offset = (pageNo - 1) * pageSize;
+      return offset + pageSize >= array.length ?
+        array.slice(offset, array.length) :
+        array.slice(offset, offset + pageSize);
+    },
+    /**
+     * 查看详情
+     * @param row 点击的当条数据
+     */
+    lockDetails(row) {
+      this.innerVisible = true;
+      this.iframeSrc = this.iframeSrc =
+        process.env.BASE_URL + ":8889/#/details?perjectId=" +
+        this.projectId +
+        "&secret=" +
+        this.secret +
+        "&FmId=" +
+        row.id +
+        "&type=0&code=" +
+        row.category.substring(2, 6);
+    },
+    pageChange() {
+      this.getEquip();
+    },
+    handleSelectionChange(val) {
+      this.multipleSelection = val;
+    },
+    //添加关系,点击确定按钮
+    addReal() {
+      if (this.multipleSelection && this.multipleSelection.length) {
+        let param = {
+          data: {
+            criterias: []
+          },
+          ProjId: this.projectId, //项目id
+          secret: this.secret
+        };
+        let falg = false;
+        if (!!!this.activeTabType) {
+          this.$message.error("没有rel_type")
+        }
+        this.multipleSelection.map(item => {
+          let rel_type = ""
+          if (this.activeTabType.rel_type < 10) {
+            rel_type = '0' + (this.activeTabType.rel_type * 100)
+          } else {
+            rel_type = (this.activeTabType.rel_type * 100).toString()
+          }
+          param.data.criterias.push({
+            from_id: item.id,
+            to_id: this.list.id,
+            graph_id: this.graphyId,
+            rel_type: this.activeTabType.rel_type == "99" ? "1" : rel_type
+          });
+          if (!!item.spaceName) {
+            falg = true;
+          }
+        });
+        if (falg) {
+          this.$confirm("选择的部分设备不在业务空间中确定添加?", "删除", {
+            confirmButtonText: "确定",
+            cancelButtonText: "取消",
+            type: "warning"
+          })
+            .then(() => {
+              this.createReal(param);
+            })
+            .catch(() => {
+              this.$message({
+                type: "info",
+                message: "已取消添加"
+              });
+              this.clearBox();
+            });
+        } else {
+          this.createReal(param);
+        }
+      } else {
+        this.$message.error("请选择设备再确定关联");
+      }
+    },
+    createReal(param) {
+      createRelation(param)
+        .then(res => {
+          if (res.data.Result == "success") {
+            this.$message.success("添加成功");
+            this.getEquip();
+          } else {
+            this.$message.error(res.data.ResultMsg);
+          }
+        })
+        .catch(() => {
+          this.$message.error("请求出错");
+        });
+    }
+  },
+  filters: {
+    cutString: function (str, len) {
+      //length属性读出来的汉字长度为1
+      if (!!str && typeof str == "string" && str.length > len) {
+        return str.substring(0, len) + "...";
+      } else {
+        return str || "--";
+      }
+    }
+  }
+};
+</script>

+ 246 - 0
src/components/business_space/table/businessTable.vue

@@ -0,0 +1,246 @@
+<template>
+  <div>
+    <div style="margin-bottom: 15px;">
+      <el-input
+        placeholder="请输入内容"
+        @blur="querySearch"
+        size="small"
+        v-model="search"
+        class="input-with-select"
+      >
+        <el-button slot="append" @click="querySearch" icon="el-icon-search"></el-button>
+      </el-input>
+    </div>
+    <el-table
+      :data="tableData"
+      height="300"
+      :stripe="true"
+      border
+      size="small"
+      v-loading="isLoading"
+      style="width: 100%"
+    >
+      <el-table-column label="业务空间名称">
+        <template slot-scope="scope">
+          <span style="margin-left: 10px">
+            <el-tooltip
+              :content="scope.row.infos.RoomLocalName || scope.row.infos.RoomName"
+              placement="top"
+            >
+              <span>{{scope.row.infos.RoomLocalName || scope.row.infos.RoomName | cutString(8)}}</span>
+            </el-tooltip>
+          </span>
+        </template>
+      </el-table-column>
+      <el-table-column v-if="type == 'relevance'" label="操作">
+        <template slot-scope="scope">
+          <el-button type="text" size="mini" @click="deleteSpace(scope.row)">关联平面图</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+    <my-pagination :page="page" @change="pageChange"></my-pagination>
+  </div>
+</template>
+
+<script>
+import { getBussines2, createRelation } from "@/api/scan/request";
+import myPagination from "@/components/common/myPagination.vue";
+import {
+        mapGetters,
+        mapActions
+    } from "vuex";
+export default {
+  name: "equip-table",
+  components: {
+    myPagination
+  },
+  computed: {
+            ...mapGetters("peojMess", [
+                "projectId",
+                "secret",
+                "userId"
+            ])
+        },
+  props: {
+    type: {
+      type: String,
+      default: "default"
+    }
+  },
+  data() {
+    return {
+      page: {
+        size: 50,
+        sizes: [10, 30, 50, 100, 150, 200],
+        total: 1,
+        currentPage: 1
+      },
+      tableData: [],
+      allData: null,
+      search: "",
+      list: {},
+      graphy: "",
+      isLoading: false,
+      code: null
+    };
+  },
+  created() { },
+  methods: {
+    getData(list, build, graphy, code) {
+      this.isLoading = true;
+      this.list = list;
+      this.graphy = graphy;
+      this.code = code
+      getBussines2(
+        //       {
+        //     data: {
+        //       criteria: {
+        //         id: build.code,
+        //         graphId: graphy,
+        //         relType: !!code ? code.rel_type : "99",
+        //         exclude: "false",
+        //         side: 1,
+        //         type: [code.code]
+        //       }
+        //     },
+        //     ProjId: this.projectId,
+        //     secret: this.secret
+        //   }
+        {
+          data: {
+            criteria: {
+              id: build.code,
+              // graphId: this.graphyId,
+              // relType: this.spaceType.rel_type,
+              // exclude: false,
+              // side: 1,
+              type: [code.code],
+              "exclude": [            // 可选, 只查询指定图/关系中的对象
+                {
+                  "graphId": graphy,
+                  "graphType": code.code,
+                  "relType": !!code ? code.rel_type : "99",
+                  "side": "toId",
+                  // "fromId": "",                 // 选填
+                  // "toId": ""                    // 选填
+                }
+              ]
+            },
+          },
+          ProjId: this.projectId,
+          secret: this.secret
+        })
+        .then(res => {
+          if (res.data.Result == "success") {
+            this.allData = res.data.Content || [];
+            this.page.total = this.allData.length;
+            this.tableData = this.pagination(
+              this.page.currentPage,
+              this.page.size,
+              this.allData
+            );
+            this.isLoading = false;
+          } else {
+            this.$message.error(res.data.ResultMsg);
+          }
+        })
+        .catch(() => {
+          this.$message.error("请求出错");
+        });
+    },
+    /**
+     * 分页函数
+     * @param pageNo   当前页数
+     * @param pageSize 当前条数
+     * @param array    全部数据
+     */
+    pagination(pageNo, pageSize, array) {
+      let offset = (pageNo - 1) * pageSize;
+      return offset + pageSize >= array.length
+        ? array.slice(offset, array.length)
+        : array.slice(offset, offset + pageSize);
+    },
+
+    //搜索
+    querySearch() {
+      var restaurants = this.allData;
+      var results = this.search
+        ? restaurants.filter(this.createFilter(this.search))
+        : restaurants;
+      this.page.total = results.length;
+      this.tableData = this.tableData = this.pagination(
+        this.page.currentPage,
+        this.page.size,
+        results
+      );
+    },
+    createFilter(queryString) {
+      return restaurant => {
+        return (
+          restaurant.infos.RoomLocalName.indexOf(queryString) > -1
+        );
+      };
+    },
+    /**
+     * 删除
+     * @param row 点击的当条数据
+     */
+    deleteSpace(row) {
+      let param = {
+        data: {
+          criterias: []
+        },
+        ProjId: this.projectId,
+        secret: this.secret
+      };
+      this.list.map(item => {
+        param.data.criterias.push({
+          from_id: item.id, //必填,object id
+          to_id: row.id, //必填,object id
+          graph_id: this.graphy, //必填,图实例id
+          rel_type: this.code.rel_type
+        });
+      });
+      createRelation(param)
+        .then(res => {
+          if (res.data.Result == "success") {
+            this.$message.success("关联成功");
+            this.$emit("createSuccess");
+          } else {
+            this.$message.error(res.data.ResultMsg);
+          }
+        })
+        .catch(() => {
+          this.$message.error("请求失败");
+        });
+    },
+    /**
+     * 查看详情
+     * @param row 点击的当条数据
+     */
+    lockDetails(row) { },
+    pageChange() {
+      this.tableData = this.pagination(
+        this.page.currentPage,
+        this.page.size,
+        this.allData
+      );
+    }
+  },
+  filters: {
+    cutString: function (str, len) {
+      //length属性读出来的汉字长度为1
+      if (!!str && typeof str == "string" && str.length > len) {
+        return str.substring(0, len) + "...";
+      } else {
+        return str || "--";
+      }
+    }
+  }
+};
+</script>
+<style>
+.el-table tr th {
+  background: #fafafa !important;
+}
+</style>

+ 365 - 0
src/components/business_space/table/equipTable.vue

@@ -0,0 +1,365 @@
+<template>
+    <div>
+        <el-tabs v-model="activeRelation" @tab-click="changeTabs">
+            <el-tab-pane v-for=" (item,index) in relationList" :key="index" :label="item.name" :name="item.code">
+                <el-table :data="tableData" height="300" :stripe="true" border size="small" v-loading="isLoading" style="width: 100%">
+                    <el-table-column width="180" label="设备名称">
+                        <template slot-scope="scope">
+                  <span style="margin-left: 10px">
+                    <el-tooltip :content="scope.row.infos.EquipName" placement="top">
+                      <span>{{scope.row.infos.EquipName | cutString(15)}}</span>
+                    </el-tooltip>
+                  </span>
+</template>
+          </el-table-column>
+          <el-table-column width="160" label="设备类">
+<template slot-scope="scope">
+    <span style="margin-left: 10px">
+                    <span>{{getName(scope.row.category)}}</span>
+    </span>
+</template>
+          </el-table-column>
+          <el-table-column label="操作">
+<template slot-scope="scope">
+    <el-button type="info" size="mini" @click="lockDetails(scope.row)">
+        详情</el-button>
+    <el-button v-if="scope.row.inSpace" type="danger" size="mini" @click="deleteSpace(scope.row)">从空间移除</el-button>
+</template>
+          </el-table-column>
+        </el-table>
+        <my-pagination :page="page" @change="pageChange"></my-pagination>
+      </el-tab-pane>
+    </el-tabs>
+    <el-dialog width="40%" title="设备详情" :visible.sync="innerVisible" append-to-body>
+      <iframe height="400px" width="100%" :src="iframeSrc"></iframe>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+    import myPagination from "@/components/common/myPagination.vue";
+    import {
+        getSpaceEquip,
+        getEqCode,
+        deleteRelation,
+        getGraphyId,
+        getSysToEq
+    } from "@/api/scan/request";
+    import {
+        mapGetters,
+        mapActions
+    } from "vuex";
+    export default {
+        name: "equip-table",
+        components: {
+            myPagination
+        },
+        computed: {
+            ...mapGetters("peojMess", [
+                "projectId",
+                "secret",
+                "userId"
+            ])
+        },
+        props: {
+            param: {
+                type: Object
+            },
+            activeTabType: {
+                type: Object,
+                default: function() {
+                    return {
+                        "code": "GeneralZone",
+                        "name": "默认分区",
+                        "rel_type": "99"
+                    }
+                }
+            }
+        },
+        data() {
+            return {
+                page: {
+                    size: 50,
+                    sizes: [10, 30, 50, 100, 150, 200],
+                    total: 0,
+                    currentPage: 1
+                },
+                tableData: [],
+                data: {},
+                EqCode: [],
+                innerVisible: false,
+                iframeSrc: "",
+                title: "",
+                graphyId: "",
+                isLoading: false,
+                relationList: [{
+                    name: "空间内的设备",
+                    code: "EquipinSpace"
+                }, {
+                    name: "服务于空间的设备",
+                    code: "EquipforSpace"
+                }, {
+                    name: "其他关系的设备",
+                    code: "EquipXSpace"
+                }],
+                activeRelation: "EquipinSpace",
+                relationType: {
+                    "code": "GeneralZone",
+                    "name": "默认分区",
+                    "rel_type": "99"
+                },
+                relType: 0
+            };
+        },
+        created() {
+            this.getEqCode();
+        },
+        methods: {
+            changeTabs() {
+                let param = {
+                    data: {
+                        limit: {
+                            // 可选
+                            skip: this.page.size * (this.page.currentPage - 1), // 跳过多少数据
+                            count: this.page.size // 查询跳过300条数据之后的50条 (默认按照创建时间从大-->小排序)
+                        },
+                        criteria: {
+                            space: this.data.id, // 必填, 指定业务空间id
+                            type: ["Eq"] // 必填, 查询类型, 允许四位编码的详细设备类
+                        }
+                    },
+                    ProjId: this.projectId, //项目id
+                    secret: this.secret
+                };
+                this.isLoading = true
+                if (this.relationType.rel_type == 99 && this.activeRelation == "EquipinSpace") {
+                    this.dataChange(param);
+                } else {
+                    this.getRlations()
+                }
+            },
+            getEqCode() {
+                getEqCode()
+                    .then(res => {
+                        if (res.data.Result == "success") {
+                            this.EqCode = res.data.Content;
+                        } else {
+                            this.$message.error(res.data.ResultMsg);
+                        }
+                    })
+                    .catch(() => {
+                        this.$message.error("请求失败");
+                    });
+            },
+            getGraphyId(row) {
+                let param = {
+                    type: this.activeRelation,
+                    ProjId: this.projectId, //项目id
+                    secret: this.secret
+                };
+                getGraphyId(param)
+                    .then(res => {
+                        if (res.data.Result == "success") {
+                            this.graphyId = res.data.graph_id;
+                            this.deleteOwn(row)
+                        } else {
+                            this.$message.error(res.data.ResultMsg);
+                        }
+                    })
+                    .catch(() => {
+                        this.$message.error("请求错误");
+                    });
+            },
+            getRlations() {
+                this.isLoading = true
+                this.relType = 0
+                if (this.relationType.rel_type == 99) {
+                    this.relType = "1"
+                } else {
+                    if (this.relationType.rel_type > 9) {
+                        this.relType = (this.relationType.rel_type * 100).toString()
+                    } else {
+                        this.relType = '0' + (this.relationType.rel_type * 100)
+                    }
+                }
+                let param = {
+                    data: {
+                        "limit": { // 可选
+                            skip: this.page.size * (this.page.currentPage - 1), // 跳过多少数据
+                            count: this.page.size // 查询跳过300条数据之后的50条 (默认按照创建时间从大-->小排序)
+                        },
+                        criteria: {
+                            graphType: this.activeRelation,
+                            relType: this.relType,
+                            toId: this.data.id,
+                            fromId: this.data.fromId,
+                            type: ["Eq"]
+                        }
+                    },
+                    ProjId: this.projectId, //项目id
+                    secret: this.secret
+                }
+                getSysToEq(param, res => {
+                    this.tableData = res.Content.map(item => {
+                        item.inSpace = true
+                        return item
+                    })
+                    this.page.total = res.TotalCount;
+                    this.isLoading = false
+                })
+            },
+            deleteOwn(row) {
+                let param = {
+                    data: {
+                        criterias: [{
+                            from_id: row.id, //选填
+                            to_id: this.data.id, //选填
+                            graph_id: this.graphyId, //选填
+                            rel_type: this.relType
+                        }]
+                    },
+                    ProjId: this.projectId, //项目id
+                    secret: this.secret
+                };
+                this.$confirm("正在删除设备关系, 是否继续?", "删除", {
+                        confirmButtonText: "确定",
+                        cancelButtonText: "取消",
+                        type: "warning"
+                    })
+                    .then(() => {
+                        deleteRelation(param)
+                            .then(res => {
+                                if (res.data.Result == "success") {
+                                    this.$message.success("删除成功");
+                                    this.change();
+                                } else {
+                                    this.$message.error(res.data.ResultMsg);
+                                }
+                            })
+                            .catch(() => {
+                                this.$message.error("请求出错");
+                            });
+                    })
+                    .catch(() => {
+                        this.$message("取消删除");
+                    });
+            },
+            getName(code) {
+                let text = "",
+                    myClass = code.substring(0, 2),
+                    system = code.substring(2, 4),
+                    last = code.substring(2, 6);
+                if (this.EqCode && this.EqCode.length) {
+                    this.EqCode.map(item => {
+                        if (item.code == myClass) {
+                            item.content.map(i => {
+                                if (i.code == system) {
+                                    i.content.map(e => {
+                                        if ((e.code == last)) {
+                                            text = e.facility;
+                                        }
+                                    });
+                                }
+                            });
+                        }
+                    });
+                }
+                return text;
+            },
+            /**
+             * 删除
+             * @param row 点击的当条数据
+             */
+            deleteSpace(row) {
+                this.getGraphyId(row)
+            },
+            /**
+             * 获取数据
+             * @param data 由上级页面传入,初始化table表格
+             */
+            getData(data, type) {
+                this.activeRelation = "EquipinSpace"
+                this.relationType = type
+                this.page = {
+                    size: 50,
+                    sizes: [10, 30, 50, 100, 150, 200],
+                    total: 0,
+                    currentPage: 1
+                };
+                this.data = data;
+                this.change();
+            },
+            change() {
+                let param = {
+                    data: {
+                        limit: {
+                            // 可选
+                            skip: this.page.size * (this.page.currentPage - 1), // 跳过多少数据
+                            count: this.page.size // 查询跳过300条数据之后的50条 (默认按照创建时间从大-->小排序)
+                        },
+                        criteria: {
+                            space: this.data.id, // 必填, 指定业务空间id
+                            type: ["Eq"] // 必填, 查询类型, 允许四位编码的详细设备类
+                        }
+                    },
+                    ProjId: this.projectId, //项目id
+                    secret: this.secret
+                };
+                this.isLoading = true
+                if (this.relationType.rel_type == 99) {
+                    this.dataChange(param);
+                } else {
+                    this.getRlations()
+                }
+            },
+            dataChange(param) {
+                getSpaceEquip(param)
+                    .then(res => {
+                        if (res.data.Result == "success") {
+                            this.page.total = res.data.TotalCount;
+                            this.tableData = res.data.Content;
+                            this.isLoading = false
+                        } else {
+                            this.$message.error(res.data.ResultMsg);
+                        }
+                    })
+                    .catch(() => this.$message.error("请求失败"));
+            },
+            /**
+             * 查看详情
+             * @param row 点击的当条数据
+             */
+            lockDetails(row) {
+                this.innerVisible = true;
+                this.iframeSrc = this.iframeSrc =
+                    // "http://172.16.0.181:8889/#/details?perjectId=" +
+                    process.env.BASE_URL + ":8889/#/details?perjectId=" +
+                    this.perjectId +
+                    "&secret=" +
+                    this.secret +
+                    "&FmId=" +
+                    row.id +
+                    "&type=0&code=" +
+                    row.category.substring(2, 6);
+            },
+            pageChange() {
+                this.change();
+            }
+        },
+        filters: {
+            cutString: function(str, len) {
+                //length属性读出来的汉字长度为1
+                if (!!str && typeof str == "string" && str.length > len) {
+                    return str.substring(0, len) + "...";
+                } else {
+                    return str || "--";
+                }
+            }
+        }
+    };
+</script>
+<style>
+    .el-table tr th {
+        background: #fafafa !important;
+    }
+</style>

+ 58 - 0
src/components/common/myPagination.vue

@@ -0,0 +1,58 @@
+<!--
+    props:{
+        size: 当前页的页数,
+        sizes: 下拉的条数,
+        total: 总条数,
+        currentPage: 当前页
+    }
+    @change 发生改变
+-->
+<template>
+    <div class="block">
+        <el-pagination
+        @size-change="handleSizeChange"
+        @current-change="handleCurrentChange"
+        :current-page.sync="page.currentPage"
+        :page-sizes="page.sizes"
+        :page-size="page.size"
+        :small="true"
+        :layout=" isSmall ? 'total, sizes, prev, pager, next, jumper' : 'prev, pager, next'"
+        :total="page.total">
+        </el-pagination>
+    </div>
+</template>
+<script>
+export default {
+  name: "pagination",
+  props: {
+    page: {
+      type: Object
+    },
+    isSmall:{
+      type:Boolean,
+      default: true
+    }
+  },
+  methods: {
+    //当前条数发生改变
+    handleSizeChange(val) {
+      this.page.size = val;
+      this.change()
+    },
+    //当前页发生改变
+    handleCurrentChange(val) {
+      this.page.currentPage = val;
+      this.change()
+    },
+    //发生改变
+    change() {
+      this.$emit("change");
+    }
+  }
+};
+</script>
+<style>
+.block{
+  margin-top: 5px;
+}
+</style>

+ 1 - 1
src/router/sagacloud.js

@@ -13,7 +13,7 @@ import pointSteps from '@/views/point/config_point/steps'
 import collectsetting from "@/views/project_setting/collection_setting/index"
 import collectsetting from "@/views/project_setting/collection_setting/index"
 
 
 /** 业务空间 */
 /** 业务空间 */
-import spacelist from "@/views/business_space/admin"
+import spacelist from "@/views/business_space/business_list"
 
 
 /** 扫楼数据整理 */
 /** 扫楼数据整理 */
 import buildAssets from "@/views/data_admin/buildAssets"
 import buildAssets from "@/views/data_admin/buildAssets"

+ 84 - 0
src/utils/handsontable/mainText.js

@@ -0,0 +1,84 @@
+const text = {
+
+    //图片类型
+    picType: (instance, td, row, col, prop, value, cellProperties) => {
+        td.style.color = "#409EFF";
+        td.style.cursor = "pointer";
+        if (value instanceof Array && value.length > 0) {
+            let i = 0
+            value.map(item => {
+                if (item.type == "image" || item.type == "video") {
+                    i++
+                }
+            })
+            td.innerHTML = "已上传:" + i;
+        } else {
+            td.innerHTML = "点击上传"
+        }
+        return td;
+    },
+    // 文件类型
+    fileType: (instance, td, row, col, prop, value, cellProperties) => {
+        td.style.color = "#409EFF";
+        td.style.cursor = "pointer";
+        if (value instanceof Array && value.length > 0) {
+            td.innerHTML = "已上传:" + value.length;
+        } else {
+            td.innerHTML = "点击上传"
+        }
+        return td;
+    },
+    //系统类型
+    systemList: (instance, td, row, col, prop, value, cellProperties) => {
+        td.style.color = "#409EFF";
+        td.style.cursor = "pointer";
+        if (value instanceof Array && value.length > 0) {
+            if (value.length == 1) {
+                td.innerHTML = !!value[0].infos ? (value[0].infos.SysLocalName || value[0].infos.SysName) : (value[0].SysLocalName || value[0].SysName)
+            } else {
+                let text = ""
+                for (let i = 0; i < value.length; i++) {
+                    if (!!value[i].SysLocalName || !!value[i].SysName) {
+                        if (i == value.length) {
+                            text += value[i].SysLocalName || value[i].SysName
+                        } else {
+                            text = value[i].SysLocalName || value[i].SysName + "、" + text
+                        }
+                    } else {
+                        if (i == value.length) {
+                            text += value[i].infos.SysLocalName || value[i].infos.SysName
+                        } else {
+                            text = value[i].infos.SysLocalName || value[i].infos.SysName + "、" + text
+                        }
+                    }
+                }
+                td.innerHTML = text.substring(0, 40) + "..."
+            }
+        } else {
+            td.innerHTML = "无关联系统"
+        }
+        return td;
+    },
+    //四大厂商
+    idType: (instance, td, row, col, prop, value, cellProperties) => {
+        td.style.color = "#409EFF";
+        td.style.cursor = "pointer";
+        if (!!value) {
+            let data = value.split("-")[1] || "空名"
+            td.innerHTML = data
+        } else {
+            td.innerHTML = "点击选择"
+        }
+        return td
+    },
+
+    //查看二维码
+    lookQRCode: (instance, td, row, col, prop, value, cellProperties) => {
+        td.style.color = "#409EFF";
+        td.style.cursor = "pointer";
+        td.innerHTML = "查看二维码"
+        return td
+    }
+}
+
+export default text

+ 541 - 0
src/utils/handsontable/notShow.js

@@ -0,0 +1,541 @@
+// 不显示的信息点数组
+import text from "@/utils/handsontable/mainText"
+import tools from "@/utils/scan/tools"
+let noShowArr = [
+    "Brand",
+    "Specification",
+    "Manufacturer",
+    "Supplier",
+    "SupplierContactor",
+    "SupplierPhone",
+    "SupplierEmail",
+    "SupplierWeb",
+    "SupplierFax",
+    "Maintainer",
+    "MaintainerContactor",
+    "MaintainerPhone",
+    "MaintainerEmail",
+    "MaintainerWeb",
+    "Principal",
+    "MaintainerFax",
+    "Insurer",
+    "InsurerContactor",
+    "InsurerPhone",
+    "InsurerEmail",
+    "InsurerWeb",
+    "InsurerFax",
+    "InsuranceFile",
+    "EquipID",
+    "EquipName",
+]
+
+let cantShow = [
+    "EquipQRCode",
+    "EquipID",
+    "EquipName",
+    "BIMLocation",
+    "Brand",
+    "Specification",
+    "Manufacturer",
+    "Supplier",
+    "SupplierContactor",
+    "SupplierPhone",
+    "SupplierEmail",
+    "SupplierWeb",
+    "SupplierFax",
+    "Maintainer",
+    "MaintainerContactor",
+    "MaintainerPhone",
+    "MaintainerEmail",
+    "MaintainerWeb",
+    "Principal",
+    "MaintainerFax",
+    "Insurer",
+    "InsurerContactor",
+    "InsurerPhone",
+    "InsurerEmail",
+    "InsurerWeb",
+    "InsurerFax",
+    "InsuranceFile",
+    "EquipID",
+    "EquipName"
+]
+
+let cutArr = [{
+    name: "品牌型号",
+    code: "DPManufacturerID",
+    num: 2,
+}, {
+    name: "供应商信息",
+    code: "DPSupplierID",
+    num: 5
+}, {
+    name: "维修商信息",
+    code: "DPMaintainerID",
+    num: 19
+}, {
+    name: "保险公司信息",
+    code: "DPInsurerID",
+    num: 25
+}]
+
+let newData = [{
+    name: "品牌型号",
+    code: "DPManufacturerID",
+    num: 2,
+}, {
+    name: "供应商信息",
+    code: "DPSupplierID",
+    num: 8
+}, {
+    name: "维修商信息",
+    code: "DPMaintainerID",
+    num: 35
+}, {
+    name: "保险公司信息",
+    code: "DPInsurerID",
+    num: 42
+}]
+
+const showTools = {
+    addArr: () => {
+        return cutArr
+    },
+    cantShow: (code) => {
+        let falg = true
+        cantShow.map(item => {
+            if (item == code) {
+                falg = false
+            }
+        })
+        return falg
+    },
+
+    //几种类型不显示
+    technologyParam: (item) => {
+        if (
+            item.FirstTag == "控制参数" &&
+            item.FirstTag == "设定参数" &&
+            item.FirstTag == "运行参数"
+        ) {
+            return undefined
+        }
+    },
+    isShow: (code) => {
+        let falg = true
+        noShowArr.map(item => {
+            if (item == code) {
+                falg = false
+            }
+        })
+        return falg
+    },
+
+    //插入需要的关系
+    insertionRea: (data) => {
+        cutArr.map(item => {
+            data.splice(item.num, 0, item.name)
+        })
+        return data
+    },
+
+    insertionRea2: (data) => {
+        newData.map(item => {
+            data.splice(item.num, 0, item.name)
+        })
+        return data
+    },
+
+    insertionType: (data, callback) => {
+        cutArr.map(item => {
+            data.splice(item.num, 0, {
+                data: "infos." + item.code,
+                renderer: callback,
+                readOnly: false
+            })
+        })
+        return data
+    },
+    insertionType2: (data, callback) => {
+        newData.map(item => {
+            data.splice(item.num, 0, {
+                data: "infos." + item.code,
+                renderer: callback,
+                readOnly: false
+            })
+        })
+        return data
+    },
+    arrToArr(arr) {
+        let first = 0,
+            scound = 0,
+            three = 0,
+            four = 0
+        arr.find(function(value, index, arr) {
+            if (
+                (value.InfoPointName == "品牌" ||
+                    value.InfoPointName == "设备型号" ||
+                    value.InfoPointName == "生产厂家") && !first
+            ) {
+                first = index
+            }
+            if (
+                (value.InfoPointName == "供应商单位名称" ||
+                    value.InfoPointName == "供应商联系人" ||
+                    value.InfoPointName == "供应商电子邮件" ||
+                    value.InfoPointName == "供应商网址" ||
+                    value.InfoPointName == "供应商传真" ||
+                    value.InfoPointName == "供应商联系电话") && !scound
+            ) {
+                scound = index
+            }
+            if (
+                (value.InfoPointName == "维修商单位名称" ||
+                    value.InfoPointName == "维修商联系人" ||
+                    value.InfoPointName == "维修商联系电话" ||
+                    value.InfoPointName == "维修商电子邮件" ||
+                    value.InfoPointName == "维修商网址" ||
+                    value.InfoPointName == "维修商传真") && !three
+            ) {
+                three = index
+            }
+            if (
+                (value.InfoPointName == "保险公司名称" ||
+                    value.InfoPointName == "保险公司联系人" ||
+                    value.InfoPointName == "保险公司联系电话" ||
+                    value.InfoPointName == "保险公司电子邮件" ||
+                    value.InfoPointName == "保险公司网址" ||
+                    value.InfoPointName == "保险公司传真") && !four
+            ) {
+                four = index
+            }
+        })
+        let numList = [first, scound, three, four]
+        numList.reverse().map((item, index) => {
+            if (!!item) {
+                if (index == 0) {
+                    arr.splice(item, 0, {
+                        InfoPointName: "保险公司信息",
+                        InfoPointCode: "DPInsurerID",
+                        InputMode: "Own",
+                        Unit: "",
+                        SecondTag: "",
+                        FirstTag: "",
+                        Visible: true,
+                    })
+                } else if (index == 1) {
+                    arr.splice(item, 0, {
+                        InfoPointName: "维修商信息",
+                        InfoPointCode: "DPMaintainerID",
+                        InputMode: "Own",
+                        Unit: "",
+                        SecondTag: "",
+                        FirstTag: "",
+                        Visible: true,
+                    })
+                } else if (index == 2) {
+                    arr.splice(item, 0, {
+                        InfoPointName: "供应商信息",
+                        InfoPointCode: "DPSupplierID",
+                        InputMode: "Own",
+                        Unit: "",
+                        SecondTag: "",
+                        FirstTag: "",
+                        Visible: true,
+                    })
+                } else if (index == 3) {
+                    arr.splice(item, 0, {
+                        InfoPointName: "品牌型号",
+                        InfoPointCode: "DPManufacturerID",
+                        InputMode: "Own",
+                        Unit: "",
+                        SecondTag: "",
+                        FirstTag: "",
+                        Visible: true,
+                    })
+                }
+            }
+        })
+        return arr
+    },
+    changeTypes(arr, onlyRead, isWatch, allMess, falg = false, taizhang = false) {
+        let data = arr.map(item => {
+            if (falg) {
+                if (item.FirstTag == "控制参数" ||
+                    item.FirstTag == "设定参数" ||
+                    item.FirstTag == "运行参数") {
+                    return undefined
+                }
+            }
+            if (item.InfoPointCode == "BIMLocation") {
+                return undefined
+            }
+            if (item.Visible || !allMess) {
+                //固定不显示的code
+                if (!showTools.cantShow(item.InfoPointCode) && !onlyRead && !taizhang) {
+                    return undefined
+                }
+
+                if (!showTools.isShow(item.InfoPointCode) && !taizhang && !taizhang) {
+                    if (isWatch && !onlyRead) {
+                        return undefined
+                    }
+                }
+
+                if (item.InfoPointCode == "EquipQRCode") {
+                    return {
+                        data: "Infos." + item.InfoPointCode,
+                        renderer: text.lookQRCode,
+                        readOnly: true
+                    }
+                }
+
+                if (item.InputMode == "D1") {
+                    return {
+                        data: "Infos." + item.InfoPointCode,
+                        renderer: tools.customDropdownRenderer,
+                        editor: "chosen",
+                        chosenOptions: {
+                            // multiple: true,//多选
+                            data: item.DataSource || ""
+                        }
+                    };
+                } else if (item.InputMode == "A1" || item.InputMode == "A2") {
+                    return {
+                        data: "Infos." + item.InfoPointCode,
+                        type: "numeric",
+                        numericFormat: {
+                            pattern: "0,0.00"
+                                // culture: 'de-DE' // use this for EUR (German),
+                                // more cultures available on http://numbrojs.com/languages.html
+                        }
+                    };
+                } else if (item.InputMode == "C5") {
+                    return {
+                        data: "Infos." + item.InfoPointCode,
+                        type: "date",
+                        dateFormat: "YYYY-MM-DD",
+                        correctFormat: true
+                    };
+                } else if (
+                    item.InputMode == "B1" ||
+                    item.InputMode == "L" ||
+                    item.InputMode == "L1" ||
+                    item.InputMode == "L2"
+                ) {
+                    return {
+                        data: "Infos." + item.InfoPointCode
+                    };
+                } else if (
+                    item.InputMode == "X"
+                    // item.InputMode == "L1" ||
+                    // item.InputMode == "L2"
+                ) {
+                    //   return undefined
+                    return {
+                        data: "Infos." + item.InfoPointCode,
+                        readOnly: true
+                    };
+                } else if (item.InputMode == "D2") {
+                    return {
+                        data: "Infos." + item.InfoPointCode,
+                        renderer: tools.customDropdownRenderer,
+                        editor: "chosen",
+                        chosenOptions: {
+                            multiple: true, //多选
+                            data: item.DataSource || ""
+                        }
+                    };
+                } else if (item.InputMode == "Own" && !onlyRead) {
+                    return {
+                        data: "Infos." + item.InfoPointCode,
+                        renderer: text.idType,
+                    }
+                } else {
+                    return undefined;
+                }
+            } else {
+                return undefined
+            }
+
+        }).filter(item => item);
+        return data
+    },
+
+    showTypes(arr, onlyRead, isWatch, allMess, falg = false, typeArr = false) {
+        let data = arr.map(item => {
+            if (falg) {
+                if (item.FirstTag == "控制参数" ||
+                    item.FirstTag == "设定参数" ||
+                    item.FirstTag == "运行参数") {
+                    return undefined
+                }
+            }
+            if (item.InfoPointCode == "BIMLocation") {
+                return undefined
+            }
+            if (!!typeArr && typeArr.indexOf(item.InputMode) > -1) {
+                return undefined
+            }
+            if (item.Visible || !allMess) {
+                //固定不显示的code
+                if (!showTools.cantShow(item.InfoPointCode) && !onlyRead) {
+                    return undefined
+                }
+
+                if (!showTools.isShow(item.InfoPointCode)) {
+                    if (isWatch && !onlyRead) {
+                        return undefined
+                    }
+                }
+
+                if (item.InfoPointCode == "EquipQRCode") {
+                    return {
+                        data: "infos." + item.InfoPointCode,
+                        renderer: text.lookQRCode,
+                        readOnly: true
+                    }
+                }
+
+                //图片类型
+                if (
+                    item.InfoPointCode == "InstallPic" ||
+                    item.InfoPointCode == "InstallDrawing" ||
+                    item.InfoPointCode == "Nameplate" ||
+                    item.InfoPointCode == "Pic" ||
+                    item.InfoPointCode == "Drawing"
+                ) {
+                    return {
+                        data: "infos." + item.InfoPointCode,
+                        renderer: text.picType,
+                        readOnly: true
+                    }
+                }
+
+                //文件类型
+                if (item.InfoPointCode == "InsuranceFile" ||
+                    item.InfoPointCode == "Archive" ||
+                    item.InfoPointCode == "CheckReport") {
+                    return {
+                        data: "infos." + item.InfoPointCode,
+                        renderer: text.fileType,
+                        readOnly: true
+                    }
+                }
+
+                if (item.InputMode == "D1") {
+                    return {
+                        data: "infos." + item.InfoPointCode,
+                        renderer: tools.customDropdownRenderer,
+                        editor: "chosen",
+                        chosenOptions: {
+                            // multiple: true,//多选
+                            data: item.DataSource || ""
+                        }
+                    };
+                } else if (item.InputMode == "A1" || item.InputMode == "A2") {
+                    return {
+                        data: "infos." + item.InfoPointCode,
+                        type: "numeric",
+                        numericFormat: {
+                            pattern: "0,0.00"
+                                // culture: 'de-DE' // use this for EUR (German),
+                                // more cultures available on http://numbrojs.com/languages.html
+                        }
+                    };
+                } else if (item.InputMode == "C5") {
+                    return {
+                        data: "infos." + item.InfoPointCode,
+                        type: "date",
+                        dateFormat: "YYYY-MM-DD",
+                        correctFormat: true
+                    };
+                } else if (
+                    item.InputMode == "B1" ||
+                    item.InputMode == "L" ||
+                    item.InputMode == "L1" ||
+                    item.InputMode == "L2"
+                ) {
+                    return {
+                        data: "infos." + item.InfoPointCode
+                    };
+                } else if (
+                    item.InputMode == "X" ||
+                    item.InputMode == "F2"
+                    // item.InputMode == "L1" ||
+                    // item.InputMode == "L2"
+                ) {
+                    //   return undefined
+                    return {
+                        data: "infos." + item.InfoPointCode,
+                        readOnly: true
+                    };
+                } else if (item.InputMode == "D2") {
+                    return {
+                        data: "infos." + item.InfoPointCode,
+                        renderer: tools.customDropdownRenderer,
+                        editor: "chosen",
+                        chosenOptions: {
+                            multiple: true, //多选
+                            data: item.DataSource || ""
+                        }
+                    };
+                } else if (item.InputMode == "Own" && !onlyRead) {
+                    return {
+                        data: "infos." + item.InfoPointCode,
+                        renderer: text.idType,
+                    }
+                } else {
+                    return undefined;
+                }
+            } else {
+                return undefined
+            }
+
+        }).filter(item => item);
+        return data
+    },
+
+    changeHeader(arr, readArr, onlyRead, isWatch, allMess, falg = false, taizhang = false) {
+        let data = arr.map(item => {
+            if (falg) {
+                if (item.FirstTag == "控制参数" ||
+                    item.FirstTag == "设定参数" ||
+                    item.FirstTag == "运行参数") {
+                    return undefined
+                }
+            }
+
+            if (item.InfoPointCode == "BIMLocation") {
+                return undefined
+            }
+            if (
+                readArr.indexOf(item.InputMode) > -1
+            ) {
+                if (item.Visible || !allMess) {
+                    if (!showTools.cantShow(item.InfoPointCode) && !onlyRead && !taizhang) {
+                        return undefined
+                    }
+
+                    if (!showTools.isShow(item.InfoPointCode) && !taizhang) {
+                        if (isWatch && !onlyRead) {
+                            return undefined
+                        }
+                    }
+                    if (item.Unit == "") {
+                        return item.InfoPointName;
+                    } else {
+                        return item.InfoPointName + "(" + item.Unit + ")";
+                    }
+                } else {
+                    return undefined
+                }
+            } else {
+                return undefined;
+            }
+        }).filter(d => d);
+        return data
+    }
+}
+
+export default showTools

+ 1 - 1
src/utils/scan/tools.js

@@ -1,8 +1,8 @@
+import Handsontable from "handsontable-pro"
 const tools = {}
 const tools = {}
 
 
 let arrX = []
 let arrX = []
 let arrY = []
 let arrY = []
-
 tools.getPointDetails = (arr) => {
 tools.getPointDetails = (arr) => {
         arr.map(item => {
         arr.map(item => {
             if (item.PointList && item.PointList.length) {
             if (item.PointList && item.PointList.length) {

+ 22 - 19
src/views/business_space/admin/index.vue

@@ -5,10 +5,10 @@
     <div id="businessSpace">
     <div id="businessSpace">
         <!------------------------    头部弹窗,选择楼层信息     -------------->
         <!------------------------    头部弹窗,选择楼层信息     -------------->
         <no-model-dialog :param="param" title="选择要进行空间管理的楼层" :isShow="floor" @close="close"></no-model-dialog>
         <no-model-dialog :param="param" title="选择要进行空间管理的楼层" :isShow="floor" @close="close"></no-model-dialog>
-        <!-- <influence-dialog ref="influence" :param="param" :tabsList="tabsList" title="受元空间变化影响的业务空间" :isShow="floor"></influence-dialog> -->
-        <!-- <details-dialog ref="details" @del="delSuccess" :param="param" :tabsList="tabsList" title="业务空间详情" :isShow="floor" :activeTabType="activeTabType"></details-dialog> -->
-        <!-- <not-related ref="notRelated" @createSuccess="createSuccess" :isShow="floor"></not-related> -->
-        <!-- <facility-dialog ref="facility" :activeTabType="activeTabType" :isShow="floor"></facility-dialog> -->
+        <influence-dialog ref="influence" :param="param" :tabsList="tabsList" title="受元空间变化影响的业务空间" :isShow="floor"></influence-dialog>
+        <details-dialog ref="details" @del="delSuccess" :param="param" :tabsList="tabsList" title="业务空间详情" :isShow="floor" :activeTabType="activeTabType"></details-dialog>
+        <not-related ref="notRelated" @createSuccess="createSuccess" :isShow="floor"></not-related>
+        <facility-dialog ref="facility" :activeTabType="activeTabType" :isShow="floor"></facility-dialog>
         <!--------- 页面头部   -------------->
         <!--------- 页面头部   -------------->
         <div class="saga-title">
         <div class="saga-title">
             <div class="saga-build-mess">
             <div class="saga-build-mess">
@@ -33,13 +33,13 @@
                 <template v-for="(item,index) in tabsList">
                 <template v-for="(item,index) in tabsList">
               <el-tab-pane :name="item.code" :key="index" :disabled="item.code > 3">
               <el-tab-pane :name="item.code" :key="index" :disabled="item.code > 3">
                 <span slot="label">{{item.name}}</span>
                 <span slot="label">{{item.name}}</span>
-                <!-- <graphy
+                <graphy
                   @getSp="checkSpace"
                   @getSp="checkSpace"
                   @dimension="checkSpace"
                   @dimension="checkSpace"
                   @businessDetails="getBuinessDetails"
                   @businessDetails="getBuinessDetails"
                   :ref="'graphy' + item.code"
                   :ref="'graphy' + item.code"
                   :canvasId="item.code"
                   :canvasId="item.code"
-                ></graphy> -->
+                ></graphy>
               </el-tab-pane>
               </el-tab-pane>
             </template>
             </template>
                 </el-tabs>
                 </el-tabs>
@@ -50,7 +50,7 @@
             <template v-for="(item,index) in tabsList">
             <template v-for="(item,index) in tabsList">
                 <el-tab-pane :name="item.code" :key="index" :disabled="item.code > 3">
                 <el-tab-pane :name="item.code" :key="index" :disabled="item.code > 3">
                     <span slot="label">{{item.name}}</span>
                     <span slot="label">{{item.name}}</span>
-                    <!-- <handsontable-main @lookEqu="lookEqu" :ref="'handsontable' + item.code" :id="'handsontable' + item.code" :param="param"></handsontable-main> -->
+                    <handsontable-main @lookEqu="lookEqu" :ref="'handsontable' + item.code" :id="'handsontable' + item.code" :param="param"></handsontable-main>
                 </el-tab-pane>
                 </el-tab-pane>
             </template>
             </template>
       </el-tabs>
       </el-tabs>
@@ -61,13 +61,13 @@
 
 
 <script>
 <script>
     import noModelDialog from "@/components/business_space/dialogs/noModelDialog";
     import noModelDialog from "@/components/business_space/dialogs/noModelDialog";
-    // import influenceDialog from "@/components/business_space/dialogs/influenceDialog";
-    // import detailsDialog from "@/components/business_space/dialogs/detailsDialog";
-    // import notRelated from "@/components/business_space/dialogs/notRelated";
-    // import facilityDialog from "@/components/business_space/dialogs/facilityDialog";
+    import influenceDialog from "@/components/business_space/dialogs/influenceDialog";
+    import detailsDialog from "@/components/business_space/dialogs/detailsDialog";
+    import notRelated from "@/components/business_space/dialogs/notRelated";
+    import facilityDialog from "@/components/business_space/dialogs/facilityDialog";
     // import spaceHandsontable from "@/components/business_space/business/spaceHandsontable";
     // import spaceHandsontable from "@/components/business_space/business/spaceHandsontable";
-    // import graphy from "@/components/business_space/graphy/business";
-    // import handsontableMain from "@/components/business_space/business/handsontable";
+    import graphy from "@/components/business_space/graphy/business";
+    import handsontableMain from "@/components/business_space/business/handsontable";
     import {
     import {
         getTableHeader,
         getTableHeader,
         getAllbusiness,
         getAllbusiness,
@@ -81,12 +81,12 @@
         components: {
         components: {
             noModelDialog,
             noModelDialog,
             // spaceHandsontable,
             // spaceHandsontable,
-            // influenceDialog,
-            // detailsDialog,
-            // notRelated,
-            // graphy,
-            // handsontableMain,
-            // facilityDialog
+            influenceDialog,
+            detailsDialog,
+            notRelated,
+            graphy,
+            handsontableMain,
+            facilityDialog
         },
         },
         computed: {
         computed: {
             ...mapGetters("peojMess", [
             ...mapGetters("peojMess", [
@@ -128,6 +128,9 @@
             };
             };
         },
         },
         created() {
         created() {
+            this.param.ProjId = this.projectId
+            this.param.UserId = this.userId
+            this.param.secret = this.secret
             this.getTypes()
             this.getTypes()
         },
         },
         mounted() {},
         mounted() {},

File diff suppressed because it is too large
+ 892 - 935
src/views/data_admin/buildAssets/index.vue