diff --git a/frontend/src/components/RecipeDetailOverlay.vue b/frontend/src/components/RecipeDetailOverlay.vue index 207edb5..f61cbff 100644 --- a/frontend/src/components/RecipeDetailOverlay.vue +++ b/frontend/src/components/RecipeDetailOverlay.vue @@ -624,17 +624,24 @@ async function applyTranslation() { } // 2. Save each oil's English name to oils table (syncs with oil reference page) + let failed = 0 for (const [oilName, enName] of Object.entries(customOilNameEn.value)) { if (!enName?.trim()) continue const meta = oilsStore.oilsMeta[oilName] - if (!meta || meta.enName === enName.trim()) continue + if (!meta) continue + if (meta.enName === enName.trim()) continue try { await oilsStore.saveOil(oilName, meta.bottlePrice, meta.dropCount, meta.retailPrice, enName.trim()) saved++ - } catch {} + } catch (e) { + console.error('Save oil en_name failed:', oilName, e) + failed++ + } } - if (saved > 0) ui.showToast(`翻译已保存(${saved}项)`) + if (saved > 0) ui.showToast(`翻译已保存(${saved}项)` + (failed > 0 ? `,${failed}项失败` : '')) + else if (failed > 0) ui.showToast(`保存失败 ${failed} 项`) + else ui.showToast('没有修改') cardImageUrl.value = null nextTick(() => generateCardImage()) diff --git a/frontend/src/views/OilReference.vue b/frontend/src/views/OilReference.vue index 4e6b72a..5552c76 100644 --- a/frontend/src/views/OilReference.vue +++ b/frontend/src/views/OilReference.vue @@ -673,24 +673,38 @@ async function saveEditOil() { async function toggleOilActive() { const name = editingOilName.value - if (!name) return + if (!name) { ui.showToast('错误: 没有选中精油'); return } const meta = getMeta(name) - const newActive = meta?.isActive === false ? 1 : 0 + if (!meta) { ui.showToast('错误: 找不到精油数据'); return } + const newActive = meta.isActive === false ? 1 : 0 + const payload = { + name, + bottle_price: Number(meta.bottlePrice) || 0, + drop_count: Number(meta.dropCount) || 1, + retail_price: meta.retailPrice ? Number(meta.retailPrice) : null, + en_name: meta.enName || null, + is_active: newActive, + } try { - await api.post('/api/oils', { - name, - bottle_price: meta?.bottlePrice || 0, - drop_count: meta?.dropCount || 1, - retail_price: meta?.retailPrice || null, - en_name: meta?.enName || null, - is_active: newActive, + const res = await fetch('/api/oils', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'Authorization': 'Bearer ' + localStorage.getItem('oil_auth_token'), + }, + body: JSON.stringify(payload), }) + if (!res.ok) { + const text = await res.text() + ui.showToast('下架失败[' + res.status + ']: ' + text) + return + } await oils.loadOils() cardVersion.value++ ui.showToast(newActive ? '已重新上架' : '已下架') editingOilName.value = null } catch (e) { - ui.showToast('操作失败: ' + (e.message || e)) + ui.showToast('网络错误: ' + e.message) } } @@ -1231,10 +1245,12 @@ async function saveCardImage(name) { white-space: nowrap; } @media (max-width: 480px) { - .oil-name-line { font-size: 12px; } + .oil-name-line { font-size: 13px; } .oil-en-line { font-size: 9px; } - .oil-price-line { font-size: 11px; } - .oil-retail-line { font-size: 9px; } + .oil-price-line { font-size: 12px; } + .oil-retail-line { font-size: 10px; } + .oils-grid { grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 8px; } + .oil-chip { padding: 10px 12px; } } .oil-chip-actions {