import * as React from "react" import { ArrowLeft, Eye, Pencil, Send, ShieldCheck, Undo2, Upload, XCircle, } 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 { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@/components/ui/table" type WorkflowStatus = "draft" | "pending" | "prepublished" | "published" | "rejected" | "recalled" type MiniAppContent = { id: string sourceCarId: string sourceCarName: string title: string subtitle: string highlights: string description: string ctaText: string scheduledPublishAt: string imageUrls: string[] workflowStatus: WorkflowStatus updatedBy: string updatedAt: string } type MiniAppContentLibraryProps = { roleView: RoleView workflowConfig: WorkflowConfig onAddAuditLog: (message: string) => void newContentRequest?: { sourceCarId: string sourceCarName: string requestId: string } | null } const CONTENTS: MiniAppContent[] = [ { id: "c1", sourceCarId: "a3", sourceCarName: "Audi A3 Sportback", title: "Audi A3 Sportback", subtitle: "进取,不负期待", highlights: "数字座舱\n城市通勤\n智能互联", description: "适合城市用户的豪华紧凑车型,兼顾效率与智能体验。", ctaText: "立即预约试驾", scheduledPublishAt: "", imageUrls: [ "https://images.unsplash.com/photo-1606152421802-db97b9c7a11b?auto=format&fit=crop&q=80&w=1200", "https://picsum.photos/seed/a3-content-1/900/600", "https://picsum.photos/seed/a3-content-2/900/600", ], workflowStatus: "published", updatedBy: "内容运营专员", updatedAt: "2026-04-11 10:02", }, { id: "c2", sourceCarId: "a4l", sourceCarName: "Audi A4L", title: "Audi A4L 四月限时礼遇", subtitle: "豪华与性能平衡", highlights: "quattro\n商务舒适\n限时礼遇", description: "面向商务人群的主推内容版本,突出舒适与操控。", ctaText: "获取活动详情", scheduledPublishAt: "2026-04-14T10:00", imageUrls: [ "https://images.unsplash.com/photo-1614162692292-7ac56d7f7f1e?auto=format&fit=crop&q=80&w=1200", "https://picsum.photos/seed/a4-content-1/900/600", ], workflowStatus: "prepublished", updatedBy: "业务/市场负责人", updatedAt: "2026-04-11 09:48", }, { id: "c3", sourceCarId: "a6l", sourceCarName: "Audi A6L", title: "Audi A6L", subtitle: "懂你,更懂未来", highlights: "行政旗舰\n长轴空间\n智能辅助", description: "正在进行文案优化,待业务审核。", ctaText: "预约顾问回电", scheduledPublishAt: "", imageUrls: [ "https://images.unsplash.com/photo-1541348263662-e0c86433610a?auto=format&fit=crop&q=80&w=1200", ], workflowStatus: "pending", updatedBy: "内容运营专员", updatedAt: "2026-04-11 09:30", }, { id: "c4", sourceCarId: "q3", sourceCarName: "Audi Q3", title: "Audi Q3 城市灵动版", subtitle: "年轻进阶,灵动出行", highlights: "紧凑SUV\n智能互联\n都市通勤", description: "新建草稿,待进一步补充图文和活动权益信息。", ctaText: "预约试驾", scheduledPublishAt: "", imageUrls: [ "https://picsum.photos/seed/q3-content-1/900/600", ], workflowStatus: "draft", updatedBy: "内容运营专员", updatedAt: "2026-04-11 08:40", }, { id: "c5", sourceCarId: "q5l", sourceCarName: "Audi Q5L", title: "Audi Q5L 周末试驾礼遇", subtitle: "自由,由我定义", highlights: "四驱性能\n家庭空间\n周末活动", description: "因权益文案与活动规则不一致,被驳回待修订。", ctaText: "了解礼遇", scheduledPublishAt: "", imageUrls: [ "https://picsum.photos/seed/q5-content-1/900/600", ], workflowStatus: "rejected", updatedBy: "业务/市场负责人", updatedAt: "2026-04-11 08:10", }, { id: "c6", sourceCarId: "a8l", sourceCarName: "Audi A8L", title: "Audi A8L 尊享礼宾版", subtitle: "旗舰格局,沉稳之选", highlights: "旗舰行政\n豪华座舱\n专属服务", description: "已发布后因活动档期调整撤回,待重新排期。", ctaText: "预约专属顾问", scheduledPublishAt: "2026-04-15T09:30", imageUrls: [ "https://picsum.photos/seed/a8-content-1/900/600", ], workflowStatus: "recalled", updatedBy: "业务/市场负责人", updatedAt: "2026-04-11 07:55", }, ] const WORKFLOW_LABEL: Record = { draft: "草稿", pending: "待审核", prepublished: "预发布", published: "已发布", rejected: "已驳回", recalled: "已撤回", } function workflowBadgeClass(status: WorkflowStatus) { switch (status) { case "draft": return "bg-gray-100 text-gray-700 border-gray-200" case "pending": return "bg-amber-50 text-amber-700 border-amber-200" case "prepublished": return "bg-blue-50 text-blue-700 border-blue-200" case "published": return "bg-emerald-50 text-emerald-700 border-emerald-200" case "rejected": return "bg-rose-50 text-rose-700 border-rose-200" case "recalled": return "bg-zinc-100 text-zinc-700 border-zinc-200" } } function nowString() { return new Date().toLocaleString("zh-CN", { hour12: false }) } export function MiniAppContentLibrary({ roleView, workflowConfig, onAddAuditLog, newContentRequest }: MiniAppContentLibraryProps) { const [contents, setContents] = React.useState(CONTENTS) const [viewMode, setViewMode] = React.useState<"list" | "editor">("list") const [selectedId, setSelectedId] = React.useState(CONTENTS[0].id) const [newImageUrl, setNewImageUrl] = React.useState("") React.useEffect(() => { if (!newContentRequest) return const id = `c${newContentRequest.requestId}` const existing = contents.find((item) => item.id === id) if (!existing) { const draft: MiniAppContent = { id, sourceCarId: newContentRequest.sourceCarId, sourceCarName: newContentRequest.sourceCarName, title: newContentRequest.sourceCarName, subtitle: "", highlights: "", description: "", ctaText: "立即预约试驾", scheduledPublishAt: "", imageUrls: [], workflowStatus: "draft", updatedBy: "内容运营专员", updatedAt: nowString(), } setContents((prev) => [draft, ...prev]) } setSelectedId(id) setViewMode("editor") }, [newContentRequest?.requestId]) const canEdit = roleView === "content-ops" const canApprove = roleView === "biz-market" const selected = contents.find((item) => item.id === selectedId) ?? null const updateContent = (id: string, patch: Partial) => { setContents((prev) => prev.map((item) => (item.id === id ? { ...item, ...patch, updatedAt: nowString() } : item)) ) } const saveDraft = (item: MiniAppContent) => { updateContent(item.id, { workflowStatus: "draft", updatedBy: "内容运营专员" }) onAddAuditLog(`内容运营专员保存 ${item.sourceCarName} 内容草稿`) } const submitForReview = (item: MiniAppContent) => { updateContent(item.id, { workflowStatus: "pending", updatedBy: "内容运营专员" }) onAddAuditLog(`内容运营专员提交 ${item.sourceCarName} 到审核队列`) } const withdrawReview = (item: MiniAppContent) => { updateContent(item.id, { workflowStatus: "draft", updatedBy: "内容运营专员" }) onAddAuditLog(`内容运营专员撤回 ${item.sourceCarName} 的审核申请`) } const approve = (item: MiniAppContent) => { const nextStatus: WorkflowStatus = workflowConfig.enablePrePublish ? "prepublished" : "published" updateContent(item.id, { workflowStatus: nextStatus, updatedBy: "业务/市场负责人" }) onAddAuditLog(`业务/市场负责人审批通过 ${item.sourceCarName}`) } const reject = (item: MiniAppContent) => { updateContent(item.id, { workflowStatus: "rejected", updatedBy: "业务/市场负责人" }) onAddAuditLog(`业务/市场负责人驳回 ${item.sourceCarName} 内容版本`) } const publish = (item: MiniAppContent) => { const actor = roleView === "biz-market" ? "业务/市场负责人" : "内容运营专员" updateContent(item.id, { workflowStatus: "published", updatedBy: actor }) onAddAuditLog(`${actor}发布 ${item.sourceCarName} 到小程序`) } const recall = (item: MiniAppContent) => { updateContent(item.id, { workflowStatus: "recalled", updatedBy: "业务/市场负责人" }) onAddAuditLog(`业务/市场负责人撤回 ${item.sourceCarName} 已发布内容`) } const revive = (item: MiniAppContent) => { const nextStatus: WorkflowStatus = workflowConfig.enablePrePublish ? "prepublished" : "published" updateContent(item.id, { workflowStatus: nextStatus, updatedBy: "业务/市场负责人" }) onAddAuditLog(`业务/市场负责人恢复 ${item.sourceCarName} 的发布流程`) } const createNewVersion = (item: MiniAppContent) => { updateContent(item.id, { workflowStatus: "draft", updatedBy: "内容运营专员" }) onAddAuditLog(`内容运营专员基于 ${item.sourceCarName} 发布版本创建新稿`) } const addImage = (item: MiniAppContent) => { const next = newImageUrl.trim() if (!next) return updateContent(item.id, { imageUrls: [...item.imageUrls, next] }) setNewImageUrl("") } const removeImage = (item: MiniAppContent, idx: number) => { updateContent(item.id, { imageUrls: item.imageUrls.filter((_, i) => i !== idx) }) } const renderActions = (item: MiniAppContent) => { const actions: React.ReactNode[] = [] if (canEdit) { if (item.workflowStatus === "draft" || item.workflowStatus === "rejected" || item.workflowStatus === "recalled") { actions.push( ) } if (item.workflowStatus === "pending") { actions.push( ) } if (item.workflowStatus === "prepublished") { actions.push( ) } if (item.workflowStatus === "published") { actions.push( ) } } if (canApprove) { if (item.workflowStatus === "pending") { actions.push( ) actions.push( ) } if (workflowConfig.allowRecall && item.workflowStatus === "published") { actions.push( ) } if (item.workflowStatus === "recalled") { actions.push( ) } } actions.push( ) return actions } if (viewMode === "editor" && selected) { const highlights = selected.highlights .split("\n") .map((s) => s.trim()) .filter(Boolean) return (

小程序内容编辑

独立编辑页:左侧字段编辑,右侧手机窗口预览。

当前状态:{WORKFLOW_LABEL[selected.workflowStatus]}
编辑字段 基于官网源车型生成的内容实体(MiniAppContent)。
updateContent(selected.id, { title: e.target.value })} />
updateContent(selected.id, { subtitle: e.target.value })} />