From 998b0bfb93b94790eb77e7c5f7e1ddb25fb0332b Mon Sep 17 00:00:00 2001 From: seaislee1209 Date: Sat, 20 Jun 2026 19:21:31 +0800 Subject: [PATCH] =?UTF-8?q?fix(product-detail):=20=E7=B4=A0=E6=9D=90?= =?UTF-8?q?=E5=8D=A1=E3=80=8C=E5=BD=92=E6=A1=A3=E3=80=8D=E6=8C=89=E9=92=AE?= =?UTF-8?q?=20=E2=86=92=20=E5=8F=AA=E8=AF=BB=E5=AE=A1=E6=A0=B8=E7=8A=B6?= =?UTF-8?q?=E6=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 状态不再是用户可点循环(通过/不通过/归档),改为只读展示团队审核结果 - 状态值 archive→pending:active(绿盾)=通过 / failed(红标)=不通过 / 其它=待审核 - 移除 statusOverrides 本地覆盖 + cycleAssetStatus + 采用三视图的状态联动 - 筛选项「归档」→「待审核」;CSS .pill.archive→.pill.pending 去 cursor:pointer Co-Authored-By: Claude Opus 4.8 --- core/frontend/src/product-detail-page.css | 7 +-- core/frontend/src/routes/products.tsx | 56 +++++------------------ 2 files changed, 14 insertions(+), 49 deletions(-) diff --git a/core/frontend/src/product-detail-page.css b/core/frontend/src/product-detail-page.css index 6f7067b..137aa10 100644 --- a/core/frontend/src/product-detail-page.css +++ b/core/frontend/src/product-detail-page.css @@ -502,24 +502,21 @@ .qa-item.primary .ic { background: var(--accent-white); color: var(--heat); border-color: var(--accent-white); } .qa-item.primary:hover { color: var(--accent-white); box-shadow: var(--shadow-cta-hover); } - /* 状态 pill 三态(通过/不通过/归档) */ + /* 审核状态 pill 三态(通过/不通过/待审核)· 只读,不再可点(去 cursor:pointer) */ .asset-card .meta .pill.pass { background: var(--accent-emerald-bg, #e6f4ec); color: var(--accent-emerald, #1f8a51); border: 1px solid var(--accent-emerald-bd, #c4e3d1); - cursor: pointer; } .asset-card .meta .pill.fail { background: var(--crimson-bg, #fdebea); color: var(--accent-crimson, #c43d3d); border: 1px solid var(--crimson-bd, #f5c2bf); - cursor: pointer; } - .asset-card .meta .pill.archive { + .asset-card .meta .pill.pending { background: var(--background-lighter); color: var(--black-alpha-56); border: 1px solid var(--border-faint); - cursor: pointer; } /* ─── Tabs ─── */ diff --git a/core/frontend/src/routes/products.tsx b/core/frontend/src/routes/products.tsx index ee90a4e..c62891c 100644 --- a/core/frontend/src/routes/products.tsx +++ b/core/frontend/src/routes/products.tsx @@ -521,22 +521,21 @@ export function ProductCreateUploadPage({ onCreate, onBack }: { onCreate: (paylo // 商品详情页 · 从 public/exact/product-detail.html 忠实转写。 // 名称 / 品类 / 目标人群 / 卖点 来自 product;商品图网格 / AI 素材卡 / 视频项目卡 // 已接入真实数据(product.images + 团队 assets + 该商品 projects),保持设计稿像素布局。 -type PdAssetStatus = "pass" | "fail" | "archive"; -const PD_ASSET_STATUS_LABEL: Record = { pass: "通过", fail: "不通过", archive: "归档" }; -// 点击循环顺序:通过 → 不通过 → 归档 → 通过(忠实移植 product-detail.html) -const PD_STATUS_CYCLE: PdAssetStatus[] = ["pass", "fail", "archive"]; +// 素材审核状态(只读,反映团队审核结果,非用户可点切换) +type PdAssetStatus = "pass" | "fail" | "pending"; +const PD_ASSET_STATUS_LABEL: Record = { pass: "通过", fail: "不通过", pending: "待审核" }; const PD_STATUS_FILTER_OPTS: Array<{ value: "" | PdAssetStatus; label: string }> = [ { value: "", label: "全部状态" }, { value: "pass", label: "通过" }, { value: "fail", label: "不通过" }, - { value: "archive", label: "归档" } + { value: "pending", label: "待审核" } ]; -// 真实火山审核状态 → 三态基线:active(绿盾)→通过 · failed(红标)→不通过 · 其它("" / processing 等)→归档(中性,未定论) +// 真实审核状态 → 三态:active(绿盾)→通过 · failed(红标)→不通过 · 其它("" / processing 等)→待审核 function pdBaseStatus(asset: Asset): PdAssetStatus { const r = asset.review_status || ""; if (r === "active") return "pass"; if (r === "failed") return "fail"; - return "archive"; + return "pending"; } const PD_CAT_OPTIONS = ["美妆个护 / 精华液", "美妆个护", "服饰内衣", "食品饮料", "家居家电", "数码 3C", "个护清洁", "运动户外", "母婴亲子"]; @@ -596,13 +595,12 @@ export function ProductDetailPage({ product, projects, initialTab = "assets", na // 素材 tab 筛选 / 排序 / 分页 / 视图 const [openFilter, setOpenFilter] = useState<"" | "type" | "status" | "sort">(""); const [typeFilter, setTypeFilter] = useState(""); - const [statusFilter, setStatusFilter] = useState<"" | "pass" | "fail" | "archive">(""); + const [statusFilter, setStatusFilter] = useState<"" | "pass" | "fail" | "pending">(""); const [assetView, setAssetView] = useState<"grid" | "list">("grid"); const [assetSortDesc, setAssetSortDesc] = useState(true); const [assetLimit, setAssetLimit] = useState(12); const [videoSortDesc, setVideoSortDesc] = useState(true); - // 素材审核状态本地覆盖(点击循环 / 采用联动写入);未覆盖则回退真实 review_status 映射 - const [statusOverrides, setStatusOverrides] = useState>({}); + // 素材审核状态为只读(直接反映 review_status),不再有用户点击覆盖 // 采用三视图后,本地 prepend 的新素材卡(供「采用版本联动 + prepend 新卡」即时呈现,不等服务端回灌) const [adoptedAssets, setAdoptedAssets] = useState([]); // 图片预览灯箱 @@ -680,17 +678,7 @@ export function ProductDetailPage({ product, projects, initialTab = "assets", na setTriAdoptedId(triViewing.id); const adopted = triViewing.asset; if (adopted) { - // 联动:被采用的三视图 → 通过(绿);该商品其余三视图 → 不通过(红)。其他类型素材不受影响。 - setStatusOverrides((prev) => { - const next = { ...prev }; - const triIds = new Set(); - for (const a of allAssetsBase) { - if (a.category === "tri_view" || a.asset_type === "tri_view") triIds.add(a.id); - } - triIds.add(adopted.id); - triIds.forEach((id) => { next[id] = id === adopted.id ? "pass" : "fail"; }); - return next; - }); + // 审核状态已改为只读(反映 review_status),不再在采用三视图时本地覆盖状态 // prepend 新卡:若服务端素材列表里还没有这条采用资产,先本地置顶呈现(去重) setAdoptedAssets((prev) => { if (prev.some((a) => a.id === adopted.id) || allImageAssets.some((a) => a.id === adopted.id)) return prev; @@ -720,7 +708,7 @@ export function ProductDetailPage({ product, projects, initialTab = "assets", na // 联动采用状态前的「全部素材基线」(供 adoptTriView 找出该商品所有三视图) const allAssetsBase = allImageAssets; // 单个素材当前显示状态:本地覆盖(点击循环 / 采用联动)优先,否则回退真实 review_status 映射 - const statusOf = (asset: Asset): PdAssetStatus => statusOverrides[asset.id] || pdBaseStatus(asset); + const statusOf = (asset: Asset): PdAssetStatus => pdBaseStatus(asset); // 类型筛选选项(当前素材里真实存在的 category) const typeOptions = Array.from(new Set(allImageAssets.map((a) => a.category).filter(Boolean))); // 全集计数(给状态筛选下拉做计数前缀,不随当前筛选变化) @@ -736,16 +724,6 @@ export function ProductDetailPage({ product, projects, initialTab = "assets", na const imageAssets = filteredAssets.slice(0, assetLimit); const hasActiveAssetFilter = Boolean(typeFilter || statusFilter); const resetAssetFilters = () => { setTypeFilter(""); setStatusFilter(""); setAssetLimit(12); setOpenFilter(""); }; - // 点击素材状态 pill 循环:通过 → 不通过 → 归档。三视图状态由「采用版本」决定,不在此循环(忠实移植 V1)。 - const cycleAssetStatus = (asset: Asset) => { - if (asset.category === "tri_view" || asset.asset_type === "tri_view") return; - setStatusOverrides((prev) => { - const cur = prev[asset.id] || pdBaseStatus(asset); - const nextStatus = PD_STATUS_CYCLE[(PD_STATUS_CYCLE.indexOf(cur) + 1) % PD_STATUS_CYCLE.length]; - return { ...prev, [asset.id]: nextStatus }; - }); - }; - // 视频项目 · 用传入的该商品 projects 渲染真实项目名 / 状态 / 阶段(按更新时间排序) const videoProjects = [...projects].sort((a, b) => { const cmp = (b.updated_at || "").localeCompare(a.updated_at || ""); @@ -1100,7 +1078,6 @@ export function ProductDetailPage({ product, projects, initialTab = "assets", na {imageAssets.map((asset) => { const url = pdAssetPreview(asset); const status = statusOf(asset); - const isTri = asset.category === "tri_view" || asset.asset_type === "tri_view"; return (
setPreview({ src: url, name: asset.name }) : undefined} onKeyDown={url ? (event) => { if (event.key === "Enter" || event.key === " ") { event.preventDefault(); setPreview({ src: url, name: asset.name }); } } : undefined}> @@ -1109,17 +1086,8 @@ export function ProductDetailPage({ product, projects, initialTab = "assets", na {url ? null : 3:4}
- {/* 状态 pill 三态可点循环;三视图状态由「采用版本」决定,此处不可点 */} - cycleAssetStatus(asset)} - onKeyDown={(event) => { if (!isTri && (event.key === "Enter" || event.key === " ")) { event.preventDefault(); cycleAssetStatus(asset); } }} - >{PD_ASSET_STATUS_LABEL[status]} + {/* 审核状态(只读):团队审核给出 通过 / 不通过,未定论显示 待审核 —— 不再是可点切换的按钮 */} + {PD_ASSET_STATUS_LABEL[status]} {(asset.created_at || "").slice(0, 10)}