Просмотр исходного кода

fix(diet): 饮食首页改造——原生导航栏+空数据弹窗+未配置共餐降级

1. 前端:删除自定义 nav-bar,使用原生导航栏(pages.json 已有 title)
2. 前端:无菌群报告/无推荐食材时弹窗引导上传报告
3. 后端:generateIngredientList 未配置共餐时降级为查询
   家庭全部成员,而非返回空列表
asus 1 месяц назад
Родитель
Сommit
629abaf2e0

+ 33 - 20
cfc-backend/src/main/java/com/etotem/cfc/service/BeijingNutritionService.java

@@ -4,12 +4,14 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.etotem.cfc.common.Result;
 import com.etotem.cfc.dto.BeijingNutritionDTO.*;
 import com.etotem.cfc.dto.IngredientRecommendation;
+import com.etotem.cfc.entity.FamilyMember;
 import com.etotem.cfc.entity.Food;
 import com.etotem.cfc.entity.HealthGutFlora;
 import com.etotem.cfc.entity.HealthReport;
 import com.etotem.cfc.entity.MealConfig;
 import com.etotem.cfc.kb.BacteriaFoodMapping;
 import com.etotem.cfc.mapper.DietPreferencesMapper;
+import com.etotem.cfc.mapper.FamilyMemberMapper;
 import com.etotem.cfc.mapper.FoodMapper;
 import com.etotem.cfc.mapper.HealthGutFloraMapper;
 import com.etotem.cfc.mapper.HealthReportMapper;
