Selaa lähdekoodia

feat(diet): 饮食推荐页面重新设计-修复居中/溢出/快捷入口不可点并全面美化

E2E Test Bot 1 kuukausi sitten
vanhempi
sitoutus
f8b3b7189b
1 muutettua tiedostoa jossa 433 lisäystä ja 195 poistoa
  1. 433 195
      cfc-frontend/pages/diet/index.vue

+ 433 - 195
cfc-frontend/pages/diet/index.vue

@@ -1,118 +1,177 @@
 <template>
   <view class="diet-page">
     <scroll-view class="content" scroll-y>
+      <!-- 页面标题区 -->
+      <view class="page-header">
+        <view class="header-icon-wrap">
+          <text class="header-icon">🍽️</text>
+        </view>
+        <view class="header-text">
+          <text class="header-title">饮食推荐</text>
+          <text class="header-subtitle">科学膳食 · 健康生活</text>
+        </view>
+      </view>
+
       <!-- 今日共餐摘要 -->
-      <view class="card meal-summary-card">
-        <view class="card-accent"></view>
-        <view class="card-body">
+      <view class="card">
+        <view class="card-header">
+          <view class="card-dot"></view>
           <text class="card-title">今日共餐</text>
-          <view class="meal-row" v-if="mealSummary.breakfast">
-            <text class="meal-label">早餐</text>
-            <text class="meal-members">{{ mealSummary.breakfast }}</text>
-          </view>
-          <view class="meal-row" v-if="mealSummary.lunch">
-            <text class="meal-label">午餐</text>
-            <text class="meal-members">{{ mealSummary.lunch }}</text>
+        </view>
+        <view class="card-body">
+          <view class="meal-grid">
+            <view class="meal-item" v-if="mealSummary.breakfast">
+              <text class="meal-emoji">🌅</text>
+              <text class="meal-label">早餐</text>
+              <text class="meal-members">{{ mealSummary.breakfast }}</text>
+            </view>
+            <view class="meal-item" v-if="mealSummary.lunch">
+              <text class="meal-emoji">☀️</text>
+              <text class="meal-label">午餐</text>
+              <text class="meal-members">{{ mealSummary.lunch }}</text>
+            </view>
+            <view class="meal-item" v-if="mealSummary.dinner">
+              <text class="meal-emoji">🌙</text>
+              <text class="meal-label">晚餐</text>
+              <text class="meal-members">{{ mealSummary.dinner }}</text>
+            </view>
           </view>
-          <view class="meal-row" v-if="mealSummary.dinner">
-            <text class="meal-label">晚餐</text>
-            <text class="meal-members">{{ mealSummary.dinner }}</text>
+          <view class="empty-hint" v-if="!mealSummary.breakfast && !mealSummary.lunch && !mealSummary.dinner">
+            <text class="empty-icon">📋</text>
+            <text class="empty-text">尚未配置共餐</text>
+            <text class="empty-sub">点击下方「共餐配置」开始设置</text>
           </view>
-          <text class="empty-hint" v-if="!mealSummary.breakfast && !mealSummary.lunch && !mealSummary.dinner">
-            尚未配置共餐,请先前往配置
-          </text>
         </view>
       </view>
 
       <!-- 食材推荐器 -->
-      <view class="card ingredient-card">
-        <view class="card-accent"></view>
+      <view class="card">
+        <view class="card-header">
+          <view class="card-dot"></view>
+          <text class="card-title">今日食材推荐</text>
+        </view>
         <view class="card-body">
-          <view class="section-header">
-            <text class="section-title">今日食材推荐</text>
-            <view class="action-btns">
-              <view class="btn-secondary" @tap="refreshIngredients">换一批</view>
-              <view class="btn-primary" @tap="showFoodPicker">添加食材</view>
-              <view class="btn-primary" @tap="generateRecipe" :class="{'disabled': selectedIngredients.length === 0}">
-                生成食谱
-              </view>
+          <view class="action-bar">
+            <view class="action-btn" @tap="refreshIngredients">
+              <text class="action-btn-text">🔄 换一批</text>
+            </view>
+            <view class="action-btn action-btn-primary" @tap="showFoodPicker">
+              <text class="action-btn-text-primary">+ 添加食材</text>
+            </view>
+            <view class="action-btn action-btn-accent" @tap="generateRecipe" :class="{'action-btn-disabled': selectedIngredients.length === 0}">
+              <text class="action-btn-text-accent">✨ 生成食谱</text>
             </view>
           </view>
