Browse Source

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

ximinghao 3 weeks ago
parent
commit
201de77769

+ 0 - 1
public/static/config/config.js

@@ -19,7 +19,6 @@ let systemConfig = {
     dmsDataProxy: "/proxy_dms",
     // 引擎基础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/",

+ 72 - 38
src/App.vue

@@ -8,11 +8,10 @@ export default {
   data() {
     return {
       loadedScripts: [],
-    }
+    };
   },
   mounted() {
-    let that = this;
-    window.loadScripts = this.loadScripts
+    window.loadScripts = this.loadScripts;
     // document.querySelector("#app").style.transform = `scale(${this.getScale()}) translate(-50%, 0%)`
     // document.querySelector("#app").style.height = window.innerHeight / this.getScale() + "px"
     // window.onresize = () => {
@@ -22,28 +21,65 @@ export default {
     // this.$nextTick(() => {
     //   this.scrollUpdate();
     // });
+    let that = this;
     // 默认登录
-    api.login({
-      userName: systemConfig.defaultAccount.userName,
-      password: AesEncryptUtil.getPassword(),
-      clientId: "1",
-    }).then((result) => {
-      if (result.code == 200) {
-        that.$store.commit("setUserInfo", result.content);
-        that.$store.commit("setToken", result.message);
-        that.$store.commit("setUserState", true);
-      } else {
+    api
+      .login({
+        userName: systemConfig.defaultAccount.userName,
+        password: AesEncryptUtil.getPassword(),
+        clientId: "1",
+      })
+      .then((result) => {
+        if (result.code == 200) {
+          that.$store.commit("setUserInfo", result.content);
+          that.$store.commit("setToken", result.message);
+          that.$store.commit("setUserState", true);
+          // 登录成功之后要批量加载一下DMS的字典,后续全局可调用
+          that.$store.state.DMSTypes.forEach((item) => {
+            api
+              .getDmsTypes({
+                cName: item,
+                type: 0,
+              })
+              .then((result2) => {
+                if (result2.code == 200) {
+                  // 遍历result2.content,将每个元素的index作为key,name作为value,存储到DmsTypesMap中
+                  let dmsTypesMap = {};
+                  result2.content.forEach((element) => {
+                    dmsTypesMap[element.index] = element.name;
+                  });
+                  that.$store.commit("setDmsTypesMap", {
+                    name: item,
+                    list: dmsTypesMap,
+                  });
+                } else {
+                  that.$message({
+                    type: "error",
+                    message: result2.content,
+                  });
+                }
+              })
+              .catch((err) => {
+                console.log(err);
+                that.$message({
+                  type: "error",
+                  message: "服务器忙碌,请稍后重试!",
+                });
+              });
+          });
+        } else {
+          that.$message({
+            type: "error",
+            message: result.content,
+          });
+        }
+      })
+      .catch((err) => {
         that.$message({
           type: "error",
-          message: result.content,
+          message: "服务器忙碌,请稍后重试!",
         });
-      }
-    }).catch((err) => {
-      that.$message({
-        type: "error",
-        message: "服务器忙碌,请稍后重试!",
       });
-    });
   },
   methods: {
     // scrollUpdate() {
@@ -53,52 +89,52 @@ export default {
     //   }, 1000);
     // },
     getScale() {
-      const ww = window.innerWidth / 1920
+      const ww = window.innerWidth / 1920;
       // const wh = window.innerHeight / 945
       // return ww < wh ? ww : wh;
-      return ww
+      return ww;
     },
 
     initScript() {
       let that = this;
       window.SkySceneryConfig = {
         authUrl: systemConfig.oauthServiceUrlOrigin,
-        token: localStorage.getItem("token")
+        token: localStorage.getItem("token"),
       };
       return new Promise((resolve, reject) => {
         const str = systemConfig.scriptMain;
-        let strArr = str.split("/")
+        let strArr = str.split("/");
         if (that.loadedScripts.indexOf(strArr[strArr.length - 1]) == -1) {
           // SkyScenery.js
           that.loadedScripts.push(strArr[strArr.length - 1]);
           that.addScripts(systemConfig.scriptMain).then(function () {
             resolve();
-          })
+          });
         } else {
           resolve();
         }
-      })
+      });
     },
     loadScripts(scriptArr) {
       // 初始化 SkyScenery.js
       let that = this;
       return new Promise((resolve, reject) => {
         that.initScript().then(function () {
-          let arr = []
+          let arr = [];
           for (let i = 0; i < scriptArr.length; i++) {
             const str = scriptArr[i];
-            let strArr = str.split("/")
+            let strArr = str.split("/");
             if (that.loadedScripts.indexOf(strArr[strArr.length - 1]) == -1) {
               let pro = that.addScripts(str);
               that.loadedScripts.push(strArr[strArr.length - 1]);
-              arr.push(pro)
+              arr.push(pro);
             }
           }
           Promise.all(arr).then(function () {
-            resolve()
+            resolve();
           });
-        })
-      })
+        });
+      });
     },
     addScripts(src) {
       return new Promise((resolve, reject) => {
@@ -111,10 +147,7 @@ export default {
         if (script.readyState) {
           // IE
           script.onreadystatechange = function () {
-            if (
-              script.readyState === "loaded" ||
-              script.readyState === "complete"
-            ) {
+            if (script.readyState === "loaded" || script.readyState === "complete") {
               script.onreadystatechange = null;
               resolve();
             }
@@ -127,7 +160,7 @@ export default {
         }
       });
     },
-  }
+  },
 };
 </script>
 <style lang="less">
@@ -141,7 +174,8 @@ html {
 }
 
 #app {
-  width: 1920px;
+  width: 100%;
+  min-width: 1440px;
   height: 100%;
   position: fixed;
   left: 50%;

+ 5 - 0
src/api/common.js

@@ -12,6 +12,11 @@ const login = (params) => {
   return postform(systemConfig.oauthServiceUrl + '/user/pwd/login', params)
 }
 
+const getDmsTypes = (params) => {
+  return postform(systemConfig.backServerPath + ":" + systemConfig.dmsWebUrlPort + systemConfig.dmsDataProxy + '/category/selectByCNameAType', params)
+}
+
 export default {
   login,
+  getDmsTypes,
 }

+ 54 - 0
src/api/count.js

@@ -533,6 +533,60 @@ async function resolveoauthResult(result) {
         throw new Error(result.message)
     }
 }
+// 服务类别分布、服务调用TOP10、详细报告。导出数据是另外一个接口?导出数据显示的数据不就是详细报告的数据吗?
+export function serviceInfo(start, end) {
+    let data = {
+        "columnId": preCountDmsId,
+        "autoSelectItem": false,
+        "page": 1,
+        "pageSize": 10000,
+        "columnAlias": "precount",
+        // "orderBy": "c_count",
+        "selectItem": JSON.stringify([
+            {
+                // 调用次数
+                "table": "precount",
+                "column": "c_count",
+                "function": "sum",
+                "alias": "count"
+            }, {
+                // 调用时间
+                "table": "precount",
+                "column": "c_date",
+                "alias": "time"
+            }, {
+                // 委办单位
+                "table": "precount",
+                "column": "c_unit",
+                "alias": "cUnit"
+            }, {
+                // 接口描述
+                "table": "precount",
+                "column": "c_path_comment",
+                "alias": "cPathComment"
+            }
+        ]),
+        "groupBy": JSON.stringify([
+            {
+                "table": "precount",
+                "column": "c_date"
+            },
+            {
+                "table": "precount",
+                "column": "c_unit"
+            },
+            {
+                "table": "precount",
+                "column": "c_path_comment"
+            }
+        ]),
+        "conditionsList": JSON.stringify([
+            ...timeCheckers(start, end),
+            ...notNullAndEmptyCheckers("precount", "c_unit")
+        ])
+    }
+    return resolveDmsMultiTableResult(postform(multiSearch, data));
+}
 function formatDateToDb(date) {
     const year = date.getFullYear();
     const month = String(date.getMonth() + 1).padStart(2, '0');

+ 5 - 0
src/api/wgn.js

@@ -7,10 +7,15 @@ const getDmsData = (params) => {
     return postform(systemConfig.dmsDataProxy + "/content/selectContentList", params)
 }
 
+const addDmsData = () => {
+    return postform(systemConfig.dmsDataProxy + "/content/addContent", params)
+}
+
 const topology = (url, params) => {
     return postBody(systemConfig.baseServicerPath + url, params)
 }
 export default {
     getDmsData,
+    addDmsData,
     topology,
 }

+ 29 - 50
src/components/AppVue/Header.vue

@@ -3,8 +3,12 @@
     <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)">
