Update App.jsx via upload script - 2026-08-07 16:53:57

This commit is contained in:
mike 2026-08-07 16:54:18 +08:00
parent a12e1145cd
commit b2d708f278
1 changed files with 55 additions and 2 deletions

57
App.jsx
View File

@ -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