diff --git a/video-gen-admin/src/pages/AdminDashboard.tsx b/video-gen-admin/src/pages/AdminDashboard.tsx index 6a3e372c..51832d04 100644 --- a/video-gen-admin/src/pages/AdminDashboard.tsx +++ b/video-gen-admin/src/pages/AdminDashboard.tsx @@ -12,10 +12,14 @@ import 'dayjs/locale/zh-cn'; dayjs.locale('zh-cn'); const MODULE_LABELS: Record = { - 'chat_ai': 'AI创作', - 'hot_opening_replicate': '爆款开头', + 'ai_creation': 'AI创作', + 'generation_record': '项目生成', + 'hot_opening_replicate': '爆款开头复刻', 'shot_replicate': '拆镜复刻', - 'project': '项目生成', + 'payment': '支付充值', + 'admin': '后台管理', + 'team': '团队管理', + 'unknown': '历史未知', 'other': '其他', }; @@ -91,10 +95,7 @@ const AdminDashboard: React.FC = () => { {[ - { title: '用户数量', value: stats?.totalUsers, icon: , color: '#6366f1' }, - { title: '总项目数', value: stats?.totalProjects, icon: , color: '#3b82f6' }, - { title: '项目记录', value: stats?.totalRecords, icon: , color: '#10b981' }, - { title: '创作记录', value: stats?.totalGenerations, icon: , color: '#f59e0b' }, + { title: '新增用户数量', value: stats?.totalUsers, icon: , color: '#6366f1' }, { title: '总收入', value: stats?.totalRevenue, icon: , color: '#ec4899', prefix: '¥' }, { title: '消耗积分', value: stats?.creditsConsumedToday, icon: , color: '#ef4444' }, ].map(s => ( @@ -166,34 +167,37 @@ const CompactStatCard: React.FC<{ title: string; value?: number; icon: React.Rea ); -// ── 折线图(按日期+模块)── +// ── 折线图(按日期+模块,固定展示选中日期往前7天)── const LineChart: React.FC<{ data: { date: string; module: string; credits: number }[] }> = ({ data }) => { + // 以数据中最新日期为基准,往前推 7 天;不足 7 天按实际天数 if (!data.length) return ; - // 按日期聚合 + const sortedDates = Array.from(new Set(data.map(d => d.date))).sort(); + const maxDate = sortedDates[sortedDates.length - 1]; + // 生成 [maxDate-6, maxDate] 共 7 天 + const baseDayjs = dayjs(maxDate); + const sevenDays: string[] = []; + for (let i = 6; i >= 0; i--) sevenDays.push(baseDayjs.subtract(i, 'day').format('YYYY-MM-DD')); + const dateMap = new Map(); - const moduleSet = new Set(); - data.forEach(d => { dateMap.set(d.date, (dateMap.get(d.date) || 0) + d.credits); moduleSet.add(d.module); }); - const dates = Array.from(dateMap.keys()).sort(); - const maxVal = Math.max(...dateMap.values(), 1); - const maxPoints = 14; - const step = Math.max(1, Math.floor(dates.length / maxPoints)); - const sampled = dates.filter((_, i) => i % step === 0 || i === dates.length - 1); + data.forEach(d => { dateMap.set(d.date, (dateMap.get(d.date) || 0) + d.credits); }); + const maxVal = Math.max(...sevenDays.map(d => dateMap.get(d) || 0), 1); return (
-
- {sampled.map(d => { +
+ {sevenDays.map(d => { const val = dateMap.get(d) || 0; const pct = (val / maxVal) * 100; return (
-
+ {val > 0 ? val.toFixed(0) : ''} +
); })}
-
- {sampled.map(d => ( +
+ {sevenDays.map(d => (
{d.slice(5)}