Просмотр исходного кода

Merge branch 'master' of http://47.103.92.60:3003/skyversation/qp_onemap_ui

ximinghao 5 месяцев назад
Родитель
Сommit
8f825fafd9
85 измененных файлов с 7020 добавлено и 1874 удалено
  1. 12 1
      README.md
  2. 1 238
      package-lock.json
  3. 2 1
      package.json
  4. 37 1
      public/index.html
  5. 128 3
      public/static/config/config.js
  6. 146 21
      public/static/css/reset.css
  7. BIN
      public/static/images/point.png
  8. BIN
      public/static/images/skmh-1.png
  9. BIN
      public/static/images/skmh-2.png
  10. BIN
      public/static/images/skmh-3.png
  11. BIN
      public/static/images/sksjgl/sjzljc/影像数据一致性检查工具.png
  12. BIN
      public/static/images/sksjgl/sjzljc/矢量数据语义一致性检查工具.png
  13. BIN
      public/static/images/sksjgl/sjzljc/矢量数据逻辑一致性检查工具.png
  14. BIN
      public/static/images/sksjgl/sjzljc/矢量数据重复项检查工具.png
  15. BIN
      public/static/images/sksjgl/sksjfb/动态地图服务发布.png
  16. BIN
      public/static/images/sksjgl/sksjfb/栅格服务发布.png
  17. BIN
      public/static/images/sksjgl/sksjfb/矢量服务发布.png
  18. BIN
      public/static/images/sksjgl/sksjgl/栅格定制任务管理.png
  19. BIN
      public/static/images/sksjgl/sksjgl/栅格瓦片产品管理.png
  20. BIN
      public/static/images/sksjgl/sksjgl/栅格瓦片服务管理.png
  21. BIN
      public/static/images/sksjgl/sksjgl/矢量瓦片集管理.png
  22. BIN
      public/static/images/sksjgl/sksjgl_title.png
  23. BIN
      public/static/images/sksjgl/sksjjg/地图字体管理.png
  24. BIN
      public/static/images/sksjgl/sksjjg/地图样式符号管理.png
  25. BIN
      public/static/images/sksjgl/sksjjg/栅格数据坐标系统转换工具.png
  26. BIN
      public/static/images/sksjgl/sksjjg/栅格数据投影转换工具.png
  27. BIN
      public/static/images/sksjgl/sksjjg/栅格数据格式转换工具.png
  28. BIN
      public/static/images/sksjgl/sksjjg/栅格数据裁切工具.png
  29. BIN
      public/static/images/sksjgl/sksjjg/正射影像数据瓦片定制.png
  30. BIN
      public/static/images/sksjgl/sksjjg/矢量数据坐标系统转换工具.png
  31. BIN
      public/static/images/sksjgl/sksjjg/矢量数据投影转换工具.png
  32. BIN
      public/static/images/sksjgl/sksjjg/矢量数据格式转换工具.png
  33. BIN
      public/static/images/sksjgl/sksjjg/矢量瓦片定制.png
  34. BIN
      public/static/images/u30.png
  35. BIN
      public/static/images/wgn_title.png
  36. 8 36
      src/App.vue
  37. 12 0
      src/api/sksjgl.js
  38. 0 0
      src/api/skszk.js
  39. 16 0
      src/api/wgn.js
  40. 0 0
      src/api/xxfk.js
  41. BIN
      src/assets/images/sksjgl/jiantou.png
  42. BIN
      src/assets/images/sksjgl/sjzljc.png
  43. BIN
      src/assets/images/sksjgl/sksjfb.png
  44. BIN
      src/assets/images/sksjgl/sksjgl.png
  45. BIN
      src/assets/images/sksjgl/sksjjg.png
  46. 3 1
      src/components/AppVue/Footer.vue
  47. 36 32
      src/components/AppVue/Header.vue
  48. 1604 0
      src/components/wgn/controlPanel.vue
  49. 139 0
      src/components/yxgl/EchartsDome.vue
  50. 93 0
      src/components/yxgl/card.vue
  51. 8 4
      src/main.js
  52. 0 60
      src/router/index-old.js
  53. 130 97
      src/router/index.js
  54. 1 2
      src/store/index.js
  55. 21 0
      src/utils/request.js
  56. 0 157
      src/views-old/Application.vue
  57. 0 19
      src/views-old/Data.vue
  58. 0 135
      src/views-old/Development.vue
  59. 0 19
      src/views-old/Display.vue
  60. 0 28
      src/views-old/Function.vue
  61. 0 791
      src/views-old/HomePage.vue
  62. 0 19
      src/views-old/OAMC.vue
  63. 0 32
      src/views/Example.vue
  64. 17 12
      src/views/HomePage.vue
  65. 60 0
      src/views/Root.vue
  66. 371 0
      src/views/Sksjgl.vue
  67. 0 31
      src/views/Skszk.vue
  68. 274 15
      src/views/Wgn.vue
  69. 0 31
      src/views/Xxfk.vue
  70. 79 16
      src/views/Yxgl.vue
  71. 1 1
      src/views/example/Example.vue
  72. 1075 0
      src/views/skmh/index.vue
  73. 110 0
      src/views/skmh/scene/index.vue
  74. 6 2
      src/views/sksjgl/Example.vue
  75. 0 27
      src/views/skszk/Example.vue
  76. 91 15
      src/views/wgn/Example.vue
  77. 490 0
      src/views/wgn/sksj/index.vue
  78. 0 27
      src/views/xxfk/Example.vue
  79. 243 0
      src/views/yxgl/StatisticalAnalysis.vue
  80. 116 0
      src/views/yygl/appCenter.vue
  81. 292 0
      src/views/yygl/index.vue
  82. 500 0
      src/views/yygl/manage/index.vue
  83. 493 0
      src/views/yygl/monitor/index.vue
  84. 398 0
      src/views/yygl/overview/index.vue
  85. 7 0
      vue.config.js

+ 12 - 1
README.md

@@ -77,4 +77,15 @@ loadScripts函数传入参数类型为Aarry,Aarry的值为需要当前地图
 
 config.js中更新各模块引入插件包的数据组织方式
 
-相应修改可见 src/views/example/Map.vue 示例
+相应修改可见 src/views/example/Map.vue 示例
+
+# 更新
+## 0.0.2
+移除 xxfk 文件夹
+
+### 业务模块对应关系
+sksjgl  时空数据管理
+skmh    时空门户
+wgn     微功能
+yygl    应用管理
+yxgl    运行管理

Разница между файлами не показана из-за своего большого размера
+ 1 - 238
package-lock.json


+ 2 - 1
package.json

@@ -12,6 +12,7 @@
     "echarts": "^5.6.0",
     "element-plus": "^2.2.15",
     "vue": "^3.2.13",
+    "vue-json-viewer": "^3.0.4",
     "vue-router": "^4.0.3",
     "vue3-lottie": "^3.3.1",
     "vuex": "^4.0.0"
@@ -30,4 +31,4 @@
     "not dead",
     "not ie 11"
   ]
-}
+}

+ 37 - 1
public/index.html

@@ -1,5 +1,5 @@
 <!DOCTYPE html>
-<html lang="">
+<html lang="" class="dark">
 
 <head>
   <meta charset="utf-8">
@@ -26,4 +26,40 @@
   <!-- built files will be auto injected -->
 </body>
 
+<style>
+    :root {
+      /* 滚动条整体部分,必须要设置 */
+      ::-webkit-scrollbar {
+        width: 6px;
+        height: 10px;
+        overflow-y: overlay;
+      }
+
+      /* 滚动条里面轨道,能向上向下移动 */
+      ::-webkit-scrollbar-track {
+        background-color: transparent;
+      }
+
+      /* 滚动条里面轨道,能向上向下移动 */
+      ::-webkit-scrollbar-track-piece {
+        background-color: transparent;
+      }
+
+      ::-webkit-scrollbar-thumb {
+        display: none;
+        border-radius: 6px;
+      }
+
+      /* 滚动条里面的小方块,能向上向下移动 */
+      *:hover::-webkit-scrollbar-thumb {
+        display: flex;
+        background-color: rgb(163, 166, 173, 0.5);
+        border-radius: 6px;
+      }
+
+      *:hover::-webkit-scrollbar-track-piece {
+        background-color: rgb(209, 207, 207,0);
+      }
+    }
+  </style>
 </html>

+ 128 - 3
public/static/config/config.js

@@ -4,6 +4,7 @@ let systemConfig = {
         userName: "user002",
         password: "Yysz@1234002"
     },
+    baseServicerPath: "/oneMap",
     // oauth地址
     oauthServiceUrlOrigin: "http://121.43.55.7:10086/",
     // oauth地址
@@ -13,16 +14,140 @@ let systemConfig = {
     // 引擎基础js
     scriptMain: "/static/plugins/skyscenery/SkyScenery.js",
 
+    GEOSERVER_URL_WMS: "http://121.43.55.7:8889/geoserver/kdyjs/wms",
+    GEOSERVER_URL_WFS: "http://121.43.55.7:8889/geoserver/kdyjs/wfs",
+    TDT_URL: "https://{s}.tianditu.gov.cn/",
     /* 以下为各模块定义各自全局变量的位置,包括 example 示例 */
     example: {
         scriptArr: [
-            "/static/plugins/skyscenery/plugins/CGCS2000ArcGisMapServerImageryProvider.js"
+            "/static/plugins/skyscenery/plugins/CGCS2000ArcGisMapServerImageryProvider.js",
+            "/static/plugins/skyscenery/plugins/3DTiles/add3DTiles.js"
         ]
     },
-    skszk: {},
+    sksjgl: {
+        funcList: {
+            sjzljc: [
+                {
+                    label: "矢量数据重复项检查工具",
+                    url: "http://47.103.92.60:1202/",
+                    image: "./static/images/sksjgl/sjzljc/矢量数据重复项检查工具.png"
+                },
+                {
+                    label: "矢量数据逻辑一致性检查工具",
+                    url: "http://47.103.92.60:1202/",
+                    image: "./static/images/sksjgl/sjzljc/矢量数据逻辑一致性检查工具.png"
+                },
+                {
+                    label: "矢量数据语义一致性检查工具",
+                    url: "http://47.103.92.60:1202/",
+                    image: "./static/images/sksjgl/sjzljc/矢量数据语义一致性检查工具.png"
+                },
+                {
+                    label: "影像数据一致性检查工具",
+                    url: "http://47.103.92.60:1202/",
+                    image: "./static/images/sksjgl/sjzljc/影像数据一致性检查工具.png"
+                },
+            ],
+            sksjjg: [
+                {
+                    label: "矢量数据格式转换工具",
+                    url: "http://47.103.92.60:1202/",
+                    image: "./static/images/sksjgl/sksjjg/矢量数据格式转换工具.png"
+                },
+                {
+                    label: "矢量数据投影转换工具",
+                    url: "http://47.103.92.60:1202/",
+                    image: "./static/images/sksjgl/sksjjg/矢量数据投影转换工具.png"
+                },
+                {
+                    label: "矢量数据坐标系统转换工具",
+                    url: "http://47.103.92.60:1202/",
+                    image: "./static/images/sksjgl/sksjjg/矢量数据坐标系统转换工具.png"
+                },
+                {
+                    label: "矢量瓦片定制",
+                    url: "http://47.103.92.60:1203/#/sliceMana",
+                    image: "./static/images/sksjgl/sksjjg/矢量瓦片定制.png"
+                },
+                {
+                    label: "地图样式符号管理",
+                    url: "http://47.103.92.60:1203/#/iconMana/icon",
+                    image: "./static/images/sksjgl/sksjjg/地图样式符号管理.png"
+                },
+                {
+                    label: "地图字体管理",
+                    url: "http://47.103.92.60:1203/#/fontsets",
+                    image: "./static/images/sksjgl/sksjjg/地图字体管理.png"
+                },
+                {
+                    label: "栅格数据格式转换工具",
+                    url: "http://47.103.92.60:1202/",
+                    image: "./static/images/sksjgl/sksjjg/栅格数据格式转换工具.png"
+                },
+                {
+                    label: "栅格数据坐标系统转换工具",
+                    url: "http://47.103.92.60:1202/",
+                    image: "./static/images/sksjgl/sksjjg/栅格数据坐标系统转换工具.png"
+                },
+                {
+                    label: "栅格数据投影转换工具",
+                    url: "http://47.103.92.60:1202/",
+                    image: "./static/images/sksjgl/sksjjg/栅格数据投影转换工具.png"
+                },
+                {
+                    label: "栅格数据裁切工具",
+                    url: "http://47.103.92.60:1202/",
+                    image: "./static/images/sksjgl/sksjjg/栅格数据裁切工具.png"
+                },
+                {
+                    label: "正射影像数据瓦片定制",
+                    url: "http://47.103.92.60:1204/",
+                    image: "./static/images/sksjgl/sksjjg/正射影像数据瓦片定制.png"
+                },
+            ],
+            sksjgl: [
+                {
+                    label: "矢量瓦片集管理",
+                    url: "http://47.103.92.60:1203/#/tileMana",
+                    image: "./static/images/sksjgl/sksjgl/矢量瓦片集管理.png"
+                },
+                {
+                    label: "栅格定制任务管理",
+                    url: "http://47.103.92.60:1204/",
+                    image: "./static/images/sksjgl/sksjgl/栅格定制任务管理.png"
+                },
+                {
+                    label: "栅格瓦片产品管理",
+                    url: "http://47.103.92.60:1204/",
+                    image: "./static/images/sksjgl/sksjgl/栅格瓦片产品管理.png"
+                },
+                {
+                    label: "栅格瓦片服务管理",
+                    url: "http://47.103.92.60:1204/",
+                    image: "./static/images/sksjgl/sksjgl/栅格瓦片服务管理.png"
+                }
+            ],
+            sksjfb: [
+                {
+                    label: "栅格服务发布",
+                    url: "http://10.235.245.174:2024/?token=1",
+                    image: "./static/images/sksjgl/sksjfb/栅格服务发布.png"
+                },
+                {
+                    label: "矢量服务发布",
+                    url: "http://10.235.245.174:2024/?token=1",
+                    image: "./static/images/sksjgl/sksjfb/矢量服务发布.png"
+                },
+                {
+                    label: "动态地图服务发布",
+                    url: "http://10.235.245.174:2024/?token=1",
+                    image: "./static/images/sksjgl/sksjfb/动态地图服务发布.png"
+                },
+            ],
+        }
+    },
     skmh: {},
     wgn: {},
     yygl: {},
-    xxfk: {},
     yxgl: {}
 }

+ 146 - 21
public/static/css/reset.css

@@ -1,25 +1,150 @@
 /* reset */
-html,body,h1,h2,h3,h4,h5,h6,div,dl,dt,dd,ul,ol,li,p,blockquote,pre,hr,figure,table,caption,th,td,form,fieldset,legend,input,button,textarea,menu{margin:0;padding:0;}
-header,footer,section,article,aside,nav,hgroup,address,figure,figcaption,menu,details{display:block;}
-html,body{overflow: hidden;}
-table{border-collapse:collapse;border-spacing:0;}
-caption,th{text-align:left;font-weight:normal;}
-html,body,fieldset,img,iframe,abbr{border:0;}
-i,cite,em,var,address,dfn{font-style:normal;}
-[hidefocus],summary{outline:0;}
-li{list-style:none;}
-h1,h2,h3,h4,h5,h6,small{font-size:100%;}
-sup,sub{font-size:83%;}
-pre,code,kbd,samp{font-family:inherit;}
-q:before,q:after{content:none;}
-textarea{overflow:auto;resize:none;}
-label,summary{cursor:default;}
-a,button{cursor:pointer;}
-h1,h2,h3,h4,h5,h6,em,strong,b{font-weight:bold;}
-del,ins,u,s,a,a:hover{text-decoration:none;}
+html,
+body,
+h1,
+h2,
+h3,
+h4,
+h5,
+h6,
+div,
+dl,
+dt,
+dd,
+ul,
+ol,
+li,
+p,
+blockquote,
+pre,
+hr,
+figure,
+table,
+caption,
+th,
+td,
+form,
+fieldset,
+legend,
+input,
+button,
+textarea,
+menu {
+  margin: 0;
+  padding: 0;
+}
+header,
+footer,
+section,
+article,
+aside,
+nav,
+hgroup,
+address,
+figure,
+figcaption,
+menu,
+details {
+  display: block;
+}
+html,
+body {
+  overflow: hidden;
+}
+table {
+  border-collapse: collapse;
+  border-spacing: 0;
+}
+caption,
+th {
+  text-align: left;
+  font-weight: normal;
+}
+html,
+body,
+fieldset,
+img,
+iframe,
+abbr {
+  border: 0;
+}
+i,
+cite,
+em,
+var,
+address,
+dfn {
+  font-style: normal;
+}
+[hidefocus],
+summary {
+  outline: 0;
+}
+li {
+  list-style: none;
+}
+h1,
+h2,
+h3,
+h4,
+h5,
+h6,
+small {
+  font-size: 100%;
+}
+sup,
+sub {
+  font-size: 83%;
+}
+pre,
+code,
+kbd,
+samp {
+  font-family: inherit;
+}
+q:before,
+q:after {
+  content: none;
+}
+textarea {
+  overflow: auto;
+  resize: none;
+}
+label,
+summary {
+  cursor: default;
+}
+a,
+button {
+  cursor: pointer;
+}
+h1,
+h2,
+h3,
+h4,
+h5,
+h6,
+em,
+strong,
+b {
+  font-weight: bold;
+}
+del,
+ins,
+u,
+s,
+a,
+a:hover {
+  text-decoration: none;
+}
 /* body,textarea,input,button,select,keygen,legend{font:12px/1.14 arial,\5b8b\4f53;color:#000000;outline:0;} */
