diff --git a/frontend/app/agency/appeals/[id]/page.tsx b/frontend/app/agency/appeals/[id]/page.tsx new file mode 100644 index 0000000..697c4f8 --- /dev/null +++ b/frontend/app/agency/appeals/[id]/page.tsx @@ -0,0 +1,348 @@ +'use client' + +import { useState } from 'react' +import { useRouter, useParams } from 'next/navigation' +import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/Card' +import { Button } from '@/components/ui/Button' +import { + ArrowLeft, + MessageSquare, + Clock, + CheckCircle, + XCircle, + AlertTriangle, + User, + FileText, + Video, + Download, + File, + Send, + Image as ImageIcon +} from 'lucide-react' + +// 申诉状态类型 +type AppealStatus = 'pending' | 'processing' | 'approved' | 'rejected' + +// 模拟申诉详情数据 +const mockAppealDetail = { + id: 'appeal-001', + taskId: 'task-001', + taskTitle: '夏日护肤推广脚本', + creatorId: 'creator-001', + creatorName: '小美护肤', + creatorAvatar: '小', + type: 'ai' as const, + contentType: 'script' as const, + reason: 'AI误判', + content: '脚本中提到的"某品牌"是泛指,并非特指竞品,AI系统可能误解了语境。我在脚本中使用的是泛化表述,并没有提及任何具体的竞品名称。请代理商重新审核此处,谢谢!', + status: 'pending' as AppealStatus, + createdAt: '2026-02-06 10:30', + // 附件 + attachments: [ + { id: 'att-001', name: '品牌授权证明.pdf', size: '1.2 MB', type: 'pdf' }, + { id: 'att-002', name: '脚本原文截图.png', size: '345 KB', type: 'image' }, + ], + // 原审核问题 + originalIssue: { + type: 'ai', + title: '疑似竞品提及', + description: '脚本第3段提到"某品牌",可能涉及竞品露出风险。', + location: '脚本第3段,第2行', + }, + // 相关任务信息 + taskInfo: { + projectName: 'XX品牌618推广', + scriptFileName: '夏日护肤推广_脚本v2.docx', + scriptFileSize: '245 KB', + }, +} + +// 状态配置 +const statusConfig: Record = { + pending: { label: '待处理', color: 'text-accent-amber', bgColor: 'bg-accent-amber/15', icon: Clock }, + processing: { label: '处理中', color: 'text-accent-indigo', bgColor: 'bg-accent-indigo/15', icon: MessageSquare }, + approved: { label: '已通过', color: 'text-accent-green', bgColor: 'bg-accent-green/15', icon: CheckCircle }, + rejected: { label: '已驳回', color: 'text-accent-coral', bgColor: 'bg-accent-coral/15', icon: XCircle }, +} + +export default function AgencyAppealDetailPage() { + const router = useRouter() + const params = useParams() + const [appeal] = useState(mockAppealDetail) + const [replyContent, setReplyContent] = useState('') + const [isSubmitting, setIsSubmitting] = useState(false) + + const status = statusConfig[appeal.status] + const StatusIcon = status.icon + + const handleApprove = async () => { + if (!replyContent.trim()) { + alert('请填写处理意见') + return + } + setIsSubmitting(true) + // 模拟提交 + await new Promise(resolve => setTimeout(resolve, 1000)) + alert('申诉已通过') + router.push('/agency/appeals') + } + + const handleReject = async () => { + if (!replyContent.trim()) { + alert('请填写驳回原因') + return + } + setIsSubmitting(true) + // 模拟提交 + await new Promise(resolve => setTimeout(resolve, 1000)) + alert('申诉已驳回') + router.push('/agency/appeals') + } + + return ( +
+ {/* 顶部导航 */} +
+
+ +
+

申诉处理

+

申诉编号: {appeal.id}

+
+
+
+ + {status.label} +
+
+ +
+ {/* 左侧:申诉详情 */} +
+ {/* 申诉人信息 */} + + + + + 申诉人信息 + + + +
+
+ {appeal.creatorAvatar} +
+
+

{appeal.creatorName}

+

达人ID: {appeal.creatorId}

+
+
+
+
+ 任务名称 +

{appeal.taskTitle}

+
+
+ 所属项目 +

{appeal.taskInfo.projectName}

+
+
+ 内容类型 +

+ {appeal.contentType === 'script' ? :

+
+
+ 提交时间 +

{appeal.createdAt}

+
+
+
+
+ + {/* 原审核问题 */} + + + + + 原审核问题 + + + +
+
+ + {appeal.originalIssue.type === 'ai' ? 'AI检测' : '人工审核'} + + {appeal.originalIssue.title} +
+

{appeal.originalIssue.description}

+

位置: {appeal.originalIssue.location}

+
+
+
+ + {/* 申诉内容 */} + + + + + 申诉内容 + + + +
+
+ 申诉原因 +

{appeal.reason}

+
+
+ 详细说明 +

{appeal.content}

+
+ + {/* 附件 */} + {appeal.attachments.length > 0 && ( +
+ 附件材料 +
+ {appeal.attachments.map((att) => ( +
+
+ {att.type === 'image' ? ( + + ) : ( + + )} +
+
+

{att.name}

+

{att.size}

+
+ +
+ ))} +
+
+ )} +
+
+
+
+ + {/* 右侧:处理面板 */} +
+ {/* 相关文件 */} + + + + + 相关文件 + + + +
+
+ +
+
+

+ {appeal.taskInfo.scriptFileName} +

+

{appeal.taskInfo.scriptFileSize}

+
+ +
+
+
+ + {/* 处理决策 */} + {appeal.status === 'pending' || appeal.status === 'processing' ? ( + + + 处理决策 + + +
+ +