Update App.jsx via upload script - 2026-07-27 16:29:52
This commit is contained in:
parent
32ae0c228d
commit
f564599b57
74
App.jsx
74
App.jsx
|
|
@ -440,6 +440,37 @@ function productExportRows(p, categories) {
|
|||
}
|
||||
|
||||
// 收集导出这份产品规格书需要翻译的全部词条(字段名 + 品类/机型这些中文数值 + 备注自由文本)
|
||||
// 按型号名称去重合并:"同一个型号只能存在1个"——如果传入的产品和列表里某个已有产品
|
||||
// 型号名称相同(但不是同一条记录本身),说明是重复建了同型号,这时用新参数覆盖旧记录
|
||||
// (复用旧记录的id),但保留旧记录里手动维护的图片/对客卖点/正本价格/内部备注,不会被
|
||||
// 这次导入/新建的技术参数覆盖清空(因为AI批量导入/新建产品表单都不会填这几项)。
|
||||
// 如果传入的产品本身就是列表里已有的那一条(正常编辑保存),走普通按id更新。
|
||||
function upsertProductByName(list, product) {
|
||||
const dupIdx = list.findIndex(p => p.id !== product.id && p.name.trim() === product.name.trim());
|
||||
const selfIdx = list.findIndex(p => p.id === product.id);
|
||||
if (dupIdx !== -1) {
|
||||
const existing = list[dupIdx];
|
||||
const merged = {
|
||||
...product,
|
||||
id: existing.id,
|
||||
productImageFileName: existing.productImageFileName,
|
||||
productImageOriginalName: existing.productImageOriginalName,
|
||||
sellingPoints: existing.sellingPoints,
|
||||
costPrice: existing.costPrice,
|
||||
notes: existing.notes,
|
||||
};
|
||||
let copy = list.map((p, i) => (i === dupIdx ? merged : p));
|
||||
if (selfIdx !== -1 && selfIdx !== dupIdx) copy = copy.filter((_, i) => i !== selfIdx);
|
||||
return { list: copy, collision: true, isNew: false, resultId: existing.id };
|
||||
}
|
||||
if (selfIdx !== -1) {
|
||||
const copy = [...list];
|
||||
copy[selfIdx] = product;
|
||||
return { list: copy, collision: false, isNew: false, resultId: product.id };
|
||||
}
|
||||
return { list: [...list, product], collision: false, isNew: true, resultId: product.id };
|
||||
}
|
||||
|
||||
function gatherExportTerms(p, categories) {
|
||||
const cat = (categories || []).find(c => c.id === p.category);
|
||||
const terms = new Set(['产品规格书', '* 产品规格如有变动,恕不另行通知', '型号', '品牌', '产品大类']);
|
||||
|
|
@ -1858,14 +1889,27 @@ function MainApp({ username, onLogout }) {
|
|||
id: 'p_' + Date.now() + '_' + i + '_' + Math.random().toString(36).slice(2, 7),
|
||||
name: n,
|
||||
}));
|
||||
setProducts(prev => {
|
||||
const exists = prev.some(p => p.id === primary.id);
|
||||
const withPrimary = exists ? prev.map(p => (p.id === primary.id ? primary : p)) : [...prev, primary];
|
||||
return [...withPrimary, ...extras];
|
||||
let working = products;
|
||||
let newCount = 0;
|
||||
let collisionCount = 0;
|
||||
let primarySelectId = primary.id;
|
||||
[primary, ...extras].forEach((prod, i) => {
|
||||
const res = upsertProductByName(working, prod);
|
||||
working = res.list;
|
||||
if (res.collision) collisionCount++;
|
||||
else if (res.isNew) newCount++;
|
||||
if (i === 0) primarySelectId = res.resultId;
|
||||
});
|
||||
setSelectedProductId(primary.id);
|
||||
setProducts(working);
|
||||
setSelectedProductId(primarySelectId);
|
||||
setProductDraft(null);
|
||||
notify(extras.length > 0 ? `已保存,共新建 ${1 + extras.length} 个产品` : '已保存');
|
||||
if (extras.length > 0) {
|
||||
notify(`已保存:新建 ${newCount} 个${collisionCount > 0 ? `,型号已存在覆盖更新 ${collisionCount} 个` : ''}`);
|
||||
} else if (collisionCount > 0) {
|
||||
notify('型号已存在,已用最新参数覆盖更新(图片/卖点/成本价/备注保留原样)');
|
||||
} else {
|
||||
notify('已保存');
|
||||
}
|
||||
}
|
||||
function deleteProduct(id) {
|
||||
if (!window.confirm('确定删除该产品档案?此操作不可恢复。')) return;
|
||||
|
|
@ -2000,10 +2044,22 @@ function MainApp({ username, onLogout }) {
|
|||
const included = (aiImportDrafts || []).filter(d => d.include && d.name.trim());
|
||||
if (!included.length) { notify('没有勾选任何要导入的产品'); return; }
|
||||
const { categories: newCats, resolved } = resolveCategoriesForImport(productCategories, included);
|
||||
const newProducts = resolved.map(buildProductFromAiDraft);
|
||||
let working = products;
|
||||
let newCount = 0;
|
||||
let collisionCount = 0;
|
||||
resolved.forEach((d, idx) => {
|
||||
const productData = buildProductFromAiDraft(d, idx);
|
||||
const res = upsertProductByName(working, productData);
|
||||
working = res.list;
|
||||
if (res.collision) collisionCount++;
|
||||
else if (res.isNew) newCount++;
|
||||
});
|
||||
setProducts(working);
|
||||
setProductCategories(newCats);
|
||||
setProducts(prev => [...prev, ...newProducts]);
|
||||
notify(`已导入 ${newProducts.length} 个产品`);
|
||||
const parts = [];
|
||||
if (newCount) parts.push(`新建 ${newCount} 个`);
|
||||
if (collisionCount) parts.push(`型号已存在,覆盖更新为最新参数 ${collisionCount} 个`);
|
||||
notify(`导入完成:${parts.join(',')}`);
|
||||
closeAiImport();
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue