Update App.jsx via upload script - 2026-08-02 17:30:20
This commit is contained in:
parent
50e76b2594
commit
98e2e1bf70
44
App.jsx
44
App.jsx
|
|
@ -592,6 +592,11 @@ function productExportRows(p, categories) {
|
|||
if (p.powerOrCapacity) rows.push({ labelKey: '功率 / 容量', value: p.powerOrCapacity });
|
||||
if (p.voltage) rows.push({ labelKey: '电压', value: p.voltage });
|
||||
}
|
||||
// 通用兜底:不属于上面任何固定字段的"其他参数"(AI识别原文时发现的、schema里没有对应字段的
|
||||
// 参数),不管品类都追加在最后,保证原文规格表里的信息不会因为不在预定义字段列表里而丢失
|
||||
(p.extraSpecs || []).forEach(item => {
|
||||
if (item && item.label && item.value) rows.push({ labelKey: item.label, value: item.value });
|
||||
});
|
||||
return rows;
|
||||
}
|
||||
|
||||
|
|
@ -773,6 +778,9 @@ const blankProduct = () => ({
|
|||
netWeight: '', // 净重(kg)(迷你UPS/离线式/在线互动式UPS共用)
|
||||
productImageFileName: '', productImageOriginalName: '', // 产品主图,导出多语言PDF时展示
|
||||
sellingPoints: '', // 对客卖点/主要特点,每行一条,专门给客户看的(和下面的costPrice/notes内部信息彻底分开,不会一起导出)
|
||||
extraSpecs: [], // 不在上面固定字段列表里的"其他参数",如 [{label:'防雷等级', value:'Type II'}];
|
||||
// AI批量导入时用来兜底承接原文规格表里有、但当前schema没有对应字段的参数,
|
||||
// 保证不会因为字段没预定义就丢信息;也支持手动在产品详情页里增删
|
||||
costPrice: '', notes: '',
|
||||
});
|
||||
|
||||
|
|
@ -833,6 +841,9 @@ 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, idx) => {
|
||||
if (item && item.label && item.value) items.push({ key: 'extraspec' + idx, label: item.label, value: item.value });
|
||||
});
|
||||
return items;
|
||||
}
|
||||
if (isBatteryCategory(cat) && p.type === 'UPS配套锂电池系统') {
|
||||
|
|
@ -859,6 +870,9 @@ 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, idx) => {
|
||||
if (item && item.label && item.value) items.push({ key: 'extraspec' + idx, label: item.label, value: item.value });
|
||||
});
|
||||
return items;
|
||||
}
|
||||
if (isUpsCategory(cat) && (p.type === '离线式UPS' || p.type === '在线互动式UPS')) {
|
||||
|
|
@ -885,6 +899,9 @@ function powerInfoItems(p, categories) {
|
|||
if (p.noiseLevel) items.push({ key: 'noiselevel', label: '噪音', value: p.noiseLevel });
|
||||
if (p.dimensions) items.push({ key: 'dim', label: '尺寸(mm)', value: p.dimensions });
|
||||
if (p.netWeight) items.push({ key: 'weight', label: '净重(kg)', value: p.netWeight });
|
||||
(p.extraSpecs || []).forEach((item, idx) => {
|
||||
if (item && item.label && item.value) items.push({ key: 'extraspec' + idx, label: item.label, value: item.value });
|
||||
});
|
||||
return items;
|
||||
}
|
||||
if (isUpsCategory(cat) && (p.type === '机架式UPS' || p.type === '在线式高频UPS')) {
|
||||
|
|
@ -920,6 +937,9 @@ function powerInfoItems(p, categories) {
|
|||
if (p.noiseLevel) items.push({ key: 'noiselevel', label: '噪音', value: p.noiseLevel });
|
||||
if (p.interfacePort) items.push({ key: 'interfaceport', label: '控制管理', value: p.interfacePort });
|
||||
if (p.optionalSnmp) items.push({ key: 'snmp', label: '可选SNMP', value: p.optionalSnmp });
|
||||
(p.extraSpecs || []).forEach((item, idx) => {
|
||||
if (item && item.label && item.value) items.push({ key: 'extraspec' + idx, label: item.label, value: item.value });
|
||||
});
|
||||
return items;
|
||||
}
|
||||
if (isUpsCategory(cat) && p.type !== '迷你UPS') {
|
||||
|
|
@ -943,6 +963,9 @@ function powerInfoItems(p, categories) {
|
|||
if (p.batterySpec) items.push({ key: 'battery', label: '电池数量和容量', value: p.batterySpec });
|
||||
if (p.dimensions) items.push({ key: 'dim', label: '尺寸(mm)', value: p.dimensions });
|
||||
if (p.netWeight) items.push({ key: 'weight', label: '净重(kg)', value: p.netWeight });
|
||||
(p.extraSpecs || []).forEach((item, idx) => {
|
||||
if (item && item.label && item.value) items.push({ key: 'extraspec' + idx, label: item.label, value: item.value });
|
||||
});
|
||||
return items;
|
||||
}
|
||||
return [{ key: 'power', label: '功率 / 容量', value: p.powerOrCapacity || '—' }];
|
||||
|
|
@ -2532,6 +2555,9 @@ function MainApp({ username, onLogout }) {
|
|||
otherStandard: p.otherStandard || '',
|
||||
sellingPoints: p.sellingPoints || '', // AI如果在原文里认出了营销卖点/主要特点,会自动填这里
|
||||
batterySpec: p.batterySpec || '', dimensions: p.dimensions || '', netWeight: p.netWeight || '', notes: p.notes || '',
|
||||
extraSpecs: Array.isArray(p.extraSpecs)
|
||||
? p.extraSpecs.filter(it => it && (it.label || it.value)).map(it => ({ label: it.label || '', value: it.value || '' }))
|
||||
: [], // 不在固定schema里的"其他参数",原文有什么就带什么,型号之间可以完全不一样
|
||||
}));
|
||||
setAiImportDrafts(drafts);
|
||||
} catch (e) {
|
||||
|
|
@ -2609,6 +2635,7 @@ function MainApp({ username, onLogout }) {
|
|||
otherStandard: d.otherStandard || '',
|
||||
sellingPoints: d.sellingPoints || '',
|
||||
batterySpec: d.batterySpec || '', dimensions: d.dimensions || '', netWeight: d.netWeight || '', notes: d.notes || '',
|
||||
extraSpecs: Array.isArray(d.extraSpecs) ? d.extraSpecs.filter(it => it && (it.label || it.value)) : [],
|
||||
};
|
||||
}
|
||||
function confirmAiImport() {
|
||||
|
|
@ -3926,6 +3953,7 @@ function MainApp({ username, onLogout }) {
|
|||
d.netWeight && `净重:${d.netWeight}`,
|
||||
(d.outputPortTypes && d.outputPortTypes.length) ? `输出口:${d.outputPortTypes.join('/')}` : '',
|
||||
d.sellingPoints ? `✓已识别对客卖点(${d.sellingPoints.split('\n').filter(Boolean).length}条)` : '',
|
||||
(d.extraSpecs && d.extraSpecs.length) ? `✓其他参数(${d.extraSpecs.length}项:${d.extraSpecs.map(it => it.label).filter(Boolean).join('、')})` : '',
|
||||
].filter(Boolean).join(' · ') || '(无更多规格信息)'}
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -4629,6 +4657,10 @@ function ProductForm({ draft, setDraft, onSave, onCancel, categories, onManage,
|
|||
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) }); }
|
||||
const extraSpecs = draft.extraSpecs || [];
|
||||
function addExtraSpec() { set({ extraSpecs: [...extraSpecs, { label: '', value: '' }] }); }
|
||||
function updateExtraSpec(idx, patch) { set({ extraSpecs: extraSpecs.map((it, i) => (i === idx ? { ...it, ...patch } : it)) }); }
|
||||
function removeExtraSpec(idx) { set({ extraSpecs: extraSpecs.filter((_, i) => i !== idx) }); }
|
||||
function toggleOutputPortType(t) {
|
||||
const list = draft.outputPortTypes || [];
|
||||
if (list.includes(t)) {
|
||||
|
|
@ -5069,6 +5101,18 @@ function ProductForm({ draft, setDraft, onSave, onCancel, categories, onManage,
|
|||
/>
|
||||
</div>
|
||||
|
||||
<div className="field">
|
||||
<span className="field-label">其他参数(可选——原文规格表里有、但上面没有专属字段的参数,AI批量导入时会自动补充在这里,也可以手动增删;会一起显示在产品详情和多语言PDF导出里)</span>
|
||||
{extraSpecs.map((item, idx) => (
|
||||
<div key={idx} style={{ display: 'flex', gap: 8, alignItems: 'center', marginBottom: 6 }}>
|
||||
<input className="input" style={{ flex: 1 }} value={item.label} onChange={e => updateExtraSpec(idx, { label: e.target.value })} placeholder="参数名,如:防雷等级" />
|
||||
<input className="input" style={{ flex: 1 }} value={item.value} onChange={e => updateExtraSpec(idx, { value: e.target.value })} placeholder="参数值,如:Type II" />
|
||||
<button type="button" className="btn btn-ghost btn-sm" onClick={() => removeExtraSpec(idx)}><Trash2 size={13} /></button>
|
||||
</div>
|
||||
))}
|
||||
<button type="button" className="btn btn-ghost btn-sm" onClick={addExtraSpec}><Plus size={13} />添加参数</button>
|
||||
</div>
|
||||
|
||||
<div className="field"><span className="field-label">正本价格(元)</span><input className="input" value={draft.costPrice} onChange={e => set({ costPrice: e.target.value })} placeholder="采购/成本价,人民币" /></div>
|
||||
<div className="field">
|
||||
<span className="field-label">内部备注(仅自己可见,不会出现在任何导出的文档里)</span>
|
||||
|
|
|
|||
Loading…
Reference in New Issue