Explorar el Código

fix(health): 修复报告列表不返回数据

问题:/api/health/report/list 不传参数时返回空/报错,无法获取家庭报告。

修复三层:
1. JwtInterceptor: user.family_id 为空时从 family_members 表反查用户所属家庭
2. HealthReportService.getFamilyReports: 优先通过家庭所有成员(subject_id/user_id)
   反查报告,兼容报告表 family_id 未填充的历史数据,再补充按 family_id 匹配并去重
3. HealthReportController.listReports: 无家庭信息时返回空列表而非报错
Xiaogang Liao hace 3 semanas
padre
commit
76cbcb1440

+ 11 - 0
cfc-backend/src/main/java/com/etotem/cfc/config/JwtInterceptor.java

@@ -140,6 +140,17 @@ public class JwtInterceptor implements HandlerInterceptor {
             try {
                 User user = userMapper.selectById(userId);
                 Long userFamilyId = (user != null) ? user.getFamilyId() : null;
+                // 兜底:user.family_id 为空时,从 family_members 表反查用户所属家庭
+                if (userFamilyId == null) {
+                    FamilyMember fm = familyMemberMapper.selectOne(
+                        new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<FamilyMember>()
+                            .eq(FamilyMember::getUserId, userId)
+                            .last("LIMIT 1")
+                    );
+                    if (fm != null) {
+                        userFamilyId = fm.getFamilyId();
+                    }
+                }
                 request.setAttribute("familyId", userFamilyId);
             } catch (Exception e) {
                 log.warn("查询用户familyId失败: userId={}, error={}", userId, e.getMessage());

+ 2 - 1
cfc-backend/src/main/java/com/etotem/cfc/controller/HealthReportController.java

@@ -287,7 +287,8 @@ public class HealthReportController {
             // 未指定 memberId 时,返回当前家庭的全部报告
             reports = healthReportService.getFamilyReports(familyId);
         } else {
-            return Result.error("无法获取家庭信息,请先创建或加入家庭");
+            // 无家庭信息时返回空列表,避免前端报错
+            return Result.success(new ArrayList<>());
         }
         if (size > 0) {
             return Result.success(limitLatest(reports, size));

+ 53 - 3
cfc-backend/src/main/java/com/etotem/cfc/service/HealthReportService.java

@@ -196,14 +196,64 @@ public class HealthReportService {
 
     /**
      * 获取全家所有健康报告(用于方案页选择已有报告)
+     * 优先通过家庭所有成员(subject_id/user_id)反查报告,兼容报告表 family_id 未填充的历史数据;
+     * 同时补充按报告表 family_id 匹配的报告,合并去重。
      */
     public List<HealthReport> getFamilyReports(Long familyId) {
-        return healthReportMapper.selectList(
+        if (familyId == null) {
+            return Collections.emptyList();
+        }
+        // 1. 查家庭所有成员 id(family_members.id + user_id)
+        Set<Long> memberIds = new HashSet<>();
+        try {
+            List<FamilyMember> members = familyMemberMapper.selectList(
+                    new LambdaQueryWrapper<FamilyMember>().eq(FamilyMember::getFamilyId, familyId));
+            for (FamilyMember m : members) {
+                memberIds.add(m.getId());
+                if (m.getUserId() != null) {
+                    memberIds.add(m.getUserId());
+                }
+            }
+        } catch (Exception e) {
+            log.warn("查询家庭{}成员失败: {}", familyId, e.getMessage());
+        }
+
+        // 2. 按成员反查报告(subject_id/user_id 匹配)
+        List<HealthReport> reports = new ArrayList<>();
+        if (!memberIds.isEmpty()) {
+            reports = healthReportMapper.selectList(
+                    new LambdaQueryWrapper<HealthReport>()
+                            .and(w -> w.in(HealthReport::getSubjectId, memberIds)
+                                    .or(w2 -> w2.isNull(HealthReport::getSubjectId)
+                                            .in(HealthReport::getUserId, memberIds)))
+                            .eq(HealthReport::getStatus, "active")
+                            .orderByDesc(HealthReport::getReportDate));
+        }
+
+        // 3. 补充按报告表 family_id 匹配的报告(去重)
+        List<HealthReport> byFamily = healthReportMapper.selectList(
                 new LambdaQueryWrapper<HealthReport>()
                         .eq(HealthReport::getFamilyId, familyId)
                         .eq(HealthReport::getStatus, "active")
-                        .orderByDesc(HealthReport::getReportDate)
-        );
+                        .orderByDesc(HealthReport::getReportDate));
+        Set<Long> seen = new HashSet<>();
+        for (HealthReport r : reports) {
+            seen.add(r.getId());
+        }
+        for (HealthReport r : byFamily) {
+            if (seen.add(r.getId())) {
+                reports.add(r);
+            }
+        }
+        // 按报告日期倒序
+        reports.sort((a, b) -> {
+            java.util.Date da = a.getReportDate();
+            java.util.Date db = b.getReportDate();
+            if (da == null) return 1;
+            if (db == null) return -1;
+            return db.compareTo(da);
+        });
+        return reports;
     }
 
     /**