Hua 2 månader sedan
förälder
incheckning
e3018fec6f

+ 15 - 0
ruoyi-ui/src/api/service/info.js

@@ -335,4 +335,19 @@ export function delMdfile(id) {
     url: '/md/file/' + id,
     method: 'delete'
   })
+}
+export function downloadFile(query) {
+  return request({
+    url: "/data/set/API/download",
+    method: "get",
+    params: query,
+  });
+}
+export function downDir(query) {
+  return request({
+    responseType: 'blob',
+    url: "/common/download/resource",
+    method: "get",
+    params: query,
+  });
 }

+ 21 - 0
ruoyi-ui/src/api/service/log.js

@@ -7,4 +7,25 @@ export function getServiceLogList(data) {
         method: 'get',
         params: data
     });
+}
+export function getMdLogList(data) {
+    return request({
+        url: '/model/run/log/list',
+        method: 'get',
+        params: data
+    });
+}
+export function getMdStatusSum(data) {
+    return request({
+        url: '/service/log/statis/mdStatusSum',
+        method: 'get',
+        params: data
+    });
+}
+export function getMdAllList(data) {
+    return request({
+        url: '/service/log/statis/mdAllList',
+        method: 'get',
+        params: data
+    });
 }

+ 3 - 3
ruoyi-ui/src/views/register/componentReg/index.vue

@@ -708,11 +708,11 @@
                 </el-table-column>
               </el-table>
             </el-tab-pane>
-            <el-tab-pane label="版本信息" style="" :key="activeTabKey">
+            <el-tab-pane label="参数文件" style="" :key="activeTabKey">
               <div style="display: flex;height:100%;">
                 <div style="width: 65%;background-color: ;height:100%;">
                   <div style="font-size: 20px;">
-                    历史版本信息
+                    历史参数信息
                   </div>
                   <el-table 
                      v-loading="loadVer"
@@ -751,7 +751,7 @@
                 </div>
                 <div style="width: 35%;background-color: ;height:100%;">
                   <div style="font-size: 20px;">
-                    上传新的版本文件
+                    上传新的参数文件
                   </div>
                   <el-upload
                     ref="uploadRefVer"

+ 3 - 8
ruoyi-ui/src/views/register/componentReg/peizhi.vue

@@ -75,12 +75,7 @@
         <el-table-column prop="address" label="操作" width="100">
             <template #default="scope">
                 <div style="display: flex;justify-content: space-between;width: 100%;">
-                    <!-- <el-button type="primary" @click="showEdit(scope.row)" size="mini" text style="margin-left: 0%;">编辑</el-button> -->
-                    <!-- <el-button type="danger" text size="mini" style="margin-left: -5%;" @click="handleDelete(scope.row)">注销</el-button> -->
-                    <!-- <el-button @click="showDe(scope.row)" type="primary" text size="mini" style="margin-left: -5%;">查看</el-button> -->
                     <el-button @click="showPei(scope.row)" type="warning" text size="mini" style="margin-left: -5%;">配置</el-button>
-                    <!-- <el-button type="danger" @click="delModel(scope.row)" text size="mini" style="margin-left: -5%;">删除</el-button>
-                    <el-button v-if="scope.row.audit === null||scope.row.audit === '2'||scope.row.audit === ''" type="info" @click="shenhe(scope.row)" text size="mini" style="margin-left: -5%;">审核申请</el-button> -->
                 </div>
             </template>
         </el-table-column>
@@ -708,11 +703,11 @@
                 </el-table-column>
               </el-table>
             </el-tab-pane>
-            <el-tab-pane label="版本信息" style="" :key="activeTabKey">
+            <el-tab-pane label="参数文件" style="" :key="activeTabKey">
               <div style="display: flex;height:100%;">
                 <div style="width: 65%;background-color: ;height:100%;">
                   <div style="font-size: 20px;">
-                    历史版本信息
+                    历史参数信息
                   </div>
                   <el-table 
                      v-loading="loadVer"
@@ -751,7 +746,7 @@
                 </div>
                 <div style="width: 35%;background-color: ;height:100%;">
                   <div style="font-size: 20px;">
