fix: 测试清单一轮bug修复(商品库/视频项目/设置/消费/平台套图)

- 商品库编辑删图假成功+悬停无删除图标;商品三视图错显角色三视图
- 视频项目演员删除入口;角色三视图防呆;故事板审核失败原因透出
- 设置:管理团队死按钮/通知未接入项屏蔽/邮箱验证链路
- 消费:账单流水切换类型重置分页+独立总页数
- 资产库上传按钮隐藏;月限额两处对齐
- 平台套图:提示词框放大/选模型胶囊内嵌/未读任务角标/工作台记录持久化
- 新建商品独立添加卖点按钮;商品库超1920自适应

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
zyc
2026-06-30 19:46:35 +08:00
co-authored by Claude Opus 4.8
parent b17a716c06
commit 22268d608b
14 changed files with 261 additions and 107 deletions
@@ -42,8 +42,9 @@ export function ProductCreateDrawer({ open, close, onCreate, onCreated, catOptio
const [title, setTitle] = useState("");
const [category, setCategory] = useState("");
const [target, setTarget] = useState("");
// 卖点 = 一组可直接编辑的输入行(每行一条);点「添加卖点」按钮新增一条空行,
// 不再靠「在一个输入框里回车隐晦追加」(YYX#17)。
const [bullets, setBullets] = useState<string[]>([]);
const [bulletDraft, setBulletDraft] = useState("");
const [images, setImages] = useState<PfImage[]>([]);
const [dragOver, setDragOver] = useState(false);
const [titleError, setTitleError] = useState(false);
@@ -74,7 +75,6 @@ export function ProductCreateDrawer({ open, close, onCreate, onCreated, catOptio
setCategory("");
setTarget("");
setBullets([]);
setBulletDraft("");
setImages((list) => { list.forEach((item) => URL.revokeObjectURL(item.url)); return []; });
setDragOver(false);
setTitleError(false);
@@ -84,7 +84,7 @@ export function ProductCreateDrawer({ open, close, onCreate, onCreated, catOptio
// YYX#24:表单是否已填内容(有任一内容即视为「编辑中」)
function isDirty() {
return Boolean(title.trim() || target.trim() || bulletDraft.trim() || bullets.length || images.length);
return Boolean(title.trim() || target.trim() || bullets.some((b) => b.trim()) || images.length);
}
// 关闭入口统一走这里:有内容则先二次确认,否则直接关
function guardedClose() {
@@ -152,11 +152,12 @@ export function ProductCreateDrawer({ open, close, onCreate, onCreated, catOptio
if (event.dataTransfer?.files?.length) addImages(event.dataTransfer.files);
}
// 点「添加卖点」→ 追加一条空的可编辑卖点行(显式新增,不靠回车隐晦添加)
function addBullet() {
const value = bulletDraft.trim();
if (!value) return;
setBullets((list) => [...list, value]);
setBulletDraft("");
setBullets((list) => [...list, ""]);
}
function updateBullet(index: number, value: string) {
setBullets((list) => list.map((item, position) => (position === index ? value : item)));
}
function removeBullet(index: number) {
setBullets((list) => list.filter((_, position) => position !== index));
@@ -169,10 +170,9 @@ export function ProductCreateDrawer({ open, close, onCreate, onCreated, catOptio
// upload-first:图必须先全部传完进桶(拿到 assetId)才能带进创建
if (images.some((im) => im.status === "uploading")) { flash("图片上传中", "请等图片传完再创建"); return; }
if (images.some((im) => im.status === "error" || !im.assetId)) { flash("有图片未传成功", "请移除失败的图后重试"); return; }
// 提交时自动收编未回车的 bulletDraft,避免用户输入了卖点却被丢弃
const pending = bulletDraft.trim();
const finalBullets = pending ? [...bullets, pending] : bullets;
if (finalBullets.length === 0) { flash("请填写核心卖点", "至少 1 条 · 回车确认"); return; }
// 卖点行可能有空行(用户点了「添加卖点」还没填):提交时过滤掉空行再去重判空
const finalBullets = bullets.map((item) => item.trim()).filter(Boolean);
if (finalBullets.length === 0) { flash("请填写核心卖点", "至少 1 条"); return; }
setSaving(true);
try {
@@ -284,23 +284,28 @@ export function ProductCreateDrawer({ open, close, onCreate, onCreated, catOptio
<div className="field pc-field-last">
<label className="field-label">核心卖点<span className="req">*</span></label>
{/* YYX#17:每条卖点 = 一行可直接编辑的输入;新增卖点走下方独立「添加卖点」按钮,
不再在一个框里靠回车隐晦追加。 */}
<ul className="bullet-list">
{bullets.map((bullet, index) => (
<li className="bl-item" key={`${bullet}-${index}`}>
<li className="bl-item bl-item-edit" key={index}>
<span className="num">{index + 1}</span>
<span className="bl-text">{bullet}</span>
<input
className="bl-input"
value={bullet}
onChange={(event) => updateBullet(index, event.target.value)}
placeholder="例: 玻尿酸双效保湿,4 小时持久水润"
/>
<button className="bl-x" type="button" onClick={() => removeBullet(index)} aria-label="删除卖点">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><path d="M6 6l12 12M6 18L18 6" /></svg>
</button>
</li>
))}
<li className="bl-add">
<span className="num">+</span>
<input className="bl-input" value={bulletDraft} onChange={(event) => setBulletDraft(event.target.value)} onKeyDown={(event) => { if (event.key === "Enter") { event.preventDefault(); addBullet(); } }} placeholder="输入卖点后点「添加」或回车" />
{/* YYX#G29:回车确认太隐晦 → 补一个显式「添加」按钮 */}
<button type="button" className="bl-add-btn" onClick={addBullet} disabled={!bulletDraft.trim()}>添加</button>
</li>
</ul>
<button type="button" className="bl-add-row" onClick={addBullet}>
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><path d="M12 5v14M5 12h14" /></svg>
添加卖点
</button>
</div>
</div>
</div>