Files
msh-system/docs/测试问题分析报告_2026-03-22.md
Claude 584ff3b666 docs: 新增测试问题分析报告(食谱计算器/AI营养师/食物百科/健康知识)
针对测试反馈的四个问题进行代码级分析,包含根因定位、涉及文件和修复建议。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 10:18:18 +08:00

10 KiB
Raw Blame History

测试问题分析报告

日期: 2026-03-22 分析人: Claude AI 项目: 民生汇 - 慢性肾病营养管理小程序


一、食谱计算器 —— 用油量计算逻辑错误

问题描述

食谱计算器计算出的用油量偏多,不符合实际膳食指导标准。

问题定位

文件: msh_crmeb_22/crmeb-service/src/main/java/com/zbkj/service/service/impl/tool/ToolCalculatorServiceImpl.java 位置: generateFoodPortions() 方法,第 516 行

// 当前代码(有误)
list.add(createFoodPortion(7, "油脂类10g", round(5.7 * energyRatio)));

根因分析

油脂类的份数计算使用了系数 5.7,与第 510 行谷薯类的系数完全相同:

list.add(createFoodPortion(1, "谷薯50g", round(5.7 * energyRatio)));  // 谷薯类
list.add(createFoodPortion(7, "油脂类10g", round(5.7 * energyRatio))); // 油脂类(错误地使用了同一系数)

其中 energyRatio = energy / 2000.0。以标准体重 60kg 患者为例:

  • 每日能量目标 = 60 × 35 = 2100 kcal
  • energyRatio = 2100 / 2000 = 1.05
  • 油脂份数 = 5.7 × 1.05 ≈ 6.0 份
  • 每份 10g即每天需要 60g 油

根据《中国居民膳食指南》和《慢性肾脏病患者膳食指导2017CKD 患者每日食用油推荐量为 25-30g,当前计算结果严重偏高。

修复建议

将油脂类的计算系数从 5.7 调整为 2.5

// 修复后
list.add(createFoodPortion(7, "油脂类10g", round(2.5 * energyRatio)));

修复后以同一患者为例2.5 × 1.05 ≈ 2.6 份,即每日约 26g 油,符合膳食指南要求。

优先级:高


二、AI 营养师 —— 反应慢、内容凌乱、体验差

问题描述

AI 营养师功能反应比较慢,提供的内容比较凌乱,逻辑性差,整体体验感不好。

问题定位

后端文件: msh_crmeb_22/crmeb-service/src/main/java/com/zbkj/service/service/impl/tool/ToolAiNutritionistServiceImpl.java 前端文件: msh_single_uniapp/pages/tool/ai-nutritionist.vue

根因分析

1. AI 服务未真正接入(核心原因)

后端 sendMessage() 方法(第 89-97 行)使用的是 Mock 模拟回复,并未真正接入 AI 服务:

// Mock AI response
// In real system, this would call AI service
// Here we just set a mock response for now
message.setAiResponse("这是一个模拟的AI回复。");
message.setAiResponseStatus("success");

虽然项目中存在 ToolCozeServiceImplCoze AI 服务)的实现,但 sendMessage() 方法中并未调用它。

2. 前端轮询机制导致延迟感

前端通过定时轮询 getResponse() 接口等待 AI 回复:

  • 用户发送消息 → 后端同步写入 mock 数据 → 前端轮询获取结果
  • 轮询间隔本身带来延迟,加上网络开销,用户体感"反应慢"

3. 缺乏流式响应

当前架构没有 SSEServer-Sent Events或 WebSocket 支持,无法实现"逐字输出"的流式效果,用户需等待完整回复后才能看到内容。

修复建议

  1. 正式接入 Coze AI 服务:在 sendMessage() 中调用 ToolCozeServiceImpl,真正发起 AI 对话请求
  2. 优化 Prompt 模板设计结构化的系统提示词System Prompt要求 AI 回复遵循固定格式(如:摘要 → 营养分析 → 建议 → 注意事项),提升内容逻辑性
  3. 引入 SSE 流式返回:后端通过 SSE 推送逐步响应,前端实时渲染,提升交互体验
  4. 增加加载状态动效:在等待回复期间展示更好的"正在思考"动画

优先级:高


三、食物百科 —— 成分表不全、图片错误、缺少重量标注

问题描述

食物百科中食物成分表内容不全,图片显示有错误,而且没有标注具体是多少重量的食物所提供的营养成分。

问题定位

后端文件: msh_crmeb_22/crmeb-service/src/main/java/com/zbkj/service/service/impl/tool/ToolFoodServiceImpl.java 前端文件: msh_single_uniapp/pages/tool/food-detail.vue 数据模型: msh_crmeb_22/crmeb-common/src/main/java/com/zbkj/common/model/tool/V2Food.java

根因分析

3.1 食物成分表内容不全

后端 getDetail() 方法返回的营养字段不完整:

// 当前返回的字段
map.put("energy", food.getEnergy());
map.put("protein", food.getProtein());
map.put("fat", food.getFat());
map.put("carbohydrate", food.getCarbohydrate());
map.put("potassium", food.getPotassium());
map.put("phosphorus", food.getPhosphorus());
map.put("sodium", food.getSodium());

