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

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

DESKTOP-6LTVLN7\Liumouren 3 недель назад
Родитель
Сommit
a722be37f7

+ 3 - 9
src/components/wgn/controlPanel.vue

@@ -5,7 +5,7 @@
         <div class="">
           场景名称:
           <el-cascader
-            :disabled="$route.query.sceneId"
+            :disabled="$route.query.sceneId != undefined"
             v-model="SceneValue"
             placeholder="试试搜索:距离"
             :options="SceneList"
@@ -144,14 +144,7 @@
             {{ backData.message || backData.error }}
           </div>
 
-          <div
-            class="vueJsonEditor_box"
-            v-show="
-              SceneValue &&
-              dmsServerItem &&
-              (ifHasType('point') || ifHasType('polyline') || ifHasType('polygon'))
-            "
-          >
+          <div class="vueJsonEditor_box" v-show="SceneValue && dmsServerItem">
             <div class="vueJsonEditor_tools">
               <span
                 v-if="
@@ -164,6 +157,7 @@
               <span @click="copyJsonData(backData.content)">copy</span>
             </div>
             <vue-json-editor
+              v-if="backData.content"
               v-model="backData.content"
               :value="backData.content"
               @json-change="handleJsonChange2"

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

@@ -81,6 +81,18 @@ export default {
           fontWeight: "normal", // 可选:字体粗细
         },
       });
+
+      // 合并tooltip配置
+      if (!mergedOption.tooltip) {
+        mergedOption.tooltip = {};
+      }
+      Object.assign(mergedOption.tooltip, {
+        backgroundColor: "rgba(0, 25, 50, 0.8)",
+        borderColor: "#1E90FF",
+        textStyle: {
+          color: "#fff",
+        },
+      });
       chartInstance.setOption(mergedOption, true);
       // 添加resize事件监听
       window.addEventListener("resize", () => {

+ 415 - 351
src/views/Sksjgl.vue

@@ -1,391 +1,455 @@
 <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 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 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>
+    <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="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-list">
-                    <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 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-list">
+          <div
+            class="card-item"
+            v-for="(item, index) in cardList"
+            :key="index"
+            @click.stop="handleOnlineDemo(item)"
+          >
+            <div class="card-title">{{ item.title.split("/")[1] }}</div>
+            <div class="card-bg">
+              <el-image
+                style="width: 100%; height: 100%"
+                :src="dmsDataProxy + item.c_picture"
+                fit="cover"
+              />
             </div>
-
+            <div class="card-desc">{{ item.content }}</div>
+          </div>
         </div>
-
+      </div>
     </div>
+  </div>
 </template>
 
 <script>
+import wgn from "@/api/wgn";
 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: "主要河网分布与水文监测数据、流域相关大数据"
-                }
-            ]
-        };
+  data() {
+    return {
+      dmsDataProxy: "",
+      activePanel: "sjzljc",
+      funcList: systemConfig.sksjgl.funcList,
+      nowFuncContent: [],
+      cardList: [],
+    };
+  },
+  mounted() {
+    this.dmsDataProxy = systemConfig.dmsDataProxy;
+    this.changePanel(this.activePanel);
+    this.searchServerList();
+  },
+  methods: {
+    changePanel(active) {
+      this.activePanel = active;
+      this.nowFuncContent = this.funcList[this.activePanel];
     },
-    mounted() {
-        this.changePanel(this.activePanel)
+    // 搜索微功能服务
+    searchServerList() {
+      let requestParams = {
+        columnId: 1651,
+        states: 0,
+        pageSize: 999,
+        page: 0,
+      };
+      requestParams.search = JSON.stringify([
+        {
+          field: "title",
+          searchType: 2,
+          content: { value: "%时空算子库%" },
+        },
+      ]);
+      // 获取微功能服务列表
+      wgn
+        .getDmsData(requestParams)
+        .then((res) => {
+          if (res.code === 200) {
+            this.cardList = res.content.data;
+          } else {
+            this.$message({
+              message: "搜索到0条微功能服务",
+              type: "warning",
+            });
+          }
+        })
+        .catch((e) => {
+          this.$message({
+            message: "搜索微功能服务失败" + e,
+            type: "error",
+          });
+        });
     },
-    methods: {
-        changePanel(active) {
-            this.activePanel = active;
-            this.nowFuncContent = this.funcList[this.activePanel]
-        }
-    }
+    // 在线演示微功能服务
+    handleOnlineDemo(item) {
+      let routerPath = {};
+      // 1. 解析目标路由(支持传参、命名路由等)
+      if (item.c_scene_name == "view") {
+        routerPath = {
+          path: item.c_url,
+        };
+      } else {
+        routerPath = {
+          path: "/wgnSingle", // 微功能
+          query: { sceneId: item.c_scene_name },
+        };
+      }
+      const routeData = this.$router.resolve(routerPath);
+      // 2. 打开新窗口(_blank 表示新窗口)
+      window.open(routeData.href, "_blank");
+    },
+  },
 };
 </script>
 
 <style lang="less" scoped>
 .container {
+  width: 100%;
+  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%;
-    margin: 0 auto;
+    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);
+        }
 