-body{background:#fff;}
-a,a:hover{color:#333;}
+body {
+  background: #fff;
+}
+a,
+a:hover {
+  color: #333;
+}
 
 /* 滚动条样式 */
 /* ::-webkit-scrollbar {
@@ -35,4 +160,4 @@ a,a:hover{color:#333;}
 ::-webkit-scrollbar-track {
     border-radius: 10px;
     background: #eeeeee;
-} */
+} */

BIN
public/static/images/point.png


BIN
public/static/images/skmh-1.png


BIN
public/static/images/skmh-2.png


BIN
public/static/images/skmh-3.png


BIN
public/static/images/sksjgl/sjzljc/影像数据一致性检查工具.png


BIN
public/static/images/sksjgl/sjzljc/矢量数据语义一致性检查工具.png


BIN
public/static/images/sksjgl/sjzljc/矢量数据逻辑一致性检查工具.png


BIN
public/static/images/sksjgl/sjzljc/矢量数据重复项检查工具.png


BIN
public/static/images/sksjgl/sksjfb/动态地图服务发布.png


BIN
public/static/images/sksjgl/sksjfb/栅格服务发布.png


BIN
public/static/images/sksjgl/sksjfb/矢量服务发布.png


BIN
public/static/images/sksjgl/sksjgl/栅格定制任务管理.png


BIN
public/static/images/sksjgl/sksjgl/栅格瓦片产品管理.png


BIN
public/static/images/sksjgl/sksjgl/栅格瓦片服务管理.png


BIN
public/static/images/sksjgl/sksjgl/矢量瓦片集管理.png


BIN
public/static/images/sksjgl/sksjgl_title.png


BIN
public/static/images/sksjgl/sksjjg/地图字体管理.png


BIN
public/static/images/sksjgl/sksjjg/地图样式符号管理.png


BIN
public/static/images/sksjgl/sksjjg/栅格数据坐标系统转换工具.png


BIN
public/static/images/sksjgl/sksjjg/栅格数据投影转换工具.png


BIN
public/static/images/sksjgl/sksjjg/栅格数据格式转换工具.png


BIN
public/static/images/sksjgl/sksjjg/栅格数据裁切工具.png


BIN
public/static/images/sksjgl/sksjjg/正射影像数据瓦片定制.png


BIN
public/static/images/sksjgl/sksjjg/矢量数据坐标系统转换工具.png


BIN
public/static/images/sksjgl/sksjjg/矢量数据投影转换工具.png


BIN
public/static/images/sksjgl/sksjjg/矢量数据格式转换工具.png


BIN
public/static/images/sksjgl/sksjjg/矢量瓦片定制.png


BIN
public/static/images/u30.png


BIN
public/static/images/wgn_title.png


+ 8 - 36
src/App.vue

@@ -1,14 +1,7 @@
 <template>
-  <div class="main">
-    <!-- <Header @scroll-update="scrollUpdate"></Header> -->
-    <el-scrollbar ref="pagescrollbar" view-style="height:100%">
-      <router-view />
-      <!-- <Footer></Footer> -->
-    </el-scrollbar>
-  </div>
+  <router-view />
 </template>
 <script>
-import { defineAsyncComponent } from "vue";
 import api from "@/api/common";
 export default {
   name: "App",
@@ -17,12 +10,6 @@ export default {
       loadedScripts: [],
     }
   },
-  components: {
-    Header: defineAsyncComponent(() =>
-      import("@/components/AppVue/Header.vue")
-    ),
-    Footer: defineAsyncComponent(() => import("@/components/AppVue/Footer.vue"))
-  },
   mounted() {
     let that = this;
     window.loadScripts = this.loadScripts
@@ -60,18 +47,19 @@ export default {
     });
   },
   methods: {
-    scrollUpdate() {
-      let that = this;
-      setTimeout(() => {
-        that.$refs.pagescrollbar.update();
-      }, 1000);
-    },
+    // scrollUpdate() {
+    //   let that = this;
+    //   setTimeout(() => {
+    //     that.$refs.pagescrollbar.update();
+    //   }, 1000);
+    // },
     getScale() {
       const ww = window.innerWidth / 1920
       // const wh = window.innerHeight / 945
       // return ww < wh ? ww : wh;
       return ww
     },
+
     initScript() {
       let that = this;
       window.SkySceneryConfig = {
@@ -154,8 +142,6 @@ html {
 }
 
 #app {
-  // width: 100vw;
-  // height: 100vw;
   width: 1920px;
   height: 100%;
   position: fixed;
@@ -164,18 +150,4 @@ html {
   transform-origin: left top;
   transform: translate(-50%, 0%);
 }
-
-.main {
-  width: 100%;
-  height: 100%;
-  margin: 0 auto;
-  overflow: hidden;
-
-  .el-scrollbar {
-    width: 100%;
-    // height: calc(100% - 90px);
-    box-sizing: border-box;
-    overflow: hidden;
-  }
-}
 </style>

+ 12 - 0
src/api/sksjgl.js

@@ -0,0 +1,12 @@
+import {
+    postBody
+} from '../utils/request'
+
+// 拓扑计算
+const topology = (url, params) => {
+    return postBody(systemConfig.baseServicerPath + url, params)
+}
+
+export default {
+    topology,
+}

+ 0 - 0
src/api/skszk.js


+ 16 - 0
src/api/wgn.js

@@ -0,0 +1,16 @@
+import {
+    postform,
+    postBody
+} from '../utils/request'
+
+const getDmsData = (params) => {
+    return postform(systemConfig.dmsDataProxy + "/content/selectContentList", params)
+}
+
+const topology = (url, params) => {
+    return postBody(systemConfig.baseServicerPath + url, params)
+}
+export default {
+    getDmsData,
+    topology,
+}

+ 0 - 0
src/api/xxfk.js


BIN
src/assets/images/sksjgl/jiantou.png


BIN
src/assets/images/sksjgl/sjzljc.png


BIN
src/assets/images/sksjgl/sksjfb.png


BIN
src/assets/images/sksjgl/sksjgl.png


BIN
src/assets/images/sksjgl/sksjjg.png


+ 3 - 1
src/components/AppVue/Footer.vue

@@ -8,7 +8,7 @@ export default {};
 
 <style lang="less" scoped>
 .footer {
-  width: 1920px;
+  width: 100%;
   box-sizing: border-box;
   text-align: center;
   background: rgba(17, 16, 16, 1);
@@ -16,5 +16,7 @@ export default {};
   height: 50px;
   line-height: 50px;
   margin: 0 auto;
+  position: absolute;
+  bottom: 0px;
 }
 </style>

+ 36 - 32
src/components/AppVue/Header.vue

@@ -3,36 +3,34 @@
     <div class="logo">青浦一张图</div>
     <div class="menu">
       <ul class="menu_ul">
-        <li
-          v-for="(item,index) in menuList"
-          :key="index"
-          :class="{'active':item.isActive}"
-          @click="menuClick(item.index,$event)"
-        >{{ item.label }}</li>
+        <li v-for="(item, index) in menuList" :key="index" :class="{ active: item.isActive }"
+          @click="menuClick(item.index, $event)">
+          {{ item.label }}
+        </li>
       </ul>
     </div>
   </div>
 </template>
 
 <script>
-import { toRaw } from "vue";
 export default {
   data() {
     return {
       menuList: [
         { index: 1, label: "首页", isActive: true },
-        { index: 2, label: "数据中心", isActive: false },
-        { index: 3, label: "应用中心", isActive: false },
-        { index: 4, label: "微功能中心", isActive: false },
-        { index: 5, label: "开发中心", isActive: false },
-        { index: 6, label: "运管中心", isActive: false },
-        { index: 7, label: "综合展示", isActive: false }
-      ]
+        { index: 2, label: "时空数据管理", isActive: false },
+        { index: 3, label: "二维GIS引擎", isActive: false },
+        { index: 4, label: "时空门户", isActive: false },
+        { index: 5, label: "微功能", isActive: false },
+        { index: 6, label: "应用管理", isActive: false },
+        { index: 7, label: "运行管理", isActive: false },
+      ],
     };
   },
   methods: {
     menuClick(index) {
-      this.menuList.map(function(item) {
+      let that = this
+      this.menuList.map(function (item) {
         if (item.index == index) {
           item.isActive = true;
         } else {
@@ -45,28 +43,30 @@ export default {
           this.$router.push("/");
           break;
         case 2:
-          this.$router.push("/data");
+          this.$router.push("/sksjgl");
           break;
         case 3:
-          this.$router.push("/application");
+          // this.$router.push("/application");
+          this.$router.push("/skmh/scene");
           break;
         case 4:
-          this.$router.push("/function");
+          // this.$router.push("/function");
+          this.$router.push("/skmh");
           break;
         case 5:
-          this.$router.push("/development");
+          this.$router.push("/wgn");
           break;
         case 6:
-          this.$router.push("/oamc");
+          this.$router.push("/yygl");
           break;
         case 7:
-          this.$router.push("/display");
+          this.$router.push("/yxgl");
           break;
       }
       this.$nextTick(() => {
-        this.$emit("scroll-update");
+        this.$emit('updateScroll');
       });
-    }
+    },
     // addClass(element, className) {
     //   if (
     //     !new RegExp("(^|\\s)" + className + "(\\s|$)").test(element.className)
@@ -79,48 +79,52 @@ export default {
     //     ""
     //   );
     // }
-  }
+  },
 };
 </script>
 
 <style lang="less" scoped>
 #header {
   width: 1920px;
-  height: 90px;
+  height: 70px;
   background: linear-gradient(180deg, #2c2f74, #494d98);
   color: #ffffff;
   margin: 0 auto;
+
   .logo {
     display: inline-block;
-    height: 90px;
+    height: 70px;
     width: 200px;
     text-align: center;
-    line-height: 90px;
+    line-height: 70px;
     font-size: 24px;
   }
+
   .menu {
     display: inline-block;
     float: right;
+
     .menu_ul {
       li {
         display: inline-block;
         height: 50px;
-        width: 150px;
+        width: fit-content;
         line-height: 50px;
         text-align: center;
         cursor: pointer;
-        margin-top: 30px;
-        margin-bottom: 10px;
-        font-size: 24px;
+        margin: 10px 20px;
+        font-size: 20px;
         font-weight: bold;
       }
+
       li:hover {
         color: #00bbff;
       }
+
       li.active {
         color: #00bbff;
       }
     }
   }
 }
-</style>
+</style>

+ 1604 - 0
src/components/wgn/controlPanel.vue

@@ -0,0 +1,1604 @@
+<template>
+  <div id="controlPanelBox">
+    <div>
+      <div class="sceneNameBox">
+        <div class="">
+          场景名称:
+          <el-cascader
+            :disabled="$route.query.sceneId"
+            v-model="SceneValue"
+            placeholder="试试搜索:距离"
+            :options="SceneList"
+            :props="{ expandTrigger: 'hover' }"
+            @change="handleChange"
+            filterable
+          ></el-cascader>
+          <el-tooltip
+            v-if="SceneValue && SceneRule[SceneValue].functionalDefinition"
+            :content="SceneRule[SceneValue].functionalDefinition"
+            placement="bottom"
+            :popper-style="{ maxWidth: '300px' }"
+          >
+            <el-icon
+              style="margin-left: 1rem; width: 1rem; height: 1rem"
+              v-show="SceneValue && SceneRule[SceneValue].functionalDefinition"
+              ><QuestionFilled
+            /></el-icon>
+          </el-tooltip>
+        </div>
+        <div>
+          <el-button type="primary" @click="sendGeometriesToBackend"
+            >发送<i class="el-icon-s-promotion el-icon--right"></i
+          ></el-button>
+        </div>
+      </div>
+      <el-divider></el-divider>
+      <div
+        v-if="
+          SceneValue &&
+          SceneRule[SceneValue] &&
+          (SceneRule[SceneValue].elementTypes.includes('point') ||
+            SceneRule[SceneValue].elementTypes.includes('polyline') ||
+            SceneRule[SceneValue].elementTypes.includes('polygon'))
+        "
+      >
+        元素个数:{{
+          SceneValue && SceneRule[SceneValue] ? SceneRule[SceneValue].numberOf : ""
+        }}
+      </div>
+      <div>
+        参数类型:{{
+          SceneValue && SceneRule[SceneValue] ? SceneRule[SceneValue].elementTypes : ""
+        }}
+      </div>
+      <div>
+        接口地址:{{
+          SceneValue && SceneRule[SceneValue] ? SceneRule[SceneValue].apiUrl : ""
+        }}
+      </div>
+    </div>
+    <el-divider></el-divider>
+    <div>
+      <!-- 元素文本渲染和操作区域 -->
+      <el-tabs tab-position="left" style="height: calc(100vh - 370px)" class="demo-tabs">
+        <el-tab-pane label="入参">
+          <div
+            v-if="
+              SceneValue &&
+              SceneRule[SceneValue] &&
+              SceneRule[SceneValue].elementTypes.includes('file')
+            "
+          >
+            <el-upload
+              v-model:file-list="fileList"
+              class="upload-demo"
+              action=""
+              :limit="1"
+              :on-change="handleFileChange"
+              :on-exceed="handleExceed"
+              :on-remove="uploadRemove"
+              :auto-upload="false"
+            >
+              <el-button type="primary">上传文件</el-button>
+            </el-upload>
+          </div>
+          <div v-if="SceneValue && SceneRule[SceneValue]">
+            <div
+              v-for="item in SceneRule[SceneValue].elementTypes"
+              :key="item"
+              style="margin-top: 0.5rem"
+            >
+              <div
+                v-if="SceneValue && SceneRule[SceneValue] && SceneRule[SceneValue][item]"
+              >
+                {{ item }}:<el-select
+                  v-if="SceneRule[SceneValue][item]"
+                  v-model="params[item]"
+                  :placeholder="'请选择' + item"
+                  style="width: 240px"
+                >
+                  <el-option
+                    v-for="item in SceneRule[SceneValue][item]"
+                    :key="item.value"
+                    :label="item.label"
+                    :value="item.value"
+                  />
+                </el-select>
+              </div>
+              <div v-if="['lon', 'lat', 'filePath', 'EPSILON'].includes(item)">
+                {{ item }}:
+                <el-input
+                  v-model="params[item]"
+                  style="width: 240px"
+                  :placeholder="'请输入' + item"
+                />
+              </div>
+            </div>
+          </div>
+          <json-viewer
+            v-if="
+              SceneValue &&
+              SceneRule[SceneValue] &&
+              (SceneRule[SceneValue].elementTypes.includes('point') ||
+                SceneRule[SceneValue].elementTypes.includes('polyline') ||
+                SceneRule[SceneValue].elementTypes.includes('polygon'))
+            "
+            :value="jsonData"
+            :editable="true"
+            :preview-mode="false"
+            style="
+              pointer-events: auto;
+              max-height: calc(100vh - 370px) !important;
+              overflow-y: scroll !important;
+            "
+            copyable
+            @input="handleJsonInput"
+          />
+        </el-tab-pane>
+        <el-tab-pane label="返回">
+          <div
+            v-if="backData.message || backData.error"
+            :style="{
+              backgroundColor: backData.code === 200 ? '#67C23A' : '#F56C6C',
+              color: '#fff',
+              padding: '5px 10px',
+              fontSize: '14px',
+            }"
+          >
+            {{ backData.message || backData.error }}
+          </div>
+          <json-viewer
+            :value="backData.content"
+            :editable="true"
+            :preview-mode="false"
+            style="
+              pointer-events: auto;
+              max-height: calc(100vh - 370px) !important;
+              overflow-y: scroll !important;
+            "
+            copyable
+        /></el-tab-pane>
+      </el-tabs>
+    </div>
+    <!-- 绘制工具栏 -->
+    <div
+      class="toolbar"
+      v-if="
+        SceneValue &&
+        SceneRule[SceneValue] &&
+        (SceneRule[SceneValue].elementTypes.includes('point') ||
+          SceneRule[SceneValue].elementTypes.includes('polyline') ||
+          SceneRule[SceneValue].elementTypes.includes('polygon'))
+      "
+    >
+      <div
+        class="tool-item"
+        @click="activateDraw('point')"
+        :class="{ active: currentTool === 'point' }"
+      >
+        绘制点
+        <el-tooltip
+          content="绘制开关,蓝色状态代表开启,再次点击结束绘制,地图左键点击选点,"
+          placement="right"
+        >
+          <el-icon style="width: 1rem; height: 1rem"><QuestionFilled /></el-icon>
+        </el-tooltip>
+      </div>
+      <div
+        class="tool-item"
+        @click="activateDraw('polyline')"
+        :class="{ active: currentTool === 'polyline' }"
+      >
+        绘制线<el-tooltip
+          content="绘制线最少需要两个点,鼠标左键点击选点,点之间自动连线,鼠标右键结束绘制"
+          placement="right"
+        >
+          <el-icon style="width: 1rem; height: 1rem"><QuestionFilled /></el-icon>
+        </el-tooltip>
+      </div>
+      <div
+        class="tool-item"
+        @click="activateDraw('polygon')"
+        :class="{ active: currentTool === 'polygon' }"
+      >
+        绘制面<el-tooltip
+          content="绘制面最少需要三个点,鼠标左键点击选点,面自动必合,鼠标右键结束绘制"
+          placement="right"
+        >
+          <el-icon style="width: 1rem; height: 1rem"><QuestionFilled /></el-icon>
+        </el-tooltip>
+      </div>
+      <!-- <div class="tool-item" @click="startHoleDrawing" :class="{ active: isDrawingHole }">
+        绘制镂空
+      </div> -->
+      <div class="tool-item" @click="clearAll">清除所有</div>
+    </div>
+  </div>
+</template>
+
+<script>
+import wgn from "../../api/wgn";
+// 控制面板
+export default {
+  name: "ControlPanel",
+  // 2. 接收父组件传递的 props(单向数据流,子组件不能直接修改)
+  props: {
+    btnText: {
+      type: String, // 类型限制
+      default: "默认按钮", // 默认值
+      required: false, // 是否必传
+    },
+    showCount: {
+      type: Boolean,
+      default: false,
+    },
+  },
+  data() {
+    return {
+      currentFile: null, // 当前选中的文件
+      fileList: [],
+      // 其他参数
+      params: {
+        unit: "",
+        outFileType: "",
+        outPrj: "",
+        inPrj: "",
+        lon: "",
+        lat: "",
+      },
+      // 请求参数
+      jsonData: {},
+      // 返回参数
+      backData: {},
+      // 当前场景值
+      SceneValue: "",
+      // 场景列表
+      SceneList: [
+        {
+          value: "1.5.1",
+          label: "1.5.1拓扑计算",
+          children: [
+            {
+              value: "1.5.1.1",
+              label: "点线面拓扑关系",
+            },
+          ],
+        },
+        {
+          value: "1.5.2",
+          label: "1.5.2空间量算",
+          children: [
+            {
+              value: "1.5.2.1",
+              label: "两点欧氏距离",
+            },
+            {
+              value: "1.5.2.2",
+              label: "点到线的最短距离",
+            },
+            {
+              value: "1.5.2.3",
+              label: "点到面的最短距离",
+            },
+            {
+              value: "1.5.2.4",
+              label: "面到面的最短距离",
+            },
+            {
+              value: "1.5.2.5",
+              label: "折线距离(累加线段长度)",
+            },
+            {
+              value: "1.5.2.6",
+              label: "平面面积、不规则面面积",
+            },
+            {
+              value: "1.5.2.7",
+              label: "曲面面积,考虑地形起伏",
+            },
+            {
+              value: "1.5.2.8",
+              label: "单点高程查询",
+            },
+            {
+              value: "1.5.2.9",
+              label: "两点高程差",
+            },
+            {
+              value: "1.5.2.10",
+              label: "区域高程统计",
+            },
+            {
+              value: "1.5.4.5",
+              label: "缓冲区计算",
+            },
+          ],
+        },
+        {
+          value: "1.5.3",
+          label: "1.5.3几何运算",
+          children: [
+            {
+              value: "1.5.3.1",
+              label: "并集运算",
+            },
+            {
+              value: "1.5.3.2",
+              label: "交集运算",
+            },
+            {
+              value: "1.5.3.3",
+              label: "差集运算",
+            },
+            {
+              value: "1.5.3.4",
+              label: "几何参数计算",
+            },
+          ],
+        },
+        {
+          value: "1.5.4",
+          label: "1.5.4关系分析",
+          children: [
+            {
+              value: "1.5.4.1",
+              label: "邻接关系分析",
+            },
+            {
+              value: "1.5.4.2",
+              label: "包含关系分析",
+            },
+            {
+              value: "1.5.4.3",
+              label: "相交关系分析",
+            },
+            {
+              value: "1.5.4.4",
+              label: "相离关系分析",
+            },
+          ],
+        },
+        {
+          value: "1.5.5",
+          label: "1.5.5非空间数据转换",
+          children: [
+            {
+              value: "1.5.5.1",
+              label: "非空间数据转空间数据",
+            },
+          ],
+        },
+        {
+          value: "1.5.6",
+          label: "1.5.6坐标转换",
+          children: [
+            {
+              value: "1.5.6.1",
+              label: "单点的坐标转换接口",
+            },
+          ],
+        },
+        {
+          value: "1.5.7",
+          label: "1.5.7时空数据格式转换",
+          children: [
+            {
+              value: "1.5.7.1",
+              label: "文件格式转换",
+            },
+            {
+              value: "1.5.7.2",
+              label: "转换文件下载",
+            },
+          ],
+        },
+      ],
+      // 场景规则
+      SceneRule: {
+        "1.5.1.1": {
+          // 功能描述
+          functionalDefinition:
+            "拓扑计算功能聚焦于深度解析大批量数据的点、线、面之间的拓扑关系,能够精准判断点与线、面的位置关系,以及线、面之间的相交、平行、邻接、包含等复杂状态。借助四叉树、R 树等精心设计的数据结构,结合 Douglas - Peucker 等高效算法,确保在处理海量空间数据时,也能快速且准确地输出分析结果。",
+          // 元素类型
+          elementTypes: ["point", "polyline", "polygon"],
+          // 元素个数
+          numberOf: 2,
+          // 后台接口路径
+          apiUrl: "/topology/geoJsonToGeoJson",
+        },
+        "1.5.2.1": {
+          // 功能描述
+          functionalDefinition:
+            "计算两个点要素之间的最短空间距离,单位支持米、千米。操作逻辑为:用户通过接口输入两点经纬度坐标,或在系统内部地图上点击选择两点,系统基于坐标系参数计算欧氏距离。例如:计算青浦区某学校与社区卫生服务中心的直线距离,用于公共服务覆盖半径评估;计算两个监测点位的直线距离,用于监测设备信号覆盖范围判断。",
+          // 元素类型
+          elementTypes: ["point", "point", "unit"],
+          // 单位
+          unit: [
+            {
+              value: "METER",
+              label: "米",
+            },
+            {
+              value: "KILOMETER",
+              label: "千米",
+            },
+          ],
+          // 元素个数
+          numberOf: 2,
+          // 后台接口路径
+          apiUrl: "/spatialMeasure/pointToPoint",
+        },
+        "1.5.2.2": {
+          // 功能描述
+          functionalDefinition: "计算点和线要素之间的最短空间距离,单位支持米、千米",
+          // 元素类型
+          elementTypes: ["point", "polyline", "unit"],
+          // 单位
+          unit: [
+            {
+              value: "METER",
+              label: "米",
+            },
+            {
+              value: "KILOMETER",
+              label: "千米",
+            },
+          ],
+          // 元素个数
+          numberOf: 2,
+          // 后台接口路径
+          apiUrl: "/spatialMeasure/pointToLine",
+        },
+        "1.5.2.3": {
+          // 功能描述
+          functionalDefinition: "计算点和面要素之间的最短空间距离,单位支持米、千米",
+          // 元素类型
+          elementTypes: ["point", "polygon", "unit"],
+          // 单位
+          unit: [
+            {
+              value: "METER",
+              label: "米",
+            },
+            {
+              value: "KILOMETER",
+              label: "千米",
+            },
+          ],
+          // 元素个数
+          numberOf: 2,
+          // 后台接口路径
+          apiUrl: "/spatialMeasure/pointToPolygon",
+        },
+        "1.5.2.4": {
+          // 功能描述
+          functionalDefinition: "计算两个面要素之间的最短空间距离,单位支持米、千米",
+          // 元素类型
+          elementTypes: ["polygon", "polygon", "unit"],
+          // 单位
+          unit: [
+            {
+              value: "METER",
+              label: "米",
+            },
+            {
+              value: "KILOMETER",
+              label: "千米",
+            },
+          ],
+          // 元素个数
+          numberOf: 2,
+          // 后台接口路径
+          apiUrl: "/spatialMeasure/PolygonToPolygon",
+        },
+        "1.5.2.5": {
+          // 功能描述
+          functionalDefinition: "计算多条线段组成的折线总长度,单位支持米、千米",
+          // 元素类型
+          elementTypes: ["polyline", "unit"],
+          // 单位
+          unit: [
+            {
+              value: "METER",
+              label: "米",
+            },
+            {
+              value: "KILOMETER",
+              label: "千米",
+            },
+          ],
+          // 元素个数
+          numberOf: 1,
+          // 后台接口路径
+          apiUrl: "/spatialMeasure/calculatePolylineDistance",
+        },
+        "1.5.2.6": {
+          // 功能描述
+          functionalDefinition:
+            "计算面要素在二维平面上的投影面积,单位支持平方米、公顷、平方千米切换",
+          // 元素类型
+          elementTypes: ["polygon", "unit"],
+          // 单位
+          unit: [
+            {
+              value: "SQUARE_METER",
+              label: "平方米",
+            },
+            {
+              value: "HECTARE",
+              label: "公顷",
+            },
+            {
+              value: "SQUARE_KILOMETER",
+              label: "平方千米",
+            },
+          ],
+          // 元素个数
+          numberOf: 1,
+          // 后台接口路径
+          apiUrl: "/spatialMeasure/calculatePlaneAreaInGeometry",
+        },
+        "1.5.2.7": {
+          // 功能描述
+          functionalDefinition:
+            "结合 DEM 高程数据,计算面要素在三维地形上的实际曲面面积(考虑地形起伏),精度依赖 DEM 数据分辨率。,单位支持平方米、公顷、平方千米切换",
+          // 元素类型
+          elementTypes: ["polygon", "unit"],
+          // 单位
+          unit: [
+            {
+              value: "SQUARE_METER",
+              label: "平方米",
+            },
+            {
+              value: "HECTARE",
+              label: "公顷",
+            },
+            {
+              value: "SQUARE_KILOMETER",
+              label: "平方千米",
+            },
+          ],
+          // 元素个数
+          numberOf: 1,
+          // 后台接口路径
+          apiUrl: "/spatialMeasure/calculateSurfaceAreaInGeometry",
+        },
+        "1.5.2.8": {
+          // 功能描述
+          functionalDefinition:
+            "查询单个点要素的海拔高度(基于 CGCS2000 大地高程基准),单位为米",
+          // 元素类型
+          elementTypes: ["point"],
+          // 元素个数
+          numberOf: 1,
+          // 后台接口路径
+          apiUrl: "/spatialMeasure/getPointElevationInGeometry",
+        },
+        "1.5.2.9": {
+          // 功能描述
+          functionalDefinition:
+            "计算两个点要素之间的高程差值,支持正负值显示(正值表示前者高于后者,负值相反)",
+          // 元素类型
+          elementTypes: ["point", "point"],
+          // 元素个数
+          numberOf: 2,
+          // 后台接口路径
+          apiUrl: "/spatialMeasure/calculateElevationDiffInGeometry",
+        },
+        "1.5.2.10": {
+          // 功能描述
+          functionalDefinition:
+            "查询单个面要素的海拔高度(基于 CGCS2000 大地高程基准),单位为米",
+          // 元素类型
+          elementTypes: ["polygon"],
+          // 元素个数
+          numberOf: 1,
+          // 后台接口路径
+          apiUrl: "/spatialMeasure/calculateAreaElevationStatsInGeometry",
+        },
+        "1.5.3.1": {
+          // 功能描述
+          functionalDefinition:
+            "将两个或多个不重叠 / 部分重叠的面要素,合并为一个连续的新面要素(消除重叠部分,保留所有要素的覆盖范围)",
+          // 元素类型
+          elementTypes: ["polygon"],
+          // 元素个数
+          minNumberOf: 2,
+          // 后台接口路径
+          apiUrl: "/geometry/union",
+        },
+        "1.5.3.2": {
+          // 功能描述
+          functionalDefinition:
+            "提取两个或多个面要素之间的重叠区域,生成新的面要素(仅保留所有要素共同覆盖的范围)",
+          // 元素类型
+          elementTypes: ["polygon"],
+          // 元素个数
+          minNumberOf: 2,
+          // 后台接口路径
+          apiUrl: "/geometry/intersection",
+        },
+        "1.5.3.3": {
+          // 功能描述
+          functionalDefinition:
+            "以一个面要素(称为 “源面”)为基础,减去与另一个面要素(称为 “裁剪面”)的重叠区域,生成新的面要素(保留源面中未被裁剪面覆盖的部分)",
+          // 元素类型
+          elementTypes: ["polygon"],
+          // 元素个数
+          minNumberOf: 2,
+          // 后台接口路径
+          apiUrl: "/geometry/difference",
+        },
+        "1.5.3.4": {
+          // 功能描述
+          functionalDefinition:
+            "计算面要素的参数(面积、周长、中心坐标、最小外接矩形等)",
+          // 元素类型
+          elementTypes: ["point", "polyline", "polygon"],
+          // 元素个数
+          numberOf: 1,
+          // 后台接口路径
+          apiUrl: "/geometry/parameters",
+        },
+        "1.5.4.1": {
+          // 功能描述
+          functionalDefinition:
+            "判断两个面要素是否 “边界接触但不重叠”,且距离小于等于自定义阈值(默认 1 米,可通过接口参数调整),核心用于 “相邻区域联动” 场景",
+          // 元素类型
+          elementTypes: ["polygon", "polygon", "EPSILON"],
+          // 元素个数
+          numberOf: 2,
+          // 后台接口路径
+          apiUrl: "/relationAnalys/adjacent",
+        },
+        "1.5.4.2": {
+          // 功能描述
+          functionalDefinition:
+            "判断一个要素(含点、线、面)是否完全位于另一个面要素内部,且无任何部分超出,核心用于 “归属界定” 场景",
+          // 元素类型
+          elementTypes: ["point", "polyline", "polygon", "EPSILON"],
+          // 元素个数
+          numberOf: 2,
+          // 后台接口路径
+          apiUrl: "/relationAnalys/include",
+        },
+        "1.5.4.3": {
+          // 功能描述
+          functionalDefinition:
+            "判断两个要素(点与线、点与面、线与线、线与面、面与面)是否存在空间重叠(含部分重叠),核心用于 “交叉影响” 场景",
+          // 元素类型
+          elementTypes: ["point", "polyline", "polygon", "EPSILON"],
+          // 元素个数
+          numberOf: 2,
+          // 后台接口路径
+          apiUrl: "/relationAnalys/intersect",
+        },
+        "1.5.4.4": {
+          // 功能描述
+          functionalDefinition:
+            "判断两个要素(点、线、面)之间无任何空间接触(含边界接触),且最小距离大于自定义阈值(默认 10 米,可通过接口参数调整),核心用于 “无关联排除” 场景",
+          // 元素类型
+          elementTypes: ["point", "polyline", "polygon", "EPSILON"],
+          // 元素个数
+          numberOf: 2,
+          // 后台接口路径
+          apiUrl: "/relationAnalys/parting",
+        },
+        "1.5.4.5": {
+          // 功能描述
+          functionalDefinition:
+            "以一个核心要素(点、线、面)为中心,按自定义半径(如 500 米、1 千米)划定范围,查询范围内所有目标要素(如设施、地块、道路),核心用于 “资源覆盖范围” 场景。由于不是我负责,暂时为缓冲区计算功能。​",
+          // 元素类型
+          elementTypes: ["point", "polyline", "polygon", "EPSILON"],
+          // 元素个数
+          numberOf: 2,
+          // 后台接口路径
+          apiUrl: "/relationAnalys/neighbor",
+        },
+        "1.5.5.1": {
+          // 功能描述
+          functionalDefinition:
+            "非空间数据转空间数据功能支持常见格式的非空间数据转换,如 CSV、Excel 表格数据等。通过与地理编码服务紧密结合,关联空间参考信息(如地址、行政区域、关联 ID),转换为带坐标的空间要素(点、线、面),将表格中的地址、坐标等信息转换为具有空间位置的矢量数据的功能,并依据用户设定规则赋予属性信息。核心解决 “业务数据与地图引擎关联” 的问题,实现 “数据可视化” 与 “空间分析” 的联动。在智慧城市建设中,整合人口、环境、交通等多源非空间数据,实现数据融合分析,为城市精细化管理提供数据支持;在地理大数据分析中,拓展非空间数据的应用维度,挖掘数据潜在价值。",
+          // 元素类型
+          elementTypes: ["file"],
+          // 元素个数
+          numberOf: 0,
+          // 后台接口路径
+          apiUrl: "/nonStandardToStandard/importFile",
+        },
+        "1.5.6.1": {
+          // 功能描述
+          functionalDefinition:
+            "坐标转换是基于青浦区三维数字底板的坐标系统(SH2000投影坐标系),将空间要素的坐标在不同坐标系之间进行转换的功能,包括地理坐标系(如 WGS84、上海 2000 等)和投影坐标系(如高斯 - 克吕格投影、UTM 投影等)",
+          // 元素类型
+          elementTypes: ["lon", "lat", "inPrj", "outPrj"],
+          inPrj: [
+            {
+              value: "WGS84",
+              label: "WGS84",
+            },
+            {
+              value: "SH2000",
+              label: "SH2000",
+            },
+            {
+              value: "UTM",
+              label: "UTM",
+            },
+          ],
+          outPrj: [
+            {
+              value: "WGS84",
+              label: "WGS84",
+            },
+            {
+              value: "SH2000",
+              label: "SH2000",
+            },
+            {
+              value: "UTM",
+              label: "UTM",
+            },
+          ],
+          // 元素个数
+          numberOf: 0,
+          // 后台接口路径
+          apiUrl: "/coordinateSystemTransformation/pointTransformation",
+        },
+        "1.5.7.1": {
+          // 功能描述
+          functionalDefinition:
+            "时空数据格式转换是将青浦区三维数字底板中的时空数据(含空间坐标与时间属性的数据,如轨迹数据、时序监测数据),在不同标准数据格式之间进行转换的功能,如 Shapefile、GeoJSON、KML、NetCDF 等。核心支持 “矢量数据格式转换”“栅格数据格式转换”“时空轨迹数据格式转换” 三类转换,确保数据能在不同 GIS 软件、不同应用系统之间兼容流转,不同部门、不同系统之间顺利读取和处理时空数据;在大数据存储和管理时,根据不同应用场景和存储需求,选择合适的数据格式。提高数据存储和访问效率,满足数据共享、分析、展示的多场景需求。",
+          // 元素类型
+          elementTypes: ["file", "outFileType", "lonKey", "latKey"],
+          outFileType: [
+            {
+              value: "geoJson",
+              label: "geoJson",
+            },
+            {
+              value: "shp",
+              label: "shp",
+            },
+            {
+              value: "csv",
+              label: "csv",
+            },
+            {
+              value: "xlsx",
+              label: "xlsx",
+            },
+          ],
+          // 元素个数
+          numberOf: 0,
+          // 后台接口路径
+          apiUrl: "/spatiotemporal_data_format_conversion/fileFormatConversion",
+        },
+        "1.5.7.2": {
+          // 功能描述
+          functionalDefinition: "转换文件下载",
+          // 元素类型
+          elementTypes: ["filePath"],
+          // 元素个数
+          numberOf: 0,
+          // 后台接口路径
+          apiUrl: "/spatiotemporal_data_format_conversion/downloadFile",
+        },
+      },
+      currentTool: null,
+      drawingMode: null,
+      handler: null,
+      drawnEntities: [],
+      geometries: [], // 存储绘制的几何对象
+      // 绘制状态相关
+      currentEntity: null, // 当前正在绘制的实体
+      currentPositions: [], // 当前正在绘制的位置数组
+      isDrawingHole: false, // 是否正在绘制镂空
+      currentPolygonEntity: null, // 当前要添加镂空的多边形实体
+      currentPolygonGeometry: null, // 当前要添加镂空的多边形几何对象
+      tempEntity: null, // 临时预览实体
+    };
+  },
+  mounted() {
+    this.SceneValue = this.$route.query.sceneId ? this.$route.query.sceneId : "";
+  },
+
+  beforeUnmount() {
+    // 组件卸载前清理资源
+    this.deactivateDraw();
+    if (this.handler) {
+      this.handler.destroy();
+    }
+  },
+  methods: {
+    handleExceed(file) {
+      this.$message({
+        message: "最多只能上传一个文件",
+        type: "warning",
+      });
+    },
+    handleFileChange(file, fileList) {
+      this.currentFile = file; // 注意:Element UI Plus 无需 .raw
+    },
+    uploadRemove() {
+      this.currentFile = null;
+    },
+    handleJsonInput(value) {
+      this.jsonData = JSON.parse(value);
+    },
+    handleChange(emit) {
+      this.params.unit = "";
+      this.currentFile = null;
+      // 清除所有地图中的元素
+      this.clearAll();
+      this.jsonData = {};
+      this.backData = {};
+      this.SceneValue = emit[emit.length - 1];
+    },
+    // 初始化绘制处理器
+    initDrawHandler() {
+      // 创建绘制处理器
+      this.handler = new SkyScenery.ScreenSpaceEventHandler(viewer.canvas);
+    },
+
+    // 激活绘制工具
+    activateDraw(type) {
+      // 取消镂空绘制模式
+      this.isDrawingHole = false;
+      // 如果已经是当前激活的工具,则取消激活
+      if (this.currentTool === type) {
+        this.deactivateDraw();
+        return;
+      }
+      // 先取消之前的绘制模式
+      this.deactivateDraw();
+      // 设置当前工具
+      this.currentTool = type;
+      this.drawingMode = type;
+      // 重置当前绘制状态
+      this.resetDrawingState();
+      switch (type) {
+        case "point":
+          this.drawPoint();
+          break;
+        case "polyline":
+          this.drawPolyline();
+          break;
+        case "polygon":
+          this.drawPolygon();
+          break;
+      }
+    },
+
+    // 重置绘制状态
+    resetDrawingState() {
+      this.currentPositions = [];
+      this.currentEntity = null;
+      // 移除临时预览实体
+      if (this.tempEntity) {
+        viewer.entities.remove(this.tempEntity);
+        viewer.scene.requestRender();
+        this.tempEntity = null;
+      }
+    },
+
+    // 取消绘制模式
+    deactivateDraw() {
+      if (this.handler) {
+        // 移除所有事件监听器
+        this.handler.removeInputAction(SkyScenery.ScreenSpaceEventType.LEFT_CLICK);
+        this.handler.removeInputAction(SkyScenery.ScreenSpaceEventType.MOUSE_MOVE);
+        this.handler.removeInputAction(SkyScenery.ScreenSpaceEventType.RIGHT_CLICK);
+      }
+      // 重置状态
+      this.resetDrawingState();
+      this.currentTool = null;
+      this.drawingMode = null;
+      this.isDrawingHole = false;
+    },
+
+    // 绘制点
+    drawPoint() {
+      const that = this;
+      this.handler.setInputAction(function (event) {
+        const ray = viewer.camera.getPickRay(event.position);
+        const position = viewer.scene.globe.pick(ray, viewer.scene);
+        if (position) {
+          const cartographic = SkyScenery.Cartographic.fromCartesian(position);
+          const longitude = SkyScenery.Math.toDegrees(cartographic.longitude);
+          const latitude = SkyScenery.Math.toDegrees(cartographic.latitude);
+          // 创建点实体(实时渲染)
+          const entity = viewer.entities.add({
+            position: position,
+            point: {
+              show: true,
+              color: SkyScenery.Color.RED,
+              pixelSize: 10,
+              outlineColor: SkyScenery.Color.WHITE,
+              outlineWidth: 2,
+            },
+          });
+          viewer.scene.requestRender();
+          that.drawnEntities.push(entity);
+          // 转换为geometry格式并保存
+          const geometry = {
+            type: "Point",
+            coordinates: [longitude, latitude],
+          };
+          that.geometries.push(geometry);
+          that.changeGeometries();
+          console.log("绘制了点:", geometry);
+        }
+      }, SkyScenery.ScreenSpaceEventType.LEFT_CLICK);
+    },
+
+    // 绘制线
+    drawPolyline() {
+      const that = this;
+      // 鼠标移动时更新临时线(实时渲染预览)
+      this.handler.setInputAction(function (event) {
+        if (that.currentPositions.length > 0) {
+          const ray = viewer.camera.getPickRay(event.endPosition);
+          const endPosition = viewer.scene.globe.pick(ray, viewer.scene);
+
+          if (endPosition) {
+            const tempPositions = [...that.currentPositions, endPosition];
+
+            // 更新临时预览实体
+            if (!that.tempEntity) {
+              that.tempEntity = viewer.entities.add({
+                polyline: {
+                  show: true,
+                  positions: tempPositions,
+                  material: SkyScenery.Color.BLUE.withAlpha(0.5),
+                  width: 3,
+                },
+              });
+              viewer.scene.requestRender();
+            } else {
+              that.tempEntity.polyline.positions = tempPositions;
+            }
+          }
+        }
+      }, SkyScenery.ScreenSpaceEventType.MOUSE_MOVE);
+
+      // 左键点击添加点
+      this.handler.setInputAction(function (event) {
+        const ray = viewer.camera.getPickRay(event.position);
+        const position = viewer.scene.globe.pick(ray, viewer.scene);
+
+        if (position) {
+          that.currentPositions.push(position.clone());
+
+          // 如果是第一个点,不需要更新实体
+          if (that.currentPositions.length > 1) {
+            // 如果已有实体,更新它
+            if (that.currentEntity) {
+              viewer.entities.remove(that.currentEntity);
+            }
+
+            // 创建当前实体(实时渲染)
+            that.currentEntity = viewer.entities.add({
+              polyline: {
+                show: true,
+                positions: [...that.currentPositions],
+                material: SkyScenery.Color.BLUE,
+                width: 3,
+              },
+            });
+            viewer.scene.requestRender();
+          }
+        }
+      }, SkyScenery.ScreenSpaceEventType.LEFT_CLICK);
+
+      // 右键点击完成绘制
+      this.handler.setInputAction(function () {
+        if (that.currentPositions.length > 1) {
+          // 移除临时预览实体
+          if (that.tempEntity) {
+            viewer.entities.remove(that.tempEntity);
+            that.tempEntity = null;
+          }
+
+          // 否则创建线
+          // 确保当前实体存在
+          if (!that.currentEntity) {
+            that.currentEntity = viewer.entities.add({
+              polyline: {
+                show: true,
+                positions: [...that.currentPositions],
+                material: SkyScenery.Color.BLUE,
+                width: 3,
+              },
+            });
+          }
+
+          that.drawnEntities.push(that.currentEntity);
+          viewer.scene.requestRender();
+
+          // 转换为geometry格式并保存
+          const coordinates = [];
+          that.currentPositions.forEach((pos) => {
+            const cartographic = SkyScenery.Cartographic.fromCartesian(pos);
+            coordinates.push([
+              SkyScenery.Math.toDegrees(cartographic.longitude),
+              SkyScenery.Math.toDegrees(cartographic.latitude),
+            ]);
+          });
+
+          const geometry = {
+            type: "LineString",
+            coordinates: coordinates,
+          };
+          that.geometries.push(geometry);
+          that.changeGeometries();
+          console.log("绘制了线:", geometry);
+          // 取消当前绘制模式
+          that.deactivateDraw();
+        }
+      }, SkyScenery.ScreenSpaceEventType.RIGHT_CLICK);
+    },
+
+    // 绘制面
+    drawPolygon() {
+      const that = this;
+
+      // 鼠标移动时更新临时面(实时渲染预览)
+      this.handler.setInputAction(function (event) {
+        if (that.currentPositions.length > 0) {
+          const ray = viewer.camera.getPickRay(event.endPosition);
+          const endPosition = viewer.scene.globe.pick(ray, viewer.scene);
+
+          if (endPosition) {
+            // 为了预览效果,临时闭合多边形
+            const tempPositions = [
+              ...that.currentPositions,
+              endPosition,
+              that.currentPositions[0],
+            ];
+
+            // 更新临时预览实体
+            if (!that.tempEntity) {
+              that.tempEntity = viewer.entities.add({
+                polygon: {
+                  show: true,
+                  hierarchy: new SkyScenery.PolygonHierarchy(tempPositions),
+                  material: new SkyScenery.ColorMaterialProperty(
+                    new SkyScenery.Color(0, 0, 1, 0.2)
+                  ),
+                  outline: true,
+                  outlineColor: SkyScenery.Color.BLUE.withAlpha(0.5),
+                  outlineWidth: 2,
+                },
+              });
+              viewer.scene.requestRender();
+            } else {
+              that.tempEntity.polygon.hierarchy = new SkyScenery.PolygonHierarchy(
+                tempPositions
+              );
+            }
+          }
+        }
+      }, SkyScenery.ScreenSpaceEventType.MOUSE_MOVE);
+
+      // 左键点击添加点
+      this.handler.setInputAction(function (event) {
+        const ray = viewer.camera.getPickRay(event.position);
+        const position = viewer.scene.globe.pick(ray, viewer.scene);
+
+        if (position) {
+          // 检查是否点击了第一个点附近(自动闭合)
+          if (
+            that.currentPositions.length > 2 &&
+            that.isPositionNearFirst(position, that.currentPositions[0])
+          ) {
+            // 完成多边形绘制
+            that.finalizePolygonDrawing();
+            that.deactivateDraw();
+            return;
+          }
+
+          that.currentPositions.push(position.clone());
+
+          // 如果有足够的点,更新多边形实体(实时渲染)
+          if (that.currentPositions.length > 2) {
+            // 闭合多边形
+            const closedPositions = [...that.currentPositions, that.currentPositions[0]];
+            // 如果已有实体,更新它
+            if (that.currentEntity) {
+              viewer.entities.remove(that.currentEntity);
+            }
+
+            // 创建当前实体
+            that.currentEntity = viewer.entities.add({
+              polygon: {
+                show: true,
+                hierarchy: new SkyScenery.PolygonHierarchy(closedPositions),
+                material: new SkyScenery.ColorMaterialProperty(
+                  new SkyScenery.Color(0, 0, 1, 0.3)
+                ),
+                outline: true,
+                outlineColor: SkyScenery.Color.BLUE,
+                outlineWidth: 2,
+              },
+            });
+            viewer.scene.requestRender();
+          }
+        }
+      }, SkyScenery.ScreenSpaceEventType.LEFT_CLICK);
+
+      // 右键点击完成绘制
+      this.handler.setInputAction(function () {
+        if (that.currentPositions.length > 2) {
+          that.finalizePolygonDrawing();
+          // 取消当前绘制模式
+          that.deactivateDraw();
+        }
+      }, SkyScenery.ScreenSpaceEventType.RIGHT_CLICK);
+    },
+
+    // 完成多边形绘制
+    finalizePolygonDrawing() {
+      // 移除临时预览实体
+      if (this.tempEntity) {
+        viewer.entities.remove(this.tempEntity);
+        this.tempEntity = null;
+      }
+
+      // 确保多边形是闭合的
+      let closedPositions = [...this.currentPositions];
+      // 创建最终的多边形实体
+      if (this.currentEntity) {
+        viewer.entities.remove(this.currentEntity);
+      }
+
+      this.currentEntity = viewer.entities.add({
+        polygon: {
+          show: true,
+          hierarchy: new SkyScenery.PolygonHierarchy(closedPositions),
+          material: new SkyScenery.ColorMaterialProperty(
+            new SkyScenery.Color(0, 0, 1, 0.3)
+          ),
+          outline: true,
+          outlineColor: SkyScenery.Color.BLUE,
+          outlineWidth: 2,
+        },
+      });
+      viewer.scene.requestRender();
+
+      this.drawnEntities.push(this.currentEntity);
+
+      // 转换为geometry格式并保存(不包含重复的最后一个点)
+      const coordinates = [];
+      const mainRing = [];
+      for (let i = 0; i < closedPositions.length; i++) {
+        const cartographic = SkyScenery.Cartographic.fromCartesian(closedPositions[i]);
+        mainRing.push([
+          SkyScenery.Math.toDegrees(cartographic.longitude),
+          SkyScenery.Math.toDegrees(cartographic.latitude),
+        ]);
+      }
+      const cartographic = SkyScenery.Cartographic.fromCartesian(closedPositions[0]);
+      mainRing.push([
+        SkyScenery.Math.toDegrees(cartographic.longitude),
+        SkyScenery.Math.toDegrees(cartographic.latitude),
+      ]);
+      coordinates.push(mainRing);
+
+      const geometry = {
+        type: "Polygon",
+        coordinates: coordinates, // GeoJSON格式
+        holes: [], // 用于存储镂空区域
+      };
+
+      // 保存实体和几何对象的关联
+      this.currentEntity.geometryRef = geometry;
+      this.geometries.push(geometry);
+      this.changeGeometries();
+      console.log("绘制了面:", geometry);
+    },
+
+    // 开始绘制镂空
+    startHoleDrawing() {
+      // 如果已经在绘制镂空,则取消
+      if (this.isDrawingHole) {
+        this.isDrawingHole = false;
+        this.deactivateDraw();
+        return;
+      }
+
+      // 取消其他绘制模式
+      this.deactivateDraw();
+
+      // 设置为镂空绘制模式
+      this.isDrawingHole = true;
+
+      console.log("请点击一个多边形以添加镂空");
+
+      // 设置点击事件选择多边形
+      const that = this;
+      this.handler.setInputAction(function (event) {
+        // 拾取实体
+        const pickedObject = viewer.scene.pick(event.position);
+        if (pickedObject && pickedObject.id && pickedObject.id.polygon) {
+          const polygonEntity = pickedObject.id;
+
+          // 检查是否有对应的几何对象
+          if (polygonEntity.geometryRef && polygonEntity.geometryRef.type === "Polygon") {
+            that.currentPolygonEntity = polygonEntity;
+            that.currentPolygonGeometry = polygonEntity.geometryRef;
+
+            console.log("已选择多边形,现在绘制镂空区域");
+
+            // 开始绘制镂空区域(使用多边形绘制逻辑,但最后添加为镂空)
+            that.resetDrawingState();
+            that.drawHole();
+          } else {
+            console.log("选择的不是有效的多边形");
+          }
+        } else {
+          console.log("未选中任何多边形");
+        }
+      }, SkyScenery.ScreenSpaceEventType.LEFT_CLICK);
+    },
+
+    // 绘制镂空区域
+    drawHole() {
+      const that = this;
+
+      // 清除之前的事件
+      this.handler.removeInputAction(SkyScenery.ScreenSpaceEventType.LEFT_CLICK);
+
+      // 鼠标移动时更新临时镂空区域
+      this.handler.setInputAction(function (event) {
+        if (that.currentPositions.length > 0) {
+          const ray = viewer.camera.getPickRay(event.endPosition);
+          const endPosition = viewer.scene.globe.pick(ray, viewer.scene);
+
+          if (endPosition) {
+            // 为了预览效果,临时闭合多边形
+            const tempPositions = [
+              ...that.currentPositions,
+              endPosition,
+              that.currentPositions[0],
+            ];
+
+            // 更新临时预览实体
+            if (!that.tempEntity) {
+              that.tempEntity = viewer.entities.add({
+                polygon: {
+                  show: true,
+                  hierarchy: new SkyScenery.PolygonHierarchy(tempPositions),
+                  material: new SkyScenery.ColorMaterialProperty(
+                    new SkyScenery.Color(1, 0, 0, 0.3)
+                  ),
+                  outline: true,
+                  outlineColor: SkyScenery.Color.RED,
+                  outlineWidth: 2,
+                },
+              });
+              viewer.scene.requestRender();
+            } else {
+              that.tempEntity.polygon.hierarchy = new SkyScenery.PolygonHierarchy(
+                tempPositions
+              );
+            }
+          }
+        }
+      }, SkyScenery.ScreenSpaceEventType.MOUSE_MOVE);
+
+      // 左键点击添加点
+      this.handler.setInputAction(function (event) {
+        const ray = viewer.camera.getPickRay(event.position);
+        const position = viewer.scene.globe.pick(ray, viewer.scene);
+
+        if (position) {
+          // 检查是否点击了第一个点附近(自动闭合)
+          if (
+            that.currentPositions.length > 2 &&
+            that.isPositionNearFirst(position, that.currentPositions[0])
+          ) {
+            // 完成镂空绘制
+            that.finalizeHoleDrawing();
+            return;
+          }
+
+          that.currentPositions.push(position.clone());
+        }
+      }, SkyScenery.ScreenSpaceEventType.LEFT_CLICK);
+
+      // 右键点击完成绘制
+      this.handler.setInputAction(function () {
+        if (that.currentPositions.length > 2) {
+          that.finalizeHoleDrawing();
+        }
+      }, SkyScenery.ScreenSpaceEventType.RIGHT_CLICK);
+    },
+
+    // 完成镂空绘制
+    finalizeHoleDrawing() {
+      // 移除临时预览实体
+      if (this.tempEntity) {
+        viewer.entities.remove(this.tempEntity);
+        viewer.scene.requestRender();
+        this.tempEntity = null;
+      }
+
+      // 确保镂空区域是闭合的
+      let closedPositions = [...this.currentPositions];
+
+      // 转换为几何坐标
+      const holeCoordinates = [];
+      for (let i = 0; i < closedPositions.length; i++) {
+        const cartographic = SkyScenery.Cartographic.fromCartesian(closedPositions[i]);
+        holeCoordinates.push([
+          SkyScenery.Math.toDegrees(cartographic.longitude),
+          SkyScenery.Math.toDegrees(cartographic.latitude),
+        ]);
+      }
+
+      const cartographic = SkyScenery.Cartographic.fromCartesian(closedPositions[0]);
+      holeCoordinates.push([
+        SkyScenery.Math.toDegrees(cartographic.longitude),
+        SkyScenery.Math.toDegrees(cartographic.latitude),
+      ]);
+      // 添加到几何对象的镂空数组
+      if (!this.currentPolygonGeometry.holes) {
+        this.currentPolygonGeometry.holes = [];
+      }
+      this.currentPolygonGeometry.holes.push(holeCoordinates);
+
+      // 更新多边形的层级结构以包含镂空
+      const polygonHierarchy = this.buildPolygonHierarchyWithHoles(
+        this.currentPolygonGeometry.coordinates[0],
+        this.currentPolygonGeometry.holes
+      );
+
+      // 更新实体显示
+      this.currentPolygonEntity.polygon.hierarchy = polygonHierarchy;
+
+      console.log("添加了镂空区域:", holeCoordinates);
+      console.log("更新后的多边形几何:", this.currentPolygonGeometry);
+
+      // 重置状态
+      this.resetDrawingState();
+      this.isDrawingHole = false;
+      this.currentPolygonEntity = null;
+      this.currentPolygonGeometry = null;
+
+      // 取消绘制模式
+      this.deactivateDraw();
+    },
+
+    // 构建包含镂空的多边形层级结构
+    buildPolygonHierarchyWithHoles(outerRing, holes) {
+      // 将外部环转换为Cartesian3数组
+      const outerRingPositions = [];
+      outerRing.forEach((coord) => {
+        const cartesian = SkyScenery.Cartesian3.fromDegrees(coord[0], coord[1]);
+        outerRingPositions.push(cartesian);
+      });
+      // 闭合外部环
+      outerRingPositions.push(outerRingPositions[0]);
+
+      // 创建层级结构
+      const hierarchy = new SkyScenery.PolygonHierarchy(outerRingPositions);
+
+      // 添加镂空
+      if (holes && holes.length > 0) {
+        hierarchy.holes = holes.map((hole) => {
+          const holePositions = [];
+          hole.forEach((coord) => {
+            const cartesian = SkyScenery.Cartesian3.fromDegrees(coord[0], coord[1]);
+            holePositions.push(cartesian);
+          });
+          // 闭合镂空环
+          holePositions.push(holePositions[0]);
+          return new SkyScenery.PolygonHierarchy(holePositions);
+        });
+      }
+      return hierarchy;
+    },
+
+    // 检查点是否靠近第一个点
+    isPositionNearFirst(position, firstPosition, tolerance = 10) {
+      // 单位:米
+      const distance = SkyScenery.Cartesian3.distance(position, firstPosition);
+      return distance < tolerance;
+    },
+    changeGeometries() {
+      let requestData = {};
+      const geometriesToSend = this.geometries;
+      let FeatureCollectionFeatures = [];
+      geometriesToSend.forEach((item) => {
+        FeatureCollectionFeatures.push({
+          type: "Feature",
+          properties: {},
+          geometry: {
+            type: item.type,
+            coordinates: item.coordinates,
+          },
+        });
+      });
+      // 构造请求数据
+      requestData = {
+        type: "FeatureCollection",
+        features: FeatureCollectionFeatures,
+        timestamp: new Date().getTime(),
+      };
+      if (
+        this.SceneValue &&
+        this.SceneRule[this.SceneValue] &&
+        this.SceneRule[this.SceneValue].elementTypes &&
+        this.SceneRule[this.SceneValue].elementTypes.includes("unit") &&
+        this.params.unit
+      ) {
+        requestData.unit = this.params.unit;
+      }
+      if (
+        this.SceneValue &&
+        this.SceneRule[this.SceneValue] &&
+        this.SceneRule[this.SceneValue].elementTypes &&
+        this.SceneRule[this.SceneValue].elementTypes.includes("EPSILON") &&
+        this.params.EPSILON
+      ) {
+        requestData.EPSILON = this.params.EPSILON;
+      }
+      this.jsonData = requestData;
+      return requestData;
+    },
+    // 发送几何数据到后台接口
+    sendGeometriesToBackend() {
+      // 这里使用axios发送请求,需要确保项目中已安装并导入axios
+      let requestData;
+      let requestUrl = this.SceneRule[this.SceneValue].apiUrl;
+      if (
+        this.SceneRule[this.SceneValue].elementTypes.includes("point") ||
+        this.SceneRule[this.SceneValue].elementTypes.includes("polyline") ||
+        this.SceneRule[this.SceneValue].elementTypes.includes("polygon")
+      ) {
+        requestData = this.changeGeometries();
+      } else {
+        requestData = new FormData();
+        this.SceneRule[this.SceneValue].elementTypes.forEach((key) => {
+          if (key == "file") {
+            if (!this.currentFile) {
+              return this.$message({
+                message: "请选择文件",
+                type: "error",
+              });
+            }
+            requestData.append("file", this.currentFile.raw);
+          } else {
+            requestData.append(key, this.params[key]);
+          }
+        });
+      }
+      let that = this;
+      // 实际项目中使用以下代码发送请求
+      wgn
+        .topology(requestUrl, requestData)
+        .then((res) => {
+          if (requestUrl.indexOf("downloadFile") == -1) {
+            that.backData = res;
+            if (res.code && res.code == 200) {
+              that.$message({
+                message: res.message,
+                type: "success",
+              });
+            } else {
+              that.$message({
+                message: res.content,
+                type: "error",
+              });
+            }
+          } else {
+            const blob = res; // 响应体是 Blob 类型
+            if (!blob) {
+              that.$message.error("下载失败:文件流为空");
+              reject("文件流为空");
+              return;
+            }
+            let _downloadFile = that.params.filePath + "";
+            let fileName = _downloadFile.substring(
+              _downloadFile.indexOf("down_files") + 11
+            );
+            // D:\work\backCode\one_map_portal_server\down_files\0378b1c2e92a4c36ab447f552c0c7888.xlsx
+            // 替换原代码中创建 url 的逻辑,先加校验
+            console.log("blob 类型:", Object.prototype.toString.call(blob)); // 正常应输出 [object Blob]
+            console.log("blob 大小:", blob.size); // 正常应大于 0
+
+            if (!(blob instanceof Blob) || blob.size === 0) {
+              this.$message.error("文件流解析失败,无法生成下载链接");
+              return;
+            }
+            const url = window.URL.createObjectURL(blob); // 将 Blob 转为临时 URL
+            const link = document.createElement("a");
+            link.href = url;
+            link.download = fileName; // 设置下载文件名
+            link.style.display = "none";
+            document.body.appendChild(link);
+            link.click(); // 触发点击下载
+            document.body.removeChild(link);
+            window.URL.revokeObjectURL(url); // 销毁临时 URL,避免内存泄漏
+          }
+        })
+        .catch((error) => {
+          console.error("后台接口调用失败:", error);
+        });
+    },
+
+    // 清除所有绘制的元素
+    clearAll() {
+      // 移除所有实体
+      this.drawnEntities.forEach((entity) => {
+        viewer.entities.remove(entity);
+      });
+      viewer.scene.requestRender();
+      // 清空数组
+      this.drawnEntities = [];
+      this.geometries = [];
+      this.changeGeometries();
+      // 取消当前绘制模式
+      this.deactivateDraw();
+
+      console.log("已清除所有绘制的元素");
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+// 操作栏样式
+#controlPanelBox {
+  width: calc(30vw - 2rem);
+  min-width: 500px;
+  height: calc(100vh - 2rem);
+  display: flex;
+  flex-direction: column;
+  padding: 1rem;
+  position: fixed;
+  top: 0px;
+  right: 0;
+  background: #fff;
+}
+
+// 绘制按钮区域
+.toolbar {
+  position: absolute;
+  top: 10px;
+  left: -120px;
+  z-index: 1000;
+  background: rgba(255, 255, 255, 0.9);
+  border-radius: 8px;
+  padding: 3px 5px;
+  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
+  display: flex;
+  flex-direction: column;
+  gap: 8px;
+}
+
+.tool-item {
+  padding: 10px 20px;
+  cursor: pointer;
+  border-radius: 4px;
+  transition: all 0.3s ease;
+  user-select: none;
+  font-size: 14px;
+}
+
+.tool-item:hover {
+  background: #f0f0f0;
+}
+
+.tool-item.active {
+  background: #409eff;
+  color: white;
+}
+.sceneNameBox {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+}
+</style>

+ 139 - 0
src/components/yxgl/EchartsDome.vue

@@ -0,0 +1,139 @@
+<template>
+  <div class="echartsDome">
+    <div class="echartsDome_title">{{ title }}</div>
+    <div class="echartsDome_chart" ref="chartContainer" id="yxglEchart"></div>
+  </div>
+</template>
+
+<script>
+import * as echarts from "echarts";
+export default {
+  name: "EchartsDome",
+  props: {
+    title: {
+      type: String,
+      default: "图表标题",
+    },
+  },
+  data() {
+    return {
+      chart: null,
+    };
+  },
+  mounted() {
+    this.initChart();
+  },
+  methods: {
+    initChart() {
+      let chart = echarts.init(document.getElementById("yxglEchart"));
+
+      let option = {
+        legend: {
+          data: ["调用次数", "平均响应时间"],
+        },
+        tooltip: {
+          show: true,
+          trigger: "axis",
+          axisPointer: { type: "shadow" },
+          // 给不同Y轴的提示文字加对应颜色
+          // formatter: (params) => {
+          //   let html = `<div style="color:#333;z-index:100;">${params[0].axisValue}</div>`;
+          //   params.forEach((item) => {
+          //     // 调用次数
+          //     if (item.yAxisIndex === 0) {
+          //       html += `<div style="color:#42a5f5">${item.seriesName}:${item.value}</div>`;
+          //     }
+          //     // 平均响应时间
+          //     else if (item.yAxisIndex === 1) {
+          //       html += `<div style="color:#4caf50">${item.seriesName}:${item.value}</div>`;
+          //     }
+          //   });
+          //   return html;
+          // },
+        },
+        xAxis: {
+          type: "category",
+          data: [
+            "Jan",
+            "Feb",
+            "Mar",
+            "Apr",
+            "May",
+            "Jun",
+            "Jul",
+            "Aug",
+            "Sep",
+            "Oct",
+            "Nov",
+          ],
+          axisTick: { show: false }, // 隐藏刻度
+          splitLine: { show: false }, // 隐藏分割线
+        },
+        yAxis: [
+          {
+            type: "value",
+            name: "调用次数", // 第一个Y轴(左侧)
+            axisLine: { lineStyle: { color: "#42a5f5" } }, // 区分样式
+          },
+          {
+            type: "value",
+            name: "响应时间(ms)", // 第二个Y轴(右侧)
+            position: "right", // 显示在右侧(关键)
+            axisLine: { lineStyle: { color: "#4caf50" } }, // 区分样式
+          },
+        ],
+        series: [
+          {
+            name: "调用次数",
+            type: "line",
+            smooth: true,
+            data: [7, 7, 15, 19, 21, 22, 25, 26, 23, 19, 12], // 模拟数据
+            lineStyle: { color: "#42a5f5" }, // 蓝色线条
+            itemStyle: { color: "#42a5f5" }, // 节点颜色
+            symbol: "circle", // 节点形状
+            symbolSize: 6, // 节点大小
+            yAxisIndex: 0, // 绑定第一个Y轴(调用次数)
+          },
+          {
+            name: "平均响应时间",
+            type: "line",
+            smooth: true,
+            data: [3, 3, 6, 12, 15, 17, 18, 17, 14, 10, 6], // 模拟数据
+            lineStyle: { color: "#4caf50", type: "dashed" }, // 绿色线条
+            itemStyle: {
+              color: "#4caf50",
+              color: "#FFF",
+              borderWidth: 2,
+              borderColor: "#4caf50",
+            },
+            symbol: "circle",
+            symbolSize: 6,
+            yAxisIndex: 1, // 绑定第二个Y轴(响应时间)
+          },
+        ],
+      };
+      // 绘制图表
+      chart.setOption(option);
+    },
+  },
+};
+</script>
+
+<style scoped>
+.echartsDome {
+  width: 100%;
+  height: 400px;
+  /* background-color: #222;
+  color: #fff; */
+  padding: 20px;
+  box-sizing: border-box;
+}
+.echartsDome_title {
+  font-size: 16px;
+  /* font-weight: bold; */
+}
+.echartsDome_chart {
+  width: 100%;
+  height: 360px;
+}
+</style>

+ 93 - 0
src/components/yxgl/card.vue

@@ -0,0 +1,93 @@
+<template>
+  <div>
+    <div class="leftInfo">
+      <div class="leftInfo_title">{{ title }}</div>
+      <div class="leftInfo_value">{{ value }}</div>
+      <div class="leftInfo_growth" :style="{ color: growthColors[upStatus + 1] }">
+        <el-icon
+          ><Top v-if="upStatus == 1" /><SemiSelect v-if="upStatus == 0" /><Bottom
+            v-if="upStatus == -1"
+        /></el-icon>
+        {{ growth }}
+      </div>
+    </div>
+    <div class="icon" :style="{ background: iconColor + '32' }">
+      <el-icon><Flag :color="iconColor" /></el-icon>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  name: "card",
+  props: {
+    title: {
+      type: String,
+      default: "",
+    },
+    value: {
+      type: String,
+      default: "",
+    },
+    growth: {
+      type: String,
+      default: "",
+    },
+    iconColor: {
+      type: String,
+      default: "#CCCCCC",
+    },
+    upStatus: {
+      type: Number,
+      //   -1 下降
+      //   0 持平
+      //   1 上升
+      default: -1,
+    },
+  },
+  data() {
+    return {
+      // 0 下降
+      // 1 持平
+      // 2 上升
+      growthColors: ["#F56C6C", "#909399", "#67C23A"],
+    };
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.leftInfo {
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: flex-start;
+}
+.leftInfo_title {
+  font-size: 12px;
+  color: #909399;
+  line-height: 20px;
+}
+.leftInfo_value {
+  margin-top: 4px;
+  font-size: 24px;
+  font-weight: bold;
+  line-height: 33px;
+}
+.leftInfo_growth {
+  margin-top: 12px;
+  font-size: 12px;
+  line-height: 20px;
+  font-weight: bold;
+}
+.icon {
+  width: 40px;
+  height: 40px;
+  border-radius: 5px;
+  background: #ccc;
+  font-size: 20px;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+}
+</style>

+ 8 - 4
src/main.js

@@ -6,13 +6,17 @@ import router from './router'
 initApp.use(router);
 import store from './store'
 initApp.use(store);
-
 import ElementPlus from 'element-plus'
-import 'element-plus/dist/index.css'
-initApp.use(ElementPlus)
-
+import zhCn from 'element-plus/es/locale/lang/zh-cn'
+import 'element-plus/dist/index.css' // 引入默认主题样式
+import 'element-plus/theme-chalk/dark/css-vars.css' // 引入暗色主题样式
+initApp.use(ElementPlus, {
+    locale: zhCn,
+})
 // 如果您正在使用CDN引入,请删除下面一行。
 import * as ElementPlusIconsVue from '@element-plus/icons-vue'
+import JsonViewer from 'vue-json-viewer'
+initApp.component('JsonViewer', JsonViewer)
 
 for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
     initApp.component(key, component)

+ 0 - 60
src/router/index-old.js

@@ -1,60 +0,0 @@
-import { createRouter, createWebHistory } from 'vue-router'
-
-const routes = [
-  {
-    path: '/',
-    name: 'home',
-    component: function () {
-      return import(/* webpackChunkName: "homepage" */ '../views/HomePage.vue')
-    }
-  },
-  {
-    path: '/data',
-    name: 'data',
-    component: function () {
-      return import(/* webpackChunkName: "data" */ '../views/Data.vue')
-    }
-  },
-  {
-    path: '/application',
-    name: 'application',
-    component: function () {
-      return import(/* webpackChunkName: "application" */ '../views/Application.vue')
-    }
-  },
-  {
-    path: '/function',
-    name: 'function',
-    component: function () {
-      return import(/* webpackChunkName: "funtcion" */ '../views/Function.vue')
-    }
-  },
-  {
-    path: '/development',
-    name: 'development',
-    component: function () {
-      return import(/* webpackChunkName: "development" */ '../views/Development.vue')
-    }
-  },
-  {
-    path: '/oamc',
-    name: 'oamc',
-    component: function () {
-      return import(/* webpackChunkName: "oamc" */ '../views/OAMC.vue')
-    }
-  },
-  {
-    path: '/display',
-    name: 'display',
-    component: function () {
-      return import(/* webpackChunkName: "display" */ '../views/Display.vue')
-    }
-  }
-]
-
-const router = createRouter({
-  history: createWebHistory(process.env.BASE_URL),
-  routes
-})
-
-export default router

+ 130 - 97
src/router/index.js

@@ -3,130 +3,163 @@ import { createRouter, createWebHistory } from 'vue-router'
 const routes = [
   {
     path: '/',
-    name: 'home',
+    name: 'root',
     component: function () {
-      return import('../views/HomePage.vue')
-    }
-  },
-  // 例子(开发时参考,生产环境中相关文件无意义)
-  {
-    path: '/example',
-    name: 'example',
-    component: function () {
-      return import('../views/Example.vue')
+      return import('../views/Root.vue')
     },
-    children: [ // 子路由配置开始
+    children: [
       {
-        path: 'example',
+        path: '/',
         component: function () {
-          return import('../views/example/Example.vue')
+          return import('../views/HomePage.vue')
         },
       },
       {
-        path: 'map',
+        path: '/sksjgl',
         component: function () {
-          return import('../views/example/Map.vue')
+          return import('../views/Sksjgl.vue')
         },
-      }
-    ], // 子路由配置结束
-  },
-
-  // 时空算子库
-  {
-    path: '/skszk',
-    name: 'skszk',
-    component: function () {
-      return import('../views/Skszk.vue')
-    },
-    children: [ // 子路由配置开始
+      },
       {
-        path: 'example',
+        path: '/wgn',
+        name: 'wgn',
         component: function () {
-          return import('../views/skszk/Example.vue')
+          return import('../views/Wgn.vue')
         },
-      }
-    ], // 子路由配置结束
-  },
-  // 时空门户
-  {
-    path: '/skmh',
-    name: 'skmh',
-    component: function () {
-      return import('../views/Skmh.vue')
-    },
-    children: [ // 子路由配置开始
+      },
       {
-        path: 'example',
+        path: 'skmh',
         component: function () {
-          return import('../views/skmh/Example.vue')
+          return import('../views/skmh/index.vue')
         },
-      }
-    ], // 子路由配置结束
-  },
-  // 微功能
-  {
-    path: '/wgn',
-    name: 'wgn',
-    component: function () {
-      return import('../views/Wgn.vue')
-    },
-    children: [ // 子路由配置开始
+      },
       {
-        path: 'example',
+        path: '/yxgl',
+        name: 'yxgl',
         component: function () {
-          return import('../views/wgn/Example.vue')
+          return import('../views/Yxgl.vue')
         },
-      }
-    ], // 子路由配置结束
-  },
-  // 应用管理
-  {
-    path: '/yygl',
-    name: 'yygl',
-    component: function () {
-      return import('../views/Yygl.vue')
-    },
-    children: [ // 子路由配置开始
+        children: [ // 子路由配置开始
+          {
+            path: 'StatisticalAnalysis',
+            component: function () {
+              return import('../views/yxgl/StatisticalAnalysis.vue')
+            },
+          }
+        ], // 子路由配置结束
+      },
+      //应用管理
       {
-        path: 'example',
+        path: '/yygl',
+        path: 'yygl',
         component: function () {
-          return import('../views/yygl/Example.vue')
-        },
-      }
-    ], // 子路由配置结束
-  },
-  // 信息反馈
-  {
-    path: '/xxfk',
-    name: 'xxfk',
-    component: function () {
-      return import('../views/Xxfk.vue')
-    },
-    children: [ // 子路由配置开始
+          return import('../views/yygl/index.vue')
+        }
+      },
+      //应用中心
       {
-        path: 'example',
+        path: 'appCenter',
+        path: 'appCenter',
         component: function () {
-          return import('../views/xxfk/Example.vue')
-        },
-      }
-    ], // 子路由配置结束
+          return import('../views/yygl/appCenter.vue')
+        }
+      },
+    ],
   },
-  // 运行管理
+  // {
+  //   path: '/example',
+  //   name: 'example',
+  //   component: function () {
+  //     return import('../views/Example.vue')
+  //   },
+  //   children: [ // 子路由配置开始
+  //     {
+  //       path: '/yygl',
+  //       path: 'yygl',
+  //       component: function () {
+  //         return import('../views/yygl/index.vue')
+  //       }
+  //     },
+  //     //应用中心
+  //     {
+  //       path: 'appCenter',
+  //       path: 'appCenter',
+  //       component: function () {
+  //         return import('../views/yygl/appCenter.vue')
+  //       }
+  //     },
+  //   ],
+  // },
+
+  /***************** 跳转单页面 ******************/
+  // 时空门户
+  // {
+  //   path: '/skmh',
+  //   name: 'skmh',
+  //   component: function () {
+  //     return import('../views/skmh/index.vue')
+  //   },
+  //   children: [ // 子路由配置开始
+  //     {
+  //       path: 'example',
+  //       component: function () {
+  //         return import('../views/skmh/Example.vue')
+  //       }
+  //     },
+  //     {
+  //       path: 'index',
+  //       component: function () {
+  //         return import('../views/skmh/index.vue')
+  //       }
+  //     },
+  //     {
+  //       path: 'scene',
+  //       component: function () {
+  //         return import('../views/skmh/scene/index.vue')
+  //       }
+  //     }
+  //   ], // 子路由配置结束
+  // },
+  // 微功能
   {
-    path: '/yxgl',
-    name: 'yxgl',
+    path: '/wgnSingle',
+    name: 'wgnSingle',
     component: function () {
-      return import('../views/Yxgl.vue')
+      return import('../views/wgn/Example.vue')
     },
-    children: [ // 子路由配置开始
-      {
-        path: 'example',
-        component: function () {
-          return import('../views/yxgl/Example.vue')
-        },
-      }
-    ], // 子路由配置结束
   },
+  // 应用管理
+  // {
+  //   path: '/yygl',
+  //   name: 'yygl',
+  //   component: function () {
+  //     return import('../views/Yygl.vue')
+  //   },
+  //   children: [ // 子路由配置开始
+  //     {
+  //       path: 'example',
+  //       component: function () {
+  //         return import('../views/yygl/Example.vue')
+  //       },
+  //     },
+  //   ], // 子路由配置结束
+  // },
+  // 运行管理
+  // {
+  //   path: '/yxgl',
+  //   name: 'yxgl',
+  //   component: function () {
+  //     return import('../views/Yxgl.vue')
+  //   },
+  //   children: [ // 子路由配置开始
+  //     {
+  //       path: 'StatisticalAnalysis',
+  //       component: function () {
+  //         return import('../views/yxgl/StatisticalAnalysis.vue')
+  //       },
+  //     }
+  //   ], // 子路由配置结束
+  // },
 ]
 
 const router = createRouter({

+ 1 - 2
src/store/index.js

@@ -8,11 +8,10 @@ export default createStore({
     userState: false,
     userInfo: null,
 
-    skszk: {},
+    sksjgl: {},
     skmh: {},
     wgn: {},
     yygl: {},
-    xxfk: {},
     yxgl: {}
   },
   getters: {

+ 21 - 0
src/utils/request.js

@@ -143,6 +143,26 @@ function postform(url, data) {
     })
   })
 }
