'use client' import { useState } from 'react' import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/Card' import { Button } from '@/components/ui/Button' import { Modal } from '@/components/ui/Modal' import { BarChart3, TrendingUp, TrendingDown, Download, Calendar, FileText, Video, Users, CheckCircle, XCircle, Clock, FileSpreadsheet, File, Check } from 'lucide-react' import { getPlatformInfo } from '@/lib/platforms' // 时间范围类型 type DateRange = 'week' | 'month' | 'quarter' | 'year' // 按时间范围的模拟数据 const mockDataByRange: Record = { week: { stats: { totalScripts: 156, totalVideos: 128, passRate: 85, avgReviewTime: 4.2, trend: { scripts: '+12%', videos: '+8%', passRate: '+3%', reviewTime: '-15%' }, }, trendData: [ { label: '周一', submitted: 25, passed: 22, rejected: 3 }, { label: '周二', submitted: 32, passed: 28, rejected: 4 }, { label: '周三', submitted: 18, passed: 16, rejected: 2 }, { label: '周四', submitted: 41, passed: 35, rejected: 6 }, { label: '周五', submitted: 35, passed: 30, rejected: 5 }, { label: '周六', submitted: 12, passed: 11, rejected: 1 }, { label: '周日', submitted: 8, passed: 7, rejected: 1 }, ], compareText: '上周', }, month: { stats: { totalScripts: 623, totalVideos: 512, passRate: 83, avgReviewTime: 4.5, trend: { scripts: '+18%', videos: '+15%', passRate: '+2%', reviewTime: '-10%' }, }, trendData: [ { label: '第1周', submitted: 145, passed: 122, rejected: 23 }, { label: '第2周', submitted: 168, passed: 140, rejected: 28 }, { label: '第3周', submitted: 155, passed: 128, rejected: 27 }, { label: '第4周', submitted: 171, passed: 145, rejected: 26 }, ], compareText: '上月', }, quarter: { stats: { totalScripts: 1856, totalVideos: 1520, passRate: 82, avgReviewTime: 4.8, trend: { scripts: '+25%', videos: '+22%', passRate: '+5%', reviewTime: '-8%' }, }, trendData: [ { label: '1月', submitted: 580, passed: 478, rejected: 102 }, { label: '2月', submitted: 615, passed: 503, rejected: 112 }, { label: '3月', submitted: 661, passed: 548, rejected: 113 }, ], compareText: '上季度', }, year: { stats: { totalScripts: 7424, totalVideos: 6080, passRate: 81, avgReviewTime: 5.0, trend: { scripts: '+45%', videos: '+40%', passRate: '+8%', reviewTime: '-20%' }, }, trendData: [ { label: '1月', submitted: 520, passed: 420, rejected: 100 }, { label: '2月', submitted: 485, passed: 392, rejected: 93 }, { label: '3月', submitted: 610, passed: 498, rejected: 112 }, { label: '4月', submitted: 580, passed: 470, rejected: 110 }, { label: '5月', submitted: 625, passed: 513, rejected: 112 }, { label: '6月', submitted: 690, passed: 565, rejected: 125 }, { label: '7月', submitted: 715, passed: 582, rejected: 133 }, { label: '8月', submitted: 680, passed: 550, rejected: 130 }, { label: '9月', submitted: 725, passed: 592, rejected: 133 }, { label: '10月', submitted: 760, passed: 620, rejected: 140 }, { label: '11月', submitted: 780, passed: 640, rejected: 140 }, { label: '12月', submitted: 834, passed: 690, rejected: 144 }, ], compareText: '去年', }, } const mockProjectStats = [ { name: 'XX品牌618推广', platform: 'douyin', scripts: 45, videos: 38, passRate: 92 }, { name: '新品口红系列', platform: 'xiaohongshu', scripts: 32, videos: 28, passRate: 85 }, { name: '护肤品秋季活动', platform: 'bilibili', scripts: 28, videos: 25, passRate: 78 }, { name: 'XX运动品牌', platform: 'kuaishou', scripts: 51, videos: 37, passRate: 88 }, ] const mockCreatorRanking = [ { name: '小美护肤', passRate: 95, total: 28 }, { name: '健身教练王', passRate: 92, total: 15 }, { name: '美妆Lisa', passRate: 88, total: 22 }, { name: '时尚达人', passRate: 82, total: 18 }, { name: '美食探店', passRate: 78, total: 25 }, ] // 时间范围标签 const dateRangeLabels: Record = { week: '本周', month: '本月', quarter: '本季度', year: '本年', } function StatCard({ title, value, unit, trend, compareText, icon: Icon, color }: { title: string value: number | string unit?: string trend?: string compareText: string icon: React.ElementType color: string }) { const isPositive = trend?.startsWith('+') || (trend?.startsWith('-') && title.includes('时长')) return (

