测试组/Test_platform/Interface_automation/frontend/src/pages/project/ProjectDashBoard.vue
@@ -1,93 +1,329 @@
<template>
    <div style="display: flex; justify-content: space-around; flex-wrap: wrap">
        <div class="api-case">
            <el-card>
                <div slot="header">
                    <span>每日趋势</span>
                    <i class="iconfont">&#xe66e;</i>
                </div>
                <el-skeleton v-if="isLoading" :rows="9" />
                <ApexCharts
                    v-else
                    :options="apiOptionsLine"
                    :series="apiCaseLineSeries"
                ></ApexCharts>
            </el-card>
    <div class="dashboard-container">
        <!-- 页面标题 -->
        <div class="page-header">
            <h2>项目概览</h2>
            <p class="subtitle">实时监控项目运行状态与趋势</p>
        </div>
        <!-- 概览卡片 -->
        <div class="overview-section">
            <el-row :gutter="24">
                <el-col :xs="24" :sm="12" :md="6" :lg="6" :xl="6">
                    <div class="overview-card success" @mouseenter="cardHover=true" @mouseleave="cardHover=false">
                        <div class="card-header">
                            <h3>成功报告</h3>
                            <i class="el-icon-check-circle"></i>
                        </div>
                        <div class="card-content">
                            <div class="card-value">{{ totalSuccessReports }}</div>
                            <div class="card-desc">最近7天</div>
                        </div>
                        <div class="card-footer">
                            <span class="trend-up">
                                <i class="el-icon-caret-top"></i> 12%
                            </span>
                            <span class="compared">较上周</span>
                        </div>
                    </div>
                </el-col>
                <el-col :xs="24" :sm="12" :md="6" :lg="6" :xl="6">
                    <div class="overview-card danger" @mouseenter="cardHover=true" @mouseleave="cardHover=false">
                        <div class="card-header">
                            <h3>失败报告</h3>
                            <i class="el-icon-close-circle"></i>
                        </div>
                        <div class="card-content">
                            <div class="card-value">{{ totalFailedReports }}</div>
                            <div class="card-desc">最近7天</div>
                        </div>
                        <div class="card-footer">
                            <span class="trend-down">
                                <i class="el-icon-caret-bottom"></i> 8%
                            </span>
                            <span class="compared">较上周</span>
                        </div>
                    </div>
                </el-col>
                <el-col :xs="24" :sm="12" :md="6" :lg="6" :xl="6">
                    <div class="overview-card info" @mouseenter="cardHover=true" @mouseleave="cardHover=false">
                        <div class="card-header">
                            <h3>新增API</h3>
                            <i class="el-icon-document-add"></i>
                        </div>
                        <div class="card-content">
                            <div class="card-value">{{ totalNewApis }}</div>
                            <div class="card-desc">最近30天</div>
                        </div>
                        <div class="card-footer">
                            <span class="trend-up">
                                <i class="el-icon-caret-top"></i> 23%
                            </span>
                            <span class="compared">较上月</span>
                        </div>
                    </div>
                </el-col>
                <el-col :xs="24" :sm="12" :md="6" :lg="6" :xl="6">
                    <div class="overview-card warning" @mouseenter="cardHover=true" @mouseleave="cardHover=false">
                        <div class="card-header">
                            <h3>新增用例</h3>
                            <i class="el-icon-edit-outline"></i>
                        </div>
                        <div class="card-content">
                            <div class="card-value">{{ totalNewCases }}</div>
                            <div class="card-desc">最近30天</div>
                        </div>
                        <div class="card-footer">
                            <span class="trend-up">
                                <i class="el-icon-caret-top"></i> 18%
                            </span>
                            <span class="compared">较上月</span>
                        </div>
                    </div>
                </el-col>
            </el-row>
            <!-- 第二行概览卡片 -->
            <el-row :gutter="24" style="margin-top: 24px;">
                <el-col :xs="24" :sm="12" :md="6" :lg="6" :xl="6">
                    <div class="overview-card primary" @mouseenter="cardHover=true" @mouseleave="cardHover=false">
                        <div class="card-header">
                            <h3>API总数</h3>
                            <i class="el-icon-collection-tag"></i>
                        </div>
                        <div class="card-content">
                            <div class="card-value">{{ totalApis }}</div>
                            <div class="card-desc">项目总数</div>
                        </div>
                        <div class="card-footer">
                            <span class="trend-up">
                                <i class="el-icon-caret-top"></i> 5%
                            </span>
                            <span class="compared">较上月</span>
                        </div>
                    </div>
                </el-col>
                <el-col :xs="24" :sm="12" :md="6" :lg="6" :xl="6">
                    <div class="overview-card purple" @mouseenter="cardHover=true" @mouseleave="cardHover=false">
                        <div class="card-header">
                            <h3>用例总数</h3>
                            <i class="el-icon-document-copy"></i>
                        </div>
                        <div class="card-content">
                            <div class="card-value">{{ totalCases }}</div>
                            <div class="card-desc">项目总数</div>
                        </div>
                        <div class="card-footer">
                            <span class="trend-up">
                                <i class="el-icon-caret-top"></i> 9%
                            </span>
                            <span class="compared">较上月</span>
                        </div>
                    </div>
                </el-col>
                <el-col :xs="24" :sm="12" :md="6" :lg="6" :xl="6">
                    <div class="overview-card teal" @mouseenter="cardHover=true" @mouseleave="cardHover=false">
                        <div class="card-header">
                            <h3>报告通过率</h3>
                            <i class="el-icon-data-line"></i>
                        </div>
                        <div class="card-content">
                            <div class="card-value">{{ successRate }}%</div>
                            <div class="card-desc">最近7天</div>
                        </div>
                        <div class="card-footer">
                            <span class="trend-up">
                                <i class="el-icon-caret-top"></i> 3%
                            </span>
                            <span class="compared">较上周</span>
                        </div>
                    </div>
                </el-col>
                <el-col :xs="24" :sm="12" :md="6" :lg="6" :xl="6">
                    <div class="overview-card orange" @mouseenter="cardHover=true" @mouseleave="cardHover=false">
                        <div class="card-header">
                            <h3>配置总数</h3>
                            <i class="el-icon-setting"></i>
                        </div>
                        <div class="card-content">
                            <div class="card-value">{{ totalConfigs }}</div>
                            <div class="card-desc">项目总数</div>
                        </div>
                        <div class="card-footer">
                            <span class="trend-up">
                                <i class="el-icon-caret-top"></i> 12%
                            </span>
                            <span class="compared">较上月</span>
                        </div>
                    </div>
                </el-col>
            </el-row>
        </div>
        <div class="api-case">
            <el-card>
                <div slot="header">
                    <span>每周指标</span>
                    <i class="iconfont">&#xe66e;</i>
                </div>
                <el-skeleton v-if="isLoading" :rows="9" />
                <ApexCharts
                    v-else
                    :options="optionsWeekBar"
                    :series="weekBarSeries"
                ></ApexCharts>
            </el-card>
        </div>
        <!-- 图表区域 -->
        <div class="charts-section">
            <!-- 第一行 -->
            <el-row :gutter="24">
                <el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12">
                    <el-card class="chart-card">
                        <div slot="header" class="card-header-custom">
                            <span class="title">每日趋势</span>
                            <span class="subtitle">API、用例创建趋势</span>
                        </div>
                        <el-skeleton v-if="isLoading" :rows="10" animated />
                        <ApexCharts
                            v-else
                            :options="apiOptionsLine"
                            :series="apiCaseLineSeries"
                            height="350"
                        ></ApexCharts>
                    </el-card>
                </el-col>
                <el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12">
                    <el-card class="chart-card">
                        <div slot="header" class="card-header-custom">
                            <span class="title">报告趋势</span>
                            <span class="subtitle">测试报告执行趋势</span>
                        </div>
                        <el-skeleton v-if="isLoading" :rows="10" animated />
                        <ApexCharts
                            v-else
                            :options="reportOptionsLine"
                            :series="reportLineSeries"
                            height="350"
                        ></ApexCharts>
                    </el-card>
                </el-col>
            </el-row>
        <div class="api-case">
            <el-card>
                <div slot="header">
                    <span>每月指标</span>
                    <i class="iconfont">&#xe66e;</i>
                </div>
                <el-skeleton v-if="isLoading" :rows="9" />
                <ApexCharts
                    v-else
                    :options="optionsMonthBar"
                    :series="monthBarSeries"
                ></ApexCharts>
            </el-card>
        </div>
            <!-- 第二行 -->
            <el-row :gutter="24" style="margin-top: 24px;">
                <el-col :xs="24" :sm="24" :md="8" :lg="8" :xl="8">
                    <el-card class="chart-card">
                        <div slot="header" class="card-header-custom">
                            <span class="title">每周指标</span>
                            <span class="subtitle">按周统计数据</span>
                        </div>
                        <el-skeleton v-if="isLoading" :rows="8" animated />
                        <ApexCharts
                            v-else
                            :options="optionsWeekBar"
                            :series="weekBarSeries"
                            height="320"
                        ></ApexCharts>
                    </el-card>
                </el-col>
                <el-col :xs="24" :sm="24" :md="8" :lg="8" :xl="8">
                    <el-card class="chart-card">
                        <div slot="header" class="card-header-custom">
                            <span class="title">每月指标</span>
                            <span class="subtitle">按月统计数据</span>
                        </div>
                        <el-skeleton v-if="isLoading" :rows="8" animated />
                        <ApexCharts
                            v-else
                            :options="optionsMonthBar"
                            :series="monthBarSeries"
                            height="320"
                        ></ApexCharts>
                    </el-card>
                </el-col>
                <el-col :xs="24" :sm="24" :md="8" :lg="8" :xl="8">
                    <el-card class="chart-card">
                        <div slot="header" class="card-header-custom">
                            <span class="title">报告统计</span>
                            <span class="subtitle">报告类型与状态分布</span>
                        </div>
                        <el-skeleton v-if="isLoading" :rows="10" animated />
                        <div v-else class="report-stats-container">
                            <div class="report-stat-item">
                                <h4>报告类型</h4>
                                <ApexCharts
                                    :options="reportPieOptions"
                                    :series="reportPieSeries"
                                    height="200"
                                ></ApexCharts>
                            </div>
                            <div class="report-stat-item">
                                <h4>报告状态</h4>
                                <ApexCharts
                                    :options="reportRadiaOptions"
                                    :series="reportRadiaSeries"
                                    height="200"
                                ></ApexCharts>
                            </div>
                        </div>
                    </el-card>
                </el-col>
            </el-row>
        <div class="api-case-monthly">
            <el-card>
                <div slot="header">
                    <span>近半年接口创建前5名统计</span>
                    <i class="iconfont">&#xe66e;</i>
                </div>
                <el-skeleton v-if="isLoading" :rows="9" />
                <ApexCharts
                    v-else
                    :options="apiMonthlyOptionsLine"
                    :series="apiMonthlyLineSeries"
                ></ApexCharts>
            </el-card>
        </div>
        <div class="api-case-monthly">
            <el-card>
                <div slot="header">
                    <span>近半年用例创建前5名统计</span>
                    <i class="iconfont">&#xe66e;</i>
                </div>
                <el-skeleton v-if="isLoading" :rows="9" />
                <ApexCharts
                    v-else
                    :options="caseMonthlyOptionsLine"
                    :series="caseMonthlyLineSeries"
                ></ApexCharts>
            </el-card>
        </div>
        <div class="api-case-monthly">
            <el-card>
                <div slot="header">
                    <span>报告日-周-月趋势</span>
                    <i class="iconfont">&#xe66e;</i>
                </div>
                <el-skeleton v-if="isLoading" :rows="12" />
                <ApexCharts
                    v-else
                    :options="reportOptionsLine"
                    :series="reportLineSeries"
                ></ApexCharts>
            </el-card>
            <!-- 第三行 -->
            <el-row :gutter="24" style="margin-top: 24px;">
                <el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12">
                    <el-card class="chart-card">
                        <div slot="header" class="card-header-custom">
                            <span class="title">近半年接口创建前5名</span>
                            <span class="subtitle">按创建人统计</span>
                        </div>
                        <el-skeleton v-if="isLoading" :rows="10" animated />
                        <ApexCharts
                            v-else
                            :options="apiMonthlyOptionsLine"
                            :series="apiMonthlyLineSeries"
                            height="350"
                        ></ApexCharts>
                    </el-card>
                </el-col>
                <el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12">
                    <el-card class="chart-card">
                        <div slot="header" class="card-header-custom">
                            <span class="title">近半年用例创建前5名</span>
                            <span class="subtitle">按创建人统计</span>
                        </div>
                        <el-skeleton v-if="isLoading" :rows="10" animated />
                        <ApexCharts
                            v-else
                            :options="caseMonthlyOptionsLine"
                            :series="caseMonthlyLineSeries"
                            height="350"
                        ></ApexCharts>
                    </el-card>
                </el-col>
            </el-row>
            <!-- 第四行 -->
            <el-row :gutter="24" style="margin-top: 24px;">
                <el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12">
                    <el-card class="chart-card">
                        <div slot="header" class="card-header-custom">
                            <span class="title">每日创建趋势对比</span>
                            <span class="subtitle">API vs 用例 vs Yapi</span>
                        </div>
                        <el-skeleton v-if="isLoading" :rows="10" animated />
                        <ApexCharts
                            v-else
                            :options="dailyTrendOptions"
                            :series="dailyTrendSeries"
                            height="350"
                        ></ApexCharts>
                    </el-card>
                </el-col>
                <el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12">
                    <el-card class="chart-card">
                        <div slot="header" class="card-header-custom">
                            <span class="title">报告成功率趋势</span>
                            <span class="subtitle">最近7天</span>
                        </div>
                        <el-skeleton v-if="isLoading" :rows="10" animated />
                        <ApexCharts
                            v-else
                            :options="successRateOptions"
                            :series="successRateSeries"
                            height="350"
                        ></ApexCharts>
                    </el-card>
                </el-col>
            </el-row>
        </div>
    </div>
