Files
msh-system/docs/测试问题分析报告_2026-03-22.md

302 lines
10 KiB
Markdown
Raw Normal View History

# 测试问题分析报告
> **日期:** 2026-03-22
> **分析人:** Claude AI
> **项目:** 民生汇 - 慢性肾病营养管理小程序
---
## 一、食谱计算器 —— 用油量计算逻辑错误
### 问题描述
食谱计算器计算出的用油量偏多,不符合实际膳食指导标准。
### 问题定位
**文件:** `msh_crmeb_22/crmeb-service/src/main/java/com/zbkj/service/service/impl/tool/ToolCalculatorServiceImpl.java`
**位置:** `generateFoodPortions()` 方法,第 516 行
```java
// 当前代码(有误)
list.add(createFoodPortion(7, "油脂类10g", round(5.7 * energyRatio)));
```
### 根因分析
油脂类的份数计算使用了系数 `5.7`,与第 510 行谷薯类的系数完全相同:
```java
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`
```java
// 修复后
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 服务:
```java
// 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");
```
虽然项目中存在 `ToolCozeServiceImpl`Coze 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()` 方法返回的营养字段不完整:
```java
// 当前返回的字段
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.vue``parseNutritionTable()` 方法尝试解析 `calcium``purine` 等字段,但后端根本没有返回这些数据。
#### 3.2 图片显示错误
两个层面的图片问题:
**a) 前端硬编码了 Figma 临时 URL**
`food-detail.vue``nutrient-detail.vue` 中的默认图片使用了 Figma API 的临时资源 URL
```javascript
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()` 中增加 `calcium``iron``vitaminC``nutrientsJson``recommendedAmount` 等字段的返回
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` 中营养素卡片的点击事件:
```html
@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.vue``data()` 中硬编码了**"钠Sodium"**作为默认数据:
```javascript
data() {
return {
nutrientData: {
name: '钠',
english: 'Sodium (Na)',
icon: '🧂',
// ... 其他钠的数据
}
}
}
```
`loadNutrientData(name)``name` 为空或不匹配 `nutrientMap` 的任何 key 时,`nutrientData` 不会被更新,页面始终显示默认的"钠"内容。
**结果**:无论点击哪个营养素,要么不跳转,要么跳转后参数丢失,最终所有页面都显示默认的"钠"内容。
### 修复建议
**修复 1改用直接传参方式推荐**
```html
<!-- nutrition-knowledge.vue -->
<!-- 修改前 -->
@click="goToNutrientDetail" :data-nutrient-index="index"
<!-- 修改后 -->
@click="goToNutrientDetail(index)"
```
```javascript
// 方法改为接收 index 参数
goToNutrientDetail(index) {
const item = this.nutrientList[index];
if (!item) return;
uni.navigateTo({
url: `/pages/tool/nutrient-detail?name=${encodeURIComponent(item.name)}`
});
}
```
**修复 2详情页增加参数解码和容错**
```javascript
// 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` | 问题四:事件传参兼容性 |