{title}

{value} {unit && {unit}}
{trend && (
{isPositive ? : } {trend} vs {compareText}
)}
) } export default function AgencyReportsPage() { const [dateRange, setDateRange] = useState('week') const [showExportModal, setShowExportModal] = useState(false) const [exportFormat, setExportFormat] = useState<'csv' | 'excel' | 'pdf'>('excel') const [isExporting, setIsExporting] = useState(false) const [exportSuccess, setExportSuccess] = useState(false) const currentData = mockDataByRange[dateRange] // 导出报表 const handleExport = async () => { setIsExporting(true) // 模拟导出过程 await new Promise(resolve => setTimeout(resolve, 1500)) // 生成文件名 const dateStr = new Date().toISOString().split('T')[0] const fileName = `审核数据报表_${dateRangeLabels[dateRange]}_${dateStr}` // 模拟下载 if (exportFormat === 'csv') { // 生成 CSV 内容 const csvContent = generateCSV() downloadFile(csvContent, `${fileName}.csv`, 'text/csv') } else if (exportFormat === 'excel') { // 实际项目中会使用 xlsx 库 alert(`Excel 文件「${fileName}.xlsx」已开始下载`) } else { alert(`PDF 文件「${fileName}.pdf」已开始下载`) } setIsExporting(false) setExportSuccess(true) setTimeout(() => { setShowExportModal(false) setExportSuccess(false) }, 1500) } // 生成 CSV 内容 const generateCSV = () => { const headers = ['指标', '数值', '趋势'] const rows = [ ['脚本审核量', currentData.stats.totalScripts, currentData.stats.trend.scripts], ['视频审核量', currentData.stats.totalVideos, currentData.stats.trend.videos], ['通过率', `${currentData.stats.passRate}%`, currentData.stats.trend.passRate], ['平均审核时长', `${currentData.stats.avgReviewTime}小时`, currentData.stats.trend.reviewTime], [], ['时间段', '提交数', '通过数', '驳回数'], ...currentData.trendData.map(d => [d.label, d.submitted, d.passed, d.rejected]), [], ['项目名称', '脚本数', '视频数', '通过率'], ...mockProjectStats.map(p => [p.name, p.scripts, p.videos, `${p.passRate}%`]), ] return [headers.join(','), ...rows.map(r => r.join(','))].join('\n') } // 下载文件 const downloadFile = (content: string, fileName: string, mimeType: string) => { const blob = new Blob(['\ufeff' + content], { type: mimeType + ';charset=utf-8' }) const url = URL.createObjectURL(blob) const link = document.createElement('a') link.href = url link.download = fileName document.body.appendChild(link) link.click() document.body.removeChild(link) URL.revokeObjectURL(url) } return (
{/* 页面标题 */}

数据报表

查看审核数据统计和趋势分析

{(['week', 'month', 'quarter', 'year'] as DateRange[]).map((range) => ( ))}
{/* 核心指标 */}
{/* 趋势图 */} 审核趋势 - {dateRangeLabels[dateRange]}
{currentData.trendData.map((item) => (
{item.label}
{item.passed} / {item.submitted}
))}
通过
驳回
{/* 达人排名 */} 达人通过率排名 {mockCreatorRanking.map((creator, index) => (
{index + 1}
{creator.name}
{creator.total} 条审核
= 90 ? 'text-accent-green' : creator.passRate >= 80 ? 'text-accent-indigo' : 'text-orange-400'}`}> {creator.passRate}%
))}
{/* 项目统计 */} 项目统计 {mockProjectStats.map((project) => { const platform = getPlatformInfo(project.platform) return ( ) })}
项目名称 平台 脚本数 视频数 通过率 通过率分布
{project.name} {platform && ( {platform.icon} {platform.name} )} {project.scripts} {project.videos} = 90 ? 'text-accent-green' : project.passRate >= 80 ? 'text-accent-indigo' : 'text-orange-400'}`}> {project.passRate}%
= 90 ? 'bg-accent-green' : project.passRate >= 80 ? 'bg-accent-indigo' : 'bg-orange-400'}`} style={{ width: `${project.passRate}%` }} />
{/* 导出弹窗 */} setShowExportModal(false)} title="导出报表">
{exportSuccess ? (

导出成功!

文件已开始下载

) : ( <>

导出{dateRangeLabels[dateRange]}的审核数据报表,包含核心指标、趋势数据和项目统计。

{[ { value: 'excel', label: 'Excel (.xlsx)', desc: '适合数据分析和图表制作', icon: FileSpreadsheet }, { value: 'csv', label: 'CSV (.csv)', desc: '通用格式,兼容性好', icon: File }, { value: 'pdf', label: 'PDF (.pdf)', desc: '适合打印和分享', icon: FileText }, ].map((format) => ( ))}
)}
) }