diff --git a/App.jsx b/App.jsx index c4123d9..446f01d 100644 --- a/App.jsx +++ b/App.jsx @@ -600,6 +600,9 @@ function productExportRows(p, categories) { if (p.container20ft) rows.push({ labelKey: '20尺柜装箱数量', value: p.container20ft }); if (p.container40ft) rows.push({ labelKey: '40尺柜装箱数量', value: p.container40ft }); 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; } @@ -781,6 +784,7 @@ const blankProduct = () => ({ netWeight: '', // 净重(kg)(迷你UPS/离线式/在线互动式UPS共用) applicationScenarios: '', // 应用场景文本,如 "电脑、投影仪、打印机、摄像机、收银机" container20ft: '', container40ft: '', container40hq: '', // 装箱数量(20尺柜/40尺柜/40高柜,无栈板台数) + extraSpecs: [], // 动态兜底参数:AI识别到但不在上面任何具名字段里的参数,原样保留 {label, value},如 [{label:'浮充电压', value:'13.7VDC/节'}] productImageFileName: '', productImageOriginalName: '', // 产品主图,导出多语言PDF时展示 sellingPoints: '', // 对客卖点/主要特点,每行一条,专门给客户看的(和下面的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.gridStandard) items.push({ key: 'gridstd', label: '并网标准', value: p.gridStandard }); 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; } 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.altitude) items.push({ key: 'altitude', label: '海拔(m)', value: p.altitude }); 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; } 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.container40ft) items.push({ key: 'container40', label: '40尺柜装箱数量', value: p.container40ft }); 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; } 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.container40ft) items.push({ key: 'container40', label: '40尺柜装箱数量', value: p.container40ft }); 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; } if (isUpsCategory(cat) && p.type !== '迷你UPS') { const maxKW = computeMaxPowerKW(p.ratedPower, p.ratedPowerUnit, p.powerFactor); - return [ + const rackFallbackItems = [ { key: 'rated', label: '视载功率', value: p.ratedPower ? `${p.ratedPower} ${p.ratedPowerUnit || 'VA'}` : '—' }, { key: 'pf', label: '功率因数', value: p.powerFactor || '—' }, { 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') { 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.container40ft) items.push({ key: 'container40', label: '40尺柜装箱数量', value: p.container40ft }); 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 [{ 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 ------------------------------ */ @@ -2548,6 +2561,9 @@ function MainApp({ username, onLogout }) { otherStandard: p.otherStandard || '', sellingPoints: p.sellingPoints || '', // AI如果在原文里认出了营销卖点/主要特点,会自动填这里 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); } catch (e) { @@ -2625,6 +2641,9 @@ function MainApp({ username, onLogout }) { otherStandard: d.otherStandard || '', sellingPoints: d.sellingPoints || '', 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() { @@ -5057,6 +5076,40 @@ function ProductForm({ draft, setDraft, onSave, onCancel, categories, onManage, )} +