+        <li
+          v-for="(item, index) in menuList"
+          :key="index"
+          :class="{ active: item.isActive }"
+          @click="menuClick(item.index, $event)"
+        >
           {{ item.label }}
         </li>
       </ul>
@@ -17,75 +21,50 @@ export default {
   data() {
     return {
       menuList: [
-        { index: 1, label: "首页", isActive: true },
-        { 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 },
+        { index: 1, path: "/", label: "首页", isActive: true },
+        { index: 2, path: "/sksjgl", label: "时空数据管理", isActive: false },
+        // { index: 3, path: "/skmh/scene", label: "二维GIS引擎", isActive: false },
+        { index: 4, path: "/skmh", label: "时空门户", isActive: false },
+        { index: 5, path: "/wgn", label: "微功能", isActive: false },
+        { index: 6, path: "/yygl", label: "应用管理", isActive: false },
+        { index: 7, path: "/yxgl", label: "运行管理", isActive: false },
       ],
     };
   },
+  mounted() {
+    // 初始化判断路径并自动选中菜单
+    let path = this.$route.path;
+    console.log(path);
+    this.menuList.map(function (item) {
+      if (item.path == path) {
+        item.isActive = true;
+      } else {
+        item.isActive = false;
+      }
+    });
+  },
   methods: {
     menuClick(index) {
-      let that = this
+      let that = this;
       this.menuList.map(function (item) {
         if (item.index == index) {
           item.isActive = true;
+          that.$router.push(item.path);
         } else {
           item.isActive = false;
         }
       });
-
-      switch (index) {
-        case 1:
-          this.$router.push("/");
-          break;
-        case 2:
-          this.$router.push("/sksjgl");
-          break;
-        case 3:
-          // this.$router.push("/application");
-          // this.$router.push("/skmh/scene");
-          break;
-        case 4:
-          // this.$router.push("/function");
-          this.$router.push("/skmh");
-          break;
-        case 5:
-          this.$router.push("/wgn");
-          break;
-        case 6:
-          this.$router.push("/yygl");
-          break;
-        case 7:
-          this.$router.push("/yxgl");
-          break;
-      }
       this.$nextTick(() => {
-        this.$emit('updateScroll');
+        this.$emit("updateScroll");
       });
     },
-    // addClass(element, className) {
-    //   if (
-    //     !new RegExp("(^|\\s)" + className + "(\\s|$)").test(element.className)
-    //   )
-    //     element.className += " " + className;
-    // },
-    // removeClass(element, className) {
-    //   element.className = element.className.replace(
-    //     new RegExp("(^|\\s)" + className + "(?=(\\s|$))", "g"),
-    //     ""
-    //   );
-    // }
   },
 };
 </script>
 
 <style lang="less" scoped>
 #header {