-                    上传新的版本文件
+                    上传新的参数文件
                   </div>
                   <el-upload
                     ref="uploadRefVer"

+ 114 - 17
ruoyi-ui/src/views/register/modelData/dataJiDe.vue

@@ -82,6 +82,8 @@
         <el-table-column prop="address" label="操作" width="250">
             <template #default="scope">
                 <div style="width: 100%;">
+                    <el-button type="primary" @click="download(scope.row,scope.$index)" size="mini" text style="margin-left: 0%;">下载</el-button>
+                    <el-button v-if="scope.row.dcType==='FILE'" type="success" @click="showUpload(scope.row,scope.$index)" size="mini" text style="margin-left: 0%;">储存</el-button>
                     <el-button type="danger" @click="delCan(scope.row,scope.$index)" size="mini" text style="margin-left: 0%;">删除</el-button>
                 </div>
             </template>
@@ -215,24 +217,26 @@
             </span>
           </template>
         </el-dialog>
-        <el-dialog @close="clearFromLev" title="" v-model="dialogVisibleLevel" width="30%" destroy-on-close :key="tableKey">
-          <el-table 
-          style="margin-top: 1%;width: 98%;"
-          :data="tableDataLog" 
-          :cell-style="{ textAlign: 'center',padding:'2px 0' }"
-          :header-cell-style="{ textAlign: 'center'}"
-          :row-style="{ height: heightAll*0.01+'px',fontSize: '16px',textAlign:'center'  }"
-          border >
-              <el-table-column prop="createBy" label="审核人员名称">
-              </el-table-column>
-              <el-table-column prop="createTime" label="审核时间">
-              </el-table-column>
-              <el-table-column prop="remark" label="审核备注" show-overflow-tooltip>
-              </el-table-column>
-          </el-table>
+        <el-dialog @close="clearFromLev" title="储存文件" v-model="dialogVisibleLevel" width="30%" destroy-on-close :key="tableKey">
+          <el-upload
+              ref="uploadRef"
+              :limit="1"
+              accept=".xlsx, .xls"
+              :headers="upload.headers"
+              :on-change="handleChange"
+              :file-list="fileList"
+              :action="upload.url + '?file=' + upload.updateSupport"
+              :on-progress="handleFileUploadProgress"
+              :on-success="handleFileSuccess"
+              :auto-upload="false"
+              drag
+          >
+              <el-icon class="el-icon--upload"><upload-filled /></el-icon>
+              <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
+          </el-upload>
           <template #footer>
               <span class="dialog-footer">
-                <el-button type="primary" size="mini" @click="dialogVisibleLevel = false">确定</el-button>
+                <el-button type="primary" size="mini" @click="saveUpload">确定</el-button>
             </span>
           </template>
         </el-dialog>
@@ -243,12 +247,14 @@
 import {getCatalog} from "@/api/service/catalog";
 import { Plus,Search,Filter,Promotion,Check  } from '@element-plus/icons-vue'
 import { reactive } from 'vue'
-import { modelTreeSelect,getSerDe,addService,shenheLog,addServiceParam,delService,addTree,deTree,getServiceInfo,testService,modelSetRela,delGuan } from "@/api/service/info";
+import { modelTreeSelect,modelSetRela,delGuan,downloadFile,downDir } from "@/api/service/info";
+import { getDataJiFile,dataJiFile } from "@/api/register/regCom.js";
 import { ref, onMounted, onUnmounted, nextTick,onBeforeMount } from 'vue';
 import { cateTree,dataSetList} from "@/api/register/regCom.js";
 import JsonViewer from 'vue-json-viewer'
 import 'vue-json-viewer/style.css' 
 import  JsonEditorVue from 'json-editor-vue3'
+import { getToken } from "@/utils/auth";
 import { cloneDeep } from 'lodash'
 import { useClipboard } from "@vueuse/core";
 
@@ -267,6 +273,22 @@ const publish = ref()
 const auditRemark = ref()
 const show1Lev = ref(true)
 const inputNode =ref('')
