Update App.jsx via upload script - 2026-08-24 14:23:12

This commit is contained in:
mike 2026-08-24 14:23:31 +08:00
parent ea1d9a524c
commit 8a034ffac8
1 changed files with 48 additions and 20 deletions

68
App.jsx
View File

@ -5210,6 +5210,12 @@ function ProductForm({ draft, setDraft, onSave, onCancel, categories, onManage,
const maxKW = computeMaxPowerKW(draft.ratedPower, draft.ratedPowerUnit, draft.powerFactor);
const extraNames = draft.extraNames || [];
const [imageUploading, setImageUploading] = useState(false);
const [dragExtraSpecIdx, setDragExtraSpecIdx] = useState(null);
function handleExtraSpecDrop(dropIdx) {
if (dragExtraSpecIdx === null || dragExtraSpecIdx === dropIdx) { setDragExtraSpecIdx(null); return; }
set({ extraSpecs: reorderArray(draft.extraSpecs || [], dragExtraSpecIdx, dropIdx) });
setDragExtraSpecIdx(null);
}
async function handleImagePick(file) {
if (!file) return;
setImageUploading(true);
@ -5263,18 +5269,27 @@ function ProductForm({ draft, setDraft, onSave, onCancel, categories, onManage,
});
}
}
function updateOutputPort(t, patch) {
set({ outputPorts: (draft.outputPorts || []).map(p => (p.type === t ? { ...p, ...patch } : p)) });
// typetype"DC"
// //""
function updateOutputPortAt(idx, patch) {
set({ outputPorts: (draft.outputPorts || []).map((p, i) => (i === idx ? { ...p, ...patch } : p)) });
}
function addOutputPort() {
const lastType = (draft.outputPorts && draft.outputPorts.length) ? draft.outputPorts[draft.outputPorts.length - 1].type : 'DC';
set({ outputPorts: [...(draft.outputPorts || []), { type: lastType, voltage: '', current: '' }] });
}
function removeOutputPortAt(idx) {
set({ outputPorts: (draft.outputPorts || []).filter((_, i) => i !== idx) });
}
// "5""5Vdc""2.4""2.4A"
// POE"24Vdc/48Vdc"
function normalizeOutputVoltageOnBlur(t, rawValue) {
function normalizeOutputVoltageOnBlur(idx, rawValue) {
const trimmed = (rawValue || '').trim();
if (/^\d+(\.\d+)?$/.test(trimmed)) updateOutputPort(t, { voltage: trimmed + 'Vdc' });
if (/^\d+(\.\d+)?$/.test(trimmed)) updateOutputPortAt(idx, { voltage: trimmed + 'Vdc' });
}
function normalizeOutputCurrentOnBlur(t, rawValue) {
function normalizeOutputCurrentOnBlur(idx, rawValue) {
const trimmed = (rawValue || '').trim();
if (/^\d+(\.\d+)?$/.test(trimmed)) updateOutputPort(t, { current: trimmed + 'A' });
if (/^\d+(\.\d+)?$/.test(trimmed)) updateOutputPortAt(idx, { current: trimmed + 'A' });
}
return (
<div className="panel">
@ -5643,18 +5658,22 @@ function ProductForm({ draft, setDraft, onSave, onCancel, categories, onManage,
))}
</div>
</div>
{(draft.outputPorts || []).length > 0 && (
<div className="field">
<span className="field-label">各输出口的输出电压 / 电流</span>
{draft.outputPorts.map(p => (
<div key={p.type} style={{ display: 'flex', gap: 8, alignItems: 'center', marginBottom: 6 }}>
<div style={{ width: 90, fontSize: 12.5, fontWeight: 700, flexShrink: 0 }}>{p.type}</div>
<input className="input" style={{ flex: 1 }} value={p.voltage} onChange={e => updateOutputPort(p.type, { voltage: e.target.value })} onBlur={e => normalizeOutputVoltageOnBlur(p.type, e.target.value)} />
<input className="input" style={{ flex: 1 }} value={p.current} onChange={e => updateOutputPort(p.type, { current: e.target.value })} onBlur={e => normalizeOutputCurrentOnBlur(p.type, e.target.value)} />
</div>
))}
</div>
)}
<div className="field">
<span className="field-label">各输出口的输出电压 / 电流</span>
{(draft.outputPorts || []).map((p, idx) => (
<div key={idx} style={{ display: 'flex', gap: 8, alignItems: 'center', marginBottom: 6 }}>
<input
className="input" style={{ width: 90, flexShrink: 0, fontWeight: 700 }}
value={p.type} onChange={e => updateOutputPortAt(idx, { type: e.target.value })}
placeholder="类型"
/>
<input className="input" style={{ flex: 1 }} placeholder="电压" value={p.voltage} onChange={e => updateOutputPortAt(idx, { voltage: e.target.value })} onBlur={e => normalizeOutputVoltageOnBlur(idx, e.target.value)} />
<input className="input" style={{ flex: 1 }} placeholder="电流" value={p.current} onChange={e => updateOutputPortAt(idx, { current: e.target.value })} onBlur={e => normalizeOutputCurrentOnBlur(idx, e.target.value)} />
<button className="btn btn-sm btn-ghost btn-danger" onClick={() => removeOutputPortAt(idx)} title="删除这一行"><Trash2 size={12} /></button>
</div>
))}
<button className="btn btn-sm" onClick={addOutputPort}><Plus size={12} />增加一个输出口</button>
</div>
<div className="grid-2">
<div className="field"><span className="field-label">尺寸mm</span><input className="input" value={draft.dimensions} onChange={e => set({ dimensions: spaceToAsterisk(e.target.value) })} placeholder="如210*130*40" /></div>
<div className="field"><span className="field-label">净重kg</span><input className="input" value={draft.netWeight} onChange={e => set({ netWeight: e.target.value })} placeholder="如0.73" /></div>
@ -5730,9 +5749,18 @@ function ProductForm({ draft, setDraft, onSave, onCancel, categories, onManage,
</div>
<div className="field">
<span className="field-label">其他参数AI识别到但暂未收录成正式字段的参数原样保留也会显示在详情页和多语言PDF导出里</span>
<span className="field-label">其他参数AI识别到但暂未收录成正式字段的参数原样保留也会显示在详情页和多语言PDF导出里拖动左侧圆点可调整顺序</span>
{(draft.extraSpecs || []).map((item, idx) => (
<div key={idx} style={{ display: 'flex', gap: 8, marginBottom: 6 }}>
<div
key={idx}
style={{ display: 'flex', gap: 8, marginBottom: 6, alignItems: 'center', opacity: dragExtraSpecIdx === idx ? 0.5 : 1 }}
draggable
onDragStart={() => setDragExtraSpecIdx(idx)}
onDragOver={e => e.preventDefault()}
onDrop={() => handleExtraSpecDrop(idx)}
onDragEnd={() => setDragExtraSpecIdx(null)}
>
<GripVertical size={14} className="drag-handle" style={{ flexShrink: 0 }} />
<input
className="input" style={{ flex: 1 }} value={item.label || ''}
placeholder="参数名,如:浮充电压"