From d4a3ca549f8755c2f87442c27217c3be39cab5cc Mon Sep 17 00:00:00 2001
From: suerprisePlus <15810472099@163.com>
Date: 星期三, 14 八月 2024 16:00:10 +0800
Subject: [PATCH] 设备维修

---
 src/assets/images/Screen/bottombg.png                            |    0 
 src/views/dataManager/semanticFunction/contentList.vue           |   10 
 src/assets/images/Screen/all.png                                 |    0 
 src/views/dataManager/equipMante/AddOrUpdate.vue                 |  166 ++++
 src/assets/images/Screen/btnbg.png                               |    0 
 src/views/visualization/lineLoss.vue                             |   37 
 src/views/dataManager/equipMante/index.vue                       |  168 ++++
 src/components/RuoYi/Msgger/index.vue                            |   41 +
 src/assets/images/Screen/prjectree.png                           |    0 
 src/api/mapView/map.js                                           |    7 
 src/assets/images/Screen/bdimg.png                               |    0 
 src/store/modules/mapLayers.js                                   |   13 
 src/views/visual/mapView/mapInfo.vue                             |   74 +
 src/assets/images/Screen/fileTypeBar.png                         |    0 
 src/permission.js                                                |    2 
 src/assets/images/Screen/ptree.png                               |    0 
 src/assets/js/mapSdk/mapData.js                                  |   22 
 src/views/visual/mapView/dataStatistics.vue                      |  120 --
 src/assets/images/Screen/bigST.png                               |    0 
 src/assets/images/Screen/geovisearth-ter.png                     |    0 
 src/assets/images/Screen/centerTooltip.png                       |    0 
 src/router/index.js                                              |  335 ++++----
 src/assets/images/Screen/leftArrow.png                           |    0 
 src/utils/mapServer/pyServer.js                                  |    8 
 src/assets/images/Screen/centerTooltipBg.png                     |    0 
 src/views/visual/mapView/index.vue                               |   34 
 src/views/visualization/leftMenu.vue                             |   60 +
 src/assets/images/Screen/rightBar.png                            |    0 
 src/assets/images/Screen/centerbtn.png                           |    0 
 src/views/visualization/bottomMenu.vue                           |  171 ++++
 src/assets/images/Screen/numBg.png                               |    0 
 src/assets/images/Screen/yximg.png                               |    0 
 src/views/visualization/rightMenu.vue                            |  248 ++++++
 src/assets/images/Screen/projectBg.png                           |    0 
 src/layout/components/Navbar.vue                                 |   36 
 src/assets/js/mapSdk/index.js                                    |    8 
 src/assets/images/Screen/logobg.png                              |    0 
 src/assets/images/Screen/rightArrow.png                          |    0 
 src/views/redirect.vue                                           |    2 
 src/views/dataManager/semanticFunction/child/agentInsertFile.vue |   67 +
 public/config/config.js                                          |    6 
 src/api/mapView/peiwang.js                                       |   12 
 src/views/visualization/mapView.vue                              |  112 ++
 src/assets/images/Screen/contentBg.png                           |    0 
 src/assets/images/Screen/asideTitleBg.png                        |    0 
 src/views/visual/mapView/lineRoaming.vue                         |    7 
 src/views/visual/statistics/index.vue                            |  146 +++
 src/assets/images/Screen/leftBar.png                             |    0 
 src/views/visual/atlas/index.vue                                 |   13 
 src/assets/images/Screen/cunchu.png                              |    0 
 src/assets/js/mapSdk/mapServe.js                                 |   83 +
 src/assets/images/Screen/chartbg.png                             |    0 
 src/assets/images/Screen/btnc.png                                |    0 
 src/assets/images/Screen/centerbtnc.png                          |    0 
 src/assets/images/Screen/return.png                              |    0 
 src/assets/js/mapSdk/menuManager.js                              |  124 ++
 src/views/visualization/index.vue                                |  164 ++++
 src/views/dataManager/semanticFunction/enterBox.vue              |    2 
 58 files changed, 1,942 insertions(+), 356 deletions(-)

diff --git a/public/config/config.js b/public/config/config.js
index 433690e..be1270a 100644
--- a/public/config/config.js
+++ b/public/config/config.js
@@ -49,4 +49,10 @@
   domTilesets: {
     url: pwythHost + "/qingxie/tileset.json"
   },
+  baseModel:{
+    serveType: 'Tileset',
+    url: pwythHost + "/modles/TY/tileset.json",
+    cnName:"baseModel",
+    id:"baseModel",
+ },
 };
diff --git a/src/api/mapView/map.js b/src/api/mapView/map.js
index e45f995..acbdd5e 100644
--- a/src/api/mapView/map.js
+++ b/src/api/mapView/map.js
@@ -1,6 +1,6 @@
 import mapServer from '@/utils/mapServer/mapServer';
 import kgServer from '@/utils/mapServer/kgServer';
-
+import pyServer from '@/utils/mapServer/pyServer';
 //閰嶇綉鎺ュ彛 => 鏌ヨ鎵�鏈�
 export function zhangzitou_selectAllLine(params) {
     return mapServer.get('/zhangzitou/selectAllLine', { params: params });
@@ -57,4 +57,7 @@
 export function zhangzitou_updateZhangzitouEntity(params) {
     return mapServer.post('/zhangzitou/updateZhangzitouEntity', params);
 }
- 
\ No newline at end of file
+//鏈哄櫒瀛︿範 => 鏁板瓧绾挎崯
+export function py_arima(params) {
+    return pyServer.get('/arima', { params: params });
+} 
\ No newline at end of file
diff --git a/src/api/mapView/peiwang.js b/src/api/mapView/peiwang.js
index ce3f6f9..839a25a 100644
--- a/src/api/mapView/peiwang.js
+++ b/src/api/mapView/peiwang.js
@@ -248,3 +248,15 @@
     //璇锋眰鍦板潃
     return peiWangServer.post('/peiwang/tokeninfo/update', params);
 }
+export function faultreport_list(params) {
+    //璇锋眰鍦板潃
+    return peiWangServer.get('/peiwang/faultreport/list', { params: params });
+}
+export function faultreport_save(params) {
+    //璇锋眰鍦板潃
+    return peiWangServer.post('/peiwang/faultreport/save', params);
+}
+export function faultreport_update(params) {
+    //璇锋眰鍦板潃
+    return peiWangServer.post('/peiwang/faultreport/update', params);
+}
diff --git a/src/assets/images/Screen/all.png b/src/assets/images/Screen/all.png
new file mode 100644
index 0000000..f3e0278
--- /dev/null
+++ b/src/assets/images/Screen/all.png
Binary files differ
diff --git a/src/assets/images/Screen/asideTitleBg.png b/src/assets/images/Screen/asideTitleBg.png
new file mode 100644
index 0000000..b86f3ab
--- /dev/null
+++ b/src/assets/images/Screen/asideTitleBg.png
Binary files differ
diff --git a/src/assets/images/Screen/bdimg.png b/src/assets/images/Screen/bdimg.png
new file mode 100644
index 0000000..102e157
--- /dev/null
+++ b/src/assets/images/Screen/bdimg.png
Binary files differ
diff --git a/src/assets/images/Screen/bigST.png b/src/assets/images/Screen/bigST.png
new file mode 100644
index 0000000..f45d62e
--- /dev/null
+++ b/src/assets/images/Screen/bigST.png
Binary files differ
diff --git a/src/assets/images/Screen/bottombg.png b/src/assets/images/Screen/bottombg.png
new file mode 100644
index 0000000..536cbd3
--- /dev/null
+++ b/src/assets/images/Screen/bottombg.png
Binary files differ
diff --git a/src/assets/images/Screen/btnbg.png b/src/assets/images/Screen/btnbg.png
new file mode 100644
index 0000000..678c750
--- /dev/null
+++ b/src/assets/images/Screen/btnbg.png
Binary files differ
diff --git a/src/assets/images/Screen/btnc.png b/src/assets/images/Screen/btnc.png
new file mode 100644
index 0000000..a909dfb
--- /dev/null
+++ b/src/assets/images/Screen/btnc.png
Binary files differ
diff --git a/src/assets/images/Screen/centerTooltip.png b/src/assets/images/Screen/centerTooltip.png
new file mode 100644
index 0000000..eb6ea22
--- /dev/null
+++ b/src/assets/images/Screen/centerTooltip.png
Binary files differ
diff --git a/src/assets/images/Screen/centerTooltipBg.png b/src/assets/images/Screen/centerTooltipBg.png
new file mode 100644
index 0000000..0e85223
--- /dev/null
+++ b/src/assets/images/Screen/centerTooltipBg.png
Binary files differ
diff --git a/src/assets/images/Screen/centerbtn.png b/src/assets/images/Screen/centerbtn.png
new file mode 100644
index 0000000..de48173
--- /dev/null
+++ b/src/assets/images/Screen/centerbtn.png
Binary files differ
diff --git a/src/assets/images/Screen/centerbtnc.png b/src/assets/images/Screen/centerbtnc.png
new file mode 100644
index 0000000..c2de00e
--- /dev/null
+++ b/src/assets/images/Screen/centerbtnc.png
Binary files differ
diff --git a/src/assets/images/Screen/chartbg.png b/src/assets/images/Screen/chartbg.png
new file mode 100644
index 0000000..30ac482
--- /dev/null
+++ b/src/assets/images/Screen/chartbg.png
Binary files differ
diff --git a/src/assets/images/Screen/contentBg.png b/src/assets/images/Screen/contentBg.png
new file mode 100644
index 0000000..58b4f8e
--- /dev/null
+++ b/src/assets/images/Screen/contentBg.png
Binary files differ
diff --git a/src/assets/images/Screen/cunchu.png b/src/assets/images/Screen/cunchu.png
new file mode 100644
index 0000000..376f3dd
--- /dev/null
+++ b/src/assets/images/Screen/cunchu.png
Binary files differ
diff --git a/src/assets/images/Screen/fileTypeBar.png b/src/assets/images/Screen/fileTypeBar.png
new file mode 100644
index 0000000..2070eb3
--- /dev/null
+++ b/src/assets/images/Screen/fileTypeBar.png
Binary files differ
diff --git a/src/assets/images/Screen/geovisearth-ter.png b/src/assets/images/Screen/geovisearth-ter.png
new file mode 100644
index 0000000..c894171
--- /dev/null
+++ b/src/assets/images/Screen/geovisearth-ter.png
Binary files differ
diff --git a/src/assets/images/Screen/leftArrow.png b/src/assets/images/Screen/leftArrow.png
new file mode 100644
index 0000000..45ce6d3
--- /dev/null
+++ b/src/assets/images/Screen/leftArrow.png
Binary files differ
diff --git a/src/assets/images/Screen/leftBar.png b/src/assets/images/Screen/leftBar.png
new file mode 100644
index 0000000..e2dde16
--- /dev/null
+++ b/src/assets/images/Screen/leftBar.png
Binary files differ
diff --git a/src/assets/images/Screen/logobg.png b/src/assets/images/Screen/logobg.png
new file mode 100644
index 0000000..7835da6
--- /dev/null
+++ b/src/assets/images/Screen/logobg.png
Binary files differ
diff --git a/src/assets/images/Screen/numBg.png b/src/assets/images/Screen/numBg.png
new file mode 100644
index 0000000..2b25fc5
--- /dev/null
+++ b/src/assets/images/Screen/numBg.png
Binary files differ
diff --git a/src/assets/images/Screen/prjectree.png b/src/assets/images/Screen/prjectree.png
new file mode 100644
index 0000000..5104f16
--- /dev/null
+++ b/src/assets/images/Screen/prjectree.png
Binary files differ
diff --git a/src/assets/images/Screen/projectBg.png b/src/assets/images/Screen/projectBg.png
new file mode 100644
index 0000000..bb10a91
--- /dev/null
+++ b/src/assets/images/Screen/projectBg.png
Binary files differ
diff --git a/src/assets/images/Screen/ptree.png b/src/assets/images/Screen/ptree.png
new file mode 100644
index 0000000..33adaba
--- /dev/null
+++ b/src/assets/images/Screen/ptree.png
Binary files differ
diff --git a/src/assets/images/Screen/return.png b/src/assets/images/Screen/return.png
new file mode 100644
index 0000000..d10f0c5
--- /dev/null
+++ b/src/assets/images/Screen/return.png
Binary files differ
diff --git a/src/assets/images/Screen/rightArrow.png b/src/assets/images/Screen/rightArrow.png
new file mode 100644
index 0000000..30ffac5
--- /dev/null
+++ b/src/assets/images/Screen/rightArrow.png
Binary files differ
diff --git a/src/assets/images/Screen/rightBar.png b/src/assets/images/Screen/rightBar.png
new file mode 100644
index 0000000..e25ee66
--- /dev/null
+++ b/src/assets/images/Screen/rightBar.png
Binary files differ
diff --git a/src/assets/images/Screen/yximg.png b/src/assets/images/Screen/yximg.png
new file mode 100644
index 0000000..aedc47d
--- /dev/null
+++ b/src/assets/images/Screen/yximg.png
Binary files differ
diff --git a/src/assets/js/mapSdk/index.js b/src/assets/js/mapSdk/index.js
index 9ea164b..972ec0b 100644
--- a/src/assets/js/mapSdk/index.js
+++ b/src/assets/js/mapSdk/index.js
@@ -1,10 +1,9 @@
 import mapConfig from './mapConfig';
 import mapData from './mapData';
 import mapServer from './mapServe';
