Update App.jsx via upload script - 2026-08-21 10:01:57
This commit is contained in:
parent
5489ea44b8
commit
d493486b76
61
App.jsx
61
App.jsx
|
|
@ -766,6 +766,8 @@ function upsertProductByName(list, product) {
|
|||
id: existing.id,
|
||||
productImageFileName: existing.productImageFileName,
|
||||
productImageOriginalName: existing.productImageOriginalName,
|
||||
brochureFileName: existing.brochureFileName,
|
||||
brochureOriginalName: existing.brochureOriginalName,
|
||||
sellingPoints: existing.sellingPoints,
|
||||
costPrice: existing.costPrice,
|
||||
notes: existing.notes,
|
||||
|
|
@ -931,6 +933,7 @@ const blankProduct = () => ({
|
|||
extraSpecs: [], // 动态兜底参数:AI识别到但不在上面任何具名字段里的参数,原样保留 {label, value},如 [{label:'浮充电压', value:'13.7VDC/节'}]
|
||||
backPanelTemplateId: '', // 引用的后板图模板id(可跨产品共用同一个模板),迷你UPS不适用
|
||||
productImageFileName: '', productImageOriginalName: '', // 产品主图,导出多语言PDF时展示
|
||||
brochureFileName: '', brochureOriginalName: '', // 原版彩页(厂家原始彩页PDF/图片),只做保存和下载,不参与PDF导出排版
|
||||
sellingPoints: '', // 对客卖点/主要特点,每行一条,专门给客户看的(和下面的costPrice/notes内部信息彻底分开,不会一起导出)
|
||||
costPrice: '', notes: '',
|
||||
});
|
||||
|
|
@ -1748,6 +1751,7 @@ const Styles = () => (
|
|||
color: var(--ink-soft); font-size: 13px; cursor: pointer; transition: border-color 0.15s, color 0.15s;
|
||||
}
|
||||
.tax-add-category:hover { border-color: var(--blue); color: var(--blue); }
|
||||
.brochure-file-chip { width: 40px; height: 40px; border-radius: 8px; background: var(--copper-soft); color: var(--copper); display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
|
||||
.catalog-view-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; flex-wrap: wrap; gap: 10px; }
|
||||
.cert-view-head { display: flex; align-items: center; justify-content: flex-end; margin-bottom: 14px; }
|
||||
.cert-add-btn {
|
||||
|
|
@ -4924,6 +4928,25 @@ function ProductForm({ draft, setDraft, onSave, onCancel, categories, onManage,
|
|||
try { await deleteFile(draft.id, draft.productImageFileName); } catch (e) {}
|
||||
set({ productImageFileName: '', productImageOriginalName: '' });
|
||||
}
|
||||
const [brochureUploading, setBrochureUploading] = useState(false);
|
||||
async function handleBrochurePick(file) {
|
||||
if (!file) return;
|
||||
setBrochureUploading(true);
|
||||
try {
|
||||
const res = await uploadFile(draft.id, file);
|
||||
set({ brochureFileName: res.fileName, brochureOriginalName: res.originalName });
|
||||
} catch (e) {
|
||||
if (onNotify) onNotify('彩页上传失败,请重试');
|
||||
} finally {
|
||||
setBrochureUploading(false);
|
||||
}
|
||||
}
|
||||
async function handleBrochureRemove() {
|
||||
if (!draft.brochureFileName) return;
|
||||
if (!window.confirm('确定删除已上传的原版彩页?')) return;
|
||||
try { await deleteFile(draft.id, draft.brochureFileName); } catch (e) {}
|
||||
set({ brochureFileName: '', brochureOriginalName: '' });
|
||||
}
|
||||
function addExtraName() { set({ extraNames: [...extraNames, ''] }); }
|
||||
function updateExtraName(idx, val) { const arr = [...extraNames]; arr[idx] = val; set({ extraNames: arr }); }
|
||||
function removeExtraName(idx) { set({ extraNames: extraNames.filter((_, i) => i !== idx) }); }
|
||||
|
|
@ -5380,6 +5403,33 @@ function ProductForm({ draft, setDraft, onSave, onCancel, categories, onManage,
|
|||
)}
|
||||
</div>
|
||||
|
||||
<div className="field">
|
||||
<div className="field-label-row">
|
||||
<span className="field-label">原版彩页(可选,保存厂家原始彩页文件,支持PDF/图片,仅用于保存和下载)</span>
|
||||
</div>
|
||||
{draft.brochureFileName ? (
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
|
||||
<div className="brochure-file-chip">
|
||||
<FileText size={16} />
|
||||
</div>
|
||||
<a
|
||||
href={`/uploads/${draft.id}/${draft.brochureFileName}`} target="_blank" rel="noreferrer" download={draft.brochureOriginalName}
|
||||
style={{ fontSize: 12.5, color: 'var(--blue)', flex: 1, wordBreak: 'break-word' }}
|
||||
>{draft.brochureOriginalName}</a>
|
||||
<label className="btn btn-sm" style={{ cursor: brochureUploading ? 'default' : 'pointer' }}>
|
||||
{brochureUploading ? '上传中…' : '替换'}
|
||||
<input type="file" style={{ display: 'none' }} disabled={brochureUploading} onChange={e => handleBrochurePick(e.target.files && e.target.files[0])} />
|
||||
</label>
|
||||
<button className="btn btn-sm btn-ghost btn-danger" onClick={handleBrochureRemove}><Trash2 size={12} /></button>
|
||||
</div>
|
||||
) : (
|
||||
<label className="tax-add-category" style={{ display: 'block', cursor: brochureUploading ? 'default' : 'pointer' }}>
|
||||
<input type="file" style={{ display: 'none' }} disabled={brochureUploading} onChange={e => handleBrochurePick(e.target.files && e.target.files[0])} />
|
||||
<FileText size={16} style={{ verticalAlign: -3, marginRight: 4 }} />{brochureUploading ? '上传中…' : '点击上传原版彩页'}
|
||||
</label>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="field">
|
||||
<span className="field-label">其他参数(AI识别到、但暂未收录成正式字段的参数,原样保留,也会显示在详情页和多语言PDF导出里)</span>
|
||||
{(draft.extraSpecs || []).map((item, idx) => (
|
||||
|
|
@ -5478,6 +5528,17 @@ function ProductDetail({ product: p, onEdit, onDelete, categories, exportLang, o
|
|||
<BackPanelReadOnly template={backPanelTemplate} />
|
||||
</div>
|
||||
)}
|
||||
{p.brochureFileName && (
|
||||
<div className="field">
|
||||
<span className="field-label">原版彩页</span>
|
||||
<a
|
||||
href={`/uploads/${p.id}/${p.brochureFileName}`} target="_blank" rel="noreferrer" download={p.brochureOriginalName}
|
||||
className="btn btn-sm" style={{ display: 'inline-flex' }}
|
||||
>
|
||||
<FileText size={12} />{p.brochureOriginalName || '下载原版彩页'}
|
||||
</a>
|
||||
</div>
|
||||
)}
|
||||
{p.notes && <div className="field"><span className="field-label">备注</span><div style={{ fontSize: 12.5, whiteSpace: 'pre-wrap' }}>{p.notes}</div></div>}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Reference in New Issue