V2Food 模型中定义了但未返回的字段包括:

  • calcium(钙)
  • iron(铁)
  • vitaminC(维生素 C
  • nutrientsJson(扩展营养素 JSON
  • recommendedAmount(推荐摄入量)

前端 food-detail.vueparseNutritionTable() 方法尝试解析 calciumpurine 等字段,但后端根本没有返回这些数据。

3.2 图片显示错误

两个层面的图片问题:

a) 前端硬编码了 Figma 临时 URL

food-detail.vuenutrient-detail.vue 中的默认图片使用了 Figma API 的临时资源 URL

iconWhyImportant: 'https://www.figma.com/api/mcp/asset/51e00c9b-5719-4391-9dff-68b70d24aece'

这些 URL 是开发阶段从 Figma 设计稿导出的临时链接,过期后图片无法加载。

b) 后端 AI 生图服务不稳定

DishImageService 通过 AI 生成食物图片并上传 OSS。当 AI API 调用失败时,部分食物的 image 字段为空或仍为旧的无效 URL导致前端图片显示异常。

3.3 缺少重量标注

后端接口返回数据中 没有 servingSize(份量基准)字段。前端虽然显示了"每100g"标签,但这是硬编码的静态文本,并非根据实际数据动态展示。如果数据库中部分食物的营养数据不是基于 100g 标准录入的,就会产生误导。

修复建议

  1. 补充后端返回字段:在 getDetail() 中增加 calciumironvitaminCnutrientsJsonrecommendedAmount 等字段的返回
  2. 替换 Figma 临时 URL:将所有 Figma API 链接替换为上传至 OSS 的稳定图片资源
  3. 增加图片容错处理:前端为食物图片增加 @error 事件处理,在图片加载失败时显示占位图
  4. 增加重量标注字段:数据库添加 serving_size 字段(如"每100g"、"每份(50g)"),后端返回后前端动态显示

优先级:中高


四、健康知识营养素板块 —— 所有选项显示同一内容

问题描述

健康知识中营养素板块,所有的营养素选项(蛋白质、钾、磷、钠、钙、水分)点击后显示的都是同一个内容。

问题定位

列表页: msh_single_uniapp/pages/tool/nutrition-knowledge.vue 第 39 行 详情页: msh_single_uniapp/pages/tool/nutrient-detail.vue 第 114 行、第 137-277 行

根因分析

这是一个前端事件传参 + 数据默认值联合导致的 Bug。

Bug 链条

第一环:列表页事件传参问题

nutrition-knowledge.vue 中营养素卡片的点击事件:

@click="goToNutrientDetail" :data-nutrient-index="index"

goToNutrientDetail 方法通过 event.currentTarget.dataset.nutrientIndex 获取索引值。但在微信小程序环境中,dataset 的属性名会被自动转换为全小写(nutrientindex 而非 nutrientIndex),导致取值为 undefined

当 index 为 undefined 时,this.nutrientList[undefined] 返回 undefined,方法执行 if (!item) return 直接退出,不发起页面跳转

即使跳转成功,中文参数 name 经过 encodeURIComponent 编码后,在某些小程序版本中解码可能不正确,导致 nutrientMap[name] 匹配失败。

第二环:详情页默认数据兜底

nutrient-detail.vuedata() 中硬编码了**"钠Sodium"**作为默认数据:

data() {
    return {
        nutrientData: {
            name: '钠',
            english: 'Sodium (Na)',
            icon: '🧂',
            // ... 其他钠的数据
        }
    }
}

loadNutrientData(name)name 为空或不匹配 nutrientMap 的任何 key 时,nutrientData 不会被更新,页面始终显示默认的"钠"内容。

结果:无论点击哪个营养素,要么不跳转,要么跳转后参数丢失,最终所有页面都显示默认的"钠"内容。

修复建议

修复 1改用直接传参方式推荐

<!-- nutrition-knowledge.vue -->
<!-- 修改前 -->
@click="goToNutrientDetail" :data-nutrient-index="index"

<!-- 修改后 -->
@click="goToNutrientDetail(index)"
// 方法改为接收 index 参数
goToNutrientDetail(index) {
    const item = this.nutrientList[index];
    if (!item) return;
    uni.navigateTo({
        url: `/pages/tool/nutrient-detail?name=${encodeURIComponent(item.name)}`
    });
}

修复 2详情页增加参数解码和容错

// nutrient-detail.vue
onLoad(options) {
    if (options.name) {
        const name = decodeURIComponent(options.name);
        this.loadNutrientData(name);
    }
}

修复 3默认数据改为空状态

data() 中的默认 nutrientData 改为空对象,并在页面增加空状态提示,避免误导用户。

优先级:高


问题优先级汇总

序号 问题 类型 优先级 影响范围
食谱计算器用油量偏多 算法缺陷 所有使用计算器的用户
AI 营养师体验差 功能缺失 所有使用 AI 营养师的用户
食物百科成分表/图片/重量 数据不完整 中高 所有查看食物详情的用户
营养素板块显示重复 前端 Bug 所有查看营养素详情的用户

涉及文件清单

后端Java

文件 问题
ToolCalculatorServiceImpl.java 问题一:油脂系数错误
ToolAiNutritionistServiceImpl.java 问题二AI 服务未接入
ToolFoodServiceImpl.java 问题三:返回字段不完整
V2Food.java 问题三:缺少 serving_size 字段

前端Vue

文件 问题
pages/tool/food-detail.vue 问题三:图片 URL、重量标注
pages/tool/nutrient-detail.vue 问题三/四Figma URL、默认数据
pages/tool/nutrition-knowledge.vue 问题四:事件传参兼容性