-    .server_title {
+        &: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% - 38px);
+        // height: 400px;
+        // background: #f0f8ff;
+        // border: 1px solid #409eff;
         display: flex;
-        justify-content: center;
         align-items: center;
+        justify-content: center;
+        font-size: 18px;
+        color: #333;
+
+        a {
+          width: 100%;
+          height: 100%;
+
+          .pictrue {
+            width: 100%;
+            aspect-ratio: 1920 / 900;
+            border-radius: 8px;
+            transition: all 0.3s ease;
+          }
 
-        .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;
-            }
+          .label {
+            color: #ffffff;
+            text-align: center;
+            height: 70px;
+            line-height: 70px;
+            font-size: 24px;
+          }
+        }
+
+        &:hover .pictrue {
+          transform: scale(1.05) translateY(-5px);
+          box-shadow: 0 10px 30px rgba(24, 144, 255, 0.3);
+          border-color: rgba(24, 144, 255, 0.6);
         }
+      }
+    }
+  }
+
+  .time-space-operator-lib {
+    background-color: #1e407c;
+    color: #fff;
+    padding: 100px 150px;
+    box-sizing: border-box;
+
+    /* 标题区域 */
+    .title-section {
+      text-align: center;
+      margin-bottom: 50px;
+
+      h1 {
+        font-size: 50px;
+        font-weight: bold;
+      }
     }
 
-    .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%;
-            }
+    /* 描述区域 */
+    .desc-section {
+      margin-bottom: 30px;
+      line-height: 2;
+      font-size: 20px;
+      text-indent: 2em;
+    }
+
+    /* 业务专区区域 */
+    .business-section {
+      margin-top: 20px;
+      border-radius: 16px 16px 16px 16px;
+      background-color: rgba(31, 41, 55, 0.16);
+      border: 1px solid #374151;
+      padding: 20px 20px;
+      box-sizing: border-box;
+
+      .business-header {
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        margin-bottom: 15px;
+        font-size: 16px;
+
+        span {
+          font-size: 20px;
         }
 
-        /* 流程内容样式 */
-        .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% - 38px);
-                // 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%;
-                        aspect-ratio: 1920 / 900;
-                        border-radius: 8px;
-                        transition: all 0.3s ease;
-                    }
-
-                    .label {
-                        color: #ffffff;
-                        text-align: center;
-                        height: 70px;
-                        line-height: 70px;
-                        font-size: 24px;
-                    }
-                }
-
-                &:hover .pictrue {
-                    transform: scale(1.05) translateY(-5px);
-                    box-shadow: 0 10px 30px rgba(24, 144, 255, 0.3);
-                    border-color: rgba(24, 144, 255, 0.6);
-                }
-
-            }
+        .more-btn {
+          background-color: transparent;
+          border: 1px solid #fff;
+          color: #fff;
+          padding: 4px 12px;
+          border-radius: 4px;
+          cursor: pointer;
         }
+      }
     }
 
