diff --git a/frontend/src/views/Projects.vue b/frontend/src/views/Projects.vue index 5789973..7717620 100644 --- a/frontend/src/views/Projects.vue +++ b/frontend/src/views/Projects.vue @@ -42,7 +42,7 @@ 成本 {{ oils.fmtPrice(oils.calcCost(p.ingredients)) }} -
+
@@ -72,8 +72,8 @@ 精油 - 单次用量(滴) - 单价/滴 + 用量 + 每滴 小计 @@ -127,7 +127,8 @@
- ⚠️ {{ limitingOil }} 最先消耗完,最多可做 {{ maxSessions }} + 可做 {{ maxSessions }} + ⚠️ {{ limitingOil }} 最先消耗完,可做 {{ maxSessions }}
@@ -467,6 +468,12 @@ const limitingOil = computed(() => { return min.oil }) +const allSameSession = computed(() => { + const data = consumptionData.value.filter(c => c.sessions > 0) + if (data.length <= 1) return true + return data.every(c => c.sessions === data[0].sessions) +}) + const maxSessions = computed(() => { const data = consumptionData.value.filter(c => c.sessions > 0) if (!data.length) return 0 @@ -490,6 +497,9 @@ function formatDate(d) { .commercial-icon { font-size: 48px; margin-bottom: 8px; } .commercial-desc { font-size: 14px; color: var(--text-light, #999); } .demo-card { border-style: dashed !important; opacity: 0.85; } +.proj-actions-hover { opacity: 0; transition: opacity 0.15s; } +.project-card:hover .proj-actions-hover { opacity: 1; } + .readonly-row { background: #f8f7f5; } .readonly-oil { font-size: 13px; color: #6b6375; } .readonly-drops { font-size: 13px; color: #3e3a44; font-weight: 500; } @@ -657,6 +667,7 @@ function formatDate(d) { .section-actions { display: flex; gap: 6px; } .ingredients-table { width: 100%; border-collapse: collapse; margin-bottom: 12px; } +.ingredients-table th { white-space: nowrap; } .ingredients-table th { text-align: center; padding: 10px 8px; font-size: 12px; font-weight: 600; color: var(--text-light, #999); border-bottom: 2px solid #e5e4e7; @@ -667,7 +678,7 @@ function formatDate(d) { .drops-input:focus { border-color: #7ec6a4; } .cell-ppd { color: #999; font-size: 12px; } .cell-subtotal { color: #4a9d7e; font-weight: 600; } -.remove-btn { border: none; background: none; color: #ccc; cursor: pointer; font-size: 18px; } +.remove-btn { border: none; background: none; color: #ccc; cursor: pointer; font-size: 14px; padding: 2px; } .remove-btn:hover { color: #c0392b; } .total-row { @@ -706,12 +717,14 @@ function formatDate(d) { .price-row { display: flex; - justify-content: space-between; align-items: center; padding: 8px 0; border-bottom: 1px solid #eae8e5; font-size: 14px; + gap: 12px; } +.price-row .price-label { flex: 0 0 80px; } +.price-row .price-value, .price-row .price-input-wrap, .price-row .form-input-inline { flex: 1; } .price-row.total { border-top: 2px solid #d4cfc7; diff --git a/frontend/vite.config.js b/frontend/vite.config.js index c87bd26..32d8d86 100644 --- a/frontend/vite.config.js +++ b/frontend/vite.config.js @@ -1,7 +1,7 @@ import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' -const buildTime = new Date().toLocaleString('zh-CN', { timeZone: 'Asia/Shanghai', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit' }) +const buildTime = new Date().toLocaleString('en-GB', { timeZone: 'Europe/London', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit' }) export default defineConfig({ define: {