修复权限验证问题:普通用户无法访问后台管理页面
This commit is contained in:
@@ -20,7 +20,7 @@
|
||||
<span>订单管理</span>
|
||||
</div>
|
||||
<div class="nav-item" @click="goToAPI">
|
||||
<el-icon><Code /></el-icon>
|
||||
<el-icon><Document /></el-icon>
|
||||
<span>API管理</span>
|
||||
</div>
|
||||
<div class="nav-item" @click="goToTasks">
|
||||
@@ -99,84 +99,7 @@
|
||||
<!-- 图表区域 -->
|
||||
<section class="charts-section">
|
||||
<!-- 日活用户趋势图 -->
|
||||
<div class="chart-card full-width">
|
||||
<div class="chart-header">
|
||||
<h3>日活用户趋势</h3>
|
||||
<div class="year-selector">
|
||||
<span>2025年</span>
|
||||
<el-icon><ArrowDown /></el-icon>
|
||||
</div>
|
||||
</div>
|
||||
<div class="chart-container">
|
||||
<div class="line-chart">
|
||||
<!-- 动态SVG曲线图 -->
|
||||
<svg width="100%" height="200" :viewBox="`0 0 ${chartWidth} ${chartHeight}`" class="chart-svg">
|
||||
<!-- 网格线 -->
|
||||
<defs>
|
||||
<pattern id="grid" width="60" height="40" patternUnits="userSpaceOnUse">
|
||||
<path d="M 60 0 L 0 0 0 40" fill="none" stroke="#e2e8f0" stroke-width="0.5"/>
|
||||
</pattern>
|
||||
</defs>
|
||||
<rect width="100%" height="100%" fill="url(#grid)" />
|
||||
|
||||
<!-- 动态数据曲线 -->
|
||||
<path :d="chartPath"
|
||||
fill="none"
|
||||
stroke="#3b82f6"
|
||||
stroke-width="3"
|
||||
class="chart-line-path"/>
|
||||
|
||||
<!-- 动态数据点 -->
|
||||
<circle
|
||||
v-for="(point, index) in chartPoints"
|
||||
:key="index"
|
||||
:cx="point.x"
|
||||
:cy="point.y"
|
||||
r="4"
|
||||
fill="#3b82f6"
|
||||
class="chart-dot"
|
||||
@click="handlePointClick(point)"
|
||||
style="cursor: pointer;"/>
|
||||
|
||||
<!-- 高亮数据点 -->
|
||||
<template v-if="highlightedPoint">
|
||||
<circle
|
||||
:cx="highlightedPoint.x"
|
||||
:cy="highlightedPoint.y"
|
||||
r="6"
|
||||
fill="#3b82f6"
|
||||
class="highlight-dot"/>
|
||||
<circle
|
||||
:cx="highlightedPoint.x"
|
||||
:cy="highlightedPoint.y"
|
||||
r="12"
|
||||
fill="#3b82f6"
|
||||
opacity="0.2"
|
||||
class="highlight-ring"/>
|
||||
|
||||
<!-- 动态工具提示 -->
|
||||
<g class="tooltip-group" :transform="`translate(${highlightedPoint.x}, ${highlightedPoint.y - 20})`">
|
||||
<rect x="-30" y="-40" width="60" height="30" rx="6" fill="#1e293b" class="tooltip-bg"/>
|
||||
<text x="0" y="-25" text-anchor="middle" fill="white" font-size="12" font-weight="600" class="tooltip-value">
|
||||
{{ highlightedPoint.value.toLocaleString() }}
|
||||
</text>
|
||||
<text x="0" y="-10" text-anchor="middle" fill="white" font-size="10" opacity="0.8" class="tooltip-date">
|
||||
{{ highlightedPoint.label }}
|
||||
</text>
|
||||
<!-- 工具提示箭头 -->
|
||||
<polygon points="0,0 -5,10 5,10" fill="#1e293b" class="tooltip-arrow"/>
|
||||
</g>
|
||||
</template>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="chart-x-axis">
|
||||
<span v-for="data in monthlyData" :key="data.month">{{ data.label }}</span>
|
||||
</div>
|
||||
<div class="chart-y-axis">
|
||||
<span v-for="tick in [1500, 1200, 900, 600, 300, 0]" :key="tick">{{ tick }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<DailyActiveUsersChart />
|
||||
|
||||
<!-- 用户转化率图 -->
|
||||
<div class="chart-card full-width">
|
||||
@@ -235,6 +158,17 @@ import { ref, onMounted, computed } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { useUserStore } from '@/stores/user'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import {
|
||||
Grid,
|
||||
User,
|
||||
ShoppingCart,
|
||||
Document,
|
||||
Setting,
|
||||
Search,
|
||||
Bell,
|
||||
ArrowDown,
|
||||
Money
|
||||
} from '@element-plus/icons-vue'
|
||||
import * as dashboardAPI from '@/api/dashboard'
|
||||
import DailyActiveUsersChart from '@/components/DailyActiveUsersChart.vue'
|
||||
|
||||
@@ -242,6 +176,8 @@ const router = useRouter()
|
||||
const userStore = useUserStore()
|
||||
|
||||
// 数据状态
|
||||
const loading = ref(false)
|
||||
const selectedYear = ref('2024')
|
||||
const dashboardData = ref({
|
||||
totalUsers: 0,
|
||||
paidUsers: 0,
|
||||
@@ -266,70 +202,7 @@ const systemStatus = ref({
|
||||
serviceStatus: '运行中'
|
||||
})
|
||||
|
||||
const selectedYear = ref(2024)
|
||||
const highlightedPoint = ref(null)
|
||||
const loading = ref(false)
|
||||
|
||||
// 计算图表尺寸和比例
|
||||
const chartWidth = 800
|
||||
const chartHeight = 200
|
||||
const padding = 60
|
||||
|
||||
// 计算数据点的SVG坐标
|
||||
const chartPoints = computed(() => {
|
||||
if (monthlyData.value.length === 0) return []
|
||||
|
||||
const maxValue = Math.max(...monthlyData.value.map(d => d.revenue || 0))
|
||||
const minValue = Math.min(...monthlyData.value.map(d => d.revenue || 0))
|
||||
const valueRange = maxValue - minValue || 1
|
||||
|
||||
return monthlyData.value.map((data, index) => {
|
||||
const x = padding + (index * (chartWidth - 2 * padding) / (monthlyData.value.length - 1))
|
||||
const y = padding + ((maxValue - (data.revenue || 0)) / valueRange) * (chartHeight - 2 * padding)
|
||||
return {
|
||||
x,
|
||||
y,
|
||||
value: data.revenue || 0,
|
||||
label: `${data.month}月`,
|
||||
month: data.month
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
// 生成SVG路径
|
||||
const chartPath = computed(() => {
|
||||
if (chartPoints.value.length < 2) return ''
|
||||
|
||||
let path = `M ${chartPoints.value[0].x},${chartPoints.value[0].y}`
|
||||
|
||||
for (let i = 1; i < chartPoints.value.length; i++) {
|
||||
const prev = chartPoints.value[i - 1]
|
||||
const curr = chartPoints.value[i]
|
||||
const next = chartPoints.value[i + 1]
|
||||
|
||||
if (next) {
|
||||
// 使用三次贝塞尔曲线创建平滑路径
|
||||
const cp1x = prev.x + (curr.x - prev.x) / 3
|
||||
const cp1y = prev.y
|
||||
const cp2x = curr.x - (next.x - curr.x) / 3
|
||||
const cp2y = curr.y
|
||||
|
||||
path += ` C ${cp1x},${cp1y} ${cp2x},${cp2y} ${curr.x},${curr.y}`
|
||||
} else {
|
||||
// 最后一个点
|
||||
const cp1x = prev.x + (curr.x - prev.x) / 3
|
||||
const cp1y = prev.y
|
||||
path += ` C ${cp1x},${cp1y} ${curr.x},${curr.y} ${curr.x},${curr.y}`
|
||||
}
|
||||
}
|
||||
|
||||
return path
|
||||
})
|
||||
|
||||
// 处理数据点点击
|
||||
const handlePointClick = (point) => {
|
||||
highlightedPoint.value = point
|
||||
}
|
||||
// 清理未使用的图表相关代码
|
||||
|
||||
// 导航功能
|
||||
const goToUsers = () => {
|
||||
@@ -346,15 +219,15 @@ const goToOrders = () => {
|
||||
}
|
||||
|
||||
const goToAPI = () => {
|
||||
ElMessage.info('跳转到API管理')
|
||||
router.push('/api-management')
|
||||
}
|
||||
|
||||
const goToTasks = () => {
|
||||
ElMessage.info('跳转到生成任务记录')
|
||||
router.push('/generate-task-record')
|
||||
}
|
||||
|
||||
const goToSettings = () => {
|
||||
ElMessage.info('跳转到系统设置')
|
||||
router.push('/system-settings')
|
||||
}
|
||||
|
||||
// 加载仪表盘数据
|
||||
@@ -371,39 +244,39 @@ const loadDashboardData = async () => {
|
||||
])
|
||||
|
||||
// 处理概览数据
|
||||
if (overviewRes.data) {
|
||||
if (overviewRes) {
|
||||
dashboardData.value = {
|
||||
totalUsers: overviewRes.data.totalUsers || 0,
|
||||
paidUsers: overviewRes.data.paidUsers || 0,
|
||||
todayRevenue: overviewRes.data.todayRevenue || 0,
|
||||
totalOrders: overviewRes.data.totalOrders || 0,
|
||||
totalRevenue: overviewRes.data.totalRevenue || 0,
|
||||
monthRevenue: overviewRes.data.monthRevenue || 0
|
||||
totalUsers: overviewRes.totalUsers || 0,
|
||||
paidUsers: overviewRes.paidUsers || 0,
|
||||
todayRevenue: overviewRes.todayRevenue || 0,
|
||||
totalOrders: overviewRes.totalOrders || 0,
|
||||
totalRevenue: overviewRes.totalRevenue || 0,
|
||||
monthRevenue: overviewRes.monthRevenue || 0
|
||||
}
|
||||
}
|
||||
|
||||
// 处理月度数据
|
||||
if (monthlyRes.data && monthlyRes.data.monthlyData) {
|
||||
monthlyData.value = monthlyRes.data.monthlyData
|
||||
if (monthlyRes && monthlyRes.monthlyData) {
|
||||
monthlyData.value = monthlyRes.monthlyData
|
||||
}
|
||||
|
||||
// 处理转化率数据
|
||||
if (conversionRes.data) {
|
||||
if (conversionRes) {
|
||||
conversionData.value = {
|
||||
totalUsers: conversionRes.data.totalUsers || 0,
|
||||
paidUsers: conversionRes.data.paidUsers || 0,
|
||||
conversionRate: conversionRes.data.conversionRate || 0,
|
||||
membershipStats: conversionRes.data.membershipStats || []
|
||||
totalUsers: conversionRes.totalUsers || 0,
|
||||
paidUsers: conversionRes.paidUsers || 0,
|
||||
conversionRate: conversionRes.conversionRate || 0,
|
||||
membershipStats: conversionRes.membershipStats || []
|
||||
}
|
||||
}
|
||||
|
||||
// 处理系统状态
|
||||
if (statusRes.data) {
|
||||
if (statusRes) {
|
||||
systemStatus.value = {
|
||||
onlineUsers: statusRes.data.onlineUsers || 0,
|
||||
systemUptime: statusRes.data.systemUptime || '0小时0分',
|
||||
databaseStatus: statusRes.data.databaseStatus || '正常',
|
||||
serviceStatus: statusRes.data.serviceStatus || '运行中'
|
||||
onlineUsers: statusRes.onlineUsers || 0,
|
||||
systemUptime: statusRes.systemUptime || '0小时0分',
|
||||
databaseStatus: statusRes.databaseStatus || '正常',
|
||||
serviceStatus: statusRes.serviceStatus || '运行中'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user