-          
+
           <view class="ingredient-list" v-if="ingredients.length > 0">
             <view class="ingredient-item" v-for="(item, index) in ingredients" :key="getIngredientKey(item, index)">
-              <view class="ingredient-info">
-                <text class="ingredient-name">{{ item.name }}</text>
-                <text class="ingredient-reason" v-if="item.reason">{{ item.reason }}</text>
+              <view class="ingredient-left">
+                <view class="ingredient-badge">
+                  <text class="ingredient-badge-text">{{ index + 1 }}</text>
+                </view>
+                <view class="ingredient-info">
+                  <text class="ingredient-name">{{ item.name }}</text>
+                  <text class="ingredient-reason" v-if="item.reason">{{ item.reason }}</text>
+                </view>
+              </view>
+              <view class="ingredient-remove" @tap="removeIngredient(index)">
+                <text class="remove-text">✕</text>
               </view>
-              <view class="ingredient-remove" @tap="removeIngredient(index)">✕</view>
             </view>
           </view>
           <view class="empty-state" v-else>
-            <text>{{ ingredientsLoading ? '加载中...' : '暂无推荐食材' }}</text>
+            <text class="empty-icon">🥬</text>
+            <text class="empty-text">{{ ingredientsLoading ? '加载中...' : '暂无推荐食材' }}</text>
+            <text class="empty-sub" v-if="!ingredientsLoading">点击「添加食材」或「换一批」获取推荐</text>
           </view>
         </view>
       </view>
 
       <!-- 快捷入口 -->
+      <view class="section-label">
+        <text class="section-label-text">常用功能</text>
+      </view>
       <view class="nav-grid">
-        <view class="nav-item" @tap="navTo('pages/diet/food-query')">
-          <text class="nav-icon">🥗</text>
+        <view class="nav-item" @tap="navTo('/pages/diet/food-query')">
+          <view class="nav-icon-wrap nav-icon-green">
+            <text class="nav-icon">🥗</text>
+          </view>
           <text class="nav-label">食材查询</text>
         </view>
-        <view class="nav-item" @tap="navTo('pages/diet/records')">
-          <text class="nav-icon">📝</text>
+        <view class="nav-item" @tap="navTo('/pages/diet/records')">
+          <view class="nav-icon-wrap nav-icon-blue">
+            <text class="nav-icon">📝</text>
+          </view>
           <text class="nav-label">饮食记录</text>
         </view>
-        <view class="nav-item" @tap="navTo('pages/diet/preferences')">
-          <text class="nav-icon">📋</text>
+        <view class="nav-item" @tap="navTo('/pages/diet/preferences')">
+          <view class="nav-icon-wrap nav-icon-orange">
+            <text class="nav-icon">📋</text>
+          </view>
           <text class="nav-label">调研表</text>
         </view>
-        <view class="nav-item" @tap="navTo('pages/diet/meal-config')">
-          <text class="nav-icon">👨‍👩‍👧</text>
+        <view class="nav-item" @tap="navTo('/pages/diet/meal-config')">
+          <view class="nav-icon-wrap nav-icon-purple">
+            <text class="nav-icon">👨‍👩‍👧</text>
+          </view>
           <text class="nav-label">共餐配置</text>
         </view>
-        <view class="nav-item" @tap="navTo('pages/diet/recommendation')">
-          <text class="nav-icon">🍽️</text>
+        <view class="nav-item" @tap="navTo('/pages/diet/recommendation')">
+          <view class="nav-icon-wrap nav-icon-red">
+            <text class="nav-icon">🍽️</text>
+          </view>
           <text class="nav-label">食谱推荐</text>
         </view>
       </view>
 
       <!-- 本周趋势 -->
