From 2a823e5bacf2aed3d9b1b145287038b16c61398e Mon Sep 17 00:00:00 2001 From: Hera Zhao Date: Thu, 9 Apr 2026 16:09:52 +0000 Subject: [PATCH] =?UTF-8?q?feat:=20=E7=B2=BE=E6=B2=B9=E4=BB=B7=E7=9B=AE?= =?UTF-8?q?=E9=A1=B5=E4=BC=98=E5=8C=96=20=E2=80=94=20=E5=90=8D=E7=A7=B0?= =?UTF-8?q?=E7=BC=A9=E6=94=BE=E3=80=81=E5=8E=BB=E5=AE=B9=E9=87=8F=E3=80=81?= =?UTF-8?q?=E7=BA=A2=E8=89=B2=E5=BA=95=E8=89=B2=E3=80=81=E4=B8=8B=E6=9E=B6?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 显示优化: - 中文名和英文名各一行,nowrap+ellipsis不换行 - 去掉📖 emoji标记 - 去掉右侧容量标签 - 划掉的零售价后面加/瓶,跟会员价一致 管理员功能: - 信息不全的精油(缺价格/滴数/零售价)显示浅红底色 - 补全后自动恢复正常底色 - 编辑弹窗加"下架"按钮,下架后所有人看到浅灰底色 - 已下架可"重新上架" 后端: - OilIn model 加 is_active 字段 - upsert 支持更新 is_active Co-Authored-By: Claude Opus 4.6 (1M context) --- backend/main.py | 8 ++- frontend/src/views/OilReference.vue | 85 ++++++++++++++++++++++++----- 2 files changed, 77 insertions(+), 16 deletions(-) diff --git a/backend/main.py b/backend/main.py index 9786964..746bcc9 100644 --- a/backend/main.py +++ b/backend/main.py @@ -80,6 +80,7 @@ class OilIn(BaseModel): drop_count: int retail_price: Optional[float] = None en_name: Optional[str] = None + is_active: Optional[int] = None class IngredientIn(BaseModel): @@ -659,10 +660,11 @@ def list_oils(): def upsert_oil(oil: OilIn, user=Depends(require_role("admin", "senior_editor"))): conn = get_db() conn.execute( - "INSERT INTO oils (name, bottle_price, drop_count, retail_price, en_name) VALUES (?, ?, ?, ?, ?) " + "INSERT INTO oils (name, bottle_price, drop_count, retail_price, en_name, is_active) VALUES (?, ?, ?, ?, ?, ?) " "ON CONFLICT(name) DO UPDATE SET bottle_price=excluded.bottle_price, drop_count=excluded.drop_count, " - "retail_price=excluded.retail_price, en_name=COALESCE(excluded.en_name, oils.en_name)", - (oil.name, oil.bottle_price, oil.drop_count, oil.retail_price, oil.en_name), + "retail_price=excluded.retail_price, en_name=COALESCE(excluded.en_name, oils.en_name), " + "is_active=COALESCE(excluded.is_active, oils.is_active)", + (oil.name, oil.bottle_price, oil.drop_count, oil.retail_price, oil.en_name, oil.is_active), ) log_audit(conn, user["id"], "upsert_oil", "oil", oil.name, oil.name, json.dumps({"bottle_price": oil.bottle_price, "drop_count": oil.drop_count})) diff --git a/frontend/src/views/OilReference.vue b/frontend/src/views/OilReference.vue index aec177d..805d171 100644 --- a/frontend/src/views/OilReference.vue +++ b/frontend/src/views/OilReference.vue @@ -124,23 +124,20 @@ v-for="name in filteredOilNames" :key="name + '-' + cardVersion" class="oil-chip" + :class="{ 'oil-chip--inactive': getMeta(name)?.isActive === false, 'oil-chip--incomplete': auth.isAdmin && isIncomplete(name) }" :style="chipStyle(name)" @click="openOilDetail(name)" >
- {{ name }} - 📖 - -
- {{ getEnglishName(name) }} +
{{ name }}
+
{{ getEnglishName(name) }}