fix: 修复6项测试问题并补全配套资源

- 修复油脂类食物推荐量系数 (5.7→2.5) [ToolCalculatorServiceImpl]
- AI营养师接入真实Coze API,替换Mock回复 [ToolAiNutritionistServiceImpl]
- 食物百科详情新增钙/铁/维C/嘌呤/重量基准字段返回 [ToolFoodServiceImpl]
- V2Food模型新增purine、servingSize字段 [V2Food.java]
- 食物百科详情页动态重量标注+新增4项营养展示+替换Figma URL [food-detail.vue]
- 修复营养素列表dataset传参Bug(WeChat camelCase) [nutrition-knowledge.vue]
- 营养素详情页接入后端API+兜底本地数据+替换Figma URL [nutrient-detail.vue]
- 新增数据库迁移脚本及参考初始化数据 [docs/sql/]
- 新增前端占位图标5个 [static/images/]
- 新增开发任务完成报告 [docs/]

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Developer
2026-03-25 14:18:00 +08:00
parent a5de6fb46d
commit ba08abd374
16 changed files with 243 additions and 54 deletions

View File

@@ -68,6 +68,16 @@ public class V2Food implements Serializable {
@ApiModelProperty(value = "维生素C(mg)")
private BigDecimal vitaminC;
/** 嘌呤含量(mg) */
@ApiModelProperty(value = "嘌呤含量(mg)")
@com.baomidou.mybatisplus.annotation.TableField("purine")
private BigDecimal purine;
/** 营养成分重量基准 */
@ApiModelProperty(value = "营养成分重量基准")
@com.baomidou.mybatisplus.annotation.TableField("serving_size")
private String servingSize;
@ApiModelProperty(value = "其他营养成分JSON格式")
private String nutrientsJson;

View File

@@ -12,6 +12,9 @@ import com.zbkj.common.token.FrontTokenComponent;
import com.zbkj.service.dao.tool.V2AiConversationDao;
import com.zbkj.service.dao.tool.V2AiMessageDao;
import com.zbkj.service.service.tool.ToolAiNutritionistService;
import com.zbkj.service.service.tool.ToolCozeService;
import com.zbkj.common.request.coze.CozeChatRequest;
import com.zbkj.common.response.CozeBaseResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -39,6 +42,9 @@ public class ToolAiNutritionistServiceImpl implements ToolAiNutritionistService
@Autowired
private FrontTokenComponent frontTokenComponent;
@Autowired
private ToolCozeService toolCozeService;
/**
* 发送消息给AI营养师
* @param data 消息数据
@@ -85,15 +91,45 @@ public class ToolAiNutritionistServiceImpl implements ToolAiNutritionistService
message.setAiResponseStatus("pending");
v2AiMessageDao.insert(message);
// 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");
// 调用 Coze API 获取 AI 回复
try {
String botId = "7591133240535449654";
String userMessage = (String) data.get("content");
CozeChatRequest cozeRequest = new CozeChatRequest();
cozeRequest.setBotId(botId);
cozeRequest.setUserId(String.valueOf(userId));
cozeRequest.setStream(false);
// 构建消息
CozeChatRequest.ChatMessage chatMessage = new CozeChatRequest.ChatMessage();
chatMessage.setRole("user");
chatMessage.setContent(userMessage);
chatMessage.setContentType("text");
cozeRequest.setAdditionalMessages(java.util.Collections.singletonList(
new java.util.HashMap<String, Object>() {{
put("role", "user");
put("content", userMessage);
put("content_type", "text");
}}
));
CozeBaseResponse<Object> cozeResponse = toolCozeService.chat(cozeRequest);
if (cozeResponse != null && cozeResponse.getData() != null) {
message.setAiResponse(String.valueOf(cozeResponse.getData()));
message.setAiResponseStatus("success");
} else {
message.setAiResponse("AI服务暂时无法响应请稍后再试。");
message.setAiResponseStatus("failed");
}
} catch (Exception e) {
log.error("Coze API调用失败, userId={}, conversationId={}", userId, conversationId, e);
message.setAiResponse("AI服务调用失败请稍后再试。");
message.setAiResponseStatus("failed");
}
message.setAiResponseTime(new Date());
// message.setSender("ai"); // Keep sender as user, response is in aiResponse field
v2AiMessageDao.updateById(message);
// Update conversation last message time

View File

@@ -513,7 +513,7 @@ public class ToolCalculatorServiceImpl extends ServiceImpl<V2CalculatorResultDao
list.add(createFoodPortion(4, "瓜果蔬菜200g", "2"));
list.add(createFoodPortion(5, "奶类230g", "1"));
list.add(createFoodPortion(6, "肉蛋类50/60g", round(protein.doubleValue() / 8.0))); // 约 8g 蛋白/份
list.add(createFoodPortion(7, "油脂类10g", round(5.7 * energyRatio)));
list.add(createFoodPortion(7, "油脂类10g", round(2.5 * energyRatio)));
return list;
}

View File

@@ -119,6 +119,11 @@ public class ToolFoodServiceImpl implements ToolFoodService {
map.put("cautionLevel", food.getCautionLevel());
map.put("cautionDesc", food.getCautionDesc());
map.put("cookingTips", food.getCookingTips());
map.put("calcium", food.getCalcium());
map.put("iron", food.getIron());
map.put("vitaminC", food.getVitaminC());
map.put("purine", food.getPurine());
map.put("servingSize", food.getServingSize());
return map;
}