-
+import * as turf from '@turf/turf';
 const mapInit = {
     async Init() {
-        console.log(location)
         window.earthCtrl = new SmartEarth.EarthCtrl('sdkContainer', {
             // 闅愯棌榛樿搴曞浘
             defaultImagery: false,
@@ -39,6 +38,11 @@
             serveType: 'tdMap',
             url: baseLayer.sUrl + baseLayer.vecLayer + baseLayer.lUrl,
         });
+
+        // mapServer.addLayer({
+        //     serveType: 'WMS',
+        //     url: 'sxpw:shanxitif',
+        // });
         // 娣诲姞澶╁湴鍥炬爣娉�
         mapServer.addLayer({
             serveType: 'tdMap',
diff --git a/src/assets/js/mapSdk/mapData.js b/src/assets/js/mapSdk/mapData.js
index 71edf0e..7511bea 100644
--- a/src/assets/js/mapSdk/mapData.js
+++ b/src/assets/js/mapSdk/mapData.js
@@ -48,6 +48,21 @@
                     name: '娣规病鍒嗘瀽',
                     pid: 's3',
                 },
+                {
+                    id: 'a4',
+                    name: '闆烽洦',
+                    pid: 's3',
+                },
+                {
+                    id: 'a5',
+                    name: '瑕嗛洩',
+                    pid: 's3',
+                },
+                {
+                    id: 'a6',
+                    name: '娓呴櫎',
+                    pid: 's3',
+                },
             ],
         },
         {
@@ -190,11 +205,12 @@
         cvaLayer: 'cva_w',
         imgLayer: 'img_w',
     },
+
     // 榛樿瑙嗚
     defaultPerspective: {
-        x: -1935239.1689147458,
-        y: 4653957.816261454,
-        z: 3900586.9686804516,
+        x: -1936842.4744685106,
+        y: 4665314.067108395,
+        z: 3898603.230008434,
     },
     // 鍥惧眰绠$悊
     layerData: {
diff --git a/src/assets/js/mapSdk/mapServe.js b/src/assets/js/mapSdk/mapServe.js
index 89bd349..cefdd3b 100644
--- a/src/assets/js/mapSdk/mapServe.js
+++ b/src/assets/js/mapSdk/mapServe.js
@@ -1,6 +1,7 @@
 import mapConfig from './mapConfig';
 import { zhangzitou_selectAll } from '@/api/mapView/map.js';
 import WKT from 'terraformer-wkt-parser';
+import store from '@/store';
 // 鏈嶅姟鍔犺浇
 const mapServer = {
     serveType: null,
@@ -39,7 +40,7 @@
                 var geom = WKT.parse(item.geom).coordinates;
                 const terrain = config.terrain;
                 if (terrain.isShow && terrain.isUrl) {
-                    this.addTerrainGLB(geom);
+                    this.addTerrainGLB(item, geom, modelLayer);
                 } else {
                     this.addGLB(item, geom, modelLayer);
                 }
@@ -52,16 +53,33 @@
             });
         });
     },
-    addTerrainGLB(geom) {
+    addTerrainGLB(item, geom, modelLayer) {
         var positions = [Cesium.Cartographic.fromDegrees(geom[0], geom[1])];
         var promise = Cesium.sampleTerrainMostDetailed(Viewer.terrainProvider, positions);
-        promise.then(updatedPositions => {
-            console.log(updatedPositions);
-        })
-        // SmartEarth.Cesium.when(promise, (updatedPositions) => {
-        //     var terrainHeight = updatedPositions[0].height;
-        //     console.log(terrainHeight);
-        // });
+        promise.then((updatedPositions) => {
+            var terrainHeight = updatedPositions[0].height;
+            var style = {
+                longitude: geom[0],
+                latitude: geom[1],
+                altitude: terrainHeight,
+                heading: 0,
+                pitch: 0,
+                roll: 0,
+            };
+            const modelMatrix = mapConfig.getModelMatrix(style);
+            const url = '/glb/' + item.type + '.glb';
+            modelLayer.add(
+                Cesium.Model.fromGltf({
+                    id: item.id,
+                    url: url,
+                    scale: 1,
+                    minimumPixelSize: 20,
+                    maximumScale: 20,
+                    modelMatrix: modelMatrix,
+                    primitive: item,
+                })
+            );
+        });
     },
     addGLB(item, geom, modelLayer) {
         var style = {
@@ -154,7 +172,9 @@
         });
         const cnName = res.cnName + '_' + res.id;
         model.item.readyPromise.then((item) => {
-            mapConfig.userSceneFlyTo(item);
+            if (res.id != 'baseModel') {
+                mapConfig.userSceneFlyTo(item);
+            }
             this.layerList.push({
                 id: res.id,
                 name: cnName,
@@ -163,7 +183,6 @@
             });
         });
     },
-    setTilesetArgs() {},
     removeLayer(res) {
         const cnName = res.cnName + '_' + res.id;
         this.layerList.map((item, index) => {
@@ -181,8 +200,46 @@
             }
         });
     },
-    async getFeatureInfo(res) {
-        console.log(res);
+    async getFeatureInfo(html) {
+        var start = html.indexOf('<caption class="featureInfo">') + '<caption class="featureInfo">'.length;
+        var end = html.indexOf('</caption>');
+        var tab = html.substr(start, end - start);
+        var std = html
+            .substr(html.indexOf('<th>'), html.lastIndexOf('</th>') - html.indexOf('<th>') + 5)
+            .replaceAll(' ', '')
+            .replaceAll('\n', '')
+            .split('</th>');
+        var str = html
+            .substr(html.indexOf('<td>'), html.lastIndexOf('</td>') - html.indexOf('<td>') + 5)
+            .replaceAll(' ', '')
+            .replaceAll('\n', '')
+            .split('</td>');
+        var arr = [];
+        for (var i in std) {
+            var name, val;
+            name = std[i];
+            val = str[i];
+            if (name == '') {
+                continue;
+            }
+            if (name.indexOf('<th>') > -1) {
+                name = name.replaceAll('<th>', '');
+            }
+            if (val.indexOf('<td>') > -1) {
+                val = val.replaceAll('<td>', '');
+            }
+            if (name != '>') {
+                arr.push({
+                    name: name,
+                    val: val,
+                });
+            }
+        }
+        store.dispatch('mapLayers/changeMapInfo', []);
+        if (arr.length > 0) {
+            // this.$store.geet.mapInfo = arr;
+            store.dispatch('mapLayers/changeMapInfo', arr);
+        }
     },
 };
 export default mapServer;
diff --git a/src/assets/js/mapSdk/menuManager.js b/src/assets/js/mapSdk/menuManager.js
index 4e31acb..c993e80 100644
--- a/src/assets/js/mapSdk/menuManager.js
+++ b/src/assets/js/mapSdk/menuManager.js
@@ -1,8 +1,14 @@
+import { time } from 'echarts';
+import mapServer from './mapServe';
+
 const menuManager = {
     pid: null,
     pointFly: null,
     particle: null,
     AnalysisFlood: null,
+    modelLayer: null,
+    regionWeather: null,
+    regionWeather: null,
     colorAll: {
         point: SmartEarth.Cesium.Color.fromCssColorString('#ff0000'),
         polyline: SmartEarth.Cesium.Color.fromCssColorString('#ffff0050'),
@@ -62,6 +68,70 @@
                 break;
         }
     },