-    .time-space-operator-lib {
-        background-color: #1e407c;
-        color: #fff;
-        padding: 100px 150px;
-        box-sizing: border-box;
-
-        /* 标题区域 */
-        .title-section {
-            text-align: center;
-            margin-bottom: 50px;
+    /* 卡片列表 */
+    .card-list {
+      display: flex;
+      grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
+      justify-content: space-between;
+
+      .card-item {
+        background-color: rgba(255, 255, 255, 0.1);
+        padding: 15px;
+        border-radius: 8px;
+        height: 240px;
+        display: flex;
+        width: 10vw;
+        flex-direction: column;
 
-            h1 {
-                font-size: 50px;
-                font-weight: bold;
-            }
+        &:hover {
+          cursor: pointer;
+          box-shadow: 0 10px 30px rgba(24, 144, 255, 0.3);
+          border-color: rgba(24, 144, 255, 0.6);
         }
 
-        /* 描述区域 */
-        .desc-section {
-            margin-bottom: 30px;
-            line-height: 2;
-            font-size: 20px;
-            text-indent: 2em;
+        .card-title {
+          font-size: 15px;
+          font-weight: 500;
+          margin-bottom: 10px;
         }
 
-        /* 业务专区区域 */
-        .business-section {
-            margin-top: 20px;
-            border-radius: 16px 16px 16px 16px;
-            background-color: rgba(31, 41, 55, 0.16);
-            border: 1px solid #374151;
-            padding: 20px 20px;
-            box-sizing: border-box;
-
-            .business-header {
-                display: flex;
-                justify-content: space-between;
-                align-items: center;
-                margin-bottom: 15px;
-                font-size: 16px;
-
-                span {
-                    font-size: 20px;
-                }
-
-                .more-btn {
-                    background-color: transparent;
-                    border: 1px solid #fff;
-                    color: #fff;
-                    padding: 4px 12px;
-                    border-radius: 4px;
-                    cursor: pointer;
-                }
-            }
+        .card-bg {
+          flex: 1;
+          border-radius: 4px;
+          margin: 8px 0;
         }
 
-        /* 卡片列表 */
-        .card-list {
-            display: grid;
-            grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
-            gap: 55px;
-
-            .card-item {
-                background-color: rgba(255, 255, 255, 0.1);
-                padding: 15px;
-                border-radius: 8px;
-                height: 240px;
-                display: flex;
-                flex-direction: column;
-
-                &:hover {
-                    cursor: pointer;
-                    box-shadow: 0 10px 30px rgba(24, 144, 255, 0.3);
-                    border-color: rgba(24, 144, 255, 0.6);
-                }
-
-                .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;
-                }
-            }
+        .card-desc {
+          font-size: 12px;
+          opacity: 0.8;
+          line-height: 1.4;
+          /* 文字最多显示两行,超出部分省略号 */
+          overflow: hidden;
+          text-overflow: ellipsis;
+          display: -webkit-box;
+          -webkit-line-clamp: 2;
+          -webkit-box-orient: vertical;
         }
+      }
     }
+  }
 }
-</style>
+</style>

+ 46 - 37
src/views/Wgn.vue

@@ -195,6 +195,8 @@ export default {
           c_department: "",
         },
       },
+      // 搜索微功能服务的防抖定时器
+      searchTimeout: null,
     };
   },
   mounted() {
@@ -204,44 +206,50 @@ export default {
   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 + "%" },
-          },
-        ]);
+      // 添加防抖功能,避免频繁搜索导致性能问题
+      if (this.searchTimeout != null) {
+        clearTimeout(this.searchTimeout);
       }
-      // 获取微功能服务列表
-      wgn
-        .getDmsData(requestParams)
-        .then((res) => {
-          if (res.code === 200) {
-            this.dmsServerList = res.content.data;
-            this.$message({
-              message: "搜索到" + this.dmsServerList.length + "条微功能服务",
-              type: "success",
-            });
-          } else {
+      this.searchTimeout = setTimeout(() => {
+        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: "搜索到0条微功能服务",
-              type: "warning",
+              message: "搜索微功能服务失败" + e,
+              type: "error",
             });
-          }
-        })
-        .catch((e) => {
-          this.$message({
-            message: "搜索微功能服务失败" + e,
-            type: "error",
           });
-        });
+      }, 0);
     },
     // 申请使用微功能服务
     handleApply(item) {
@@ -306,15 +314,16 @@ export default {
         routerPath = {
           path: item.c_url,
         };
+        this.$router.push(routerPath);
       } else {
         routerPath = {
           path: "/wgnSingle", // 微功能
           query: { sceneId: item.c_scene_name },
         };
+        const routeData = this.$router.resolve(routerPath);
+        // 2. 打开新窗口(_blank 表示新窗口)
+        window.open(routeData.href, "_blank");
       }
-      const routeData = this.$router.resolve(routerPath);
-      // 2. 打开新窗口(_blank 表示新窗口)
-      window.open(routeData.href, "_blank");
     },
   },
 };

+ 5 - 1
src/views/Yxgl.vue

@@ -18,7 +18,10 @@
           <template #title>信息反馈</template>
         </el-menu-item>
       </el-sub-menu>
