Преглед изворни кода

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

# Conflicts:
#	src/api/appCenter.js
#	src/store/index.js
#	src/views/rwgl/Index.vue
DESKTOP-6LTVLN7\Liumouren пре 2 недеља
родитељ
комит
e4af98b02c

+ 31 - 13
src/api/appCenter.js

@@ -1,19 +1,16 @@
-import {
-    postform,
-    postBody
-} from '../utils/request'
+import { postform, postBody } from "../utils/request";
 //获得数据列表接口
 const getDmsDataList = (params) => {
-    return postform(systemConfig.dmsDataProxy + "/content/selectContentList", params)
-}
+    return postform(systemConfig.dmsDataProxy + "/content/selectContentList", params);
+};
 //获得类型接口
 const getDmsCNameAType = (params) => {
-    return postform(systemConfig.dmsDataProxy + "/category/selectByCNameAType", params)
-}
+    return postform(systemConfig.dmsDataProxy + "/category/selectByCNameAType", params);
+};
 //获得标签多选框接口
 const getDmsSName = (params) => {
-    return postform(systemConfig.dmsDataProxy + "/select/getSelectBySName", params)
-}
+    return postform(systemConfig.dmsDataProxy + "/select/getSelectBySName", params);
+};
 //根据模型id查询模型详情接口
 const getModelById = (params) => {
     return postform(systemConfig.dmsDataProxy + "/model/getModelById", params)
@@ -28,7 +25,26 @@ const getContentById = (params) => {
 }
 // 获取运行管理页面数据(params:{nowTimes:[],lastTimes:[]})
 const getAllYxglDatas = (params) => {
-    return postBody(systemConfig.baseServicerPath + '/OperationManagementController/getAllYxglDatas', params);
+    return postBody(
+        systemConfig.baseServicerPath + "/OperationManagementController/getAllYxglDatas",
+        params
+    );
+};
+
+// 获取所有服务数据(params:{nowTimes:[]})
+const downFileAllServiceDatas = (params) => {
+    return postBody(
+        systemConfig.baseServicerPath + "/OperationManagementController/downFileAllServiceDatas",
+        params
+    );
+};
+
+// 根据时间查询服务调用详情(params:{nowTimes:[]})
+const getServiceDataByDate = (params) => {
+    return postBody(
+        systemConfig.baseServicerPath + "/OperationManagementController/getServiceDataByDate",
+        params
+    );
 }
 
 export default {
@@ -38,5 +54,7 @@ export default {
     updateContent,
     getModelById,
     getContentById,
-    getAllYxglDatas
-}
+    getAllYxglDatas,
+    downFileAllServiceDatas,
+    getServiceDataByDate
+};

+ 3 - 3
src/components/yxgl/table.vue

@@ -16,9 +16,9 @@
     >
       <!-- 添加序号列 -->
       <el-table-column type="index" label="" width="100" align="center" />
-      <el-table-column prop="c_path_comment" label="服务名称" />
-      <el-table-column prop="service_type" label="类别" width="600" />
-      <el-table-column prop="c_count" label="调用次数" width="280" />
+      <el-table-column prop="path_comment" label="服务名称" />
+      <el-table-column prop="type" label="类别" width="600" />
+      <el-table-column prop="count" label="调用次数" width="280" />
     </el-table>
     <!-- <div class="table_pagination">
       <el-pagination

+ 9 - 9
src/store/index.js

@@ -8,19 +8,19 @@ export default createStore({
     userState: false,
     userInfo: null,
     // DMS字典,系统app.vue初始化一次之后,后续直接全局$getDmsTypes可调用,传入字典cName和index,返回对应字典数据
-    DMSTypes: ["appstatus","applevel"],
-    // appstatus: 应用状态
+    DMSTypes: ["appstatus", "yzt_task_type", "applevel"],
+    // appstatus: 应用状态;yzt_task_type: 任务类型
     DmsTypesMap: localStorage.getItem("DmsTypesMap") ? JSON.parse(localStorage.getItem("DmsTypesMap")) : {},
     activeMenu: sessionStorage.getItem('activeMenu') ? parseInt(sessionStorage.getItem('activeMenu')) : 1, // 初始化为1或具体的菜单项ID
     menuList: [
-      { id:1,path: "/", label: "首页" },
-      { id:2,path: "/sksjgl", label: "时空数据管理" },
+      { id: 1, path: "/", label: "首页" },
+      { id: 2, path: "/sksjgl", label: "时空数据管理" },
       // { id:3,path: "/skmh/scene", label: "二维GIS引擎"},
-      { id:4,path: "/skmh", label: "时空门户" },
-      { id:5,path: "/wgn", label: "微功能" },
-      { id:6,path: "/yygl", label: "应用管理" },
-      { id:7,path: "/yxgl", label: "运行管理" },
-      { id:8,path: "/taskManger", label: "任务管理" }
+      { id: 4, path: "/skmh", label: "时空门户" },
+      { id: 5, path: "/wgn", label: "微功能" },
+      { id: 6, path: "/yygl", label: "应用管理" },
+      { id: 7, path: "/yxgl", label: "运行管理" },
+      { id: 8, path: "/taskManger", label: "任务管理" }
     ],
     sksjgl: {},
     skmh: {},

+ 1 - 1
src/utils/request.js

@@ -153,7 +153,7 @@ function postBody(url, data) {
         'Content-Type': 'application/json;'
       }
     };
-    if (url.indexOf('downloadFile') != -1) {
+    if (url.indexOf('downloadFile') != -1 || url.indexOf('downFileAllServiceDatas') != -1) {
       params.responseType = 'blob';
     }
     service(params).then(res => {

+ 72 - 6
src/views/Wgn.vue

@@ -15,6 +15,12 @@
           两大核心能力,所有功能均以标准化服务接口形式对外提供(支持第三方委办、上层应用系统调用),同时在系统内部集成可视化操作界面,实现
           “计算 - 分析 - 展示” 闭环。
         </div>
+        <div class="server_title_text_btu">
+          <!-- 先打开弹窗,然后上传文件保存信息到DMS的任务表,同时发送任务到微功能子系统,微功能子系统处理完成后,更新任务状态 -->
+          <el-button type="primary" round plain size="large" @click="createTask"
+            >大批量数据处理任务<el-icon><Position /></el-icon
+          ></el-button>
+        </div>
       </div>
     </div>
     <div class="server_list_box">
@@ -125,11 +131,51 @@
           </div>
         </template>
       </el-dialog>
+      <!-- 创建任务的表单弹窗 -->
+      <el-dialog
+        title="创建任务"
+        v-model="showTaskFrom"
+        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_task_name">
+            <el-input v-model="column.from.c_task_name" placeholder="请输入任务名称" />
+          </el-form-item>
+          <el-form-item label="任务描述" prop="c_task_description">
+            <el-input
+              type="textarea"
+              v-model="column.from.c_task_description"
+              placeholder="请输入任务描述"
+            />
+          </el-form-item>
+          <!-- 下拉框选择任务类型 -->
+          <el-form-item label="任务类型" prop="c_task_type">
+            <el-select v-model="column.from.c_task_type" placeholder="请选择任务类型">
+              <el-option
+                v-for="(name, index) in $store.state.DmsTypesMap['yzt_task_type']"
+                :key="index"
+                :label="name"
+                :value="index"
+              />
+            </el-select>
+          </el-form-item>
+        </el-form>
+        <template #footer>
+          <div class="dialog-footer">
+            <el-button @click="showTaskFrom = false">取消</el-button>
+            <el-button type="primary" @click="handleTaskSubmit">确定</el-button>
+          </div>
+        </template>
+      </el-dialog>
     </div>
   </div>
 </template>
 
 <script>
+import { ElNotification } from "element-plus";
 import wgn from "@/api/wgn";
 import api from "@/api/content";
 export default {
@@ -144,6 +190,8 @@ export default {
       dmsDataProxy: "",
       // 是否显示申请使用微功能服务的表单弹窗
       showFrom: false,
+      // 是否显示创建任务的表单弹窗
+      showTaskFrom: false,
       // 申请使用微功能服务的表单验证规则
       rules: {
         c_application_name: [
@@ -232,21 +280,24 @@ export default {
           .then((res) => {
             if (res.code === 200) {
               this.dmsServerList = res.content.data;
-              this.$message({
+              ElNotification.success({
+                title: "成功",
                 message: "搜索到" + this.dmsServerList.length + "条微功能服务",
-                type: "success",
+                offset: 80,
               });
             } else {
-              this.$message({
+              ElNotification.error({
+                title: "失败",
                 message: "搜索到0条微功能服务",
-                type: "warning",
+                offset: 80,
               });
             }
           })
           .catch((e) => {
-            this.$message({
+            ElNotification.error({
+              title: "失败",
               message: "搜索微功能服务失败" + e,
-              type: "error",
+              offset: 80,
             });
           });
       }, 0);
@@ -262,6 +313,15 @@ export default {
       this.column.from.c_interface_path = item.c_url;
       this.showFrom = true;
     },
+    // 创建任务
+    createTask() {
+      // 打开弹窗,显示任务创建表单
+      this.showTaskFrom = true;
+    },
+    // 提交任务创建表单
+    handleTaskSubmit() {
+      let that = this;
+    },
     // 提交申请使用微功能服务表单
     handleApplySubmit() {
       let that = this;
@@ -359,6 +419,12 @@ export default {
     margin-top: 77px;
     font-size: 22px;
   }
+  &_btu {
+    margin-top: 77px;
+    font-size: 22px;
+    letter-spacing: 0.2rem;
+    color: #4095e5;
+  }
 }
 .anchor_box {
   background: #ffffff32;

+ 494 - 434
src/views/rwgl/Index.vue

@@ -1,333 +1,403 @@
 <template>
-    <div class="blue-background">
-        <div class="lighter-container">
-            <div class="left-row">
-                <div>
-                    <div>状态:</div>
-                    <el-tag size="large" :effect="focusTaskStatus.includes('all') ? 'dark' : ''" type="primary"
-                        @click="changeTaskStatus()">
-                        全部
-                    </el-tag>
-                    <template v-for="status in taskStatus" :key="status.index">
-                        <el-tag size="large" :effect="focusTaskStatus.includes(status.index) ? 'dark' : ''"
-                            type="primary" @click="changeTaskStatus(status)">
-                            {{ status.name }}
-                        </el-tag>
-                    </template>
-                </div>
-                <div>
-                    <div>类别:</div>
-                    <el-tag size="large" :effect="focusTaskType.includes('all') ? 'dark' : ''" type="primary"
-                        @click="changeTaskType()">
-                        全部
-                    </el-tag>
-                    <template v-for="type in taskType" :key="type.index">
-                        <el-tag size="large" :effect="focusTaskType.includes(type.index) ? 'dark' : ''" type="primary"
-                            @click="changeTaskType(type)">
-                            {{ type.name }}
-                        </el-tag>
-                    </template>
-                </div>
-            </div>
-            <div class="row">
-                <el-input class="searcher" v-model="searcher" placeholder="请输入任务名称相关关键字" />
-                <el-button type="primary" @click="pullTaskData(1)">搜索</el-button>
-                <el-button type="primary" @click="reset(), pullTaskData(1)">重置</el-button>
-            </div>
+  <div class="blue-background">
+    <div class="lighter-container">
+      <div class="left-row">
+        <div>
+          <div>状态:</div>
+          <el-tag
+            size="large"
+            :effect="focusTaskStatus.includes('all') ? 'dark' : ''"
+            type="primary"
+            @click="changeTaskStatus()"
+          >
+            全部
+          </el-tag>
+          <template v-for="status in taskStatus" :key="status.index">
+            <el-tag
+              size="large"
+              :effect="focusTaskStatus.includes(status.index) ? 'dark' : ''"
+              type="primary"
+              @click="changeTaskStatus(status)"
+            >
+              {{ status.name }}
+            </el-tag>
+          </template>
         </div>
-        <div class="lighter-container">
-            查询到{{ taskNum }}条任务
-            <el-table table-layout="fixed" row-key="main_id" :data="taskData" class="table">
-                <el-table-column prop="main_c_name" label="名称" />
-                <el-table-column prop="main_c_user_name" label="用户" />
-                <el-table-column prop="main_c_state" label="类型">
-                    <template #default="scope">
-                        <el-tag effect="dark" v-show="getType(scope.row.main_c_type) != null" disable-transitions>{{
-                            getType(scope.row.main_c_type)?.name ?? '' }}
-                        </el-tag>
-                    </template>
-                </el-table-column>
-                <el-table-column prop="main_c_state" label="状态">
-                    <template #default="scope">
-                        <el-tag effect="dark" v-show="getStatus(scope.row.main_c_state)!=null" :type="statusStaticInfo[scope.row.main_c_state]?.tagType ?? ''"
-                            disable-transitions>{{
-                                getStatus(scope.row.main_c_state)?.name ?? '' }}</el-tag>
-                    </template>
-                </el-table-column>
-                <el-table-column prop="main_c_start_time" label="任务开始时间">
-                    <template #default="scope">
-                        {{ timeFormatter(scope.row.main_c_start_time) }}
-                    </template>
-                </el-table-column>
-                <el-table-column prop="main_c_end_time" label="任务结束时间">
-                    <template #default="scope">
-                        {{ timeFormatter(scope.row.main_c_end_time) }}
-                    </template>
-                </el-table-column>
-                <el-table-column prop="main_c_file_name" label="结果">
-                    <template #default="scope">
-                        <span class="link" v-if="scope.row.main_c_file != null && scope.row.main_c_file_name != null"
-                            @click="downloadWithBlob(scope.row.main_c_file, scope.row.main_c_file_name)">
-                            {{ scope.row.main_c_file_name }}
-                        </span>
-                    </template>
-                </el-table-column>
-                <el-table-column label="操作" width="360">
-                    <template #default="scope">
-                        <el-button type="primary" @click="() => { dialog = true; focusTask = scope.row }">
-                            查看详情
-                        </el-button>
-                        <template v-if="scope.row.main_c_file != null && scope.row.main_c_file_name != null">
-                            <el-button type="primary"
-                                @click="downloadWithBlob(scope.row.main_c_file, scope.row.main_c_file_name)">
-                                下载结果
-                            </el-button>
-                            <el-button type="primary" @click="preView(scope.row.main_c_file)">
-                                预览结果
-                            </el-button>
-                        </template>
-                    </template>
-
-                </el-table-column>
-            </el-table>
-            <div class="between-row">
-                <div><!--empty div--></div>
-                <el-pagination layout="prev, pager, next" :total="taskNum" @change="page => pullTaskData(page)" />
-            </div>
+        <div>
+          <div>类别:</div>
+          <el-tag
+            size="large"
+            :effect="focusTaskType.includes('all') ? 'dark' : ''"
+            type="primary"
+            @click="changeTaskType()"
+          >
+            全部
+          </el-tag>
+          <template v-for="type in taskType" :key="type.index">
+            <el-tag
+              size="large"
+              :effect="focusTaskType.includes(type.index) ? 'dark' : ''"
+              type="primary"
+              @click="changeTaskType(type)"
+            >
+              {{ type.name }}
+            </el-tag>
+          </template>
         </div>
-        <el-dialog v-model="dialog" :show-close="true" width="750">
-            <template #header>
-                <div class="my-header">
-                    <span class="second-title">{{ focusTask.main_c_name }}</span>
-                </div>
+      </div>
+      <div class="row">
+        <el-input
+          class="searcher"
+          v-model="searcher"
+          placeholder="请输入任务名称相关关键字"
+        />
+        <el-button type="primary" @click="pullTaskData(1)">搜索</el-button>
+        <el-button type="primary" @click="reset(), pullTaskData(1)">重置</el-button>
+      </div>
+    </div>
+    <div class="lighter-container">
+      查询到{{ taskNum }}条任务
+      <el-table table-layout="fixed" row-key="main_id" :data="taskData" class="table">
+        <el-table-column prop="main_c_name" label="名称" />
+        <el-table-column prop="main_c_user_name" label="用户" />
+        <el-table-column prop="main_c_state" label="类型">
+          <template #default="scope">
+            <el-tag
+              effect="dark"
+              v-show="getType(scope.row.main_c_type) != null"
+              disable-transitions
+              >{{ getType(scope.row.main_c_type)?.name ?? "" }}
+            </el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column prop="main_c_state" label="状态">
+          <template #default="scope">
+            <el-tag
+              effect="dark"
+              v-show="getStatus(scope.row.main_c_state) != null"
+              :type="statusStaticInfo[scope.row.main_c_state]?.tagType ?? ''"
+              disable-transitions
+              >{{ getStatus(scope.row.main_c_state)?.name ?? "" }}</el-tag
+            >
+          </template>
+        </el-table-column>
+        <el-table-column prop="main_c_start_time" label="任务开始时间">
+          <template #default="scope">
+            {{ timeFormatter(scope.row.main_c_start_time) }}
+          </template>
+        </el-table-column>
+        <el-table-column prop="main_c_end_time" label="任务结束时间">
+          <template #default="scope">
+            {{ timeFormatter(scope.row.main_c_end_time) }}
+          </template>
+        </el-table-column>
+        <el-table-column prop="main_c_file_name" label="结果">
+          <template #default="scope">
+            <span
+              class="link"
+              v-if="scope.row.main_c_file != null && scope.row.main_c_file_name != null"
+              @click="downloadWithBlob(scope.row.main_c_file, scope.row.main_c_file_name)"
+            >
+              {{ scope.row.main_c_file_name }}
+            </span>
+          </template>
+        </el-table-column>
+        <el-table-column label="操作" width="360">
+          <template #default="scope">
+            <el-button
+              type="primary"
+              @click="
+                () => {
+                  dialog = true;
+                  focusTask = scope.row;
+                }
+              "
+            >
+              查看详情
+            </el-button>
+            <template
+              v-if="scope.row.main_c_file != null && scope.row.main_c_file_name != null"
+            >
+              <el-button
+                type="primary"
+                @click="
+                  downloadWithBlob(scope.row.main_c_file, scope.row.main_c_file_name)
+                "
+              >
+                下载结果
+              </el-button>
+              <el-button type="primary" @click="preView(scope.row.main_c_file)">
+                预览结果
+              </el-button>
             </template>
-            <el-descriptions class="margin-top" label-width="128" :column="1" border>
-                <el-descriptions-item label="任务名称">
-                    {{ focusTask.main_c_name }}
-                </el-descriptions-item>
-                <el-descriptions-item label="任务描述">
-                    {{ focusTask.main_c_comment }}
-                </el-descriptions-item>
-                <el-descriptions-item label="任务类型">
-                    <el-tag effect="dark" v-show="getType(focusTask.main_c_type) != null" disable-transitions>{{
-                            getType(focusTask.main_c_type)?.name ?? '' }}
-                        </el-tag>
-                </el-descriptions-item>
-                <el-descriptions-item label="用户名">
-                    {{ focusTask.main_c_user_name }}
-                </el-descriptions-item>
-                <el-descriptions-item label="用户id">
-                    {{ focusTask.main_c_user_id }}
-                </el-descriptions-item>
-                <el-descriptions-item label="状态">
-                    <el-tag effect="dark" :type="statusStaticInfo[focusTask.main_c_state]?.tagType ?? ''"
-                        disable-transitions>{{
-                            getStatus(focusTask.main_c_state)?.name ?? '' }}
-                    </el-tag>
-                </el-descriptions-item>
-                <el-descriptions-item label="任务开始时间">
-                    {{ timeFormatter(focusTask.main_c_start_time) }}
-                </el-descriptions-item>
-                <el-descriptions-item label="任务结束时间">
-                    {{ timeFormatter(focusTask.main_c_end_time) }}
-                </el-descriptions-item>
-                <el-descriptions-item label="结果文件">
-                    {{ focusTask.main_c_file_name }}
-
-                    <template v-if="focusTask.main_c_file != null && focusTask.main_c_file_name != null">
-                        <el-button type="primary" size="small"
-                            @click="downloadWithBlob(focusTask.main_c_file, focusTask.main_c_file_name)">
-                            下载结果
-                        </el-button>
-                        <el-button type="primary" size="small" @click="preView(focusTask.main_c_file)">
-                            预览结果
-                        </el-button>
-                    </template>
-                </el-descriptions-item>
-                <el-descriptions-item label="原始数据">
-                    <template v-if="focusTask.main_c_source_file_name != null && focusTask.main_c_source_file != null">
-                        {{ focusTask.main_c_source_file_name }}
-                        <br />
-                    </template>
-                    <template v-if="focusTask.main_c_source_data != null">
-                        <div class="hide-scrollbar long-text">
-
-                            {{ truncateText(focusTask.main_c_source_data, 10000) }}
-                        </div>
-                    </template>
-                </el-descriptions-item>
-            </el-descriptions>
-        </el-dialog>
+          </template>
+        </el-table-column>
+      </el-table>
+      <div class="between-row">
+        <div><!--empty div--></div>
+        <el-pagination
+          layout="prev, pager, next"
+          :total="taskNum"
+          @change="(page) => pullTaskData(page)"
+        />
+      </div>
     </div>
+    <el-dialog v-model="dialog" :show-close="true" width="750">
+      <template #header>
+        <div class="my-header">
+          <span class="second-title">{{ focusTask.main_c_name }}</span>
+        </div>
+      </template>
+      <el-descriptions class="margin-top" label-width="128" :column="1" border>
+        <el-descriptions-item label="任务名称">
+          {{ focusTask.main_c_name }}
+        </el-descriptions-item>
+        <el-descriptions-item label="任务描述">
+          {{ focusTask.main_c_comment }}
+        </el-descriptions-item>
+        <el-descriptions-item label="任务类型">
+          <el-tag
+            effect="dark"
+            v-show="getType(focusTask.main_c_type) != null"
+            disable-transitions
+            >{{ getType(focusTask.main_c_type)?.name ?? "" }}
+          </el-tag>
+        </el-descriptions-item>
+        <el-descriptions-item label="用户名">
+          {{ focusTask.main_c_user_name }}
+        </el-descriptions-item>
+        <el-descriptions-item label="用户id">
+          {{ focusTask.main_c_user_id }}
+        </el-descriptions-item>
+        <el-descriptions-item label="状态">
+          <el-tag
+            effect="dark"
+            :type="statusStaticInfo[focusTask.main_c_state]?.tagType ?? ''"
+            disable-transitions
+            >{{ getStatus(focusTask.main_c_state)?.name ?? "" }}
+          </el-tag>
+        </el-descriptions-item>
+        <el-descriptions-item label="任务开始时间">
+          {{ timeFormatter(focusTask.main_c_start_time) }}
+        </el-descriptions-item>
+        <el-descriptions-item label="任务结束时间">
+          {{ timeFormatter(focusTask.main_c_end_time) }}
+        </el-descriptions-item>
+        <el-descriptions-item label="结果文件">
+          {{ focusTask.main_c_file_name }}
+
+          <template
+            v-if="focusTask.main_c_file != null && focusTask.main_c_file_name != null"
+          >
+            <el-button
+              type="primary"
+              size="small"
+              @click="downloadWithBlob(focusTask.main_c_file, focusTask.main_c_file_name)"
+            >
+              下载结果
+            </el-button>
+            <el-button
+              type="primary"
+              size="small"
+              @click="preView(focusTask.main_c_file)"
+            >
+              预览结果
+            </el-button>
+          </template>
+        </el-descriptions-item>
+        <el-descriptions-item label="原始数据">
+          <template
+            v-if="
+              focusTask.main_c_source_file_name != null &&
+              focusTask.main_c_source_file != null
+            "
+          >
+            {{ focusTask.main_c_source_file_name }}
+            <br />
+          </template>
+          <template v-if="focusTask.main_c_source_data != null">
+            <div class="hide-scrollbar long-text">
+              {{ truncateText(focusTask.main_c_source_data, 10000) }}
+            </div>
+          </template>
+        </el-descriptions-item>
+      </el-descriptions>
+    </el-dialog>
+  </div>
 </template>
 
 <script>
-import { getTasks, getCName } from '@/api/rwgl';
+import { getTasks, getCName } from "@/api/rwgl";
 
 export default {
-    data() {
-        return {
-            searcher: "",
-            taskStatus: [],
-            focusTaskStatus: ["all"],
-            statusStaticInfo: {
-                0: {
-                    tagType: "primary"
-                },
-                1: {
-                    tagType: "primary"
-                },
-                2: {
-                    tagType: "success"
-                },
-                3: {
-                    tagType: "danger"
-                },
-            },
-            taskType: [],
-            focusTaskType: ["all"],
-            taskData: [],
-            taskNum: 0,
-            focusTask: {},
-            dialog: false,
-            page: 1
-        }
-    },
-    mounted() {
-        this.pullTaskStatus()
-        this.pullTaskType()
-        this.pullTaskData(1)
-    },
-    methods: {
-        async pullTaskStatus() {
-            this.taskStatus = (await getCName("task_status")).sort((a, b) => a.index - b.index)
-        },
-        changeTaskStatus(status) {
-            if (status == null) {
-                this.focusTaskStatus = ["all"]
-            } else {
-                let set = new Set(this.focusTaskStatus)
-                set.delete("all")
-                let index = status.index
-                if (this.focusTaskStatus.includes(index)) {
-                    set.delete(index)
-                } else {
-                    set.add(index)
-                }
-                this.focusTaskStatus = Array.from(set)
-            }
-            // if(this.taskStatus.length==this.focusTaskStatus.length){
-            //     this.focusTaskStatus = ["all"]
-            // }
-        },
-        getCheckedStatus() {
-            if (this.focusTaskStatus.includes("all")) {
-                return null
-            } else {
-                return this.focusTaskStatus
-            }
-        },
-        getStatus(index) {
-            for (let i = 0; i < this.taskStatus.length; i++) {
-                const e = this.taskStatus[i];
-                if (e.index == index) {
-                    return e;
-                }
-            }
-        },
-        async pullTaskType() {
-            this.taskType = (await getCName("yzt_task_type")).sort((a, b) => a.index - b.index)
-        },
-        changeTaskType(types) {
-            if (types == null) {
-                this.focusTaskType = ["all"]
-            } else {
-                let set = new Set(this.focusTaskType)
-                set.delete("all")
-                let index = types.index
-                if (this.focusTaskType.includes(index)) {
-                    set.delete(index)
-                } else {
-                    set.add(index)
-                }
-                this.focusTaskType = Array.from(set)
-            }
-        },
-        getCheckedType() {
-            if (this.focusTaskType.includes("all")) {
-                return null
-            } else {
-                return this.focusTaskType
-            }
-        },
-        getType(index) {
-            for (let i = 0; i < this.taskType.length; i++) {
-                const e = this.taskType[i];
-                if (e.index == index) {
-                    return e;
-                }
-            }
-        },
-        async pullTaskData(page) {
-            if (page != null) this.page = page
-            let res = await getTasks(this.page, 10, this.searcher, this.getCheckedStatus(), this.getCheckedType())
-            this.taskNum = res.count
-            this.taskData = res.data
-        },
-        timeFormatter(time) {
-            if (time == null) return;
-
-            let date = new Date(time)
-
-            return date.toLocaleString()
+  data() {
+    return {
+      searcher: "",
+      taskStatus: [],
+      focusTaskStatus: ["all"],
+      statusStaticInfo: {
+        0: {
+          tagType: "primary",
         },
-        async downloadWithBlob(url, filename) {
-            try {
-                const response = await fetch(systemConfig.dmsDataProxy + url);
-                const blob = await response.blob();
-                const blobUrl = window.URL.createObjectURL(blob);
-
-                const link = document.createElement('a');
-                link.href = blobUrl;
-                link.download = filename || 'file';
-                link.click();
-
-                // 清理URL对象
-                window.URL.revokeObjectURL(blobUrl);
-            } catch (error) {
-                console.error('下载失败:', error);
-            }
+        1: {
+          tagType: "primary",
         },
-        reset() {
-            this.focusTaskStatus = ["all"]
-            this.searcher = ""
+        2: {
+          tagType: "success",
         },
-        preView(url) {
-            window.open("fileView?url=" + systemConfig.dmsDataProxy + url, '_blank')
+        3: {
+          tagType: "danger",
         },
-        truncateText(text, maxLength = 40) {
-            if (typeof text !== 'string' || text.length <= maxLength) {
-                return text;
-            }
-            return text.substring(0, maxLength) + '…';
+      },
+      taskType: [],
+      focusTaskType: ["all"],
+      taskData: [],
+      taskNum: 0,
+      focusTask: {},
+      dialog: false,
+      page: 1,
+    };
+  },
+  mounted() {
+    this.pullTaskStatus();
+    this.pullTaskType();
+    this.pullTaskData(1);
+  },
+  methods: {
+    async pullTaskStatus() {
+      this.taskStatus = (await getCName("task_status")).sort((a, b) => a.index - b.index);
+    },
+    changeTaskStatus(status) {
+      if (status == null) {
+        this.focusTaskStatus = ["all"];
+      } else {
+        let set = new Set(this.focusTaskStatus);
+        set.delete("all");
+        let index = status.index;
+        if (this.focusTaskStatus.includes(index)) {
+          set.delete(index);
+        } else {
+          set.add(index);
+        }
+        this.focusTaskStatus = Array.from(set);
+      }
+      // if(this.taskStatus.length==this.focusTaskStatus.length){
+      //     this.focusTaskStatus = ["all"]
+      // }
+    },
+    getCheckedStatus() {
+      if (this.focusTaskStatus.includes("all")) {
+        return null;
+      } else {
+        return this.focusTaskStatus;
+      }
+    },
+    getStatus(index) {
+      for (let i = 0; i < this.taskStatus.length; i++) {
+        const e = this.taskStatus[i];
+        if (e.index == index) {
+          return e;
+        }
+      }
+    },
+    async pullTaskType() {
+      this.taskType = (await getCName("yzt_task_type")).sort((a, b) => a.index - b.index);
+    },
+    changeTaskType(types) {
+      if (types == null) {
+        this.focusTaskType = ["all"];
+      } else {
+        let set = new Set(this.focusTaskType);
+        set.delete("all");
+        let index = types.index;
+        if (this.focusTaskType.includes(index)) {
+          set.delete(index);
+        } else {
+          set.add(index);
         }
+        this.focusTaskType = Array.from(set);
+      }
+    },
+    getCheckedType() {
+      if (this.focusTaskType.includes("all")) {
+        return null;
+      } else {
+        return this.focusTaskType;
+      }
+    },
+    getType(index) {
+      for (let i = 0; i < this.taskType.length; i++) {
+        const e = this.taskType[i];
+        if (e.index == index) {
+          return e;
+        }
+      }
+    },
+    async pullTaskData(page) {
+      if (page != null) this.page = page;
+      let res = await getTasks(
+        this.page,
+        10,
+        this.searcher,
+        this.getCheckedStatus(),
+        this.getCheckedType()
+      );
+      this.taskNum = res.count;
+      this.taskData = res.data;
+    },
+    timeFormatter(time) {
+      if (time == null) return;
 
-    }
-}
+      let date = new Date(time);
+
+      return date.toLocaleString();
+    },
+    async downloadWithBlob(url, filename) {
+      try {
+        const response = await fetch(systemConfig.dmsDataProxy + url);
+        const blob = await response.blob();
+        const blobUrl = window.URL.createObjectURL(blob);
+
+        const link = document.createElement("a");
+        link.href = blobUrl;
+        link.download = filename || "file";
+        link.click();
+
+        // 清理URL对象
+        window.URL.revokeObjectURL(blobUrl);
+      } catch (error) {
+        console.error("下载失败:", error);
+      }
+    },
+    reset() {
+      this.focusTaskStatus = ["all"];
+      this.searcher = "";
+    },
+    preView(url) {
+      window.open("fileView?url=" + systemConfig.dmsDataProxy + url, "_blank");
+    },
+    truncateText(text, maxLength = 40) {
+      if (typeof text !== "string" || text.length <= maxLength) {
+        return text;
+      }
+      return text.substring(0, maxLength) + "…";
+    },
+  },
+};
 </script>
 
 <style lang="less" scoped>
 * {
-    --el-table-bg-color: #eeeeee0b;
-    /* 表格背景 */
-    --el-table-header-bg-color: #eeeeee0b;
-    /* 表头背景 */
-    --el-table-tr-bg-color: #eeeeee0b;
-    /* 行背景 */
-    --el-table-row-hover-bg-color: #eeeeee0b;
-    /* 行悬浮背景 */
-    --el-table-header-text-color: #ededed;
-    /* 表头文字颜色 */
+  --el-table-bg-color: #eeeeee0b;
+  /* 表格背景 */
+  --el-table-header-bg-color: #eeeeee0b;
+  /* 表头背景 */
+  --el-table-tr-bg-color: #eeeeee0b;
+  /* 行背景 */
+  --el-table-row-hover-bg-color: #eeeeee0b;
+  /* 行悬浮背景 */
+  --el-table-header-text-color: #ededed;
+  /* 表头文字颜色 */
 }
 
 .font,
@@ -338,34 +408,34 @@ export default {
 .third-title,
 .strong-data,
 link {
-    color: #fff;
+  color: #fff;
 }
 
 .hide-scrollbar {
-    -ms-overflow-style: none;
-    /* IE和Edge */
-    scrollbar-width: none;
-    /* Firefox */
+  -ms-overflow-style: none;
+  /* IE和Edge */
+  scrollbar-width: none;
+  /* Firefox */
 }
 
 .hide-scrollbar::-webkit-scrollbar {
-    display: none;
-    /* Chrome, Safari和Opera */
+  display: none;
+  /* Chrome, Safari和Opera */
 }
 
 .long-text {
-    width: 100%;
-    height: 200px;
-    overflow: scroll;
+  width: 100%;
+  height: 200px;
+  overflow: scroll;
 }
 
 .icon {
-    color: #fff;
-    fill: currentColor;
+  color: #fff;
+  fill: currentColor;
 }
 
 .middle {
-    text-align: center;
+  text-align: center;
 }
 
 .darkblue-background,
@@ -373,208 +443,198 @@ link {
 .bluedark-background,
 .blue-background,
 .image-background {
-    padding-top: 40px;
-    padding-bottom: 40px;
-    margin-left: 0;
-    padding-left: 90px;
-    padding-right: 90px;
-    min-height: 600px;
+  padding-top: 40px;
+  padding-bottom: 40px;
+  margin-left: 0;
+  padding-left: 90px;
+  padding-right: 90px;
+  min-height: 600px;
 }
 
 .darkblue-background {
-    background: linear-gradient(to bottom,
-            #02060c 0%,
-            #0f3460 40%,
-            #0f3460 100%);
+  background: linear-gradient(to bottom, #02060c 0%, #0f3460 40%, #0f3460 100%);
 }
 
 .dark-background {
-    background: #0a0a08
+  background: #0a0a08;
 }
 
 .blue-background,
 body {
-    background: #0f3460
+  background: #0f3460;
 }
 
 .bluedark-background {
-    background: linear-gradient(to bottom,
-            #0f3460 0%,
-            #0f3460 60%,
-            #02060c 100%);
+  background: linear-gradient(to bottom, #0f3460 0%, #0f3460 60%, #02060c 100%);
 }
 
 .image-background {
-    background-repeat: no-repeat;
-    background-position: center;
-    background-size: 100% auto;
+  background-repeat: no-repeat;
+  background-position: center;
+  background-size: 100% auto;
 }
 
 .lighter-container {
-    background-color: #eeeeee0b;
-    padding: 10px;
-    margin: 15px;
-    vertical-align: middle;
-    border-radius: 3%;
+  background-color: #eeeeee0b;
+  padding: 10px;
+  margin: 15px;
+  vertical-align: middle;
+  border-radius: 3%;
 }
 
 .lightblue-container {
-    border-radius: 3%;
-    padding: 10px;
-    margin: 15px;
-    background: linear-gradient(to bottom,
-            #215476 0%,
-            #28638b 66%,
-            #337aac 100%);
-    font-size: 20px;
-
-     .third-title {
-        font-size: 28px;
-        padding: 0;
-    } 
+  border-radius: 3%;
+  padding: 10px;
+  margin: 15px;
+  background: linear-gradient(to bottom, #215476 0%, #28638b 66%, #337aac 100%);
+  font-size: 20px;
+
+  .third-title {
+    font-size: 28px;
+    padding: 0;
+  }
 }
 
 .middle-container {
-    display: flex !important;
-    justify-content: center;
-    flex-direction: column;
-    padding: 0;
-    align-items: stretch;
+  display: flex !important;
+  justify-content: center;
+  flex-direction: column;
+  padding: 0;
+  align-items: stretch;
 }
 
 .row,
 .warp-row,
 .between-row,
 .left-row {
-    display: flex !important;
-    justify-content: space-around;
-    padding: 0;
-    align-items: stretch;
+  display: flex !important;
+  justify-content: space-around;
+  padding: 0;
+  align-items: stretch;
 }
 
 .warp-row {
-    flex-wrap: wrap;
+  flex-wrap: wrap;
 }
 
 .between-row {
-    justify-content: space-between;
+  justify-content: space-between;
 }
 
-.left-row{
-    justify-content: flex-start;
+.left-row {
+  justify-content: flex-start;
 }
-.left-row>*{
-    margin-right: 15px;
+.left-row > * {
+  margin-right: 15px;
 }
 
 .col {
-    display: flex !important;
-    justify-content: space-around;
-    flex-direction: column;
+  display: flex !important;
+  justify-content: space-around;
+  flex-direction: column;
 }
 
 .dense-col {
-    display: flex !important;
-    justify-content: center;
-    flex-direction: column;
+  display: flex !important;
+  justify-content: center;
+  flex-direction: column;
 }
 
 .start-reverse-col {
-    display: flex !important;
-    justify-content: start;
-    flex-direction: column-reverse;
+  display: flex !important;
+  justify-content: start;
+  flex-direction: column-reverse;
 }
 
-.dense-col>*,
-.start-reverse-col>* {
-    margin: 10px;
+.dense-col > *,
+.start-reverse-col > * {
+  margin: 10px;
 }
 
 .grid-2x2 {
-    display: grid !important;
-    grid-template-columns: 1fr 1fr;
-    gap: 12px;
-    width: 100%;
-    height: 80%;
+  display: grid !important;
+  grid-template-columns: 1fr 1fr;
+  gap: 12px;
+  width: 100%;
+  height: 80%;
 }
 
 .strong-data {
-    font-size: 32px;
-    font-weight: bold;
-    text-align: center;
+  font-size: 32px;
+  font-weight: bold;
+  text-align: center;
 }
 
 .title {
-    font-size: 36px;
-    margin-top: 10px;
-    text-align: center;
-    font-weight: bold;
+  font-size: 36px;
+  margin-top: 10px;
+  text-align: center;
+  font-weight: bold;
 }
 
 .super-title {
-    font-size: 44px;
-    margin-top: 10px;
-    text-align: center;
-    font-weight: bold;
-
+  font-size: 44px;
+  margin-top: 10px;
+  text-align: center;
+  font-weight: bold;
 }
 
 .title-sub {
-    font-size: 16px;
-    margin-top: 10px;
-    color: rgb(192, 192, 192);
-    text-align: center;
+  font-size: 16px;
+  margin-top: 10px;
+  color: rgb(192, 192, 192);
+  text-align: center;
 }
 
 .second-title {
-    font-size: 20px;
-    margin-top: 10px;
-    padding-left: 10px;
-    border-left: 2px solid #3498db;
-    font-weight: bold;
+  font-size: 20px;
+  margin-top: 10px;
+  padding-left: 10px;
+  border-left: 2px solid #3498db;
+  font-weight: bold;
 }
 
 .third-title {
-    font-size: 18px;
-    margin-top: 10px;
-    padding-left: 10px;
-    display: flex;
-    font-weight: bold;
+  font-size: 18px;
+  margin-top: 10px;
+  padding-left: 10px;
+  display: flex;
+  font-weight: bold;
 }
 
 .link {
-    font-weight: bold;
-    /* 字体加粗 */
-    text-decoration: underline;
-    /* 下划线 */
-    cursor: pointer;
-    /* 鼠标悬浮时变为手型(可点击形式) */
+  font-weight: bold;
+  /* 字体加粗 */
+  text-decoration: underline;
+  /* 下划线 */
+  cursor: pointer;
+  /* 鼠标悬浮时变为手型(可点击形式) */
 }
 
 .searcher {
-    background-color: #334155;
-    margin-right: 15px;
+  background-color: #334155;
+  margin-right: 15px;
 }
 
 .blue {
-    color: #3498db;
+  color: #3498db;
 }
 
 .grey {
-    color: rgb(192, 192, 192);
+  color: rgb(192, 192, 192);
 }
 
 .lightgrey {
-    color: rgb(229, 229, 229);
+  color: rgb(229, 229, 229);
 }
 
 #echart1 {
-    width: 100%;
-    height: 450px;
+  width: 100%;
+  height: 450px;
 }
 
 .container {
-    width: 1920px;
-    margin: 0 auto;
+  width: 1920px;
+  margin: 0 auto;
 }
-</style>
+</style>

+ 253 - 58
src/views/yxgl/StatisticalAnalysis.vue

@@ -1,10 +1,8 @@
 <template>
-  <div class="mainBox">
+  <div class="mainBox" v-loading="getDataStatus">
     <!-- 搜索区域 -->
     <div class="searchBox">
       <div>
-        <!-- 添加一个按钮触发事件 -->
-        <!-- <el-button type="primary" @click="playTTS()">请求音频</el-button> -->
         <!-- 对比时间:
         <el-date-picker
           v-model="lastTimes"
@@ -48,10 +46,12 @@
     <div class="bigCard">
       <div class="bigCard_title">服务类信息统计</div>
       <div class="tools">
-        <el-button>
+        <el-button @click="downFileAllServiceDatas">
+          <!-- 这个要查询查询时间范围内的所有服务数据 -->
           <el-icon><Upload /></el-icon> 导出数据
         </el-button>
-        <el-button type="primary">
+        <el-button type="primary" @click="showDetailReport">
+          <!-- 这个直接弹窗展示所有的服务调用数据,而不是下载 -->
           <el-icon><TrendCharts /></el-icon>
           详细报告
         </el-button>
@@ -68,6 +68,62 @@
         <Table title="服务调用TOP10" :tableData="tableDatas" />
       </div>
     </div>
+    <!-- 服务调用详情弹窗 -->
+    <el-dialog
+      v-model="showServerDetailReport"
+      width="60%"
+      :close-on-click-modal="false"
+      :close-on-press-escape="false"
+      :show-close="true"
+      title="服务调用详情"
+    >
+      <div style="width: 100%; position: relative; padding-bottom: 20px">
+        <!-- 过滤条件,全字段(除了调用时间)下拉框选择 -->
+        <div style="width: 100%; margin-bottom: 10px">
+          <!-- 支持筛选条件清空 -->
+          <el-select
+            style="width: 200px; margin-right: 10px"
+            v-for="(value, key, index) in selectOptions"
+            :key="key + index"
+            v-model="selectedModel[key]"
+            @change="changeSelectModel"
+            :placeholder="'请选择' + selectKeyName[key]"
+            filterable
+            clearable
+          >
+            <el-option v-for="item in value" :key="item" :label="item" :value="item" />
+          </el-select>
+          <!-- 重置按钮 -->
+          <el-button type="primary" @click="resetSelectModel">重置</el-button>
+        </div>
+        <el-table
+          :data="showServerData"
+          style="width: 100%"
+          height="500px"
+          border
+          fit
+          highlight-current-row
+        >
+          <el-table-column prop="application" label="应用名称" />
+          <el-table-column prop="path_comment" label="服务名称" />
+          <el-table-column prop="unit" label="委办单位" width="200" />
+          <el-table-column prop="type" label="服务类别" width="120" />
+          <el-table-column prop="date" label="调用时间" width="120" />
+        </el-table>
+        <div class="table_pagination">
+          <el-pagination
+            v-model:current-page="currentPage"
+            v-model:page-size="pageSize"
+            :page-sizes="[100, 200, 300, 400]"
+            background
+            layout="total, sizes, prev, pager, next, jumper"
+            :total="serverData.length"
+            @size-change="handleSizeChange"
+            @current-change="handleCurrentChange"
+          />
+        </div>
+      </div>
+    </el-dialog>
     <!-- 委办信息统计 -->
     <div class="bigCard">
       <div class="bigCard_title">委办信息统计</div>
@@ -156,7 +212,6 @@ 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: "",
@@ -167,10 +222,42 @@ export default {
   },
   data() {
     return {
+      // 获取数据状态
+      getDataStatus: false,
       // 比较的时间范围(默认60天到30天前,主要跟nowTimes有关系)
       lastTimes: [],
       // 当前选中的时间范围
       nowTimes: [],
+      // 服务调用详情弹窗是否显示
+      showServerDetailReport: false,
+      // 服务调用详情数据
+      serverData: [],
+      // 展示的详细数据(能根据时间和字段模糊筛选)
+      showServerData: [],
+      // 筛选条件下拉框选项
+      selectOptions: {
+        application: [],
+        path_comment: [],
+        unit: [],
+        type: [],
+      },
+      selectKeyName: {
+        application: "应用名称",
+        path_comment: "接口注释",
+        unit: "单位",
+        type: "数据类型",
+      },
+      // 筛选条件下拉框选中的值
+      selectedModel: {
+        application: "",
+        path_comment: "",
+        unit: "",
+        type: "",
+      },
+      // 分页大小
+      pageSize: 100,
+      // 当前页码
+      currentPage: 1,
       TopCardDatas: [
         {
           name: "委办总数",
@@ -243,37 +330,74 @@ export default {
     });
   },
   methods: {
-    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);
-          };
+    handleSizeChange() {
+      let searchDatas = this.serverData.filter((item) => {
+        return (
+          (!this.selectedModel.application ||
+            item.application === this.selectedModel.application) &&
+          (!this.selectedModel.path_comment ||
+            item.path_comment === this.selectedModel.path_comment) &&
+          (!this.selectedModel.unit || item.unit === this.selectedModel.unit) &&
+          (!this.selectedModel.type || item.type === this.selectedModel.type)
+        );
+      });
+      this.showServerData = searchDatas.slice(
+        (this.currentPage - 1) * this.pageSize,
+        this.currentPage * this.pageSize
+      );
+      // 遍历筛选条件下拉框选项,更新每个选项的数组
+      for (let key in this.selectOptions) {
+        this.selectOptions[key] = [
+          ...new Set(this.serverData.map((item) => (item[key] ? item[key] : "未知"))),
+        ];
+      }
+      // 更新分页组件数据
+      this.total = searchDatas.length;
+      this.showServerDetailReport = true;
+    },
+    handleCurrentChange() {
+      this.handleSizeChange();
+    },
+    // 筛选条件下拉框选中值改变时,触发的事件
+    changeSelectModel() {
+      // 重置当前页码为第一页
+      this.currentPage = 1;
+      // 处理分页数据
+      this.handleSizeChange();
+    },
+    // 重置筛选条件下拉框选中的值
+    resetSelectModel() {
+      for (let key in this.selectedModel) {
+        this.selectedModel[key] = "";
+      }
+      this.handleSizeChange();
+    },
+    // 打开弹窗,渲染table列表,展示查询时间的所有数据详情
+    showDetailReport() {
+      // 要先请求,然后时间排序一下。
+      appCenter
+        .getServiceDataByDate({
+          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 23:59:59"),
+          ],
         })
-        .catch((error) => {
-          console.error("TTS请求失败:", error);
+        .then((res) => {
+          if (res && res.code == 200) {
+            if (res.content && res.content.length > 0) {
+              this.serverData = res.content;
+              this.handleSizeChange();
+            } else {
+              this.$message({
+                message: "暂无数据",
+                type: "warning",
+              });
+            }
+          }
         });
     },
     initChart() {
+      this.getDataStatus = true;
       // 获取运行管理页面数据
       appCenter
         .getAllYxglDatas({
@@ -285,7 +409,13 @@ export default {
         })
         .then((res) => {
           if (res && res.code == 200) {
-            this.TopCardDatas = res.content.TopCardDatas;
+            if (
+              res.content.TopCardDatas &&
+              typeof res.content.TopCardDatas === "object"
+            ) {
+              this.TopCardDatas = res.content.TopCardDatas;
+            }
+
             this.dataToOption(
               "服务调用趋势",
               "line",
@@ -293,7 +423,7 @@ export default {
               {
                 legend: { data: ["调用次数"] },
                 xData: [],
-                xKey: "key",
+                xKey: "date",
                 xFormart: "YYYY-MM-DD",
                 yAxis: {
                   type: "value",
@@ -301,7 +431,7 @@ export default {
                   axisLine: { lineStyle: { color: "#42a5f5" } }, // 区分样式
                 },
                 yData: {
-                  key: "value",
+                  key: "count",
                   name: "调用次数",
                   color: "#42a5f5",
                   data: [],
@@ -309,24 +439,52 @@ export default {
                 },
               }
             );
+            let serviceCountType = [];
+            serviceCountType = res.content.serviceCountType;
+            if (res.content.serviceCountType && res.content.serviceCountType.length > 0) {
+              serviceCountType.forEach((item) => {
+                if (!item.type) {
+                  item.type = "未知";
+                }
+              });
+            }
             // 初始化服务类别分布,这个地方需要先根据serviceType进行groupBy统计调用次数
-            this.dataToOption("服务类别分布", "pie", [...res.content.serviceCountType], {
-              pieKey: { value: "value", name: "key" },
+            this.dataToOption("服务类别分布", "pie", serviceCountType, {
+              pieKey: { value: "count", name: "type" },
               pieData: [],
             });
 
-            // 服务调用TOP10《cPathComment+cUnit,调用次数》
+            // 服务调用TOP10
             let serviceDatas = [];
             serviceDatas = res.content.serviceCountTop;
+            if (serviceDatas && serviceDatas.length > 0) {
+              serviceDatas.forEach((item) => {
+                if (!item.path_comment) {
+                  item.path_comment = "未知";
+                }
+                if (!item.type) {
+                  item.type = "未知";
+                }
+              });
+            }
             // 排序
-            serviceDatas.sort((a, b) => b.c_count - a.c_count);
+            serviceDatas.sort((a, b) => b.count - a.count);
             this.initTableDatas(serviceDatas.slice(0, 10));
-
+            let serviceCountUnit = [];
+            serviceCountUnit = res.content.serviceCountUnit;
+            if (serviceCountUnit && serviceCountUnit.length > 0) {
+              serviceCountUnit.forEach((item) => {
+                if (!item.unit) {
+                  item.unit = "未知";
+                }
+              });
+            }
             // 委办分布
-            this.dataToOption("委办分布", "pie", [...res.content.serviceCountUnit], {
-              pieKey: { value: "value", name: "key" },
+            this.dataToOption("委办分布", "pie", serviceCountUnit, {
+              pieKey: { value: "count", name: "unit" },
               pieData: [],
               legend: {
+                show: false,
                 bottom: 10,
               },
               radius: "60%",
@@ -335,16 +493,11 @@ export default {
               label: {},
             });
 
-            // 先清洗一下res.content.serviceCountUnitTrend
-            let serviceCountUnitTrend = [];
-            serviceCountUnitTrend = res.content.serviceCountUnitTrend;
+            // 先同步一下legend
             let serviceCountUnitTrendLegend = [];
-            let itemData = serviceCountUnitTrend[0];
-            for (let key in itemData) {
-              if (key !== "key") {
-                serviceCountUnitTrendLegend.push(key);
-              }
-            }
+            serviceCountUnit.forEach((item) => {
+              serviceCountUnitTrendLegend.push(item.unit);
+            });
             this.dataToOption(
               "委办活跃度趋势",
               "line",
@@ -352,7 +505,7 @@ export default {
               {
                 legend: { data: serviceCountUnitTrendLegend },
                 xData: [],
-                xKey: "key",
+                xKey: "date",
                 xFormart: "YYYY-MM-DD",
                 yAxis: {
                   type: "value",
@@ -365,14 +518,19 @@ export default {
             let serviceDatas2 = [];
             serviceDatas2 = res.content.serviceCountApplicationTop;
             // 排序
-            serviceDatas2.sort((a, b) => a.c_count - b.c_count);
+            serviceDatas2.sort((a, b) => b.count - a.count);
+            let forData = serviceDatas2.slice(0, 10);
+            let showApplicationTopDatas = [];
+            for (let i = forData.length - 1; i >= 0; i--) {
+              showApplicationTopDatas.push(forData[i]);
+            }
             // 用户部门分布
-            this.dataToOption("热点应用TOP10排名", "bar", serviceDatas2.slice(0, 10), {
+            this.dataToOption("热点应用TOP10排名", "bar", showApplicationTopDatas, {
               showLegend: false,
               xData: [],
-              xKey: "c_application",
+              xKey: "application",
               yData: {
-                key: "c_count",
+                key: "count",
                 name: "调用次数",
                 color: "#42a5f5",
                 data: [],
@@ -393,8 +551,16 @@ export default {
               });
             }
 
-            // console.log("getAllYxglDatas", res);
+            console.log("getAllYxglDatas", res);
           }
+          this.getDataStatus = false;
+        })
+        .catch((error) => {
+          this.getDataStatus = false;
+          this.$message({
+            type: "error",
+            message: "服务器忙碌,请稍后重试!",
+          });
         });
       // 应用状态分布,cloumnId:1659
       appCenter
@@ -440,6 +606,30 @@ export default {
 
       this.dataToOption("数据质量评分", "radar", null, null);
     },
+    // 导出所选时间范围内的所有服务数据
+    downFileAllServiceDatas() {
+      appCenter.downFileAllServiceDatas({ nowTimes: this.nowTimes }).then((res) => {
+        const blob = res; // 响应体是 Blob 类型
+        if (!blob) {
+          that.$message.error("下载失败:文件流为空");
+          reject("文件流为空");
+          return;
+        }
+        if (!(blob instanceof Blob) || blob.size === 0) {
+          this.$message.error("文件流解析失败,无法生成下载链接");
+          return;
+        }
+        const url = window.URL.createObjectURL(blob); // 将 Blob 转为临时 URL
+        const link = document.createElement("a");
+        link.href = url;
+        link.download = "服务信息统计.xlsx"; // 设置下载文件名
+        link.style.display = "none";
+        document.body.appendChild(link);
+        link.click(); // 触发点击下载
+        document.body.removeChild(link);
+        window.URL.revokeObjectURL(url); // 销毁临时 URL,避免内存泄漏
+      });
+    },
     /**
      * 数据转换为图表选项
      * @param title 图表标题
@@ -852,5 +1042,10 @@ export default {
   .demo-date-picker .block:last-child {
     border-bottom: none;
   }
+  .table_pagination {
+    position: absolute;
+    bottom: 20px;
+    right: 20px;
+  }
 }
 </style>