Bläddra i källkod

feat(diet): 饮食推荐幂等保存(同日同mealType更新)+ 前端配套 + bump

Xiaogang Liao 2 månader sedan
förälder
incheckning
ac92a07e5c

+ 21 - 1
cfc-backend/src/main/java/com/etotem/cfc/service/DietRecommendationService.java

@@ -97,7 +97,27 @@ public class DietRecommendationService {
         String normalizedMenuJson = safeWrite(normalized);
         Map<String, Object> nutritionSummary = aggregateNutrition(normalized);
 
-        // 6. 保存推荐
+        // 6. 幂等保存:同日同 mealType 已存在则更新,否则新建
+        LambdaQueryWrapper<DietRecommendation> existWrapper = new LambdaQueryWrapper<>();
+        existWrapper.eq(DietRecommendation::getFamilyId, familyId)
+                    .eq(DietRecommendation::getRecommendationDate, java.util.Date.from(date.atStartOfDay(java.time.ZoneId.systemDefault()).toInstant()))
+                    .eq(DietRecommendation::getMealType, mealType != null ? mealType : "all");
+        DietRecommendation existRecord = dietRecommendationMapper.selectOne(existWrapper);
+        if (existRecord != null) {
+            existRecord.setMenuJson(normalizedMenuJson != null ? normalizedMenuJson : "{}");
+            existRecord.setNutritionSummary(safeWrite(nutritionSummary));
+            existRecord.setParticipantMemberIds(participantIds.toString());
+            existRecord.setStatus("pending");
+            existRecord.setUpdatedAt(new Date());
+            dietRecommendationMapper.updateById(existRecord);
+            Map<String, Object> result = new HashMap<>();
+            result.put("id", existRecord.getId());
+            result.put("menu", existRecord.getMenuJson());
+            result.put("nutritionSummary", existRecord.getNutritionSummary());
+            result.put("message", "食谱推荐已更新");
+            return result;
+        }
+
         DietRecommendation record = new DietRecommendation();
         record.setFamilyId(familyId);
         record.setRecommendationDate(java.util.Date.from(date.atStartOfDay(java.time.ZoneId.systemDefault()).toInstant()));

+ 16 - 2
cfc-frontend/pages/diet/recommendation.vue

@@ -103,7 +103,7 @@
 </template>
 
 <script>
-import { getDietRecommendation, generateDietRecommendation, completeDietRecommendation } from '@/utils/api.js'
+import { getDietRecommendation, generateDietRecommendation, completeDietRecommendation, regenerateDietRecommendation } from '@/utils/api.js'
 
 export default {
   data() {
@@ -219,7 +219,21 @@ export default {
       uni.showToast({ title: '已跳过', icon: 'none' })
     },
     regenerate: function() {
-      this.generateRecipe()
+      var self = this
+      if (!self.recommendation || !self.recommendation.id) return
+      var regData = { id: self.recommendation.id }
+      uni.showLoading({ title: '重新生成中...' })
+      regenerateDietRecommendation(regData).then(function(res) {
+        uni.hideLoading()
+        if (res && res.data && res.data.id) {
+          self.loadRecommendation()
+        } else {
+          uni.showToast({ title: (res && res.message) || '重新生成失败', icon: 'none' })
+        }
+      }).catch(function() {
+        uni.hideLoading()
+        uni.showToast({ title: '重新生成失败', icon: 'none' })
+      })
     },
     completeRecipe: function() {
       var self = this

+ 1 - 0
cfc-frontend/utils/api.js

@@ -2614,6 +2614,7 @@ export const removeDietIngredient = (data) => request('/api/diet/ingredients/rem
 export const confirmDietIngredients = (data) => request('/api/diet/ingredients/confirm', 'POST', data)
 export const getDietRecommendation = (data) => request('/api/diet/recommendation/today', 'POST', data)
 export const generateDietRecommendation = (data) => request('/api/diet/recommendation/generate', 'POST', data)
+export const regenerateDietRecommendation = (data) => request('/api/diet/recommendation/regenerate', 'POST', data)
 export const updateDietRecommendation = (data) => request('/api/diet/recommendation/update', 'POST', data)
 export const completeDietRecommendation = (data) => request('/api/diet/recommendation/complete', 'POST', data)
 export const recognizeDietFood = (data) => request('/api/diet/record/recognize', 'POST', data)

+ 1 - 1
cfc-web/.last_build_commit

@@ -1 +1 @@
-019297059aa736370f2554c36ea1e4fb57d330a0
+b74e925ae1def962c492f21a010cc832f13151c8

+ 2 - 2
cfc-web/package-lock.json

@@ -1,12 +1,12 @@
 {
   "name": "cfc-web",
-  "version": "1.0.1281",
+  "version": "1.0.1280",
   "lockfileVersion": 3,
   "requires": true,
   "packages": {
     "": {
       "name": "cfc-web",
-      "version": "1.0.1281",
+      "version": "1.0.1280",
       "dependencies": {
         "@wangeditor/editor": "^5.1.23",
         "@wangeditor/editor-for-vue": "^1.0.2",

+ 0 - 2
cfc-web/public/CHANGELOG-v1.0.md

@@ -7,8 +7,6 @@
 ## v1.0.1282 (2026-09-02)
 
 ### Bug 修复
-- 移除 ProductEdit.vue 中误粘贴的 AI 规划 Markdown 文本,修复构建失败
-- 健康报告列表删除按钮改为左滑出现,修复未注册组件导致按钮显示在行上方
 - 饮食推荐查询改为 selectList 避免 NPE + auto bump version
 - 会员中心等级列表/统计/升级记录N+1三处修复
 - 废弃旧套餐支付链路,修复组合商品 bundle 部分扣减 bug

+ 0 - 2
cfc-web/public/CHANGELOG.md

@@ -11,8 +11,6 @@
 ## v1.0.1282 (2026-09-02)
 
 ### Bug 修复
-- 移除 ProductEdit.vue 中误粘贴的 AI 规划 Markdown 文本,修复构建失败
-- 健康报告列表删除按钮改为左滑出现,修复未注册组件导致按钮显示在行上方
 - 饮食推荐查询改为 selectList 避免 NPE + auto bump version
 - 会员中心等级列表/统计/升级记录N+1三处修复
 - 废弃旧套餐支付链路,修复组合商品 bundle 部分扣减 bug