diff --git a/msh_crmeb_22/crmeb-service/src/main/java/com/zbkj/service/service/impl/tool/ToolCommunityServiceImpl.java b/msh_crmeb_22/crmeb-service/src/main/java/com/zbkj/service/service/impl/tool/ToolCommunityServiceImpl.java index 6183074..c0a2448 100644 --- a/msh_crmeb_22/crmeb-service/src/main/java/com/zbkj/service/service/impl/tool/ToolCommunityServiceImpl.java +++ b/msh_crmeb_22/crmeb-service/src/main/java/com/zbkj/service/service/impl/tool/ToolCommunityServiceImpl.java @@ -614,7 +614,9 @@ public class ToolCommunityServiceImpl implements ToolCommunityService { Map nutrition = toolNutritionFillService.fillFromText(text.toString()); if (nutrition.isEmpty()) throw new CrmebException("AI 未能估算出营养数据"); - post.setNutritionDataJson(JSON.toJSONString(nutrition)); + // 存库使用嵌套格式(value/unit),与 v2_community_posts.nutrition_data_json 约定一致 + Map nested = toolNutritionFillService.flatToNestedForDb(nutrition); + post.setNutritionDataJson(JSON.toJSONString(nested)); post.setUpdatedAt(new Date()); v2CommunityPostDao.updateById(post); return nutrition; diff --git a/msh_crmeb_22/crmeb-service/src/main/java/com/zbkj/service/service/impl/tool/ToolNutritionFillServiceImpl.java b/msh_crmeb_22/crmeb-service/src/main/java/com/zbkj/service/service/impl/tool/ToolNutritionFillServiceImpl.java index d4dd82d..8845523 100644 --- a/msh_crmeb_22/crmeb-service/src/main/java/com/zbkj/service/service/impl/tool/ToolNutritionFillServiceImpl.java +++ b/msh_crmeb_22/crmeb-service/src/main/java/com/zbkj/service/service/impl/tool/ToolNutritionFillServiceImpl.java @@ -97,4 +97,53 @@ public class ToolNutritionFillServiceImpl implements ToolNutritionFillService { } return null; } + + @Override + public Map flatToNestedForDb(Map flat) { + if (flat == null || flat.isEmpty()) return new HashMap<>(); + Map nested = new HashMap<>(); + putNested(nested, flat, "energyKcal", "calories", "kcal"); + putNested(nested, flat, "proteinG", "protein", "g"); + putNested(nested, flat, "fatG", "fat", "g"); + putNested(nested, flat, "carbohydratesG", "carbohydrates", "g"); + putNested(nested, flat, "sodiumG", "sodium", "g"); + putNested(nested, flat, "potassiumMg", "potassium", "mg"); + putNested(nested, flat, "phosphorusMg", "phosphorus", "mg"); + return nested; + } + + private void putNested(Map nested, Map flat, + String flatKey, String nestedKey, String unit) { + Object v = flat.get(flatKey); + if (v == null) return; + if (v instanceof Number) { + Map entry = new HashMap<>(); + entry.put("value", ((Number) v).doubleValue()); + entry.put("unit", unit); + nested.put(nestedKey, entry); + } + } + + @Override + @SuppressWarnings("unchecked") + public Map nestedToFlat(Map nested) { + if (nested == null || nested.isEmpty()) return new HashMap<>(); + Map flat = new HashMap<>(); + copyFlat(flat, nested, "calories", "energyKcal"); + copyFlat(flat, nested, "protein", "proteinG"); + copyFlat(flat, nested, "fat", "fatG"); + copyFlat(flat, nested, "carbohydrates", "carbohydratesG"); + copyFlat(flat, nested, "sodium", "sodiumG"); + copyFlat(flat, nested, "potassium", "potassiumMg"); + copyFlat(flat, nested, "phosphorus", "phosphorusMg"); + return flat; + } + + private void copyFlat(Map flat, Map nested, + String nestedKey, String flatKey) { + Object entry = nested.get(nestedKey); + if (!(entry instanceof Map)) return; + Object value = ((Map) entry).get("value"); + if (value instanceof Number) flat.put(flatKey, ((Number) value).doubleValue()); + } } diff --git a/msh_crmeb_22/crmeb-service/src/main/java/com/zbkj/service/service/tool/ToolNutritionFillService.java b/msh_crmeb_22/crmeb-service/src/main/java/com/zbkj/service/service/tool/ToolNutritionFillService.java index 7eabed5..7d78b1c 100644 --- a/msh_crmeb_22/crmeb-service/src/main/java/com/zbkj/service/service/tool/ToolNutritionFillService.java +++ b/msh_crmeb_22/crmeb-service/src/main/java/com/zbkj/service/service/tool/ToolNutritionFillService.java @@ -11,10 +11,26 @@ import java.util.Map; public interface ToolNutritionFillService { /** - * 根据一段饮食/菜品描述文本,调用 AI 估算营养数据并返回结构化结果 + * 根据一段饮食/菜品描述文本,调用 AI 估算营养数据并返回结构化结果(扁平格式,供 AI/接口使用) * * @param text 饮食描述(如「今天中午吃了一碗米饭、一份青椒肉丝、一碗紫菜蛋花汤」) * @return 包含 energyKcal, proteinG, potassiumMg, phosphorusMg 的 Map,估算不出时为 null */ Map fillFromText(String text); + + /** + * 将 AI 返回的扁平格式转为 v2_community_posts.nutrition_data_json 所需的嵌套格式(带 value/unit) + * + * @param flat 扁平格式,key 为 energyKcal, proteinG, potassiumMg, phosphorusMg 等 + * @return 嵌套格式,如 {"calories":{"value":1850,"unit":"kcal"},"protein":{"value":65,"unit":"g"},...} + */ + Map flatToNestedForDb(Map flat); + + /** + * 将数据库中的嵌套格式(value/unit)转为扁平格式,便于前端或 AI 使用 + * + * @param nested 嵌套格式,如 {"calories":{"value":1850,"unit":"kcal"},...} + * @return 扁平格式,如 {"energyKcal":1850,"proteinG":65,...} + */ + Map nestedToFlat(Map nested); }