+    handlerClick(res) {
+        var that = this;
+        var handler = new Cesium.ScreenSpaceEventHandler(Viewer.scene.canvas);
+        handler.setInputAction((event) => {
+            let cartesian = Viewer.camera.pickEllipsoid(event.position);
+            let cartographic = Cesium.Cartographic.fromCartesian(cartesian);
+
+            if (cartesian) {
+                let lng = parseFloat(Cesium.Math.toDegrees(cartographic.longitude)).toFixed(6); // 缁忓害
+                let lat = parseFloat(Cesium.Math.toDegrees(cartographic.latitude)).toFixed(6); // 绾害
+                var alt = Viewer.camera.positionCartographic.height.toFixed(0);
+                if (res == 'a2') {
+                    that.setCreateFireAnalysis(lng, lat, alt);
+                } else if (res == 'a4') {
+                    that.setCreateRainAnalysis(lng, lat, alt);
+                } else if (res == 'a5') {
+                    that.setCreateSnowAnalysis(lng, lat, alt);
+                }
+            }
+            handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
+        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
+    },
+    getModelLayer() {
+        const obj = mapServer.layerList.filter((item) => {
+            if (item.id == 'baseModel') {
+                return time;
+            }
+        });
+        if (obj.length <= 0) return;
+        this.modelLayer = obj[0].layer;
+    },
+    setCreateRainAnalysis(lng, lat, alt) {
+        this.regionWeather = earthCtrl.factory.createRegionWeather({
+            primitive: this.modelLayer.item,
+            position: new SmartEarth.Cesium.Cartesian3.fromDegrees(lng, lat, 1000),
+            radius: 1000,
+        });
+        this.regionWeather.enableWeatherType = SmartEarth.Cesium.RegionWeather.TYPE_RAIN;
+        this.regionWeather.regionAlpha = 0.6;
+        this.regionWeather.regionGradientDistance = 300;
+    },
+    setCreateSnowAnalysis(lng, lat, alt) {
+        this.regionWeather = earthCtrl.factory.createRegionWeather({
+            primitive: this.modelLayer.item,
+            position: new SmartEarth.Cesium.Cartesian3.fromDegrees(lng, lat, 1000),
+            radius: 1000,
+        });
+        this.regionWeather.enableWeatherType = SmartEarth.Cesium.RegionWeather.TYPE_SNOW;
+        this.regionWeather.regionAlpha = 0.8;
+        this.regionWeather.regionGradientDistance = 300;
+    },
+    setClearMenuS3() {
+        if (this.particle) {
+            this.particle.remove();
+            this.particle = null;
+        }
+        if (this.AnalysisFlood) {
+            this.AnalysisFlood.endWater();
+            this.AnalysisFlood = undefined;
+        }
+        if (this.regionWeather) {
+            this.regionWeather.enableWeatherType = SmartEarth.Cesium.RegionWeather.TYPE_NONE;
+        }
+    },
     // 鐏惧绠$悊
     setMenuS3(res) {
         switch (res.id) {
@@ -74,27 +144,14 @@
                     this.particle = null;
                     return;
                 }
+                this.handlerClick(res.id);
 
-                var that = this;
-                var handler = new Cesium.ScreenSpaceEventHandler(Viewer.scene.canvas);
-                handler.setInputAction((event) => {
-                    let cartesian = Viewer.camera.pickEllipsoid(event.position);
-                    let cartographic = Cesium.Cartographic.fromCartesian(cartesian);
-
-                    if (cartesian) {
-                        let lng = parseFloat(Cesium.Math.toDegrees(cartographic.longitude)).toFixed(6); // 缁忓害
-                        let lat = parseFloat(Cesium.Math.toDegrees(cartographic.latitude)).toFixed(6); // 绾害
-                        var alt = Viewer.camera.positionCartographic.height.toFixed(0);
-                        that.setCreateFireAnalysis(lng, lat, alt);
-                    }
-                    handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
-                }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
                 break;
             case 'a3':
                 if (this.AnalysisFlood) {
                     this.AnalysisFlood.endWater();
                     this.AnalysisFlood = undefined;
-                    return
+                    return;
                 }
                 var url = SmartEarthRootUrl + 'Workers/image/33.gif';
                 const method = {
@@ -104,6 +161,22 @@
                     url: url,
                 };
                 this.AnalysisFlood = earthCtrl.analysis.createSubmergence(method, (value) => {});
+                break;
+            case 'a4':
+                if (!this.modelLayer) {
+                    this.getModelLayer();
+                }
+                this.handlerClick(res.id);
+                break;
+
+            case 'a5':
+                if (!this.modelLayer) {
+                    this.getModelLayer();
+                }
+                this.handlerClick(res.id);
+                break;
+            case 'a6':
+                this.setClearMenuS3();
                 break;
             default:
                 return null;
@@ -189,7 +262,26 @@
                 earthCtrl.factory.createSimpleGraphic('label', {}, (entity) => {});
                 break;
             case 'a3':
-                earthCtrl.factory.createSimpleGraphic('polyline', { showSize: false }, (entity) => {});
+                earthCtrl.factory.createSimpleGraphic('polyline', { showSize: false }, (entity) => {
+                   
+                    // console.log(entity);
+
+                    // const obj = entity.polyline.positions.getValue();
+                    // var std = [];
+                    // for (var i in obj) {
+                    //     var ellipsoid =Viewer.scene.globe.ellipsoid;
+
+                    //     // 灏嗕笘鐣屽潗鏍囪浆鎹负鍦扮悊鍧愭爣锛圕artographic锛�
+                    //     var cartographic = ellipsoid.cartesianToCartographic(obj[i]);
+
+                    //     // 鑾峰彇缁忕含搴�
+                    //     var longitude = Cesium.Math.toDegrees(cartographic.longitude);
+                    //     var latitude = Cesium.Math.toDegrees(cartographic.latitude);
+                    //     var height = 0;
+                    //     std.push([longitude, latitude, height]);
+                    // }
+                    // console.log(std);
+                });
                 break;
             case 'a4':
                 earthCtrl.factory.createSimpleGraphic('rectangle', { showSize: false }, (entity) => {});
diff --git a/src/components/RuoYi/Msgger/index.vue b/src/components/RuoYi/Msgger/index.vue
new file mode 100644
index 0000000..3fd0286
--- /dev/null
+++ b/src/components/RuoYi/Msgger/index.vue
@@ -0,0 +1,41 @@
+<template>
+    <div class="msgBox" @click="setShowMenuClick">
+
+        <i style="font-size: 20px;" class="el-icon-chat-line-round"></i>
+        <el-badge v-show="msgCount > 0" :value="msgCount" class="item">
+        </el-badge>
+
+    </div>
+</template>
+
+<script>
+export default {
+    name: 'RouYiMsg',
+    data() {
+        return {
+            msgCount: 0,
+            dialogVisible: false
+        }
+    },
+    methods: {
+        setShowMenuClick() {
+            this.dialogVisible = true
+        },
+        handleClose() {
+            this.dialogVisible = false
+        }
+    },
+    mounted() {
+        console.log(123);
+
+    },
+}
+</script>
+
+<style lang="scss" scoped>
+.msgBox {
+    display: flex;
+
+
+}
+</style>
\ No newline at end of file
diff --git a/src/layout/components/Navbar.vue b/src/layout/components/Navbar.vue
index f79de97..ac5a934 100644
--- a/src/layout/components/Navbar.vue
+++ b/src/layout/components/Navbar.vue
@@ -1,27 +1,29 @@
 <template>
   <div class="navbar">
-    <hamburger id="hamburger-container" :is-active="sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar" />
+    <hamburger id="hamburger-container" :is-active="sidebar.opened" class="hamburger-container"
+      @toggleClick="toggleSideBar" />
 
-    <breadcrumb id="breadcrumb-container" class="breadcrumb-container" v-if="!topNav"/>
-    <top-nav id="topmenu-container" class="topmenu-container" v-if="topNav"/>
+    <breadcrumb id="breadcrumb-container" class="breadcrumb-container" v-if="!topNav" />
+    <top-nav id="topmenu-container" class="topmenu-container" v-if="topNav" />
 
     <div class="right-menu">
-      <template v-if="device!=='mobile'">
+      <template v-if="device !== 'mobile'">
         <!-- <search id="header-search" class="right-menu-item" /> -->
-        
-        <!-- <el-tooltip content="婧愮爜鍦板潃" effect="dark" placement="bottom">
-          <ruo-yi-git id="ruoyi-git" class="right-menu-item hover-effect" />
-        </el-tooltip> -->
 
-        <el-tooltip content="鏂囨。鍦板潃" effect="dark" placement="bottom">
-          <ruo-yi-doc id="ruoyi-doc" class="right-menu-item hover-effect" />
+        <el-tooltip content="搴旀�ヤ俊鎭�" effect="dark" placement="bottom">
+          <!-- <ruo-yi-git id="ruoyi-git" class="right-menu-item hover-effect" /> -->
+          <ruo-yi-msg id="ruoyi-msg" class="right-menu-item  hover-effect" ></ruo-yi-msg>
         </el-tooltip>
+       
+        <!-- <el-tooltip content="鏂囨。鍦板潃" effect="dark" placement="bottom">
+          <ruo-yi-doc id="ruoyi-doc" class="right-menu-item hover-effect" />
+        </el-tooltip> -->
 
         <screenfull id="screenfull" class="right-menu-item hover-effect" />
 
-        <el-tooltip content="甯冨眬澶у皬" effect="dark" placement="bottom">
+        <!-- <el-tooltip content="甯冨眬澶у皬" effect="dark" placement="bottom">
           <size-select id="size-select" class="right-menu-item hover-effect" />
-        </el-tooltip>
+        </el-tooltip> -->
 
       </template>
 
@@ -56,6 +58,7 @@
 import Search from '@/components/HeaderSearch'
 import RuoYiGit from '@/components/RuoYi/Git'
 import RuoYiDoc from '@/components/RuoYi/Doc'
+import RuoYiMsg from '@/components/RuoYi/Msgger'
 
 export default {
   components: {
@@ -66,7 +69,8 @@
     SizeSelect,
     Search,
     RuoYiGit,
-    RuoYiDoc
+    RuoYiDoc,
+    RuoYiMsg
   },
   computed: {
     ...mapGetters([
@@ -104,7 +108,7 @@
         this.$store.dispatch('LogOut').then(() => {
           location.href = '/index';
         })
-      }).catch(() => {});
+      }).catch(() => { });
     }
   }
 }
@@ -116,7 +120,7 @@
   overflow: hidden;
   position: relative;
   background: #fff;
-  box-shadow: 0 1px 4px rgba(0,21,41,.08);
+  box-shadow: 0 1px 4px rgba(0, 21, 41, .08);
 
   .hamburger-container {
     line-height: 46px;
@@ -124,7 +128,7 @@
     float: left;
     cursor: pointer;
     transition: background .3s;
-    -webkit-tap-highlight-color:transparent;
+    -webkit-tap-highlight-color: transparent;
 
     &:hover {
       background: rgba(0, 0, 0, .025)
diff --git a/src/permission.js b/src/permission.js
index 6bb0a1f..bdcd8c8 100644
--- a/src/permission.js
+++ b/src/permission.js
@@ -8,7 +8,7 @@
 
 NProgress.configure({ showSpinner: false })
 
-const whiteList = ['/login', '/auth-redirect', '/bind', '/register']
+const whiteList = ['/login', '/auth-redirect','/visualization', '/bind', '/register']
 
 router.beforeEach((to, from, next) => {
   NProgress.start()
diff --git a/src/router/index.js b/src/router/index.js
index 2e20e27..634b04e 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -1,10 +1,10 @@
-import Vue from 'vue'
-import Router from 'vue-router'
+import Vue from 'vue';
+import Router from 'vue-router';
 
-Vue.use(Router)
+Vue.use(Router);
 
 /* Layout */
-import Layout from '@/layout'
+import Layout from '@/layout';
 
 /**
  * Note: 璺敱閰嶇疆椤�
@@ -30,174 +30,179 @@
 
 // 鍏叡璺敱
 export const constantRoutes = [
-  {
-    path: '/redirect',
-    component: Layout,
-    hidden: true,
-    children: [
-      {
-        path: '/redirect/:path(.*)',
-        component: () => import('@/views/redirect')
-      }
-    ]
-  },
     {
-    path: '/bigScreen',
-    component: () => import('@/views/bigScreen/home'),
-    hidden: true,
-    meta: { bigScreen: true }
-  },
-  {
-    path: '/login',
-    component: () => import('@/views/login'),
-    hidden: true
-  },
-  {
-    path: '/register',
-    component: () => import('@/views/register'),
-    hidden: true
-  },
-  {
-    path: '/404',
-    component: () => import('@/views/error/404'),
-    hidden: true
-  },
-  {
-    path: '/401',
-    component: () => import('@/views/error/401'),
-    hidden: true
-  },
-  {
-    path: '',
-    component: Layout,
-    redirect: 'index',
-    children: [
-      {
-        path: 'index',
-        component: () => import('@/views/index'),
-        name: 'Index',
-        meta: { title: '棣栭〉', icon: 'dashboard', affix: true }
-      }
-    ]
-  },
-  {
-    path: '/user',
-    component: Layout,
-    hidden: true,
-    redirect: 'noredirect',
-    children: [
-      {
-        path: 'profile',
-        component: () => import('@/views/system/user/profile/index'),
-        name: 'Profile',
-        meta: { title: '涓汉涓績', icon: 'user' }
-      }
-    ]
-  }
-]
+        path: '/redirect',
+        component: Layout,
+        hidden: true,
+        children: [
+            {
+                path: '/redirect/:path(.*)',
+                component: () => import('@/views/redirect'),
+            },
+        ],
+    },
+    {
+        path: '/bigScreen',
+        component: () => import('@/views/bigScreen/home'),
+        hidden: true,
+        meta: { bigScreen: true },
+    },
+    {
+        path: '/login',
+        component: () => import('@/views/login'),
+        hidden: true,
+    },
+    {
+        path: '/register',
+        component: () => import('@/views/register'),
+        hidden: true,
+    },
+    {
+        path: '/404',
+        component: () => import('@/views/error/404'),
+        hidden: true,
+    },
+    {
+        path: '/visualization',
+        component: () => import('@/views/visualization/index.vue'),
+        hidden: true,
+    },
+    {
+        path: '/401',
+        component: () => import('@/views/error/401'),
+        hidden: true,
+    },
+    {
+        path: '',
+        component: Layout,
+        redirect: 'index',
+        children: [
+            {
+                path: 'index',
+                component: () => import('@/views/index'),
+                name: 'Index',
+                meta: { title: '棣栭〉', icon: 'dashboard', affix: true },
+            },
+        ],
+    },
+    {
+        path: '/user',
+        component: Layout,
+        hidden: true,
+        redirect: 'noredirect',
+        children: [
+            {
+                path: 'profile',
+                component: () => import('@/views/system/user/profile/index'),
+                name: 'Profile',
+                meta: { title: '涓汉涓績', icon: 'user' },
+            },
+        ],
+    },
+];
 
 // 鍔ㄦ�佽矾鐢憋紝鍩轰簬鐢ㄦ埛鏉冮檺鍔ㄦ�佸幓鍔犺浇
 export const dynamicRoutes = [
-  {
-    path: '/system/user-auth',
-    component: Layout,
-    hidden: true,
-    permissions: ['system:user:edit'],
-    children: [
-      {
-        path: 'role/:userId(\\d+)',
-        component: () => import('@/views/system/user/authRole'),
-        name: 'AuthRole',
-        meta: { title: '鍒嗛厤瑙掕壊', activeMenu: '/system/user' }
-      }
-    ]
-  },
-  {
-    path: '/system/role-auth',
-    component: Layout,
-    hidden: true,
-    permissions: ['system:role:edit'],
-    children: [
-      {
-        path: 'user/:roleId(\\d+)',
-        component: () => import('@/views/system/role/authUser'),
-        name: 'AuthUser',
-        meta: { title: '鍒嗛厤鐢ㄦ埛', activeMenu: '/system/role' }
-      }
-    ]
-  },
-  {
-    path: '/system/dict-data',
-    component: Layout,
-    hidden: true,
-    permissions: ['system:dict:list'],
-    children: [
-      {
-        path: 'index/:dictId(\\d+)',
-        component: () => import('@/views/system/dict/data'),
-        name: 'Data',
-        meta: { title: '瀛楀吀鏁版嵁', activeMenu: '/system/dict' }
-      }
-    ]
-  },
-  {
-    path: '/monitor/job-log',
-    component: Layout,
-    hidden: true,
-    permissions: ['monitor:job:list'],
-    children: [
-      {
-        path: 'index/:jobId(\\d+)',
-        component: () => import('@/views/monitor/job/log'),
-        name: 'JobLog',
-        meta: { title: '璋冨害鏃ュ織', activeMenu: '/monitor/job' }
-      }
-    ]
-  },
-  {
-    path: '/tool/gen-edit',
-    component: Layout,
-    hidden: true,
-    permissions: ['tool:gen:edit'],
-    children: [
-      {
-        path: 'index/:tableId(\\d+)',
-        component: () => import('@/views/tool/gen/editTable'),
-        name: 'GenEdit',
-        meta: { title: '淇敼鐢熸垚閰嶇疆', activeMenu: '/tool/gen' }
-      }
-    ]
-  },
-  {
-    path: '/iot',
-    component: Layout,
-    hidden: true,
-    permissions: ['iot:device:add'],
-    children: [
-      {
-        path: 'product-edit',
-        component: () => import('@/views/iot/product/product-edit'),
-        name: 'ProductEdit',
-        meta: { title: '缂栬緫浜у搧', activeMenu: '/iot/product',nocache: true}
-      },
-      {
-        path: 'device-edit',
-        component: () => import('@/views/iot/device/device-edit'),
-        name: 'DeviceEdit',
-        meta: { title: '缂栬緫璁惧', activeMenu: '/iot/device', noCache: true}
-      }
-    ]
-  },
-]
+    {
+        path: '/system/user-auth',
+        component: Layout,
+        hidden: true,
+        permissions: ['system:user:edit'],
+        children: [
+            {
+                path: 'role/:userId(\\d+)',
+                component: () => import('@/views/system/user/authRole'),
+                name: 'AuthRole',
+                meta: { title: '鍒嗛厤瑙掕壊', activeMenu: '/system/user' },
+            },
+        ],
+    },
+    {
+        path: '/system/role-auth',
+        component: Layout,
+        hidden: true,
+        permissions: ['system:role:edit'],
+        children: [
+            {
+                path: 'user/:roleId(\\d+)',
+                component: () => import('@/views/system/role/authUser'),
+                name: 'AuthUser',
+                meta: { title: '鍒嗛厤鐢ㄦ埛', activeMenu: '/system/role' },
+            },
+        ],
+    },
+    {
+        path: '/system/dict-data',
+        component: Layout,
+        hidden: true,
+        permissions: ['system:dict:list'],
+        children: [
+            {
+                path: 'index/:dictId(\\d+)',
+                component: () => import('@/views/system/dict/data'),
+                name: 'Data',
+                meta: { title: '瀛楀吀鏁版嵁', activeMenu: '/system/dict' },
+            },
+        ],
+    },
+    {
+        path: '/monitor/job-log',
+        component: Layout,
+        hidden: true,
+        permissions: ['monitor:job:list'],
+        children: [
+            {
+                path: 'index/:jobId(\\d+)',
+                component: () => import('@/views/monitor/job/log'),
+                name: 'JobLog',
+                meta: { title: '璋冨害鏃ュ織', activeMenu: '/monitor/job' },
+            },
+        ],
+    },
+    {
+        path: '/tool/gen-edit',
+        component: Layout,
+        hidden: true,
+        permissions: ['tool:gen:edit'],
+        children: [
+            {
+                path: 'index/:tableId(\\d+)',
+                component: () => import('@/views/tool/gen/editTable'),
+                name: 'GenEdit',
+                meta: { title: '淇敼鐢熸垚閰嶇疆', activeMenu: '/tool/gen' },
+            },
+        ],
+    },
+    {
+        path: '/iot',
+        component: Layout,
+        hidden: true,
+        permissions: ['iot:device:add'],
+        children: [
+            {
+                path: 'product-edit',
+                component: () => import('@/views/iot/product/product-edit'),
+                name: 'ProductEdit',
+                meta: { title: '缂栬緫浜у搧', activeMenu: '/iot/product', nocache: true },
+            },
+            {
+                path: 'device-edit',
+                component: () => import('@/views/iot/device/device-edit'),
+                name: 'DeviceEdit',
+                meta: { title: '缂栬緫璁惧', activeMenu: '/iot/device', noCache: true },
+            },
+        ],
+    },
+];
 
 // 闃叉杩炵画鐐瑰嚮澶氭璺敱鎶ラ敊
 let routerPush = Router.prototype.push;
 Router.prototype.push = function push(location) {
-  return routerPush.call(this, location).catch(err => err)
-}
+    return routerPush.call(this, location).catch((err) => err);
+};
 
 export default new Router({
-  mode: 'history', // 鍘绘帀url涓殑#
-  scrollBehavior: () => ({ y: 0 }),
-  routes: constantRoutes
-})
+    mode: 'history', // 鍘绘帀url涓殑#
+    scrollBehavior: () => ({ y: 0 }),
+    routes: constantRoutes,
+});
diff --git a/src/store/modules/mapLayers.js b/src/store/modules/mapLayers.js
index aa0a339..4a46496 100644
--- a/src/store/modules/mapLayers.js
+++ b/src/store/modules/mapLayers.js
@@ -1,16 +1,22 @@
 import Cookies from 'js-cookie';
-
+import busEvent from '@/utils/busEvent';
 const state = {
     layerTree: [],
     defaultLayer: [],
+    mapInfo: [],
 };
 
 const mutations = {
     CHANGE_LAYERTREE: (state, res) => {
         state.layerTree = res;
     },
-    CHANGE_DEFAULTLAYER: (state,res) => {
+    CHANGE_DEFAULTLAYER: (state, res) => {
         state.defaultLayer = res;
+    },
+    CHANGE_MAPINFO: (state, res) => {
+        state.mapInfo = res;
+        busEvent.$emit('CHANGE_MAPINFO',  state.mapInfo);
+    
     },
 };
 
@@ -21,6 +27,9 @@
     changeDefaultLayer({ commit }, obj) {
         commit('CHANGE_DEFAULTLAYER', obj);
     },
+    changeMapInfo({ commit }, obj) {
+        commit('CHANGE_MAPINFO', obj);
+    },
 };
 
 export default {
diff --git a/src/utils/mapServer/pyServer.js b/src/utils/mapServer/pyServer.js
new file mode 100644
index 0000000..99b915b
--- /dev/null
+++ b/src/utils/mapServer/pyServer.js
@@ -0,0 +1,8 @@
+import axios from 'axios';
+const pyServer = axios.create({
+    // axios涓姹傞厤缃湁baseURL閫夐」锛岃〃绀鸿姹俇RL鍏叡閮ㄥ垎
+    baseURL: config.pyServices,
+    // 瓒呮椂
+    timeout: -1,
+});
+export default pyServer;
diff --git a/src/views/dataManager/equipMante/AddOrUpdate.vue b/src/views/dataManager/equipMante/AddOrUpdate.vue
new file mode 100644
index 0000000..1c5b69e
--- /dev/null
+++ b/src/views/dataManager/equipMante/AddOrUpdate.vue
@@ -0,0 +1,166 @@
+<template>
+    <el-dialog :title="!dataForm.id ? '鏂板' : '淇敼'" :close-on-click-modal="false" :visible.sync="visible">
+        <el-form :model="dataForm" :rules="dataRule" ref="dataForm" @keyup.enter.native="dataFormSubmit()"
+            label-width="120px">
+            <el-form-item label="瀹㈡埛鍚嶇О" prop="cName">
+                <el-input v-model="dataForm.cName" placeholder="瀹㈡埛鍚嶇О"></el-input>
+            </el-form-item>
+            <el-form-item label="鏁呴殰鍦扮偣鍚嶇О" prop="fName">
+                <el-input v-model="dataForm.fName" placeholder="鏁呴殰鍦扮偣鍚嶇О"></el-input>
+            </el-form-item>
+            <el-form-item label="鏁呴殰鍦扮偣缁忕含搴�" prop="fLocation">
+                <el-input v-model="dataForm.fLocation" placeholder="鏁呴殰鍦扮偣缁忕含搴�"></el-input>
+            </el-form-item>
+            <el-form-item label="鑱旂郴鐢佃瘽" prop="fPhone">
+                <el-input v-model="dataForm.fPhone" placeholder="鑱旂郴鐢佃瘽"></el-input>
+            </el-form-item>
+            <el-form-item label="鏁呴殰鏃堕棿" prop="fDate">
+                <el-input v-model="dataForm.fDate" placeholder="鏁呴殰鏃堕棿"></el-input>
+            </el-form-item>
+            <el-form-item label="鎶ヤ慨鏂瑰紡" prop="fType">
+                <el-input v-model="dataForm.fType" placeholder="鎶ヤ慨鏂瑰紡"></el-input>
+            </el-form-item>
+            <el-form-item label="璁板綍浜�" prop="fMan">
+                <el-input v-model="dataForm.fMan" placeholder="璁板綍浜�"></el-input>
+            </el-form-item>
+            <el-form-item label="鎶ヤ慨鍐呭" prop="fContent">
+                <el-input v-model="dataForm.fContent" placeholder="鎶ヤ慨鍐呭"></el-input>
+            </el-form-item>
+            <el-form-item label="鍒拌揪鐜板満鏃堕棿" prop="rDate">
+                <el-input v-model="dataForm.rDate" placeholder="鍒拌揪鐜板満鏃堕棿"></el-input>
+            </el-form-item>
+            <el-form-item label="缁翠慨缁撴潫鏃堕棿" prop="reDate">
+                <el-input v-model="dataForm.reDate" placeholder="缁翠慨缁撴潫鏃堕棿"></el-input>
+            </el-form-item>
+            <el-form-item label="缁翠慨杞ㄨ抗" prop="rePosition">
+                <el-input v-model="dataForm.rePosition" placeholder="缁翠慨杞ㄨ抗"></el-input>
+            </el-form-item>
+            <el-form-item label="缁翠慨瑙嗛" prop="reVideo">
+                <el-input v-model="dataForm.reVideo" placeholder="缁翠慨瑙嗛"></el-input>
+            </el-form-item>
+            <el-form-item label="瀹㈡埛璇勪环" prop="reEvaluation">
+                <el-input v-model="dataForm.reEvaluation" placeholder="瀹㈡埛璇勪环"></el-input>
+            </el-form-item>
+        </el-form>
+        <span slot="footer" class="dialog-footer">
+            <el-button @click="visible = false">鍙栨秷</el-button>
+            <el-button type="primary" @click="dataFormSubmit()">纭畾</el-button>
+        </span>
+    </el-dialog>
+</template>
+
+<script>
+import { faultreport_save, faultreport_update } from '@/api/mapView/peiwang.js';
+export default {
+    data() {
+        return {
+            visible: false,
+            dataForm: {
+                id: undefined,
+                cName: '',
+                fName: '',
+                fLocation: '',
+                fPhone: '',
+                fDate: '',
+                fType: '',
+                fMan: '',
+                fContent: '',
+                rDate: '',
+                reDate: '',
+                rePosition: '',
+                reVideo: '',
+                reEvaluation: ''
+            },
+            dataRule: {
+                cName: [
+                    { required: true, message: '瀹㈡埛鍚嶇О涓嶈兘涓虹┖', trigger: 'blur' }
+                ],
+                fName: [
+                    { required: true, message: '鏁呴殰鍦扮偣鍚嶇О涓嶈兘涓虹┖', trigger: 'blur' }
+                ],
+                fLocation: [
+                    { required: true, message: '鏁呴殰鍦扮偣缁忕含搴︿笉鑳戒负绌�', trigger: 'blur' }
+                ],
+                fPhone: [
+                    { required: true, message: '鑱旂郴鐢佃瘽涓嶈兘涓虹┖', trigger: 'blur' }
+                ],
+                fDate: [
+                    { required: true, message: '鏁呴殰鏃堕棿涓嶈兘涓虹┖', trigger: 'blur' }
+                ],
+                fType: [
+                    { required: true, message: '鎶ヤ慨鏂瑰紡涓嶈兘涓虹┖', trigger: 'blur' }
+                ],
+                fMan: [
+                    { required: true, message: '璁板綍浜轰笉鑳戒负绌�', trigger: 'blur' }
+                ],
+                fContent: [
+                    { required: true, message: '鎶ヤ慨鍐呭涓嶈兘涓虹┖', trigger: 'blur' }
+                ],
+                rDate: [
+                    { required: true, message: '鍒拌揪鐜板満鏃堕棿涓嶈兘涓虹┖', trigger: 'blur' }
+                ],
+                reDate: [
+                    { required: true, message: '缁翠慨缁撴潫鏃堕棿涓嶈兘涓虹┖', trigger: 'blur' }
+                ],
+                rePosition: [
+                    { required: true, message: '缁翠慨杞ㄨ抗涓嶈兘涓虹┖', trigger: 'blur' }
+                ],
+                reVideo: [
+                    { required: true, message: '缁翠慨瑙嗛涓嶈兘涓虹┖', trigger: 'blur' }
+                ],
+                reEvaluation: [
+                    { required: true, message: '瀹㈡埛璇勪环涓嶈兘涓虹┖', trigger: 'blur' }
+                ]
+            }
+        }
+    },
+    methods: {
+        init(response) {
+            this.visible = true
+            if (response) {
+                this.dataForm = { ...response }
+            }
+
+        },
+        // 琛ㄥ崟鎻愪氦
+        dataFormSubmit() {
+            this.$refs['dataForm'].validate((valid) => {
+                if (valid) {
+                    if (this.dataForm.id) {
+                        this.setEditReport();
+                    } else {
+                        this.setSaveReport();
+                    }
+                }
+            })
+        },
+        setSaveReport() {
+            faultreport_save(this.dataForm).then(response => {
+                console.log(response);
+                // this.$message({
+                //   message: '鎿嶄綔鎴愬姛',
+                //   type: 'success',
+                //   duration: 1500,
+                //   onClose: () => {
+                //     this.visible = false
+                //     this.$emit('refreshDataList')
+                //   }
+                // })
+            })
+        },
+        setEditReport() {
+            faultreport_update(this.dataForm).then(response => {
+                console.log(response);
+
+            })
+        },
+
+
+
+
+
+
+
+    }
+}
+</script>
diff --git a/src/views/dataManager/equipMante/index.vue b/src/views/dataManager/equipMante/index.vue
new file mode 100644
index 0000000..1d5633d
--- /dev/null
+++ b/src/views/dataManager/equipMante/index.vue
@@ -0,0 +1,168 @@
+<!-- 璁惧缁翠慨 -->
+<template>
+    <div class="equipManteBox">
+        <el-card>
+            <div class="infoSearch">
+                <el-form :inline="true" :model="dataForm">
+                    <el-form-item>
+                        <el-input size="small" v-model="dataForm.key" placeholder="鍙傛暟鍚�" clearable></el-input>
+                    </el-form-item>
+                </el-form>
+                <div>
+                    <el-button plain size="small" @click="getDataList()">鏌ヨ</el-button>
+                    <el-button plain size="small" type="primary" @click="addOrUpdateHandle()">鏂板</el-button>
+                    <el-button plain size="small" type="danger"
+                        :disabled="dataListSelections.length <= 0">鎵归噺鍒犻櫎</el-button>
+                </div>
+            </div>
+        </el-card>
+        <el-card class="infoConTent">
+            <div class="infoTable">
+                <el-table :data="dataList" border height="calc(100% - 65px)" v-loading="dataListLoading"
+                    @selection-change="selectionChangeHandle" style="width: 100%;">
+                    <el-table-column type="selection" header-align="center" align="center" width="50">
+                    </el-table-column>
+                    <el-table-column align="center" type="index" label="搴忓彿" width="70px" />
+                    <!-- <el-table-column prop="id" header-align="center" align="center" label="${column.comments}">
+                    </el-table-column> -->
+                    <el-table-column prop="c_name" header-align="center" align="center" label="瀹㈡埛鍚嶇О">
+                    </el-table-column>
+                    <el-table-column prop="f_name" header-align="center" align="center" label="鏁呴殰鍦扮偣鍚嶇О">
+                    </el-table-column>
+                    <el-table-column prop="f_location" header-align="center" align="center" label="鏁呴殰鍦扮偣缁忕含搴�">
+                    </el-table-column>
+                    <el-table-column prop="f_phone" header-align="center" align="center" label="鑱旂郴鐢佃瘽">
+                    </el-table-column>
+                    <el-table-column prop="f_date" header-align="center" align="center" label="鏁呴殰鏃堕棿">
+                    </el-table-column>
+                    <el-table-column prop="f_type" header-align="center" align="center" label="鎶ヤ慨鏂瑰紡">
+                    </el-table-column>
+                    <el-table-column prop="f_man" header-align="center" align="center" label="璁板綍浜�">
+                    </el-table-column>
+                    <el-table-column prop="f_content" header-align="center" align="center" label="鎶ヤ慨鍐呭">
+                    </el-table-column>
+                    <el-table-column prop="r_date" header-align="center" align="center" label="鍒拌揪鐜板満鏃堕棿">
+                    </el-table-column>
+                    <el-table-column prop="re_date" header-align="center" align="center" label="缁翠慨缁撴潫鏃堕棿">
+                    </el-table-column>
+                    <el-table-column prop="re_position" header-align="center" align="center" label="缁翠慨杞ㄨ抗">
+                    </el-table-column>
+                    <el-table-column prop="re_video" header-align="center" align="center" label="缁翠慨瑙嗛">
+                    </el-table-column>
+                    <el-table-column prop="re_evaluation" header-align="center" align="center" label="瀹㈡埛璇勪环">
+                    </el-table-column>
+                    <el-table-column fixed="right" header-align="center" align="center" width="150" label="鎿嶄綔">
+                        <template slot-scope="scope">
+                            <el-button type="text" size="small">淇敼</el-button>
+                            <el-button type="text" size="small">鍒犻櫎</el-button>
+                        </template>
+                    </el-table-column>
+                </el-table>
+                <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageIndex"
+                    :limit.sync="queryParams.pageSize" @pagination="getDataList" />
+            </div>
+        </el-card>
+        <!-- 寮圭獥, 鏂板 / 淇敼 -->
+        <add-or-update v-if="addOrUpdateVisible" ref="addOrUpdate" @refreshDataList="getDataList"></add-or-update>
+    </div>
+</template>
+
+<script>
+import { faultreport_list } from '@/api/mapView/peiwang.js';
+import AddOrUpdate from './AddOrUpdate.vue';
+export default {
+    name: "equipMante",
+    components: {
+        AddOrUpdate
+    },
+    data() {
+        return {
+            dataForm: {
+                key: ""
+            },
+            dataListSelections: [],
+            queryParams: {
+                pageIndex: 1,
+                pageSize: 10,
+                name: '',
+                srid: 4326,
+            },
+            dataListLoading: false,
+            dataList: [],
+            total: 0,
+            addOrUpdateVisible: false,
+        }
+    },
+    mounted() {
+        this.getDataList();
+    },
+    methods: {
+        addOrUpdateHandle(res) {
+            this.addOrUpdateVisible = true
+            this.$nextTick(() => {
+                   this.$refs.addOrUpdate.init(res)
+            })
+        },
+        selectionChangeHandle(res) {
+            this.dataListSelections = res;
+        },
+        getDataList() {
+            this.dataListLoading = true;
+            faultreport_list({
+                page: this.queryParams.pageIndex,
+                limit: this.queryParams.pageSize,
+                key: this.queryParams.name,
+            }).then(response => {
+                this.dataListLoading = false;
+                if (response.status != 200) return
+                const obj = response.data.page;
+                this.total = obj.totalCount;
+                this.dataList = obj.list;
+            })
+        }
+    }
+
+}
+</script>
+
+<style lang="scss" scoped>
+.equipManteBox {
+    width: calc(100% - 20px);
+    height: calc(100% - 20px);
+    position: absolute;
+    margin: 10px;
+    border-radius: 5px;
+    display: flex;
+    flex-direction: column;
+
+    .infoSearch {
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+
+        ::v-deep.el-form-item {
+            margin: 0px;
+        }
+    }
+
+    .infoConTent {
+        margin-top: 10px;
+        flex: 1;
+        position: relative;
+
+        .infoTable {
+            width: calc(100% - 30px);
+            height: calc(100% - 36px);
+            position: absolute;
+            display: flex;
+            flex-direction: column;
+        }
+    }
+
+    ::v-deep.el-card__body {
+        padding: 15px;
+    }
+
+
+}
+</style>
\ No newline at end of file
diff --git a/src/views/dataManager/semanticFunction/child/agentInsertFile.vue b/src/views/dataManager/semanticFunction/child/agentInsertFile.vue
index 32e2189..87bf7f1 100644
--- a/src/views/dataManager/semanticFunction/child/agentInsertFile.vue
+++ b/src/views/dataManager/semanticFunction/child/agentInsertFile.vue
@@ -1,27 +1,36 @@
 <template>
     <div :id="msgId" class="textBox">
- 
+        <div v-loading="loading" element-loading-text="鏁版嵁涓婁紶涓�..." element-loading-spinner="el-icon-loading"
+            element-loading-background="rgba(0, 0, 0, 0.6)" class="fileBox" v-for="(item, index) in filieOption"
+            :key="index">
+            <span>{{ item.name }}</span><span class="upMsg">
+                {{ upMsg }}
+            </span>
+        </div>
     </div>
 </template>
 
 <script>
+import { rag_chat, rag_search, rag_upload } from "@/api/mapView/rag.js";
 export default {
     data() {
         return {
             msgId: null,
-            msgText: '',
+            filieOption: [],
+            loading: false,
+            upMsg: "",
         }
     },
     props: {
         childObject: {
-            type: Array,
+            type: Object,
+            required: true
         }
     },
     watch: {
         childObject: {
             handler(newVal, oldVal) {
                 if (newVal) {
-                    console.log(newVal);
                     this.setTextMsg(newVal)
                 }
             },
@@ -31,11 +40,57 @@
     },
     methods: {
         setTextMsg(res) {
+            if (!res.msg) return
             this.id = res.id
-            console.log("insertFile", msg);
+            this.filieOption = res.msg;
+            this.$nextTick(() => {
+                this.loading = true;
+                this.setInsertFile()
+            })
+        },
+        setInsertFile() {
+            const fs = document.getElementById("insertFile")
+            if (fs.files.length <= 0) return;
+            const formData = new FormData();
+            for (var i = 0, c = fs.files.length; i < c; i++) {
+                formData.append("file", fs.files[i]); // fs.files[i].name,file
+            }
+            rag_upload(formData).then(response => {
+                this.loading = false
+                document.getElementById('insertFile').value = ""
+                if (response.data == 'success') {
+                    this.upMsg = "涓婁紶鎴愬姛"
+                } else {
+                    this.upMsg = "涓婁紶澶辫触"
+                }
+
+            })
         }
     }
 }
 </script>
 
-<style></style>
\ No newline at end of file
+<style lang="scss" scoped>
+.textBox {
+    padding-top: 10px;
+}
+
+.fileBox {
+    background: white;
+    padding: 10px;
+    margin-bottom: 10px;
+    min-width: 300px;
+    min-height: 70px;
+    display: flex;
+    align-items: center;
+    border-radius: 5px;
+    justify-content: space-between;
+    .upMsg {
+        font-size: 12px;
+        color: #1890ff;
+    }
+
+
+
+}
+</style>
diff --git a/src/views/dataManager/semanticFunction/contentList.vue b/src/views/dataManager/semanticFunction/contentList.vue
index 6ead7e1..1d42177 100644
--- a/src/views/dataManager/semanticFunction/contentList.vue
+++ b/src/views/dataManager/semanticFunction/contentList.vue
@@ -15,16 +15,15 @@
                             <agent-text :id="item.id + key" :child-object="res"></agent-text>
                         </div>
                         <!-- loading -->
-                        <div v-if="res.type == 'loading'">
+                        <div v-else-if="res.type == 'loading'">
                             <agent-load></agent-load>
                         </div>
                         <!-- rag -->
-                        <div v-if="res.type == 'rag'">
+                        <div v-else-if="res.type == 'rag'">
                             <agent-rag :id="item.id + key" :child-object="res"></agent-rag>
                         </div>
                         <!-- insrtFile -->
-                        <div v-if="res.type == 'insrtFile'">
-                            {{ res }}
+                        <div v-else-if="res.type == 'insertFile'">
                             <agent-insert-file :id="item.id + key" :child-object="res"></agent-insert-file>
                         </div>
 
@@ -90,8 +89,7 @@
                 msg: res.msg,
                 mine: true,
             })
-            console.log(obj);
-            this.msgList.push()
+            this.msgList.push(obj)
         },
         setUserMsg(res) {
             this.msgList.push(msgconfig.initMsg({
diff --git a/src/views/dataManager/semanticFunction/enterBox.vue b/src/views/dataManager/semanticFunction/enterBox.vue
index 5de6131..a447ce1 100644
--- a/src/views/dataManager/semanticFunction/enterBox.vue
+++ b/src/views/dataManager/semanticFunction/enterBox.vue
@@ -1,7 +1,7 @@
 <template>
     <div class="enterBox">
 
-        <input type="file" @change="setInputFileChange" accept=".docx,.txt" id="insertFile" style="display:none">
+        <input type="file" @change="setInputFileChange" multiple accept=".docx,.txt" id="insertFile" style="display:none">
         <div class="enterContent">
             <el-input type="textarea" :rows="rows" maxRows="4" placeholder="璇疯緭鍏ユ偍鐨勯棶棰�..." v-model="msgContent"
                 maxlength="4000" @keyup="onKeyup">
diff --git a/src/views/redirect.vue b/src/views/redirect.vue
index db4c1d6..1062103 100644
--- a/src/views/redirect.vue
+++ b/src/views/redirect.vue
@@ -3,6 +3,8 @@
   created() {
     const { params, query } = this.$route
     const { path } = params
+    console.log(path);
+    
     this.$router.replace({ path: '/' + path, query })
   },
   render: function(h) {
diff --git a/src/views/visual/atlas/index.vue b/src/views/visual/atlas/index.vue
index d890e9f..7d6e9a8 100644
--- a/src/views/visual/atlas/index.vue
+++ b/src/views/visual/atlas/index.vue
@@ -12,7 +12,7 @@
         <div class="graphicBox" v-show="showEcharts">
             <div class="konwReturn fl">
                 <el-link @click="showEcharts = false">
-                    <i class="el-icon-d-arrow-left"></i>
+                    <i style="color: #409EFF;" class="el-icon-d-arrow-left"></i>
                 </el-link>
                 褰撳墠棰嗗煙:{{ targetName }}
             </div>
@@ -146,9 +146,9 @@
         getGraphicNodes(res, lines, obj) {
             const std = [];
             const ids = [];
-           
+
             lines.filter(item => {
-             
+
                 if (ids.indexOf(item.sourceId) < 0) {
                     ids.push(item.sourceId)
                 }
@@ -165,7 +165,7 @@
                 if (item.poi && item.poi == 1) {
                     poi = true;
                 }
-               
+
                 const expand = ids.indexOf(item.uuid) > -1 ? false : true
                 if (!expand) {
 
@@ -219,7 +219,7 @@
                     graphInstance.doLayout();
                 });
 
-            }, 1000);
+            }, 200);
 
 
             setTimeout(() => {
@@ -364,13 +364,16 @@
     .graphicBox {
         width: 100%;
         height: 100%;
+        position: relative;
         display: flex;
         flex-direction: column;
+        color: #409EFF;
 
         .graphicContent {
             padding: 10px;
             flex: 1;
 
+
         }
     }
 }
diff --git a/src/views/visual/mapView/dataStatistics.vue b/src/views/visual/mapView/dataStatistics.vue
index 7d6735f..6365912 100644
--- a/src/views/visual/mapView/dataStatistics.vue
+++ b/src/views/visual/mapView/dataStatistics.vue
@@ -2,27 +2,19 @@
     <Popup ref="pop" top="20px" :title="title" @close="close(true)" width="1000px" :maxHeight="'700px'"
         @cancel="close(false)">
         <div class="menuBox">
-            <div class="serachContent">
-                <el-select v-model="linesName" @change="setEchartChange" placeholder="璇烽�夋嫨">
-                    <el-option v-for="(item, key) in linesOption" :key="key" :label="item.line" :value="item.line">
-                    </el-option>
-                </el-select>
-            </div>
-            <div class="echartContent">
-                <div id="myEchart" class="myChart"> </div>
-            </div>
+            <statistics></statistics>
         </div>
+
     </Popup>
 </template>
 
 <script>
 import Popup from '@/components/Tool/Popup.vue';
-import { zhangzitou_selectInfos } from "@/api/mapView/map.js"
-import mapData from '@/assets/js/mapSdk/mapData';
-import * as echarts from 'echarts';
+ 
+import statistics from '@/views/visual/statistics/index.vue'
 export default {
     name: 'dataAnalysis',
-    components: { Popup },
+    components: { Popup ,statistics},
     data() {
         return {
             title: '鏁版嵁缁熻',
@@ -44,86 +36,7 @@
         open() {
             this.close(true);
             this.$refs.pop.open();
-            this.getAllLines();
-        },
-        getAllLines() {
-            zhangzitou_selectInfos().then(response => {
-                if (response.data.code != 200) {
-                    return this.close();
-                }
-                this.setAllLinses(response.data.result)
-            })
-        },
-        setAllLinses(res) {
-            this.allLines = res;
-            this.linesOption = this.allLines.filter((item, index, self) =>
-                index === self.findIndex((t) => t.line === item.line)
-            );
-            this.linesName = this.linesOption[0].line;
-            this.setEchartChange();
-        },
-        setEchartChange() {
-            zhangzitou_selectInfos({
-                line: this.linesName
-            }).then(response => {
-                if (response.data.code != 200) return
-                const result = response.data.result;
-
-                const objData = []
-                result.filter(item => {
-                    const type = mapData.dataStatistics[item.type];
-                    if (type) {
-                        item.type = type
-                    }
-                    objData.push({
-                        value: item.count, name: item.type
-                    })
-                })
-                this.setEchartShow(objData)
-            })
-
-        },
-
-        setEchartShow(res) {
-
-            let option = {
-                title: {
-
-                    left: 'center'
-                },
-                tooltip: {
-                    trigger: 'item'
-                },
-                legend: {
-                    orient: 'vertical',
-                    left: 'left'
-                },
-                series: [
-                    {
-                        name: this.linesName,
-                        type: 'pie',
-                        radius: '50%',
-                        data: res,
-                        emphasis: {
-                            itemStyle: {
-                                shadowBlur: 10,
-                                shadowOffsetX: 0,
-                                shadowColor: 'rgba(0, 0, 0, 0.5)'
-                            }
-                        }
-                    }
-                ]
-            };
-            if (!this.myChart) {
-
-                this.myChart = echarts.init(document.getElementById("myEchart"));
-            }
-
-
-            this.myChart.setOption(option);
-            window.addEventListener("resize", () => {
-                this.myChart.resize();
-            });
+            
         },
     },
 };
@@ -133,25 +46,10 @@
 .menuBox {
     position: relative;
     height: 660px;
-    width: calc(100% - 0px);
-    padding: 10px;
-    display: flex;
-    flex-direction: column;
+    width: calc(100% - 0px)
+  
 
-    .serachContent {
-        display: flex;
-    }
-
-    .echartContent {
-        flex: 1;
-
-
-        .myChart {
-            margin-top: 10px;
-            width: 100%;
-            height: calc(100% - 10px);
-        }
-    }
+     
 
 }
 </style>
diff --git a/src/views/visual/mapView/index.vue b/src/views/visual/mapView/index.vue
index 539c4f3..d019da3 100644
--- a/src/views/visual/mapView/index.vue
+++ b/src/views/visual/mapView/index.vue
@@ -45,6 +45,7 @@
             <dataStatistics ref="dataStatistics"></dataStatistics>
             <!-- 灞炴�т俊鎭� -->
             <attributeInfo ref="attributeInfo"></attributeInfo>
+            <map-info :childObj="childObj" ref="mapInfo"></map-info>
         </div>
     </div>
 </template>
@@ -65,31 +66,58 @@
 import dataAnalysis from './dataAnalysis.vue';
 import dataStatistics from './dataStatistics.vue'
 import attributeInfo from './attributeInfo.vue';
+import mapInfo from './mapInfo.vue';
 export default {
     name: 'mapView',
-    components: { layerManager, location, knowledge, lineRoaming, undergroundMode, dataAnalysis, dataStatistics, attributeInfo },
+    components: { layerManager, location, knowledge, lineRoaming, undergroundMode, dataAnalysis, dataStatistics, attributeInfo, mapInfo },
     data() {
         return {
             menuIsShow: false,
             menuOption: [],
             childMenuIsShow: true,
             childMenuOption: [],
+            childObj: [],
         };
     },
     mounted() {
         this.mapViewStart();
+        this.$busEvent.$on('CHANGE_MAPINFO', res => {
+
+            this.setMapInfo(res)
+
+        });
 
     },
     beforeDestroy() {
         this.$store.dispatch('mapLayers/changeLayerTree', [])
         this.$store.dispatch('mapLayers/changeDefaultLayer', [])
     },
+
+
     methods: {
+        setMapInfo(res) {
+            // console.log(res);
+            if (res.length > 0) {
+                this.childObj = res;
+                setTimeout(() => {
+                    this.$refs && this.$refs.mapInfo && this.$refs.mapInfo.open();
+                }, 200);
+
+
+            }
+
+        },
         mapViewStart() {
             this.menuOption = mapData.menuData;
             this.$nextTick(() => {
                 mapInit.Init();
-                this.getSelectLayers();
+                setTimeout(() => {
+                  if(config.baseModel.url){
+                    mapServer.addLayer(config.baseModel);
+                  }
+                    this.getSelectLayers();
+                }, 500);
+
             });
         },
         getSelectLayers() {
@@ -196,7 +224,7 @@
         .rightMenu {
             width: 30px;
             height: 40px;
-            background: rgba(245, 245, 245, 1);
+            background: rgba(255, 255, 255, 1);
             border: 1px solid rgb(245, 245, 245);
             color: #4ab1fc;
             display: flex;
diff --git a/src/views/visual/mapView/lineRoaming.vue b/src/views/visual/mapView/lineRoaming.vue
index 0d1b304..dab1099 100644
--- a/src/views/visual/mapView/lineRoaming.vue
+++ b/src/views/visual/mapView/lineRoaming.vue
@@ -132,7 +132,6 @@
         },
         setLineOption1Chagne() {
             this.roamLine = this.value1;
-            console.log(this.lineOption1);
         },
         setRoamStart() {
             if (!this.roamLine) return;
@@ -147,11 +146,11 @@
                     "coordinates": degreesArr
                 }
             }
-            const fly = sgworld.factory.createDynamicObject(routeData, url, shuj);
+            // const fly = sgworld.factory.createDynamicObject(routeData, url, shuj);
             earthCtrl.factory.getFlyData(degreesArr, data => {
                 data.showPoint = false;
                 data.showLine = true;
-                data.mode = 1;
+                data.mode = 0;
                 // 寮圭獥鏁版嵁
                 window.PathAnimationData = {
                     flyData: data,
@@ -180,7 +179,7 @@
             })
         },
         setRoamStop() {
-
+            window.PathAnimationData.fly &&   window.PathAnimationData.fly.exit();
         },
 
 
diff --git a/src/views/visual/mapView/mapInfo.vue b/src/views/visual/mapView/mapInfo.vue
new file mode 100644
index 0000000..3c378a1
--- /dev/null
+++ b/src/views/visual/mapView/mapInfo.vue
@@ -0,0 +1,74 @@
+<template>
+    <Popup ref="pop" top="20px" left="calc(100% - 600px)" :title="title" @close="close(true)" width="300px"
+        @cancel="close(false)">
+        <div  class="infoBox">
+            <table>
+                <tr cla="infoTr" v-for="item in childObj">
+                    <td class="infotd">{{ item.name }}</td>
+                    <td class="infotd">:</td>
+                    <td class="infotd">{{ item.val }}</td>
+                </tr>
+            </table>
+
+        </div>
+
+    </Popup>
+</template>
+
+<script>
+import Popup from '@/components/Tool/Popup.vue';
+import store from '@/store';
+import { type } from 'jquery';
+export default {
+    name: 'location',
+    components: { Popup },
+    data() {
+        return {
+            title: '璇︾粏淇℃伅',
+            mapInfoOption: [],
+        };
+    },
+    props: {
+        childObj: {
+            type: Array,
+            default: null
+        }
+    },
+    methods: {
+        // 鍏抽棴寮圭獥
+        close(isCloseBtn, removeLayer = true) {
+            //   removeLayer && this.removeImageLayer();
+            // 閲嶇疆data鍊�
+
+            Object.assign(this.$data, this.$options.data());
+            !isCloseBtn && this.$refs.pop.close();
+
+        },
+        // 鎵撳紑寮圭獥
+        open() {
+            this.close(true);
+            this.$refs.pop.open();
+
+
+
+            setTimeout(() => {
+                console.log(store.getters.mapInfo);
+            }, 500);
+        },
+
+
+    },
+};
+</script>
+
+<style lang="scss" scoped>
+
+.infoBox{
+    margin: 10px;
+    
+}
+.infotd{
+    min-width: 30px;
+    text-align: center;
+}
+</style>
diff --git a/src/views/visual/statistics/index.vue b/src/views/visual/statistics/index.vue
new file mode 100644
index 0000000..5436370
--- /dev/null
+++ b/src/views/visual/statistics/index.vue
@@ -0,0 +1,146 @@
+<template>
+
+    <div class="menuBox1">
+        <div class="serachContent">
+            <el-select v-model="linesName" @change="setEchartChange" placeholder="璇烽�夋嫨">
+                <el-option v-for="(item, key) in linesOption" :key="key" :label="item.line" :value="item.line">
+                </el-option>
+            </el-select>
+        </div>
+        <div class="echartContent">
+            <div id="myEchart" class="myChart"> </div>
+        </div>
+    </div>
+</template>
+
+<script>
+import Popup from '@/components/Tool/Popup.vue';
+import { zhangzitou_selectInfos } from "@/api/mapView/map.js"
+import mapData from '@/assets/js/mapSdk/mapData';
+import * as echarts from 'echarts';
+export default {
+    name: 'dataAnalysis',
+    components: { Popup },
+    data() {
+        return {
+            title: '鏁版嵁缁熻',
+            allLines: [],
+            linesOption: [],
+            linesName: '',
+            myChart: null,
+        };
+    },
+    mounted(){
+        this.getAllLines();
+    },
+    methods: {
+        
+        getAllLines() {
+            zhangzitou_selectInfos().then(response => {
+                if (response.data.code != 200) {
+                    return this.close();
+                }
+                this.setAllLinses(response.data.result)
+            })
+        },
+        setAllLinses(res) {
+            this.allLines = res;
+            this.linesOption = this.allLines.filter((item, index, self) =>
+                index === self.findIndex((t) => t.line === item.line)
+            );
+            this.linesName = this.linesOption[0].line;
+            this.setEchartChange();
+        },
+        setEchartChange() {
+            zhangzitou_selectInfos({
+                line: this.linesName
+            }).then(response => {
+                if (response.data.code != 200) return
+                const result = response.data.result;
+
+                const objData = []
+                result.filter(item => {
+                    const type = mapData.dataStatistics[item.type];
+                    if (type) {
+                        item.type = type
+                    }
+                    objData.push({
+                        value: item.count, name: item.type
+                    })
+                })
+                this.setEchartShow(objData)
+            })
+
+        },
+
+        setEchartShow(res) {
+
+            let option = {
+                title: {
+
+                    left: 'center'
+                },
+                tooltip: {
+                    trigger: 'item'
+                },
+                legend: {
+                    orient: 'vertical',
+                    left: 'left'
+                },
+                series: [
+                    {
+                        name: this.linesName,
+                        type: 'pie',
+                        radius: '50%',
+                        data: res,
+                        emphasis: {
+                            itemStyle: {
+                                shadowBlur: 10,
+                                shadowOffsetX: 0,
+                                shadowColor: 'rgba(0, 0, 0, 0.5)'
+                            }
+                        }
+                    }
+                ]
+            };
+            if (!this.myChart) {
+
+                this.myChart = echarts.init(document.getElementById("myEchart"));
+            }
+
+
+            this.myChart.setOption(option);
+            window.addEventListener("resize", () => {
+                this.myChart.resize();
+            });
+        },
+    },
+};
+</script>
+
+<style lang="scss" scoped>
+.menuBox1 {
+    position: relative;
+    height: 100%;
+    width: calc(100% - 0px);
+    padding: 10px;
+    display: flex;
+    flex-direction: column;
+
+    .serachContent {
+        display: flex;
+    }
+
+    .echartContent {
+        flex: 1;
+
+
+        .myChart {
+            margin-top: 10px;
+            width: 100%;
+            height: calc(100% - 10px);
+        }
+    }
+
+}
+</style>
diff --git a/src/views/visualization/bottomMenu.vue b/src/views/visualization/bottomMenu.vue
new file mode 100644
index 0000000..f8001ce
--- /dev/null
+++ b/src/views/visualization/bottomMenu.vue
@@ -0,0 +1,171 @@
+<template>
+    <div class="bottomMnu">
+        <div class="bottomBox">
+            <div class="menuButton" v-for="(i, k) in menuOption">
+                <el-popover popper-class="popover" placement="top" v-show="i.children && i.children.length > 0"
+                    width="100" trigger="click">
+                    <span slot="reference">{{ i.name }}</span>
+                    <div @click="setChildData(c)" class="popover__item" v-show="i.children && i.children.length > 0"
+                        v-for="(c, f) in i.children" c :title="c.name"> {{
+                            c.name.slice(0, 8) }}
+                    </div>
+                </el-popover>
+                <span @click="setChildData(i)" slot="reference" v-show="!i.children || i.children.length <= 0">{{ i.name }}</span>
+            </div>
+
+        </div>
+        <div class="bottomImage">
+            <img src="@/assets/images/Screen/bottombg.png" />
+        </div>
+
+    </div>
+</template>
+
+<script>
+export default {
+    data() {
+        return {
+            menuOption: [
+                {
+                    name: '閰嶇綉宸℃',
+                    children: [
+                        {
+                            id: 'a1',
+                            name: '鐭ヨ瘑鍥捐氨',
+                            pid: 's1',
+                        }
+                    ]
+                }, {
+                    name: '閰嶇綉杩愭',
+                    children: [{
+                        id: 'a1',
+                        name: '鏁版嵁缁熻',
+                        pid: 's2',
+                    }]
+                }, {
+                    name: '鐏惧绠$悊',
+                    children: [{
+                        id: 'a1',
+                        name: '鏁版嵁鍒嗘瀽',
+                        pid: 's3',
+                    }]
+                }, {
+                    name: '鏁板瓧绾挎崯',
+         
+                }
+            ],
+            visible: false
+
+        }
+    },
+    methods: {
+        setChildData(res) {
+            this.visible = false;
+            this.$emit('childData', res);
+        }
+    }
+}
+</script>
+
+<style lang="scss" scoped>
+.bottomMnu {
+    width: 100%;
+    height: 100%;
+    display: flex;
+    flex-direction: column;
+    justify-content: space-between;
+
+    .bottomBox {
+        flex: 1;
+        width: 100%;
+
+        display: flex;
+        justify-content: center;
+
+        .menuButton {
+            height: 36px;
+            width: 147px;
+            background: url(~@/assets/images/Screen/centerbtn.png);
+            background-size: 100% 100%;
+            background-repeat: no-repeat;
+            font-size: 16px;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            color: #fff;
+            font-weight: 600;
+            cursor: pointer;
+
+            &:hover {
+                background: url(~@/assets/images/Screen/centerbtnc.png);
+                background-size: 100% 100%;
+            }
+        }
+    }
+
+    .bottomImage {
+        width: 100%;
+        display: flex;
+        justify-content: center;
+
+        img {
+            width: 80%;
+            height: 50px;
+        }
+
+    }
+
+}
+</style>
+<style lang="scss">
+.popover {
+    display: flex;
+    justify-content: center;
+    width: 163px;
+    background: url(~@/assets/images/Screen/centerTooltipBg.png);
+    background-size: 100% 100%;
+    border: none;
+    padding-bottom: 0px;
+
+    &_list {
+        display: flex;
+        flex-direction: column;
+        width: 145px;
+        overflow-x: hidden;
+        align-items: center;
+
+    }
+
+    .popper__arrow {
+        display: none;
+    }
+
+    .popover-content {
+        height: auto !important;
+    }
+
+    .popover__item {
+        margin-bottom: 12px;
+        color: #fff;
+        width: 130px;
+        height: 30px;
+        line-height: 30px;
+        text-align: center;
+        background: url(~@/assets/images/Screen/btnbg.png);
+        background-size: 100% 100%;
+
+
+    }
+
+    .popover__item:hover {
+        background: url(~@/assets/images/Screen/btnc.png);
+        background-size: 100% 100%;
+    }
+}
+
+.elpopover {
+    .popover {
+        display: none !important;
+    }
+}
+</style>
\ No newline at end of file
diff --git a/src/views/visualization/index.vue b/src/views/visualization/index.vue
new file mode 100644
index 0000000..d54d49d
--- /dev/null
+++ b/src/views/visualization/index.vue
@@ -0,0 +1,164 @@
+<template>
+    <div class="visualization">
+        <div class="title"></div>
+        <mapView></mapView>
+        <div class="leftMenu">
+            <left-menu></left-menu>
+        </div>
+        <div class="rightMenu">
+            <right-menu></right-menu>
+        </div>
+        <div class="bottomMenu">
+            <bottomMenu @childData="childData"></bottomMenu>
+        </div>
+        <div class="visualInfo" v-show="showInfo">
+            <div class="infotitle">
+                <div class="titleInfo">
+                    {{ isShow }}
+                </div>
+                <div @click="setInfoClose" class="titleInfo">
+                    X
+                </div>
+            </div>
+            <div class="infobox">
+                <div class="infoContent">
+                    <atlas v-if="isShow == '鐭ヨ瘑鍥捐氨'"></atlas>
+                    <analysis v-if="isShow == '鏁版嵁鍒嗘瀽'"></analysis>
+                    <statistics v-if="isShow == '鏁版嵁缁熻'"></statistics>
+                    <line-loss v-if="isShow == '鏁板瓧绾挎崯'"></line-loss>
+                </div>
+
+            </div>
+        </div>
+    </div>
+</template>
+
+<script>
+import mapView from './mapView.vue';
+import leftMenu from './leftMenu.vue';
+import rightMenu from './rightMenu.vue';
+import bottomMenu from './bottomMenu.vue';
+import atlas from '@/views/visual/atlas/index.vue'
+import analysis from '@/views/visual/analysis/index.vue'
+import lineLoss from './lineLoss.vue';
+import statistics from '@/views/visual/statistics/index.vue'
+export default {
+    components: {
+        mapView, leftMenu,
+        rightMenu, bottomMenu, atlas, analysis, statistics, lineLoss
+    },
+    data() {
+        return {
+            isShow: null,
+            showInfo: false
+        }
+    },
+    mounted() {
+    },
+    methods: {
+        childData(res) {
+            if (!res) return
+            this.showInfo = true;
+            this.$nextTick(() => {
+                this.isShow = res.name
+            })
+
+        },
+        setInfoClose() {
+            this.showInfo = false;
+            this.isShow = null;
+        },
+    }
+}
+</script>
+
+<style lang="scss" scoped>
+.visualization {
+    width: 100%;
+    height: 100%;
+
+    .title {
+        height: 86px;
+        width: 100%;
+        z-index: 40;
+        background: url(~@/assets/images/Screen/logobg.png);
+        background-size: 100% 100%;
+        background-repeat: no-repeat;
+        position: absolute;
+    }
+
+    .leftMenu {
+        width: 15%;
+        top: 90px;
+        left: 10px;
+        height: calc(100% - 180px);
+        z-index: 40;
+        position: absolute;
+    }
+
+    .rightMenu {
+        width: 15%;
+        top: 90px;
+        right: 10px;
+        height: calc(100% - 180px);
+        z-index: 40;
+        position: absolute;
+    }
+
+    .bottomMenu {
+        width: 100%;
+        height: 90px;
+        z-index: 40;
+        position: absolute;
+        bottom: 0px;
+    }
+
+    .visualInfo {
+        width: 60%;
+        height: 60%;
+        z-index: 50;
+        position: absolute;
+        left: 50%;
+        top: 50%;
+        transform: translate(-50%, -50%);
+        background: url(~@/assets/images/Screen/chartbg.png)no-repeat;
+        background-size: 100% 100%;
+        display: flex;
+
+        flex-direction: column;
+
+        .infotitle {
+            height: 12%;
+            display: flex;
+            justify-content: space-between;
+
+            .titleInfo {
+                color: white;
+                font-size: 24px;
+                font-weight: bolder;
+                height: 100%;
+                display: flex;
+                align-items: center;
+                margin-left: 8%;
+                margin-right: 3%;
+            }
+
+        }
+
+        .infobox {
+            flex: 1;
+
+            .infoContent {
+                width: 100%;
+                height: 100%;
+                position: relative;
+            }
+        }
+    }
+}
+</style>
+<style>
+::v-deep.map-info-bar {
+    display: none;
+}
+</style>
\ No newline at end of file
diff --git a/src/views/visualization/leftMenu.vue b/src/views/visualization/leftMenu.vue
new file mode 100644
index 0000000..668da82
--- /dev/null
+++ b/src/views/visualization/leftMenu.vue
@@ -0,0 +1,60 @@
+<template>
+    <div class="leftMnu">
+        <div class="menuBox">
+            <div class="aside-title">{{ title.t1 }}</div>
+        </div>
+        <div class="menuBox">
+            <div class="aside-title">{{ title.t2 }}</div>
+        </div>
+        <div class="menuBox">
+            <div class="aside-title">{{ title.t3 }}</div>
+        </div>
+    </div>
+</template>
+
+<script>
+export default {
+    data() {
+        return {
+            title: {
+                t1: 'xxx',
+                t2: 'XXXX',
+                t3: 'xxxxx'
+            }
+        }
+    }
+}
+</script>
+
+<style lang="scss" scoped>
+.leftMnu {
+    height: 100%;
+    width: 100%;
+    display: flex;
+    flex-direction: column;
+    justify-content: space-between;
+
+    .menuBox {
+        width: 100%;
+        height: 33%;
+        background: url(~@/assets/images/Screen/chartbg.png);
+        background-size: 100% 100%;
+        background-repeat: no-repeat;
+
+        .aside-title {
+            box-sizing: border-box;
+            padding-left: 30px;
+
+            font-size: 15px;
+            font-family: YouSheBiaoTiHei, YouSheBiaoTiHei-Regular;
+            color: #fff;
+            width: 100%;
+            height: 45px;
+            line-height: 45px;
+            // background: url(~@/assets/images/Screen/asideTitleBg.png);
+            background-size: 100% 100%;
+            background-repeat: no-repeat;
+        }
+    }
+}
+</style>
\ No newline at end of file
diff --git a/src/views/visualization/lineLoss.vue b/src/views/visualization/lineLoss.vue
new file mode 100644
index 0000000..5d656ce
--- /dev/null
+++ b/src/views/visualization/lineLoss.vue
@@ -0,0 +1,37 @@
+<template>
+    <div class="lineLossBox">
+        <el-image style="width: 100%; height:100%" :src="imgUrl" :preview-src-list="[imgUrl]">
+        </el-image>
+    </div>
+</template>
+
+<script>
+import { py_arima } from '@/api/mapView/map.js';
+export default {
+    data() {
+        return {
+            imgUrl: null,
+        }
+    },
+    mounted() {
+        this.initPyArima();
+    },
+    methods: {
+        initPyArima() {
+            py_arima().then(response => {
+                if (response.status != 200) return
+                this.imgUrl = config.pyServices + '/image?file_name=' + response.data.image1
+
+            })
+        }
+    }
+}
+</script>
+
+<style lang="scss" scoped>
+.lineLossBox {
+    width: 100%;
+    height: 100%;
+    padding:10px;
+}
+</style>
\ No newline at end of file
diff --git a/src/views/visualization/mapView.vue b/src/views/visualization/mapView.vue
new file mode 100644
index 0000000..871e722
--- /dev/null
+++ b/src/views/visualization/mapView.vue
@@ -0,0 +1,112 @@
+<template>
+    <div id="mapContainer" class="mapContainer">
+
+    </div>
+</template>
+
+<script>
+import mapServer from '@/assets/js/mapSdk/mapServe';
+import mapConfig from '@/assets/js/mapSdk/mapConfig';
+import mapData from '@/assets/js/mapSdk/mapData';
+import { layer_selectAll } from "@/api/mapView/map.js";
+export default {
+    name: 'mapView',
+    mounted() {
+        this.initMap();
+    },
+    methods: {
+        async initMap() {
+            window.earthCtrl = new SmartEarth.EarthCtrl('mapContainer', {
+                // 闅愯棌榛樿搴曞浘
+                defaultImagery: false,
+                // 闅愯棌logo
+                printLog: false,
+                // sceneMode: SmartEarth.Cesium.SceneMode.SCENE2D
+                StaticFileBaseUrl: '/CimSDK/',
+                navigationOption: {
+                    enableCompass: false,
+                    enableZoomControls: false,
+                    enableDistanceLegend: false,
+                    enableCompassOuterRing: false,
+                },
+
+            });
+
+            // 鍒濆鍖朇esium
+            window.Cesium = SmartEarth.Cesium;
+            // 鍒濆鍖朧iewer
+            window.Viewer = earthCtrl.viewer;
+            //璁剧疆鍦扮悆棰滆壊
+            Viewer.scene.globe.baseColor = Cesium.Color.fromCssColorString('#A9A9A9');
+            // 鍦板舰鍔犺浇
+            const terrain = config.terrain;
+            if (terrain.isShow && terrain.isUrl) {
+                const terrainProvider = await Cesium.CesiumTerrainProvider.fromUrl(terrain.isUrl, {
+                    requestWaterMask: true,
+                    requestVertexNormals: true,
+                });
+
+                Viewer.terrainProvider = terrainProvider;
+            }
+            // 榛樿璁剧疆搴曞浘
+            this.addImageLayer();
+        },
+        addImageLayer() {
+            const baseLayer = mapData.baseLayer;
+            // 娣诲姞澶╁湴鍥惧簳鍥�
+            mapServer.addLayer({
+                serveType: 'tdMap',
+                url: baseLayer.sUrl + baseLayer.vecLayer + baseLayer.lUrl,
+            });
+            // 娣诲姞澶╁湴鍥炬爣娉�
+            mapServer.addLayer({
+                serveType: 'tdMap',
+                url: baseLayer.sUrl + baseLayer.cvaLayer + baseLayer.lUrl,
+            });
+            // 鍒濆鍖栬瑙�
+            this.setdefaultPerspective();
+        },
+        setdefaultPerspective() {
+            mapConfig.sertCameraTo(mapData.defaultPerspective);
+            if (config.baseModel.url) {
+                mapServer.addLayer(config.baseModel);
+            }
+            this.getSelectLayers();
+
+
+        },
+        getSelectLayers() {
+            layer_selectAll().then(response => {
+                if (response.data.code != 200) return
+             
+                const val = response.data.result.filter(item => {
+     
+                    if (item.type == 2 && item.isShow == 1) {
+                
+                        mapServer.addLayer(item)
+                   
+                    }
+                    return item;
+                })
+              
+            })
+        },
+    }
+}
+</script>
+
+<style lang="scss" scoped>
+.mapContainer {
+    width: 100%;
+    height: 100%;
+}
+</style>
+<style>
+.map-info-bar {
+    display: none !important;
+}
+
+.el-form-item__label {
+    color: white
+}
+</style>
\ No newline at end of file
diff --git a/src/views/visualization/rightMenu.vue b/src/views/visualization/rightMenu.vue
new file mode 100644
index 0000000..f13926a
--- /dev/null
+++ b/src/views/visualization/rightMenu.vue
@@ -0,0 +1,248 @@
+<template>
+  <div class="rightMnu">
+    <div class="menuBox">
+      <div class="aside-title">{{ title.t1 }}</div>
+      <div class="echartBox">
+        <div id="rightEchart1" class="chartBox"></div>
+      </div>
+    </div>
+    <div class="menuBox">
+      <div class="aside-title">{{ title.t2 }}</div>
+      <div class="echartBox">
+        <div id="rightEchart2" class="chartBox"></div>
+      </div>
+    </div>
+    <div class="menuBox">
+      <div class="aside-title">{{ title.t3 }}</div>
+      <div class="echartBox">
+        <div id="rightEchart3" class="chartBox"></div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import * as echarts from 'echarts';
+
+export default {
+  data() {
+    return {
+      title: {
+        t1: 'xxx',
+        t2: 'XXXX',
+        t3: 'xxxxx'
+      }
+    }
+  },
+  mounted() {
+    this.initEchart();
+  },
+  methods: {
+    initEchart() {
+      this.initEchart1();
+      this.initEchart2();
+      this.initEchart3();
+    },
+    initEchart1() {
+      var myChart = echarts.init(document.getElementById('rightEchart1'));
+      var option = {
+        xAxis: {
+          type: 'category',
+          data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
+          axisLine: {
+            lineStyle: {
+              color: 'white' // 璁剧疆涓虹孩鑹�
+            }
+          }
+        },
+        yAxis: {
+          type: 'value',
+          axisLine: {
+            lineStyle: {
+              color: 'white' // 璁剧疆涓虹孩鑹�
+            }
+          }
+        },
+        series: [
+          {
+            data: [820, 932, 901, 934, 1290, 1330, 1320],
+            type: 'line',
+            smooth: true,
+            lineStyle: {
+              color: '#409EFF', // 鎶樼嚎棰滆壊
+
+            }
+          }
+        ]
+      };
+
+      option && myChart.setOption(option);
+
+    },
+
+    initEchart2() {
+      var myChart1 = echarts.init(document.getElementById('rightEchart2'));
+      var option1 = {
+        title: {
+
+          subtext: 'Fake Data',
+          left: 'center'
+        },
+        tooltip: {
+          trigger: 'item'
+        },
+        legend: {
+          orient: 'vertical',
+          left: 'left',
+          show: false
+        },
+        series: [
+          {
+            name: 'Access From',
+            type: 'pie',
+            radius: '50%',
+            data: [
+              { value: 1048, name: 'Search Engine' },
+              { value: 735, name: 'Direct' },
+              { value: 580, name: 'Email' },
+              { value: 484, name: 'Union Ads' },
+              { value: 300, name: 'Video Ads' }
+            ],
+            emphasis: {
+              itemStyle: {
+                shadowBlur: 10,
+                shadowOffsetX: 0,
+                shadowColor: 'rgba(0, 0, 0, 0.5)'
+              }
+            }
+          }
+        ]
+      };
+      option1 && myChart1.setOption(option1);
+    },
+    initEchart3() {
+      var myChart2 = echarts.init(document.getElementById('rightEchart3'));
+      // prettier-ignore
+      let dataAxis = ['鐐�', '鍑�', '鏌�', '瀛�',];
+      // prettier-ignore
+      let data = [220, 182, 191, 234, 290];
+      let yMax = 500;
+      let dataShadow = [];
+      for (let i = 0; i < data.length; i++) {
+        dataShadow.push(yMax);
+      }
+     var  option2 = {
+        title: {
+
+        },
+        xAxis: {
+          data: dataAxis,
+          axisTick: {
+            show: false
+          },
+          axisLine: {
+            show: false,
+            lineStyle: {
+              color: 'white' // 璁剧疆涓虹孩鑹�
+            }
+          },
+          z: 10
+        },
+        yAxis: {
+          axisLine: {
+            show: false,
+            lineStyle: {
+              color: 'white' // 璁剧疆涓虹孩鑹�
+            }
+          },
+          axisTick: {
+            show: false
+          },
+          axisLabel: {
+            color: '#fff'
+          },
+          
+        },
+        dataZoom: [
+          {
+            type: 'inside'
+          }
+        ],
+        series: [
+          {
+            type: 'bar',
+            showBackground: true,
+            itemStyle: {
+              color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+                { offset: 0, color: '#83bff6' },
+                { offset: 0.5, color: '#188df0' },
+                { offset: 1, color: '#188df0' }
+              ])
+            },
+            emphasis: {
+              itemStyle: {
+                color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+                  { offset: 0, color: '#2378f7' },
+                  { offset: 0.7, color: '#2378f7' },
+                  { offset: 1, color: '#83bff6' }
+                ])
+              }
+            },
+            data: data
+          }
+        ]
+      };
+      option2 && myChart2.setOption(option2);
+    }
+
+
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.rightMnu {
+  height: 100%;
+  width: 100%;
+  display: flex;
+  flex-direction: column;
+  justify-content: space-between;
+
+  .menuBox {
+    width: 100%;
+    height: 33%;
+    background: url(~@/assets/images/Screen/chartbg.png);
+    background-size: 100% 100%;
+    background-repeat: no-repeat;
+    display: flex;
+    flex-direction: column;
+  }
+
+  .aside-title {
+    box-sizing: border-box;
+    padding-left: 30px;
+    font-size: 15px;
+    font-family: YouSheBiaoTiHei, YouSheBiaoTiHei-Regular;
+    color: #fff;
+    width: 100%;
+    height: 45px;
+    line-height: 45px;
+    // background: url(~@/assets/images/Screen/asideTitleBg.png);
+    background-size: 100% 100%;
+    background-repeat: no-repeat;
+  }
+
+  .echartBox {
+    flex: 1;
+    padding: 5px;
+    position: relative;
+
+    .chartBox {
+      width: calc(100% - 10px);
+      height: calc(100% - 10px);
+
+      position: absolute;
+    }
+  }
+}
+</style>
\ No newline at end of file

--
Gitblit v1.9.3