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: {