feat: 为所有终端添加平台显示功能

- 新增 frontend/lib/platforms.ts 共享平台配置模块
- 支持6个平台: 抖音、小红书、B站、快手、微博、微信视频号
- 品牌方终端: 项目看板、项目详情、终审台列表添加平台显示
- 代理商终端: 工作台概览、审核台、Brief配置、达人管理、
  数据报表、消息中心、申诉处理添加平台显示
- 达人端: 任务列表添加平台显示
- 统一使用彩色头部条样式展示平台信息

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Your Name
2026-02-06 18:53:51 +08:00
co-authored by Claude Opus 4.5
parent 964797d2e9
commit 0bfedb95c8
22 changed files with 1784 additions and 460 deletions
+50 -21
View File
@@ -17,6 +17,7 @@ import {
} from 'lucide-react'
import { ResponsiveLayout } from '@/components/layout/ResponsiveLayout'
import { cn } from '@/lib/utils'
import { platformOptions, getPlatformInfo } from '@/lib/platforms'
// 任务阶段状态类型
type StageStatus = 'pending' | 'current' | 'done' | 'error'
@@ -26,6 +27,7 @@ type Task = {
id: string
title: string
description: string
platform: string // 发布平台
// 脚本阶段
scriptStage: {
submit: StageStatus
@@ -54,6 +56,7 @@ const mockTasks: Task[] = [
id: 'task-001',
title: 'XX品牌618推广',
description: '产品种草视频 · 时长要求 60-90秒 · 截止: 2026-02-10',
platform: 'douyin',
scriptStage: { submit: 'current', ai: 'pending', agency: 'pending', brand: 'pending' },
videoStage: { submit: 'pending', ai: 'pending', agency: 'pending', brand: 'pending' },
buttonText: '上传脚本',
@@ -65,6 +68,7 @@ const mockTasks: Task[] = [
id: 'task-002',
title: 'YY美妆新品',
description: '口播测评 · 已上传视频 · 提交于: 今天 14:30',
platform: 'xiaohongshu',
scriptStage: { submit: 'done', ai: 'current', agency: 'pending', brand: 'pending' },
videoStage: { submit: 'pending', ai: 'pending', agency: 'pending', brand: 'pending' },
buttonText: '查看详情',
@@ -76,6 +80,7 @@ const mockTasks: Task[] = [
id: 'task-003',
title: 'ZZ饮品夏日',
description: '探店Vlog · 发现2处问题 · 需修改后重新提交',
platform: 'bilibili',
scriptStage: { submit: 'done', ai: 'error', agency: 'pending', brand: 'pending' },
videoStage: { submit: 'pending', ai: 'pending', agency: 'pending', brand: 'pending' },
buttonText: '查看修改',
@@ -87,6 +92,7 @@ const mockTasks: Task[] = [
id: 'task-004',
title: 'AA数码新品发布',
description: '开箱测评 · 审核通过 · 可发布',
platform: 'douyin',
scriptStage: { submit: 'done', ai: 'done', agency: 'done', brand: 'done' },
videoStage: { submit: 'done', ai: 'done', agency: 'done', brand: 'done' },
buttonText: '查看详情',
@@ -98,6 +104,7 @@ const mockTasks: Task[] = [
id: 'task-005',
title: 'BB运动饮料',
description: '运动场景 · 脚本AI审核中 · 等待结果',
platform: 'kuaishou',
scriptStage: { submit: 'done', ai: 'current', agency: 'pending', brand: 'pending' },
videoStage: { submit: 'pending', ai: 'pending', agency: 'pending', brand: 'pending' },
buttonText: '查看详情',
@@ -109,6 +116,7 @@ const mockTasks: Task[] = [
id: 'task-006',
title: 'CC服装春季款',
description: '穿搭展示 · 脚本待代理商审核',
platform: 'xiaohongshu',
scriptStage: { submit: 'done', ai: 'done', agency: 'current', brand: 'pending' },
videoStage: { submit: 'pending', ai: 'pending', agency: 'pending', brand: 'pending' },
buttonText: '查看详情',
@@ -120,6 +128,7 @@ const mockTasks: Task[] = [
id: 'task-007',
title: 'DD家电测评',
description: '开箱视频 · 脚本待品牌终审',
platform: 'bilibili',
scriptStage: { submit: 'done', ai: 'done', agency: 'done', brand: 'current' },
videoStage: { submit: 'pending', ai: 'pending', agency: 'pending', brand: 'pending' },
buttonText: '查看详情',
@@ -131,6 +140,7 @@ const mockTasks: Task[] = [
id: 'task-008',
title: 'EE食品试吃',
description: '美食测评 · 脚本通过 · 待上传视频',
platform: 'douyin',
scriptStage: { submit: 'done', ai: 'done', agency: 'done', brand: 'done' },
videoStage: { submit: 'current', ai: 'pending', agency: 'pending', brand: 'pending' },
buttonText: '上传视频',
@@ -142,6 +152,7 @@ const mockTasks: Task[] = [
id: 'task-009',
title: 'FF护肤品',
description: '使用教程 · 视频AI审核中',
platform: 'xiaohongshu',
scriptStage: { submit: 'done', ai: 'done', agency: 'done', brand: 'done' },
videoStage: { submit: 'done', ai: 'current', agency: 'pending', brand: 'pending' },
buttonText: '查看详情',
@@ -153,6 +164,7 @@ const mockTasks: Task[] = [
id: 'task-010',
title: 'GG智能手表',
description: '功能展示 · 脚本代理商不通过',
platform: 'weibo',
scriptStage: { submit: 'done', ai: 'done', agency: 'error', brand: 'pending' },
videoStage: { submit: 'pending', ai: 'pending', agency: 'pending', brand: 'pending' },
buttonText: '查看修改',
@@ -164,6 +176,7 @@ const mockTasks: Task[] = [
id: 'task-011',
title: 'HH美妆代言',
description: '品牌代言 · 脚本品牌不通过',
platform: 'xiaohongshu',
scriptStage: { submit: 'done', ai: 'done', agency: 'done', brand: 'error' },
videoStage: { submit: 'pending', ai: 'pending', agency: 'pending', brand: 'pending' },
buttonText: '查看修改',
@@ -175,6 +188,7 @@ const mockTasks: Task[] = [
id: 'task-012',
title: 'II数码配件',
description: '配件展示 · 视频代理商审核中',
platform: 'bilibili',
scriptStage: { submit: 'done', ai: 'done', agency: 'done', brand: 'done' },
videoStage: { submit: 'done', ai: 'done', agency: 'current', brand: 'pending' },
buttonText: '查看详情',
@@ -186,6 +200,7 @@ const mockTasks: Task[] = [
id: 'task-013',
title: 'JJ旅行vlog',
description: '旅行记录 · 视频代理商不通过',
platform: 'wechat',
scriptStage: { submit: 'done', ai: 'done', agency: 'done', brand: 'done' },
videoStage: { submit: 'done', ai: 'done', agency: 'error', brand: 'pending' },
buttonText: '查看修改',
@@ -197,6 +212,7 @@ const mockTasks: Task[] = [
id: 'task-014',
title: 'KK宠物用品',
description: '宠物日常 · 视频品牌终审中',
platform: 'douyin',
scriptStage: { submit: 'done', ai: 'done', agency: 'done', brand: 'done' },
videoStage: { submit: 'done', ai: 'done', agency: 'done', brand: 'current' },
buttonText: '查看详情',
@@ -208,6 +224,7 @@ const mockTasks: Task[] = [
id: 'task-015',
title: 'LL厨房电器',
description: '使用演示 · 视频品牌不通过',
platform: 'kuaishou',
scriptStage: { submit: 'done', ai: 'done', agency: 'done', brand: 'done' },
videoStage: { submit: 'done', ai: 'done', agency: 'done', brand: 'error' },
buttonText: '查看修改',
@@ -297,6 +314,8 @@ function ProgressBar({ stage, color }: {
// 任务卡片组件
function TaskCard({ task, onClick }: { task: Task; onClick: () => void }) {
const platform = getPlatformInfo(task.platform)
const getStageColor = (color: string) => {
switch (color) {
case 'blue': return 'text-accent-blue'
@@ -320,31 +339,40 @@ function TaskCard({ task, onClick }: { task: Task; onClick: () => void }) {
return (
<div
className="bg-bg-card rounded-2xl p-5 flex flex-col gap-4 card-shadow cursor-pointer hover:bg-bg-elevated/30 transition-colors"
className="bg-bg-card rounded-2xl overflow-hidden card-shadow cursor-pointer hover:bg-bg-elevated/30 transition-colors"
onClick={onClick}
>
{/* 任务主行 */}
<div className="flex items-center justify-between">
{/* 左侧:缩略图 + 信息 */}
<div className="flex items-center gap-4">
<div className="w-20 h-[60px] rounded-lg bg-[#1A1A1E] flex items-center justify-center flex-shrink-0">
<Video className="w-6 h-6 text-text-tertiary" />
</div>
<div className="flex flex-col gap-1.5">
<span className="text-base font-semibold text-text-primary">{task.title}</span>
<span className="text-[13px] text-text-secondary">{task.description}</span>
</div>
{/* 平台顶部条 */}
{platform && (
<div className={`px-5 py-2 ${platform.bgColor} border-b ${platform.borderColor} flex items-center gap-2`}>
<span className="text-base">{platform.icon}</span>
<span className={`text-sm font-medium ${platform.textColor}`}>{platform.name}</span>
</div>
)}
{/* 右侧:操作按钮 */}
<button
type="button"
className={cn('px-5 py-2.5 rounded-[10px] text-sm font-semibold', getButtonStyle())}
onClick={(e) => { e.stopPropagation(); onClick() }}
>
{task.buttonText}
</button>
</div>
<div className="p-5 flex flex-col gap-4">
{/* 任务主行 */}
<div className="flex items-center justify-between">
{/* 左侧:缩略图 + 信息 */}
<div className="flex items-center gap-4">
<div className="w-20 h-[60px] rounded-lg bg-[#1A1A1E] flex items-center justify-center flex-shrink-0">
<Video className="w-6 h-6 text-text-tertiary" />
</div>
<div className="flex flex-col gap-1.5">
<span className="text-base font-semibold text-text-primary">{task.title}</span>
<span className="text-[13px] text-text-secondary">{task.description}</span>
</div>
</div>
{/* 右侧:操作按钮 */}
<button
type="button"
className={cn('px-5 py-2.5 rounded-[10px] text-sm font-semibold', getButtonStyle())}
onClick={(e) => { e.stopPropagation(); onClick() }}
>
{task.buttonText}
</button>
</div>
{/* 进度条容器 */}
<div className="flex flex-col gap-3 pt-3">
@@ -363,6 +391,7 @@ function TaskCard({ task, onClick }: { task: Task; onClick: () => void }) {
</div>
</div>
</div>
</div>
</div>
)
}