+function postBody(url, data) {
+  return new Promise((resolve, reject) => {
+    let params = {
+      method: 'POST',
+      url,
+      data: data,
+      headers: {
+        'Content-Type': 'application/json;'
+      }
+    };
+    if (url.indexOf('downloadFile') != -1) {
+      params.responseType = 'blob';
+    }
+    service(params).then(res => {
+      resolve(res.data);
+    }).catch(err => {
+      reject(err);
+    })
+  })
+}
 
 function put(url, data) {
   return new Promise((resolve, reject) => {
@@ -280,6 +300,7 @@ export {
   put,
   putform,
   postform,
+  postBody,
   delform,
   postFile,
   getFile,

+ 0 - 157
src/views-old/Application.vue

@@ -1,157 +0,0 @@
-<template>
-  <div class="application container">
-    <div class="part1">
-      <div class="title">应用中心</div>
-      <p>收集、管理区级应用的访问地址、使用单位、使用情况等。区委办局、街镇、居村应基于区级节点开展区级时空应用建设。</p>
-    </div>
-    <div class="part2">
-      <div class="service" v-for="(item, index) in projectList" :key="index">
-        <div class="img" :style="{backgroundImage: 'url(' + item.bgUrl + ')' }"></div>
-        <h2 class="title">{{item.title}}</h2>
-        <div class="type">访问类型:{{item.visitType}}</div>
-        <div class="company">建设单位:{{item.company}}</div>
-        <div class="time">建设时间:{{item.time}}</div>
-      </div>
-    </div>
-  </div>
-</template>
-
-<script>
-import bg1 from "@/assets/images/common/app-bg-1.png";
-import bg2 from "@/assets/images/common/app-bg-2.png";
-import bg3 from "@/assets/images/common/app-bg-3.png";
-import bg4 from "@/assets/images/common/app-bg-4.png";
-export default {
-  name: "Application",
-  data() {
-    return {
-      projectList: [
-        {
-          title: "青浦区环境自动监测信息化平台",
-          visitType: "公开",
-          company: "青浦区环境局",
-          time: "2024.10.25",
-          bgUrl: bg1
-        },
-        {
-          title: "青浦区燃气行业监管平台",
-          visitType: "公开",
-          company: "青浦区环境局",
-          time: "2024.10.25",
-          bgUrl: bg2
-        },
-        {
-          title: "青浦区环境自动监测信息化平台",
-          visitType: "公开",
-          company: "青浦区环境局",
-          time: "2024.10.25",
-          bgUrl: bg3
-        },
-        {
-          title: "青浦区消防救援平台支队一网统管平台",
-          visitType: "公开",
-          company: "青浦区环境局",
-          time: "2024.10.25",
-          bgUrl: bg4
-        }
-      ]
-    };
-  }
-};
-</script>
-
-<style lang="less" scoped>
-.container {
-  width: 1920px;
-  margin: 0 auto;
-}
-.application {
-  .part1 {
-    width: 100%;
-    height: 644px;
-    background: url(~@/assets/images/common/u661.png) no-repeat;
-    position: relative;
-    color: #ffffff;
-    .title {
-      position: absolute;
-      top: 160px;
-      left: 120px;
-      font-family: "微软雅黑 Bold", "微软雅黑", sans-serif;
-      font-size: 50px;
-      font-weight: bold;
-    }
-    p {
-      position: absolute;
-      top: 250px;
-      left: 120px;
-      font-family: "微软雅黑 Light", "微软雅黑", sans-serif;
-      font-size: 24px;
-      width: 630px;
-    }
-  }
-
-  .part2 {
-    width: 100%;
-    background: #08224a;
-    padding-top: 40px;
-    padding-bottom: 1px;
-    .service {
-      margin: 0 30px;
-      width: 730px;
-      height: 520px;
-      display: inline-block;
-      box-sizing: border-box;
-      overflow: hidden;
-      position: relative;
-      color: #ffffff;
-
-      .img {
-        width: 730px;
-        height: 360px;
-        background-repeat: no-repeat;
-        background-size: 100% 100%;
-        border-radius: 10px;
-      }
-
-      .tag {
-        border-width: 0px;
-        width: 213px;
-        height: 52px;
-        line-height: 52px;
-        text-align: center;
-        background: inherit;
-        background-color: rgba(226, 228, 244, 1);
-        border-radius: 5px;
-        filter: drop-shadow(none);
-        transition: none;
-        font-size: 20px;
-        color: #7281ee;
-        margin-bottom: 20px;
-      }
-      .title {
-        position: relative;
-        height: 30px;
-        line-height: 30px;
-        font-size: 30px;
-        text-align: left;
-        padding-bottom: 20px;
-        margin-top: 20px;
-      }
-
-      p {
-        font-size: 20px;
-        line-height: 1.5;
-      }
-    }
-    > :nth-child(2n + 1) {
-      margin-left: 140px;
-      margin-right: 90px;
-    }
-
-    > :nth-child(2n) {
-      margin-left: 90px;
-      margin-right: 140px;
-    }
-  }
-}
-</style>

+ 0 - 19
src/views-old/Data.vue

@@ -1,19 +0,0 @@
-<template>
-  <div class="data container">数据中心</div>
-</template>
-
-<script>
-export default {
-  name: "Data"
-};
-</script>
-
-<style lang="less" scoped>
-.container {
-  width: 1920px;
-  margin: 0 auto;
-}
-.data {
-   
-}
-</style>

+ 0 - 135
src/views-old/Development.vue

@@ -1,135 +0,0 @@
-<template>
-  <div class="development container">
-    <div class="part1">
-      <div class="title">开发中心</div>
-      <p>提供集成低代码、开发示例、开发手册等模块内容,实现代码、文档和多种开发资源的集中管理,为开发人员提供有关软件、应用程序或系统的全面指导。</p>
-      <el-button size="large" type="primary">点击进入</el-button>
-    </div>
-    <div class="part2">
-      <div class="service" v-for="(item, index) in projectList" :key="index">
-        <div class="img" :style="{backgroundImage: 'url(' + item.bgUrl + ')' }">
-          <div class="label">{{ item.label }}</div>
-        </div>
-        <div class="content">{{ item.content }}</div>
-      </div>
-    </div>
-  </div>
-</template>
-
-<script>
-import bg1 from "@/assets/images/common/dev-bg-1.png";
-import bg2 from "@/assets/images/common/dev-bg-2.png";
-export default {
-  name: "Development",
-  data() {
-    return {
-      projectList: [
-        {
-          label: "开发示例",
-          content:
-            "提供开发示例。展示多模型示例,提供详细于发样例,演示技术的框架或库的用法,通过查看和理解示例代码,开发者可以更迅速地掌握新技术的基本用法和功能。",
-          bgUrl: bg1
-        },
-        {
-          label: "开发手册",
-          content:
-            "包含二三维一体化平台。实现场景快速搭建能力,允许用户以较少的代码量快速开发应用程序,通过最小化手动编码的需求,加速应用程序和业务流程的开发,使非专业开发人员也能参与应用程序的构建和定制。",
-          bgUrl: bg2
-        }
-      ]
-    };
-  }
-};
-</script>
-
-<style lang="less" scoped>
-.container {
-  width: 1920px;
-  margin: 0 auto;
-}
-.development {
-  .part1 {
-    width: 100%;
-    height: 500px;
-    background: url(~@/assets/images/common/u720.png) no-repeat;
-    position: relative;
-    color: #ffffff;
-    .title {
-      position: absolute;
-      top: 120px;
-      left: 120px;
-      font-family: "微软雅黑 Bold", "微软雅黑", sans-serif;
-      font-size: 50px;
-      font-weight: bold;
-    }
-    p {
-      position: absolute;
-      top: 210px;
-      left: 120px;
-      font-family: "微软雅黑 Light", "微软雅黑", sans-serif;
-      font-size: 24px;
-      width: 630px;
-    }
-    .el-button {
-      position: absolute;
-      top: 330px;
-      left: 120px;
-      font-size: 24px;
-      padding-top: 20px;
-      padding-bottom: 20px;
-    }
-  }
-  .part2 {
-    width: 100%;
-    background: #08224a;
-    padding-top: 40px;
-    padding-bottom: 1px;
-    .service {
-      margin: 0 30px;
-      width: 560px;
-      height: 700px;
-      display: inline-block;
-      box-sizing: border-box;
-      overflow: hidden;
-      position: relative;
-      color: #ffffff;
-      .img {
-        width: 480px;
-        height: 480px;
-        background-repeat: no-repeat;
-        background-size: 100% 100%;
-        border-radius: 10px;
-        position: relative;
-        margin: 0 auto;
-      }
-      .label {
-        position: absolute;
-        height: 30px;
-        line-height: 30px;
-        font-size: 30px;
-        text-align: left;
-        bottom: 80px;
-        width: 120px;
-        padding: 10px 10px;
-        border-radius: 5px;
-        left: calc(50% - 70px);
-        background: #062141;
-      }
-      .content {
-        margin-top: 20px;
-        font-size: 20px;
-        line-height: 1.5;
-      }
-    }
-    > :nth-child(2n + 1) {
-      margin-left: 280px;
-      margin-right: 120px;
-    }
-
-    > :nth-child(2n) {
-      margin-left: 120px;
-      margin-right: 280px;
-    }
-  }
-}
-</style>

+ 0 - 19
src/views-old/Display.vue

@@ -1,19 +0,0 @@
-<template>
-  <div class="display container">综合展示</div>
-</template>
-
-<script>
-export default {
-  name: "Display"
-};
-</script>
-
-<style lang="less" scoped>
-.container {
-  width: 1920px;
-  margin: 0 auto;
-}
-.display {
-  height: 1500px;
-}
-</style>

+ 0 - 28
src/views-old/Function.vue

@@ -1,28 +0,0 @@
-<template>
-  <div class="function container">
-    <div class="part1">
-      <div class="title">微功能中心</div>
-      <div class="subtitle">服务介绍</div>
-      三数据服务是围绕二维地理信息数据展开的综合服务体系。它涵盖以像元阵列形式存储的栅格服务,广泛应用于影像地图展示、地形分析等;通过将地图切割成小图片进行快速加载的瓦片服务,提升地图浏览流畅度;能够精确表达地理要素几何形状和属性的矢量时空数据服务,记录地理对象随时间的变化;以及包含特定主题数据集合的专题库服务,如交通专题库、土地利用专题库等,满足不同行业对特定地理信息的深度挖掘与分析需求,为城市规划、资源管理、环境监测等领域提供有力的数据支撑。
-    </div>
-    <div class="part2"></div>
-  </div>
-</template>
-
-<script>
-export default {
-  name: "Function"
-};
-</script>
-
-<style lang="less" scoped>
-.container {
-  width: 1920px;
-  margin: 0 auto;
-}
-
-.function {
-  width: 100%;
-  height: 644px;
-}
-</style>

+ 0 - 791
src/views-old/HomePage.vue

@@ -1,791 +0,0 @@
-<template>
-  <div class="home container">
-    <div class="part1">
-      <div class="part1-1">
-        <div class="part1-1-1">
-          <div class="number-container">
-            <span class="text">调用总数</span>
-            <span v-for="(num,index) in totalCall" :key="index">
-              <span v-if="num.indexOf(',')>-1">
-                <span class="separator">,</span>
-              </span>
-              <span v-else>
-                <span class="number-item">{{ num }}</span>
-              </span>
-            </span>
-            <span class="text">次</span>
-          </div>
-        </div>
-        <div class="part1-1-2">
-          <div class="call-count-container">
-            <div class="line"></div>
-            <div>
-              <span class="text1">当日调用量</span>
-              <span class="count">{{ todayCall }}</span>
-              <span class="text2">次</span>
-            </div>
-            <div class="line"></div>
-          </div>
-        </div>
-      </div>
-      <div class="part1-2">
-        <div class="part1-2-1">
-          <div>服务总数</div>
-          <div>{{ serveNum }}个</div>
-        </div>
-        <div class="part1-2-2">
-          <div>授权用户数</div>
-          <div>{{ userNum }}个</div>
-        </div>
-        <div class="part1-2-3">
-          <div>授权应用数</div>
-          <div>{{ appNum }}个</div>
-        </div>
-      </div>
-      <div class="part1-3">
-        <div id="echart1"></div>
-      </div>
-    </div>
-    <div class="part2">
-      <div class="chapter">核心服务</div>
-      <div class="row">
-        <div class="service">
-          <h2 class="title yellow">空间数据查询</h2>
-          <p>空间数据查询是从空间数据集中检索特定信息的操作。它可在关系型数据库如MySQL和SQL Server中进行,也能在NoSQL数据库如MongoDB里实现。通过特定函数和方法,能快速找到符合条件的数据,为地理信息等领域提供重要支持。</p>
-        </div>
-        <div class="service">
-          <h2 class="title gray">数据分析</h2>
-          <p>空间数据查询是从空间数据集中检索特定信息的操作。它可在关系型数据库如MySQL和SQL Server中进行,也能在NoSQL数据库如MongoDB里实现。通过特定函数和方法,能快速找到符合条件的数据,为地理信息等领域提供重要支持。</p>
-        </div>
-        <div class="service">
-          <h2 class="title blue">可视化服务</h2>
-          <p>空间数据查询是从空间数据集中检索特定信息的操作。它可在关系型数据库如MySQL和SQL Server中进行,也能在NoSQL数据库如MongoDB里实现。通过特定函数和方法,能快速找到符合条件的数据,为地理信息等领域提供重要支持。</p>
-        </div>
-      </div>
-      <div class="row">
-        <div class="service">
-          <h2 class="title orange">空间数据查询</h2>
-          <p>空间数据查询是从空间数据集中检索特定信息的操作。它可在关系型数据库如MySQL和SQL Server中进行,也能在NoSQL数据库如MongoDB里实现。通过特定函数和方法,能快速找到符合条件的数据,为地理信息等领域提供重要支持。</p>
-        </div>
-        <div class="service">
-          <h2 class="title green">数据分析</h2>
-          <p>空间数据查询是从空间数据集中检索特定信息的操作。它可在关系型数据库如MySQL和SQL Server中进行,也能在NoSQL数据库如MongoDB里实现。通过特定函数和方法,能快速找到符合条件的数据,为地理信息等领域提供重要支持。</p>
-        </div>
-        <div class="service">
-          <h2 class="title yellow-green">可视化服务</h2>
-          <p>空间数据查询是从空间数据集中检索特定信息的操作。它可在关系型数据库如MySQL和SQL Server中进行,也能在NoSQL数据库如MongoDB里实现。通过特定函数和方法,能快速找到符合条件的数据,为地理信息等领域提供重要支持。</p>
-        </div>
-      </div>
-    </div>
-    <div class="part3">
-      <div class="container">
-        <h1>二三维一体化引擎</h1>
-        <p>
-          GIS 通用计算功能,实用便捷超乎想象!
-          <br />测距、剖面分析及点线面绘制轻松实现,坐标转换精准高效,路径规划快速准确,地名搜索智能推荐
-        </p>
-        <el-button type="primary" size="large">了解更多</el-button>
-      </div>
-    </div>
-    <div class="part4">
-      <div class="chapter">实践与探索</div>
-      <div class="row">
-        <div class="service">
-          <h2 class="title yellow">空间数据查询</h2>
-          <p>空间数据查询是从空间数据集中检索特定信息的操作。它可在关系型数据库如MySQL和SQL Server中进行,也能在NoSQL数据库如MongoDB里实现。通过特定函数和方法,能快速找到符合条件的数据,为地理信息等领域提供重要支持。</p>
-          <el-button size="large" link>了解详情→</el-button>
-        </div>
-        <div class="service">
-          <h2 class="title gray">数据分析</h2>
-          <p>空间数据查询是从空间数据集中检索特定信息的操作。它可在关系型数据库如MySQL和SQL Server中进行,也能在NoSQL数据库如MongoDB里实现。通过特定函数和方法,能快速找到符合条件的数据,为地理信息等领域提供重要支持。</p>
-          <el-button size="large" link>了解详情→</el-button>
-        </div>
-        <div class="service">
-          <h2 class="title blue">可视化服务</h2>
-          <p>空间数据查询是从空间数据集中检索特定信息的操作。它可在关系型数据库如MySQL和SQL Server中进行,也能在NoSQL数据库如MongoDB里实现。通过特定函数和方法,能快速找到符合条件的数据,为地理信息等领域提供重要支持。</p>
-          <el-button size="large" link>了解详情→</el-button>
-        </div>
-      </div>
-      <div class="row">
-        <div class="service">
-          <h2 class="title orange">空间数据查询</h2>
-          <p>空间数据查询是从空间数据集中检索特定信息的操作。它可在关系型数据库如MySQL和SQL Server中进行,也能在NoSQL数据库如MongoDB里实现。通过特定函数和方法,能快速找到符合条件的数据,为地理信息等领域提供重要支持。</p>
-          <el-button size="large" link>了解详情→</el-button>
-        </div>
-        <div class="service">
-          <h2 class="title green">数据分析</h2>
-          <p>空间数据查询是从空间数据集中检索特定信息的操作。它可在关系型数据库如MySQL和SQL Server中进行,也能在NoSQL数据库如MongoDB里实现。通过特定函数和方法,能快速找到符合条件的数据,为地理信息等领域提供重要支持。</p>
-          <el-button size="large" link>了解详情→</el-button>
-        </div>
-        <div class="service">
-          <h2 class="title yellow-green">可视化服务</h2>
-          <p>空间数据查询是从空间数据集中检索特定信息的操作。它可在关系型数据库如MySQL和SQL Server中进行,也能在NoSQL数据库如MongoDB里实现。通过特定函数和方法,能快速找到符合条件的数据,为地理信息等领域提供重要支持。</p>
-          <el-button size="large" link>了解详情→</el-button>
-        </div>
-      </div>
-    </div>
-    <div class="part5">
-      <div class="chapter">应用案例</div>
-      <div class="part5-1">
-        <div class="part5-1-1">
-          <div>
-            约
-            <p>545</p>万次
-          </div>
-          <div>地址</div>
-        </div>
-        <div class="part5-1-2">
-          <div>
-            <p>319</p>个
-          </div>
-          <div>应用场景</div>
-        </div>
-        <div class="part5-1-3">
-          <div>
-            约
-            <p>230</p>万条
-          </div>
-          <div>服务人数</div>
-        </div>
-      </div>
-      <div class="part5-2">
-        <div class="tab-container">
-          <div
-            v-for="(item) in tabs"
-            :key="item.key"
-            @click="currentTab = item.key"
-            :class="{'tab-item':true, 'tab-item-active': currentTab === item.key }"
-          >
-            <!-- <span class="tab-icon">{{ item.icon }}</span> -->
-            <span class="tab-title">{{ item.title }}</span>
-          </div>
-        </div>
-        <div class="row">
-          <div class="service">
-            <div class="content">
-              <div class="tag">盈港街道、夏阳街道</div>
-              <h2 class="title">上海市青浦区教育局·学区查询</h2>
-              <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean euismod bibendum laoreet. Proin gravida dolor sit amet lacus accumsan et viverra justo commodo. Proin sodales pulvinar sic tempor. Sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nam fermentum, nulla luctus pharetra vulputate, felis tellus mollis orci, sed rhoncus pronin sapien nunc accuan eget.</p>
-            </div>
-          </div>
-          <div class="service">
-            <div class="content">
-              <div class="tag">全区、快递实验室</div>
-              <h2 class="title">上海市青浦区快递实验室</h2>
-              <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean euismod bibendum laoreet. Proin gravida dolor sit amet lacus accumsan et viverra justo commodo. Proin sodales pulvinar sic tempor. Sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nam fermentum, nulla luctus pharetra vulputate, felis tellus mollis orci, sed rhoncus pronin sapien nunc accuan eget.</p>
-            </div>
-          </div>
-        </div>
-        <div class="row">
-             <div class="service">
-            <div class="content">
-              <div class="tag">盈港街道、夏阳街道</div>
-              <h2 class="title">上海市青浦区教育局·学区查询</h2>
-              <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean euismod bibendum laoreet. Proin gravida dolor sit amet lacus accumsan et viverra justo commodo. Proin sodales pulvinar sic tempor. Sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nam fermentum, nulla luctus pharetra vulputate, felis tellus mollis orci, sed rhoncus pronin sapien nunc accuan eget.</p>
-            </div>
-          </div>
-          <div class="service">
-            <div class="content">
-              <div class="tag">全区、快递实验室</div>
-              <h2 class="title">上海市青浦区快递实验室</h2>
-              <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean euismod bibendum laoreet. Proin gravida dolor sit amet lacus accumsan et viverra justo commodo. Proin sodales pulvinar sic tempor. Sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nam fermentum, nulla luctus pharetra vulputate, felis tellus mollis orci, sed rhoncus pronin sapien nunc accuan eget.</p>
-            </div>
-          </div>
-        </div>
-      </div>
-    </div>
-  </div>
-</template>
-
-<script>
-import * as echarts from "echarts";
-export default {
-  name: "Home",
-  data() {
-    return {
-      todayCall: "857,605",
-      totalCall: [],
-
-      serveNum: 456,
-      userNum: 17,
-      appNum: 43,
-
-      currentTab: "data-governance", // 初始选中项
-      tabs: [
-        { key: "data-governance", icon: "", title: "数据治理" },
-        { key: "business-app", icon: "", title: "业务应用" },
-        { key: "comprehensive-decision", icon: "", title: "综合决策" }
-      ]
-    };
-  },
-  mounted() {
-    this.handleTotalCallNumber(667507060);
-    this.setChart();
-  },
-  methods: {
-    // 处理调用总数数字
-    handleTotalCallNumber(num) {
-      // 667507060
-      let str = num.toString();
-      let strArr = str.split("").reverse();
-      this.totalCall = [];
-      for (let i = 0; i < strArr.length; i++) {
-        const num = strArr[i];
-        this.totalCall.unshift(num);
-        if (i % 3 == 2 && i != strArr.length - 1) {
-          this.totalCall.unshift(",");
-        }
-      }
-    },
-    setChart() {
-      // 基于准备好的dom,初始化echarts实例
-      var myChart = echarts.init(document.getElementById("echart1"));
-
-      let option = {
-        tooltip: {
-          trigger: "axis", // 坐标轴触发提示
-          axisPointer: { type: "shadow" }
-        },
-        legend: {
-          data: ["tokyo", "london"],
-          textStyle: { color: "#fff" } // 图例文字颜色
-        },
-        xAxis: {
-          type: "category",
-          data: [
-            "Jan",
-            "Feb",
-            "Mar",
-            "Apr",
-            "May",
-            "Jun",
-            "Jul",
-            "Aug",
-            "Sep",
-            "Oct",
-            "Nov"
-          ],
-          axisLine: { lineStyle: { color: "#fff" } }, // 坐标轴颜色
-          axisTick: { show: false }, // 隐藏刻度
-          splitLine: { show: false } // 隐藏分割线
-        },
-        yAxis: {
-          type: "value",
-          max: 30,
-          axisLine: { lineStyle: { color: "#fff" } },
-          splitLine: {
-            lineStyle: {
-              type: "dashed", // 虚线网格
-              color: "#fff"
-            }
-          }
-        },
-        series: [
-          {
-            name: "tokyo",
-            type: "line",
-            data: [7, 7, 15, 19, 21, 22, 25, 26, 23, 19, 12], // 模拟数据
-            lineStyle: { color: "#42a5f5" }, // 蓝色线条
-            itemStyle: { color: "#42a5f5" }, // 节点颜色
-            symbol: "circle", // 节点形状
-            symbolSize: 6 // 节点大小
-          },
-          {
-            name: "london",
-            type: "line",
-            data: [3, 3, 6, 12, 15, 17, 18, 17, 14, 10, 6], // 模拟数据
-            lineStyle: { color: "#4caf50" }, // 绿色线条
-            itemStyle: { color: "#4caf50" },
-            symbol: "circle",
-            symbolSize: 6
-          }
-        ]
-      };
-      // 绘制图表
-      myChart.setOption(option);
-    }
-  }
-};
-</script>
-
-<style lang="less" scoped>
-.container {
-  width: 1920px;
-  margin: 0 auto;
-}
-.home {
-  position: relative;
-  .part1 {
-    height: 810px;
-    background: url(~@/assets/images/common/home-bg1.png) no-repeat;
-    position: relative;
-    overflow: hidden;
-    .part1-1 {
-      width: 1000px;
-      height: 200px;
-      background: #09284c;
-      margin: 0 auto;
-      margin-top: 30px;
-      overflow: hidden;
-      .part1-1-1 {
-        height: 70px;
-        width: fit-content;
-        margin: 0 auto;
-        margin-top: 30px;
-        .number-container {
-          display: flex;
-          align-items: flex-start;
-          font-size: 2em;
-        }
-
-        .number-item {
-          width: 57px;
-          height: 70px;
-          background-color: #007bff;
-          color: white;
-          display: flex;
-          justify-content: center;
-          align-items: center;
-          margin-right: 20px;
-          font-size: 44px;
-          line-height: 70px;
-          font-weight: bold;
-        }
-
-        .separator {
-          margin-right: 20px;
-          font-size: 35px;
-          text-align: end;
-          color: #ffffff;
-        }
-
-        .text {
-          font-size: 24px;
-          line-height: 70px;
-          margin-right: 20px;
-          color: #ffffff;
-          font-weight: bold;
-        }
-      }
-      .part1-1-2 {
-        height: 50px;
-        width: 700px;
-        margin: 0 auto;
-        margin-top: 30px;
-        background: #8080804d;
-        border-radius: 5px;
-        line-height: 50px;
-
-        div {
-          display: inline-block;
-          vertical-align: top;
-          &.line {
-            height: 2px;
-            background: #808080;
-            width: 100px;
-            margin: 24px 20px;
-            margin-right: 20px;
-          }
-          &:nth-child(2) {
-            width: 420px;
-            text-align: center;
-            color: #ffffff;
-            font-size: 20px;
-            font-weight: bold;
-            .text1 {
-              margin-right: 20px;
-            }
-            .text2 {
-              margin-left: 20px;
-            }
-          }
-          &:nth-child(4) {
-            float: right;
-          }
-        }
-      }
-    }
-    .part1-2 {
-      color: #ffffff;
-      margin-top: 20px;
-      .part1-2-1,
-      .part1-2-2,
-      .part1-2-3 {
-        display: inline-block;
-        text-align: center;
-        font-weight: bold;
-        width: calc(100% / 3);
-        div:nth-child(1) {
-          font-size: 24px;
-        }
-        div:nth-child(2) {
-          margin-top: 10px;
-          font-size: 32px;
-        }
-      }
-    }
-    .part1-3 {
-      margin-top: 20px;
-      height: 450px;
-      overflow: hidden;
-      #echart1 {
-        width: 100%;
-        height: 100%;
-      }
-    }
-  }
-  .part2 {
-    background: #08224a;
-    padding-bottom: 1px;
-    .chapter {
-      text-align: center;
-      font-size: 40px;
-      width: 100%;
-      height: 80px;
-      line-height: 80px;
-      color: #ffffff;
-      font-weight: bold;
-      border-bottom: 2px solid gray;
-      margin-bottom: 20px;
-    }
-
-    .row {
-      display: flex;
-      justify-content: space-between;
-      margin-bottom: 20px;
-      padding: 0 100px;
-    }
-
-    .service {
-      flex: 1;
-      margin: 0 30px;
-      text-align: center;
-    }
-
-    .title {
-      position: relative;
-      padding-bottom: 10px;
-      margin-bottom: 15px;
-      height: 50px;
-      line-height: 90px;
-      font-size: 30px;
-    }
-
-    .title::before {
-      content: "";
-      position: absolute;
-      left: 0;
-      right: 0;
-      top: 0;
-      height: 15px;
-    }
-
-    .yellow {
-      color: #f1c40f;
-    }
-
-    .yellow::before {
-      background-color: #f1c40f;
-    }
-
-    .gray {
-      color: #bdc3c7;
-    }
-
-    .gray::before {
-      background-color: #bdc3c7;
-    }
-
-    .blue {
-      color: #3498db;
-    }
-
-    .blue::before {
-      background-color: #3498db;
-    }
-
-    .orange {
-      color: #e67e22;
-    }
-
-    .orange::before {
-      background-color: #e67e22;
-    }
-
-    .green {
-      color: #27ae60;
-    }
-
-    .green::before {
-      background-color: #27ae60;
-    }
-
-    .yellow-green {
-      color: #b2be2c;
-    }
-
-    .yellow-green::before {
-      background-color: #b2be2c;
-    }
-
-    p {
-      font-size: 20px;
-      line-height: 2;
-      color: #ffffff;
-    }
-  }
-
-  .part3 {
-    .container {
-      position: relative;
-      width: 100%;
-      height: 940px;
-      background-image: url("~@/assets/images/common/u30.png"); /* 替换为实际图片路径 */
-      background-size: cover;
-      background-position: center;
-      display: flex;
-      flex-direction: column;
-      justify-content: center;
-      align-items: center;
-      text-align: center;
-      color: #000000;
-      font-family: Arial, sans-serif;
-      overflow: hidden;
-    }
-
-    h1 {
-      position: absolute;
-      top: 30px;
-      font-size: 40px;
-      font-weight: bold;
-    }
-
-    p {
-      margin-bottom: 30px;
-      font-weight: bold;
-      font-size: 24px;
-      line-height: 2;
-    }
-    .el-button {
-      position: absolute;
-      bottom: 150px;
-    }
-  }
-
-  .part4 {
-    background: #08224a;
-    padding-bottom: 1px;
-    .chapter {
-      text-align: center;
-      font-size: 40px;
-      width: 100%;
-      height: 80px;
-      line-height: 80px;
-      color: #ffffff;
-      font-weight: bold;
-      /* border-bottom: 2px solid gray; */
-      margin-bottom: 20px;
-    }
-
-    .row {
-      display: flex;
-      justify-content: space-between;
-      margin-bottom: 40px;
-      padding: 0 100px;
-    }
-
-    .service {
-      flex: 1;
-      margin: 0 30px;
-      width: 500px;
-      height: 320px;
-      border: 1px solid gray;
-      border-radius: 8px;
-      padding: 10px 10px;
-      box-sizing: border-box;
-      overflow: hidden;
-      position: relative;
-    }
-
-    .title {
-      position: relative;
-      height: 30px;
-      line-height: 30px;
-      font-size: 30px;
-      text-align: left;
-      color: #ffffff;
-      padding-bottom: 20px;
-    }
-
-    p {
-      text-indent: 2rem;
-      font-size: 20px;
-      line-height: 2;
-      color: #ffffff;
-    }
-
-    .el-button {
-      position: absolute;
-      bottom: 10px;
-      left: 10px;
-      font-size: 20px;
-      color: #ffffff;
-      &:hover {
-        color: #3498db;
-      }
-    }
-  }
-
-  .part5 {
-    background: #08224a;
-    padding-bottom: 1px;
-    .chapter {
-      text-align: center;
-      font-size: 40px;
-      width: 100%;
-      height: 80px;
-      line-height: 80px;
-      color: #ffffff;
-      font-weight: bold;
-      /* border-bottom: 2px solid gray; */
-      margin-bottom: 20px;
-    }
-    .part5-1 {
-      color: #ffffff;
-      margin-top: 20px;
-      margin-bottom: 20px;
-      .part5-1-1,
-      .part5-1-2,
-      .part5-1-3 {
-        display: inline-block;
-        text-align: center;
-        font-weight: bold;
-        width: calc(100% / 3);
-        div {
-          font-size: 24px;
-        }
-        div:nth-child(2) {
-          margin-top: 10px;
-          font-size: 24px;
-        }
-        div p {
-          display: inline-block;
-          font-size: 40px;
-        }
-      }
-    }
-    .part5-2 {
-      margin-top: 40px;
-      padding-bottom: 1px;
-      height: fit-content;
-      .tab-container {
-        display: flex;
-        gap: 40px; /* 选项卡间距 */
-        // border-bottom: 1px solid #eee; /* 可选底部分隔线 */
-        width: fit-content;
-        margin: 0 auto;
-        position: relative;
-        margin-bottom: 40px;
-        height: 55px;
-      }
-      .tab-container::after {
-        content: "";
-        display: block;
-        height: 1px;
-        width: 100%;
-        background: #eeeeee; /* 下划线颜色 */
-        position: absolute;
-        bottom: 0;
-      }
-
-      .tab-item {
-        color: #ffffff;
-        cursor: pointer;
-        overflow: hidden;
-        position: relative;
-        font-size: 30px;
-        height: 55px;
-      }
-      .tab-item-active {
-        color: #66f; /* 选中文字颜色 */
-      }
-      .tab-item-active::after {
-        content: "";
-        display: block;
-        height: 2px;
-        width: 100%;
-        background: #66f; /* 下划线颜色 */
-        margin-top: 5px;
-        position: absolute;
-        bottom: 0;
-        z-index: 1;
-      }
-      .tab-icon {
-        margin-right: 5px; /* 图标与文字间距 */
-      }
-
-      .row {
-        display: flex;
-        justify-content: space-between;
-        margin-bottom: 40px;
-        padding: 0 120px;
-        > :nth-child(1) {
-          background: url(~@/assets/images/common/u301.png) no-repeat 0 0/100%;
-        }
-        > :nth-child(2) {
-          background: url(~@/assets/images/common/u302.png) no-repeat 0 0/100%;
-        }
-      }
-
-      .service {
-        flex: 1;
-        margin: 0 30px;
-        height: 660px;
-        border: 1px solid gray;
-        border-radius: 10px;
-        box-sizing: border-box;
-        overflow: hidden;
-        position: relative;
-        .content {
-          position: absolute;
-          bottom: 0;
-          width: 100%;
-          height: 430px;
-          background: #ffffff;
-          border-radius: 10px;
-          padding: 20px 20px;
-          box-sizing: border-box;
-          .tag {
-            border-width: 0px;
-            width: 213px;
-            height: 52px;
-            line-height: 52px;
-            text-align: center;
-            background: inherit;
-            background-color: rgba(226, 228, 244, 1);
-            border-radius: 5px;
-            filter: drop-shadow(none);
-            transition: none;
-            font-size: 20px;
-            color: #7281ee;
-            margin-bottom: 20px;
-          }
-          .title {
-            position: relative;
-            height: 30px;
-            line-height: 30px;
-            font-size: 30px;
-            text-align: left;
-            padding-bottom: 20px;
-          }
-
-          p {
-            font-size: 20px;
-            line-height: 1.5;
-          }
-        }
-      }
-    }
-  }
-}
-</style>

+ 0 - 19
src/views-old/OAMC.vue

@@ -1,19 +0,0 @@
-<template>
-  <div class="oamc container">运管中心</div>
-</template>
-
-<script>
-export default {
-  name: "OAMC"
-};
-</script>
-
-<style lang="less" scoped>
-.container {
-  width: 1920px;
-  margin: 0 auto;
-}
-.oamc {
-  height: 1500px;
-}
-</style>

+ 0 - 32
src/views/Example.vue

@@ -1,32 +0,0 @@
-<template>
-    <div class="example container">
-        <router-view />
-    </div>
-</template>
-
-<script>
-export default {
-    name: "example",
-    data() {
-        return {
-
-        };
-    },
-    mounted() {
-    },
-    methods: {
-    }
-};
-</script>
-
-<style lang="less" scoped>
-.container {
-    width: 1920px;
-    min-height: 100%;
-    margin: 0 auto;
-}
-
-.example {
-    position: relative;
-}
-</style>

+ 17 - 12
src/views/HomePage.vue

@@ -596,6 +596,11 @@ export default {
     this.initChart2();
   },
   methods: {
+    gotoDetail() {
+      this.$router.push({
+        path: "/sksjgl",
+      });
+    },
     // 处理调用总数数字
     handleTotalCallNumber(num) {
       // 667507060
@@ -617,11 +622,11 @@ export default {
       let option = {
         tooltip: {
           trigger: "axis", // 坐标轴触发提示
-          axisPointer: { type: "shadow" }
+          axisPointer: { type: "shadow" },
         },
         legend: {
           data: ["tokyo", "london"],
-          textStyle: { color: "#fff" } // 图例文字颜色
+          textStyle: { color: "#fff" }, // 图例文字颜色
         },
         xAxis: {
           type: "category",
@@ -636,11 +641,11 @@ export default {
             "Aug",
             "Sep",
             "Oct",
-            "Nov"
+            "Nov",
           ],
           axisLine: { lineStyle: { color: "#fff" } }, // 坐标轴颜色
           axisTick: { show: false }, // 隐藏刻度
-          splitLine: { show: false } // 隐藏分割线
+          splitLine: { show: false }, // 隐藏分割线
         },
         yAxis: {
           type: "value",
@@ -649,9 +654,9 @@ export default {
           splitLine: {
             lineStyle: {
               type: "dashed", // 虚线网格
-              color: "#fff"
-            }
-          }
+              color: "#fff",
+            },
+          },
         },
         series: [
           {
@@ -661,7 +666,7 @@ export default {
             lineStyle: { color: "#42a5f5" }, // 蓝色线条
             itemStyle: { color: "#42a5f5" }, // 节点颜色
             symbol: "circle", // 节点形状
-            symbolSize: 6 // 节点大小
+            symbolSize: 6, // 节点大小
           },
           {
             name: "london",
@@ -670,9 +675,9 @@ export default {
             lineStyle: { color: "#4caf50" }, // 绿色线条
             itemStyle: { color: "#4caf50" },
             symbol: "circle",
-            symbolSize: 6
-          }
-        ]
+            symbolSize: 6,
+          },
+        ],
       };
       // 绘制图表
       myChart.setOption(option);
@@ -1498,4 +1503,4 @@ export default {
     }
   }
 }
-</style>
+</style>

+ 60 - 0
src/views/Root.vue

@@ -0,0 +1,60 @@
+<template>
+  <div class="main">
+    <Header @updateScroll="updateScrollbar"></Header>
+    <el-scrollbar ref="pagescrollbar">
+      <router-view />
+    </el-scrollbar>
+    <Footer></Footer>
+  </div>
+</template>
+
+<script>
+import { defineAsyncComponent, toRaw } from "vue";
+export default {
+  name: "Home",
+  data() {
+    return {
+      todayCall: "857,605",
+      totalCall: [],
+
+      serveNum: 456,
+      userNum: 17,
+      appNum: 43,
+
+      currentTab: "data-governance", // 初始选中项
+      tabs: [
+        { key: "data-governance", icon: "", title: "数据治理" },
+        { key: "business-app", icon: "", title: "业务应用" },
+        { key: "comprehensive-decision", icon: "", title: "综合决策" },
+      ],
+    };
+  },
+  components: {
+    Header: defineAsyncComponent(() =>
+      import("@/components/AppVue/Header.vue")
+    ),
+    Footer: defineAsyncComponent(() => import("@/components/AppVue/Footer.vue"))
+  },
+  methods: {
+    updateScrollbar() {
+      this.$refs.pagescrollbar.setScrollTop(0)
+    }
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.main {
+  width: 100%;
+  height: 100%;
+  margin: 0 auto;
+  overflow: hidden;
+
+  .el-scrollbar {
+    width: 100%;
+    height: calc(100% - 120px);
+    box-sizing: border-box;
+    overflow: auto;
+  }
+}
+</style>

+ 371 - 0
src/views/Sksjgl.vue

@@ -0,0 +1,371 @@
+<template>
+    <div class="sksjgl container">
+        <div class="server_title">
+            <el-image style="width: 824px; height: 786px" src="static/images/sksjgl/sksjgl_title.png" fit="cover" />
+            <div class="server_title_text">
+                <div class="server_title_text_title">时空数据管理</div>
+                <div class="server_title_text_content">
+                    二维数据服务是围绕二维地理信息数据展开的综合服务体系。它涵盖以像元阵列形式存储的栅格服务,广泛应用于影像地图展示、地形分析等;通过将地图切割成小图片进行快速加载的瓦片服务,提升地图浏览流畅度;能够精确表达地理要素几何形状和属性的矢量时空数据服务,记录地理对象随时间的变化;以及包含特定主题数据集合的专题库服务,如交通专题库、土地利用专题库等,满足不同行业对特定地理信息的深度挖掘与分析需求,为城市规划、资源管理、环境监测等领域提供有力的数据支撑。
+                </div>
+            </div>
+        </div>
+        <div class="checkModule">
+            <!-- 流程步骤 -->
+            <div class="process-bar">
+                <div :class="{ 'process-item': true, 'active': activePanel == 'sjzljc' }"
+                    @click="changePanel('sjzljc')">
+                    <div class="icon-box"> </div>
+                    <div class="label">数据质量检查</div>
+                </div>
+                <div class="divider"></div>
+                <div :class="{ 'process-item': true, 'active': activePanel == 'sksjjg' }"
+                    @click="changePanel('sksjjg')">
+                    <div class="icon-box"></div>
+                    <div class="label">时空数据加工</div>
+                </div>
+                <div class="divider"></div>
+                <div :class="{ 'process-item': true, 'active': activePanel == 'sksjgl' }"
+                    @click="changePanel('sksjgl')">
+                    <div class="icon-box"></div>
+                    <div class="label">时空数据管理</div>
+                </div>
+                <div class="divider"></div>
+                <div :class="{ 'process-item': true, 'active': activePanel == 'sksjfb' }"
+                    @click="changePanel('sksjfb')">
+                    <div class="icon-box"></div>
+                    <div class="label">时空数据发布</div>
+                </div>
+            </div>
+            <!-- 流程内容 -->
+            <div class="process-content">
+                <div class="process-content-item" v-for="(item, index) in nowFuncContent" :key="index">
+                    <a :href="item.url" target="_blank" rel="noopener noreferrer">
+                        <div class="pictrue"
+                            :style="{ background: 'url(' + item.image + ') no-repeat center center/100% 100%' }"></div>
+                        <div class="label">{{ item.label }}</div>
+                    </a>
+                </div>
+            </div>
+        </div>
+        <div class="time-space-operator-lib">
+            <!-- 标题区域 -->
+            <div class="title-section">
+                <h1>时空算子库</h1>
+            </div>
+            <!-- 描述区域 -->
+            <div class="desc-section">
+                <p>
+                    时空算子库具备丰富且强大的功能能力,在空间计算方面,涵盖量托轮廓下的宽度和面积计算,可利用投影坐标系结合既定定理与比例尺换算公式计算宽度,将多边形分割成三角形计算面积;还能判断点线面体的相互状态,通过计算点到线距离、射线法等方式判断点与线、面关系,利用计算几何方法判断线与线、线与面、体与点线面的关系;可进行缓冲区计算,以点、线、面为基础按给定距离生成缓冲区,支持线面体分割,依据指定规则对其进行分割并重新构建边和拓扑关系。在时空分析方面,能够对个面进行时空差异分析,判断空间重叠部分并通过求差来得到不相交面,同时考虑时间因素分析不同时间点面的状态变化。
+                </p>
+            </div>
+            <!-- 业务专区区域 -->
+            <div class="business-section">
+                <div class="business-header">
+                    <span>业务专属时空数据</span>
+                    <button class="more-btn">查看更多</button>
+                </div>
+                <!-- 功能卡片列表 -->
+                <!-- 单个功能卡片 -->
+                <div class="card-item" v-for="(item, index) in cardList" :key="index">
+                    <div class="card-title">{{ item.title }}</div>
+                    <div class="card-bg" :style="{ backgroundColor: item.bgColor }"></div>
+                    <div class="card-desc">{{ item.desc }}</div>
+                </div>
+            </div>
+
+        </div>
+
+    </div>
+</template>
+
+<script>
+export default {
+    data() {
+        return {
+            activePanel: 'sjzljc',
+            funcList: systemConfig.sksjgl.funcList,
+            nowFuncContent: [],
+
+            cardList: [
+                {
+                    title: "量托计算宽度面积",
+                    bgColor: "#1a4b8e",
+                    desc: "城市水系承载空间分析数据,包括主干道网和街道直径"
+                },
+                {
+                    title: "设置障碍的路径计算",
+                    bgColor: "#3a3a4a",
+                    desc: "城市大气降水水位时空监测,数据的历史分析"
+                },
+                {
+                    title: "判断点线面体的相互状态",
+                    bgColor: "#5a3a7a",
+                    desc: "公共服务设施分布分析,包含医院、教育、交通等场所"
+                },
+                {
+                    title: "缓冲区计算",
+                    bgColor: "#2a7a5a",
+                    desc: "农业用地分布现状与种植结构空间数据、全域耕地空间"
+                },
+                {
+                    title: "线面体分割",
+                    bgColor: "#1a5a8a",
+                    desc: "主要河网分布与水文监测数据、流域相关大数据"
+                },
+                {
+                    title: "时空差异分析",
+                    bgColor: "#1a6a9a",
+                    desc: "主要河网分布与水文监测数据、流域相关大数据"
+                }
+            ]
+        };
+    },
+    mounted() {
+        this.changePanel(this.activePanel)
+    },
+    methods: {
+        changePanel(active) {
+            this.activePanel = active;
+            this.nowFuncContent = this.funcList[this.activePanel]
+        }
+    }
+};
+</script>
+
+<style lang="less" scoped>
+.container {
+    width: 1920px;
+    margin: 0 auto;
+
+    .server_title {
+        display: flex;
+        justify-content: center;
+        align-items: center;
+
+        .server_title_text {
+            width: calc(100vw - 824px);
+            height: 786px;
+            background-color: #1c2631;
+            color: #fff;
+            padding: 0 160px 0 60px;
+            display: flex;
+            flex-direction: column;
+            justify-content: center;
+            overflow: hidden;
+
+            &_title {
+                font-size: 64px;
+                font-weight: bold;
+                letter-spacing: 0.5rem;
+            }
+
+            &_content {
+                margin-top: 77px;
+                font-size: 22px;
+            }
+        }
+    }
+
+    .checkModule {
+        width: 100%;
+        background-color: #0f2545;
+
+        /* 流程步骤样式 */
+        .process-bar {
+            width: fit-content;
+            margin: 0 auto;
+            padding-top: 100px;
+            padding-bottom: 100px;
+
+            .process-item {
+                width: 250px;
+                height: 200px;
+                display: inline-block;
+                color: #ffffff;
+                cursor: pointer;
+                border-radius: 10px;
+                padding: 10px 15px;
+
+                .icon-box {
+                    width: 90px;
+                    height: 90px;
+                    text-align: center;
+                    margin: 30px 80px 30px 80px;
+                }
+
+                .label {
+                    height: 50px;
+                    line-height: 50px;
+                    font-size: 24px;
+                    text-align: center;
+                    letter-spacing: 5px;
+                }
+
+                &.active {
+                    background-color: rgba(64, 149, 229, 0.69);
+                }
+
+                &:hover {
+                    background-color: rgba(64, 149, 229, 0.69);
+                }
+
+                &:nth-child(1) .icon-box {
+                    background: url("~@/assets/images/sksjgl/sjzljc.png") no-repeat center center/100% 100%;
+                }
+
+                &:nth-child(3) .icon-box {
+                    background: url("~@/assets/images/sksjgl/sksjjg.png") no-repeat center center/100% 100%;
+                }
+
+                &:nth-child(5) .icon-box {
+                    background: url("~@/assets/images/sksjgl/sksjgl.png") no-repeat center center/100% 100%;
+                }
+
+                &:nth-child(7) .icon-box {
+                    background: url("~@/assets/images/sksjgl/sksjfb.png") no-repeat center center/100% 100%;
+                }
+            }
+
+            .divider {
+                width: 60px;
+                height: 200px;
+                vertical-align: top;
+                display: inline-block;
+                background: url("~@/assets/images/sksjgl/jiantou.png") no-repeat center center/100%;
+            }
+        }
+
+        /* 流程内容样式 */
+        .process-content {
+            width: 100%;
+            padding: 50px 150px;
+            box-sizing: border-box;
+            display: flex;
+            /* 允许换行 */
+            flex-wrap: wrap;
+            /* 元素之间的间距(可选) */
+            gap: 75px;
+
+
+            .process-content-item {
+                /* 核心:每行2个,扣除gap间距 */
+                width: calc(50% - 40px);
+                height: 400px;
+                // background: #f0f8ff;
+                // border: 1px solid #409eff;
+
+                display: flex;
+                align-items: center;
+                justify-content: center;
+                font-size: 18px;
+                color: #333;
+
+                a {
+                    width: 100%;
+                    height: 100%;
+
+                    .pictrue {
+                        width: 100%;
+                        height: 361px;
+                        border-radius: 8px;
+                    }
+
+                    .label {
+                        color: #ffffff;
+                        text-align: center;
+                        height: 50px;
+                        line-height: 50px;
+                        font-size: 24px;
+                    }
+                }
+
+
+            }
+        }
+    }
+
+
+    .time-space-operator-lib {
+        background-color: #1e407c;
+        color: #fff;
+        padding: 50px 150px;
+        height: 700px;
+        box-sizing: border-box;
+
+        /* 标题区域 */
+        .title-section {
+            text-align: center;
+            margin-bottom: 20px;
+
+            h1 {
+                font-size: 28px;
+                font-weight: bold;
+            }
+        }
+
+        /* 描述区域 */
+        .desc-section {
+            margin-bottom: 30px;
+            line-height: 1.6;
+            font-size: 14px;
+            opacity: 0.9;
+        }
+
+        /* 业务专区区域 */
+        .business-section {
+            margin-top: 20px;
+
+            .business-header {
+                display: flex;
+                justify-content: space-between;
+                align-items: center;
+                margin-bottom: 15px;
+                font-size: 16px;
+
+                .more-btn {
+                    background-color: transparent;
+                    border: 1px solid #fff;
+                    color: #fff;
+                    padding: 4px 12px;
+                    border-radius: 4px;
+                    cursor: pointer;
+                }
+            }
+        }
+
+        /* 卡片列表 */
+        .card-list {
+            display: grid;
+            grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
+            gap: 20px;
+
+            .card-item {
+                background-color: rgba(255, 255, 255, 0.1);
+                padding: 15px;
+                border-radius: 8px;
+                height: 180px;
+                display: flex;
+                flex-direction: column;
+
+                .card-title {
+                    font-size: 15px;
+                    font-weight: 500;
+                    margin-bottom: 10px;
+                }
+
+                .card-bg {
+                    flex: 1;
+                    border-radius: 4px;
+                    margin: 8px 0;
+                }
+
+                .card-desc {
+                    font-size: 12px;
+                    opacity: 0.8;
+                    line-height: 1.4;
+                }
+            }
+        }
+    }
+}
+</style>

+ 0 - 31
src/views/Skszk.vue

@@ -1,31 +0,0 @@
-<template>
-    <div class="skszk container">
-        <router-view />
-    </div>
-</template>
-
-<script>
-export default {
-    name: "skszk",
-    data() {
-        return {
-
-        };
-    },
-    mounted() {
-    },
-    methods: {
-    }
-};
-</script>
-
-<style lang="less" scoped>
-.container {
-    width: 1920px;
-    margin: 0 auto;
-}
-
-.skszk {
-    position: relative;
-}
-</style>

+ 274 - 15
src/views/Wgn.vue

@@ -1,31 +1,290 @@
 <template>
-    <div class="wgn container">
-        <router-view />
+  <div class="container">
+    <div class="server_title">
+      <el-image
+        style="width: 824px; height: 786px"
+        src="static/images/wgn_title.png"
+        fit="cover"
+      />
+      <div class="server_title_text">
+        <div class="server_title_text_title">微功能服务</div>
+        <div class="server_title_text_content">
+          微功能子系统专注于提供强大的空间计算与数据处理能力,是支撑青浦区三维数字底板空间分析与数据流转的核心模块,聚焦
+          “精准计算 + 灵活处理”
+          两大核心能力,所有功能均以标准化服务接口形式对外提供(支持第三方委办、上层应用系统调用),同时在系统内部集成可视化操作界面,实现
+          “计算 - 分析 - 展示” 闭环。
+        </div>
+      </div>
     </div>
+    <div class="server_list_box">
+      <div class="server_list_box_title">微功能列表</div>
+      <div class="server_list_box_search">
+        功能搜索
+        <el-input
+          v-model="searchStr"
+          style="width: 525px; margin-left: 37px"
+          placeholder="输入搜索关键词"
+          class="input-with-select"
+          clearable
+          size="large"
+          @change="searchServerList()"
+        >
+          <template #append>
+            <el-button icon="Search" @click="searchServerList()" />
+          </template>
+        </el-input>
+      </div>
+      <div class="server_list_box_table" v-if="dmsServerList">
+        <div
+          v-for="item in dmsServerList"
+          :key="item.c_scene_name"
+          class="server_list_box_table_item"
+        >
+          <div class="server_list_box_table_item_content">
+            <div class="server_list_box_table_item_content_title">{{ item.title }}</div>
+            <div class="server_list_box_table_item_content_text">{{ item.content }}</div>
+            <div class="server_list_box_table_item_content_button_box">
+              <div
+                class="server_list_box_table_item_content_button_box_item"
+                @click.stop="handleOnlineDemo(item)"
+              >
+                在线演示
+              </div>
+              <div
+                class="server_list_box_table_item_content_button_box_item"
+                @click.stop="handleApply(item)"
+              >
+                申请使用
+              </div>
+            </div>
+          </div>
+          <div class="server_list_box_table_item_image">
+            <el-image
+              style="width: 690px; height: 410px"
+              :src="dmsDataProxy + item.c_picture"
+              fit="cover"
+            />
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
 </template>
 
 <script>
+import wgn from "@/api/wgn";
 export default {
-    name: "wgn",
-    data() {
-        return {
-
-        };
+  name: "微功能服务",
+  data() {
+    return {
+      // 搜索关键词
+      searchStr: "",
+      // 微功能服务列表
+      dmsServerList: [],
+      // DMS数据代理地址
+      dmsDataProxy: "",
+    };
+  },
+  mounted() {
+    this.dmsDataProxy = systemConfig.dmsDataProxy;
+    this.searchServerList();
+  },
+  methods: {
+    // 搜索微功能服务
+    searchServerList() {
+      let requestParams = {
+        columnId: 1651,
+        states: 0,
+        pageSize: 999,
+        page: 0,
+      };
+      if (this.searchStr) {
+        requestParams.search = JSON.stringify([
+          {
+            field: "title",
+            searchType: 2,
+            content: { value: "%" + this.searchStr + "%" },
+          },
+        ]);
+      }
+      // 获取微功能服务列表
+      wgn.getDmsData(requestParams)
+        .then((res) => {
+          if (res.code === 200) {
+            this.dmsServerList = res.content.data;
+            this.$message({
+              message: "搜索到" + this.dmsServerList.length + "条微功能服务",
+              type: "success",
+            });
+          } else {
+            this.$message({
+              message: "搜索到0条微功能服务",
+              type: "warning",
+            });
+          }
+        })
+        .catch((e) => {
+          this.$message({
+            message: "搜索微功能服务失败" + e,
+            type: "error",
+          });
+        });
     },
-    mounted() {
+    // 申请使用微功能服务
+    handleApply(item) {
+      this.$confirm("确认申请使用" + item.title + "吗?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+        .then(() => {
+          // 确认申请使用
+          this.$message({
+            message: "申请使用" + item.title + "?等url吧!",
+            type: "success",
+          });
+        })
+        .catch(() => {
+          // 取消申请使用
+        });
     },
-    methods: {
-    }
+    // 在线演示微功能服务
+    handleOnlineDemo(item) {
+      // 1. 解析目标路由(支持传参、命名路由等)
+      const routeData = this.$router.resolve({
+        path: "/wgnSingle", // 微功能
+        query: { sceneId: item.c_scene_name },
+      });
+      // 2. 打开新窗口(_blank 表示新窗口)
+      window.open(routeData.href, "_blank");
+    },
+  },
 };
 </script>
 
 <style lang="less" scoped>
 .container {
-    width: 1920px;
-    margin: 0 auto;
+  width: 100vw;
+  margin: 0 auto;
+  background-color: #08224a;
 }
-
-.wgn {
+.server_title {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+}
+.server_title_text {
+  width: calc(100vw - 824px);
+  height: 786px;
+  background-color: #1c2631;
+  color: #fff;
+  padding: 0 160px 0 60px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  overflow: hidden;
+  &_title {
+    font-size: 64px;
+    font-weight: bold;
+    letter-spacing: 0.5rem;
+  }
+  &_content {
+    margin-top: 77px;
+    font-size: 22px;
+  }
+}
+.server_list_box {
+  width: 100vw;
+  background-color: rgba(0, 0, 0, 0.15);
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  color: #fff;
+  &_title {
+    margin-top: 100px;
+    font-size: 35px;
+    font-weight: bold;
     position: relative;
+    &::after {
+      content: "";
+      position: absolute;
+      bottom: -12px;
+      left: 50%;
+      transform: translateX(-50%);
+      width: 100px;
+      height: 4px;
+      background-image: linear-gradient(to right, #1d88f0, #00bfff);
+    }
+  }
+  &_search {
+    margin-top: 100px;
+    font-size: 25px;
+    display: flex;
+    flex-wrap: nowrap;
+    align-items: center;
+    width: -webkit-fill-available;
+    justify-content: center;
+  }
+  &_table {
+    margin-top: 50px;
+    width: 100vw;
+    &_item {
+      display: flex;
+      justify-content: space-evenly;
+      align-items: center;
+      padding: 100px 0;
+
+      &:nth-child(odd) {
+        flex-direction: row;
+      }
+      &:nth-child(even) {
+        flex-direction: row-reverse;
+      }
+      &_content {
+        width: 760px;
+        height: 100px;
+        display: flex;
+        flex-direction: column;
+        justify-content: center;
+        align-items: center;
+        &_title {
+          font-size: 35px;
+          font-weight: bold;
+          color: #4095e5;
+        }
+        &_text {
+          margin-top: 35px;
+          font-size: 18px;
+        }
+        &_button_box {
+          display: flex;
+          justify-content: space-evenly;
+          width: 100%;
+          &_item {
+            margin-top: 35px;
+            font-size: 20px;
+            letter-spacing: 0.2rem;
+            color: #4095e5;
+            border: 1px solid #4095e5;
+            border-radius: 10px;
+            padding: 10px 36px;
+            cursor: pointer;
+            &:hover {
+              background-color: #4095e5;
+              color: #fff;
+            }
+          }
+        }
+      }
+      &_image {
+        width: 690px;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        border-radius: 30px;
+        overflow: hidden;
+      }
+    }
+  }
 }
-</style>
+</style>

+ 0 - 31
src/views/Xxfk.vue

@@ -1,31 +0,0 @@
-<template>
-    <div class="xxfk container">
-        <router-view />
-    </div>
-</template>
-
-<script>
-export default {
-    name: "xxfk",
-    data() {
-        return {
-
-        };
-    },
-    mounted() {
-    },
-    methods: {
-    }
-};
-</script>
-
-<style lang="less" scoped>
-.container {
-    width: 1920px;
-    margin: 0 auto;
-}
-
-.xxfk {
-    position: relative;
-}
-</style>

+ 79 - 16
src/views/Yxgl.vue

@@ -1,31 +1,94 @@
 <template>
-    <div class="yxgl container">
-        <router-view />
+  <div id="yxgl_box">
+    <el-menu
+      :default-active="menuActive"
+      class="el-menu-vertical-demo"
+      :collapse="isCollapse"
+      @open="handleOpen"
+      @close="handleClose"
+    >
+      <el-sub-menu index="/#">
+        <template #title>
+          <el-icon><Platform /></el-icon>
+          <span>运行中心</span>
+        </template>
+        <el-menu-item index="StatisticalAnalysis">
+          <el-icon><Histogram /></el-icon>
+          <template #title>统计分析</template>
+        </el-menu-item>
+      </el-sub-menu>
+      <el-sub-menu index="2">
+        <template #title>
+          <el-icon><Tools /></el-icon>
+          <span>管理中心</span>
+        </template>
+        <el-menu-item index="oauth">
+          <el-icon><UserFilled /></el-icon>
+          <template #title>用户权限</template>
+        </el-menu-item>
+        <el-menu-item index="dms">
+          <el-icon><Ticket /></el-icon>
+          <template #title>数据管理</template>
+        </el-menu-item>
+      </el-sub-menu>
+    </el-menu>
+    <div
+      class="viewBox"
+      :style="{ width: isCollapse ? 'calc(100vw - 60px)' : 'calc(100% - 200px)' }"
+    >
+      <StatisticalAnalysis />
     </div>
+  </div>
 </template>
 
 <script>
+import StatisticalAnalysis from "@/views/yxgl/StatisticalAnalysis.vue";
 export default {
-    name: "yxgl",
-    data() {
-        return {
-
-        };
+  name: "yxgl",
+  data() {
+    return {
+      isCollapse: false,
+      menuActive: "StatisticalAnalysis",
+    };
+  },
+  // 2. 局部注册组件(键值同名可简写)
+  components: {
+    StatisticalAnalysis, // 完整写法:MyButton: MyButton
+  },
+  mounted() {},
+  methods: {
+    handleOpen(key, keyPath) {
+      console.log(key, keyPath);
     },
-    mounted() {
+    handleClose(key, keyPath) {
+      console.log(key, keyPath);
     },
-    methods: {
-    }
+  },
 };
 </script>
 
 <style lang="less" scoped>
-.container {
-    width: 1920px;
-    margin: 0 auto;
+#yxgl_box {
+  width: 100vw;
+  height: calc(100vh - 120px);
+  margin: 0;
+  display: flex;
+  overflow: hidden;
 }
 
-.yxgl {
-    position: relative;
+.el-menu-vertical-demo:not(.el-menu--collapse) {
+  width: 200px;
+  height: calc(100vh - 120px);
+  margin: 0;
+  //   background: #08224a;
+}
+.viewBox {
+  width: calc(100vw - 200px);
+  margin: 0;
+  height: calc(100vh - 120px);
+  position: relative;
+  overflow: hidden;
+  overflow-y: auto;
+  background-color: #eee;
 }
-</style>
+</style>

+ 1 - 1
src/views/example/Example.vue

@@ -25,7 +25,7 @@ export default {
     margin: 0 auto;
 }
 
-.skszk {
+.sksjgl {
     position: relative;
 }
 </style>

+ 1075 - 0
src/views/skmh/index.vue

@@ -0,0 +1,1075 @@
+<template>
+  <div class="dashboard-container">
+    <!-- 顶部横幅 -->
+
+    <div class="server_title">
+      <el-image
+        style="width: 824px; height: 786px"
+        src="static/images/wgn_title.png"
+        fit="cover"
+      />
+      <div class="server_title_text">
+        <div class="server_title_text_title">时空门户</div>
+        <div class="server_title_text_content">
+          时空门户子系统为用户提供信息概览、导航入口及交互功能,帮助用户快速了解和使用平台服务。系统统计访问量(累计和日均)、用户使用时长及活跃时段;展示平台功能、核心能力及操作演示视频;统计并展示服务总数、分类占比及新上线服务;同时统计各委办平台的注册用户信息及用户总数。
+        </div>
+      </div>
+    </div>
+
+    <!-- <div class="banner">
+      <div class="banner-content">
+        <h1>时空门户</h1>
+        <p>时空门户是一个集数据采集、分析、展示于一体的综合性平台,为用户提供全面的设备监控和数据分析服务</p>
+        <button class="enter-btn">进入系统</button>
+      </div>
+    </div> -->
+
+    <!-- 平台数据统计 -->
+    <div class="stats-section">
+      <div class="overview-header">
+        <h2>平台数据统计</h2>
+      </div>
+      <div class="stats-grid">
+        <div class="stat-card card-1">
+          <div class="stat-label">平台服务总数
+              <el-image
+              style="width: 20px; height: 20px"
+              src="static/images/skmh-1.png"
+              fit="cover"
+            />
+          </div>
+          <div class="stat-number">1,248</div>
+          <div class="stat-label">较上月增长12.5%</div>
+        </div>
+        <div class="stat-card card-2">
+          <div class="stat-label">新上线服务统计
+            <el-image
+              style="width: 20px; height: 20px"
+              src="static/images/skmh-2.png"
+              fit="cover"
+            />
+          </div>
+          <div class="stat-number">86</div>
+          <div class="stat-label">本月新增服务</div>
+        </div>
+        <div class="stat-card card-3">
+          <div class="stat-label">注册用户总数
+            <el-image
+              style="width: 20px; height: 20px"
+              src="static/images/skmh-3.png"
+              fit="cover"
+            />
+          </div>
+          <div class="stat-number">24,586</div>
+          <div class="stat-label">本周新增12,34人</div>
+        </div>
+      </div>
+    </div>
+
+    <!-- 数据概览 -->
+    <div class="data-overview">
+      <div class="overview-header">
+        <h2>数据概览</h2>
+        <!-- <div class="time-tabs">
+          <div class="tab active">今日</div>
+          <div class="tab">本周</div>
+          <div class="tab">本月</div>
+          <div class="tab">本年</div>
+        </div> -->
+      </div>
+       <div class="time-section">
+        <div class="time-card">
+          <div class="time-content">
+            <div style="">
+              <el-date-picker
+                class="el-date-picker"
+                v-model="fromTime.date"
+                type="daterange"
+                range-separator="-"
+                start-placeholder="开始日期"
+                end-placeholder="结束日期"
+                format="YYYY-MM-DD"
+                 @change="changeTime"
+                
+              />
+            </div>
+            <div class="button-row">
+              <el-button type="primary" @click="handleType(7)">最近7天</el-button>
+              <el-button type="primary" @click="handleType(30)">最近30天</el-button>
+              <el-button type="primary" @click="handleType(90)">最近90天</el-button>
+              <el-button type="primary" @click="handleType(365)">最近1年</el-button>
+          </div>
+          </div>
+        </div>
+      </div>
+      <div class="charts-grid">
+        <!-- 访问量统计柱状图 -->
+        <div class="chart-card">
+          <div class="chart-title">访问量统计</div>
+          <div ref="deviceChart" class="chart-container"></div>
+        </div>
+        <!-- 服务分类占比饼图 -->
+        <div class="chart-card">
+          <div class="chart-title">服务分类占比</div>
+          <div ref="statusChart" class="chart-container"></div>
+        </div>
+        <!-- 用户活跃度分析折线图 -->
+        <!-- <div class="chart-card">
+          <div class="chart-title">用户活跃度分析</div>
+          <div ref="activityChart" class="chart-container"></div>
+        </div> -->
+        <!-- 数据量柱状图 -->
+        <!-- <div class="chart-card">
+          <div class="chart-title">数据量</div>
+          <div ref="dataVolumeChart" class="chart-container"></div>
+        </div> -->
+      </div>
+    </div>
+
+    <!-- 设备综合分析比较 -->
+    <div class="comparison-section">
+      <div class="chart-card full-width">
+        <div class="chart-title">各委办平台用户分布</div>
+        <!-- <div ref="comparisonChart" class="chart-container"></div> -->
+        <el-table :data="tableData" style="width: 100%">
+          <el-table-column prop="name" label="委办单位" />
+          <el-table-column prop="number" label="注册用户数" />
+          <el-table-column prop="activity" label="活跃度" />
+          <el-table-column prop="server" label="服务使用量" />
+        </el-table>
+      </div>
+    </div>
+
+    <!-- 功能演示 -->
+    <div class="demo-section">
+      <div class="overview-header">
+        <h2>功能演示</h2>
+      </div>
+      <div class="demo-grid">
+        <div class="demo-card">
+          <div class="demo-thumbnail">
+            <div class="play-btn">▶</div>
+          </div>
+          <div class="demo-title">
+            <div class="demo-label">核心功能操作演示</div>
+            <div class="demo-text">展示系统核心功能操作流程与交互方式</div>
+          </div>
+        </div>
+        <div class="demo-card">
+          <div class="demo-thumbnail">
+            <div class="play-btn">▶</div>
+          </div>
+          <div class="demo-title">
+            <div class="demo-label">二三维一体化引擎</div>
+            <div class="demo-text">展示空间数据可视化与交互分析能力</div>
+          </div>
+        </div>
+        <div class="demo-card">
+          <div class="demo-thumbnail">
+            <div class="play-btn">▶</div>
+          </div>
+          <div class="demo-title">
+            <div class="demo-label">实际业务场景应用</div>
+            <div class="demo-text">展示系统在行业中的实际应用案例</div>
+          </div>
+          
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import * as echarts from 'echarts'
+
+export default {
+  name: 'SpatialTemporalPortal',
+  data() {
+    return {
+      deviceChart: null,
+      statusChart: null,
+      activityChart: null,
+      dataVolumeChart: null,
+      comparisonChart: null,
+      fromTime:{
+        date:[new Date(),new Date()]
+      },
+      tableData:[
+        {
+          number: '1234',
+          name: 'tom',
+          activity:'87',
+          server: '2324',
+        },
+        {
+          number: '1234',
+          name: 'canver',
+          activity:'78',
+          server: '2324',
+        },
+        {
+          number: '1234',
+          name: 'lina',
+          activity:'88',
+          server: '2324',
+        },
+        {
+          number: '1234',
+          name: 'wang',
+          activity:'86',
+          server: '2324',
+        },
+      ]
+    }
+  },
+  mounted() {
+    this.initCharts()
+    window.addEventListener('resize', this.handleResize)
+  },
+  beforeUnmount() {
+    window.removeEventListener('resize', this.handleResize)
+    this.destroyCharts()
+  },
+  methods: {
+    initCharts() {
+      this.initDeviceChart()
+      this.initStatusChart()
+      // this.initActivityChart()
+      // this.initDataVolumeChart()
+      // this.initComparisonChart()
+    },
+    handleType(param){
+      const end = new Date()
+      const start = new Date()
+      start.setTime(start.getTime() - 3600 * 1000 * 24 * param) //天计算
+      end.setTime(end.getTime() - 3600 * 1000 * 24 * 1) //天计算
+      // start.setMonth(start.getMonth() - 6)
+      this.fromTime.date = [start,end]
+    },
+    changeTime(v){
+      debugger
+      console.log('[ eee ] >', v)
+      this.fromTime.date=v
+      
+    },
+    
+    initDeviceChart() {
+      this.deviceChart = echarts.init(this.$refs.deviceChart)
+      const option = {
+        tooltip: {
+          trigger: 'item',
+          backgroundColor: 'rgba(0, 25, 50, 0.8)',
+          borderColor: '#1E90FF',
+          textStyle: {
+            color: '#fff'
+          }
+        },
+        legend: {
+          orient: 'horizontal',
+          // bottom: 0,
+          top:0,
+          textStyle: {
+            color: '#a3b6c7'
+          }
+        },
+        grid: {
+          left: '3%',
+          right: '4%',
+          bottom: '3%',
+          containLabel: true
+        },
+        xAxis: {
+          type: 'category',
+          data: ['00:00', '04:00', '08:00', '12:00', '16:00', '20:00'],
+          axisLabel: {
+            color: '#a3b6c7'
+          },
+          axisLine: {
+            lineStyle: {
+              color: '#1E90FF'
+            }
+          }
+        },
+        yAxis: {
+          type: 'value',
+          axisLabel: {
+            color: '#a3b6c7'
+          },
+          axisLine: {
+            lineStyle: {
+              color: '#1E90FF'
+            }
+          },
+          splitLine: {
+            lineStyle: {
+              color: 'rgba(30, 144, 255, 0.2)'
+            }
+          }
+        },
+        series: [
+          {
+            data: [120, 200, 150, 80, 70, 110],
+            type: 'bar',
+            barWidth: '60%',
+            itemStyle: {
+              color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+                { offset: 0, color: '#1E90FF' },
+                { offset: 1, color: '#00BFFF' }
+              ])
+            }
+          }
+        ]
+      }
+      this.deviceChart.setOption(option)
+    },
+    
+    initStatusChart() {
+      this.statusChart = echarts.init(this.$refs.statusChart)
+      const option = {
+        tooltip: {
+          trigger: 'item',
+          backgroundColor: 'rgba(0, 25, 50, 0.8)',
+          borderColor: '#1E90FF',
+          textStyle: {
+            color: '#fff'
+          }
+        },
+        legend: {
+          orient: 'horizontal',
+          bottom: 0,
+          textStyle: {
+            color: '#a3b6c7'
+          }
+        },
+        series: [
+          {
+            name: '服务分类占比',
+            type: 'pie',
+            radius: ['40%', '70%'],
+            avoidLabelOverlap: false,
+            itemStyle: {
+              borderRadius: 10,
+              borderColor: '#0A192F',
+              borderWidth: 2
+            },
+            label: {
+              show: false,
+              position: 'center'
+            },
+            emphasis: {
+              label: {
+                show: true,
+                fontSize: 20,
+                fontWeight: 'bold',
+                color: '#fff'
+              }
+            },
+            labelLine: {
+              show: false
+            },
+            data: [
+              { value: 400, name: '空间分析', itemStyle: { color: '#52C41A' } },
+              { value: 300, name: '数据查询', itemStyle: { color: '#FAAD14' } },
+              { value: 200, name: '三维可视化', itemStyle: { color: '#F5222D' } },
+              { value: 100, name: '路径规划', itemStyle: { color: '#8C8C8C' } }
+            ]
+          }
+        ]
+      }
+      this.statusChart.setOption(option)
+    },
+    
+    initActivityChart() {
+      this.activityChart = echarts.init(this.$refs.activityChart)
+      const option = {
+        tooltip: {
+          trigger: 'axis',
+          backgroundColor: 'rgba(0, 25, 50, 0.8)',
+          borderColor: '#1E90FF',
+          textStyle: {
+            color: '#fff'
+          }
+        },
+        grid: {
+          left: '3%',
+          right: '4%',
+          bottom: '3%',
+          containLabel: true
+        },
+        xAxis: {
+          type: 'category',
+          boundaryGap: false,
+          data: ['00:00', '04:00', '08:00', '12:00', '16:00', '20:00'],
+          axisLabel: {
+            color: '#a3b6c7'
+          },
+          axisLine: {
+            lineStyle: {
+              color: '#1E90FF'
+            }
+          }
+        },
+        yAxis: {
+          type: 'value',
+          axisLabel: {
+            color: '#a3b6c7'
+          },
+          axisLine: {
+            lineStyle: {
+              color: '#1E90FF'
+            }
+          },
+          splitLine: {
+            lineStyle: {
+              color: 'rgba(30, 144, 255, 0.2)'
+            }
+          }
+        },
+        series: [
+          {
+            name: '活跃度',
+            type: 'line',
+            stack: 'Total',
+            smooth: true,
+            lineStyle: {
+              color: '#1E90FF'
+            },
+            areaStyle: {
+              color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+                { offset: 0, color: 'rgba(30, 144, 255, 0.6)' },
+                { offset: 1, color: 'rgba(30, 144, 255, 0.1)' }
+              ])
+            },
+            emphasis: {
+              focus: 'series'
+            },
+            data: [120, 132, 101, 134, 90, 230]
+          }
+        ]
+      }
+      this.activityChart.setOption(option)
+    },
+    
+    initDataVolumeChart() {
+      this.dataVolumeChart = echarts.init(this.$refs.dataVolumeChart)
+      const option = {
+        tooltip: {
+          trigger: 'axis',
+          backgroundColor: 'rgba(0, 25, 50, 0.8)',
+          borderColor: '#1E90FF',
+          textStyle: {
+            color: '#fff'
+          }
+        },
+        grid: {
+          left: '3%',
+          right: '4%',
+          bottom: '3%',
+          containLabel: true
+        },
+        xAxis: {
+          type: 'category',
+          data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'],
+          axisLabel: {
+            color: '#a3b6c7'
+          },
+          axisLine: {
+            lineStyle: {
+              color: '#1E90FF'
+            }
+          }
+        },
+        yAxis: {
+          type: 'value',
+          axisLabel: {
+            color: '#a3b6c7'
+          },
+          axisLine: {
+            lineStyle: {
+              color: '#1E90FF'
+            }
+          },
+          splitLine: {
+            lineStyle: {
+              color: 'rgba(30, 144, 255, 0.2)'
+            }
+          }
+        },
+        series: [
+          {
+            data: [1200, 2000, 1500, 800, 700, 1100, 1300],
+            type: 'bar',
+            barWidth: '60%',
+            itemStyle: {
+              color: '#FF7F50'
+            }
+          }
+        ]
+      }
+      this.dataVolumeChart.setOption(option)
+    },
+    
+    initComparisonChart() {
+      this.comparisonChart = echarts.init(this.$refs.comparisonChart)
+      const option = {
+        tooltip: {
+          trigger: 'axis',
+          backgroundColor: 'rgba(0, 25, 50, 0.8)',
+          borderColor: '#1E90FF',
+          textStyle: {
+            color: '#fff'
+          }
+        },
+        legend: {
+          data: ['设备A', '设备B', '设备C'],
+          textStyle: {
+            color: '#a3b6c7'
+          }
+        },
+        grid: {
+          left: '3%',
+          right: '4%',
+          bottom: '3%',
+          containLabel: true
+        },
+        xAxis: {
+          type: 'category',
+          boundaryGap: false,
+          data: ['00:00', '04:00', '08:00', '12:00', '16:00', '20:00'],
+          axisLabel: {
+            color: '#a3b6c7'
+          },
+          axisLine: {
+            lineStyle: {
+              color: '#1E90FF'
+            }
+          }
+        },
+        yAxis: {
+          type: 'value',
+          axisLabel: {
+            color: '#a3b6c7'
+          },
+          axisLine: {
+            lineStyle: {
+              color: '#1E90FF'
+            }
+          },
+          splitLine: {
+            lineStyle: {
+              color: 'rgba(30, 144, 255, 0.2)'
+            }
+          }
+        },
+        series: [
+          {
+            name: '设备A',
+            type: 'line',
+            stack: 'Total',
+            smooth: true,
+            lineStyle: {
+              color: '#1E90FF'
+            },
+            areaStyle: {
+              color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+                { offset: 0, color: 'rgba(30, 144, 255, 0.6)' },
+                { offset: 1, color: 'rgba(30, 144, 255, 0.1)' }
+              ])
+            },
+            data: [120, 132, 101, 134, 90, 230]
+          },
+          {
+            name: '设备B',
+            type: 'line',
+            stack: 'Total',
+            smooth: true,
+            lineStyle: {
+              color: '#52C41A'
+            },
+            areaStyle: {
+              color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+                { offset: 0, color: 'rgba(82, 196, 26, 0.6)' },
+                { offset: 1, color: 'rgba(82, 196, 26, 0.1)' }
+              ])
+            },
+            data: [220, 182, 191, 234, 290, 330]
+          },
+          {
+            name: '设备C',
+            type: 'line',
+            stack: 'Total',
+            smooth: true,
+            lineStyle: {
+              color: '#FF7F50'
+            },
+            areaStyle: {
+              color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+                { offset: 0, color: 'rgba(255, 127, 80, 0.6)' },
+                { offset: 1, color: 'rgba(255, 127, 80, 0.1)' }
+              ])
+            },
+            data: [150, 232, 201, 154, 190, 330]
+          }
+        ]
+      }
+      this.comparisonChart.setOption(option)
+    },
+    
+    handleResize() {
+      if (this.deviceChart) this.deviceChart.resize()
+      if (this.statusChart) this.statusChart.resize()
+      if (this.activityChart) this.activityChart.resize()
+      if (this.dataVolumeChart) this.dataVolumeChart.resize()
+      if (this.comparisonChart) this.comparisonChart.resize()
+    },
+    
+    destroyCharts() {
+      if (this.deviceChart) {
+        this.deviceChart.dispose()
+        this.deviceChart = null
+      }
+      if (this.statusChart) {
+        this.statusChart.dispose()
+        this.statusChart = null
+      }
+      if (this.activityChart) {
+        this.activityChart.dispose()
+        this.activityChart = null
+      }
+      if (this.dataVolumeChart) {
+        this.dataVolumeChart.dispose()
+        this.dataVolumeChart = null
+      }
+      if (this.comparisonChart) {
+        this.comparisonChart.dispose()
+        this.comparisonChart = null
+      }
+    }
+  }
+}
+</script>
+
+<style lang="less" scoped>
+
+/* 确保你的自定义样式优先级更高 */
+.el-date-picker {
+    /* 重置为期望的样式 */
+    color: initial !important; /* 使用 !important 来确保优先级 */
+    background-color: white !important; /* 确保背景色正确 */
+}
+.dashboard-container {
+  background-color: #0A192F;
+  min-height: 100vh;
+  color: #fff;
+}
+
+.server_title {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+}
+.server_title_text {
+  width: calc(100vw - 824px);
+  height: 786px;
+  background-color: #1c2631;
+  color: #fff;
+  padding: 0 160px 0 60px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  overflow: hidden;
+  &_title {
+    font-size: 64px;
+    font-weight: bold;
+    letter-spacing: 0.5rem;
+  }
+  &_content {
+    margin-top: 77px;
+    font-size: 22px;
+  }
+}
+
+/* 顶部横幅 */
+.banner {
+  position: relative;
+  height: 500px;
+  background: url('@/assets/images/common/home-bg1.png') center/cover no-repeat;
+  display: flex;
+  align-items: center;
+  justify-content: flex-end;
+  padding-right: 10%;
+  
+  &::before {
+    content: '';
+    position: absolute;
+    top: 0;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    background: linear-gradient(to right, rgba(10, 25, 47, 0.9), rgba(10, 25, 47, 0.7));
+  }
+  
+  .banner-content {
+    position: relative;
+    max-width: 600px;
+    text-align: left;
+    padding: 0 20px;
+    
+    h1 {
+      font-size: 42px;
+      font-weight: bold;
+      margin-bottom: 20px;
+      color: #fff;
+    }
+    
+    p {
+      font-size: 14px;
+      line-height: 1.8;
+      margin-bottom: 30px;
+      color: #a3b6c7;
+    }
+    
+    .enter-btn {
+      background-color: transparent;
+      color: #409eff;
+      border: 1px solid #409eff;
+      padding: 8px 30px;
+      font-size: 16px;
+      border-radius: 20px;
+      cursor: pointer;
+      transition: all 0.3s ease;
+      
+      &:hover {
+        background-color: #409eff;
+        color: #fff;
+        transform: translateY(-2px);
+      }
+    }
+  }
+}
+
+/* 平台数据统计 */
+.stats-section {
+  padding: 40px 20px;
+  .overview-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    margin-bottom: 30px;
+    
+    h2 {
+      font-size: 24px;
+      color: #fff;
+      margin: 0;
+    }
+  }
+  
+  .stats-grid {
+    display: flex;
+    justify-content: center;
+    gap: 30px;
+    flex-wrap: wrap;
+    
+    .stat-card {
+      width: 555px;
+      height: 150px;
+      border-radius: 12px;
+      padding: 20px;
+      display: flex;
+      flex-direction: column;
+      justify-content: center;
+      align-items: flex-start;
+      box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
+      transition: transform 0.3s ease;
+      
+      &:hover {
+        transform: translateY(-5px);
+      }
+      
+      .stat-number {
+        font-size: 36px;
+        font-weight: bold;
+        margin-top: 10px;
+        margin-bottom: 10px;
+        color: #fff;
+      }
+      
+      .stat-label {
+        font-size: 16px;
+        color: rgba(255, 255, 255, 0.8);
+        width: 100%;
+        justify-content: space-between;
+        display: flex;
+      }
+    }
+    
+    .card-1 {
+      background: linear-gradient(135deg, #3B82F6 0%, #4F46E5 100%);
+    }
+    
+    .card-2 {
+      background: linear-gradient(135deg, #22C55E 0%, #059669 100%);
+    }
+    
+    .card-3 {
+      background: linear-gradient(135deg, #A855F7 0%, #7C3AED 100%);
+    }
+  }
+}
+
+/* 数据概览 */
+.data-overview {
+  padding: 0 20px 40px;
+  
+  .overview-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    margin-bottom: 30px;
+    
+    h2 {
+      font-size: 24px;
+      color: #fff;
+      margin: 0;
+    }
+    
+    .time-tabs {
+      display: flex;
+      gap: 20px;
+      
+      .tab {
+        padding: 8px 16px;
+        cursor: pointer;
+        color: #a3b6c7;
+        border-radius: 20px;
+        transition: all 0.3s ease;
+        
+        &:hover {
+          color: #409eff;
+        }
+        
+        &.active {
+          background-color: #409eff;
+          color: #fff;
+        }
+      }
+    }
+  }
+  
+  .charts-grid {
+    display: grid;
+    grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
+    gap: 30px;
+    
+    .chart-card {
+      background-color: rgba(30, 41, 59, 0.6);
+      border-radius: 12px;
+      padding: 20px;
+      box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
+      
+      .chart-title {
+        font-size: 18px;
+        color: #fff;
+        margin-bottom: 20px;
+        text-align: left;
+      }
+      
+      .chart-container {
+        height: 300px;
+        width: 100%;
+      }
+    }
+  }
+}
+// 时间筛选
+.time-section{
+  padding: 0 0px 40px;
+  .time-card {
+    background-color: rgba(30, 41, 59, 0.6);
+    border-radius: 12px;
+    padding: 20px;
+    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
+  }
+  .time-content{
+    display: flex;
+    justify-content: space-between;
+    width: 100%;
+  }
+}
+
+
+/* 设备综合分析比较 */
+.comparison-section {
+  padding: 0 20px 40px;
+  
+  .chart-card {
+    background-color: rgba(30, 41, 59, 0.6);
+    border-radius: 12px;
+    padding: 20px;
+    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
+    
+    &.full-width {
+      max-width: 100%;
+    }
+    
+    .chart-title {
+      font-size: 18px;
+      color: #fff;
+      margin-bottom: 20px;
+      text-align: left;
+    }
+    
+    .chart-container {
+      height: 400px;
+      width: 100%;
+    }
+  }
+}
+
+/* 功能演示 */
+.demo-section {
+  padding: 0 20px 100px;
+  
+ .overview-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    margin-bottom: 30px;
+    
+    h2 {
+      font-size: 24px;
+      color: #fff;
+      margin: 0;
+    }
+  }
+  
+  .demo-grid {
+    display: flex;
+    justify-content: space-between;
+    gap: 30px;
+    flex-wrap: wrap;
+    
+    .demo-card {
+      width: 350px;
+      background-color: rgba(30, 41, 59, 0.6);
+      border-radius: 12px;
+      overflow: hidden;
+      box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
+      transition: transform 0.3s ease;
+      
+      &:hover {
+        transform: translateY(-5px);
+      }
+      
+      .demo-thumbnail {
+        height: 200px;
+        background-color: #1E90FF;
+        position: relative;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        
+        .play-btn {
+          width: 60px;
+          height: 60px;
+          border-radius: 50%;
+          background-color: rgba(255, 255, 255, 0.8);
+          color: #1E90FF;
+          font-size: 30px;
+          display: flex;
+          justify-content: center;
+          align-items: center;
+          cursor: pointer;
+          transition: all 0.3s ease;
+          
+          &:hover {
+            background-color: #fff;
+            transform: scale(1.1);
+          }
+        }
+      }
+      
+      .demo-title {
+        padding: 15px;
+        color: #fff;
+        text-align: left;
+      }
+      .demo-label {
+        font-size: 16px;
+        color: #fff;
+        padding-bottom: 10px;
+        text-align: left;
+      }
+      .demo-text {
+        font-size: 12px;
+        color: #fff;
+        text-align: left;
+      }
+    }
+  }
+}
+
+/* 响应式设计 */
+@media (max-width: 768px) {
+  .banner {
+    padding-right: 5%;
+    
+    .banner-content {
+      h1 {
+        font-size: 32px;
+      }
+    }
+  }
+  
+  .stats-section {
+    .stats-grid {
+      gap: 20px;
+      
+      .stat-card {
+        width: 100%;
+        max-width: 300px;
+      }
+    }
+  }
+  
+  .data-overview {
+    .overview-header {
+      flex-direction: column;
+      gap: 20px;
+      
+      h2 {
+        text-align: center;
+      }
+    }
+    
+    .charts-grid {
+      grid-template-columns: 1fr;
+      
+      .chart-card {
+        .chart-container {
+          height: 250px;
+        }
+      }
+    }
+  }
+  
+  .comparison-section {
+    .chart-card {
+      .chart-container {
+        height: 300px;
+      }
+    }
+  }
+  
+  .demo-section {
+    .demo-grid {
+      gap: 20px;
+      
+      .demo-card {
+        width: 100%;
+        max-width: 350px;
+      }
+    }
+  }
+}
+</style>

+ 110 - 0
src/views/skmh/scene/index.vue

@@ -0,0 +1,110 @@
+<template>
+    <div class="container">
+        <div style="padding: 20px;display: ruby-text;">
+            <div v-for="info in listData" :key="info" style="padding: 20px;">
+                <el-card style="border-radius: 10px !important;" @click="openVideo(info)">
+                    <div class="card picDiv"><img :src="info.img" ></div>
+                    <template #footer>
+                        <div style="width: 260px;">
+                            <div style="font-weight: bold;padding-bottom: 10px;">{{info.title}}</div>
+                            <div class="ellipsis3">
+                                <el-popover
+                                    title=""
+                                    width="300"
+                                    effect="dark"
+                                    :content="info.desc"
+                                    placement="top-start"
+                                >
+                                    <template #reference>
+                                        <div>{{info.desc}}</div>
+                                    </template>
+                                </el-popover>
+                            </div>
+                        </div>
+                    </template>
+                </el-card>
+            </div>
+        </div>
+        <div>
+            <el-dialog v-model="centerDialogVisible" title="预览" width="800" center :before-close="closeDialog">
+                <video :src="videoUrl" controls style="width: 100%;"/>  
+            </el-dialog>
+        </div>
+    </div>
+</template>
+
+<script>
+export default {
+    name: "",
+    data() {
+        return {
+            listData:[],
+            centerDialogVisible:false,
+            videoUrl:''
+
+        };
+    },
+    mounted() {
+        this.initData()
+    },
+    methods: {
+        initData(){
+            let that = this;
+            for(let i=0; i<10; i++){
+                let str = {
+                    url:"https://realbot-oss.oss-accelerate.aliyuncs.com/scrm/2025/2025-05-21/659fa31d-dc87-4882-8be5-1fba8fb7e6ff/flower.mp4",
+                    img:require("@static/images/u30.png"),
+                    title:"无人机实时成图_"+i,
+                    desc:"无人机巡察场景可实时接入无人机视频画面,叠加到GIS场景中,实现边飞边出图的真实场景还原,并可将历史画面内容实现快速切图、上图展示,利用AI技术赋能无人机场景,实现无人机视频画面目标提取,实现关键目标要素点位标记及相关业务分析应用,可用于城市规划、应急、军用侦察等行业应用场景。"
+                }
+                that.listData.push(str);
+            }
+        },
+        openVideo(param){
+            this.videoUrl = param.url;
+            this.centerDialogVisible=true
+        },
+        closeDialog(){
+            this.videoUrl='';
+            this.centerDialogVisible=false
+        }
+    }
+};
+</script>
+
+<style lang="less" scoped>
+/deep/ .el-card__body{
+    padding: 0px !important;
+    height: 140px;
+}
+.container {
+    width: 100%;
+    padding: 0px;
+    margin: 0 auto;
+}
+.card{
+    float: left;
+    height: 150px;
+    width: 300px;
+    cursor: pointer;
+    box-sizing: border-box;
+}
+.picDiv{
+    overflow: hidden;
+}
+.picDiv img{
+    width: 100%;
+    height: 100%;
+    transition: all 1s;
+}
+.picDiv img:hover{
+    transform:scale(1.2,1.2);
+}
+.ellipsis3{
+    display: -webkit-box;
+    -webkit-box-orient: vertical;
+    -webkit-line-clamp: 3;
+    overflow: hidden;
+    text-overflow: ellipsis;
+}
+</style>

+ 6 - 2
src/views/yxgl/Example.vue → src/views/sksjgl/Example.vue

@@ -1,12 +1,12 @@
 <template>
     <div class="example">
-        yxgl example
+        示例
     </div>
 </template>
 
 <script>
 export default {
-    name: "",
+    name: "skmh",
     data() {
         return {
 
@@ -24,4 +24,8 @@ export default {
     width: 1920px;
     margin: 0 auto;
 }
+
+.sksjgl {
+    position: relative;
+}
 </style>

+ 0 - 27
src/views/skszk/Example.vue

@@ -1,27 +0,0 @@
-<template>
-    <div class="example">
-        skszk example
-    </div>
-</template>
-
-<script>
-export default {
-    name: "",
-    data() {
-        return {
-
-        };
-    },
-    mounted() {
-    },
-    methods: {
-    }
-};
-</script>
-
-<style lang="less" scoped>
-.container {
-    width: 1920px;
-    margin: 0 auto;
-}
-</style>

+ 91 - 15
src/views/wgn/Example.vue

@@ -1,27 +1,103 @@
 <template>
-    <div class="example">
-        wgn example
-    </div>
+  <!-- 时空算子库 -->
+  <div class="example">
+    <div id="skysceneryContainer"></div>
+    <!-- 操作栏 -->
+    <ControlPanel ref="controlPanel" />
+  </div>
 </template>
 
 <script>
+import ControlPanel from "../../components/wgn/controlPanel.vue";
+// 需要开发出一个时空算子库的示例页面:需要能绘制点线面的工具,且能包装绘制的几何对象传入到后台接口中
 export default {
-    name: "",
-    data() {
-        return {
+  name: "wgnExample",
+  // 2. 局部注册组件(键值同名可简写)
+  components: {
+    ControlPanel, // 完整写法:MyButton: MyButton
+  },
+  data() {
+    return {};
+  },
+  mounted() {
+    window.SkySceneryConfig = {};
+    window.loadScripts([systemConfig.scriptMain]).then(() => {
+      this.creatMap();
+    });
+  },
+  methods: {
+    creatMap() {
+      window.viewer = new SkyScenery.Viewer("skysceneryContainer", {
+        animation: false, //是否创建动画小器件,左下角仪表
+        baseLayerPicker: false, //是否显示图层选择器
+        imageryProvider: new SkyScenery.SingleTileImageryProvider({
+          url: (function createColorCanvas(color) {
+            var width = 1,
+              height = 1;
+            var canvas = document.createElement("canvas");
+            canvas.width = width;
+            canvas.height = height;
+            var ctx = canvas.getContext("2d");
+            ctx.fillStyle = color;
+            ctx.fillRect(0, 0, width, height);
+            return canvas.toDataURL();
+          })("#ffffff00"),
+          rectangle: SkyScenery.Rectangle.fromDegrees(-180.0, -90.0, 180.0, 90.0),
+        }),
+        fullscreenButton: false, //是否显示全屏按钮
+        geocoder: false, //是否显示geocoder小器件,右上角查询按钮
+        homeButton: false, //是否显示Home按钮
+        infoBox: false, //是否显示信息框
+        sceneModePicker: false, //是否显示3D/2D选择器
+        selectionIndicator: false, //是否显示选取指示器组件
+        timeline: false, //是否显示时间轴
+        navigationHelpButton: false, //是否显示右上角的帮助按钮
+        scene3DOnly: true, //如果设置为true,则所有几何图形以3D模式绘制以节约GPU资源
+        shouldAnimate: false, //是否自动播放
+        // 性能优化配置
+        requestRenderMode: true,
+        maximumRenderTimeChange: Infinity,
+        preserveDrawingBuffer: false,
+        useBrowserRecommendedResolution: true,
+      });
 
-        };
-    },
-    mounted() {
+      // 添加地图服务
+      viewer.imageryLayers.addImageryProvider(
+        new SkyScenery.ArcGisMapServerImageryProvider({
+          url:
+            "https://szlszxdt.qpservice.org.cn/internal_map/?servertype=shmap_blue_web&proxyToken=" +
+            SkySceneryConfig.token,
+          enablePickFeatures: false, // 禁用要素拾取功能以提高性能
+        })
+      );
+
+      // 定位
+      viewer.camera.setView({
+        destination: SkyScenery.Cartesian3.fromDegrees(121.1, 31, 30000.0), // 设置位置
+        orientation: {
+          heading: SkyScenery.Math.toRadians(0.0), // 方向
+          pitch: SkyScenery.Math.toRadians(-90.0), // 倾斜角度
+          roll: 0,
+        },
+      });
+      this.$refs["controlPanel"].initDrawHandler();
     },
-    methods: {
-    }
+  },
 };
 </script>
 
 <style lang="less" scoped>
-.container {
-    width: 1920px;
-    margin: 0 auto;
+.example {
+  width: 100%;
+  // height: calc(100vh - 120px);
+  height: 100vh;
+  position: relative;
+  overflow: hidden;
+}
+
+#skysceneryContainer {
+  width: 70vw;
+  max-width: calc(100vw - 500px);
+  height: 100%;
 }
-</style>
+</style>

+ 490 - 0
src/views/wgn/sksj/index.vue

@@ -0,0 +1,490 @@
+<template>
+    <div class="container">
+        <div style="position: absolute;top: 20px;left: 20px;z-index: 9;">
+            <div style="display: flex;">
+                <el-select
+                v-model="typeValue"
+                placeholder="Select"
+                style="width: 150px"
+                @change="changType"
+                >
+                <el-option
+                    v-for="item in options"
+                    :key="item.value"
+                    :label="item.label"
+                    :value="item.value"
+                />
+                </el-select>
+                <el-input v-if="typeValue != 6" v-model="inputAddress" style="width: 200px;height: 32px;padding: 0px 10px;" placeholder="输入URL地址……" />
+                <div style="padding: 0px 10px;" v-if="typeValue == 6">
+                    <el-upload
+                        ref="uploadRef"
+                        action=""
+                        :auto-upload="false"
+                        :file-list="fileList"
+                        :show-file-list="false"
+                        accept=".json,.geojson"
+                        :on-change="handleChange"
+                    >
+                    <template #trigger>
+                        <el-button type="primary">上传文件</el-button>
+                    </template>
+                    </el-upload>
+                </div>
+                <el-button type="primary" @click="parse">解析</el-button>
+            </div>
+        </div>
+        <Map style="overflow: hidden;"></Map>
+        <div class="infoDialog" v-show="infoDialogShow">
+            <div class="close" @click="closeWin">×</div>
+            <div class="content" v-if="nowPoint != null">
+                <el-scrollbar>
+                    <div class="item" v-for="info in nowPointInfo" :key="info">{{info.key}}: {{ info.value }}</div>
+                </el-scrollbar>
+            </div>
+        </div>
+    </div>
+</template>
+
+<script>
+import { ElMessage } from 'element-plus'
+import Map from "@/views/example/Map.vue";
+import { toRaw } from "vue";
+export default {
+    name: "",
+    components: {
+       Map
+    },
+    data() {
+        return {
+            listData:[],
+            fileList: [],
+            dataJson:[],
+            wmslayer: {},
+            pointImg:require('@static/images/point.png'),
+            geometryArr:[],
+            mapHandle:null,
+            infoDialogShow:false,
+            nowPoint: null,
+            nowPointInfo:null,
+            typeValue:'1',
+            inputAddress:'http://121.43.55.7:8889/geoserver/kdyjs/wms',
+            options:[
+                {
+                    value: '1',
+                    label: '栅格WMS服务',
+                },
+                {
+                    value: '2',
+                    label: '栅格WMTS服务',
+                },{
+                    value: '3',
+                    label: '栅格ArcGis服务',
+                },
+                {
+                    value: '4',
+                    label: '3dtiles数据',
+                },
+                // {
+                //     value: '5',
+                //     label: '矢量数据',
+                // },
+                {
+                    value: '6',
+                    label: '矢量文件',
+                }
+            ]
+        };
+    },
+    mounted() {
+        
+    },
+    methods: {
+        beforeUpload(file) {
+            const maxSize = 2; // 限制为2MB
+            if (file.size / 1024 / 1024 > maxSize) {
+                ElMessage({
+                    type: 'error',
+                    message: `文件大小不能超过 ${maxSize}MB!`,
+                })
+                return false;
+            }
+            return true;
+        },
+        handleChange(files,fileLists){
+            let that = this;
+            if (fileLists.length >1) {
+                fileLists.shift();
+            }
+            that.fileList = fileLists;
+            let reader = new FileReader();
+            reader.readAsText(that.fileList[0].raw, "UTF-8");
+            reader.onload = (evt) => {
+                that.dataJson = JSON.parse(evt.target.result);
+                console.log(that.dataJson); // 输出解析后的JSON数据
+                ElMessage({
+                    type: 'success',
+                    message: `文件处理成功,请解析上图展示`,
+                })
+            };
+        },
+        closeWin() {
+            this.infoDialogShow = false;
+            this.nowPoint = null;
+            this.nowPointInfo = null;
+        },
+        dwanMap(){
+            let that = this;
+            if(that.geometryArr.length>0){
+                that.geometryArr.map(function (info) {
+                    viewer.entities.remove(info)
+                })
+            }
+            that.geometryArr = that.dataJson.features.map(function (info) {
+                if(info.geometry.type == "Point"){
+                    return that.addPoint(info)
+                }else if(info.geometry.type == "LineString"){
+                    return that.addLine(info)
+                }else{
+                    return that.addPolygon(info)
+                }
+                
+            })
+            that.pointTCHandle();
+        },
+        addPolygon(param){
+            let arr = [];
+            param.geometry.coordinates.forEach(element => {
+                element.forEach(e => {
+                    arr.push(e[0]);
+                    arr.push(e[1]);
+                })
+            });
+            return viewer.entities.add(new SkyScenery.Entity({
+                name: " polygon",
+                polygon: {
+                    hierarchy: {
+                        positions: SkyScenery.Cartesian3.fromDegreesArray(arr)
+                    },
+                    heightReference: SkyScenery.HeightReference.CLAMP_TO_GROUND,
+                    material: SkyScenery.Color.CYAN.withAlpha(0.5)
+                },
+                info: {
+                    coor: [arr[0], arr[1]],
+                    properties: param.properties
+                },
+            }));
+        },
+        addLine(param){
+            return viewer.entities.add({
+                name: "line",
+                polyline: {
+                    //经纬度数组转世界坐标,带高度的话是fromDegreesArrayHeights
+                    positions: SkyScenery.Cartesian3.fromDegreesArray(param.geometry.coordinates),
+                    width: 2,
+                    material: SkyScenery.Color.CYAN,
+                    info: {
+                        properties: param.properties
+                    },
+                }
+            });
+        },
+        addPoint(param){
+            let that = this;
+            return viewer.entities.add(new SkyScenery.Entity({
+                name:"point",
+                position: SkyScenery.Cartesian3.fromDegrees(param.geometry.coordinates[0], param.geometry.coordinates[1]),
+                type: "point",
+                info: {
+                  coor: [param.geometry.coordinates[0], param.geometry.coordinates[1]],
+                  properties: param.properties
+                },
+                billboard: {
+                  image: that.pointImg,
+                  disableDepthTestDistance: Number.POSITIVE_INFINITY,
+                  scale: 0.3,
+                  horizontalOrigin: SkyScenery.HorizontalOrigin.CENTER,
+                  verticalOrigin: SkyScenery.VerticalOrigin.BOTTOM,
+                }
+              }));
+        },
+        // 点击事件绑定
+        pointTCHandle() {
+            let that = this;
+            if (!this.mapHandle) {
+                this.mapHandle = new SkyScenery.ScreenSpaceEventHandler(viewer.canvas, this);
+                this.mapHandle.setInputAction(function (movement) {
+                    that.infoDialogShow = false
+                    const pickedObject = viewer.scene.pick(movement.position);
+
+                    let cartesian = viewer.camera.pickEllipsoid(
+                        movement.position,
+                        viewer.scene.globe.ellipsoid
+                    );
+                    // 空间坐标转世界坐标(弧度)
+                    let cartographic = SkyScenery.Cartographic.fromCartesian(cartesian);
+                    // 弧度转为角度(经纬度)
+                    let lon = SkyScenery.Math.toDegrees(cartographic.longitude); // 经度值
+                    let lat = SkyScenery.Math.toDegrees(cartographic.latitude); // 纬度值
+                    let center = [lon,lat]
+                    if (SkyScenery.defined(pickedObject) && SkyScenery.defined(pickedObject.id)) {
+                        const entity = pickedObject.id;
+                        that.infoDialogShow = true
+                        that.nowPoint = entity.info;
+                        that.nowPointInfo =  Object.keys(that.nowPoint.properties).map(key => ({ key, value: that.nowPoint.properties[key] }));
+                        that.nowPoint["type"] = "info";
+                        // let xy = that.lonlatConvertToScreenXY(entity.info.coor)
+                        let xy = that.lonlatConvertToScreenXY(center)
+                        document.querySelector(".infoDialog").style.top = (xy.y - 230) + "px";
+                        document.querySelector(".infoDialog").style.left = (xy.x - 100) + "px";
+                    } else {
+                        // console.log('未拾取到实体');
+                    }
+                }, SkyScenery.ScreenSpaceEventType.LEFT_CLICK);
+                viewer.scene.postRender.addEventListener(that.updatePosition, this);
+            } else {
+                toRaw(this.mapHandle).destroy();
+                this.mapHandle = null
+                that.nowPointInfo = null
+                viewer.scene.postRender.removeEventListener(that.updatePosition, this);
+            }
+        },
+        // 经纬度转屏幕坐标
+        lonlatConvertToScreenXY(lonlat) {
+            // 定义经纬度
+            var longitude = SkyScenery.Math.toRadians(lonlat[0]); // 例如:东经116.391度
+            var latitude = SkyScenery.Math.toRadians(lonlat[1]); // 例如:北纬39.907度
+            var height = 0; // 高度,通常在地表为0
+            // 将经纬度转换为笛卡尔坐标
+            // var cartographic = SkyScenery.Cartographic.fromDegrees(longitude, latitude, height);
+            var cartesian = SkyScenery.Cartesian3.fromRadians(longitude, latitude, height, viewer.scene.globe.ellipsoid);
+            // 将笛卡尔坐标转换为窗口坐标
+            var canvasCoordinates = viewer.scene.cartesianToCanvasCoordinates(cartesian);
+            return canvasCoordinates
+        },
+        // 位置更新
+        updatePosition() {
+            try {
+                if (this.nowPoint != null) {
+                    const obj = toRaw(this.nowPoint);
+                    let xy = this.lonlatConvertToScreenXY(obj.coor)
+                    if (!xy) {
+                        document.querySelector(".infoDialog").style.top = "-9999px";
+                        document.querySelector(".infoDialog").style.left = "-9999px";
+                    } else {
+                        document.querySelector(".infoDialog").style.top = (xy.y - 230) + "px";
+                        document.querySelector(".infoDialog").style.left = (xy.x - 100) + "px";
+                    }
+                }
+            } catch (error) {
+                // debugger
+            }
+        },
+        addWMTSLayer(param) {
+            let matrixIds = [];
+            for (let i = 0; i < 19; i++) {
+                matrixIds[i] = i + 1;
+            }
+            // this.removeMapLayer();
+            // console.log('[ WMTS ] >'+param)
+            let layer = viewer.imageryLayers.addImageryProvider(
+                new SkyScenery.WebMapTileServiceImageryProvider({
+                    url: param.url,
+                    layer: param.layers, // 固定的 cia  img  vec  cva 四种类型
+                    style: "default",
+                    format: "tiles",
+                    // format:"image/png",
+                    tileMatrixSetID: "w",
+                    TileMatrixLabels: matrixIds,
+                    subdomains: ["t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7"],
+                    minimumLevel: 1,
+                    maximumLevel: 18,
+                    tilingScheme: new SkyScenery.WebMercatorTilingScheme()
+                })
+            );
+            this.wmslayer.mapItemLayer = layer;
+        },
+        addWMSLayer(param) {
+            // console.log('[ WMS ] >'+param)
+            let layer =  viewer.imageryLayers.addImageryProvider(
+                new SkyScenery.WebMapServiceImageryProvider({
+                    url: param.url,
+                    layers: param.layers, //固定的已发布的类型
+                    parameters: {
+                        TRANSPARENT: true,
+                        format: "image/png"
+                    }
+                })
+            );
+            this.wmslayer.mapItemLayer = layer;
+        },
+        addARCGISLayer(param){
+            // console.log('[ ArcGisMapServer ] >'+param)
+            // this.removeMapLayer();
+            // 添加地图服务
+            let layer =  viewer.imageryLayers.addImageryProvider(
+                // 此处使用的地图服务地址也可存放在配置文件中
+                new SkyScenery.ArcGisMapServerImageryProvider({
+                    url: param.url
+                })
+            );
+            this.wmslayer.mapItemLayer = layer;
+        },
+        removeMapLayer(){
+            // console.log('[ eee ] >')
+            if(this.wmslayer.mapItemLayer){
+                viewer.imageryLayers.remove(toRaw(this.wmslayer.mapItemLayer))
+                delete this.wmslayer.mapItemLayer;
+            }
+            
+        },
+        getVectorData(param){
+            let that = this;
+            fetch(param.url, {
+                method: 'GET',
+            }).then(response => response.json()) // 假设服务器返回 JSON 数据
+                .then(data => {
+                    console.log('[ eee ] >')
+                    that.dataJson = data.result;
+                    that.closeWin()
+                    that.dwanMap()
+                })
+        },
+        add3dtilesData(param){
+            console.log('[ add3dtilesData ] >'+param)
+            let tile1 = new SkyScenery.add3DTilesData(param.url, viewer)
+            tile1.readyPromise.then(function (tileset) {
+                viewer.zoomTo(tile1)
+            });
+        },
+        changType(){
+            let that = this;
+            // this.inputAddress = '';
+            if(that.typeValue == 1){
+                let curUrl = 'http://121.43.55.7:8889/geoserver/kdyjs/wms';
+                that.inputAddress = curUrl;
+            }else if(that.typeValue == 2){
+                let type = "vec"; //cia  img  vec  cva
+                let curUrl = "https://{s}.tianditu.gov.cn/"+type+"_w/wmts?tk=f74e6c0cc247c42af05f7053e0b5fb9b";
+                that.inputAddress = curUrl;
+             
+            }else if(that.typeValue == 3){
+                let curUrl = 'https://service-api.onemap.sh.gov.cn/data-service-manage-service/MapProxyApi/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhcHBsaWNhdGlvbl9pZCI6NjEsImFwcGxpY2F0aW9uX25hbWUiOiLpnZLmtabkuozkuInnu7TmnI3liqHns7vnu58iLCJleHAiOjIwNDY2Nzg0MDN9.IKUMdjUX4U1jncIUNren-iotL7duXI90aLECMjpvUX8/shmap_normal_web/MapServer';
+                that.inputAddress = curUrl;
+            }else if(that.typeValue == 4){
+                let curUrl = "http://121.43.55.7:65456/shzx/tileset.json";
+                that.inputAddress = curUrl;
+            }else if(that.typeValue == 5){
+                let curUrl = "http://121.43.55.7:10018/kdyjs/shop/recommend?type=1&size=20&banned=1,2,3";
+                that.inputAddress = curUrl;
+            }else if(that.typeValue == 6){
+                that.inputAddress = "";
+            }
+        },
+        parse(){
+            let that = this;
+            if( that.typeValue != 6 && that.inputAddress == ''){
+                return ElMessage({
+                    type: 'error',
+                    message: `输入地址不能为空!请输入地址后进行解析`,
+                })
+            }
+            console.log('[ eee ] >')
+            //  typeValue:'1',
+            // inputAddress:'',
+            
+            if(that.typeValue == 1){
+                // let curUrl = that.inputAddress;
+                let curUrl = 'http://121.43.55.7:8889/geoserver/kdyjs/wms';
+                that.inputAddress = curUrl;
+                let param = {url:curUrl,layers:'kdyjs:CourtyardFace'}
+                that.addWMSLayer(param)
+
+            }else if(that.typeValue == 2){
+                let type = "vec"; //cia  img  vec  cva
+                let curUrl = "https://{s}.tianditu.gov.cn/"+type+"_w/wmts?tk=f74e6c0cc247c42af05f7053e0b5fb9b";
+                that.inputAddress = curUrl;
+                let param = {url:curUrl,layers:type}
+                that.addWMTSLayer(param)
+             
+            }else if(that.typeValue == 3){
+                // let curUrl = that.inputAddress;
+                let curUrl = 'https://service-api.onemap.sh.gov.cn/data-service-manage-service/MapProxyApi/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhcHBsaWNhdGlvbl9pZCI6NjEsImFwcGxpY2F0aW9uX25hbWUiOiLpnZLmtabkuozkuInnu7TmnI3liqHns7vnu58iLCJleHAiOjIwNDY2Nzg0MDN9.IKUMdjUX4U1jncIUNren-iotL7duXI90aLECMjpvUX8/shmap_normal_web/MapServer';
+                that.inputAddress = curUrl;
+                let param = {url:curUrl,layers:'arcgisLayer'}
+                that.addARCGISLayer(param)
+            }else if(that.typeValue == 4){
+                // let curUrl = that.inputAddress;
+                let curUrl = "http://121.43.55.7:65456/shzx/tileset.json";
+                that.inputAddress = curUrl;
+                let param = {url:curUrl}
+                that.add3dtilesData(param);
+            }else if(that.typeValue == 5){
+                // let curUrl = that.inputAddress;
+                let curUrl = "https://kdyjs-proxy.metamaker.cn/proxy_map/static/json/%E6%A5%BC%E5%AE%87%E6%95%B0%E6%8D%AE-20250820.geojson";
+                that.inputAddress = curUrl;
+                let param = {url:curUrl}
+                that.getVectorData(param);
+            }else if(that.typeValue == 6){
+                //上传GeoJson文件解析数据并上图
+                if(this.mapHandle){
+                    toRaw(this.mapHandle).destroy();
+                    this.mapHandle = null
+                    that.nowPointInfo = null
+                }
+                that.closeWin()
+                that.dwanMap()
+                
+            }
+            
+        }
+    },
+    beforeDestroy() {
+        viewer = undefined
+    }
+};
+</script>
+<style lang="less" scoped>
+
+.container {
+    width: 100%;
+    padding: 0px;
+    margin: 0 auto;
+    overflow: hidden;
+}
+.infoDialog {
+    position: absolute;
+    top: 0px;
+    left: 0px;
+    max-width: 500px;
+    height: 200px;
+    // background: #01346f99;
+    background: #ffffff;
+    border-radius: 10px;
+
+    .close {
+      font-size: 24px;
+      position: absolute;
+      top: 6px;
+      right: 8px;
+      line-height: 24px;
+      width: 24px;
+      height: 24px;
+      cursor: pointer;
+      // color: #ffffff;
+      color: #000000;
+    }
+
+    .content {
+      height: 160px;
+      // color: #ffffff;
+      color: #000000;
+      margin: 30px 0px 10px 20px;
+      overflow: auto;
+      .item {
+        line-height: 30px;
+        margin-right: 20px;
+      }
+    }
+  }
+</style>

+ 0 - 27
src/views/xxfk/Example.vue

@@ -1,27 +0,0 @@
-<template>
-    <div class="example">
-        xxfk example
-    </div>
-</template>
-
-<script>
-export default {
-    name: "",
-    data() {
-        return {
-
-        };
-    },
-    mounted() {
-    },
-    methods: {
-    }
-};
-</script>
-
-<style lang="less" scoped>
-.container {
-    width: 1920px;
-    margin: 0 auto;
-}
-</style>

+ 243 - 0
src/views/yxgl/StatisticalAnalysis.vue

@@ -0,0 +1,243 @@
+<template>
+  <div class="mainBox">
+    <!-- 搜索区域 -->
+    <div class="searchBox">
+      <div>
+        <el-date-picker
+          v-model="dateValue"
+          type="daterange"
+          unlink-panels
+          range-separator="到"
+          start-placeholder="开始时间"
+          end-placeholder="结束时间"
+          :shortcuts="shortcuts"
+          size="large"
+        />
+      </div>
+    </div>
+    <!-- 服务调用card -->
+    <div class="flex">
+      <card
+        class="card flex"
+        :title="'服务机构总数'"
+        :value="8"
+        :growth="'较上个月增长了12%'"
+        iconColor="#2563db"
+        :upStatus="1"
+      />
+      <card
+        class="card flex"
+        :title="'服务总数'"
+        :value="100"
+        :growth="'较上个月下降了12%'"
+        iconColor="#16a34a"
+        :upStatus="-1"
+      />
+      <card
+        class="card flex"
+        :title="'服务调用总次数'"
+        :value="1000"
+        :growth="'较上个月增长了12%'"
+        iconColor="#9333ea"
+        :upStatus="1"
+      />
+      <card
+        class="card flex"
+        :title="'服务类别数量'"
+        :value="10"
+        :growth="'与上月持平'"
+        iconColor="#ca8a04"
+        :upStatus="0"
+      />
+    </div>
+    <!-- 服务类信息统计 -->
+    <div class="bigCard">
+      <div class="bigCard_title">服务类信息统计</div>
+      <div class="tools">
+        <el-button>
+          <el-icon><Upload /></el-icon> 导出数据
+        </el-button>
+        <el-button type="primary">
+          <el-icon><TrendCharts /></el-icon>
+          详细报告
+        </el-button>
+      </div>
+      <div class="flex">
+        <div style="width: 48%; height: 400px">
+          <EchartsDome title="服务调用趋势(近30天)" />
+        </div>
+        <div style="width: 48%; height: 400px">echarts2</div>
+      </div>
+      <div style="width: 100%; height: 400px">tables</div>
+    </div>
+    <!-- 用户信息统计 -->
+    <div class="bigCard">用户信息统计</div>
+    <!-- 应用类信息统计 -->
+    <div class="bigCard">应用类信息统计</div>
+    <!-- 数据类信息统计 -->
+    <div class="bigCard">数据类信息统计</div>
+    <!-- 区级特色信息统计 -->
+    <div class="bigCard">区级特色信息统计</div>
+  </div>
+</template>
+
+<script>
+import card from "@/components/yxgl/card.vue";
+import EchartsDome from "@/components/yxgl/EchartsDome.vue";
+export default {
+  name: "",
+  components: {
+    card,
+    EchartsDome,
+  },
+  data() {
+    return {
+      dateValue: "",
+      shortcuts: this.shortcuts(),
+    };
+  },
+  mounted() {},
+  methods: {
+    shortcuts() {
+      return [
+        {
+          text: "最近7天",
+          value: () => {
+            const end = new Date();
+            const start = new Date();
+            start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
+            return [start, end];
+          },
+        },
+        {
+          text: "最近30天",
+          value: () => {
+            const end = new Date();
+            const start = new Date();
+            start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
+            return [start, end];
+          },
+        },
+        {
+          text: "最近90天",
+          value: () => {
+            const end = new Date();
+            const start = new Date();
+            start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
+            return [start, end];
+          },
+        },
+        {
+          text: "最近1年",
+          value: () => {
+            const end = new Date();
+            const start = new Date();
+            start.setTime(start.getTime() - 3600 * 1000 * 24 * 365);
+            return [start, end];
+          },
+        },
+      ];
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.mainBox {
+  width: calc(100% - 60px);
+  margin: 30px;
+  & > div {
+    margin: 20px 0;
+    display: flex;
+    overflow: hidden;
+  }
+  .card {
+    width: calc(25% - 56px);
+    border-radius: 5px;
+    padding: 20px 18px;
+    background: #ffffff;
+  }
+
+  .bigCard {
+    width: calc(100% - 36px);
+    border-radius: 5px;
+    padding: 20px 18px;
+    background: #ffffff;
+    position: relative;
+    flex-direction: column;
+    .tools {
+      position: absolute;
+      top: 20px;
+      right: 20px;
+      display: flex;
+      flex-direction: row;
+      justify-content: flex-end;
+    }
+    &_title {
+      font-size: 20px;
+      font-weight: bold;
+    }
+  }
+
+  .flex {
+    display: flex;
+    flex-direction: row;
+    justify-content: space-between;
+  }
+
+  .searchBox {
+    width: 100%;
+    height: 50px;
+    line-height: 50px;
+    text-align: center;
+    font-size: 20px;
+    font-weight: bold;
+    flex-direction: row-reverse;
+    display: flex;
+  }
+}
+
+// 日期选择框样式
+.demo-date-picker {
+  display: flex;
+  width: 100%;
+  padding: 0;
+  flex-wrap: wrap;
+}
+
+.demo-date-picker .block {
+  padding: 1.5rem 0;
+  text-align: center;
+  border-right: solid 1px var(--el-border-color);
+  flex: 1;
+  min-width: 400px;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+}
+
+.demo-date-picker .block:last-child {
+  border-right: none;
+}
+
+.demo-date-picker .demonstration {
+  display: block;
+  color: var(--el-text-color-secondary);
+  font-size: 14px;
+  margin-bottom: 1rem;
+}
+
+@media screen and (max-width: 1200px) {
+  .demo-date-picker .block {
+    flex: 0 0 100%;
+    padding: 1rem 0;
+    min-width: auto;
+    border-right: none;
+    border-bottom: solid 1px var(--el-border-color);
+  }
+
+  .demo-date-picker .block:last-child {
+    border-bottom: none;
+  }
+}
+</style>

+ 116 - 0
src/views/yygl/appCenter.vue

@@ -0,0 +1,116 @@
+<template>
+  <div class="app-center">
+    <div class="container">
+        <!-- 左侧导航栏 -->
+        <div class="sidebar">
+        <div class="sidebar-menu">
+            <div class="menu-item" :class="{'active': menuValue === 1}" @click="handleMenuClick(1)">
+            <el-icon><Menu /></el-icon>
+            <span>应用概览</span>
+            </div>
+            <div class="menu-item" :class="{'active': menuValue === 2}" @click="handleMenuClick(2)">
+            <el-icon><Grid /></el-icon>
+            <span>应用管理</span>
+            </div>
+            <div class="menu-item" :class="{'active': menuValue === 3}" @click="handleMenuClick(3)">
+            <el-icon><Monitor /></el-icon>
+            <span>应用监测</span>
+            </div>
+        </div>
+        </div>
+
+        <!-- 右侧主内容区 -->
+        <div class="main-content">
+            <AppOverview v-if="menuValue === 1" />
+            <AppManagement v-if="menuValue === 2" />
+            <AppMonitoring v-if="menuValue === 3" />
+        </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import AppOverview from "@/views/yygl/overview/index.vue";
+import AppManagement from "@/views/yygl/manage/index.vue";
+import AppMonitoring from "@/views/yygl/monitor/index.vue";
+export default {
+  name: "AppCenter",
+  components: {
+    AppOverview,
+    AppManagement,
+    AppMonitoring,
+  },
+  data() {
+    return {
+        menuValue:1
+    }
+  },
+  methods: {
+    handleMenuClick(value) {
+      this.menuValue = value;
+    }
+  }
+}
+</script>
+
+<style lang="less" scoped>
+.app-center {
+  width: 100%;
+//   min-height: 100vh;
+  height: calc(100vh - 120px);
+  background-color: #08224a;
+  color: #ffffff;
+  overflow-x: hidden;
+}
+.container {
+  display: flex;
+  width: 100%;
+  height: 100%;
+  background-color: #08224a;
+  color: #ffffff;
+}
+
+/* 左侧导航栏样式 */
+.sidebar {
+  width: 200px;
+  background-color: #0a2a5a;
+  border-right: 1px solid rgba(255, 255, 255, 0.1);
+  
+  .sidebar-menu {
+    padding: 20px 0;
+    
+    .menu-item {
+      display: flex;
+      align-items: center;
+      padding: 15px 20px;
+      cursor: pointer;
+      transition: all 0.3s ease;
+      color: rgba(255, 255, 255, 0.8);
+      
+      i {
+        margin-right: 12px;
+        font-size: 18px;
+      }
+      
+      &:hover {
+        background-color: rgba(24, 144, 255, 0.2);
+        color: #ffffff;
+      }
+      
+      &.active {
+        background-color: rgba(24, 144, 255, 0.3);
+        color: #ffffff;
+        border-right: 3px solid #1890ff;
+      }
+    }
+  }
+}
+
+/* 右侧主内容区 */
+.main-content {
+  flex: 1;
+  padding: 20px 30px;
+  overflow: auto;
+}
+
+</style>

+ 292 - 0
src/views/yygl/index.vue

@@ -0,0 +1,292 @@
+<template>
+  <div class="application-center">
+    <!-- 顶部横幅区域 -->
+    <div class="banner">
+      <div class="banner-content">
+        <h1 class="banner-title">应用中心</h1>
+        <p class="banner-description">
+          收集、管理区级应用的访问地址、使用单位、使用情况等。
+          区委办局、街镇、居村应基于区级节点开展区级时空应用建设。
+        </p>
+        <el-button type="primary" class="enter-button" @click="handleEnterClick">点击进入</el-button>
+      </div>
+    </div>
+
+    <!-- 示范应用区域 -->
+    <div class="demo-applications">
+      <div class="section-title">
+        <h2>示范应用</h2>
+        <div class="title-line"></div>
+      </div>
+
+      <div class="applications-grid">
+        <!-- 应用卡片1 -->
+        <div class="application-card">
+          <div class="card-image">
+            <img src="~@/assets/images/common/app-bg-1.png" alt="青浦区环境自动监测信息化平台" />
+          </div>
+          <h3 class="card-title">青浦区环境自动监测信息化平台</h3>
+          <div class="card-info">
+            <p><strong>访问类型:</strong>公开</p>
+            <p><strong>建设单位:</strong>青浦区环境局</p>
+            <p><strong>建设时间:</strong>2024.10.25</p>
+          </div>
+        </div>
+
+        <!-- 应用卡片2 -->
+        <div class="application-card">
+          <div class="card-image">
+            <img src="~@/assets/images/common/app-bg-2.png" alt="青浦区燃气行业监管平台" />
+          </div>
+          <h3 class="card-title">青浦区燃气行业监管平台</h3>
+          <div class="card-info">
+            <p><strong>访问类型:</strong>公开</p>
+            <p><strong>建设单位:</strong>青浦区环境局</p>
+            <p><strong>建设时间:</strong>2024.10.25</p>
+          </div>
+        </div>
+
+      </div>
+       <div class="applications-grid">
+        <!-- 应用卡片3 -->
+            <div class="application-card">
+            <div class="card-image">
+                <img src="~@/assets/images/common/app-bg-3.png" alt="青浦区环境自动监测信息化平台" />
+            </div>
+            <h3 class="card-title">青浦区环境自动监测信息化平台</h3>
+            <div class="card-info">
+                <p><strong>访问类型:</strong>公开</p>
+                <p><strong>建设单位:</strong>青浦区环境局</p>
+                <p><strong>建设时间:</strong>2024.10.25</p>
+            </div>
+            </div>
+
+            <!-- 应用卡片4 -->
+            <div class="application-card">
+            <div class="card-image">
+                <img src="~@/assets/images/common/app-bg-4.png" alt="青浦区消防救援支队一网统管平台" />
+            </div>
+            <h3 class="card-title">青浦区消防救援支队一网统管平台</h3>
+            <div class="card-info">
+                <p><strong>访问类型:</strong>公开</p>
+                <p><strong>建设单位:</strong>青浦区环境局</p>
+                <p><strong>建设时间:</strong>2024.10.25</p>
+            </div>
+            </div>
+       </div>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  name: "ApplicationCenter",
+  data() {
+    return {}
+  },
+  methods: {
+    handleEnterClick() {
+      this.$router.push('appCenter');
+    }
+  }
+}
+</script>
+
+<style lang="less" scoped>
+.application-center {
+  width: 100%;
+  min-height: 100vh;
+  background-color: #08224a;
+  color: #ffffff;
+  overflow-x: hidden;
+}
+
+/* 顶部横幅样式 */
+.banner {
+  width: 100%;
+  height: 786px;
+  background: url(~@/assets/images/common/u720.png) no-repeat center center;
+  background-size: cover;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  position: relative;
+  overflow: hidden;
+
+  &::before {
+    content: '';
+    position: absolute;
+    top: 0;
+    left: 0;
+    width: 100%;
+    height: 100%;
+    background: rgba(8, 34, 74, 0.7);
+    z-index: 1;
+  }
+
+  .banner-content {
+    position: relative;
+    z-index: 2;
+    text-align: center;
+    max-width: 800px;
+    padding: 0 20px;
+  }
+
+  .banner-title {
+    font-size: 64px;
+    font-weight: bold;
+    letter-spacing: 0.5rem;
+    margin-bottom: 20px;
+    color: #ffffff;
+    text-align: left;
+    text-shadow: 0 2px 10px rgba(0, 0, 0, 0.5);
+  }
+
+  .banner-description {
+    font-size: 22px;
+    line-height: 1.8;
+    margin-bottom: 40px;
+    margin-top: 70px;
+    text-align: left;
+    color: rgba(255, 255, 255, 0.9);
+  }
+
+  .enter-button {
+    padding: 12px 36px;
+    font-size: 18px;
+    border-radius: 10px;
+    background-color: #1890ff;
+    border: none;
+    transition: all 0.3s ease;
+
+    &:hover {
+      background-color: #40a9ff;
+      transform: translateY(-2px);
+      box-shadow: 0 4px 12px rgba(24, 144, 255, 0.4);
+    }
+  }
+}
+
+/* 示范应用区域样式 */
+.demo-applications {
+  padding: 60px 20px;
+//   max-width: 1400px;
+  width: 80%;
+  margin: 0 auto;
+
+  .section-title {
+    text-align: center;
+    margin-bottom: 60px;
+
+    h2 {
+      font-size: 36px;
+      font-weight: bold;
+      margin-bottom: 15px;
+      color: #ffffff;
+    }
+
+    .title-line {
+      width: 80px;
+      height: 3px;
+      background-color: #1890ff;
+      margin: 0 auto;
+    }
+  }
+
+  .applications-grid {
+    display: grid;
+    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
+    gap: 30px;
+    margin: 60px 0 60px 0px;
+    .application-card {
+      background: rgba(24, 144, 255, 0.1);
+      border: 1px solid rgba(24, 144, 255, 0.3);
+      border-radius: 8px;
+      overflow: hidden;
+      transition: all 0.3s ease;
+
+      &:hover {
+        transform: translateY(-5px);
+        box-shadow: 0 10px 30px rgba(24, 144, 255, 0.3);
+        border-color: rgba(24, 144, 255, 0.6);
+      }
+
+      .card-image {
+        width: 100%;
+        height: 200px;
+        overflow: hidden;
+
+        img {
+          width: 100%;
+          height: 100%;
+          object-fit: cover;
+          transition: transform 0.3s ease;
+        }
+
+        &:hover img {
+          transform: scale(1.05);
+        }
+      }
+
+      .card-title {
+        font-size: 18px;
+        font-weight: bold;
+        padding: 20px 20px 15px;
+        margin: 0;
+        color: #ffffff;
+        border-bottom: 1px solid rgba(24, 144, 255, 0.3);
+      }
+
+      .card-info {
+        padding: 15px 20px 20px;
+        font-size: 14px;
+        // color: rgba(255, 255, 255, 0.8);
+        color: #ffffff;
+
+        p {
+          margin: 8px 0;
+          line-height: 1.6;
+
+          strong {
+            // color: rgba(24, 144, 255, 0.9);
+            color: #ffffff;
+          }
+        }
+      }
+    }
+  }
+}
+
+/* 响应式设计 */
+@media (max-width: 768px) {
+  .banner {
+    height: 400px;
+
+    .banner-title {
+      font-size: 36px;
+    }
+
+    .banner-description {
+      font-size: 14px;
+    }
+
+    .enter-button {
+      padding: 10px 28px;
+      font-size: 16px;
+    }
+  }
+
+  .demo-applications {
+    padding: 40px 15px;
+
+    .section-title h2 {
+      font-size: 28px;
+    }
+
+    .applications-grid {
+      grid-template-columns: 1fr;
+      gap: 20px;
+    }
+  }
+}
+</style>

+ 500 - 0
src/views/yygl/manage/index.vue

@@ -0,0 +1,500 @@
+<template>
+  <div class="application-management">
+    <!-- 右侧主内容区 -->
+    <div class="main-content">
+      <!-- 过滤条件区域 -->
+      <div class="filter-section">
+        <!-- 应用范围过滤 -->
+        <div class="filter-group">
+          <span class="filter-title">应用范围:</span>
+          <el-radio-group v-model="scopeFilter" size="small">
+            <el-radio-button label="all">全部</el-radio-button>
+            <el-radio-button label="district">区级</el-radio-button>
+            <el-radio-button label="street">街道</el-radio-button>
+            <el-radio-button label="community">社区</el-radio-button>
+          </el-radio-group>
+        </div>
+
+        <!-- 应用状态过滤 -->
+        <div class="filter-group">
+          <span class="filter-title">应用状态:</span>
+          <el-radio-group v-model="statusFilter" size="small">
+            <el-radio-button label="all">全部</el-radio-button>
+            <el-radio-button label="online">在等</el-radio-button>
+            <el-radio-button label="offline">在建</el-radio-button>
+            <el-radio-button label="suspended">在维</el-radio-button>
+            <el-radio-button label="expired">停用</el-radio-button>
+          </el-radio-group>
+        </div>
+
+        <!-- 应用标签过滤 -->
+        <div class="filter-group">
+          <span class="filter-title">应用标签:</span>
+          <el-radio-group v-model="tagFilter" size="small">
+            <el-radio-button label="all">全部</el-radio-button>
+            <el-radio-button label="special">特色应用</el-radio-button>
+            <el-radio-button label="code">代码平台</el-radio-button>
+            <el-radio-button label="government">仅供演示</el-radio-button>
+            <el-radio-button label="demo">示范应用</el-radio-button>
+            <el-radio-button label="water">水务</el-radio-button>
+            <el-radio-button label="test">测试</el-radio-button>
+          </el-radio-group>
+        </div>
+      </div>
+
+      <!-- 搜索栏区域 -->
+      <div class="search-section">
+        <el-input 
+          placeholder="请输入应用名称模块相关关键字" 
+          v-model="searchKeyword" 
+          class="search-input" 
+          clearable
+        >
+          <template #prepend><el-icon><search /></el-icon></template>
+        </el-input>
+        <el-button type="primary" class="search-btn">搜索</el-button>
+        <el-button class="reset-btn">重置</el-button>
+        <el-button type="success" class="add-btn">+ 应用介入</el-button>
+      </div>
+
+      <!-- 应用列表区域 -->
+      <div class="applications-section">
+        <div class="section-header">
+          <span class="total-count">共检索43个应用</span>
+          <div class="sort-control">
+            <span>排序:</span>
+            <el-select v-model="sortBy" size="small" style="width: 120px;">
+              <el-option label="上架时间" value="publishTime"></el-option>
+              <el-option label="下架时间" value="romveTime"></el-option>
+            </el-select>
+          </div>
+        </div>
+
+        <!-- 应用列表 -->
+        <div class="applications-list">
+          <div class="application-item" v-for="(app, index) in applications" :key="index">
+            <div class="app-info">
+              <div class="app-logo">
+                <img :src="app.logo" :alt="app.name" />
+              </div>
+              <div class="app-details">
+                <div class="app-header">
+                  <h3 class="app-name">{{ app.name }}</h3>
+                  <span class="app-version">{{ app.version }}</span>
+                </div>
+                <div class="app-tags">
+                  <el-tag size="small" type="primary" v-if="app.isPublic">区属应用</el-tag>
+                  <el-tag size="small" v-if="app.tag">{{ app.tag }}</el-tag>
+                </div>
+              </div>
+            </div>
+
+            <div class="app-metrics">
+              <div class="metric-item">
+                <span class="metric-label">应用范围</span>
+                <span class="metric-value">{{ app.buff }}</span>
+              </div>
+              <div class="metric-item">
+                <span class="metric-label">状态</span>
+                <span class="metric-value" :class="`status-${app.status}`">{{ app.statusText }}</span>
+              </div>
+              <div class="metric-item">
+                <span class="metric-label">使用单位</span>
+                <span class="metric-value">{{ app.usingUnit }}</span>
+              </div>
+              <div class="metric-item">
+                <span class="metric-label">访问量</span>
+                <span class="metric-value">{{ app.visitCount }}</span>
+              </div>
+              <div class="metric-item">
+                <span class="metric-label">上架时间</span>
+                <span class="metric-value">{{ app.createDate }}</span>
+              </div>
+            </div>
+
+            <div class="app-actions">
+              <!-- <span class="app-date">{{ app.createDate }}</span> -->
+              <el-button type="primary" size="small" class="detail-btn">查看详情</el-button>
+            </div>
+          </div>
+        </div>
+
+        <!-- 分页控件 -->
+        <div class="pagination-section">
+          <span class="total-text">共43个应用</span>
+          <el-pagination
+            layout="prev, pager, next, jumper, total"
+            :total="43"
+            :current-page="currentPage"
+            :page-size="10"
+            @current-change="handleCurrentChange"
+          >
+          </el-pagination>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  name: "ApplicationManagement",
+  data() {
+    return {
+      // 过滤条件
+      scopeFilter: 'all',
+      statusFilter: 'all',
+      tagFilter: 'all',
+      searchKeyword: '',
+      
+      // 排序条件
+      sortBy: 'publishTime',
+      
+      // 分页信息
+      currentPage: 1,
+      
+      // 应用列表数据
+      applications: [
+        {
+          logo: require('@/assets/images/common/app-bg-1.png'),
+          name: '水系统综合管理',
+          version: 'v1.0',
+          isPublic: true,
+          tag: '水务',
+          buff: '市级',
+          status: 'offline',
+          statusText: '在维',
+          usingUnit: '暂无',
+          visitCount: 64,
+          createDate: '2025-10-29 16:10:17'
+        },
+        {
+          logo: require('@/assets/images/common/app-bg-2.png'),
+          name: '虹口区历史脉管理系统开发',
+          version: 'v1.0',
+          isPublic: true,
+          tag: '',
+          buff: '区级',
+          status: 'online',
+          statusText: '在线',
+          usingUnit: '虹口区文旅局',
+          visitCount: 8,
+          createDate: '2025-09-15 18:02:32'
+        },
+        {
+          logo: require('@/assets/images/common/app-bg-3.png'),
+          name: '虹口区智慧环卫监管平台',
+          version: 'v1.0',
+          isPublic: true,
+          tag: '',
+          buff: '街道',
+          status: 'offline',
+          statusText: '在维',
+          usingUnit: '虹口区城管局',
+          visitCount: 14,
+          createDate: '2025-09-15 18:01:57'
+        },
+        {
+          logo: require('@/assets/images/common/app-bg-4.png'),
+          name: '上海市虹口区一网统管平台',
+          version: 'v1.0',
+          isPublic: true,
+          tag: '',
+          buff: '街道',
+          status: 'online',
+          statusText: '在线',
+          usingUnit: '虹口区政府办',
+          visitCount: 15,
+          createDate: '2025-09-15 18:01:09'
+        },
+        {
+          logo: require('@/assets/images/common/u661.png'),
+          name: '上海公共交通服务保障',
+          version: 'v1.0',
+          isPublic: true,
+          tag: '',
+          buff: '社区',
+          status: 'offline',
+          statusText: '在维',
+          usingUnit: '虹口区体育局',
+          visitCount: 13,
+          createDate: '2025-09-15 18:00:22'
+        }
+      ]
+    }
+  },
+  methods: {
+    // 处理分页变化
+    handleCurrentChange(page) {
+      this.currentPage = page;
+      // 这里可以添加分页数据加载逻辑
+    }
+  }
+}
+</script>
+
+<style lang="less" scoped>
+.application-management {
+  width: 100%;
+  background-color: #08224a;
+  color: #ffffff;
+}
+
+/* 右侧主内容区 */
+.main-content {
+  padding: 20px 30px;
+  overflow-y: auto;
+}
+
+/* 过滤条件区域 */
+.filter-section {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 20px;
+  margin-bottom: 20px;
+  padding-bottom: 15px;
+  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
+}
+
+.filter-group {
+  display: flex;
+  align-items: center;
+  gap: 10px;
+}
+
+.filter-title {
+  font-size: 14px;
+  color: rgba(255, 255, 255, 0.8);
+}
+
+/* 搜索栏区域 */
+.search-section {
+  display: flex;
+  align-items: center;
+  gap: 10px;
+  margin-bottom: 25px;
+}
+
+.search-input {
+  // width: 400px;
+  margin-right: 10px;
+}
+
+.search-btn, .reset-btn, .add-btn {
+  padding: 8px 16px;
+  font-size: 14px;
+}
+
+/* 应用列表区域 */
+.applications-section {
+  background-color: rgba(255, 255, 255, 0.05);
+  border-radius: 8px;
+  padding: 20px;
+}
+
+.section-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 20px;
+}
+
+.total-count {
+  font-size: 14px;
+  color: rgba(255, 255, 255, 0.8);
+}
+
+.sort-control {
+  display: flex;
+  align-items: center;
+  gap: 5px;
+  font-size: 14px;
+  color: rgba(255, 255, 255, 0.8);
+}
+
+/* 应用列表 */
+.applications-list {
+  margin-bottom: 20px;
+}
+
+.application-item {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: 15px;
+  margin-bottom: 10px;
+  background-color: rgba(255, 255, 255, 0.05);
+  border: 1px solid rgba(255, 255, 255, 0.1);
+  border-radius: 6px;
+  transition: all 0.3s ease;
+  
+  &:hover {
+    border-color: rgba(24, 144, 255, 0.4);
+    background-color: rgba(24, 144, 255, 0.05);
+  }
+}
+
+.app-info {
+  display: flex;
+  align-items: center;
+  // flex: 1;
+  width: 500px;
+  gap: 15px;
+}
+
+.app-logo {
+  width: 60px;
+  height: 60px;
+  border-radius: 6px;
+  overflow: hidden;
+  
+  img {
+    width: 100%;
+    height: 100%;
+    object-fit: cover;
+  }
+}
+
+.app-details {
+  display: flex;
+  flex-direction: column;
+  gap: 5px;
+}
+
+.app-header {
+  display: flex;
+  align-items: center;
+  gap: 10px;
+}
+
+.app-name {
+  font-size: 16px;
+  font-weight: bold;
+  margin: 0;
+  color: #ffffff;
+}
+
+.app-version {
+  font-size: 12px;
+  color: rgba(255, 255, 255, 0.6);
+  background-color: rgba(255, 255, 255, 0.1);
+  padding: 2px 6px;
+  border-radius: 4px;
+}
+
+.app-tags {
+  display: flex;
+  gap: 5px;
+}
+
+/* 应用指标 */
+.app-metrics {
+  display: flex;
+  gap: 40px;
+  flex: 1;
+  justify-content: space-around;
+}
+
+.metric-item {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  gap: 3px;
+}
+
+.metric-label {
+  font-size: 12px;
+  color: rgba(255, 255, 255, 0.6);
+}
+
+.metric-value {
+  font-size: 14px;
+  font-weight: bold;
+  color: #ffffff;
+}
+
+.status-online {
+  color: #67c23a;
+}
+
+.status-offline {
+  color: #e6a23c;
+}
+
+.status-suspended {
+  color: #909399;
+}
+
+.status-expired {
+  color: #f56c6c;
+}
+
+/* 应用操作 */
+.app-actions {
+  display: flex;
+  align-items: center;
+  gap: 20px;
+}
+
+.app-date {
+  font-size: 12px;
+  color: rgba(255, 255, 255, 0.6);
+}
+
+.detail-btn {
+  padding: 4px 12px;
+  font-size: 12px;
+}
+
+/* 分页控件 */
+.pagination-section {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding-top: 15px;
+  border-top: 1px solid rgba(255, 255, 255, 0.1);
+}
+
+.total-text {
+  font-size: 14px;
+  color: rgba(255, 255, 255, 0.8);
+}
+
+/* 响应式设计 */
+@media (max-width: 1200px) {
+  .app-metrics {
+    gap: 20px;
+  }
+}
+
+@media (max-width: 992px) {
+  .main-content {
+    padding: 15px 20px;
+  }
+  
+  .filter-section {
+    flex-direction: column;
+    align-items: flex-start;
+  }
+  
+  .search-input {
+    width: 300px;
+  }
+  
+  .application-item {
+    flex-direction: column;
+    align-items: flex-start;
+    gap: 15px;
+  }
+  
+  .app-metrics {
+    width: 100%;
+    justify-content: space-around;
+  }
+  
+  .app-actions {
+    width: 100%;
+    justify-content: space-between;
+  }
+}
+</style>

+ 493 - 0
src/views/yygl/monitor/index.vue

@@ -0,0 +1,493 @@
+<template>
+  <div class="application-monitor">
+    <!-- 右侧主内容区 -->
+    <div class="main-content">
+      <!-- 应用统计卡片 -->
+      <div class="stats-cards">
+        <div class="stat-card">
+          <div class="stat-icon approved">
+            <el-icon><CircleCheckFilled /></el-icon>
+          </div>
+          <div class="stat-content">
+            <div class="stat-label">已审批应用</div>
+            <div class="stat-number">490个</div>
+          </div>
+        </div>
+        <div class="stat-card">
+          <div class="stat-icon pending">
+            <el-icon><Clock /></el-icon>
+          </div>
+          <div class="stat-content">
+            <div class="stat-label">待上架应用</div>
+            <div class="stat-number">168个</div>
+          </div>
+        </div>
+        <div class="stat-card">
+          <div class="stat-icon online">
+            <el-icon><UploadFilled /></el-icon>
+          </div>
+          <div class="stat-content">
+            <div class="stat-label">已上架应用</div>
+            <div class="stat-number">43个</div>
+          </div>
+        </div>
+        <div class="stat-card">
+          <div class="stat-icon offline">
+            <el-icon><DeleteFilled /></el-icon>
+          </div>
+          <div class="stat-content">
+            <div class="stat-label">已下架应用</div>
+            <div class="stat-number">20个</div>
+          </div>
+        </div>
+      </div>
+
+      <!-- 内容模块 -->
+      <div class="content-modules">
+        <!-- 应用状态分布 -->
+        <div class="module">
+          <div class="module-header">
+            <h3 class="module-title">应用状态分布</h3>
+          </div>
+          <div class="module-content">
+            <div ref="statusChart" class="chart-container"></div>
+          </div>
+        </div>
+
+        <!-- 快捷应用 -->
+        <div class="module">
+          <div class="module-header">
+            <h3 class="module-title">快捷应用</h3>
+            <a href="#" class="module-more">更多</a>
+          </div>
+          <div class="module-content">
+            <div class="quick-app" v-for="(app, index) in quickApps" :key="index">
+              <div class="app-item">
+                <span class="app-icon" :style="{ backgroundColor: getAppColor(app.type) }"><el-icon><Promotion /></el-icon></span>
+                <span class="app-name">{{ app.name }}</span>
+              </div>
+            </div>
+          </div>
+        </div>
+
+        <!-- 应用上新 -->
+        <div class="module">
+          <div class="module-header">
+            <h3 class="module-title">应用上新</h3>
+            <a href="#" class="module-more">更多</a>
+          </div>
+          <div class="module-content">
+            <div class="new-app" v-for="(app, index) in newApps" :key="index">
+              <div class="app-info">
+                <span class="app-name">{{ app.name }}</span>
+                <span class="app-date">{{ app.date }}</span>
+              </div>
+            </div>
+          </div>
+        </div>
+
+        <!-- 应用热度排行TOP5 -->
+        <div class="module">
+          <div class="module-header">
+            <h3 class="module-title">应用热度排行TOP5</h3>
+            <a href="#" class="module-more">更多</a>
+          </div>
+          <div class="module-content">
+            <div class="hot-app" v-for="(app, index) in hotApps" :key="index">
+              <div class="app-rank">
+                <span class="rank-number">{{ index + 1 }}</span>
+                <span class="app-name">{{ app.name }}</span>
+              </div>
+              <div class="app-stats">
+                <!-- <div class="stat-bar" :style="{ width: app.percentage + '%' }"></div> -->
+                 <div style="width: 100%;">
+                    <el-progress :percentage="app.percentage" />
+                 </div>
+                <span class="stat-count">{{ app.count }}次</span>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import * as echarts from 'echarts'
+export default {
+  name: "ApplicationMonitor",
+  data() {
+    return {
+      statusChart: null,
+      // 快捷应用数据
+      quickApps: [
+        { name: '农产品安全管控示范应用场', type: 'green' },
+        { name: '崇明区乡村振兴一张图', type: 'yellow' },
+        { name: '数字孪生黄浦', type: 'blue' }
+      ],
+      
+      // 应用上新数据
+      newApps: [
+        { name: '水系综合管理系统', date: '2023-10-29' },
+        { name: '虹口历史文脉管理系统开发', date: '2023-09-15' },
+        { name: '虹口智慧环卫监管平台', date: '2023-09-15' },
+        { name: '上海虹口区一网统管平台', date: '2023-09-15' },
+        { name: '上海公共交通服务保障', date: '2023-09-15' }
+      ],
+      
+      // 应用热度排行数据
+      hotApps: [
+        { name: '崇明区乡村振兴一张图', count: 128, percentage: 100 },
+        { name: '数字孪生浦江', count: 65, percentage: 50.8 },
+        { name: '上海"一张图"大数据', count: 62, percentage: 48.4 },
+        { name: '黄浦智慧城管系统', count: 45, percentage: 35.2 },
+        { name: '上海生态环境管理', count: 38, percentage: 29.7 }
+      ]
+    }
+  },
+   mounted() {
+    this.initCharts()
+    window.addEventListener('resize', this.handleResize)
+  },
+  beforeUnmount() {
+    window.removeEventListener('resize', this.handleResize)
+    this.destroyCharts()
+  },
+  methods: {
+    initCharts() {
+      this.initStatusChart()
+    },
+    handleResize() {
+      if (this.statusChart) this.statusChart.resize()
+    },
+    destroyCharts() {
+      if (this.statusChart) {
+        this.statusChart.dispose()
+        this.statusChart = null
+      }
+    },
+    initStatusChart() {
+      this.statusChart = echarts.init(this.$refs.statusChart)
+      const option = {
+        tooltip: {
+          trigger: 'item',
+          backgroundColor: 'rgba(0, 25, 50, 0.8)',
+          borderColor: '#1E90FF',
+          textStyle: {
+            color: '#fff'
+          }
+        },
+        legend: {
+          orient: 'horizontal',
+          bottom: 0,
+          textStyle: {
+            color: '#a3b6c7'
+          }
+        },
+        series: [
+          {
+            name: '应用状态分布',
+            type: 'pie',
+            radius: ['40%', '70%'],
+            avoidLabelOverlap: false,
+            itemStyle: {
+              borderRadius: 10,
+              borderColor: '#0A192F',
+              borderWidth: 2
+            },
+            label: {
+              show: false,
+              position: 'center'
+            },
+            emphasis: {
+              label: {
+                show: true,
+                fontSize: 20,
+                fontWeight: 'bold',
+                color: '#fff'
+              }
+            },
+            labelLine: {
+              show: false
+            },
+            data: [
+              { value: 400, name: '在维', itemStyle: { color: '#52C41A' } },
+              { value: 300, name: '在筹', itemStyle: { color: '#FAAD14' } },
+              { value: 200, name: '停用', itemStyle: { color: '#F5222D' } }
+            ]
+          }
+        ]
+      }
+      this.statusChart.setOption(option)
+    },
+    // 获取应用图标的背景颜色
+    getAppColor(type) {
+      const colorMap = {
+        green: 'rgba(103, 194, 58, 0.2)',
+        yellow: 'rgba(230, 162, 60, 0.2)',
+        blue: 'rgba(64, 158, 255, 0.2)'
+      }
+      return colorMap[type] || 'rgba(64, 158, 255, 0.2)'
+    }
+  }
+}
+</script>
+
+<style lang="less" scoped>
+.application-monitor {
+  width: 100%;
+  background-color: #08224a;
+  color: #ffffff;
+}
+
+/* 右侧主内容区 */
+.main-content {
+  flex: 1;
+  padding: 20px 30px;
+  overflow-y: auto;
+}
+
+/* 统计卡片 */
+.stats-cards {
+  display: flex;
+  gap: 20px;
+  margin-bottom: 20px;
+  flex-wrap: wrap;
+}
+
+.stat-card {
+  flex: 1;
+  min-width: 200px;
+  height: 100px;
+  background-color: rgba(255, 255, 255, 0.05);
+  border-radius: 8px;
+  padding: 20px;
+  display: flex;
+  align-items: center;
+  gap: 15px;
+  transition: all 0.3s ease;
+  
+  &:hover {
+    background-color: rgba(255, 255, 255, 0.08);
+  }
+}
+
+.stat-icon {
+  width: 60px;
+  height: 60px;
+  border-radius: 50%;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  font-size: 24px;
+  
+  &.approved {
+    background-color: rgba(64, 158, 255, 0.2);
+    color: #409EFF;
+  }
+  
+  &.pending {
+    background-color: rgba(230, 162, 60, 0.2);
+    color: #E6A23C;
+  }
+  
+  &.online {
+    background-color: rgba(103, 194, 58, 0.2);
+    color: #67C23A;
+  }
+  
+  &.offline {
+    background-color: rgba(245, 108, 108, 0.2);
+    color: #F56C6C;
+  }
+}
+
+.stat-content {
+  display: flex;
+  flex-direction: column;
+  gap: 5px;
+}
+
+.stat-label {
+  font-size: 14px;
+  color: rgba(255, 255, 255, 0.6);
+}
+
+.stat-number {
+  font-size: 28px;
+  font-weight: bold;
+  color: #ffffff;
+}
+
+/* 内容模块 */
+.content-modules {
+  display: grid;
+  grid-template-columns: 1fr 1fr;
+  grid-template-rows: 1fr 1fr;
+  gap: 20px;
+}
+
+/* 模块通用样式 */
+.module {
+  background-color: rgba(255, 255, 255, 0.05);
+  border-radius: 8px;
+  overflow: hidden;
+}
+
+.module-header {
+  padding: 15px 20px;
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
+}
+
+.module-title {
+  font-size: 16px;
+  font-weight: bold;
+  margin: 0;
+  color: #ffffff;
+}
+
+.module-more {
+  font-size: 12px;
+  color: rgba(255, 255, 255, 0.6);
+  text-decoration: none;
+  
+  &:hover {
+    color: #409EFF;
+  }
+}
+
+.module-content {
+  padding: 20px;
+}
+
+/* 应用状态分布图 */
+.chart-container {
+  width: 100%;
+  height: 300px;
+}
+
+/* 快捷应用 */
+.quick-app {
+  margin-bottom: 15px;
+}
+
+.app-item {
+  display: flex;
+  align-items: center;
+  gap: 10px;
+  padding: 10px;
+  background-color: rgba(255, 255, 255, 0.05);
+  border-radius: 6px;
+  transition: all 0.3s ease;
+  
+  &:hover {
+    background-color: rgba(255, 255, 255, 0.08);
+  }
+}
+
+.app-icon {
+  width: 32px;
+  height: 32px;
+  border-radius: 4px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  color: #ffffff;
+  font-size: 14px;
+}
+
+.app-name {
+  font-size: 14px;
+  color: rgba(255, 255, 255, 0.8);
+}
+
+/* 应用上新 */
+.new-app {
+  margin-bottom: 15px;
+  padding-bottom: 15px;
+  border-bottom: 1px solid rgba(255, 255, 255, 0.05);
+  
+  &:last-child {
+    margin-bottom: 0;
+    padding-bottom: 0;
+    border-bottom: none;
+  }
+}
+
+.app-info {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+}
+
+.app-date {
+  font-size: 12px;
+  color: rgba(255, 255, 255, 0.6);
+}
+
+/* 使用热度排行 */
+.hot-app {
+  margin-bottom: 20px;
+  display: flex;
+  flex-direction: column;
+  gap: 8px;
+}
+
+.app-rank {
+  display: flex;
+  align-items: center;
+  gap: 10px;
+}
+
+.rank-number {
+  width: 20px;
+  height: 20px;
+  border-radius: 50%;
+  background-color: rgba(255, 255, 255, 0.1);
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  font-size: 12px;
+  font-weight: bold;
+}
+
+.app-stats {
+  display: flex;
+  align-items: center;
+  gap: 10px;
+}
+
+.stat-bar {
+  flex: 1;
+  height: 6px;
+  background-color: #409EFF;
+  border-radius: 3px;
+}
+
+.stat-count {
+  font-size: 12px;
+  color: rgba(255, 255, 255, 0.6);
+  min-width: 50px;
+  text-align: right;
+}
+
+/* 响应式设计 */
+@media (max-width: 1200px) {
+  .content-modules {
+    grid-template-columns: 1fr;
+    grid-template-rows: repeat(4, auto);
+  }
+  
+  .stats-cards {
+    flex-direction: column;
+  }
+  
+  .stat-card {
+    min-width: auto;
+  }
+}
+</style>

+ 398 - 0
src/views/yygl/overview/index.vue

@@ -0,0 +1,398 @@
+<template>
+  <div class="application-overview">
+    <!-- 右侧主内容区 -->
+    <div class="main-content">
+        <div style="display: flex;justify-content: space-between;">
+            <!-- 搜索栏 -->
+            <div class="search-bar">
+                <el-input
+                    placeholder="请输入应用名称关键字"
+                    v-model="searchKeyword"
+                    class="search-input"
+                    >
+                    <!-- <template #append>
+                        <el-button type="primary" class="search-btn">搜索</el-button>
+                    </template> -->
+                    
+                </el-input>
+                <el-button type="primary" class="search-btn">搜索</el-button>
+            </div>
+            
+
+            <!-- 应用范围过滤 -->
+            <div class="filter-tabs">
+                <el-radio-group v-model="activeTab" size="medium">
+                    <el-radio-button label="all">全部(41)</el-radio-button>
+                    <el-radio-button label="district">区级(19)</el-radio-button>
+                    <el-radio-button label="street">街镇(8)</el-radio-button>
+                </el-radio-group>
+            </div>
+        </div>
+      <!-- 应用卡片网格 -->
+      <div class="applications-grid">
+        <div class="application-card" v-for="(app, index) in applications" :key="index">
+          <div class="card-image">
+            <img :src="app.image" :alt="app.name" />
+          </div>
+          <div class="card-content">
+            <div class="app-header">
+              <h3 class="app-name">{{ app.name }}</h3>
+              <span class="app-version">{{ app.version }}</span>
+            </div>
+            <div class="app-tags">
+              <el-tag size="small" type="success">{{ app.status }}</el-tag>
+              <el-tag size="small" v-for="tag in app.tags" :key="tag">{{ tag }}</el-tag>
+            </div>
+            <p class="app-description">{{ app.description }}</p>
+            <div class="app-footer">
+              <span class="app-date">{{ app.date }}</span>
+              <el-button type="primary" size="small" class="visit-button">访问</el-button>
+            </div>
+          </div>
+        </div>
+      </div>
+
+      <!-- 加载更多按钮 -->
+      <!-- <div class="load-more">
+        <el-button type="primary" size="medium">查看更多</el-button>
+      </div> -->
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  name: "ApplicationOverview",
+  data() {
+    return {
+      searchKeyword: '',
+      activeTab: 'all',
+      applications: [
+        {
+          image: require('@/assets/images/common/app-bg-1.png'),
+          name: '智慧园区',
+          version: 'v1.0',
+          status: '待审核',
+          tags: [],
+          description: '智慧园区运维管理平台',
+          date: '2025-12-09 11:09:07'
+        },
+        {
+          image: require('@/assets/images/common/app-bg-2.png'),
+          name: '上海市一图一网一屏',
+          version: 'v1.0',
+          status: '待审核',
+          tags: [],
+          description: '城市综合数据可视化平台',
+          date: '2025-12-09 11:09:06'
+        },
+        {
+          image: require('@/assets/images/common/app-bg-3.png'),
+          name: '水系综合管理',
+          version: 'v1.0',
+          status: '未完成',
+          tags: ['水务'],
+          description: '汇聚各类水务水务等专业数据,构建综合业务平台',
+          date: '2025-11-30 15:17:17'
+        },
+        {
+          image: require('@/assets/images/common/app-bg-4.png'),
+          name: '数字孪生黄浦江',
+          version: 'v1.0',
+          status: '待发布',
+          tags: ['未完成', '水务'],
+          description: '利用大数据、物联网、BIM、三维可视化技术构建数字孪生平台',
+          date: '2025-12-08 15:11:36'
+        },
+        {
+          image: require('@/assets/images/common/u661.png'),
+          name: '上海市生态环境管理',
+          version: 'v1.0',
+          status: '待审核',
+          tags: [],
+          description: '生态环境综合监测与管理平台',
+          date: '2025-11-30 15:43:56'
+        },
+        {
+          image: require('@/assets/images/common/app-bg-1.png'),
+          name: '智慧园区',
+          version: 'v1.0',
+          status: '待审核',
+          tags: [],
+          description: '智慧园区运维管理平台',
+          date: '2025-12-09 11:09:07'
+        },
+        {
+          image: require('@/assets/images/common/app-bg-2.png'),
+          name: '上海市一图一网一屏',
+          version: 'v1.0',
+          status: '待审核',
+          tags: [],
+          description: '城市综合数据可视化平台',
+          date: '2025-12-09 11:09:06'
+        },
+        {
+          image: require('@/assets/images/common/app-bg-3.png'),
+          name: '水系综合管理',
+          version: 'v1.0',
+          status: '未完成',
+          tags: ['水务'],
+          description: '汇聚各类水务水务等专业数据,构建综合业务平台',
+          date: '2025-11-30 15:17:17'
+        },
+        {
+          image: require('@/assets/images/common/app-bg-4.png'),
+          name: '数字孪生黄浦江',
+          version: 'v1.0',
+          status: '待发布',
+          tags: ['未完成', '水务'],
+          description: '利用大数据、物联网、BIM、三维可视化技术构建数字孪生平台',
+          date: '2025-12-08 15:11:36'
+        },
+        {
+          image: require('@/assets/images/common/u661.png'),
+          name: '上海市生态环境管理',
+          version: 'v1.0',
+          status: '待审核',
+          tags: [],
+          description: '生态环境综合监测与管理平台',
+          date: '2025-11-30 15:43:56'
+        }
+      ]
+    }
+  }
+}
+</script>
+
+<style lang="less" scoped>
+.application-overview {
+  display: flex;
+  width: 100%;
+  background-color: #08224a;
+  color: #ffffff;
+}
+
+/* 右侧主内容区 */
+.main-content {
+  flex: 1;
+  padding: 20px 30px;
+  overflow-y: auto;
+}
+
+/* 搜索栏样式 */
+.search-bar {
+  margin-bottom: 20px;
+  
+  .search-input {
+    width: 400px;
+    
+    // ::v-deep .el-input__inner {
+    //   background-color: rgba(255, 255, 255, 0.1);
+    //   border: 1px solid rgba(255, 255, 255, 0.2);
+    //   color: #ffffff;
+      
+    //   &::placeholder {
+    //     color: rgba(255, 255, 255, 0.6);
+    //   }
+    // }
+    
+    // ::v-deep .el-input__prepend {
+    //   background-color: rgba(255, 255, 255, 0.1);
+    //   border-color: rgba(255, 255, 255, 0.2);
+    //   color: rgba(255, 255, 255, 0.8);
+    // }
+  }
+  .search-btn {
+    margin-left: 10px;
+  }
+}
+
+/* 过滤标签样式 */
+.filter-tabs {
+  margin-bottom: 30px;
+  
+  ::v-deep .el-radio-group {
+    .el-radio-button {
+      background-color: rgba(255, 255, 255, 0.1);
+      border-color: rgba(255, 255, 255, 0.2);
+      color: rgba(255, 255, 255, 0.8);
+      
+      &:first-child .el-radio-button__inner {
+        border-left-color: rgba(255, 255, 255, 0.2);
+      }
+      
+      .el-radio-button__inner {
+        background-color: transparent;
+        border-color: rgba(255, 255, 255, 0.2);
+        color: rgba(255, 255, 255, 0.8);
+      }
+      
+      &.is-active {
+        background-color: #1890ff;
+        
+        .el-radio-button__inner {
+          background-color: #1890ff;
+          border-color: #1890ff;
+          color: #ffffff;
+        }
+      }
+    }
+  }
+}
+
+/* 应用卡片网格样式 */
+.applications-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
+  gap: 25px;
+}
+
+/* 应用卡片样式 */
+.application-card {
+  background-color: rgba(255, 255, 255, 0.05);
+  border: 1px solid rgba(255, 255, 255, 0.1);
+  border-radius: 8px;
+  overflow: hidden;
+  transition: all 0.3s ease;
+  
+  &:hover {
+    transform: translateY(-5px);
+    box-shadow: 0 10px 30px rgba(24, 144, 255, 0.2);
+    border-color: rgba(24, 144, 255, 0.4);
+  }
+  
+  .card-image {
+    width: 100%;
+    height: 160px;
+    overflow: hidden;
+    
+    img {
+      width: 100%;
+      height: 100%;
+      object-fit: cover;
+      transition: transform 0.3s ease;
+    }
+    
+    &:hover img {
+      transform: scale(1.05);
+    }
+  }
+  
+  .card-content {
+    padding: 15px;
+  }
+  
+  .app-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    margin-bottom: 10px;
+    
+    .app-name {
+      font-size: 16px;
+      font-weight: bold;
+      margin: 0;
+      color: #ffffff;
+    }
+    
+    .app-version {
+      font-size: 12px;
+      color: rgba(255, 255, 255, 0.6);
+      background-color: rgba(255, 255, 255, 0.1);
+      padding: 2px 6px;
+      border-radius: 4px;
+    }
+  }
+  
+  .app-tags {
+    margin-bottom: 10px;
+    
+    .el-tag {
+      margin-right: 5px;
+      margin-bottom: 5px;
+    }
+  }
+  
+  .app-description {
+    font-size: 13px;
+    line-height: 1.6;
+    color: rgba(255, 255, 255, 0.7);
+    margin-bottom: 15px;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    display: -webkit-box;
+    -webkit-line-clamp: 2;
+    -webkit-box-orient: vertical;
+  }
+  
+  .app-footer {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    
+    .app-date {
+      font-size: 12px;
+      color: rgba(255, 255, 255, 0.5);
+    }
+    
+    .visit-button {
+      padding: 4px 12px;
+      font-size: 12px;
+      border-radius: 4px;
+    }
+  }
+}
+
+/* 加载更多按钮 */
+.load-more {
+  text-align: center;
+  margin-bottom: 30px;
+  
+  .el-button {
+    padding: 10px 30px;
+    background-color: rgba(24, 144, 255, 0.2);
+    border-color: rgba(24, 144, 255, 0.4);
+    color: #1890ff;
+    
+    &:hover {
+      background-color: rgba(24, 144, 255, 0.3);
+      border-color: rgba(24, 144, 255, 0.6);
+    }
+  }
+}
+
+/* 响应式设计 */
+@media (max-width: 1200px) {
+  .applications-grid {
+    grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
+    gap: 20px;
+  }
+}
+
+@media (max-width: 992px) {
+  .sidebar {
+    width: 180px;
+    
+    .sidebar-menu .menu-item {
+      padding: 12px 15px;
+      
+      i {
+        font-size: 16px;
+      }
+    }
+  }
+  
+  .main-content {
+    padding: 15px 20px;
+  }
+  
+  .search-input {
+    width: 300px !important;
+  }
+  
+  .applications-grid {
+    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
+    gap: 15px;
+  }
+}
+</style>

+ 7 - 0
vue.config.js

@@ -95,6 +95,13 @@ module.exports = defineConfig({
           '^/proxy_dms': ''
         }
       },
+      '/oneMap/': {
+        target: 'http://127.0.0.1:10099/qpyzt',
+        changeOrigin: true,
+        pathRewrite: {
+          '^/oneMap': ''
+        }
+      },
     },
   }
 })

Некоторые файлы не были показаны из-за большого количества измененных файлов