fix: 测试清单一轮bug修复(商品库/视频项目/设置/消费/平台套图)
- 商品库编辑删图假成功+悬停无删除图标;商品三视图错显角色三视图 - 视频项目演员删除入口;角色三视图防呆;故事板审核失败原因透出 - 设置:管理团队死按钮/通知未接入项屏蔽/邮箱验证链路 - 消费:账单流水切换类型重置分页+独立总页数 - 资产库上传按钮隐藏;月限额两处对齐 - 平台套图:提示词框放大/选模型胶囊内嵌/未读任务角标/工作台记录持久化 - 新建商品独立添加卖点按钮;商品库超1920自适应 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user