Update App.jsx via upload script - 2026-08-07 16:53:57
This commit is contained in:
parent
a12e1145cd
commit
b2d708f278
57
App.jsx
57
App.jsx
|
|
@ -600,6 +600,9 @@ function productExportRows(p, categories) {
|
||||||
if (p.container20ft) rows.push({ labelKey: '20尺柜装箱数量', value: p.container20ft });
|
if (p.container20ft) rows.push({ labelKey: '20尺柜装箱数量', value: p.container20ft });
|
||||||
if (p.container40ft) rows.push({ labelKey: '40尺柜装箱数量', value: p.container40ft });
|
if (p.container40ft) rows.push({ labelKey: '40尺柜装箱数量', value: p.container40ft });
|
||||||
if (p.container40hq) rows.push({ labelKey: '40高柜装箱数量', value: p.container40hq });
|
if (p.container40hq) rows.push({ labelKey: '40高柜装箱数量', value: p.container40hq });
|
||||||
|
(p.extraSpecs || []).forEach(item => {
|
||||||
|
if (item && item.label && item.value) rows.push({ labelKey: item.label, value: item.value });
|
||||||
|
});
|
||||||
return rows;
|
return rows;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -781,6 +784,7 @@ const blankProduct = () => ({
|
||||||
netWeight: '', // 净重(kg)(迷你UPS/离线式/在线互动式UPS共用)
|
netWeight: '', // 净重(kg)(迷你UPS/离线式/在线互动式UPS共用)
|
||||||
applicationScenarios: '', // 应用场景文本,如 "电脑、投影仪、打印机、摄像机、收银机"
|
applicationScenarios: '', // 应用场景文本,如 "电脑、投影仪、打印机、摄像机、收银机"
|
||||||
container20ft: '', container40ft: '', container40hq: '', // 装箱数量(20尺柜/40尺柜/40高柜,无栈板台数)
|
container20ft: '', container40ft: '', container40hq: '', // 装箱数量(20尺柜/40尺柜/40高柜,无栈板台数)
|
||||||
|
extraSpecs: [], // 动态兜底参数:AI识别到但不在上面任何具名字段里的参数,原样保留 {label, value},如 [{label:'浮充电压', value:'13.7VDC/节'}]
|
||||||
productImageFileName: '', productImageOriginalName: '', // 产品主图,导出多语言PDF时展示
|
productImageFileName: '', productImageOriginalName: '', // 产品主图,导出多语言PDF时展示
|
||||||
sellingPoints: '', // 对客卖点/主要特点,每行一条,专门给客户看的(和下面的costPrice/notes内部信息彻底分开,不会一起导出)
|
sellingPoints: '', // 对客卖点/主要特点,每行一条,专门给客户看的(和下面的costPrice/notes内部信息彻底分开,不会一起导出)
|
||||||
costPrice: '', notes: '',
|
costPrice: '', notes: '',
|
||||||
|
|
@ -843,6 +847,7 @@ function powerInfoItems(p, categories) {
|
||||||
if (p.safetyStandard) items.push({ key: 'safetystd', label: '安规/EMC标准', value: p.safetyStandard });
|
if (p.safetyStandard) items.push({ key: 'safetystd', label: '安规/EMC标准', value: p.safetyStandard });
|
||||||
if (p.gridStandard) items.push({ key: 'gridstd', label: '并网标准', value: p.gridStandard });
|
if (p.gridStandard) items.push({ key: 'gridstd', label: '并网标准', value: p.gridStandard });
|
||||||
if (p.otherStandard) items.push({ key: 'otherstd', label: '其他标准', value: p.otherStandard });
|
if (p.otherStandard) items.push({ key: 'otherstd', label: '其他标准', value: p.otherStandard });
|
||||||
|
(p.extraSpecs || []).forEach((item, i) => { if (item && item.label && item.value) items.push({ key: 'extra_' + i, label: item.label, value: item.value }); });
|
||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
if (isBatteryCategory(cat) && p.type === 'UPS配套锂电池系统') {
|
if (isBatteryCategory(cat) && p.type === 'UPS配套锂电池系统') {
|
||||||
|
|
@ -869,6 +874,7 @@ function powerInfoItems(p, categories) {
|
||||||
if (p.cabinetWeight) items.push({ key: 'cabinetweight', label: '系统柜重量(kg)', value: p.cabinetWeight });
|
if (p.cabinetWeight) items.push({ key: 'cabinetweight', label: '系统柜重量(kg)', value: p.cabinetWeight });
|
||||||
if (p.altitude) items.push({ key: 'altitude', label: '海拔(m)', value: p.altitude });
|
if (p.altitude) items.push({ key: 'altitude', label: '海拔(m)', value: p.altitude });
|
||||||
if (p.selfDischargeRate) items.push({ key: 'selfdischarge', label: '自放电率', value: p.selfDischargeRate });
|
if (p.selfDischargeRate) items.push({ key: 'selfdischarge', label: '自放电率', value: p.selfDischargeRate });
|
||||||
|
(p.extraSpecs || []).forEach((item, i) => { if (item && item.label && item.value) items.push({ key: 'extra_' + i, label: item.label, value: item.value }); });
|
||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
if (isUpsCategory(cat) && (p.type === '离线式UPS' || p.type === '在线互动式UPS')) {
|
if (isUpsCategory(cat) && (p.type === '离线式UPS' || p.type === '在线互动式UPS')) {
|
||||||
|
|
@ -899,6 +905,7 @@ function powerInfoItems(p, categories) {
|
||||||
if (p.container20ft) items.push({ key: 'container20', label: '20尺柜装箱数量', value: p.container20ft });
|
if (p.container20ft) items.push({ key: 'container20', label: '20尺柜装箱数量', value: p.container20ft });
|
||||||
if (p.container40ft) items.push({ key: 'container40', label: '40尺柜装箱数量', value: p.container40ft });
|
if (p.container40ft) items.push({ key: 'container40', label: '40尺柜装箱数量', value: p.container40ft });
|
||||||
if (p.container40hq) items.push({ key: 'container40hq', label: '40高柜装箱数量', value: p.container40hq });
|
if (p.container40hq) items.push({ key: 'container40hq', label: '40高柜装箱数量', value: p.container40hq });
|
||||||
|
(p.extraSpecs || []).forEach((item, i) => { if (item && item.label && item.value) items.push({ key: 'extra_' + i, label: item.label, value: item.value }); });
|
||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
if (isUpsCategory(cat) && (p.type === '机架式UPS' || p.type === '在线式高频UPS')) {
|
if (isUpsCategory(cat) && (p.type === '机架式UPS' || p.type === '在线式高频UPS')) {
|
||||||
|
|
@ -938,15 +945,18 @@ function powerInfoItems(p, categories) {
|
||||||
if (p.container20ft) items.push({ key: 'container20', label: '20尺柜装箱数量', value: p.container20ft });
|
if (p.container20ft) items.push({ key: 'container20', label: '20尺柜装箱数量', value: p.container20ft });
|
||||||
if (p.container40ft) items.push({ key: 'container40', label: '40尺柜装箱数量', value: p.container40ft });
|
if (p.container40ft) items.push({ key: 'container40', label: '40尺柜装箱数量', value: p.container40ft });
|
||||||
if (p.container40hq) items.push({ key: 'container40hq', label: '40高柜装箱数量', value: p.container40hq });
|
if (p.container40hq) items.push({ key: 'container40hq', label: '40高柜装箱数量', value: p.container40hq });
|
||||||
|
(p.extraSpecs || []).forEach((item, i) => { if (item && item.label && item.value) items.push({ key: 'extra_' + i, label: item.label, value: item.value }); });
|
||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
if (isUpsCategory(cat) && p.type !== '迷你UPS') {
|
if (isUpsCategory(cat) && p.type !== '迷你UPS') {
|
||||||
const maxKW = computeMaxPowerKW(p.ratedPower, p.ratedPowerUnit, p.powerFactor);
|
const maxKW = computeMaxPowerKW(p.ratedPower, p.ratedPowerUnit, p.powerFactor);
|
||||||
return [
|
const rackFallbackItems = [
|
||||||
{ key: 'rated', label: '视载功率', value: p.ratedPower ? `${p.ratedPower} ${p.ratedPowerUnit || 'VA'}` : '—' },
|
{ key: 'rated', label: '视载功率', value: p.ratedPower ? `${p.ratedPower} ${p.ratedPowerUnit || 'VA'}` : '—' },
|
||||||
{ key: 'pf', label: '功率因数', value: p.powerFactor || '—' },
|
{ key: 'pf', label: '功率因数', value: p.powerFactor || '—' },
|
||||||
{ key: 'maxkw', label: '最大功率', value: maxKW !== null ? `${maxKW} kW` : '—' },
|
{ key: 'maxkw', label: '最大功率', value: maxKW !== null ? `${maxKW} kW` : '—' },
|
||||||
];
|
];
|
||||||
|
(p.extraSpecs || []).forEach((item, i) => { if (item && item.label && item.value) rackFallbackItems.push({ key: 'extra_' + i, label: item.label, value: item.value }); });
|
||||||
|
return rackFallbackItems;
|
||||||
}
|
}
|
||||||
if (isUpsCategory(cat) && p.type === '迷你UPS') {
|
if (isUpsCategory(cat) && p.type === '迷你UPS') {
|
||||||
const items = [{ key: 'maxout', label: '输出功率', value: p.powerOrCapacity || '—' }];
|
const items = [{ key: 'maxout', label: '输出功率', value: p.powerOrCapacity || '—' }];
|
||||||
|
|
@ -965,9 +975,12 @@ function powerInfoItems(p, categories) {
|
||||||
if (p.container20ft) items.push({ key: 'container20', label: '20尺柜装箱数量', value: p.container20ft });
|
if (p.container20ft) items.push({ key: 'container20', label: '20尺柜装箱数量', value: p.container20ft });
|
||||||
if (p.container40ft) items.push({ key: 'container40', label: '40尺柜装箱数量', value: p.container40ft });
|
if (p.container40ft) items.push({ key: 'container40', label: '40尺柜装箱数量', value: p.container40ft });
|
||||||
if (p.container40hq) items.push({ key: 'container40hq', label: '40高柜装箱数量', value: p.container40hq });
|
if (p.container40hq) items.push({ key: 'container40hq', label: '40高柜装箱数量', value: p.container40hq });
|
||||||
|
(p.extraSpecs || []).forEach((item, i) => { if (item && item.label && item.value) items.push({ key: 'extra_' + i, label: item.label, value: item.value }); });
|
||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
return [{ key: 'power', label: '功率 / 容量', value: p.powerOrCapacity || '—' }];
|
const fallbackItems = [{ key: 'power', label: '功率 / 容量', value: p.powerOrCapacity || '—' }];
|
||||||
|
(p.extraSpecs || []).forEach((item, i) => { if (item && item.label && item.value) fallbackItems.push({ key: 'extra_' + i, label: item.label, value: item.value }); });
|
||||||
|
return fallbackItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------- quotes/invoices ------------------------------ */
|
/* ------------------------------- quotes/invoices ------------------------------ */
|
||||||
|
|
@ -2548,6 +2561,9 @@ function MainApp({ username, onLogout }) {
|
||||||
otherStandard: p.otherStandard || '',
|
otherStandard: p.otherStandard || '',
|
||||||
sellingPoints: p.sellingPoints || '', // AI如果在原文里认出了营销卖点/主要特点,会自动填这里
|
sellingPoints: p.sellingPoints || '', // AI如果在原文里认出了营销卖点/主要特点,会自动填这里
|
||||||
batterySpec: p.batterySpec || '', dimensions: p.dimensions || '', netWeight: p.netWeight || '', notes: p.notes || '',
|
batterySpec: p.batterySpec || '', dimensions: p.dimensions || '', netWeight: p.netWeight || '', notes: p.notes || '',
|
||||||
|
applicationScenarios: p.applicationScenarios || '',
|
||||||
|
container20ft: p.container20ft || '', container40ft: p.container40ft || '', container40hq: p.container40hq || '',
|
||||||
|
extraSpecs: Array.isArray(p.extraSpecs) ? p.extraSpecs.filter(x => x && x.label && x.value) : [],
|
||||||
}));
|
}));
|
||||||
setAiImportDrafts(drafts);
|
setAiImportDrafts(drafts);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
@ -2625,6 +2641,9 @@ function MainApp({ username, onLogout }) {
|
||||||
otherStandard: d.otherStandard || '',
|
otherStandard: d.otherStandard || '',
|
||||||
sellingPoints: d.sellingPoints || '',
|
sellingPoints: d.sellingPoints || '',
|
||||||
batterySpec: d.batterySpec || '', dimensions: d.dimensions || '', netWeight: d.netWeight || '', notes: d.notes || '',
|
batterySpec: d.batterySpec || '', dimensions: d.dimensions || '', netWeight: d.netWeight || '', notes: d.notes || '',
|
||||||
|
applicationScenarios: d.applicationScenarios || '',
|
||||||
|
container20ft: d.container20ft || '', container40ft: d.container40ft || '', container40hq: d.container40hq || '',
|
||||||
|
extraSpecs: Array.isArray(d.extraSpecs) ? d.extraSpecs.filter(x => x && x.label && x.value) : [],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
function confirmAiImport() {
|
function confirmAiImport() {
|
||||||
|
|
@ -5057,6 +5076,40 @@ function ProductForm({ draft, setDraft, onSave, onCancel, categories, onManage,
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className="field">
|
||||||
|
<span className="field-label">其他参数(AI识别到、但暂未收录成正式字段的参数,原样保留,也会显示在详情页和多语言PDF导出里)</span>
|
||||||
|
{(draft.extraSpecs || []).map((item, idx) => (
|
||||||
|
<div key={idx} style={{ display: 'flex', gap: 8, marginBottom: 6 }}>
|
||||||
|
<input
|
||||||
|
className="input" style={{ flex: 1 }} value={item.label || ''}
|
||||||
|
placeholder="参数名,如:浮充电压"
|
||||||
|
onChange={e => {
|
||||||
|
const next = (draft.extraSpecs || []).slice();
|
||||||
|
next[idx] = { ...next[idx], label: e.target.value };
|
||||||
|
set({ extraSpecs: next });
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<input
|
||||||
|
className="input" style={{ flex: 1 }} value={item.value || ''}
|
||||||
|
placeholder="数值,如:13.7VDC/节"
|
||||||
|
onChange={e => {
|
||||||
|
const next = (draft.extraSpecs || []).slice();
|
||||||
|
next[idx] = { ...next[idx], value: e.target.value };
|
||||||
|
set({ extraSpecs: next });
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
className="btn btn-sm btn-ghost btn-danger"
|
||||||
|
onClick={() => set({ extraSpecs: (draft.extraSpecs || []).filter((_, i) => i !== idx) })}
|
||||||
|
><Trash2 size={12} /></button>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
<button
|
||||||
|
className="btn btn-sm btn-ghost"
|
||||||
|
onClick={() => set({ extraSpecs: [...(draft.extraSpecs || []), { label: '', value: '' }] })}
|
||||||
|
><Plus size={12} style={{ verticalAlign: -2, marginRight: 4 }} />添加一条</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className="field">
|
<div className="field">
|
||||||
<span className="field-label">对客卖点 / 主要特点(可选,每行一条,会显示在多语言PDF导出的资料里)</span>
|
<span className="field-label">对客卖点 / 主要特点(可选,每行一条,会显示在多语言PDF导出的资料里)</span>
|
||||||
<textarea
|
<textarea
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue