import * as React from "react" import { AlertCircle, CheckCircle2, Clock, Filter, Plus, RefreshCw, Search } from "lucide-react" import type { RoleView, WorkflowConfig } from "@/App" import { Badge } from "@/components/ui/badge" import { Button } from "@/components/ui/button" import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card" import { Input } from "@/components/ui/input" import { Progress } from "@/components/ui/progress" import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@/components/ui/table" type SyncStatus = "synced" | "pending" | "error" type SourceCar = { id: string name: string officialTagline: string sourceUpdatedAt: string syncStatus: SyncStatus imageCount: number } type SyncLog = { id: string time: string status: "success" | "failed" message: string } type CarLibraryProps = { roleView: RoleView workflowConfig: WorkflowConfig onAddAuditLog: (message: string) => void onCreateContent?: (sourceCarId: string, sourceCarName: string) => void } const SOURCE_CARS: SourceCar[] = [ { id: "a3", name: "Audi A3 Sportback", officialTagline: "进取,不负期待", sourceUpdatedAt: "2026-04-11 09:30", syncStatus: "synced", imageCount: 8, }, { id: "a4l", name: "Audi A4L", officialTagline: "做更强大的自己", sourceUpdatedAt: "2026-04-11 09:30", syncStatus: "synced", imageCount: 6, }, { id: "a6l", name: "Audi A6L", officialTagline: "懂你,更懂未来", sourceUpdatedAt: "2026-04-10 14:20", syncStatus: "pending", imageCount: 5, }, { id: "q5l", name: "Audi Q5L", officialTagline: "自由,由我定义", sourceUpdatedAt: "2026-04-10 09:15", syncStatus: "error", imageCount: 0, }, ] const INITIAL_LOGS: SyncLog[] = [ { id: "l1", time: "2026-04-11 09:30", status: "success", message: "同步成功:4 个车型,素材 19 张" }, { id: "l2", time: "2026-04-10 09:15", status: "failed", message: "Audi Q5L 图片拉取失败:CDN 超时" }, ] function syncBadge(status: SyncStatus) { if (status === "synced") { return ( 已同步 ) } if (status === "pending") { return ( 待同步 ) } return ( 同步失败 ) } function nowString() { return new Date().toLocaleString("zh-CN", { hour12: false }) } export function CarLibrary({ onAddAuditLog, onCreateContent }: CarLibraryProps) { const [sourceCars, setSourceCars] = React.useState(SOURCE_CARS) const [query, setQuery] = React.useState("") const [isSyncing, setIsSyncing] = React.useState(false) const [progress, setProgress] = React.useState(0) const [syncLogs, setSyncLogs] = React.useState(INITIAL_LOGS) const filtered = sourceCars.filter((car) => car.name.toLowerCase().includes(query.toLowerCase())) const handleSync = () => { setIsSyncing(true) setProgress(0) const interval = setInterval(() => { setProgress((prev) => { if (prev >= 100) { clearInterval(interval) const time = nowString() setSourceCars((curr) => curr.map((car) => ({ ...car, sourceUpdatedAt: time, syncStatus: "synced", imageCount: car.imageCount || 4, })) ) setSyncLogs((curr) => [ { id: String(Date.now()), time, status: "success", message: "手动同步完成:4 个车型已更新" }, ...curr, ]) onAddAuditLog("内容运营专员执行官网车型同步") setTimeout(() => setIsSyncing(false), 300) return 100 } return prev + 4 }) }, 45) } const retryFailedSync = (logId: string) => { const time = nowString() setSyncLogs((curr) => curr.map((log) => log.id === logId ? { ...log, status: "success", time, message: `${log.message} -> 已重试成功` } : log ) ) setSourceCars((curr) => curr.map((car) => (car.syncStatus === "error" ? { ...car, syncStatus: "synced", sourceUpdatedAt: time, imageCount: 4 } : car)) ) onAddAuditLog("项目与运维负责人重试官网同步失败任务") } return (

车型库(官网同步源)

本页仅管理官网同步原始数据。编辑、审核、发布请前往“小程序内容库”。

{isSyncing && (
正在同步官网车型素材... {Math.round(progress)}%
)}
官网车型列表 Source Entity: SourceCar
setQuery(e.target.value)} placeholder="搜索官网车型名称..." className="pl-9 bg-gray-50/50 border-none" />
车型名称 官网文案 图片数量 同步状态 最近同步 操作 {filtered.map((car) => ( {car.name} {car.officialTagline} {car.imageCount} 张 {syncBadge(car.syncStatus)} {car.sourceUpdatedAt} {car.syncStatus === "synced" ? ( ) : ( )} ))}
同步记录 同步异常可重试,重试结果将写入本页日志。 {syncLogs.map((log) => (
{log.status === "success" ? ( ) : ( )}

{log.message}

{log.time}

{log.status === "failed" && ( )}
))}
) }