Your Name e4959d584f feat: 完善代理商端业务逻辑与前后端框架
主要更新:
- 更新代理商端文档,明确项目由品牌方分配流程
- 新增Brief配置详情页(已配置)设计稿
- 完善工作台紧急待办中品牌新任务功能
- 整理Pencil设计文件中代理商端页面顺序
- 新增后端FastAPI框架及核心API
- 新增前端Next.js页面和组件库
- 添加.gitignore排除构建和缓存文件

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 19:27:31 +08:00

208 lines
7.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* ReviewSteps 审核进度条组件
* 设计稿参考: pencil-new.pen 达人端任务列表
* 显示4个步骤已提交 → AI审核中 → 代理商审核 → 审核通过
*/
import React from 'react'
import { Check, X, Loader2, Users } from 'lucide-react'
export type StepStatus = 'done' | 'current' | 'failed' | 'pending'
export interface ReviewStep {
key: string
label: string
status: StepStatus
}
interface ReviewStepsProps {
steps: ReviewStep[]
className?: string
}
function StepIcon({ status, isLast }: { status: StepStatus; isLast: boolean }) {
const baseClass = 'w-7 h-7 rounded-full flex items-center justify-center'
switch (status) {
case 'done':
return (
<div className={`${baseClass} bg-accent-green`}>
<Check size={14} className="text-white" />
</div>
)
case 'current':
return (
<div className={`${baseClass} bg-accent-indigo`}>
<Loader2 size={14} className="text-white animate-spin" />
</div>
)
case 'failed':
return (
<div className={`${baseClass} bg-accent-coral`}>
<X size={14} className="text-white" />
</div>
)
case 'pending':
default:
return (
<div className={`${baseClass} bg-bg-elevated border-[1.5px] border-border-subtle`}>
{isLast ? (
<Check size={14} className="text-text-tertiary" />
) : (
<Users size={14} className="text-text-tertiary" />
)}
</div>
)
}
}
function StepLine({ active }: { active: boolean }) {
return (
<div
className={`flex-1 h-0.5 mx-1 ${active ? 'bg-accent-green' : 'bg-border-subtle'}`}
/>
)
}
export const ReviewSteps: React.FC<ReviewStepsProps> = ({ steps, className = '' }) => {
return (
<div className={`flex items-center w-full py-2 ${className}`}>
{steps.map((step, index) => {
const isLast = index === steps.length - 1
const nextStepActive = index < steps.length - 1 &&
(steps[index + 1].status === 'done' || steps[index + 1].status === 'current' || steps[index + 1].status === 'failed')
return (
<React.Fragment key={step.key}>
<div className="flex flex-col items-center w-[70px]">
<StepIcon status={step.status} isLast={isLast} />
<span
className={`text-[11px] mt-1 font-medium ${
step.status === 'done' ? 'text-text-secondary' :
step.status === 'current' ? 'text-accent-indigo' :
step.status === 'failed' ? 'text-accent-coral' :
'text-text-tertiary'
}`}
>
{step.label}
</span>
</div>
{!isLast && <StepLine active={step.status === 'done' || nextStepActive} />}
</React.Fragment>
)
})}
</div>
)
}
// 根据任务状态生成步骤数据 (达人端视角)
export function getReviewSteps(taskStatus: string): ReviewStep[] {
switch (taskStatus) {
case 'pending_upload':
return [
{ key: 'submitted', label: '已提交', status: 'pending' },
{ key: 'ai_review', label: 'AI审核', status: 'pending' },
{ key: 'agent_review', label: '代理商审核', status: 'pending' },
{ key: 'passed', label: '审核通过', status: 'pending' },
]
case 'ai_reviewing':
return [
{ key: 'submitted', label: '已提交', status: 'done' },
{ key: 'ai_review', label: 'AI审核中', status: 'current' },
{ key: 'agent_review', label: '代理商审核', status: 'pending' },
{ key: 'passed', label: '审核通过', status: 'pending' },
]
case 'agent_reviewing':
return [
{ key: 'submitted', label: '已提交', status: 'done' },
{ key: 'ai_review', label: 'AI审核', status: 'done' },
{ key: 'agent_review', label: '代理商审核', status: 'current' },
{ key: 'passed', label: '审核通过', status: 'pending' },
]
case 'need_revision':
return [
{ key: 'submitted', label: '已提交', status: 'done' },
{ key: 'ai_review', label: '需修改', status: 'failed' },
{ key: 'agent_review', label: '代理商审核', status: 'pending' },
{ key: 'passed', label: '审核通过', status: 'pending' },
]
case 'passed':
return [
{ key: 'submitted', label: '已提交', status: 'done' },
{ key: 'ai_review', label: 'AI审核', status: 'done' },
{ key: 'agent_review', label: '代理商审核', status: 'done' },
{ key: 'passed', label: '审核通过', status: 'done' },
]
case 'rejected':
return [
{ key: 'submitted', label: '已提交', status: 'done' },
{ key: 'ai_review', label: 'AI审核', status: 'done' },
{ key: 'agent_review', label: '已驳回', status: 'failed' },
{ key: 'passed', label: '审核通过', status: 'pending' },
]
default:
return [
{ key: 'submitted', label: '已提交', status: 'pending' },
{ key: 'ai_review', label: 'AI审核', status: 'pending' },
{ key: 'agent_review', label: '代理商审核', status: 'pending' },
{ key: 'passed', label: '审核通过', status: 'pending' },
]
}
}
// 代理商/品牌方视角的审核步骤 (包含品牌终审)
export function getAgencyReviewSteps(taskStatus: string): ReviewStep[] {
switch (taskStatus) {
case 'ai_reviewing':
return [
{ key: 'submitted', label: '已提交', status: 'done' },
{ key: 'ai_review', label: 'AI审核', status: 'current' },
{ key: 'agent_review', label: '代理商', status: 'pending' },
{ key: 'brand_review', label: '品牌终审', status: 'pending' },
]
case 'agent_reviewing':
return [
{ key: 'submitted', label: '已提交', status: 'done' },
{ key: 'ai_review', label: 'AI审核', status: 'done' },
{ key: 'agent_review', label: '代理商', status: 'current' },
{ key: 'brand_review', label: '品牌终审', status: 'pending' },
]
case 'brand_reviewing':
return [
{ key: 'submitted', label: '已提交', status: 'done' },
{ key: 'ai_review', label: 'AI审核', status: 'done' },
{ key: 'agent_review', label: '代理商', status: 'done' },
{ key: 'brand_review', label: '品牌终审', status: 'current' },
]
case 'need_revision':
return [
{ key: 'submitted', label: '已提交', status: 'done' },
{ key: 'ai_review', label: '需修改', status: 'failed' },
{ key: 'agent_review', label: '代理商', status: 'pending' },
{ key: 'brand_review', label: '品牌终审', status: 'pending' },
]
case 'passed':
return [
{ key: 'submitted', label: '已提交', status: 'done' },
{ key: 'ai_review', label: 'AI审核', status: 'done' },
{ key: 'agent_review', label: '代理商', status: 'done' },
{ key: 'brand_review', label: '品牌终审', status: 'done' },
]
case 'rejected':
return [
{ key: 'submitted', label: '已提交', status: 'done' },
{ key: 'ai_review', label: 'AI审核', status: 'done' },
{ key: 'agent_review', label: '已驳回', status: 'failed' },
{ key: 'brand_review', label: '品牌终审', status: 'pending' },
]
default:
return [
{ key: 'submitted', label: '已提交', status: 'done' },
{ key: 'ai_review', label: 'AI审核', status: 'done' },
{ key: 'agent_review', label: '代理商', status: 'current' },
{ key: 'brand_review', label: '品牌终审', status: 'pending' },
]
}
}
export default ReviewSteps