'use client' import { useState } from 'react' import { useRouter } from 'next/navigation' import { Card, CardContent } from '@/components/ui/Card' import { Button } from '@/components/ui/Button' import { Bell, CheckCircle, XCircle, AlertTriangle, FileText, Video, Users, Clock, Check, MoreVertical, Building2, FolderPlus, Settings, MessageCircle, CalendarClock, Megaphone, FileCheck, UserCheck, Eye } from 'lucide-react' import { getPlatformInfo } from '@/lib/platforms' import { cn } from '@/lib/utils' // 消息类型 type MessageType = | 'agency_review_pass' // 代理商审核通过,待品牌终审 | 'script_pending' // 新脚本待终审 | 'video_pending' // 新视频待终审 | 'project_created' // 项目创建成功 | 'agency_accept' // 代理商接受项目邀请 | 'creators_assigned' // 代理商配置达人到项目 | 'content_published' // 内容已发布 | 'rule_updated' // 规则更新生效 | 'review_timeout' // 审核超时提醒 | 'creator_appeal' // 达人发起申诉 | 'brief_config_updated' // 代理商更新了Brief配置 | 'batch_review_done' // 批量审核完成 | 'system_notice' // 系统通知 type Message = { id: string type: MessageType title: string content: string time: string read: boolean platform?: string projectId?: string taskId?: string agencyName?: string hasAction?: boolean actionType?: 'review' | 'view' } // 消息配置 const messageConfig: Record = { agency_review_pass: { icon: FileCheck, iconColor: 'text-accent-indigo', bgColor: 'bg-accent-indigo/20' }, script_pending: { icon: FileText, iconColor: 'text-accent-indigo', bgColor: 'bg-accent-indigo/20' }, video_pending: { icon: Video, iconColor: 'text-purple-400', bgColor: 'bg-purple-500/20' }, project_created: { icon: FolderPlus, iconColor: 'text-accent-green', bgColor: 'bg-accent-green/20' }, agency_accept: { icon: UserCheck, iconColor: 'text-accent-green', bgColor: 'bg-accent-green/20' }, creators_assigned: { icon: Users, iconColor: 'text-accent-indigo', bgColor: 'bg-accent-indigo/20' }, content_published: { icon: Megaphone, iconColor: 'text-accent-green', bgColor: 'bg-accent-green/20' }, rule_updated: { icon: Settings, iconColor: 'text-accent-amber', bgColor: 'bg-accent-amber/20' }, review_timeout: { icon: CalendarClock, iconColor: 'text-orange-400', bgColor: 'bg-orange-500/20' }, creator_appeal: { icon: MessageCircle, iconColor: 'text-accent-amber', bgColor: 'bg-accent-amber/20' }, brief_config_updated: { icon: FileText, iconColor: 'text-accent-indigo', bgColor: 'bg-accent-indigo/20' }, batch_review_done: { icon: CheckCircle, iconColor: 'text-accent-green', bgColor: 'bg-accent-green/20' }, system_notice: { icon: Bell, iconColor: 'text-text-secondary', bgColor: 'bg-bg-elevated' }, } // 模拟消息数据 const mockMessages: Message[] = [ { id: 'msg-001', type: 'creators_assigned', title: '达人已分配', content: '「星辰传媒」已为【XX品牌618推广】项目配置了5位达人,可查看达人列表', time: '5分钟前', read: false, platform: 'douyin', agencyName: '星辰传媒', projectId: 'proj-001', hasAction: true, actionType: 'view', }, { id: 'msg-002', type: 'script_pending', title: '脚本待终审', content: '【XX品牌618推广】「星辰传媒」的达人「小美护肤」脚本已通过代理商审核,请进行终审', time: '10分钟前', read: false, platform: 'xiaohongshu', agencyName: '星辰传媒', taskId: 'task-007', hasAction: true, actionType: 'review', }, { id: 'msg-003', type: 'video_pending', title: '视频待终审', content: '【BB运动饮料】「光影传媒」的达人「健身教练王」视频已通过代理商审核,请进行终审', time: '30分钟前', read: false, platform: 'bilibili', agencyName: '光影传媒', taskId: 'task-014', hasAction: true, actionType: 'review', }, { id: 'msg-003b', type: 'creators_assigned', title: '达人已分配', content: '「光影传媒」已为【BB运动饮料】项目配置了3位达人,可查看达人列表', time: '1小时前', read: false, platform: 'bilibili', agencyName: '光影传媒', projectId: 'proj-002', hasAction: true, actionType: 'view', }, { id: 'msg-004', type: 'review_timeout', title: '审核超时提醒', content: '有5条内容已等待终审超过48小时,请及时处理避免影响达人创作进度', time: '1小时前', read: false, hasAction: true, actionType: 'review', }, { id: 'msg-005', type: 'agency_accept', title: '代理商已加入', content: '「星辰传媒」已接受您的项目邀请,加入【XX品牌618推广】项目', time: '2小时前', read: true, agencyName: '星辰传媒', projectId: 'proj-001', }, { id: 'msg-007', type: 'project_created', title: '项目创建成功', content: '您的项目【XX品牌618推广】已创建成功,可以开始邀请代理商参与', time: '昨天 14:30', read: true, projectId: 'proj-001', hasAction: true, actionType: 'view', }, { id: 'msg-008', type: 'content_published', title: '内容已发布', content: '【XX品牌618推广】项目已有12条视频发布,累计播放量达50万+', time: '昨天 10:00', read: true, platform: 'douyin', projectId: 'proj-001', }, { id: 'msg-009', type: 'brief_config_updated', title: 'Brief配置更新', content: '「星辰传媒」更新了【XX品牌618推广】的Brief配置,新增3个卖点要求', time: '昨天 09:15', read: true, agencyName: '星辰传媒', projectId: 'proj-001', hasAction: true, actionType: 'view', }, { id: 'msg-010', type: 'creator_appeal', title: '达人申诉通知', content: '达人「美妆Lisa」对【新品口红试色】的驳回结果发起申诉,请关注处理进度', time: '2天前', read: true, taskId: 'task-003', }, { id: 'msg-011', type: 'rule_updated', title: '规则更新生效', content: '您配置的品牌规则【禁用竞品词库】已更新生效,新增15个违禁词', time: '2天前', read: true, }, { id: 'msg-012', type: 'batch_review_done', title: '批量审核完成', content: '您今日已完成8条内容终审,其中通过6条,驳回2条', time: '3天前', read: true, }, { id: 'msg-013', type: 'system_notice', title: '系统通知', content: '平台违禁词库已更新,新增「抖音」平台美妆类目违禁词56个', time: '3天前', read: true, }, ] export default function BrandMessagesPage() { const router = useRouter() const [messages, setMessages] = useState(mockMessages) const [filter, setFilter] = useState<'all' | 'unread' | 'pending'>('all') const unreadCount = messages.filter(m => !m.read).length const pendingReviewCount = messages.filter(m => !m.read && (m.type === 'agency_review_pass' || m.type === 'script_pending' || m.type === 'video_pending') ).length const getFilteredMessages = () => { switch (filter) { case 'unread': return messages.filter(m => !m.read) case 'pending': return messages.filter(m => m.type === 'agency_review_pass' || m.type === 'script_pending' || m.type === 'video_pending' || m.type === 'review_timeout' ) default: return messages } } const filteredMessages = getFilteredMessages() const markAsRead = (id: string) => { setMessages(prev => prev.map(m => m.id === id ? { ...m, read: true } : m)) } const markAllAsRead = () => { setMessages(prev => prev.map(m => ({ ...m, read: true }))) } const handleMessageClick = (message: Message) => { if (message.type === 'system_notice') return // 系统通知不跳转 markAsRead(message.id) // 根据消息类型跳转 switch (message.type) { case 'script_pending': if (message.taskId) router.push(`/brand/review/script/${message.taskId}`) else router.push('/brand/review') break case 'video_pending': if (message.taskId) router.push(`/brand/review/video/${message.taskId}`) else router.push('/brand/review') break case 'creator_appeal': // 达人申诉 -> 终审台 router.push('/brand/review') break case 'rule_updated': // 规则更新 -> 规则配置 router.push('/brand/rules') break case 'batch_review_done': // 批量审核完成 -> 终审台 router.push('/brand/review') break case 'agency_review_pass': case 'review_timeout': // 待终审内容 -> 终审台 router.push('/brand/review') break default: if (message.projectId) { router.push(`/brand/projects/${message.projectId}`) } } } const handleAction = (message: Message, e: React.MouseEvent) => { e.stopPropagation() markAsRead(message.id) if (message.actionType === 'review') { if (message.taskId) { if (message.type === 'script_pending') { router.push(`/brand/review/script/${message.taskId}`) } else { router.push(`/brand/review/video/${message.taskId}`) } } else { router.push('/brand/review') } } else if (message.actionType === 'view') { if (message.projectId) { router.push(`/brand/projects/${message.projectId}`) } else if (message.type === 'rule_updated') { router.push('/brand/rules') } } } return (
{/* 页面标题 */}

消息中心

{unreadCount > 0 && ( {unreadCount} 条未读 )} {pendingReviewCount > 0 && ( {pendingReviewCount} 条待审 )}
{/* 筛选标签 */}
{/* 消息列表 */}
{filteredMessages.map((message) => { const config = messageConfig[message.type] const Icon = config.icon const platform = message.platform ? getPlatformInfo(message.platform) : null return ( handleMessageClick(message)} > {/* 平台顶部条 */} {platform && (
{platform.icon} {platform.name}
)}
{/* 图标 */}
{/* 内容 */}

{message.title}

{!message.read && ( )}

{message.content}

{message.time}

{/* 操作按钮 */} {message.hasAction && ( )}
) })}
{/* 空状态 */} {filteredMessages.length === 0 && (

{filter === 'unread' ? '没有未读消息' : filter === 'pending' ? '没有待处理消息' : '暂无消息'}

)}
) }