-      <view class="card trend-card" v-if="trendData.days > 0">
-        <view class="card-accent"></view>
-        <view class="card-body">
+      <view class="card" v-if="trendData.days > 0">
+        <view class="card-header">
+          <view class="card-dot"></view>
           <text class="card-title">本周饮食</text>
-          <view class="trend-stats">
-            <text class="trend-num">{{ trendData.totalCalories || 0 }}</text>
-            <text class="trend-unit">kcal</text>
-            <text class="trend-label">总摄入</text>
-          </view>
-          <view class="trend-stats">
-            <text class="trend-num">{{ trendData.days }}</text>
-            <text class="trend-unit">天</text>
-            <text class="trend-label">记录天数</text>
+        </view>
+        <view class="card-body">
+          <view class="trend-row">
+            <view class="trend-item">
+              <text class="trend-num">{{ trendData.totalCalories || 0 }}</text>
+              <text class="trend-unit">kcal</text>
+              <text class="trend-label">总摄入</text>
+            </view>
+            <view class="trend-divider"></view>
+            <view class="trend-item">
+              <text class="trend-num">{{ trendData.days }}</text>
+              <text class="trend-unit">天</text>
+              <text class="trend-label">记录天数</text>
+            </view>
           </view>
         </view>
       </view>
+
+      <!-- 底部留白 -->
+      <view class="bottom-space"></view>
     </scroll-view>
 
     <!-- 食材选择弹窗 -->
     <view class="modal" v-if="showPicker" @tap="closePicker">
+      <view class="modal-mask"></view>
       <view class="modal-content" @tap.stop>
         <view class="modal-header">
           <text class="modal-title">选择食材</text>
-          <text class="modal-close" @tap="closePicker">✕</text>
+          <view class="modal-close" @tap="closePicker">
+            <text class="close-text">✕</text>
+          </view>
+        </view>
+        <view class="search-wrap">
+          <input class="search-input" placeholder="搜索食材..." placeholder-style="color:#bbb" v-model="searchQuery" @input="searchFood" />
         </view>
-        <input class="search-input" placeholder="搜索食材..." v-model="searchQuery" @input="searchFood" />
         <scroll-view class="food-list" scroll-y>
           <view class="food-item" v-for="food in searchResults" :key="food.id" @tap="addFood(food)">
             <text class="food-name">{{ food.name }}</text>
-            <text class="food-category">{{ food.category }}</text>
+            <text class="food-tag">{{ food.category }}</text>
           </view>
         </scroll-view>
         <view class="empty-state" v-if="searchResults.length === 0 && searchQuery">
-          <text>未找到匹配食材</text>
+          <text class="empty-text">未找到匹配食材</text>
         </view>
       </view>
     </view>