@@ -48,6 +50,9 @@ public class BeijingNutritionService {
     @Resource
     private MealConfigMapper mealConfigMapper;
 
+    @Resource
+    private FamilyMemberMapper familyMemberMapper;
+
     // ============================================================
     // 核心推荐引擎
     // ============================================================
@@ -247,34 +252,42 @@ public class BeijingNutritionService {
         List<IngredientRecommendation> result = new ArrayList<>();
         
         // 1. 查 meal_configs → participant_member_ids
-        LambdaQueryWrapper<com.etotem.cfc.entity.MealConfig> configWrapper = new LambdaQueryWrapper<>();
-        configWrapper.eq(com.etotem.cfc.entity.MealConfig::getFamilyId, familyId);
-        configWrapper.eq(com.etotem.cfc.entity.MealConfig::getConfigDateType, isWeekend(date) ? "weekend" : "weekday");
-        List<com.etotem.cfc.entity.MealConfig> mealConfigs = mealConfigMapper.selectList(configWrapper);
-        
-        if (mealConfigs.isEmpty()) {
-            log.warn("家庭 {} 未配置共餐信息", familyId);
-            return result;
-        }
+        LambdaQueryWrapper<MealConfig> configWrapper = new LambdaQueryWrapper<>();
+        configWrapper.eq(MealConfig::getFamilyId, familyId);
+        configWrapper.eq(MealConfig::getConfigDateType, isWeekend(date) ? "weekend" : "weekday");
+        List<MealConfig> mealConfigs = mealConfigMapper.selectList(configWrapper);
         
-        // 2. 收集所有参与成员
+        // 2. 收集参与成员
         Set<Long> participantIds = new HashSet<>();
-        for (MealConfig config : mealConfigs) {
-            // 解析 participantMemberIds JSON
-            try {
-                com.fasterxml.jackson.databind.JsonNode nodes = new com.fasterxml.jackson.databind.ObjectMapper().readTree(config.getParticipantMemberIds());
-                if (nodes.isArray()) {
-                    for (com.fasterxml.jackson.databind.JsonNode node : nodes) {
-                        participantIds.add(node.asLong());
+        if (!mealConfigs.isEmpty()) {
+            for (MealConfig config : mealConfigs) {
+                // 解析 participantMemberIds JSON
+                try {
+                    com.fasterxml.jackson.databind.JsonNode nodes = new com.fasterxml.jackson.databind.ObjectMapper().readTree(config.getParticipantMemberIds());
+                    if (nodes.isArray()) {
+                        for (com.fasterxml.jackson.databind.JsonNode node : nodes) {
+                            participantIds.add(node.asLong());
+                        }
                     }
+                } catch (Exception e) {
+                    log.warn("解析 participantMemberIds 失败: {}", e.getMessage());
                 }
-            } catch (Exception e) {
-                log.warn("解析 participantMemberIds 失败: {}", e.getMessage());
             }
         }
         
+        // 未配置共餐时,降级为查询该家庭全部成员
         if (participantIds.isEmpty()) {
-            return result;
+            LambdaQueryWrapper<FamilyMember> memberWrapper = new LambdaQueryWrapper<>();
+            memberWrapper.eq(FamilyMember::getFamilyId, familyId);
+            List<FamilyMember> allMembers = familyMemberMapper.selectList(memberWrapper);
+            for (FamilyMember m : allMembers) {
+                participantIds.add(m.getId());
+            }
+            if (participantIds.isEmpty()) {
+                log.warn("家庭 {} 无任何家庭成员", familyId);
+                return result;
+            }
+            log.info("家庭 {} 未配置共餐,降级为使用全部 {} 个家庭成员", familyId, allMembers.size());
         }
         
         // 3. 查每个 member 的 diet_preferences + health_gut_flora

+ 17 - 42
cfc-frontend/pages/diet/index.vue

@@ -1,14 +1,5 @@
 <template>
   <view class="diet-page">
-    <!-- 顶部导航 -->
-    <view class="nav-bar">
-      <view class="nav-back" @tap="goBack">
-        <text class="back-text">‹ 返回</text>
-      </view>
-      <text class="nav-title">饮食</text>
-      <view class="nav-placeholder"></view>
-    </view>
-
     <scroll-view class="content" scroll-y>
       <!-- 今日共餐摘要 -->
       <view class="card meal-summary-card">
@@ -143,7 +134,8 @@ export default {
       trendData: {},
       showPicker: false,
       searchQuery: '',
-      searchResults: []
+      searchResults: [],
+      uploadPromptShown: false
     }
   },
   onLoad() {
@@ -157,9 +149,6 @@ export default {
     this.loadMealSummary()
   },
   methods: {
-    goBack() {
-      uni.navigateBack()
-    },
     navTo(url) {
       uni.navigateTo({ url: url })
     },
@@ -173,6 +162,21 @@ export default {
         self.ingredientsLoading = false
         if (res && res.ingredients) {
           self.ingredients = res.ingredients
+          // 无推荐食材时弹窗引导上传菌群报告
+          if (res.ingredients.length === 0 && !self.uploadPromptShown) {
+            self.uploadPromptShown = true
+            uni.showModal({
+              title: '暂无推荐食材',
+              content: '还未上传菌群报告,无法生成个性化食材推荐。是否前往上传报告?',
+              confirmText: '去上传',
+              cancelText: '稍后',
+              success: function(modalRes) {
+                if (modalRes.confirm) {
+                  uni.navigateTo({ url: '/pages/health/report-upload' })
+                }
+              }
+            })
+          }
         }
       }).catch(function() {
         self.ingredientsLoading = false
@@ -280,35 +284,6 @@ export default {
   display: flex;
   flex-direction: column;
 }
-.nav-bar {
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  height: 88rpx;
-  padding-top: env(safe-area-inset-top);
-  background-color: #FFFFFF;
-  position: relative;
-  border-bottom: 1rpx solid #f0f0f0;
-}
-.nav-back {
-  position: absolute;
-  left: 30rpx;
-  top: 50%;
-  transform: translateY(-50%);
-  padding: 10rpx;
-}
-.back-text {
-  font-size: 28rpx;
-  color: #333;
-}
-.nav-title {
-  font-size: 32rpx;
-  font-weight: 600;
-  color: #333;
-}
-.nav-placeholder {
-  width: 80rpx;
-}
 .content {
   flex: 1;
   padding: 30rpx;