Update App.jsx via upload script - 2026-08-24 14:23:12
This commit is contained in:
parent
ea1d9a524c
commit
8a034ffac8
68
App.jsx
68
App.jsx
|
|
@ -5210,6 +5210,12 @@ function ProductForm({ draft, setDraft, onSave, onCancel, categories, onManage,
|
||||||
const maxKW = computeMaxPowerKW(draft.ratedPower, draft.ratedPowerUnit, draft.powerFactor);
|
const maxKW = computeMaxPowerKW(draft.ratedPower, draft.ratedPowerUnit, draft.powerFactor);
|
||||||
const extraNames = draft.extraNames || [];
|
const extraNames = draft.extraNames || [];
|
||||||
const [imageUploading, setImageUploading] = useState(false);
|
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) {
|
async function handleImagePick(file) {
|
||||||
if (!file) return;
|
if (!file) return;
|
||||||
setImageUploading(true);
|
setImageUploading(true);
|
||||||
|
|
@ -5263,18 +5269,27 @@ function ProductForm({ draft, setDraft, onSave, onCancel, categories, onManage,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function updateOutputPort(t, patch) {
|
// 各输出口那份列表按数组下标操作(不再靠type字段去重定位),这样同一个type(比如多个"DC"口,
|
||||||
set({ outputPorts: (draft.outputPorts || []).map(p => (p.type === t ? { ...p, ...patch } : p)) });
|
// 电压不同)可以并存多行,用户可以自由增加/删除/改类型名,不受"输出口类型"勾选框数量限制。
|
||||||
|
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"),
|
// 失焦时自动补单位:纯数字才补(比如"5"变"5Vdc"、"2.4"变"2.4A"),
|
||||||
// 如果用户已经手动填了完整格式(比如POE常见的"24Vdc/48Vdc"),保持原样不动,避免破坏。
|
// 如果用户已经手动填了完整格式(比如POE常见的"24Vdc/48Vdc"),保持原样不动,避免破坏。
|
||||||
function normalizeOutputVoltageOnBlur(t, rawValue) {
|
function normalizeOutputVoltageOnBlur(idx, rawValue) {
|
||||||
const trimmed = (rawValue || '').trim();
|
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();
|
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 (
|
return (
|
||||||
<div className="panel">
|
<div className="panel">
|
||||||
|
|
@ -5643,18 +5658,22 @@ function ProductForm({ draft, setDraft, onSave, onCancel, categories, onManage,
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{(draft.outputPorts || []).length > 0 && (
|
<div className="field">
|
||||||
<div className="field">
|
<span className="field-label">各输出口的输出电压 / 电流</span>
|
||||||
<span className="field-label">各输出口的输出电压 / 电流</span>
|
{(draft.outputPorts || []).map((p, idx) => (
|
||||||
{draft.outputPorts.map(p => (
|
<div key={idx} style={{ display: 'flex', gap: 8, alignItems: 'center', marginBottom: 6 }}>
|
||||||
<div key={p.type} style={{ display: 'flex', gap: 8, alignItems: 'center', marginBottom: 6 }}>
|
<input
|
||||||
<div style={{ width: 90, fontSize: 12.5, fontWeight: 700, flexShrink: 0 }}>{p.type}</div>
|
className="input" style={{ width: 90, flexShrink: 0, fontWeight: 700 }}
|
||||||
<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)} />
|
value={p.type} onChange={e => updateOutputPortAt(idx, { 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)} />
|
placeholder="类型"
|
||||||
</div>
|
/>
|
||||||
))}
|
<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)} />
|
||||||
</div>
|
<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="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">尺寸(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>
|
<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>
|
||||||
|
|
||||||
<div className="field">
|
<div className="field">
|
||||||
<span className="field-label">其他参数(AI识别到、但暂未收录成正式字段的参数,原样保留,也会显示在详情页和多语言PDF导出里)</span>
|
<span className="field-label">其他参数(AI识别到、但暂未收录成正式字段的参数,原样保留,也会显示在详情页和多语言PDF导出里;拖动左侧圆点可调整顺序)</span>
|
||||||
{(draft.extraSpecs || []).map((item, idx) => (
|
{(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
|
<input
|
||||||
className="input" style={{ flex: 1 }} value={item.label || ''}
|
className="input" style={{ flex: 1 }} value={item.label || ''}
|
||||||
placeholder="参数名,如:浮充电压"
|
placeholder="参数名,如:浮充电压"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue