Przeglądaj źródła

feat(diet): 前端生成食谱/换一批取值修复 + 添加食材弹窗搜索

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
E2E Test Bot 2 miesięcy temu
rodzic
commit
84c277658b

+ 14 - 4
cfc-frontend/pages/diet/index.vue

@@ -158,7 +158,7 @@
 </template>
 
 <script>
-import { getDietIngredients, refreshDietIngredients, addDietIngredient, removeDietIngredient, generateDietRecommendation, getMealConfig } from '@/utils/api.js'
+import { getDietIngredients, refreshDietIngredients, addDietIngredient, removeDietIngredient, generateDietRecommendation, getMealConfig, searchDietFoods } from '@/utils/api.js'
 import { parseDate } from '@/utils/format.js'
 
 export default {
@@ -223,6 +223,7 @@ export default {
         self.ingredientsLoading = false
         if (res && res.code === 200 && res.data && res.data.ingredients) {
           self.ingredients = res.data.ingredients
+          self.selectedIngredients = self.ingredients
           if (self.ingredients.length === 0 && !self.uploadPromptShown) {
             self.uploadPromptShown = true
             uni.showModal({
@@ -249,6 +250,7 @@ export default {
         self.ingredientsLoading = false
         if (res && res.code === 200 && res.data && res.data.ingredients) {
           self.ingredients = res.data.ingredients
+          self.selectedIngredients = self.ingredients
         }
       }).catch(function() {
         self.ingredientsLoading = false
@@ -276,11 +278,13 @@ export default {
         meal_type: 'all',
         selected_foods: JSON.stringify(foodIds)
       }).then(function(res) {
-        if (res && res.id) {
+        if (res && res.data && res.data.id) {
           uni.showToast({ title: '食谱生成成功', icon: 'success' })
           setTimeout(function() {
             self.navTo('/pages/diet/recommendation')
           }, 1000)
+        } else {
+          uni.showToast({ title: (res && res.message) || '生成失败', icon: 'none' })
         }
       })
     },
@@ -330,11 +334,17 @@ export default {
       this.searchResults = []
     },
     searchFood: function() {
-      if (!this.searchQuery) {
+      var self = this
+      var kw = (this.searchQuery || '').trim()
+      if (!kw) {
         this.searchResults = []
         return
       }
-      this.searchResults = []
+      searchDietFoods(kw).then(function(res) {
+        if (res && res.code === 200 && res.data && res.data.foods) {
+          self.searchResults = res.data.foods
+        }
+      })
     },
     addFood: function(food) {
       var self = this

+ 30 - 10
cfc-frontend/pages/diet/recommendation.vue

@@ -138,33 +138,51 @@ export default {
       var self = this
       var today = self.formatDate(new Date())
       getDietRecommendation({ date: today }).then(function(res) {
-        if (res && res.id) {
-          self.recommendation = res
-          self.parseMenu(res.menu)
-          self.summary = res.nutritionSummary || {}
+        var d = res && res.data
+        if (d && d.id) {
+          self.recommendation = d
+          self.parseMenu(d.menu)
+          var ns = d.nutritionSummary
+          self.summary = ns ? (typeof ns === 'string' ? JSON.parse(ns) : ns) : {}
+        } else {
+          self.recommendation = null
+          self.meals = []
+          self.summary = {}
         }
       })
     },
     parseMenu: function(menuJson) {
       try {
-        var menu = JSON.parse(menuJson || '{}')
+        var menu = (typeof menuJson === 'string') ? JSON.parse(menuJson || '{}') : (menuJson || {})
         this.meals = []
-        
+
         var mealMap = {
           'breakfast': { name: '早餐', icon: '🌅' },
           'lunch': { name: '午餐', icon: '☀️' },
           'dinner': { name: '晚餐', icon: '🌙' }
         }
-        
+
         if (menu.meals) {
+          var self = this
           menu.meals.forEach(function(meal) {
-            var config = mealMap[meal.type] || { name: meal.type, icon: '🍽️' }
+            var config = mealMap[meal.type] || { name: meal.name || meal.type, icon: '🍽️' }
+            var dishes = (meal.dishes || []).map(function(dish) {
+              var ing = (dish.ingredients || []).map(function(item) {
+                return { name: item.name, amount: item.amount || item.grams || 0 }
+              })
+              return {
+                name: dish.name,
+                calories: dish.calories || (dish.nutrition && dish.nutrition.calories) || 0,
+                ingredients: ing,
+                method: dish.method || dish.cooking_method || ''
+              }
+            })
             self.meals.push({
               name: config.name,
               icon: config.icon,
               type: meal.type,
               participants: meal.participants || 1,
-              dishes: meal.dishes || []
+              dishes: dishes
             })
           })
         }
@@ -180,9 +198,11 @@ export default {
         meal_type: 'all'
       }).then(function(res) {
         self.loading = false
-        if (res && res.id) {
+        if (res && res.data && res.data.id) {
           uni.showToast({ title: '食谱生成成功', icon: 'success' })
           self.loadRecommendation()
+        } else {
+          uni.showToast({ title: (res && res.message) || '生成失败', icon: 'none' })
         }
       }).catch(function() {
         self.loading = false

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

@@ -2604,6 +2604,7 @@ export const getDietPreferences = (data) => request('/api/diet/preferences/curre
 export const saveDietPreferences = (data) => request('/api/diet/preferences/save', 'POST', data)
 export const getDietIngredients = () => request('/api/diet/ingredients/suggest', 'POST', {})
 export const refreshDietIngredients = () => request('/api/diet/ingredients/recommend', 'POST', {})
+export const searchDietFoods = (keyword) => request('/api/diet/ingredients/search', 'POST', { keyword })
 export const addDietIngredient = (data) => request('/api/diet/ingredients/add', 'POST', data)
 export const removeDietIngredient = (data) => request('/api/diet/ingredients/remove', 'POST', data)
 export const confirmDietIngredients = (data) => request('/api/diet/ingredients/confirm', 'POST', data)