+const fileList = ref([])
+const uploadRef = ref(null);
+const upload = reactive({
+  // 是否显示弹出层(用户导入)
+  open: false,
+  // 弹出层标题(用户导入)
+  title: "",
+  // 是否禁用上传
+  isUploading: false,
+  // 是否更新已经存在的用户数据
+  updateSupport: '',
+  // 设置上传的请求头部 
+  headers: { Authorization: "Bearer " + getToken() },
+  // 上传的地址
+  url: import.meta.env.VITE_APP_BASE_API + "/common/upload"
+});
 const dialogVisibleJi = ref(false)
 const isEdit = ref(true)
 const dataReturn = ref('')
@@ -467,6 +489,23 @@ const parShenhe = ref({})
 function handleSelectionChange(selection){
   parSelJi.value = selection
 }
+function saveUpload(){
+  proxy.$refs["uploadRef"].submit();
+}
+async function handleFileSuccess(response, file, fileList){
+  var par = {
+    dcCode:parRow.value.dcCode,
+    filePath:response.fileName,
+    originalFilename:response.originalFilename
+  }
+  await dataJiFile(par).then(res=>{
+    if(res.code===200){
+      proxy.$modal.msgSuccess("操作");
+      dialogVisibleLevel.value = false
+      fileList.value = []
+    }
+  })
+};
 function filterModelNodes(nodes) {
   if (!Array.isArray(nodes)) return [];
   
@@ -489,6 +528,11 @@ function filterModelNodes(nodes) {
   }
   return result;
 }
+const parRow = ref()
+function showUpload(row){
+  parRow.value = row
+  dialogVisibleLevel.value = true
+}
 function clearAdd(){
   tableDataJi.value = [
   ]
@@ -501,6 +545,59 @@ function clearFromLev(){
     itemNotes:'',
   }
 }