-  width: 1920px;
+  width: 100%;
   height: 70px;
   background: linear-gradient(180deg, #2c2f74, #494d98);
   color: #ffffff;

+ 50 - 25
src/components/yxgl/EchartsDome.vue

@@ -16,11 +16,13 @@ export default {
     },
     chartOption: {
       type: Object,
-      default: {},
+      default: () => ({}), // 使用函数返回默认对象
     },
   },
   data() {
-    return {};
+    return {
+      chartInstance: null, // 保存ECharts实例引用
+    };
   },
   mounted() {
     this.$nextTick(() => {
@@ -30,8 +32,9 @@ export default {
   watch: {
     chartOption: {
       handler(newVal, oldVal) {
-        if (newVal.length > 0) {
-          this.initChart();
+        // 检查是否为有效对象
+        if (newVal && typeof newVal === "object") {
+          this.updateChart(newVal);
         }
       },
       deep: true,
@@ -39,28 +42,50 @@ export default {
   },
   methods: {
     initChart() {
-      let chartDom = echarts.init(this.$refs.chartContainer);
-      if (this.chartOption) {
-        // 绘制图表
-        this.chartOption.grid = {
-          top: 80,
-          left: 10, // 核心1:grid左侧距离容器左侧0px
-          right: 50, // 核心2:grid右侧距离容器右侧0px
-          bottom: 0,
-          containLabel: true, // 关键:防止坐标轴标签超出容器(可选,根据需求添加)
-        };
-        if (!this.chartOption.legend) {
-          this.chartOption.legend = {};
-        }
-        Object.assign(this.chartOption.legend, {
-          textStyle: {
-            color: "#F2F3F5", // 字体颜色(支持十六进制、RGB、颜色名)
-            fontSize: 14, // 可选:字体大小
-            fontWeight: "normal", // 可选:字体粗细
-          },
-        });
-        chartDom.setOption(this.chartOption);
+      // 如果已存在实例,先销毁
+      if (this.chartInstance) {
+        this.chartInstance.dispose();
+      }
+      // 创建新实例
+      let chartInstance = echarts.init(this.$refs.chartContainer);
+      this.chartInstance = chartInstance;
+      // 更新图表配置
+      this.updateChart(this.chartOption);
+    },
+    updateChart(option) {
+      // 创建新实例
+      // 如果已存在实例,先销毁
+      if (this.chartInstance) {
+        this.chartInstance.dispose();
+      }
+      // 创建新实例
+      let chartInstance = echarts.init(this.$refs.chartContainer);
+      this.chartInstance = chartInstance;
+      // 深拷贝配置,避免修改原始props
+      const mergedOption = JSON.parse(JSON.stringify(option));
+      // 绘制图表
+      mergedOption.grid = {
+        top: 80,
+        left: 10, // 核心1:grid左侧距离容器左侧0px
+        right: 50, // 核心2:grid右侧距离容器右侧0px
+        bottom: 0,
+        containLabel: true, // 关键:防止坐标轴标签超出容器(可选,根据需求添加)
+      };
+      if (!mergedOption.legend) {
+        mergedOption.legend = {};
       }
+      Object.assign(mergedOption.legend, {
+        textStyle: {
+          color: "#F2F3F5", // 字体颜色(支持十六进制、RGB、颜色名)
+          fontSize: 14, // 可选:字体大小
+          fontWeight: "normal", // 可选:字体粗细
+        },
+      });
+      chartInstance.setOption(mergedOption, true);
+      // 添加resize事件监听
+      window.addEventListener("resize", () => {
+        chartInstance.resize();
+      });
     },
   },
 };

+ 3 - 2
src/components/yxgl/card.vue

@@ -26,8 +26,8 @@ export default {
       default: "",
     },
     value: {
-      type: String,
-      default: "",
+      type: Number,
+      default: 0,
     },
     growth: {
       type: String,
@@ -85,6 +85,7 @@ export default {
   height: 40px;
   border-radius: 5px;
   background: #ccc;
+  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.3);
   font-size: 20px;
   display: flex;
   justify-content: center;

+ 118 - 12
src/components/yxgl/table.vue

@@ -1,21 +1,27 @@
 <template>
   <div class="table_box">
     <div class="table_title">{{ title }}</div>
-    <div class="table_more">
+    <!-- <div class="table_more">
       <el-button type="primary" link> 更多 </el-button>
-    </div>
+    </div> -->
     <el-table
       :data="tableData"
-      style="width: 100%; background-color: #00000032"
-      height="calc(100% - 60px)"
+      style="width: 100%"
+      height="calc(100% - 40px);
+  background-color: rgba(255, 255, 255, 0.1);"
+      :header-cell-style="headerCellStyle"
+      :row-style="rowStyle"
+      :cell-style="cellStyle"
+      stripe
+      border
     >
-      <el-table-column prop="serviceName" label="服务名称" width="300" />
-      <el-table-column prop="serviceType" label="类别" width="300" />
-      <el-table-column prop="callCount" label="调用次数" width="480" />
-      <el-table-column prop="successRate" label="成功率" width="180" />
-      <el-table-column prop="avgResponseTime" label="平均响应" />
+      <!-- 添加序号列 -->
+      <el-table-column type="index" label="" width="50" align="center" />
+      <el-table-column prop="serviceName" label="服务名称" />
+      <el-table-column prop="serviceType" label="类别" width="600" />
+      <el-table-column prop="callCount" label="调用次数" width="280" />
     </el-table>
-    <div class="table_pagination">
+    <!-- <div class="table_pagination">
       <el-pagination
         v-model:current-page="currentPage"
         v-model:page-size="pageSize"
@@ -26,7 +32,7 @@
         @size-change="handleSizeChange"
         @current-change="handleCurrentChange"
       />
-    </div>
+    </div> -->
   </div>
 </template>
 
@@ -49,6 +55,32 @@ export default {
       currentPage: 1,
     };
   },
+  computed: {
+    headerCellStyle() {
+      return {
+        backgroundColor: "rgba(24, 144, 255, 0.25)",
+        color: "#0071e3",
+        fontWeight: "bold",
+        borderBottom: "2px solid rgba(24, 144, 255, 0.3)",
+        padding: "12px 8px",
+      };
+    },
+    rowStyle() {
+      return {
+        // 调整行背景色为更浅的黑色,增加透明度
+        backgroundColor: "rgba(0, 0, 0, 0.05)",
+        borderBottom: "1px solid rgba(255, 255, 255, 0.05)",
+        transition: "all 0.3s ease",
+      };
+    },
+    cellStyle() {
+      return {
+        color: "#e0e0e0",
+        padding: "12px 8px",
+        borderRight: "1px solid rgba(255, 255, 255, 0.05)",
+      };
+    },
+  },
   methods: {
     handleSizeChange(val) {
       this.pageSize = val;
@@ -67,9 +99,18 @@ export default {
   padding: 20px;
   box-sizing: border-box;
   position: relative;
+  // background-color: rgba(255, 255, 255, 0.1);
+  border-radius: 8px;
+  // box-shadow: 0 2px 12px rgba(0, 0, 0, 0.3);
 }
+
 .table_title {
-  font-size: 16px;
+  font-size: 18px;
+  color: #ffffff;
+  font-weight: bold;
+  margin-bottom: 15px;
+  padding-bottom: 8px;
+  // border-bottom: 2px solid rgba(24, 144, 255, 0.2);
 }
 
 .table_more {
@@ -78,10 +119,75 @@ export default {
   right: 20px;
   font-size: 14px;
   color: #1890ff;
+
+  .el-button {
+    color: #0071e3;
+
+    &:hover {
+      color: #0056b3;
+    }
+  }
 }
+
 .table_pagination {
   position: absolute;
   bottom: 20px;
   right: 20px;
+
+  .el-pagination {
+    color: #e0e0e0;
+
+    .btn-prev,
+    .btn-next,
+    .el-pager li {
+      background-color: rgba(0, 0, 0, 0.3);
+      color: #e0e0e0;
+      border: 1px solid rgba(255, 255, 255, 0.1);
+
+      &:hover {
+        background-color: rgba(24, 144, 255, 0.2);
+        color: #0071e3;
+        border-color: rgba(24, 144, 255, 0.3);
+      }
+    }
+
+    .el-pager li.active {
+      background-color: rgba(24, 144, 255, 0.3);
+      color: #0071e3;
+      border-color: rgba(24, 144, 255, 0.5);
+    }
+  }
+}
+
+// 美化表格行悬停效果
+:deep(.el-table__body tr:hover > td) {
+  background-color: rgba(24, 144, 255, 0.1) !important;
+}
+
+// 美化表格边框
+:deep(.el-table__inner-wrapper) {
+  border-radius: 6px;
+  overflow: hidden;
+}
+
+:deep(.el-table__cell) {
+  border-right: 1px solid rgba(255, 255, 255, 0.05);
+}
+
+:deep(.el-table__row) {
+  border-bottom: 1px solid rgba(255, 255, 255, 0.05);
+}
+
+// 调整奇偶行背景色,使其更明亮
+:deep(.el-table--striped .el-table__body tr.el-table__row--striped) {
+  background-color: rgba(255, 255, 255, 0.02) !important;
+}
+
+// 调整表格主体背景色
+:deep(.el-table__body) {
+  background-color: rgba(0, 0, 0, 0.05);
+}
+:deep(.el-table--striped .el-table__body tr.el-table__row--striped td.el-table__cell) {
+  background-color: rgba(255, 255, 255, 0.02);
 }
 </style>

+ 23 - 16
src/main.js

@@ -1,28 +1,35 @@
-import { createApp } from 'vue'
-import App from './App.vue'
+import { createApp } from 'vue';
+import App from './App.vue';
 let initApp = createApp(App);
 
-import router from './router'
+import router from './router';
+import store from './store';
+import ElementPlus from 'element-plus';
+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(router);
-import store from './store'
 initApp.use(store);
-import ElementPlus from 'element-plus'
-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)
-import VueJsonEditor from 'vue-json-editor'
-initApp.component('VueJsonEditor', VueJsonEditor)
+import * as ElementPlusIconsVue from '@element-plus/icons-vue';
+import JsonViewer from 'vue-json-viewer';
+initApp.component('JsonViewer', JsonViewer);
+import VueJsonEditor from 'vue-json-editor';
+initApp.component('VueJsonEditor', VueJsonEditor);
+
+import moment from 'moment';
+initApp.config.globalProperties.$moment = moment;
+
+// 添加自定义方法,传入DMS字典名称,返回对应字典数据
+initApp.config.globalProperties.$getDmsTypes = (cName, index) => {
+    return store.state.DmsTypesMap[cName] ? store.state.DmsTypesMap[cName][index + ''] : cName + "_" + index;
+};
 
 for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
     initApp.component(key, component)
-}
+};
 
 initApp.mount('#app');

+ 17 - 2
src/store/index.js

@@ -7,7 +7,18 @@ export default createStore({
     token: "",
     userState: false,
     userInfo: null,
-
+    // DMS字典,系统app.vue初始化一次之后,后续直接全局$getDmsTypes可调用,传入字典cName和index,返回对应字典数据
+    DMSTypes: ["appstatus"],
+    // appstatus: 应用状态
+    DmsTypesMap: localStorage.getItem("DmsTypesMap") ? JSON.parse(localStorage.getItem("DmsTypesMap")) : {},
+    menuList: [
+      { path: "/", label: "首页" },
+      { path: "/sksjgl", label: "时空数据管理" },
+      // { path: "/skmh/scene", label: "二维GIS引擎"},
+      { path: "/skmh", label: "时空门户" },
+      { path: "/wgn", label: "微功能" },
+      { path: "/yygl", label: "应用管理" },
+      { path: "/yxgl", label: "运行管理" },],
     sksjgl: {},
     skmh: {},
     wgn: {},
@@ -26,9 +37,13 @@ export default createStore({
     },
   },
   mutations: {
+    setDmsTypesMap(state, obj) {
+      state.DmsTypesMap[obj.name] = obj.list;
+      localStorage.setItem("DmsTypesMap", JSON.stringify(state.DmsTypesMap));
+    },
     setToken(state, str) {
       state.token = str;
-      localStorage.setItem("token",str)
+      localStorage.setItem("token", str)
     },
     setUserState(state, bool) {
       state.userState = bool;

+ 10 - 9
src/views/Root.vue

@@ -1,6 +1,6 @@
 <template>
   <div class="main">
-    <Header @updateScroll="updateScrollbar"></Header>
+    <Header />
     <el-scrollbar ref="pagescrollbar">
       <router-view />
     </el-scrollbar>
@@ -30,16 +30,17 @@ export default {
     };
   },
   components: {
-    Header: defineAsyncComponent(() =>
-      import("@/components/AppVue/Header.vue")
-    ),
-    Footer: defineAsyncComponent(() => import("@/components/AppVue/Footer.vue"))
+    Header: defineAsyncComponent(() => import("@/components/AppVue/Header.vue")),
+    Footer: defineAsyncComponent(() => import("@/components/AppVue/Footer.vue")),
   },
-  methods: {
-    updateScrollbar() {
-      this.$refs.pagescrollbar.setScrollTop(0)
-    }
+  watch: {
+    $route(to, from) {
+      this.$nextTick(() => {
+        this.$refs.pagescrollbar.setScrollTop(0);
+      });
+    },
   },
+  methods: {},
 };
 </script>
 

+ 1 - 1
src/views/Sksjgl.vue

@@ -136,7 +136,7 @@ export default {
 
 <style lang="less" scoped>
 .container {
-    width: 1920px;
+    width: 100%;
     margin: 0 auto;
 
     .server_title {

+ 167 - 21
src/views/Wgn.vue

@@ -3,7 +3,7 @@
     <el-backtop target=".wgn_box" :right="20" :bottom="70" />
     <div class="server_title">
       <el-image
-        style="width: 824px; height: calc(100vh - 70px)"
+        style="width: 43vw; height: calc(100vh - 120px)"
         src="static/images/wgn_title.png"
         fit="cover"
       />
@@ -19,7 +19,7 @@
     </div>
     <div class="server_list_box">
       <div class="server_list_box_title">微功能列表</div>
-      <el-affix :offset="0">
+      <el-affix :offset="80">
         <div class="server_list_box_search">
           <el-input
             v-model="searchStr"
@@ -70,12 +70,68 @@
           </div>
         </div>
       </div>
+      <!-- 申请使用微功能服务的表单弹窗 -->
+      <el-dialog
+        title="申请使用微功能服务"
+        v-model="showFrom"
+        width="60%"
+        :close-on-click-modal="false"
+        :close-on-press-escape="false"
+        :show-close="true"
+      >
+        <el-form :model="column.from" :rules="rules" ref="formRef" label-width="120px">
+          <el-form-item label="应用名称" prop="c_application_name">
+            <el-input
+              v-model="column.from.c_application_name"
+              placeholder="请输入应用名称"
+            />
+          </el-form-item>
+          <el-form-item label="接口路径" prop="c_interface_path">
+            <el-input
+              v-model="column.from.c_interface_path"
+              disabled
+              placeholder="请输入接口路径"
+            />
+          </el-form-item>
+          <el-form-item label="联系电话" prop="c_phone">
+            <el-input v-model="column.from.c_phone" placeholder="请输入联系电话" />
+          </el-form-item>
+          <el-form-item label="单位名称" prop="c_unit_name">
+            <el-input v-model="column.from.c_unit_name" placeholder="请输入单位名称" />
+          </el-form-item>
+          <el-form-item label="部门名称" prop="c_department">
+            <el-input v-model="column.from.c_department" placeholder="请输入部门名称" />
+          </el-form-item>
+          <!-- 项目负责人 -->
+          <el-form-item label="项目负责人" prop="c_business_leader">
+            <el-input
+              v-model="column.from.c_business_leader"
+              placeholder="请输入项目负责人"
+            />
+          </el-form-item>
+          <!-- 申请使用微功能服务的详细信息 -->
+          <el-form-item label="申请使用微功能服务的详细信息" prop="content">
+            <el-input
+              type="textarea"
+              v-model="column.from.content"
+              placeholder="请输入申请使用微功能服务的详细信息"
+            />
+          </el-form-item>
+        </el-form>
+        <template #footer>
+          <div class="dialog-footer">
+            <el-button @click="showFrom = false">取消</el-button>
+            <el-button type="primary" @click="handleApplySubmit">确定</el-button>
+          </div>
+        </template>
+      </el-dialog>
     </div>
   </div>
 </template>
 
 <script>
 import wgn from "@/api/wgn";
+import api from "@/api/content";
 export default {
   name: "微功能服务",
   data() {
@@ -86,6 +142,59 @@ export default {
       dmsServerList: [],
       // DMS数据代理地址
       dmsDataProxy: "",
+      // 是否显示申请使用微功能服务的表单弹窗
+      showFrom: false,
+      // 申请使用微功能服务的表单验证规则
+      rules: {
+        c_application_name: [
+          { required: true, message: "请输入应用名称", trigger: "blur" },
+        ],
+        c_interface_path: [
+          { required: true, message: "请输入接口路径", trigger: "blur" },
+        ],
+        c_business_leader: [
+          { required: true, message: "请输入项目负责人", trigger: "blur" },
+        ],
+        // 添加手机号正则验证
+        c_phone: [
+          { required: true, message: "请输入联系电话", trigger: "blur" },
+          {
+            validator: (rule, value, callback) => {
+              // 手机号正则验证
+              let phoneRegex = /^1[3456789]\d{9}$/;
+              if (!phoneRegex.test(value)) {
+                callback(new Error("请输入正确的手机号"));
+              } else {
+                callback();
+              }
+            },
+            trigger: "blur",
+          },
+        ],
+        c_unit_name: [{ required: true, message: "请输入单位名称", trigger: "blur" }],
+        c_department: [{ required: true, message: "请输入部门名称", trigger: "blur" }],
+      },
+      // 申请使用微功能服务的表单数据
+      column: {
+        columnId: 1665,
+        modelId: 1677,
+        from: {
+          // 备注:申请使用微功能服务的详细信息,非必填
+          content: "",
+          // 项目负责人,必填
+          c_business_leader: "",
+          // 应用名称,必填
+          c_application_name: "",
+          // 接口路径,必填
+          c_interface_path: "",
+          // 联系电话,必填
+          c_phone: "",
+          // 单位名称,必填
+          c_unit_name: "",
+          // 部门名称,必填
+          c_department: "",
+        },
+      },
     };
   },
   mounted() {
@@ -136,21 +245,58 @@ export default {
     },
     // 申请使用微功能服务
     handleApply(item) {
-      this.$confirm("确认申请使用" + item.title + "吗?", "提示", {
-        confirmButtonText: "确定",
-        cancelButtonText: "取消",
-        type: "warning",
-      })
-        .then(() => {
-          // 确认申请使用
-          this.$message({
-            message: "申请使用" + item.title + "?等url吧!",
-            type: "success",
+      // 申请使用微功能服务时,先从localStorage中获取数据,填充到表单中
+      let applyInfo = localStorage.getItem("wgnApplyInfo");
+      if (applyInfo) {
+        this.column.from = JSON.parse(applyInfo);
+      }
+      // 先打开弹窗,显示from表单,用户输入表单数据并提交
+      this.column.from.c_interface_path = item.c_url;
+      this.showFrom = true;
+    },
+    // 提交申请使用微功能服务表单
+    handleApplySubmit() {
+      let that = this;
+      this.$refs.formRef.validate((valid) => {
+        if (valid) {
+          // 提交时把信息添加到localStorage中,下次打开弹窗时,从localStorage中获取数据,填充到表单中
+          localStorage.setItem("wgnApplyInfo", JSON.stringify(that.column.from));
+          // 标题:电话+时间
+          that.column.from.title =
+            that.column.from.c_unit_name +
+            "_" +
+            that.column.from.c_business_leader +
+            "_" +
+            that.column.from.c_phone;
+          // 备注:申请使用微功能服务的详细信息
+          let params = {
+            content: JSON.stringify(that.column.from),
+            columnId: that.column.columnId,
+            modelId: that.column.modelId,
+          };
+          api.addContent(params).then((res) => {
+            if (res.code === 200) {
+              // 确认申请使用
+              that.$message({
+                message: "申请成功,请等待审核通过后工作人员专人联系,请保持电话通畅!",
+                type: "success",
+              });
+              that.showFrom = false;
+            } else {
+              that.$message({
+                message: "申请使用" + item.title + "失败" + res.msg,
+                type: "error",
+              });
+            }
           });
-        })
-        .catch(() => {
-          // 取消申请使用
-        });
+        } else {
+          // 表单验证失败,提示用户填写完整信息
+          that.$message({
+            message: "请填写完整信息",
+            type: "warning",
+          });
+        }
+      });
     },
     // 在线演示微功能服务
     handleOnlineDemo(item) {
@@ -186,15 +332,15 @@ export default {
   align-items: center;
 }
 .server_title_text {
-  width: calc(100vw - 824px);
-  height: calc(100vh - 70px);
+  width: calc(77vw - 200px);
+  height: calc(100vh - 120px);
   background-color: #1c2631;
   color: #fff;
-  padding: 0 160px 0 60px;
   display: flex;
   flex-direction: column;
   justify-content: center;
   overflow: hidden;
+  padding: 0 100px;
   &_title {
     font-size: 64px;
     font-weight: bold;
@@ -224,7 +370,7 @@ export default {
     z-index: 1;
   }
   &_title {
-    margin-top: 100px;
+    margin: 100px 0;
     font-size: 35px;
     font-weight: bold;
     position: relative;
@@ -240,7 +386,7 @@ export default {
     }
   }
   &_search {
-    margin-top: 100px;
+    // margin-top: 100px;
     font-size: 25px;
     display: flex;
     flex-wrap: nowrap;

+ 3 - 3
src/views/Yxgl.vue

@@ -11,7 +11,7 @@
       <el-sub-menu index="/#">
         <template #title>
           <el-icon><Platform /></el-icon>
-          <span>运行中心</span>
+          <span>信息反馈子系统</span>
         </template>
         <el-menu-item index="StatisticalAnalysis">
           <el-icon><Histogram /></el-icon>
@@ -21,7 +21,7 @@
       <el-sub-menu index="2">
         <template #title>
           <el-icon><Tools /></el-icon>
-          <span>管理中心</span>
+          <span>运行管理子系统</span>
         </template>
         <el-menu-item index="oauth">
           <el-icon><UserFilled /></el-icon>
@@ -124,7 +124,7 @@ export default {
 }
 iframe {
   width: 100%;
-  height: calc(100% - 10px);
+  height: calc(100%);
   background: #08224a;
 }
 </style>

+ 282 - 229
src/views/yxgl/StatisticalAnalysis.vue

@@ -3,6 +3,19 @@
     <!-- 搜索区域 -->
     <div class="searchBox">
       <div>
+        对比时间:
+        <el-date-picker
+          v-model="compareTimes"
+          type="daterange"
+          unlink-panels
+          range-separator="到"
+          start-placeholder="开始时间"
+          end-placeholder="结束时间"
+          disabled
+          size="large"
+          style="margin-right: 30px"
+        />
+        搜索时间:
         <el-date-picker
           v-model="dateValue"
           type="daterange"
@@ -10,7 +23,7 @@
           range-separator="到"
           start-placeholder="开始时间"
           end-placeholder="结束时间"
-          :shortcuts="shortcuts"
+          :shortcuts="shortcutsFun"
           size="large"
         />
       </div>
@@ -19,7 +32,7 @@
     <div class="flex">
       <card
         class="card flex"
-        :title="'服务机构总数'"
+        :title="'委办总数'"
         :value="8"
         :growth="'较上个月增长了12%'"
         iconColor="#2563db"
@@ -27,7 +40,7 @@
       />
       <card
         class="card flex"
-        :title="'服务总数'"
+        :title="'系统总数'"
         :value="100"
         :growth="'较上个月下降了12%'"
         iconColor="#16a34a"
@@ -35,7 +48,7 @@
       />
       <card
         class="card flex"
-        :title="'服务调用数'"
+        :title="'服务总数'"
         :value="1000"
         :growth="'较上个月增长了12%'"
         iconColor="#9333ea"
@@ -43,7 +56,7 @@
       />
       <card
         class="card flex"
-        :title="'服务类别数量'"
+        :title="'服务调用总数'"
         :value="10"
         :growth="'与上月持平'"
         iconColor="#ca8a04"
@@ -74,26 +87,26 @@
         </div>
       </div>
       <div style="width: 100%; height: 400px">
-        <Table title="服务调用" :tableData="tableDatas" />
+        <Table title="服务调用TOP10" :tableData="tableDatas" />
       </div>
     </div>
-    <!-- 用户信息统计 -->
+    <!-- 委办信息统计 -->
     <div class="bigCard">
-      <div class="bigCard_title">用户信息统计</div>
+      <div class="bigCard_title">委办信息统计</div>
       <div class="flex">
         <div style="width: 28%; height: 400px">
-          <EchartsDome :chartOption="chartOptions['用户角色分布']" title="用户角色分布" />
+          <EchartsDome :chartOption="chartOptions['委办分布']" title="委办分布" />
         </div>
         <div style="width: 68%; height: 400px">
           <EchartsDome
-            :chartOption="chartOptions['用户活跃度趋势']"
-            title="用户活跃度趋势"
+            :chartOption="chartOptions['服务调用趋势(近30天)']"
+            title="委办活跃度趋势"
           />
         </div>
       </div>
-      <div style="width: 100%; height: 400px">
+      <!-- <div style="width: 100%; height: 400px">
         <EchartsDome :chartOption="chartOptions['用户部门分布']" title="用户部门分布" />
-      </div>
+      </div> -->
     </div>
     <!-- 应用类信息统计 -->
     <div class="bigCard">
@@ -106,7 +119,7 @@
           />
         </div>
         <div style="width: 38%; height: 400px">
-          <EchartsDome :chartOption="chartOptions['服务类别分布']" title="应用状态分布" />
+          <EchartsDome :chartOption="chartOptions['应用状态分布']" title="应用状态分布" />
         </div>
       </div>
     </div>
@@ -123,7 +136,7 @@
       </div>
     </div>
     <!-- 区级特色信息统计 -->
-    <div class="bigCard" style="background: #00000000">
+    <div class="bigCard">
       <div class="bigCard_title">区级特色信息统计</div>
       <div class="flex" style="margin-top: 20px">
         <div class="flex_column" style="width: 28%; height: 420px">
@@ -167,6 +180,8 @@
 import card from "@/components/yxgl/card.vue";
 import EchartsDome from "@/components/yxgl/EchartsDome.vue";
 import Table from "@/components/yxgl/table.vue";
+import { totalCountGroupByTime, serviceInfo } from "@/api/count";
+import appCenter from "@/api/appCenter";
 export default {
   name: "",
   components: {
@@ -176,151 +191,234 @@ export default {
   },
   data() {
     return {
-      dateValue: "",
-      shortcuts: this.shortcuts(),
+      // 比较的时间范围(默认60天到30天前,主要跟dateValue有关系)
+      compareTimes: [],
+      // 当前选中的时间范围
+      dateValue: [],
+      shortcutsFun: this.shortcuts(),
       chartOptions: {},
       tableDatas: [],
     };
   },
-  mounted() {
-    let datas = [
-      { value: 1048, name: "调用次数", value2: 3, date: "12/17" },
-      { value: 735, name: "平均响应时间", value2: 3, date: "12/18" },
-    ];
-
-    let datas2 = [
-      {
-        value: 20,
-        name: "业务数据",
-        children: [
-          { value: 7, name: "交通数据" },
-          { value: 5, name: "环保数据" },
-          { value: 5, name: "水务数据" },
-          { value: 3, name: "教育数据" },
-        ],
-      },
-      {
-        value: 13,
-        name: "基础数据",
-        children: [
-          { value: 5, name: "人口数据" },
-          { value: 5, name: "地理数据" },
-          { value: 3, name: "企业数据" },
-        ],
-      },
-      {
-        value: 9,
-        name: "专题数据",
-        children: [
-          { value: 4, name: "规划数据" },
-          { value: 3, name: "医疗数据" },
-          { value: 2, name: "文旅数据" },
-        ],
+  watch: {
+    dateValue: {
+      handler(newVal, oldVal) {
+        if (newVal !== oldVal && newVal.length > 0) {
+          // 计算出比较的时间范围
+          this.compareTimes = [
+            this.$moment(
+              new Date(
+                new Date(newVal[0]).setTime(
+                  new Date(newVal[0]).getTime() - (newVal[1] - newVal[0])
+                )
+              )
+            ).format("YYYY-MM-DD"),
+            this.$moment(new Date(newVal[0])).format("YYYY-MM-DD"),
+          ];
+          this.initChart();
+        }
       },
-    ];
-
-    this.dataToOption("数据类别分布", "sunburst", datas2, null);
-    this.dataToOption("数据质量评分", "radar", datas2, null);
-    this.dataToOption("服务调用趋势(近30天)", "line", datas, {
-      xData: [],
-      xKey: "date",
-      yAxis: [
-        {
-          type: "value",
-          name: "调用次数",
-          axisLine: { lineStyle: { color: "#42a5f5" } }, // 区分样式
-        },
-        {
-          type: "value",
-          name: "响应时间(ms)",
-          axisLine: { lineStyle: { color: "#4caf50" } }, // 区分样式
-          position: "right",
-        },
-      ],
-      yData: [
-        {
-          key: "value",
-          name: "调用次数",
-          color: "#42a5f5",
-          data: [],
-          yAxisIndex: 0,
-        },
-        {
-          key: "value2",
-          name: "响应时间(ms)",
-          color: "#4caf50",
-          data: [],
-          ifDashed: true,
-          yAxisIndex: 1,
-        },
-      ],
-    });
-    this.dataToOption("用户活跃度趋势", "line", datas, {
-      xData: [],
-      xKey: "date",
-      yData: [
-        {
-          key: "value",
-          name: "调用次数",
-          color: "#42a5f5",
-          data: [],
-        },
-        {
-          key: "value2",
-          name: "响应时间(ms)",
-          color: "#4caf50",
-          data: [],
-        },
-      ],
+      deep: true,
+      // immediate: true,
+    },
+  },
+  mounted() {
+    this.$nextTick(() => {
+      this.dateValue = [
+        new Date(new Date().setTime(new Date() - 3600 * 1000 * 24 * 30)),
+        new Date(),
+      ];
     });
+  },
+  methods: {
+    initChart() {
+      let datas = [
+        { value: 1048, name: "调用次数", value2: 3, date: "12/17" },
+        { value: 735, name: "平均响应时间", value2: 3, date: "12/18" },
+      ];
 
-    this.dataToOption("服务类别分布", "pie", datas, {
-      pieKey: { value: "value", name: "name" },
-      pieData: [],
-    });
+      // 根据时间返回服务调用趋势(近30天)
+      totalCountGroupByTime(this.dateValue[0], this.dateValue[1]).then((res) => {
+        if (res) {
+          const sortAsc = [...res].sort((a, b) => a.time - b.time);
+          this.dataToOption("服务调用趋势(近30天)", "line", [...sortAsc], {
+            legend: { data: ["调用次数"] },
+            xData: [],
+            xKey: "time",
+            xFormart: "YYYY-MM-DD",
+            yAxis: {
+              type: "value",
+              name: "调用次数",
+              axisLine: { lineStyle: { color: "#42a5f5" } }, // 区分样式
+            },
+            yData: {
+              key: "count",
+              name: "调用次数",
+              color: "#42a5f5",
+              data: [],
+              yAxisIndex: 0,
+            },
+          });
+        }
+      });
+      serviceInfo(this.dateValue[0], this.dateValue[1]).then((res) => {
+        if (res) {
+          // 得到服务类别分布,map中key是cUnit,value是count,可以写一个公共方法,专门用来统计服务类别分布
+          let serviceTypeMap = {};
+          res.forEach((item) => {
+            if (serviceTypeMap[item.cUnit]) {
+              serviceTypeMap[item.cUnit] += item.count;
+            } else {
+              serviceTypeMap[item.cUnit] = item.count;
+            }
+          });
+          // 转换为数组
+          let serviceTypeDatas = [];
+          for (let key in serviceTypeMap) {
+            if (serviceTypeMap[key] && key) {
+              serviceTypeDatas.push({
+                name: key,
+                value: serviceTypeMap[key],
+              });
+            }
+          }
+          this.dataToOption("服务类别分布", "pie", [...serviceTypeDatas], {
+            pieKey: { value: "value", name: "name" },
+            pieData: [],
+          });
 
-    this.dataToOption("用户角色分布", "pie", datas, {
-      pieKey: { value: "value", name: "name" },
-      pieData: [],
-      legend: {
-        bottom: 10,
-      },
-      radius: "60%",
-      padAngle: 0,
-      borderRadius: 0,
-      label: {},
-    });
-    this.dataToOption("用户部门分布", "bar", datas, {
-      showLegend: false,
-      xData: [],
-      xKey: "date",
-      yData: [
-        {
+          this.dataToOption("委办分布", "pie", [...serviceTypeDatas], {
+            pieKey: { value: "value", name: "name" },
+            pieData: [],
+            legend: {
+              bottom: 10,
+            },
+            radius: "60%",
+            padAngle: 0,
+            borderRadius: 0,
+            label: {},
+          });
+          // 服务调用TOP10《cPathComment+cUnit,调用次数》
+          let serviceTypeMap2 = {};
+          res.forEach((item) => {
+            if (serviceTypeMap2[item.cPathComment + item.cUnit]) {
+              serviceTypeMap2[item.cPathComment + item.cUnit].push(item);
+            } else {
+              serviceTypeMap2[item.cPathComment + item.cUnit] = [item];
+            }
+          });
+          // 转换为数组
+          let serviceTypeDatas2 = [];
+          for (let key in serviceTypeMap2) {
+            if (serviceTypeMap2[key] && key) {
+              let item = serviceTypeMap2[key];
+              let tableDataItem = {
+                serviceName: "",
+                serviceType: "",
+                callCount: 0,
+              };
+              item.forEach((item2) => {
+                tableDataItem.serviceName = item2.cPathComment;
+                tableDataItem.serviceType = item2.cUnit;
+                tableDataItem.callCount += item2.count;
+              });
+              serviceTypeDatas2.push(tableDataItem);
+            }
+          }
+          // 根据callCount进行降序排序并截取前10条
+          serviceTypeDatas2.sort((a, b) => b.callCount - a.callCount);
+          serviceTypeDatas2 = serviceTypeDatas2.slice(0, 10);
+          this.initTableDatas(serviceTypeDatas2);
+        }
+      });
+      // 应用状态分布,cloumnId:1659
+      appCenter
+        .getDmsDataList({
+          columnId: 1659,
+          pageSize: 1000,
+          page: 0,
+        })
+        .then((res) => {
+          if (res.code == 200) {
+            let dmsDatas = res.content.data;
+            let tableDatas = [];
+            // 根据状态进行groupBy统计个数
+            let statusMap = {};
+            dmsDatas.forEach((item) => {
+              if (statusMap[item.appstauts + ""]) {
+                statusMap[item.appstauts + ""] += 1;
+              } else {
+                statusMap[item.appstauts + ""] = 1;
+              }
+            });
+            // 转换为数组
+            for (let key in statusMap) {
+              if (statusMap[key] && key) {
+                tableDatas.push({
+                  name: this.$getDmsTypes("appstatus", key),
+                  value: statusMap[key],
+                });
+              }
+            }
+            this.dataToOption("应用状态分布", "pie", tableDatas, {
+              pieKey: { value: "value", name: "name" },
+              pieData: [],
+            });
+          } else {
+            this.$message({
+              type: "error",
+              message: "服务器忙碌,请稍后重试!",
+            });
+          }
+        });
+
+      // 用户部门分布
+      this.dataToOption("用户部门分布", "bar", datas, {
+        showLegend: false,
+        xData: [],
+        xKey: "date",
+        yData: {
           key: "value",
           name: "调用次数",
           color: "#42a5f5",
           data: [],
         },
-      ],
-    });
-    // 表格数据初始化
-    this.initTableDatas();
-  },
-  methods: {
-    dataToOption(title, type, datas, keyRule) {
+      });
+      this.dataToOption("数据类别分布", "pie", datas, {
+        pieKey: { value: "value", name: "name" },
+        pieData: [],
+        legend: {
+          bottom: 10,
+        },
+        radius: "60%",
+        padAngle: 0,
+        borderRadius: 0,
+        label: {},
+      });
+      this.dataToOption("数据质量评分", "radar", null, null);
+    },
+    /**
+     * 数据转换为图表选项
+     * @param title 图表标题
+     * @param type 图表类型
+     * @param datas 原始数据
+     * @param keyRule 解析规则
+     */
+    async dataToOption(title, type, datas, keyRule) {
       // 根据规则解析数据
       if (keyRule) {
         datas.forEach((item) => {
           // 有的图表没有X轴
           if (keyRule.xKey) {
+            if (keyRule.xFormart) {
+              item[keyRule.xKey] = this.$moment(item[keyRule.xKey]).format(
+                keyRule.xFormart
+              );
+            }
             keyRule.xData.push(item[keyRule.xKey]);
           }
           if (keyRule.yData) {
-            keyRule.legend = [];
-            keyRule.yData.forEach((dataItem) => {
-              dataItem.data.push(item[dataItem.key]);
-              keyRule.legend.push(dataItem.name);
-            });
+            keyRule.yData.data.push(item[keyRule.yData.key]);
           }
           if (keyRule.pieKey) {
             keyRule.pieData.push({
@@ -336,7 +434,7 @@ export default {
           // 折线图基础
           _option = {
             legend: {
-              data: keyRule.legend,
+              data: keyRule.legend.data,
             },
             tooltip: {
               show: true,
@@ -351,26 +449,22 @@ export default {
               splitLine: { show: false }, // 隐藏分割线
             },
             yAxis: keyRule.yAxis ? keyRule.yAxis : { type: "value" },
-            series: [],
+            series: [
+              {
+                name: keyRule.yData.name,
+                type: "line",
+                smooth: true,
+                data: keyRule.yData.data,
+                lineStyle: {
+                  color: keyRule.yData.color ? keyRule.yData.color : "",
+                  type: keyRule.yData.ifDashed ? "dashed" : "",
+                }, // 蓝色线条
+                itemStyle: keyRule.yData.color,
+                symbol: "circle", // 节点形状
+                symbolSize: 6, // 节点大小
+              },
+            ],
           };
-          // 补充数据
-          keyRule.yData.forEach((item) => {
-            // 补充server
-            _option.series.push({
-              name: item.name,
-              type: "line",
-              smooth: true,
-              data: item.data, // 模拟数据
-              lineStyle: {
-                color: item.color ? item.color : "",
-                type: item.ifDashed ? "dashed" : "",
-              }, // 蓝色线条
-              itemStyle: item.color ? { color: item.color } : {}, // 节点颜色
-              symbol: "circle", // 节点形状
-              symbolSize: 6, // 节点大小
-              yAxisIndex: item.yAxisIndex != undefined ? item.yAxisIndex : 0, // 绑定Y轴
-            });
-          });
           break;
         case "pie":
           // 饼状图
@@ -438,36 +532,19 @@ export default {
               type: "category",
               data: keyRule.xData,
             },
-            series: [],
-          };
-          keyRule.yData.forEach((item) => {
-            _option.series.push({
-              name: item.name,
-              type: "bar",
-              label: {
-                show: true,
-              },
-              emphasis: {
-                focus: "series",
-              },
-              data: item.data,
-            });
-          });
-          break;
-        case "sunburst":
-          // 旭日图
-          _option = {
-            series: {
-              type: "sunburst",
-              emphasis: {
-                focus: "ancestor",
-              },
-              data: datas,
-              radius: [0, "90%"],
-              label: {
-                rotate: "radial",
+            series: [
+              {
+                name: keyRule.yData.name,
+                type: "bar",
+                label: {
+                  show: true,
+                },
+                emphasis: {
+                  focus: "series",
+                },
+                data: keyRule.yData.data,
               },
-            },
+            ],
           };
           break;
         default:
@@ -483,11 +560,11 @@ export default {
             radar: [
               {
                 indicator: [
-                  { text: "完整性", max: 100 },
-                  { text: "可用性", max: 100 },
-                  { text: "一致性", max: 100 },
-                  { text: "及时性", max: 100 },
-                  { text: "准确性", max: 100 },
+                  { name: "健壮性", max: 100 },
+                  { name: "完整性", max: 100 },
+                  { name: "一致性", max: 100 },
+                  { name: "及时性", max: 100 },
+                  { name: "准确性", max: 100 },
                 ],
               },
             ],
@@ -497,12 +574,8 @@ export default {
                 areaStyle: {},
                 data: [
                   {
-                    value: [85, 90, 90, 95, 95],
-                    name: "A Phone",
-                  },
-                  {
-                    value: [95, 80, 95, 90, 93],
-                    name: "Another Phone",
+                    value: [93, 85, 92, 95, 93],
+                    name: "",
                   },
                 ],
               },
@@ -513,30 +586,8 @@ export default {
       this.chartOptions[title] = _option;
     },
     // 服务调用列表
-    initTableDatas() {
-      this.tableDatas = [
-        {
-          serviceName: "服务A",
-          serviceType: "类别A",
-          callCount: 100,
-          successRate: "90%",
-          avgResponseTime: "100ms",
-        },
-        {
-          serviceName: "服务B",
-          serviceType: "类别B",
-          callCount: 200,
-          successRate: "80%",
-          avgResponseTime: "150ms",
-        },
-        {
-          serviceName: "服务C",
-          serviceType: "类别C",
-          callCount: 300,
-          successRate: "70%",
-          avgResponseTime: "200ms",
-        },
-      ];
+    initTableDatas(serviceTypeDatas2) {
+      this.tableDatas = serviceTypeDatas2;
     },
     // 时间范围自定义时间
     shortcuts() {
@@ -595,26 +646,28 @@ export default {
     width: calc(25% - 56px);
     border-radius: 5px;
     padding: 20px 18px;
-    background: #00000032;
-    box-shadow: 0 0 15px 1px rgba(0, 0, 0, 0.15);
+    // background: #00000032;
+    background: rgba(255, 255, 255, 0.1);
+    box-shadow: 0 2px 12px rgba(0, 0, 0, 0.3);
   }
 
   .card2 {
     width: 100%;
     border-radius: 5px;
     padding: 20px 18px;
-    background: #00000032;
-    box-shadow: 0 0 15px 1px rgba(0, 0, 0, 0.15);
+    // background: rgba(255, 255, 255, 0.1);
+    box-shadow: 0 2px 12px rgba(0, 0, 0, 0.3);
   }
 
   .bigCard {
     width: calc(100% - 36px);
     border-radius: 5px;
     padding: 20px 18px;
-    background: #00000032;
+    // background: #00000032;
     position: relative;
     flex-direction: column;
-    box-shadow: 0 0 15px 1px rgba(0, 0, 0, 0.15);
+    background: rgba(255, 255, 255, 0.1);
+    box-shadow: 0 2px 12px rgba(0, 0, 0, 0.3);
     .tools {
       position: absolute;
       top: 20px;

+ 141 - 110
src/views/yygl/overview/index.vue

@@ -2,32 +2,38 @@
   <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>
+      <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" @click="getDmsDataList">搜索</el-button>
-            </div>
-            
+          </el-input>
+          <el-button type="primary" class="search-btn" @click="getDmsDataList"
+            >搜索</el-button
+          >
+        </div>
 
-            <!-- 应用范围过滤 -->
-            <div class="filter-tabs">
-                <el-radio-group v-model="activeTab" size="medium" @change="handleTabChange" v-for="item in levelOptions" :key="item.value">
-                    <el-radio-button :label="item.label">{{ item.value }}</el-radio-button>
-                    <!-- <el-radio-button label="1">区级</el-radio-button>
+        <!-- 应用范围过滤 -->
+        <div class="filter-tabs">
+          <el-radio-group
+            v-model="activeTab"
+            size="medium"
+            @change="handleTabChange"
+            v-for="item in levelOptions"
+            :key="item.value"
+          >
+            <el-radio-button :label="item.label">{{ item.value }}</el-radio-button>
+            <!-- <el-radio-button label="1">区级</el-radio-button>
                     <el-radio-button label="2">街镇</el-radio-button> -->
-                </el-radio-group>
-            </div>
+          </el-radio-group>
         </div>
+      </div>
       <!-- 应用卡片网格 -->
       <div class="app-content">
         <div class="applications-grid">
@@ -48,7 +54,13 @@
               <p class="app-description">{{ app.content }}</p>
               <div class="app-footer">
                 <span class="app-date">{{ app.createTime }}</span>
-                <el-button type="primary" size="small" class="visit-button" @click="handleVisit">访问</el-button>
+                <el-button
+                  type="primary"
+                  size="small"
+                  class="visit-button"
+                  @click="handleVisit"
+                  >访问</el-button
+                >
               </div>
             </div>
           </div>
@@ -64,29 +76,31 @@
 
 <script>
 import appCenter from "@/api/appCenter";
-import moment from 'moment';
+import moment from "moment";
 export default {
   name: "ApplicationOverview",
   data() {
     return {
-      searchKeyword: '',
-      activeTab: 'all',
-      curUrl:systemConfig.dmsDataProxy,
+      searchKeyword: "",
+      activeTab: "all",
+      curUrl: systemConfig.dmsDataProxy,
       levelOptions: [],
       tagOptions: [],
       applications: [],
-      itemApplications: []
-    }
+      itemApplications: [],
+    };
   },
-   mounted() {
-    this.initData()
+  mounted() {
+    this.initData();
   },
   methods: {
     handleTabChange() {
-      if (this.activeTab == 'all') {
+      if (this.activeTab == "all") {
         this.applications = this.itemApplications;
       } else {
-        this.applications = this.itemApplications.filter(item => item.level == this.activeTab);
+        this.applications = this.itemApplications.filter(
+          (item) => item.level == this.activeTab
+        );
       }
     },
     initData() {
@@ -97,54 +111,57 @@ export default {
     handleVisit() {
       // http://localhost:2027/fileView?url=/proxy_dms/static/1_青浦大数据中心一张图功能表20240531.xlsx
       // http://localhost:2027/fileView?url=/proxy_dms/static/test.geojson
-      window.open('fileView?url='+this.curUrl+'/static/1_青浦大数据中心一张图功能表20240531.xlsx', '_blank');
+      window.open(
+        "fileView?url=" +
+          this.curUrl +
+          "/static/1_青浦大数据中心一张图功能表20240531.xlsx",
+        "_blank"
+      );
     },
-    getDmsTagSName(){
+    getDmsTagSName() {
       let requestParams = {
-        sName: 'tag',
+        sName: "tag",
       };
-      appCenter.getDmsSName(requestParams).then(res => {
+      appCenter.getDmsSName(requestParams).then((res) => {
         if (res.code === 200) {
-            this.tagOptions = res.content.map(item => ({
-              label: item.index,
-              value: item.name
-            }));
-            let allOption = {
-              label: 'all',
-              value: '全部'
-            }
-            this.tagOptions.unshift(allOption);
-            
+          this.tagOptions = res.content.map((item) => ({
+            label: item.index,
+            value: item.name,
+          }));
+          let allOption = {
+            label: "all",
+            value: "全部",
+          };
+          this.tagOptions.unshift(allOption);
         }
-      })
+      });
     },
     getDmsCNameAType() {
       let requestParams = {
-        cName: 'applevel',
-        type: 0
+        cName: "applevel",
+        type: 0,
       };
-      
-      appCenter.getDmsCNameAType(requestParams).then(res => {
+
+      appCenter.getDmsCNameAType(requestParams).then((res) => {
         if (res.code === 200) {
-            this.levelOptions = res.content.map(item => ({
-              label: item.index,
-              value: item.name
-            }));
-            let allOption = {
-              label: 'all',
-              value: '全部'
-            }
-            this.levelOptions.unshift(allOption);
-            
+          this.levelOptions = res.content.map((item) => ({
+            label: item.index,
+            value: item.name,
+          }));
+          let allOption = {
+            label: "all",
+            value: "全部",
+          };
+          this.levelOptions.unshift(allOption);
         }
-      })
+      });
     },
     getDmsDataList() {
       let requestParams = {
         columnId: 1658,
         states: 0,
         pageSize: 999,
-        page: 0
+        page: 0,
       };
       if (this.searchKeyword) {
         requestParams.search = JSON.stringify([
@@ -155,25 +172,39 @@ export default {
           },
         ]);
       }
-      appCenter.getDmsDataList(requestParams).then(res => {
+      appCenter.getDmsDataList(requestParams).then((res) => {
         if (res.code === 200) {
-          this.itemApplications = res.content.data.map(item => ({
+          this.itemApplications = res.content.data.map((item) => ({
             ...item,
-            status: item.status === 0 ? '待审核' : item.status === 1 ? '待发布' : item.status === 2 ? '未完成' : '已完成',
+            status:
+              item.status === 0
+                ? "待审核"
+                : item.status === 1
+                ? "待发布"
+                : item.status === 2
+                ? "未完成"
+                : "已完成",
             // levelName: item.level == 0 ? '区级' : item.level == 1 ? '街镇' : item.level == 2 ? '社区' : '',
-            levelName: this.levelOptions.find(info => info.label == item.level.trim())?.value || '',
-            tags: item.tag.split(',').map(tag => this.tagOptions.find(info => info.label == tag.trim())?.value || ''),
-            createTime: moment(item.create_time).format('YYYY-MM-DD HH:mm:ss')
-          }))
+            levelName:
+              this.levelOptions.find((info) => info.label == item.level.trim())?.value ||
+              "",
+            tags: item.tag
+              .split(",")
+              .map(
+                (tag) =>
+                  this.tagOptions.find((info) => info.label == tag.trim())?.value || ""
+              ),
+            createTime: moment(item.create_time).format("YYYY-MM-DD HH:mm:ss"),
+          }));
           this.applications = this.itemApplications;
           this.handleTabChange();
-        }else{
+        } else {
           this.applications = [];
         }
-      })
-    }
-  }
-}
+      });
+    },
+  },
+};
 </script>
 
 <style lang="less" scoped>
@@ -194,20 +225,20 @@ export default {
 /* 搜索栏样式 */
 .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);
@@ -222,26 +253,26 @@ export default {
 /* 过滤标签样式 */
 .filter-tabs {
   margin-bottom: 30px;
-  
-  ::v-deep .el-radio-group {
+
+  :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;
@@ -251,10 +282,10 @@ export default {
     }
   }
 }
-.app-content{
-    // height: 640px;
-    height: calc(100vh - 266px);
-    overflow: auto;
+.app-content {
+  // height: 640px;
+  height: calc(100vh - 266px);
+  overflow: auto;
 }
 
 /* 应用卡片网格样式 */
@@ -271,40 +302,40 @@ export default {
   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;
@@ -327,16 +358,16 @@ export default {
       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;
@@ -348,17 +379,17 @@ export default {
     -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;
@@ -371,13 +402,13 @@ export default {
 .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);
@@ -396,27 +427,27 @@ export default {
 @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>
+</style>

+ 4 - 1
vue.config.js

@@ -96,7 +96,10 @@ module.exports = defineConfig({
         }
       },
       '/oneMap/': {
-        target: 'http://127.0.0.1:10099/qpyzt',
+        // 本地环境
+        // target: 'http://127.0.0.1:10099/qpyzt',
+        // 线上环境
+        target: 'http://121.43.55.7:13901/qpyzt',
         changeOrigin: true,
         pathRewrite: {
           '^/oneMap': ''