@@ -124,7 +183,7 @@ import { getDietIngredients, refreshDietIngredients, addDietIngredient, removeDi
 import { parseDate } from '@/utils/format.js'
 
 export default {
-  data() {
+  data: function() {
     return {
       familyId: null,
       familyMemberId: null,
@@ -139,31 +198,30 @@ export default {
       uploadPromptShown: false
     }
   },
-  onLoad() {
+  onLoad: function() {
     this.familyId = uni.getStorageSync('familyId')
     this.familyMemberId = uni.getStorageSync('currentChildId') || uni.getStorageSync('currentMemberId') || uni.getStorageSync('userId')
     this.loadIngredients()
     this.loadMealSummary()
   },
-  onShow() {
+  onShow: function() {
     this.loadIngredients()
     this.loadMealSummary()
   },
   methods: {
-    navTo(url) {
+    navTo: function(url) {
       uni.navigateTo({ url: url })
     },
-    getIngredientKey(item, index) {
+    getIngredientKey: function(item, index) {
       return 'ing-' + (item.id || index)
     },
-    loadIngredients() {
+    loadIngredients: function() {
       this.ingredientsLoading = true
       var self = this
       getDietIngredients().then(function(res) {
         self.ingredientsLoading = false
         if (res && res.ingredients) {
           self.ingredients = res.ingredients
-          // 无推荐食材时弹窗引导上传菌群报告
           if (res.ingredients.length === 0 && !self.uploadPromptShown) {
             self.uploadPromptShown = true
             uni.showModal({
@@ -183,7 +241,7 @@ export default {
         self.ingredientsLoading = false
       })
     },
-    refreshIngredients() {
+    refreshIngredients: function() {
       var self = this
       refreshDietIngredients().then(function(res) {
         if (res && res.ingredients) {
@@ -191,24 +249,24 @@ export default {
         }
       })
     },
-    addIngredient(index) {
+    addIngredient: function(index) {
       var self = this
       var item = this.ingredients[index]
       addDietIngredient({ food_id: item.foodId, name: item.name }).then(function(res) {
         self.loadIngredients()
       })
     },
-    removeIngredient(index) {
+    removeIngredient: function(index) {
       var self = this
       var item = this.ingredients[index]
       removeDietIngredient({ food_id: item.foodId }).then(function(res) {
         self.loadIngredients()
       })
     },
-    generateRecipe() {
+    generateRecipe: function() {
       var self = this
       var foodIds = this.ingredients.map(function(item) { return { food_id: item.foodId, name: item.name } })
-      generateDietRecommendation({ 
+      generateDietRecommendation({
         date: self.formatDate(new Date()),
         meal_type: 'all',
         selected_foods: JSON.stringify(foodIds)
@@ -216,19 +274,21 @@ export default {
         if (res && res.id) {
           uni.showToast({ title: '食谱生成成功', icon: 'success' })
           setTimeout(function() {
-            self.navTo('pages/diet/recommendation')
+            self.navTo('/pages/diet/recommendation')
           }, 1000)
         }
       })
     },
-    formatDate(date) {
+    formatDate: function(date) {
       var d = parseDate(date)
       if (!d) return ''
-      var m = (d.getMonth() + 1).toString().padStart(2, '0')
-      var day = d.getDate().toString().padStart(2, '0')
+      var m = (d.getMonth() + 1).toString()
+      if (m.length < 2) m = '0' + m
+      var day = d.getDate().toString()
+      if (day.length < 2) day = '0' + day
       return d.getFullYear() + '-' + m + '-' + day
     },
-    loadMealSummary() {
+    loadMealSummary: function() {
       var self = this
       var dateType = self.isWeekend(new Date()) ? 'weekend' : 'weekday'
       Promise.all([
@@ -241,7 +301,7 @@ export default {
         self.mealSummary.dinner = self.parseMembers(results[2])
       })
     },
-    parseMembers(config) {
+    parseMembers: function(config) {
       if (!config || !config.participantMemberIds) return ''
       try {
         var ids = JSON.parse(config.participantMemberIds)
@@ -250,27 +310,26 @@ export default {
         return ''
       }
     },
-    isWeekend(date) {
+    isWeekend: function(date) {
       var day = date.getDay()
       return day === 0 || day === 6
     },
-    showFoodPicker() {
+    showFoodPicker: function() {
       this.showPicker = true
     },
-    closePicker() {
+    closePicker: function() {
       this.showPicker = false
       this.searchQuery = ''
       this.searchResults = []
     },
-    searchFood() {
+    searchFood: function() {
       if (!this.searchQuery) {
         this.searchResults = []
         return
       }
-      // 简化:实际应调用搜索API
       this.searchResults = []
     },
-    addFood(food) {
+    addFood: function(food) {
       var self = this
       addDietIngredient({ food_id: food.id, name: food.name }).then(function(res) {
         self.closePicker()
@@ -284,235 +343,414 @@ export default {
 <style scoped>
 .diet-page {
   min-height: 100vh;
-  background-color: #F5F7FA;
+  background: linear-gradient(180deg, #FFF7ED 0%, #FFF3E6 30%, #F5F7FA 100%);
+}
+.content {
+  padding: 24rpx 32rpx;
+}
+
+/* 页面头部 */
+.page-header {
+  display: flex;
+  align-items: center;
+  padding: 20rpx 0 32rpx;
+}
+.header-icon-wrap {
+  width: 80rpx;
+  height: 80rpx;
+  border-radius: 24rpx;
+  background: linear-gradient(135deg, #FF8C42, #FFB366);
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  margin-right: 24rpx;
+  flex-shrink: 0;
+}
+.header-icon {
+  font-size: 40rpx;
+}
+.header-text {
   display: flex;
   flex-direction: column;
 }
-.content {
-  flex: 1;
-  padding: 30rpx;
+.header-title {
+  font-size: 36rpx;
+  font-weight: 700;
+  color: #333;
+}
+.header-subtitle {
+  font-size: 24rpx;
+  color: #999;
+  margin-top: 4rpx;
 }
+
+/* 卡片通用 */
 .card {
-  display: flex;
-  background-color: #FFFFFF;
-  border-radius: 20rpx;
-  margin-bottom: 30rpx;
-  box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.06);
+  background: #FFFFFF;
+  border-radius: 24rpx;
+  margin-bottom: 24rpx;
+  box-shadow: 0 4rpx 20rpx rgba(255, 140, 66, 0.08);
   overflow: hidden;
 }
-.card-accent {
+.card-header {
+  display: flex;
+  align-items: center;
+  padding: 28rpx 28rpx 0;
+}
+.card-dot {
   width: 8rpx;
-  background-color: #FF8C42;
+  height: 32rpx;
+  border-radius: 4rpx;
+  background: linear-gradient(180deg, #FF8C42, #FFB366);
+  margin-right: 16rpx;
   flex-shrink: 0;
 }
-.card-body {
-  flex: 1;
-  padding: 30rpx;
-}
 .card-title {
   font-size: 30rpx;
   font-weight: 600;
   color: #333;
-  margin-bottom: 20rpx;
-  display: block;
 }
-.section-header {
+.card-body {
+  padding: 24rpx 28rpx 28rpx;
+}
+
+/* 共餐格子 */
+.meal-grid {
   display: flex;
   justify-content: space-between;
+}
+.meal-item {
+  flex: 1;
+  display: flex;
+  flex-direction: column;
   align-items: center;
-  margin-bottom: 20rpx;
+  background: #FFF8F0;
+  border-radius: 16rpx;
+  padding: 24rpx 12rpx;
+  margin-left: 12rpx;
+  margin-right: 12rpx;
 }
-.section-title {
-  font-size: 28rpx;
+.meal-item:first-child {
+  margin-left: 0;
+}
+.meal-item:last-child {
+  margin-right: 0;
+}
+.meal-emoji {
+  font-size: 36rpx;
+  margin-bottom: 8rpx;
+}
+.meal-label {
+  font-size: 24rpx;
+  color: #666;
+  margin-bottom: 4rpx;
+}
+.meal-members {
+  font-size: 24rpx;
+  color: #FF8C42;
   font-weight: 600;
-  color: #333;
 }
-.action-btns {
+
+/* 操作按钮栏 */
+.action-bar {
   display: flex;
-  gap: 16rpx;
+  margin-bottom: 24rpx;
+}
+.action-btn {
+  padding: 14rpx 24rpx;
+  border-radius: 32rpx;
+  background: #F5F5F5;
+  margin-right: 16rpx;
+}
+.action-btn:last-child {
+  margin-right: 0;
+}
+.action-btn-primary {
+  background: #FF8C42;
+}
+.action-btn-accent {
+  background: #FFF0E0;
+}
+.action-btn-disabled {
+  opacity: 0.4;
 }
-.btn-secondary {
-  padding: 12rpx 24rpx;
-  border: 1rpx solid #ddd;
-  border-radius: 30rpx;
+.action-btn-text {
   font-size: 24rpx;
   color: #666;
 }
-.btn-primary {
-  padding: 12rpx 24rpx;
-  background-color: #FF8C42;
-  color: #FFFFFF;
-  border-radius: 30rpx;
+.action-btn-text-primary {
   font-size: 24rpx;
+  color: #FFFFFF;
 }
-.btn-primary.disabled {
-  background-color: #ccc;
+.action-btn-text-accent {
+  font-size: 24rpx;
+  color: #FF8C42;
 }
+
+/* 食材列表 */
 .ingredient-list {
-  display: flex;
-  flex-direction: column;
-  gap: 16rpx;
+  margin-top: 8rpx;
 }
 .ingredient-item {
   display: flex;
+  align-items: center;
   justify-content: space-between;
+  padding: 20rpx 0;
+  border-bottom: 1rpx solid #F5F5F5;
+}
+.ingredient-item:last-child {
+  border-bottom: none;
+}
+.ingredient-left {
+  display: flex;
   align-items: center;
-  padding: 16rpx 0;
-  border-bottom: 1rpx solid #f0f0f0;
+  flex: 1;
+}
+.ingredient-badge {
+  width: 40rpx;
+  height: 40rpx;
+  border-radius: 12rpx;
+  background: linear-gradient(135deg, #FF8C42, #FFB366);
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  margin-right: 20rpx;
+  flex-shrink: 0;
+}
+.ingredient-badge-text {
+  font-size: 20rpx;
+  color: #FFFFFF;
+  font-weight: 600;
 }
 .ingredient-info {
   display: flex;
   flex-direction: column;
-  gap: 4rpx;
+  flex: 1;
 }
 .ingredient-name {
-  font-size: 26rpx;
+  font-size: 28rpx;
   color: #333;
   font-weight: 500;
 }
 .ingredient-reason {
   font-size: 22rpx;
   color: #999;
+  margin-top: 4rpx;
 }
 .ingredient-remove {
-  width: 40rpx;
-  height: 40rpx;
+  width: 48rpx;
+  height: 48rpx;
   display: flex;
   align-items: center;
   justify-content: center;
-  font-size: 24rpx;
-  color: #999;
-}
-.meal-row {
-  display: flex;
-  justify-content: space-between;
-  padding: 12rpx 0;
-  border-bottom: 1rpx solid #f0f0f0;
-}
-.meal-label {
-  font-size: 26rpx;
-  color: #666;
+  flex-shrink: 0;
 }
-.meal-members {
-  font-size: 26rpx;
-  color: #FF8C42;
-  font-weight: 500;
+.remove-text {
+  font-size: 28rpx;
+  color: #ccc;
 }
-.empty-hint {
-  font-size: 24rpx;
-  color: #999;
-  text-align: center;
-  padding: 20rpx 0;
+
+/* 区域标签 */
+.section-label {
+  padding: 8rpx 0 16rpx;
 }
-.empty-state {
-  text-align: center;
-  padding: 40rpx 0;
-  font-size: 26rpx;
-  color: #999;
+.section-label-text {
+  font-size: 28rpx;
+  font-weight: 600;
+  color: #333;
 }
+
+/* 快捷入口网格 */
 .nav-grid {
   display: flex;
   flex-wrap: wrap;
-  justify-content: space-between;
-  margin-bottom: 30rpx;
+  margin-bottom: 24rpx;
 }
 .nav-item {
-  width: 30%;
-  background-color: #FFFFFF;
-  border-radius: 20rpx;
-  padding: 30rpx 0;
-  margin-bottom: 20rpx;
+  width: 20%;
   display: flex;
   flex-direction: column;
   align-items: center;
-  box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.06);
+  padding: 20rpx 0;
+  position: relative;
+  z-index: 1;
 }
-.nav-icon {
-  font-size: 48rpx;
+.nav-icon-wrap {
+  width: 88rpx;
+  height: 88rpx;
+  border-radius: 24rpx;
+  display: flex;
+  align-items: center;
+  justify-content: center;
   margin-bottom: 12rpx;
 }
+.nav-icon-green {
+  background: linear-gradient(135deg, #E8F5E9, #C8E6C9);
+}
+.nav-icon-blue {
+  background: linear-gradient(135deg, #E3F2FD, #BBDEFB);
+}
+.nav-icon-orange {
+  background: linear-gradient(135deg, #FFF3E0, #FFE0B2);
+}
+.nav-icon-purple {
+  background: linear-gradient(135deg, #F3E5F5, #E1BEE7);
+}
+.nav-icon-red {
+  background: linear-gradient(135deg, #FBE9E7, #FFCCBC);
+}
+.nav-icon {
+  font-size: 36rpx;
+}
 .nav-label {
-  font-size: 24rpx;
+  font-size: 22rpx;
   color: #333;
 }
-.trend-stats {
+
+/* 趋势卡片 */
+.trend-row {
   display: flex;
-  align-items: baseline;
-  gap: 8rpx;
-  margin-bottom: 16rpx;
+  align-items: center;
+}
+.trend-item {
+  flex: 1;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+}
+.trend-divider {
+  width: 1rpx;
+  height: 60rpx;
+  background: #F0F0F0;
 }
 .trend-num {
   font-size: 48rpx;
-  font-weight: 600;
+  font-weight: 700;
   color: #FF8C42;
 }
 .trend-unit {
-  font-size: 24rpx;
+  font-size: 22rpx;
   color: #999;
+  margin-top: 4rpx;
 }
 .trend-label {
-  font-size: 24rpx;
+  font-size: 22rpx;
   color: #666;
-  margin-left: auto;
+  margin-top: 4rpx;
 }
+
+/* 空状态 */
+.empty-hint {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  padding: 20rpx 0;
+}
+.empty-state {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  padding: 40rpx 0;
+}
+.empty-icon {
+  font-size: 48rpx;
+  margin-bottom: 12rpx;
+}
+.empty-text {
+  font-size: 26rpx;
+  color: #999;
+}
+.empty-sub {
+  font-size: 22rpx;
+  color: #ccc;
+  margin-top: 8rpx;
+}
+
+/* 弹窗 */
 .modal {
   position: fixed;
   top: 0;
   left: 0;
   right: 0;
   bottom: 0;
-  background-color: rgba(0, 0, 0, 0.5);
+  z-index: 999;
   display: flex;
-  align-items: center;
+  align-items: flex-end;
   justify-content: center;
-  z-index: 999;
+}
+.modal-mask {
+  position: fixed;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  background: rgba(0, 0, 0, 0.5);
 }
 .modal-content {
-  width: 90%;
-  max-height: 80%;
-  background-color: #FFFFFF;
-  border-radius: 20rpx;
-  padding: 30rpx;
+  position: relative;
+  width: 100%;
+  max-height: 80vh;
+  background: #FFFFFF;
+  border-radius: 32rpx 32rpx 0 0;
+  padding: 32rpx;
+  z-index: 1;
 }
 .modal-header {
   display: flex;
-  justify-content: space-between;
   align-items: center;
-  margin-bottom: 20rpx;
+  justify-content: space-between;
+  margin-bottom: 24rpx;
 }
 .modal-title {
-  font-size: 30rpx;
+  font-size: 32rpx;
   font-weight: 600;
   color: #333;
 }
 .modal-close {
+  width: 48rpx;
+  height: 48rpx;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+.close-text {
   font-size: 32rpx;
   color: #999;
 }
-.search-input {
-  border: 1rpx solid #ddd;
-  border-radius: 30rpx;
-  padding: 16rpx 24rpx;
-  font-size: 26rpx;
-  background-color: #FAFAFA;
+.search-wrap {
   margin-bottom: 20rpx;
 }
+.search-input {
+  border: 1rpx solid #eee;
+  border-radius: 40rpx;
+  padding: 20rpx 28rpx;
+  font-size: 28rpx;
+  background: #F8F8F8;
+}
 .food-list {
   max-height: 500rpx;
-  overflow-y: auto;
 }
 .food-item {
   display: flex;
+  align-items: center;
   justify-content: space-between;
-  padding: 20rpx 0;
-  border-bottom: 1rpx solid #f0f0f0;
+  padding: 24rpx 0;
+  border-bottom: 1rpx solid #F5F5F5;
 }
 .food-name {
-  font-size: 26rpx;
+  font-size: 28rpx;
   color: #333;
 }
-.food-category {
-  font-size: 24rpx;
-  color: #999;
+.food-tag {
+  font-size: 22rpx;
+  color: #FF8C42;
+  background: #FFF0E0;
+  padding: 6rpx 16rpx;
+  border-radius: 20rpx;
+}
+
+/* 底部留白 */
+.bottom-space {
+  height: 40rpx;
 }
 </style>