+function download(row){
+  proxy.$modal.confirm('是否确认下载?').then(function () {
+    if(row.dcType==='API'){
+      var par = {
+        dcCode:row.dcCode
+      }
+      downloadFile(par).then(res=>{
+        const blob = new Blob([res.data], { type: 'text/plain' });
+    // 创建临时URL
+        const url = URL.createObjectURL(blob);
+        // 创建a标签
+        const link = document.createElement('a');
+        link.href = url;
+        // 设置下载的文件名
+        link.download = '';
+        // 将a标签添加到文档中
+        document.body.appendChild(link);
+        // 触发点击下载
+        link.click();
+        // 下载完成后移除a标签
+        document.body.removeChild(link);
+        // 释放URL对象
+        URL.revokeObjectURL(url);
+      })
+    }
+      if(row.dcType==='FILE'){
+        getDataJiFile(row.dcCode).then(res1=>{
+          var par  ={
+            resource:res1.data.filePath
+          }
+          downDir(par).then(res=>{
+            const blob = new Blob([res], { type: 'blob' });
+            // 创建临时URL
+            const url = URL.createObjectURL(blob);
+            // 创建a标签
+            const link = document.createElement('a');
+            link.href = url;
+            // 设置下载的文件名
+            link.download = res1.data.originalFilename;
+            // 将a标签添加到文档中
+            document.body.appendChild(link);
+            // 触发点击下载
+            link.click();
+            // 下载完成后移除a标签
+            document.body.removeChild(link);
+            // 释放URL对象
+            URL.revokeObjectURL(url);
+          })
+        })
+      }
+    
+  })
+}
 function delCan(row,index){
   proxy.$modal.confirm('是否确认删除?').then(function () {
     var par = {

+ 1 - 1
ruoyi-ui/src/views/register/modelData/metaData.vue

@@ -420,7 +420,7 @@ function getTree(){
   getDataSourceList().then(res=>{
     data.value = res.rows
     data.value.forEach(item=>{
-      item.label = item.dsDbname
+      item.label = item.dsTitle
       item.value = item.dsCode
     })
   })

+ 1 - 1
ruoyi-ui/src/views/service/info/editModel.vue

@@ -1124,7 +1124,7 @@ function showJian(row){
   var par ={
     pageNum: pageNumJian.value,
     pageSize: 20,
-    srvId:row.srvId
+    serId:row.srvId
   }
   getServiceLogList(par)
       .then((r) => {

+ 444 - 5
ruoyi-ui/src/views/service/log/index.vue

@@ -1,6 +1,94 @@
 <template>
-  <div class="app-container">
-    <el-row>
+  <div style="width: 98%;margin-left: 1%;">
+    <el-tabs
+      v-model="activeName"
+      type="card"
+      class="demo-tabs"
+      
+      @tab-click="handleClick"
+    >
+      <el-tab-pane label="模型事件" name="first">
+        <el-form ref="formRef" :inline="true" :model="queryParams1">
+          <el-form-item label="运行事件">
+            <el-select
+               v-model="queryParams1.event"
+               placeholder=""
+               clearable
+               style="width: 150px"
+            >
+               <el-option
+                  v-for="dict in model_run_log_event"
+                  :key="dict.value"
+                  :label="dict.label"
+                  :value="dict.value"
+               />
+            </el-select>
+          </el-form-item>
+          <el-form-item label="模型名称">
+            <el-input v-model="queryParams1.mdName" style="width: 150px"></el-input>
+          </el-form-item>
+          <el-form-item label="时间">
+            <el-date-picker v-model="queryParams1.time" type="daterange" range-separator="至"
+                            start-placeholder="开始时间" end-placeholder="结束时间" 
+                            value-format="YYYY-MM-DD">
+            </el-date-picker>
+          </el-form-item>
+          <el-form-item>
+            <el-button type="primary" @click="getList1" icon="Search">搜索</el-button>
+          </el-form-item>
+        </el-form>
+        <div style="display: flex;width: 100%;">
+          <div style="width: 60%;">
+            <el-table
+              stripe
+              style="height: 68vh;margin-top: 1%;width: 100%;"
+              :data="tableDataJian"
+              :cell-style="{ padding: '5px' }"
+              :row-style="{ fontSize: '1rem', textAlign:'center' }"
+              border>
+              <el-table-column type="index" align="center" label="序号" width="60">
+                <template #default="{ $index }">
+                  <div style="text-align: center;">{{ $index + 1 }}</div>
+                </template>
+              </el-table-column>
+              <el-table-column show-overflow-tooltip header-align="center" align="left"  prop="createBy" label="人员名称"/>
+              <el-table-column show-overflow-tooltip header-align="center" align="left"  prop="createTime" label="创建时间"/>
+              <el-table-column show-overflow-tooltip header-align="center" align="left"  prop="mdName" label="模型名称"/>
+              <el-table-column show-overflow-tooltip header-align="center" align="left"  prop="event" label="运行事件"/>
+            </el-table>
+            <div style="display: flex;">
+              <el-pagination
+                small
+                background
+                style="margin-top: 1%;margin-left: auto;display: flex;margin-right: 1%;"
+                layout="prev, pager, next"
+                :total="totalJian"
+                v-model="pageNumJian"
+                @change="fanJian"
+                class="mt-4"
+            />
+            </div>
+          </div>
+          <div style="width: 49%;margin-left: 1%;margin-top: 1%;">
+            <div>
+              过去7天模型吞吐量
+            </div>
+            <div style="height: 30vh;width: 100%;background-color: ;margin-top: 1%;" id="right1">
+
+            </div>
+            <div style="margin-top: 5%;">
+              过去7天模型错误率
+            </div>
+            <div style="height: 30vh;width: 100%;background-color: ;margin-top: 1%;" id="right2">
+
+            </div>
+          </div>
+        </div>
+        
+        
+      </el-tab-pane>
+      <el-tab-pane label="模型服务监控" name="second" style="height: 100vh;">
+        <el-row>
       <!-- 筛选条件 -->
       <el-form ref="formRef" :inline="true" :model="queryParams">
         <el-form-item label="服务名称">
@@ -23,8 +111,8 @@
     <el-row class="table_box">
       <el-table
           stripe
+          style="height: 68vh;"
           :data="tableData"
-          :height="tableHeight"
           :cell-style="{ padding: '5px' }"
           :row-style="{ fontSize: '1rem', textAlign:'center' }"
           border>
@@ -67,22 +155,31 @@
         :total="total"
         v-model:page="queryParams.pageNum"
         v-model:limit="queryParams.pageSize"
+        style="margin-top: 1%;"
         @pagination="getList"
     />
 
     <el-dialog v-model="open" title="服务日志详情" width="60%" append-to-body>
 
     </el-dialog>
+      </el-tab-pane>
+    </el-tabs>
+    
   </div>
 </template>
 <script setup>
+import * as echarts from 'echarts';
 import {onMounted, reactive, ref} from "vue";
-import {getServiceLogList} from "@/api/service/log.js";
+import {getServiceLogList,getMdLogList,getMdStatusSum,getMdAllList } from "@/api/service/log.js";
 import useClipboard from 'vue-clipboard3'
 
 const {toClipboard} = useClipboard()
 const {proxy} = getCurrentInstance();
-const tableHeight = ref(window.innerHeight - 280)
+const { model_run_log_event } = proxy.useDict("model_run_log_event");
+const tableHeight = ref(window.innerHeight - 400)
+const queryParams1 = ref({
+  time:[]
+})
 const queryParams = reactive({
   pageNum: 1,
   pageSize: 20,
@@ -93,6 +190,10 @@ const queryParams = reactive({
   sttm: "",
   entm: "",
 })
+const totalJian = ref(0)
+const tableDataJian = ref([])
+const pageNumJian = ref(1)
+const activeName = ref('first')
 const tableData = ref([])
 const total = ref(0)
 const shortcuts = ref([
@@ -139,7 +240,191 @@ async function copyParams(message) {
     proxy.$modal.msgSuccess("复制成功!");
   })
 }
+function fanJian(val){
+  pageNumJian.value = val
+  getList1()
+}
+function getList1(){
+  queryParams1.value.pageSize = 20
+  queryParams1.value.pageNum = pageNumJian.value
+  var par = {
+    pageNum:pageNumJian.value,
+    pageSize:20,
+    event:queryParams1.value.event,
+    mdName:queryParams1.value.mdName,
+    params:{
+      beginTime:queryParams1.value.time==[]?'':queryParams1.value.time[0],
+      endTime:queryParams1.value.time==[]?'':queryParams1.value.time[1],
+    }
+  }
+  getMdLogList(par).then(r=>{
+    tableDataJian.value = r.rows;
+    totalJian.value = r.total;
+    for(var i = 0;i<tableDataJian.value.length;i++){
+      for(var i1 = 0;i1<model_run_log_event.value.length;i1++){
+        if(tableDataJian.value[i].event===model_run_log_event.value[i1].value){
+          tableDataJian.value[i].event = model_run_log_event.value[i1].label
+        }
+      }
+    }
+  })
+  
+}
+function getLast7DaysRange() {
+  const end = new Date(); 
+  const start = new Date();
+  end.setDate(start.getDate() - 1);
+  start.setDate(end.getDate() - 7);
+  function formatDate(date) {
+    const year = date.getFullYear();
+    const month = String(date.getMonth() + 1).padStart(2, '0');
+    const day = String(date.getDate()).padStart(2, '0');
+    return `${year}-${month}-${day}`;
+  }
+
+  return {
+    start: formatDate(start),
+    end: formatDate(end)
+  };
+}
+function mergeModelData(data) {
+  const mergeMap = {};
+  
+  data.forEach(item => {
+    const mdName = item.mdName?.trim(); // 处理可能的空格
+    if (!mdName) return;
+    
+    if (!mergeMap[mdName]) {
+      mergeMap[mdName] = {
+        mdName: mdName,
+        mdId: item.mdId,
+        statisNum: 0,
+        statisNumErr: 0
+      };
+    }
+    
+    const current = mergeMap[mdName];
+    const statisNumValue = Number(item.statisNum) || 0;
+    
+    if (item.statusCode === '200') {
+      // statusCode为200,保留statisNum
+      current.statisNum = statisNumValue;
+    } else if (item.statusCode) {
+      // 其他statusCode,累加到statisNumErr
+      current.statisNumErr += statisNumValue;
+    }
+    
+    // 保留第一个非空的mdId
+    if (!current.mdId && item.mdId) {
+      current.mdId = item.mdId;
+    }
+  });
+  
+  return Object.values(mergeMap);
+}
+async function drawRight2(){
+  var chartDom = document.getElementById('right2');
+  var myChart = echarts.init(chartDom);
+  var option;
+  const last7Days = getLast7DaysRange();
+  var par1 = {
+    params:{
+      beginTime:last7Days.start,
+      endTime:last7Days.end,
+    }
+  }
+  var uniqueMdNames
+  var mergedData
+  var success = []
+  var error = []
+  await getMdStatusSum(par1).then(res=>{
+    uniqueMdNames = [...new Map(res.data.map(item => [item.mdName, item.mdName])).values()].filter(Boolean);
+    mergedData = mergeModelData(res.data)
+    mergedData.forEach(item=>{
+      success.push(item.statisNum)
+      error.push(item.statisNumErr)
+    })
+  })
+  option = {
+     grid: {
+      top: '15%',     // 图表距离容器顶部的距离
+      right: '5%',    // 图表距离容器右侧的距离
+      bottom: '15%',  // 图表距离容器底部的距离
+      left: '10%',    // 图表距离容器左侧的距离
+      containLabel: true  // 确保坐标轴标签在 grid 区域内
+    },
+    tooltip: {
+      trigger: 'axis',
+      axisPointer: {
+        type: 'shadow'
+      }
+    },
+    legend: {},
+    color: ['#67C23A','#F56C6C',],
+    xAxis: [
+      {
+        type: 'category',
+        data: uniqueMdNames,
+        axisLabel: {
+          interval: 0,  // 强制显示所有标签
+          rotate: -25,   // 旋转角度,正值表示顺时针旋转,负值表示逆时针旋转
+          // 可以设置文字样式,如字体大小、颜色等
+          textStyle: {
+            fontSize: 9,
+            color: '#333'
+          }
+        }
+      }
+    ],
+    yAxis: [
+      {
+        type: 'value'
+      }
+    ],
+    series: [
+      {
+        name: '成功',
+        type: 'bar',
+        stack: 'Ad',
+        emphasis: {
+          focus: 'series'
+        },
+        data: success,
+        
+      },
+      {
+        name: '失败',
+        type: 'bar',
+        stack: 'Ad',
+        emphasis: {
+          focus: 'series'
+        },
+        data: error,
+        label: {
+          show: true, // 显示标签
+          position: 'top', // 标签位置在柱子上方
+          // 自定义标签内容,formatter可以是字符串模板,也可以是回调函数
+          formatter: function(params) {
+          // 计算每个柱子占当天的总比例
+            const total = params.data + option.series[0].data[params.dataIndex];
+            const percent = ((params.data / total) * 100).toFixed(1);
+            if(params.data){
+              return params.data + `\n(${percent}%)`;
+            }
+          },
+          // 标签文本样式
+          textStyle: {
+            color: '#000', // 颜色
+            fontSize: 12
+          }
+        }
+      },
+    ]
+  };
+
+  option && myChart.setOption(option);
 
+}
 function getList() {
   getServiceLogList(queryParams)
       .then((r) => {
@@ -147,9 +432,163 @@ function getList() {
         total.value = r.total;
       });
 }
+function processModelData(data) {
+  const resultMap = {};
+  
+  data.forEach(item => {
+    const mdName = item.mdName?.trim();
+    if (!mdName) return;
+    
+    const statisNum = Number(item.statisNum) || 0;
+    
+    if (!resultMap[mdName]) {
+      // 初始化该模型的数据
+      resultMap[mdName] = {
+        mdName: mdName,
+        mdId: item.mdId || null,
+        totalStatisNum: statisNum,
+        recordCount: 1,
+        firstRecordDate: item.statisTm,
+        lastRecordDate: item.statisTm,
+        records: [item] // 可选:保留详细记录
+      };
+    } else {
+      // 更新现有模型数据
+      resultMap[mdName].totalStatisNum += statisNum;
+      resultMap[mdName].recordCount += 1;
+      
+      // 更新最新记录日期
+      if (item.statisTm && (!resultMap[mdName].lastRecordDate || item.statisTm > resultMap[mdName].lastRecordDate)) {
+        resultMap[mdName].lastRecordDate = item.statisTm;
+      }
+      
+      resultMap[mdName].records.push(item);
+    }
+  });
+  
+  // 转换为数组并排序(按统计数字降序)
+  return Object.values(resultMap)
+    .sort((a, b) => b.totalStatisNum - a.totalStatisNum);
+}
+function getDateRange(startStr, endStr) {
+    const startDate = new Date(startStr);
+    const endDate = new Date(endStr);
+    const dates = [];
+    
+    // 验证日期有效性
+    if (isNaN(startDate.getTime()) || isNaN(endDate.getTime())) {
+        throw new Error('无效的日期格式');
+    }
+    
+    if (startDate > endDate) {
+        throw new Error('开始日期不能晚于结束日期');
+    }
+    
+    // 复制开始日期对象,避免修改原日期
+    const currentDate = new Date(startDate);
+    
+    // 循环直到当前日期超过结束日期
+    while (currentDate <= endDate) {
+        // 格式化为 YYYY-MM-DD
+        const year = currentDate.getFullYear();
+        const month = String(currentDate.getMonth() + 1).padStart(2, '0');
+        const day = String(currentDate.getDate()).padStart(2, '0');
+        
+        dates.push(`${year}-${month}-${day}`);
+        
+        // 日期加一天
+        currentDate.setDate(currentDate.getDate() + 1);
+    }
+    
+    return dates;
+}
+async function drawRight1(){
+  var chartDom = document.getElementById('right1');
+  var myChart = echarts.init(chartDom);
+  var option;
+  const last7Days = getLast7DaysRange();
+  var par = {
+    params:{
+      beginTime:last7Days.start,
+      endTime:last7Days.end,
+    }
+  }
+  var x = getDateRange(last7Days.start,last7Days.end)
+  var y = []
+  await getMdAllList(par).then(res=>{
+    res.data.forEach(item=>{
+      item.value = []
+      item.lineCharts.forEach(item1=>{
+        item.value.push(item1.num)
+      })
+    })
+    res.data.forEach(item=>{
+      var par = {
+        name: item.mdName,
+        type: 'line',
+        data: item.value,
+        smooth: true
+      }
+      y.push(par)
+    })
+    console.log(res.data)
+  })
+  option = {
+     grid: {
+      top: '15%',     // 图表距离容器顶部的距离
+      right: '5%',    // 图表距离容器右侧的距离
+      bottom: '15%',  // 图表距离容器底部的距离
+      left: '10%',    // 图表距离容器左侧的距离
+      containLabel: true  // 确保坐标轴标签在 grid 区域内
+    },
+    tooltip: {
+        trigger: 'axis'
+    },
+    legend: {
+      top:'90%'
+    },
+    xAxis: {
+      splitLine: { show: false },
+      // type: 'category',
+      data: x,
+      axisLabel: {
+          interval: 0,  // 强制显示所有标签
+          rotate: -25,   // 旋转角度,正值表示顺时针旋转,负值表示逆时针旋转
+          // 可以设置文字样式,如字体大小、颜色等
+          textStyle: {
+            fontSize: 9,
+            color: '#333'
+          }
+        }
+    },
+    yAxis: {
+      type: 'value',
+      show: true,
+      splitLine: { show: false },
+      name: '单位:次', 
+      minInterval: 1, 
+      axisTick: {
+        show: true // 确保显示刻度线
+      },
+       axisLine: {
+        show: true, // 确保显示轴线
+        lineStyle: {
+          color: '#333', // 可以设置轴线的颜色,例如与文字颜色一致
+          // width: 1 // 可以设置轴线宽度,可选
+        }
+      },
+    },
+    series:y
+  };
+  
+  option && myChart.setOption(option);
 
+}
 onMounted(() => {
   getList()
+  getList1()
+  drawRight2()
+  drawRight1()
 });
 
 watch(() => queryParams.time, value => {