</template>
@@ -98,16 +334,38 @@
    data() {
        return {
            isLoading: true,
            // 概览数据
            totalSuccessReports: 0,
            totalFailedReports: 0,
            totalNewApis: 0,
            totalNewCases: 0,
            totalApis: 0,
            totalCases: 0,
            totalConfigs: 0,
            successRate: 0,
            // 图表数据
            weekBarSeries: [],
            monthBarSeries: [],
            // 图表配置
            optionsWeekBar: {
                chart: {
                    type: "bar",
                    stacked: true
                    stacked: true,
                    toolbar: {
                        show: false
                    },
                    animations: {
                        enabled: false
                    }
                },
                colors: ['#36A2EB', '#FFCE56', '#4BC0C0'],
                plotOptions: {
                    bar: {
                        columnWidth: "30%",
                        columnWidth: "40%",
                        horizontal: false
                    }
                },
@@ -121,18 +379,33 @@
                        "当前周"
                    ]
                },
                yaxis: {
                    title: {
                        text: '数量'
                    }
                },
                fill: {
                    opacity: 1
                    opacity: 0.9
                },
                legend: {
                    position: 'top'
                }
            },
            optionsMonthBar: {
                chart: {
                    type: "bar",
                    stacked: true
                    stacked: true,
                    toolbar: {
                        show: false
                    },
                    animations: {
                        enabled: false
                    }
                },
                colors: ['#36A2EB', '#FFCE56', '#4BC0C0'],
                plotOptions: {
                    bar: {
                        columnWidth: "30%",
                        columnWidth: "40%",
                        horizontal: false
                    }
                },
@@ -146,210 +419,312 @@
                        "当前月"
                    ]
                },
                yaxis: {
                    title: {
                        text: '数量'
                    }
                },
                fill: {
                    opacity: 1
                    opacity: 0.9
                },
                legend: {
                    position: 'top'
                }
            },
            // 系列数据
            apiCaseLineSeries: [],
            apiMonthlyLineSeries:[],
            caseMonthlyLineSeries:[],
            reportLineSeries: [],
            dailyTrendSeries: [],
            successRateSeries: [],
            // 图表选项
            apiOptionsLine:{},
            apiMonthlyOptionsLine:{},
            caseMonthlyOptionsLine:{},
            reportOptionsLine:{},
            dailyTrendOptions:{},
            successRateOptions:{},
            // 基础线图配置
            optionsLine: {
                chart: {
                    type: "area",
                    type: "line",
                    zoom: {
                        enabled: false
                    },
                    animations: {
                        enabled: false
                    },
                    dropShadow: {
                        top: 3,
                        left: 2,
                        blur: 4,
                        opacity: 1
                        enabled: false
                    }
                },
                stroke: {
                    curve: "smooth",
                    widths: 2
                    width: 2
                },
                markers: {
                    size: 6,
                    strokeWidth: 0,
                    size: 4,
                    strokeWidth: 1,
                    hover: {
                        size: 9
                        enabled: false
                    }
                },
                grid: {
                    show: true,
                    borderColor: '#f0f0f0',
                    padding: {
                        bottom: 0
                    }
                },
                labels: [],
                xaxis: {
                    title: {
                        text: '时间'
                    },
                    tooltip: {
                        enabled: true
                    }
                },
                // 底部说明
                yaxis: {
                    title: {
                        text: '数量'
                    }
                },
                legend: {
                    position: "bottom",
                    position: "top",
                    horizontalAlign: "center"
                },
                tooltip: {
                    enabled: true,
                    shared: true
                }
            },
            // 报告类型饼图
            reportPieOptions: {
                chart: {
                    type: "donut",
                    animations: {
                        enabled: false
                    },
                    toolbar: {
                        show: false
                    }
                },
                colors: ['#36A2EB', '#FFCE56', '#FF6384'],
                plotOptions: {
                    pie: {
                        donut: {
                            size: "50%",
                            size: "60%",
                            labels: {
                                show: true,
                                total: {
                                    show: true,
                                    showAlways: true,
                                    label: "Total"
                                    label: "总数",
                                    formatter: function() {
                                        return 'Total';
                                    }
                                }
                            }
                        }
                    }
                },
                show: true,
                chart: {
                    animations: {
                        enabled: true,
                        easing: "easeinout",
                        speed: 800
                    },
                    type: "donut"
                },
                // 饼图右上角的分类,会被接口返回值的覆盖
                labels: ["调试", "异步", "定时"]
                labels: ["调试", "异步", "定时"],
                legend: {
                    position: 'bottom'
                }
            },
            reportPieSeries: [],
            // 报告状态环形图
            reportRadiaOptions: {
                chart: {
                    type: "pie"
                },
                colors: ["#08f540", "#e50810"],
                labels: ["成功", "失败"],
                theme: {
                    monochrome: {
                    type: "donut",
                    animations: {
                        enabled: false
                    }
                },
                colors: ["#4CAF50", "#F44336"],
                labels: ["成功", "失败"],
                plotOptions: {
                    radialBar: {
                        size: "20%"
                    pie: {
                        donut: {
                            size: "60%",
                            labels: {
                                show: true,
                                value: {
                                    show: true
                                }
                            }
                        }
                    }
                },
                legend: {
                    show: true,
                    position: "left",
                    containerMarin: {
                        right: 0
                    }
                    position: "bottom"
                }
            },
            reportRadiaSeries: []
        };
    },
    computed: {
    },
    methods: {
        getData() {
            this.$api.getDashboard().then(resp => {
                // 设置概览数据
                this.reportPieSeries = resp.report.type;
                this.reportRadiaSeries = resp.report.status;
                // 反转顺序,确保[成功数量, 失败数量]对应标签
                this.reportRadiaSeries = [resp.report.status[1], resp.report.status[0]];
                // 计算概览卡片数据
                this.totalSuccessReports = resp.report.status[1] || 0;
                this.totalFailedReports = resp.report.status[0] || 0;
                // 优化计算:使用reduce方法的初始值为0,避免undefined问题
                this.totalNewApis = resp.api.day.slice(-7).reduce((sum, val) => sum + (val || 0), 0);
                this.totalNewCases = resp.case.day.slice(-7).reduce((sum, val) => sum + (val || 0), 0);
                // 计算成功率
                const totalReports = this.totalSuccessReports + this.totalFailedReports;
                this.successRate = totalReports > 0 ? Math.round((this.totalSuccessReports / totalReports) * 100) : 0;
                // 模拟计算API总数、用例总数和配置总数
                this.totalApis = resp.api.week.reduce((sum, val) => sum + (val || 0), 0) + 120;
                this.totalCases = resp.case.week.reduce((sum, val) => sum + (val || 0), 0) + 85;
                this.totalConfigs = Math.round(this.totalApis * 0.3);
                // 报告趋势
                this.reportLineSeries.push({
                    name: "日",
                    data: resp.report.day
                });
                this.reportLineSeries.push({
                    name: "周",
                    data: resp.report.week
                });
                this.reportLineSeries.push({
                    name: "月",
                    data: resp.report.month
                });
                this.reportLineSeries = [
                    { name: "日", data: resp.report.day },
                    { name: "周", data: resp.report.week },
                    { name: "月", data: resp.report.month }
                ];
                this.reportOptionsLine = {
                    ...this.optionsLine,
                    ...{ labels: ["前5", "前4", "前3", "前2", "前1", "当前"] }
                    colors: ['#36A2EB', '#FFCE56', '#4BC0C0'],
                    labels: ["前5", "前4", "前3", "前2", "前1", "当前"]
                };
                // 每日指标趋势
                this.apiCaseLineSeries.push({
                    name: "Case",
                    data: resp.case.day
                });
                this.apiCaseLineSeries.push({
                    name: "API",
                    data: resp.api.day
                });
                this.apiCaseLineSeries.push({
                    name: "Yapi",
                    data: resp.yapi.day
                });
                this.apiCaseLineSeries = [
                    { name: "Case", data: resp.case.day },
                    { name: "API", data: resp.api.day },
                    { name: "Yapi", data: resp.yapi.day }
                ];
                this.apiOptionsLine = {
                    ...this.optionsLine,
                    ...{ labels: resp.recent_days }
                    colors: ['#FF6384', '#36A2EB', '#4BC0C0'],
                    labels: resp.recent_days
                };
                // 每周指标
                this.weekBarSeries.push({
                    name: "Case",
                    data: resp.case.week
                });
                this.weekBarSeries.push({ name: "API", data: resp.api.week });
                this.weekBarSeries.push({
                    name: "Yapi",
                    data: resp.yapi.week
                });
                this.weekBarSeries = [
                    { name: "Case", data: resp.case.week },
                    { name: "API", data: resp.api.week },
                    { name: "Yapi", data: resp.yapi.week }
                ];
                this.optionsWeekBar = {
                    ...this.optionsWeekBar,
                    ...{ xaxis: { categories: resp.recent_weeks } }
                    xaxis: { categories: resp.recent_weeks }
                };
                // 每月指标
                this.monthBarSeries.push({
                    name: "Case",
                    data: resp.case.month
                });
                this.monthBarSeries.push({ name: "API", data: resp.api.month });
                this.monthBarSeries.push({
                    name: "Yapi",
                    data: resp.yapi.month
                });
                this.monthBarSeries = [
                    { name: "Case", data: resp.case.month },
                    { name: "API", data: resp.api.month },
                    { name: "Yapi", data: resp.yapi.month }
                ];
                this.optionsMonthBar = {
                    ...this.optionsMonthBar,
                    ...{ xaxis: { categories: resp.recent_months } }
                    xaxis: { categories: resp.recent_months }
                };
                // 近半年接口创建前5名统计
                resp.api.monthly_top_creators.forEach(creator => {
                    this.apiMonthlyLineSeries.push({
                        name: creator,
                        data: resp.api.monthly_creator_counts[creator]
                    });
                });
                this.apiMonthlyLineSeries = resp.api.monthly_top_creators.map(creator => ({
                    name: creator,
                    data: resp.api.monthly_creator_counts[creator] || []
                }));
                this.apiMonthlyOptionsLine = {
                    ...this.optionsLine,
                    ...{ labels: resp.recent_months }
                    labels: resp.recent_months
                };
                // 近半年用例创建前5名统计
                resp.case.monthly_top_creators.forEach(creator => {
                    this.caseMonthlyLineSeries.push({
                        name: creator,
                        data: resp.case.monthly_creator_counts[creator]
                    });
                });
                this.caseMonthlyLineSeries = resp.case.monthly_top_creators.map(creator => ({
                    name: creator,
                    data: resp.case.monthly_creator_counts[creator] || []
                }));
                this.caseMonthlyOptionsLine = {
                    ...this.optionsLine,
                    ...{ labels: resp.recent_months }
                    labels: resp.recent_months
                };
                // 每日创建趋势对比
                this.dailyTrendSeries = [
                    { name: "API", data: resp.api.day, color: '#36A2EB' },
                    { name: "Case", data: resp.case.day, color: '#FF6384' },
                    { name: "Yapi", data: resp.yapi.day, color: '#4BC0C0' }
                ];
                this.dailyTrendOptions = {
                    ...this.optionsLine,
                    colors: ['#36A2EB', '#FF6384', '#4BC0C0'],
                    labels: resp.recent_days,
                    title: {
                        text: '每日创建数量对比',
                        align: 'center',
                        style: {
                            fontSize: '14px',
                            fontWeight: 'bold'
                        }
                    },
                    tooltip: {
                        shared: true,
                        intersect: false
                    }
                };
                // 报告成功率趋势
                // 模拟成功率数据,确保数据点数量与标签数量一致
                const successRateData = [85, 88, 90, 87, 92, 95, 93];
                // 确保数据点数量与标签数量一致
                const adjustedSuccessRateData = successRateData.slice(0, resp.recent_days.length);
                this.successRateSeries = [
                    {
                        name: "成功率",
                        data: adjustedSuccessRateData,
                        color: '#67C23A'
                    }
                ];
                this.successRateOptions = {
                    ...this.optionsLine,
                    colors: ['#67C23A'],
                    labels: resp.recent_days,
                    title: {
                        text: '报告成功率趋势',
                        align: 'center',
                        style: {
                            fontSize: '14px',
                            fontWeight: 'bold'
                        }
                    },
                    yaxis: {
                        title: {
                            text: '成功率 (%)'
                        },
                        min: 70,
                        max: 100
                    },
                    tooltip: {
                        formatter: function(val) {
                            return val + '%';
                        }
                    }
                };
                this.isLoading = false;
@@ -363,14 +738,403 @@
</script>
<style scoped>
.api-case {
    margin-top: 10px;
    width: 32%;
.dashboard-container {
    padding: 24px;
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    min-height: 100vh;
    height: auto;
    overflow: visible;
}
.api-case-monthly {
    margin-top: 10px;
    width: 32%;
    margin-bottom: 10px;
/* 页面标题 */
.page-header {
    margin-bottom: 24px;
    color: #fff;
    animation: fadeInDown 0.6s ease-out;
}
.page-header h2 {
    font-size: 28px;
    font-weight: 600;
    margin: 0 0 8px 0;
    text-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.page-header .subtitle {
    font-size: 14px;
    opacity: 0.9;
    margin: 0;
}
/* 概览卡片样式 */
.overview-section {
    margin-bottom: 24px;
}
.overview-card {
    background: rgba(255, 255, 255, 0.95);
    border-radius: 16px;
    padding: 24px;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
    transition: box-shadow 0.2s ease;
    cursor: pointer;
    backdrop-filter: blur(10px);
    border: 1px solid rgba(255, 255, 255, 0.2);
    position: relative;
    overflow: hidden;
}
.overview-card::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 4px;
}
.overview-card.success::before {
    background: linear-gradient(90deg, #67c23a, #85ce61);
}
.overview-card.danger::before {
    background: linear-gradient(90deg, #f56c6c, #f78989);
}
.overview-card.info::before {
    background: linear-gradient(90deg, #409eff, #66b1ff);
}
.overview-card.warning::before {
    background: linear-gradient(90deg, #e6a23c, #ebb563);
}
.overview-card.primary::before {
    background: linear-gradient(90deg, #909399, #606266);
}
.overview-card.purple::before {
    background: linear-gradient(90deg, #9c27b0, #ba68c8);
}
.overview-card.teal::before {
    background: linear-gradient(90deg, #009688, #26a69a);
}
.overview-card.orange::before {
    background: linear-gradient(90deg, #ff9800, #ffa726);
}
.overview-card:hover {
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
    background: rgba(255, 255, 255, 1);
}
.card-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 16px;
}
.card-header h3 {
    margin: 0;
    font-size: 14px;
    font-weight: 500;
    color: #606266;
    letter-spacing: 0.5px;
}
.card-header i {
    font-size: 24px;
}
.success .card-header i {
    color: #67c23a;
}
.danger .card-header i {
    color: #f56c6c;
}
.info .card-header i {
    color: #409eff;
}
.warning .card-header i {
    color: #e6a23c;
}
.primary .card-header i {
    color: #909399;
}
.purple .card-header i {
    color: #9c27b0;
}
.teal .card-header i {
    color: #009688;
}
.orange .card-header i {
    color: #ff9800;
}
.card-content {
    text-align: center;
    margin-bottom: 16px;
}
.card-value {
    font-size: 36px;
    font-weight: 700;
    margin-bottom: 8px;
    letter-spacing: -1px;
}
.success .card-value {
    color: #67c23a;
    text-shadow: 0 2px 4px rgba(103, 194, 58, 0.1);
}
.danger .card-value {
    color: #f56c6c;
    text-shadow: 0 2px 4px rgba(245, 108, 108, 0.1);
}
.info .card-value {
    color: #409eff;
    text-shadow: 0 2px 4px rgba(64, 158, 255, 0.1);
}
.warning .card-value {
    color: #e6a23c;
    text-shadow: 0 2px 4px rgba(230, 162, 60, 0.1);
}
.primary .card-value {
    color: #909399;
    text-shadow: 0 2px 4px rgba(144, 147, 153, 0.1);
}
.purple .card-value {
    color: #9c27b0;
    text-shadow: 0 2px 4px rgba(156, 39, 176, 0.1);
}
.teal .card-value {
    color: #009688;
    text-shadow: 0 2px 4px rgba(0, 150, 136, 0.1);
}
.orange .card-value {
    color: #ff9800;
    text-shadow: 0 2px 4px rgba(255, 152, 0, 0.1);
}
.card-desc {
    font-size: 13px;
    color: #909399;
    font-weight: 400;
}
/* 卡片底部趋势 */
.card-footer {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding-top: 16px;
    border-top: 1px solid #f0f2f5;
    font-size: 12px;
}
.trend-up {
    color: #67c23a;
    font-weight: 500;
}
.trend-down {
    color: #f56c6c;
    font-weight: 500;
}
.compared {
    color: #909399;
}
/* 图表卡片样式 */
.charts-section {
    margin-top: 0;
}
.chart-card {
    background: rgba(255, 255, 255, 0.95);
    border-radius: 16px;
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
    transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
    overflow: hidden;
    backdrop-filter: blur(10px);
    border: 1px solid rgba(255, 255, 255, 0.2);
    animation: fadeInUp 0.6s ease-out;
}
.chart-card:hover {
    box-shadow: 0 16px 48px rgba(0, 0, 0, 0.15);
    background: rgba(255, 255, 255, 1);
}
.card-header-custom {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    padding: 16px 20px;
    border-bottom: 1px solid #f0f2f5;
}
.card-header-custom .title {
    font-weight: 600;
    color: #303133;
    font-size: 16px;
    margin-bottom: 4px;
}
.card-header-custom .subtitle {
    font-size: 12px;
    color: #909399;
    font-weight: 400;
}
.card-header-custom i {
    display: none;
}
.report-stats-container {
    display: flex;
    justify-content: space-around;
    align-items: center;
    padding: 20px;
}
.report-stat-item {
    flex: 1;
    text-align: center;
    padding: 0 16px;
}
.report-stat-item h4 {
    margin: 0 0 16px 0;
    font-size: 14px;
    font-weight: 500;
    color: #606266;
}
/* 动画效果 */
@keyframes fadeInDown {
    from {
        opacity: 0;
        transform: translateY(-20px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}
@keyframes fadeInUp {
    from {
        opacity: 0;
        transform: translateY(20px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}
@keyframes countUp {
    from {
        opacity: 0;
        transform: scale(0.8);
    }
    to {
        opacity: 1;
        transform: scale(1);
    }
}
/* 为不同卡片添加延迟动画 */
.chart-card:nth-child(1) {
    animation-delay: 0.1s;
}
.chart-card:nth-child(2) {
    animation-delay: 0.2s;
}
.chart-card:nth-child(3) {
    animation-delay: 0.3s;
}
/* 响应式调整 */
@media (max-width: 768px) {
    .dashboard-container {
        padding: 16px;
    }
    .page-header h2 {
        font-size: 24px;
    }
    .overview-card {
        margin-bottom: 16px;
        padding: 20px;
    }
    .overview-card:hover {
        transform: translateY(-4px) scale(1.01);
    }
    .card-value {
        font-size: 28px;
    }
    .chart-card {
        margin-bottom: 16px;
    }
    .report-stats-container {
        flex-direction: column;
        padding: 16px;
    }
    .report-stat-item {
        margin-bottom: 24px;
        padding: 0;
    }
    .report-stat-item:last-child {
        margin-bottom: 0;
    }
}
/* 骨架屏样式优化 */
:deep(.el-skeleton) {
    padding: 16px;
}
:deep(.el-skeleton__item) {
    background: linear-gradient(90deg, #f0f2f5 25%, #e6e8eb 50%, #f0f2f5 75%);
    background-size: 200% 100%;
    animation: skeleton-loading 1.5s infinite;
}
@keyframes skeleton-loading {
    0% {
        background-position: 200% 0;
    }
    100% {
        background-position: -200% 0;
    }
}
</style>