-      <el-sub-menu index="2">
+      <el-sub-menu
+        index="2"
+        v-if="$store.userInfo && $store.userInfo.id != touristUserId"
+      >
         <template #title>
           <el-icon><Tools /></el-icon>
           <span>运行管理子系统</span>
@@ -54,6 +57,7 @@ export default {
   name: "yxgl",
   data() {
     return {
+      touristUserId: systemConfig.touristUserId,
       isCollapse: false,
       menuActive: "StatisticalAnalysis",
       iframeUrl: "",

+ 91 - 36
src/views/yxgl/StatisticalAnalysis.vue

@@ -3,7 +3,9 @@
     <!-- 搜索区域 -->
     <div class="searchBox">
       <div>
-        对比时间:
+        <!-- 添加一个按钮触发事件 -->
+        <!-- <el-button type="primary" @click="playTTS()">请求音频</el-button> -->
+        <!-- 对比时间:
         <el-date-picker
           v-model="lastTimes"
           type="daterange"
@@ -14,7 +16,7 @@
           disabled
           size="large"
           style="margin-right: 30px"
-        />
+        /> -->
         搜索时间:
         <el-date-picker
           v-model="nowTimes"
@@ -153,6 +155,8 @@ import card from "@/components/yxgl/card.vue";
 import EchartsDome from "@/components/yxgl/EchartsDome.vue";
 import Table from "@/components/yxgl/table.vue";
 import appCenter from "@/api/appCenter";
+import { color } from "echarts";
+
 export default {
   name: "",
   components: {
@@ -214,15 +218,15 @@ export default {
             this.$moment(
               new Date(
                 new Date(newVal[0]).setTime(
-                  new Date(newVal[0]).getTime() - (newVal[1] - newVal[0])
+                  new Date(newVal[0]).getTime() -
+                    (newVal[1] - newVal[0]) -
+                    24 * 60 * 60 * 1000
                 )
               )
             ).format("YYYY-MM-DD 00:00:00"),
             this.$moment(new Date(newVal[0])).format("YYYY-MM-DD 00:00:00"),
           ];
           this.initChart();
-          // 头部的服务调用总数等信息
-          this.initUserInfo();
         }
       },
       deep: true,
@@ -238,20 +242,35 @@ export default {
     });
   },
   methods: {
-    initUserInfo() {
-      if (this.lastTimes.length === 0) {
-        this.lastTimes = [
-          this.$moment(
-            new Date(
-              new Date(this.nowTimes[0]).setTime(
-                new Date(this.nowTimes[0]).getTime() -
-                  (this.nowTimes[1] - this.nowTimes[0])
-              )
-            )
-          ).format("YYYY-MM-DD 00:00:00"),
-          this.$moment(new Date(this.nowTimes[0])).format("YYYY-MM-DD 00:00:00"),
-        ];
-      }
+    playTTS() {
+      const url = "http://192.168.2.8:8008/api/tts/audio";
+      fetch(url, {
+        method: "POST",
+        headers: {
+          "Content-Type": "application/json",
+        },
+        body: JSON.stringify({
+          text: `纸扎铺的灯笼
+深巷尽头的纸扎铺,夜半总飘出灯笼光。
+我加班晚归,撞见铺门虚掩,昏黄的灯笼悬在檐下,穗子无风自动。老板低头扎纸人,指尖翻飞,纸人眉眼竟和巷口失踪的外卖员一模一样。
+“要灯笼吗?” 他头也不抬,声音像揉皱的黄纸。
+我拔腿就跑,身后传来细碎的脚步声。回头看,那盏灯笼悠悠跟着,灯笼里的烛火,映出一张纸糊的脸。
+次日清晨,巷口多了一盏新灯笼,上面贴着我的名字。`,
+        }),
+      })
+        .then((response) => response.blob()) // 转换为Blob对象
+        .then((blob) => {
+          const audio = new Audio();
+          const blobUrl = window.URL.createObjectURL(blob);
+          audio.src = blobUrl;
+          audio.play();
+          audio.onended = () => {
+            window.URL.revokeObjectURL(blobUrl);
+          };
+        })
+        .catch((error) => {
+          console.error("TTS请求失败:", error);
+        });
     },
     initChart() {
       // 获取运行管理页面数据
@@ -259,7 +278,7 @@ export default {
         .getAllYxglDatas({
           nowTimes: [
             this.$moment(new Date(this.nowTimes[0])).format("YYYY-MM-DD 00:00:00"),
-            this.$moment(new Date(this.nowTimes[1])).format("YYYY-MM-DD 00:00:00"),
+            this.$moment(new Date(this.nowTimes[1])).format("YYYY-MM-DD 23:59:59"),
           ],
           lastTimes: this.lastTimes,
         })
@@ -358,6 +377,21 @@ export default {
                 data: [],
               },
             });
+            // 数据类别分布
+            if (res.content.dataTypes && res.content.dataTypes.length > 0) {
+              this.dataToOption("数据类别分布", "pie", [...res.content.dataTypes], {
+                pieKey: { value: "count", name: "service_name" },
+                pieData: [],
+                legend: {
+                  bottom: 10,
+                },
+                radius: "60%",
+                padAngle: 0,
+                borderRadius: 0,
+                label: {},
+              });
+            }
+
             // console.log("getAllYxglDatas", res);
           }
         });
