Kaynağa Gözat

fix: diet/record/daily, survey/status, survey/history memberId 为空时优雅降级

- DietRecordController /daily /weekly: 必填 @RequestAttribute(familyMemberId) + @RequestParam 改为 @RequestBody + required=false 兜底,消除 Missing request attribute 500
- DietRecordService: getDailySummary/getWeeklyTrend 增加 userId 参数 + resolveMemberId 反查当前用户自己的 family_members 记录
- SurveyController: 移除 status/history/submit 的缺少成员ID 报错
- SurveyServiceImpl: resolveMemberId 兜底,submit 时仍无法确定则抛业务异常返回 400
Xiaogang Liao 1 ay önce
ebeveyn
işleme
bbee4803cc

+ 0 - 3
cfc-backend/src/main/java/com/etotem/cfc/controller/SurveyController.java

@@ -29,7 +29,6 @@ public class SurveyController {
             @RequestAttribute(value = "currentMemberId", required = false) Long currentMemberId) {
         Long memberId = params.get("memberId") != null
                 ? Long.valueOf(params.get("memberId").toString()) : currentMemberId;
-        if (memberId == null) return Result.error("缺少成员ID");
         return Result.success(surveyService.getSurveyStatus(userId, memberId));
     }
 
@@ -47,7 +46,6 @@ public class SurveyController {
             @RequestAttribute(value = "currentMemberId", required = false) Long currentMemberId) {
         Long memberId = params.get("memberId") != null
                 ? Long.valueOf(params.get("memberId").toString()) : currentMemberId;
-        if (memberId == null) return Result.error("缺少成员ID");
         Long templateId = Long.valueOf(params.get("templateId").toString());
         String answersJson = (String) params.get("answersJson");
         Date ps = params.get("periodStart") != null ? new Date(Long.valueOf(params.get("periodStart").toString())) : null;
@@ -63,7 +61,6 @@ public class SurveyController {
             @RequestAttribute(value = "currentMemberId", required = false) Long currentMemberId) {
         Long memberId = params.get("memberId") != null
                 ? Long.valueOf(params.get("memberId").toString()) : currentMemberId;
-        if (memberId == null) return Result.error("缺少成员ID");
         return Result.success(surveyService.getSurveyHistory(userId, memberId));
     }
 }

+ 15 - 6
cfc-backend/src/main/java/com/etotem/cfc/controller/diet/DietRecordController.java

@@ -28,15 +28,24 @@ public class DietRecordController {
 
     @PostMapping("/daily")
     public Result<Map> getDailySummary(
-            @RequestAttribute("familyMemberId") Long familyMemberId,
-            @RequestParam String date) {
-        return Result.success(dietRecordService.getDailySummary(familyMemberId, date));
+            @RequestAttribute("userId") Long userId,
+            @RequestBody Map<String, Object> params,
+            @RequestAttribute(value = "familyMemberId", required = false) Long familyMemberId,
+            @RequestAttribute(value = "currentMemberId", required = false) Long currentMemberId) {
+        Long memberId = familyMemberId != null ? familyMemberId : currentMemberId;
+        String date = params.get("date") != null ? params.get("date").toString() : java.time.LocalDate.now().toString();
+        return Result.success(dietRecordService.getDailySummary(userId, memberId, date));
     }
 
     @PostMapping("/weekly")
     public Result<Map> getWeeklyTrend(
-            @RequestAttribute("familyMemberId") Long familyMemberId,
-            @RequestParam String startDate) {
-        return Result.success(dietRecordService.getWeeklyTrend(familyMemberId, startDate));
+            @RequestAttribute("userId") Long userId,
+            @RequestBody Map<String, Object> params,
+            @RequestAttribute(value = "familyMemberId", required = false) Long familyMemberId,
+            @RequestAttribute(value = "currentMemberId", required = false) Long currentMemberId) {
+        Long memberId = familyMemberId != null ? familyMemberId : currentMemberId;
+        String startDate = params.get("startDate") != null ? params.get("startDate").toString() : null;
+        if (startDate == null) return Result.error("startDate不能为空");
+        return Result.success(dietRecordService.getWeeklyTrend(userId, memberId, startDate));
     }
 }

+ 42 - 16
cfc-backend/src/main/java/com/etotem/cfc/service/DietRecordService.java

@@ -4,8 +4,10 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.etotem.cfc.dto.RecognizeFoodResult;
 import com.etotem.cfc.entity.DietRecord;
 import com.etotem.cfc.entity.DietRecordItem;
+import com.etotem.cfc.entity.FamilyMember;
 import com.etotem.cfc.mapper.DietRecordItemMapper;
 import com.etotem.cfc.mapper.DietRecordMapper;
