diff --git a/App.jsx b/App.jsx
index 446f01d..f93463e 100644
--- a/App.jsx
+++ b/App.jsx
@@ -458,6 +458,25 @@ async function resolveExportTranslations(terms, lang) {
// 把某个产品需要展示的规格行整理出来(和ProductDetail的powerInfoItems逻辑对齐,但拆分出
// 独立的label/value结构,方便多语言渲染时分别处理"字段名要翻译"和"数值一般不用翻译")
+// 把AI识别到但没有具名字段的参数(extraSpecs)插入到已经组装好的规格行列表里——如果这一条
+// 标注了afterLabel(应该跟在哪个已知字段后面显示),就插到那个字段紧后面;找不到匹配的就
+// 兜底追加到列表最后,不会丢数据,只是位置不够准确。labelProp传'labelKey'(productExportRows
+// 用)或'label'(powerInfoItems用),因为两边字段名不一样。
+function insertExtraSpecs(list, extraSpecs, labelProp) {
+ (extraSpecs || []).forEach((item, i) => {
+ if (!item || !item.label || !item.value) return;
+ const entry = labelProp === 'labelKey'
+ ? { labelKey: item.label, value: item.value }
+ : { key: 'extra_' + i + '_' + item.label, label: item.label, value: item.value };
+ if (item.afterLabel) {
+ const idx = list.findIndex(r => r[labelProp] === item.afterLabel);
+ if (idx !== -1) { list.splice(idx + 1, 0, entry); return; }
+ }
+ list.push(entry);
+ });
+ return list;
+}
+
function productExportRows(p, categories) {
const cat = (categories || []).find(c => c.id === p.category);
const rows = [];
@@ -600,9 +619,7 @@ 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 });
- });
+ insertExtraSpecs(rows, p.extraSpecs, 'labelKey');
return rows;
}
@@ -847,7 +864,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 }); });
+ insertExtraSpecs(items, p.extraSpecs, 'label');
return items;
}
if (isBatteryCategory(cat) && p.type === 'UPS配套锂电池系统') {
@@ -874,7 +891,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 }); });
+ insertExtraSpecs(items, p.extraSpecs, 'label');
return items;
}
if (isUpsCategory(cat) && (p.type === '离线式UPS' || p.type === '在线互动式UPS')) {
@@ -905,7 +922,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 }); });
+ insertExtraSpecs(items, p.extraSpecs, 'label');
return items;
}
if (isUpsCategory(cat) && (p.type === '机架式UPS' || p.type === '在线式高频UPS')) {
@@ -945,7 +962,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 }); });
+ insertExtraSpecs(items, p.extraSpecs, 'label');
return items;
}
if (isUpsCategory(cat) && p.type !== '迷你UPS') {
@@ -955,7 +972,7 @@ function powerInfoItems(p, categories) {
{ 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 }); });
+ insertExtraSpecs(rackFallbackItems, p.extraSpecs, 'label');
return rackFallbackItems;
}
if (isUpsCategory(cat) && p.type === '迷你UPS') {
@@ -975,11 +992,11 @@ 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 }); });
+ insertExtraSpecs(items, p.extraSpecs, 'label');
return items;
}
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 }); });
+ insertExtraSpecs(fallbackItems, p.extraSpecs, 'label');
return fallbackItems;
}
@@ -5098,6 +5115,15 @@ function ProductForm({ draft, setDraft, onSave, onCancel, categories, onManage,
set({ extraSpecs: next });
}}
/>
+ {
+ const next = (draft.extraSpecs || []).slice();
+ next[idx] = { ...next[idx], afterLabel: e.target.value };
+ set({ extraSpecs: next });
+ }}
+ />