@@ -402,17 +436,6 @@ export default {
           }
         });
 
-      this.dataToOption("数据类别分布", "pie", [{ name: "test", value: 10 }], {
-        pieKey: { value: "value", name: "name" },
-        pieData: [],
-        legend: {
-          bottom: 10,
-        },
-        radius: "60%",
-        padAngle: 0,
-        borderRadius: 0,
-        label: {},
-      });
       this.dataToOption("数据质量评分", "radar", null, null);
     },
     /**
@@ -507,8 +530,21 @@ export default {
               data: keyRule.xData,
               axisTick: { show: false }, // 隐藏刻度
               splitLine: { show: false }, // 隐藏分割线
+              axisLabel: {
+                color: "#F2F3F5cc", // 字体颜色(支持十六进制、RGB、颜色名)
+                fontSize: 14, // 可选:字体大小
+                fontWeight: "normal", // 可选:字体粗细
+              },
+            },
+            yAxis: {
+              type: "value",
+              axisLabel: {
+                color: "#42a5f5cc", // 字体颜色(支持十六进制、RGB、颜色名)
+                fontSize: 14, // 可选:字体大小
+                fontWeight: "normal", // 可选:字体粗细
+              },
+              splitLine: { lineStyle: { color: "#42a5f532" } },
             },
-            yAxis: keyRule.yAxis ? keyRule.yAxis : { type: "value" },
             series: keyRule.series,
           };
           break;
@@ -573,10 +609,21 @@ export default {
             },
             xAxis: {
               type: "value",
+              axisLabel: {
+                color: "#42a5f5cc", // 字体颜色(支持十六进制、RGB、颜色名)
+                fontSize: 14, // 可选:字体大小
+                fontWeight: "normal", // 可选:字体粗细
+              },
+              splitLine: { lineStyle: { color: "#42a5f532" } },
             },
             yAxis: {
               type: "category",
               data: keyRule.xData,
+              axisLabel: {
+                color: "#F2F3F5cc", // 字体颜色(支持十六进制、RGB、颜色名)
+                fontSize: 14, // 可选:字体大小
+                fontWeight: "normal", // 可选:字体粗细
+              },
             },
             series: [
               {
@@ -638,12 +685,20 @@ export default {
     // 时间范围自定义时间
     shortcuts() {
       return [
+        {
+          text: "当天",
+          value: () => {
+            const end = new Date();
+            const start = new Date();
+            return [start, end];
+          },
+        },
         {
           text: "最近7天",
           value: () => {
             const end = new Date();
             const start = new Date();
-            start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
+            start.setTime(start.getTime() - 3600 * 1000 * 24 * 6);
             return [start, end];
           },
         },
@@ -652,7 +707,7 @@ export default {
           value: () => {
             const end = new Date();
             const start = new Date();
-            start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
+            start.setTime(start.getTime() - 3600 * 1000 * 24 * 29);
             return [start, end];
           },
         },
@@ -661,7 +716,7 @@ export default {
           value: () => {
             const end = new Date();
             const start = new Date();
-            start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
+            start.setTime(start.getTime() - 3600 * 1000 * 24 * 89);
             return [start, end];
           },
         },
@@ -670,7 +725,7 @@ export default {
           value: () => {
             const end = new Date();
             const start = new Date();
-            start.setTime(start.getTime() - 3600 * 1000 * 24 * 365);
+            start.setTime(start.getTime() - 3600 * 1000 * 24 * 364);
             return [start, end];
           },
         },