+import com.etotem.cfc.mapper.FamilyMemberMapper;
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import lombok.extern.slf4j.Slf4j;
@@ -27,6 +29,9 @@ public class DietRecordService {
     @Resource
     private DietRecordItemMapper dietRecordItemMapper;
 
+    @Resource
+    private FamilyMemberMapper familyMemberMapper;
+
     @Resource
     private AiGateway aiGateway;
 
@@ -84,40 +89,61 @@ public class DietRecordService {
         return result;
     }
 
-    public Map<String, Object> getDailySummary(Long memberId, String dateStr) {
+    public Map<String, Object> getDailySummary(Long userId, Long memberId, String dateStr) {
+        memberId = resolveMemberId(userId, memberId);
         LocalDate date = LocalDate.parse(dateStr, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
-        
-        LambdaQueryWrapper<DietRecord> wrapper = new LambdaQueryWrapper<>();
-        wrapper.eq(DietRecord::getMemberId, memberId)
-               .eq(DietRecord::getRecordDate, date);
-        List<DietRecord> records = dietRecordMapper.selectList(wrapper);
-        
+
         Map<String, Object> summary = new HashMap<>();
         summary.put("date", dateStr);
-        summary.put("records", records);
+        summary.put("records", java.util.Collections.emptyList());
         summary.put("totalCalories", 0);
         summary.put("totalProtein", 0);
         summary.put("totalCarbs", 0);
-        
+        if (memberId == null) return summary;
+
+        LambdaQueryWrapper<DietRecord> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(DietRecord::getMemberId, memberId)
+               .eq(DietRecord::getRecordDate, date);
+        List<DietRecord> records = dietRecordMapper.selectList(wrapper);
+        summary.put("records", records);
         return summary;
     }
 
-    public Map<String, Object> getWeeklyTrend(Long memberId, String startDateStr) {
+    public Map<String, Object> getWeeklyTrend(Long userId, Long memberId, String startDateStr) {
+        memberId = resolveMemberId(userId, memberId);
         LocalDate startDate = LocalDate.parse(startDateStr, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
         LocalDate endDate = startDate.plusDays(6);
-        
+
+        Map<String, Object> trend = new HashMap<>();
+        trend.put("start_date", startDateStr);
+        trend.put("end_date", endDate.toString());
+        trend.put("records", java.util.Collections.emptyList());
+        trend.put("days", 0);
+        if (memberId == null) return trend;
+
         LambdaQueryWrapper<DietRecord> wrapper = new LambdaQueryWrapper<>();
         wrapper.eq(DietRecord::getMemberId, memberId)
                .ge(DietRecord::getRecordDate, startDate)
                .le(DietRecord::getRecordDate, endDate);
         List<DietRecord> records = dietRecordMapper.selectList(wrapper);
-        
-        Map<String, Object> trend = new HashMap<>();
-        trend.put("start_date", startDateStr);
-        trend.put("end_date", endDate.toString());
         trend.put("records", records);
         trend.put("days", records.size());
-        
         return trend;
     }
+
+    private Long resolveMemberId(Long userId, Long memberId) {
+        if (memberId != null) return memberId;
+        if (userId == null) return null;
+        try {
+            FamilyMember self = familyMemberMapper.selectOne(
+                new LambdaQueryWrapper<FamilyMember>()
+                    .eq(FamilyMember::getUserId, userId)
+                    .last("LIMIT 1")
+            );
+            return self != null ? self.getId() : null;
+        } catch (Exception e) {
+            log.warn("根据userId反查family_members失败: userId={}, error={}", userId, e.getMessage());
+            return null;
+        }
+    }
 }

+ 22 - 0
cfc-backend/src/main/java/com/etotem/cfc/service/impl/SurveyServiceImpl.java

@@ -81,6 +81,7 @@ public class SurveyServiceImpl implements SurveyService {
 
     @Override
     public Object getSurveyStatus(Long userId, Long memberId) {
+        memberId = resolveMemberId(userId, memberId);
         List<SurveyTemplate> activeTemplates = getActiveTemplates();
         List<SurveyRecord> allRecords = surveyRecordMapper.selectList(null);
         Map<Long, List<SurveyRecord>> recordsByTemplate = new HashMap<>();
@@ -119,10 +120,14 @@ public class SurveyServiceImpl implements SurveyService {
 
     @Override
     public SurveyRecord submitSurvey(Long userId, Long memberId, Long templateId, String answersJson, Date periodStart, Date periodEnd) {
+        memberId = resolveMemberId(userId, memberId);
         SurveyTemplate template = surveyTemplateMapper.selectById(templateId);
         if (template == null) {
             throw new RuntimeException("调研模板不存在");
         }
+        if (memberId == null) {
+            throw new RuntimeException("无法确定成员ID,请先完善家庭成员信息");
+        }
         FamilyMember member = familyMemberMapper.selectById(memberId);
         SurveyRecord record = new SurveyRecord();
         record.setFamilyId(member != null ? member.getFamilyId() : null);
@@ -137,6 +142,7 @@ public class SurveyServiceImpl implements SurveyService {
 
     @Override
     public List<SurveyRecord> getSurveyHistory(Long userId, Long memberId) {
+        memberId = resolveMemberId(userId, memberId);
         List<SurveyRecord> all = surveyRecordMapper.selectList(null);
         List<SurveyRecord> result = new ArrayList<>();
         for (SurveyRecord r : all) {
@@ -147,6 +153,22 @@ public class SurveyServiceImpl implements SurveyService {
         return result;
     }
 
+    private Long resolveMemberId(Long userId, Long memberId) {
+        if (memberId != null) return memberId;
+        if (userId == null) return null;
+        try {
+            FamilyMember self = familyMemberMapper.selectOne(
+                new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<FamilyMember>()
+                    .eq(FamilyMember::getUserId, userId)
+                    .last("LIMIT 1")
+            );
+            return self != null ? self.getId() : null;
+        } catch (Exception e) {
+            log.warn("根据userId反查family_members失败: userId={}, error={}", userId, e.getMessage());
+            return null;
+        }
+    }
+
     @Override
     public String aiGenerateQuestions(String dimension, String topic) {
         if (langgraphBaseUrl == null || langgraphBaseUrl.isEmpty()) {