Просмотр исходного кода

解决了 vue-tsc 版本兼容性、ts 类型错误和未使用变量问题

liuziting 6 месяцев назад
Родитель
Сommit
4238b18615

+ 4 - 4
package-lock.json

@@ -16,7 +16,7 @@
                 "vue-router": "^4.2.0"
             },
             "devDependencies": {
-                "@types/node": "^20.0.0",
+                "@types/node": "^20.19.11",
                 "@vitejs/plugin-vue": "^5.0.0",
                 "autoprefixer": "^10.4.0",
                 "postcss": "^8.4.0",
@@ -869,9 +869,9 @@
             "license": "MIT"
         },
         "node_modules/@types/node": {
-            "version": "20.19.10",
-            "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.10.tgz",
-            "integrity": "sha512-iAFpG6DokED3roLSP0K+ybeDdIX6Bc0Vd3mLW5uDqThPWtNos3E+EqOM11mPQHKzfWHqEBuLjIlsBQQ8CsISmQ==",
+            "version": "20.19.11",
+            "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.11.tgz",
+            "integrity": "sha512-uug3FEEGv0r+jrecvUUpbY8lLisvIjg6AAic6a2bSP5OEOLeJsDSnvhCDov7ipFFMXS3orMpzlmi0ZcuGkBbow==",
             "dev": true,
             "license": "MIT",
             "dependencies": {

+ 1 - 1
package.json

@@ -19,7 +19,7 @@
         "vue-router": "^4.2.0"
     },
     "devDependencies": {
-        "@types/node": "^20.0.0",
+        "@types/node": "^20.19.11",
         "@vitejs/plugin-vue": "^5.0.0",
         "autoprefixer": "^10.4.0",
         "postcss": "^8.4.0",

+ 42 - 65
src/components/FortuneCard.vue

@@ -14,25 +14,19 @@
                             <span>⏱️</span>
                             <span>{{ fortune.cookingTime }}分钟</span>
                         </span>
-                        <span :class="[
-                            'px-2 py-1 rounded-full text-xs font-medium',
-                            getDifficultyStyle(fortune.difficulty)
-                        ]">
+                        <span :class="['px-2 py-1 rounded-full text-xs font-medium', getDifficultyStyle(fortune.difficulty)]">
                             {{ getDifficultyName(fortune.difficulty) }}
                         </span>
                     </div>
                 </div>
             </div>
-            
+
             <!-- 幸运指数 -->
             <div class="mt-4 flex items-center gap-4">
                 <div class="text-center">
                     <div class="text-xs opacity-80 mb-1">幸运指数</div>
                     <div class="flex items-center gap-1">
-                        <span v-for="i in 10" :key="i" :class="[
-                            'text-lg hidden sm:inline',
-                            i <= fortune.luckyIndex ? 'text-yellow-300' : 'text-white/30'
-                        ]">⭐</span>
+                        <span v-for="i in 10" :key="i" :class="['text-lg hidden sm:inline', i <= fortune.luckyIndex ? 'text-yellow-300' : 'text-white/30']">⭐</span>
                         <span class="text-xl font-bold text-yellow-300">{{ fortune.luckyIndex }}/10</span>
                     </div>
                 </div>
@@ -65,11 +59,7 @@
                     <span>神秘食材</span>
                 </h3>
                 <div class="grid md:grid-cols-2 gap-2">
-                    <div
-                        v-for="(ingredient, index) in fortune.ingredients"
-                        :key="index"
-                        class="flex items-center gap-2 p-2 bg-gray-50 rounded-lg"
-                    >
+                    <div v-for="(ingredient, index) in fortune.ingredients" :key="index" class="flex items-center gap-2 p-2 bg-gray-50 rounded-lg">
                         <span class="w-2 h-2 bg-purple-400 rounded-full"></span>
                         <span class="text-gray-700">{{ ingredient }}</span>
                     </div>
@@ -83,11 +73,7 @@
                     <span>神秘步骤</span>
                 </h3>
                 <div class="space-y-4">
-                    <div
-                        v-for="(step, index) in fortune.steps"
-                        :key="index"
-                        class="flex gap-4 p-4 bg-gray-50 rounded-lg border-l-4 border-purple-400"
-                    >
+                    <div v-for="(step, index) in fortune.steps" :key="index" class="flex gap-4 p-4 bg-gray-50 rounded-lg border-l-4 border-purple-400">
                         <div class="flex-shrink-0">
                             <div class="w-8 h-8 bg-purple-500 text-white rounded-full flex items-center justify-center font-bold text-sm">
                                 {{ index + 1 }}
@@ -107,11 +93,7 @@
                     <span>神秘建议</span>
                 </h3>
                 <div class="space-y-2">
-                    <div
-                        v-for="(tip, index) in fortune.tips"
-                        :key="index"
-                        class="flex items-start gap-2 p-3 bg-yellow-50 rounded-lg border border-yellow-200"
-                    >
+                    <div v-for="(tip, index) in fortune.tips" :key="index" class="flex items-start gap-2 p-3 bg-yellow-50 rounded-lg border border-yellow-200">
                         <span class="text-yellow-600 mt-0.5">💫</span>
                         <span class="text-gray-700">{{ tip }}</span>
                     </div>
@@ -126,8 +108,6 @@
                 </h3>
                 <p class="text-gray-700 italic text-center">{{ fortune.mysticalMessage }}</p>
             </div>
-
-           
         </div>
     </div>
 </template>
@@ -137,12 +117,9 @@ import type { FortuneResult, FortuneType } from '@/types'
 
 interface Props {
     fortune: FortuneResult
-    showActions?: boolean
 }
 
-const props = withDefaults(defineProps<Props>(), {
-    showActions: false
-})
+const { fortune } = defineProps<Props>()
 
 // 获取占卜类型名称
 const getFortuneTypeName = (type: FortuneType): string => {
@@ -175,39 +152,39 @@ const getDifficultyName = (difficulty: 'easy' | 'medium' | 'hard'): string => {
     return names[difficulty]
 }
 
-// 分享结果
-const shareResult = () => {
-    const shareText = `🔮 料理占卜师为我推荐了:${props.fortune.dishName}\n\n✨ ${props.fortune.reason}\n\n🌟 幸运指数:${props.fortune.luckyIndex}/10\n\n来"一饭封神"体验神秘的料理占卜吧!`
-    
-    if (navigator.share) {
-        navigator.share({
-            title: '料理占卜结果',
-            text: shareText,
-            url: window.location.href
-        })
-    } else {
-        navigator.clipboard.writeText(shareText).then(() => {
-            // 可以添加提示
-            console.log('占卜结果已复制到剪贴板')
-        })
-    }
-}
+// 分享结果 - 暂时未使用
+// const shareResult = () => {
+//     const shareText = `🔮 料理占卜师为我推荐了:${props.fortune.dishName}\n\n✨ ${props.fortune.reason}\n\n🌟 幸运指数:${props.fortune.luckyIndex}/10\n\n来"一饭封神"体验神秘的料理占卜吧!`
 
-// 保存结果
-const saveResult = () => {
-    try {
-        const savedResults = JSON.parse(localStorage.getItem('fortune_results') || '[]')
-        savedResults.unshift(props.fortune)
-        
-        // 只保留最近20个结果
-        if (savedResults.length > 20) {
-            savedResults.splice(20)
-        }
-        
-        localStorage.setItem('fortune_results', JSON.stringify(savedResults))
-        console.log('占卜结果已保存')
-    } catch (error) {
-        console.error('保存占卜结果失败:', error)
-    }
-}
-</script>
+//     if (navigator.share) {
+//         navigator.share({
+//             title: '料理占卜结果',
+//             text: shareText,
+//             url: window.location.href
+//         })
+//     } else {
+//         navigator.clipboard.writeText(shareText).then(() => {
+//             // 可以添加提示
+//             console.log('占卜结果已复制到剪贴板')
+//         })
+//     }
+// }
+
+// 保存结果 - 暂时未使用
+// const saveResult = () => {
+//     try {
+//         const savedResults = JSON.parse(localStorage.getItem('fortune_results') || '[]')
+//         savedResults.unshift(props.fortune)
+
+//         // 只保留最近20个结果
+//         if (savedResults.length > 20) {
+//             savedResults.splice(20)
+//         }
+
+//         localStorage.setItem('fortune_results', JSON.stringify(savedResults))
+//         console.log('占卜结果已保存')
+//     } catch (error) {
+//         console.error('保存占卜结果失败:', error)
+//     }
+// }
+</script>

+ 1 - 1
src/components/NotesModal.vue

@@ -44,7 +44,7 @@ interface Props {
 }
 
 const props = defineProps<Props>()
-const emit = defineEmits<{
+defineEmits<{
     close: []
     save: [notes: string]
 }>()

+ 9 - 40
src/components/SauceRecipe.vue

@@ -14,17 +14,13 @@
                             <span>⏱️</span>
                             <span>{{ sauce.makingTime }}分钟</span>
                         </span>
-                        <span :class="[
-                            'px-2 py-1 rounded-full text-xs font-medium',
-                            getDifficultyStyle(sauce.difficulty)
-                        ]">
+                        <span :class="['px-2 py-1 rounded-full text-xs font-medium', getDifficultyStyle(sauce.difficulty)]">
                             {{ getDifficultyName(sauce.difficulty) }}
                         </span>
                     </div>
                 </div>
-
             </div>
-            
+
             <!-- 口味特征 -->
             <div class="mt-4 grid grid-cols-4 gap-2 md:gap-4">
                 <div class="text-center">
@@ -71,11 +67,7 @@
                     <span>食材清单</span>
                 </h3>
                 <div class="grid md:grid-cols-2 gap-2">
-                    <div
-                        v-for="(ingredient, index) in sauce.ingredients"
-                        :key="index"
-                        class="flex items-center gap-2 p-2 bg-gray-50 rounded-lg"
-                    >
+                    <div v-for="(ingredient, index) in sauce.ingredients" :key="index" class="flex items-center gap-2 p-2 bg-gray-50 rounded-lg">
                         <span class="w-2 h-2 bg-orange-400 rounded-full"></span>
                         <span class="text-gray-700">{{ ingredient }}</span>
                     </div>
@@ -89,11 +81,7 @@
                     <span>制作步骤</span>
                 </h3>
                 <div class="space-y-4">
-                    <div
-                        v-for="step in sauce.steps"
-                        :key="step.step"
-                        class="flex gap-4 p-4 bg-gray-50 rounded-lg border-l-4 border-orange-400"
-                    >
+                    <div v-for="step in sauce.steps" :key="step.step" class="flex gap-4 p-4 bg-gray-50 rounded-lg border-l-4 border-orange-400">
                         <div class="flex-shrink-0">
                             <div class="w-8 h-8 bg-orange-500 text-white rounded-full flex items-center justify-center font-bold text-sm">
                                 {{ step.step }}
@@ -127,11 +115,7 @@
                     <span>制作技巧</span>
                 </h3>
                 <div class="space-y-2">
-                    <div
-                        v-for="(tip, index) in sauce.tips"
-                        :key="index"
-                        class="flex items-start gap-2 p-3 bg-yellow-50 rounded-lg border border-yellow-200"
-                    >
+                    <div v-for="(tip, index) in sauce.tips" :key="index" class="flex items-start gap-2 p-3 bg-yellow-50 rounded-lg border border-yellow-200">
                         <span class="text-yellow-600 mt-0.5">💡</span>
                         <span class="text-gray-700">{{ tip }}</span>
                     </div>
@@ -169,11 +153,7 @@
                     <span>搭配建议</span>
                 </h3>
                 <div class="flex flex-wrap gap-2">
-                    <span
-                        v-for="pairing in sauce.pairings"
-                        :key="pairing"
-                        class="px-3 py-2 bg-green-100 text-green-800 rounded-full text-sm border border-green-200"
-                    >
+                    <span v-for="pairing in sauce.pairings" :key="pairing" class="px-3 py-2 bg-green-100 text-green-800 rounded-full text-sm border border-green-200">
                         {{ pairing }}
                     </span>
                 </div>
@@ -182,17 +162,9 @@
             <!-- 标签 -->
             <div v-if="sauce.tags.length > 0" class="mb-4">
                 <div class="flex flex-wrap gap-2">
-                    <span
-                        v-for="tag in sauce.tags"
-                        :key="tag"
-                        class="px-2 py-1 bg-gray-200 text-gray-700 rounded-full text-xs"
-                    >
-                        #{{ tag }}
-                    </span>
+                    <span v-for="tag in sauce.tags" :key="tag" class="px-2 py-1 bg-gray-200 text-gray-700 rounded-full text-xs"> #{{ tag }} </span>
                 </div>
             </div>
-
-
         </div>
     </div>
 </template>
@@ -203,10 +175,7 @@ import { getCategoryIcon, getCategoryName, getDifficultyStyle, getDifficultyName
 
 interface Props {
     sauce: SauceRecipe
-    showActions?: boolean
 }
 
-const props = withDefaults(defineProps<Props>(), {
-    showActions: false
-})
-</script>
+const { sauce } = defineProps<Props>()
+</script>

+ 2 - 3
src/services/aiService.ts

@@ -453,14 +453,13 @@ export const generateMultipleRecipesStream = async (
             onRecipeGenerated(recipe, index, total)
         } catch (error) {
             console.error(`生成${cuisine.name}菜谱失败:`, error)
-            
+
             // 调用错误回调,让前端可以显示友好的错误信息
             if (onRecipeError) {
-                const errorMessage = error instanceof Error ? error.message : `${cuisine.name}生成失败`
                 const friendlyError = new Error(`${cuisine.name}不会这道菜,哈哈`)
                 onRecipeError(friendlyError, index, cuisine, total)
             }
-            
+
             // 即使某个菜系失败,也继续生成其他菜系
             continue
         }

+ 0 - 13
src/types/index.ts

@@ -27,7 +27,6 @@ export interface Recipe {
     tips: string[]
     nutritionAnalysis?: NutritionAnalysis // 营养分析
     winePairing?: WinePairing // 酒水搭配
-    winePairing?: WinePairing // 酒水搭配
 }
 
 // 制作步骤
@@ -74,18 +73,6 @@ export interface WinePairing {
     origin?: string // 产地
 }
 
-// 酒水搭配类型
-export interface WinePairing {
-    name: string // 酒水名称
-    type: 'red_wine' | 'white_wine' | 'beer' | 'sake' | 'tea' | 'cocktail' | 'spirits' | 'non_alcoholic' // 酒水类型
-    reason: string // 搭配理由
-    flavor: string // 风味描述
-    servingTemperature: string // 侍酒温度
-    glassType?: string // 推荐酒杯
-    alcoholContent?: string // 酒精度
-    origin?: string // 产地
-}
-
 // 收藏菜谱类型
 export interface FavoriteRecipe {
     id: string

+ 1 - 1
src/views/Favorites.vue

@@ -198,7 +198,7 @@
 
 <script setup lang="ts">
 import { ref, computed, onMounted } from 'vue'
-import type { Recipe, FavoriteRecipe } from '@/types'
+import type { FavoriteRecipe } from '@/types'
 import { FavoriteService } from '@/services/favoriteService'
 import RecipeCard from '@/components/RecipeCard.vue'
 import GlobalNavigation from '@/components/GlobalNavigation.vue'

+ 145 - 147
src/views/Home.vue

@@ -394,7 +394,7 @@
                                                         <span>😓</span>
                                                         技能点不够
                                                     </span>
-                                                    <span>🎯 换个大师试试</span>
+                                                    <span>🎯 开小差了</span>
                                                 </div>
                                             </div>
                                             <div class="text-2xl ml-2">🤷‍♂️</div>
@@ -408,16 +408,12 @@
                                                 <span class="text-orange-500 text-2xl">🤔</span>
                                             </div>
                                             <h4 class="text-lg font-bold text-gray-800 mb-2">大师表示很为难</h4>
-                                            <p class="text-gray-600 text-sm mb-4">
-                                                {{ cuisineInfo.name }}看了看你的食材,挠了挠头说:"这个组合我还没学会呢!"
-                                            </p>
+                                            <p class="text-gray-600 text-sm mb-4">{{ cuisineInfo.name }}看了看你的食材,挠了挠头说:"这个组合我还没学会呢!"</p>
                                         </div>
 
                                         <!-- 建议区域 -->
                                         <div class="bg-yellow-50 border-2 border-yellow-200 rounded-lg p-4 mb-4">
-                                            <h5 class="text-sm font-bold text-yellow-800 mb-2 flex items-center gap-1 justify-center">
-                                                💡 大师的建议
-                                            </h5>
+                                            <h5 class="text-sm font-bold text-yellow-800 mb-2 flex items-center gap-1 justify-center">💡 大师的建议</h5>
                                             <div class="text-xs text-yellow-700 space-y-1">
                                                 <p>• 试试其他菜系大师,他们可能有不同的想法</p>
                                                 <p>• 调整一下食材搭配,或许会有惊喜</p>
@@ -618,8 +614,8 @@ import { ingredientCategories } from '@/config/ingredients'
 import RecipeCard from '@/components/RecipeCard.vue'
 import GlobalNavigation from '@/components/GlobalNavigation.vue'
 import GlobalFooter from '@/components/GlobalFooter.vue'
-import { generateMultipleRecipes, generateCustomRecipe, generateMultipleRecipesStream, generateRecipe } from '@/services/aiService'
-import type { Recipe, CuisineType, NutritionAnalysis } from '@/types'
+import { generateCustomRecipe, generateMultipleRecipesStream, generateRecipe } from '@/services/aiService'
+import type { Recipe, CuisineType } from '@/types'
 
 // 响应式数据
 const ingredients = ref<string[]>([])
@@ -647,16 +643,16 @@ interface CuisineSlot {
 }
 const cuisineSlots = ref<CuisineSlot[]>([])
 
-// 加载文字轮播
-const loadingTexts = [
-    '大师正在挑选食材...',
-    '大师正在起火热锅...',
-    '大师正在爆香配料...',
-    '大师正在调制秘制酱料...',
-    '大师正在掌控火候...',
-    '大师正在精心摆盘...',
-    '美味佳肴即将出炉...'
-]
+// 加载文字轮播 - 暂时未使用
+// const loadingTexts = [
+//     '大师正在挑选食材...',
+//     '大师正在起火热锅...',
+//     '大师正在爆香配料...',
+//     '大师正在调制秘制酱料...',
+//     '大师正在掌控火候...',
+//     '大师正在精心摆盘...',
+//     '美味佳肴即将出炉...'
+// ]
 
 let loadingInterval: NodeJS.Timeout | null = null
 
@@ -679,23 +675,25 @@ const tastePresets = [
     { id: 'crispy', name: '酥脆爽口', prompt: '口感酥脆,层次分明,嚼劲十足' }
 ]
 
-const healthPresets = [
-    { id: 'lowfat', name: '低脂健康', prompt: '低脂肪制作,健康营养,适合减脂期间食用' },
-    { id: 'highprotein', name: '高蛋白', prompt: '富含优质蛋白质,适合健身人群和成长期儿童' },
-    { id: 'vegetarian', name: '素食主义', prompt: '纯素食制作,不含任何动物性食材,营养均衡' },
-    { id: 'diabetic', name: '控糖友好', prompt: '低糖低GI,适合糖尿病患者或需要控制血糖的人群' },
-    { id: 'elderly', name: '老人友好', prompt: '软烂易消化,营养丰富,适合老年人食用' },
-    { id: 'children', name: '儿童喜爱', prompt: '造型可爱,营养全面,适合儿童的口味偏好' }
-]
-
-const cookingPresets = [
-    { id: 'steam', name: '清蒸', prompt: '采用蒸制方法,保持食材原味和营养' },
-    { id: 'stirfry', name: '爆炒', prompt: '大火爆炒,锁住食材鲜味,口感脆嫩' },
-    { id: 'braise', name: '红烧', prompt: '红烧制作,色泽红亮,味道浓郁' },
-    { id: 'soup', name: '煲汤', prompt: '制作成汤品,清香鲜美,营养丰富' },
-    { id: 'cold', name: '凉拌', prompt: '凉拌制作,清爽开胃,适合夏季' },
-    { id: 'grill', name: '烧烤', prompt: '烧烤方式制作,香气四溢,口感独特' }
-]
+// 健康偏好预设 - 暂时未使用
+// const healthPresets = [
+//     { id: 'lowfat', name: '低脂健康', prompt: '低脂肪制作,健康营养,适合减脂期间食用' },
+//     { id: 'highprotein', name: '高蛋白', prompt: '富含优质蛋白质,适合健身人群和成长期儿童' },
+//     { id: 'vegetarian', name: '素食主义', prompt: '纯素食制作,不含任何动物性食材,营养均衡' },
+//     { id: 'diabetic', name: '控糖友好', prompt: '低糖低GI,适合糖尿病患者或需要控制血糖的人群' },
+//     { id: 'elderly', name: '老人友好', prompt: '软烂易消化,营养丰富,适合老年人食用' },
+//     { id: 'children', name: '儿童喜爱', prompt: '造型可爱,营养全面,适合儿童的口味偏好' }
+// ]
+
+// 烹饪方式预设 - 暂时未使用
+// const cookingPresets = [
+//     { id: 'steam', name: '清蒸', prompt: '采用蒸制方法,保持食材原味和营养' },
+//     { id: 'stirfry', name: '爆炒', prompt: '大火爆炒,锁住食材鲜味,口感脆嫩' },
+//     { id: 'braise', name: '红烧', prompt: '红烧制作,色泽红亮,味道浓郁' },
+//     { id: 'soup', name: '煲汤', prompt: '制作成汤品,清香鲜美,营养丰富' },
+//     { id: 'cold', name: '凉拌', prompt: '凉拌制作,清爽开胃,适合夏季' },
+//     { id: 'grill', name: '烧烤', prompt: '烧烤方式制作,香气四溢,口感独特' }
+// ]
 
 // 添加食材
 const addIngredient = () => {
@@ -940,7 +938,7 @@ const generateRecipes = async () => {
                         }, 1000)
                     }
                 },
-                (error: Error, index: number, cuisine: CuisineType, total: number) => {
+                (error: Error, index: number, _cuisine: CuisineType, total: number) => {
                     // 处理菜谱生成失败
                     const targetSlot = cuisineSlots.value.find(slot => selectedCuisineObjects[index] && slot.id === selectedCuisineObjects[index].id)
 
@@ -1009,7 +1007,7 @@ const retryFailedCuisine = async (failedSlot: CuisineSlot) => {
         await new Promise(resolve => setTimeout(resolve, delay))
 
         // 重新生成菜谱
-        const recipe = customPrompt.value.trim() 
+        const recipe = customPrompt.value.trim()
             ? await generateCustomRecipe(ingredients.value, customPrompt.value.trim())
             : await generateRecipe(ingredients.value, cuisine, customPrompt.value.trim() || undefined)
 
@@ -1024,7 +1022,7 @@ const retryFailedCuisine = async (failedSlot: CuisineSlot) => {
         clearInterval(progressInterval)
     } catch (error) {
         console.error(`重试${cuisine.name}菜谱失败:`, error)
-        
+
         // 重新设置错误状态
         failedSlot.error = true
         failedSlot.errorMessage = error instanceof Error ? error.message : `${cuisine.name}还是不会这道菜`
@@ -1035,114 +1033,114 @@ const retryFailedCuisine = async (failedSlot: CuisineSlot) => {
     }
 }
 
-// 模拟AI调用(后续替换为真实接口)
-const simulateAICall = async () => {
-    return new Promise(resolve => {
-        setTimeout(() => {
-            // 获取要使用的菜系
-            let cuisinesToUse = cuisines.filter(c => selectedCuisines.value.includes(c.id))
-            if (cuisinesToUse.length === 0) {
-                // 随机选择2个菜系
-                const shuffled = [...cuisines].sort(() => 0.5 - Math.random())
-                cuisinesToUse = shuffled.slice(0, 2)
-            }
-
-            // 检查是否有自定义提示词
-            let mockRecipes: Recipe[] = []
-
-            if (customPrompt.value.trim()) {
-                // 生成自定义菜谱
-                mockRecipes = [
-                    {
-                        id: `recipe-custom-${Date.now()}`,
-                        name: `自定义:${ingredients.value.join('')}料理`,
-                        cuisine: '自定义',
-                        ingredients: ingredients.value,
-                        steps: [
-                            { step: 1, description: '准备所有食材,清洗干净', time: 5 },
-                            { step: 2, description: '根据要求进行烹饪处理', time: 10 },
-                            { step: 3, description: '调味并完成最后的制作', time: 8 },
-                            { step: 4, description: '装盘即可享用', time: 2 }
-                        ],
-                        cookingTime: 25,
-                        difficulty: 'medium',
-                        tips: ['根据个人喜好调整口味', '注意食材的新鲜度', '掌握好火候'],
-                        nutritionAnalysis: generateMockNutrition(ingredients.value)
-                    }
-                ]
-            } else {
-                // 生成菜系菜谱
-                mockRecipes = cuisinesToUse.map((cuisine, index) => {
-                    return {
-                        id: `recipe-${cuisine.id}-${Date.now()}-${index}`,
-                        name: `${cuisine.name}推荐:${ingredients.value.join('')}料理`,
-                        cuisine: cuisine.name,
-                        ingredients: ingredients.value,
-                        steps: [
-                            { step: 1, description: '准备所有食材,清洗干净', time: 5 },
-                            { step: 2, description: '热锅下油,爆香配料', time: 3 },
-                            { step: 3, description: '下主料翻炒至半熟', time: 8 },
-                            { step: 4, description: '调味炒制至熟透', time: 5 },
-                            { step: 5, description: '装盘即可享用', time: 1 }
-                        ],
-                        cookingTime: 22,
-                        difficulty: 'medium',
-                        tips: ['火候要掌握好,避免炒糊', '调料要适量,突出食材本味', '炒制过程中要勤翻动'],
-                        nutritionAnalysis: generateMockNutrition(ingredients.value)
-                    }
-                })
-            }
-
-            recipes.value = mockRecipes
-            resolve(mockRecipes)
-        }, 3000)
-    })
-}
-
-// 生成模拟营养分析数据
-const generateMockNutrition = (ingredients: string[]): NutritionAnalysis => {
-    // 基于食材数量和类型估算营养成分
-    const baseCalories = ingredients.length * 50 + Math.floor(Math.random() * 100) + 200
-    const hasVegetables = ingredients.some(ing => ['菜', '瓜', '豆', '萝卜', '白菜', '菠菜', '西红柿', '黄瓜', '茄子', '土豆'].some(veg => ing.includes(veg)))
-    const hasMeat = ingredients.some(ing => ['肉', '鸡', '鱼', '虾', '蛋', '牛', '猪', '羊'].some(meat => ing.includes(meat)))
-    const hasGrains = ingredients.some(ing => ['米', '面', '粉', '饭', '面条', '馒头'].some(grain => ing.includes(grain)))
-
-    // 生成饮食标签
-    const dietaryTags: string[] = []
-    if (hasVegetables && !hasMeat) dietaryTags.push('素食')
-    if (hasMeat) dietaryTags.push('高蛋白')
-    if (hasVegetables) dietaryTags.push('富含维生素')
-    if (!hasGrains) dietaryTags.push('低碳水')
-    if (baseCalories < 300) dietaryTags.push('低卡路里')
-
-    // 生成营养建议
-    const balanceAdvice: string[] = []
-    if (!hasVegetables) balanceAdvice.push('建议搭配新鲜蔬菜增加维生素和膳食纤维')
-    if (!hasMeat && !ingredients.some(ing => ['豆', '蛋', '奶'].some(protein => ing.includes(protein)))) {
-        balanceAdvice.push('建议增加蛋白质来源,如豆类或蛋类')
-    }
-    if (hasGrains && hasMeat) balanceAdvice.push('营养搭配均衡,适合日常食用')
-    if (ingredients.length > 5) balanceAdvice.push('食材丰富,营养全面')
-
-    return {
-        nutrition: {
-            calories: baseCalories,
-            protein: hasMeat ? 20 + Math.floor(Math.random() * 15) : 8 + Math.floor(Math.random() * 8),
-            carbs: hasGrains ? 35 + Math.floor(Math.random() * 20) : 15 + Math.floor(Math.random() * 10),
-            fat: hasMeat ? 12 + Math.floor(Math.random() * 8) : 5 + Math.floor(Math.random() * 5),
-            fiber: hasVegetables ? 6 + Math.floor(Math.random() * 4) : 2 + Math.floor(Math.random() * 2),
-            sodium: 600 + Math.floor(Math.random() * 400),
-            sugar: 3 + Math.floor(Math.random() * 5),
-            vitaminC: hasVegetables ? 20 + Math.floor(Math.random() * 30) : undefined,
-            calcium: hasMeat || ingredients.some(ing => ['奶', '豆'].some(ca => ing.includes(ca))) ? 100 + Math.floor(Math.random() * 100) : undefined,
-            iron: hasMeat ? 2 + Math.floor(Math.random() * 3) : undefined
-        },
-        healthScore: Math.floor(Math.random() * 3) + (hasVegetables ? 6 : 4) + (hasMeat ? 1 : 0),
-        balanceAdvice: balanceAdvice.length > 0 ? balanceAdvice : ['营养搭配合理,可以放心享用'],
-        dietaryTags: dietaryTags.length > 0 ? dietaryTags : ['家常菜'],
-        servingSize: '1人份'
-    }
-}
+// 模拟AI调用(后续替换为真实接口)- 暂时未使用
+// const simulateAICall = async () => {
+//     return new Promise(resolve => {
+//         setTimeout(() => {
+//             // 获取要使用的菜系
+//             let cuisinesToUse = cuisines.filter(c => selectedCuisines.value.includes(c.id))
+//             if (cuisinesToUse.length === 0) {
+//                 // 随机选择2个菜系
+//                 const shuffled = [...cuisines].sort(() => 0.5 - Math.random())
+//                 cuisinesToUse = shuffled.slice(0, 2)
+//             }
+
+//             // 检查是否有自定义提示词
+//             let mockRecipes: Recipe[] = []
+
+//             if (customPrompt.value.trim()) {
+//                 // 生成自定义菜谱
+//                 mockRecipes = [
+//                     {
+//                         id: `recipe-custom-${Date.now()}`,
+//                         name: `自定义:${ingredients.value.join('')}料理`,
+//                         cuisine: '自定义',
+//                         ingredients: ingredients.value,
+//                         steps: [
+//                             { step: 1, description: '准备所有食材,清洗干净', time: 5 },
+//                             { step: 2, description: '根据要求进行烹饪处理', time: 10 },
+//                             { step: 3, description: '调味并完成最后的制作', time: 8 },
+//                             { step: 4, description: '装盘即可享用', time: 2 }
+//                         ],
+//                         cookingTime: 25,
+//                         difficulty: 'medium',
+//                         tips: ['根据个人喜好调整口味', '注意食材的新鲜度', '掌握好火候'],
+//                         nutritionAnalysis: generateMockNutrition(ingredients.value)
+//                     }
+//                 ]
+//             } else {
+//                 // 生成菜系菜谱
+//                 mockRecipes = cuisinesToUse.map((cuisine, index) => {
+//                     return {
+//                         id: `recipe-${cuisine.id}-${Date.now()}-${index}`,
+//                         name: `${cuisine.name}推荐:${ingredients.value.join('')}料理`,
+//                         cuisine: cuisine.name,
+//                         ingredients: ingredients.value,
+//                         steps: [
+//                             { step: 1, description: '准备所有食材,清洗干净', time: 5 },
+//                             { step: 2, description: '热锅下油,爆香配料', time: 3 },
+//                             { step: 3, description: '下主料翻炒至半熟', time: 8 },
+//                             { step: 4, description: '调味炒制至熟透', time: 5 },
+//                             { step: 5, description: '装盘即可享用', time: 1 }
+//                         ],
+//                         cookingTime: 22,
+//                         difficulty: 'medium',
+//                         tips: ['火候要掌握好,避免炒糊', '调料要适量,突出食材本味', '炒制过程中要勤翻动'],
+//                         nutritionAnalysis: generateMockNutrition(ingredients.value)
+//                     }
+//                 })
+//             }
+
+//             recipes.value = mockRecipes
+//             resolve(mockRecipes)
+//         }, 3000)
+//     })
+// }
+
+// 生成模拟营养分析数据 - 暂时未使用
+// const generateMockNutrition = (ingredients: string[]): NutritionAnalysis => {
+//     // 基于食材数量和类型估算营养成分
+//     const baseCalories = ingredients.length * 50 + Math.floor(Math.random() * 100) + 200
+//     const hasVegetables = ingredients.some(ing => ['菜', '瓜', '豆', '萝卜', '白菜', '菠菜', '西红柿', '黄瓜', '茄子', '土豆'].some(veg => ing.includes(veg)))
+//     const hasMeat = ingredients.some(ing => ['肉', '鸡', '鱼', '虾', '蛋', '牛', '猪', '羊'].some(meat => ing.includes(meat)))
+//     const hasGrains = ingredients.some(ing => ['米', '面', '粉', '饭', '面条', '馒头'].some(grain => ing.includes(grain)))
+
+//     // 生成饮食标签
+//     const dietaryTags: string[] = []
+//     if (hasVegetables && !hasMeat) dietaryTags.push('素食')
+//     if (hasMeat) dietaryTags.push('高蛋白')
+//     if (hasVegetables) dietaryTags.push('富含维生素')
+//     if (!hasGrains) dietaryTags.push('低碳水')
+//     if (baseCalories < 300) dietaryTags.push('低卡路里')
+
+//     // 生成营养建议
+//     const balanceAdvice: string[] = []
+//     if (!hasVegetables) balanceAdvice.push('建议搭配新鲜蔬菜增加维生素和膳食纤维')
+//     if (!hasMeat && !ingredients.some(ing => ['豆', '蛋', '奶'].some(protein => ing.includes(protein)))) {
+//         balanceAdvice.push('建议增加蛋白质来源,如豆类或蛋类')
+//     }
+//     if (hasGrains && hasMeat) balanceAdvice.push('营养搭配均衡,适合日常食用')
+//     if (ingredients.length > 5) balanceAdvice.push('食材丰富,营养全面')
+
+//     return {
+//         nutrition: {
+//             calories: baseCalories,
+//             protein: hasMeat ? 20 + Math.floor(Math.random() * 15) : 8 + Math.floor(Math.random() * 8),
+//             carbs: hasGrains ? 35 + Math.floor(Math.random() * 20) : 15 + Math.floor(Math.random() * 10),
+//             fat: hasMeat ? 12 + Math.floor(Math.random() * 8) : 5 + Math.floor(Math.random() * 5),
+//             fiber: hasVegetables ? 6 + Math.floor(Math.random() * 4) : 2 + Math.floor(Math.random() * 2),
+//             sodium: 600 + Math.floor(Math.random() * 400),
+//             sugar: 3 + Math.floor(Math.random() * 5),
+//             vitaminC: hasVegetables ? 20 + Math.floor(Math.random() * 30) : undefined,
+//             calcium: hasMeat || ingredients.some(ing => ['奶', '豆'].some(ca => ing.includes(ca))) ? 100 + Math.floor(Math.random() * 100) : undefined,
+//             iron: hasMeat ? 2 + Math.floor(Math.random() * 3) : undefined
+//         },
+//         healthScore: Math.floor(Math.random() * 3) + (hasVegetables ? 6 : 4) + (hasMeat ? 1 : 0),
+//         balanceAdvice: balanceAdvice.length > 0 ? balanceAdvice : ['营养搭配合理,可以放心享用'],
+//         dietaryTags: dietaryTags.length > 0 ? dietaryTags : ['家常菜'],
+//         servingSize: '1人份'
+//     }
+// }
 
 onUnmounted(() => {
     if (loadingInterval) {

+ 1 - 1
src/views/SauceDesign.vue

@@ -283,7 +283,7 @@
 import { ref, onMounted } from 'vue'
 import { generateSauceRecipe, recommendSauces } from '@/services/aiService'
 import type { SauceRecipe, SaucePreference } from '@/types'
-import { useCaseOptions, tasteDescriptions } from '@/config/sauces'
+import { useCaseOptions } from '@/config/sauces'
 import SauceRecipeComponent from '@/components/SauceRecipe.vue'
 import GlobalNavigation from '@/components/GlobalNavigation.vue'
 import GlobalFooter from '@/components/GlobalFooter.vue'

+ 49 - 49
src/views/TableDesign.vue

@@ -477,7 +477,7 @@ import type { Recipe } from '@/types'
 import RecipeCard from '@/components/RecipeCard.vue'
 import GlobalNavigation from '@/components/GlobalNavigation.vue'
 import GlobalFooter from '@/components/GlobalFooter.vue'
-import { generateTableMenu, generateDishRecipe, testAIConnection } from '@/services/aiService'
+import { generateTableMenu, generateDishRecipe } from '@/services/aiService'
 
 // 配置选项
 interface TableConfig {
@@ -570,19 +570,19 @@ const toggleTaste = (tasteId: string) => {
     }
 }
 
-// 增加菜品数量
-const increaseDishCount = () => {
-    if (config.dishCount < 20) {
-        config.dishCount++
-    }
-}
+// 增加菜品数量 - 暂时未使用
+// const increaseDishCount = () => {
+//     if (config.dishCount < 20) {
+//         config.dishCount++
+//     }
+// }
 
-// 减少菜品数量
-const decreaseDishCount = () => {
-    if (config.dishCount > 1) {
-        config.dishCount--
-    }
-}
+// 减少菜品数量 - 暂时未使用
+// const decreaseDishCount = () => {
+//     if (config.dishCount > 1) {
+//         config.dishCount--
+//     }
+// }
 
 // 验证菜品数量输入
 const validateDishCount = (event: Event) => {
@@ -615,19 +615,19 @@ const removeCustomDish = (dish: string) => {
     }
 }
 
-// 测试AI连接
-const testConnection = async () => {
-    try {
-        const isConnected = await testAIConnection()
-        if (isConnected) {
-            alert('AI连接测试成功!')
-        } else {
-            alert('大厨暂时不在厨房,请稍后再试~')
-        }
-    } catch (error) {
-        alert('大厨暂时不在厨房:' + error)
-    }
-}
+// 测试AI连接 - 暂时未使用
+// const testConnection = async () => {
+//     try {
+//         const isConnected = await testAIConnection()
+//         if (isConnected) {
+//             alert('AI连接测试成功!')
+//         } else {
+//             alert('大厨暂时不在厨房,请稍后再试~')
+//         }
+//     } catch (error) {
+//         alert('大厨暂时不在厨房:' + error)
+//     }
+// }
 
 // 生成一桌菜
 const generateTableMenuAction = async () => {
@@ -668,7 +668,7 @@ const enableBodyScroll = () => {
 }
 
 // 生成单个菜品的菜谱
-const generateDishRecipeAction = async (dish: DishInfo, index: number) => {
+const generateDishRecipeAction = async (dish: DishInfo, _index: number) => {
     if (dish.recipe) {
         selectedRecipe.value = dish.recipe
         disableBodyScroll()
@@ -700,28 +700,28 @@ const closeRecipeModal = () => {
     enableBodyScroll()
 }
 
-// 测试弹窗功能
-const testModal = () => {
-    // 创建一个测试菜谱
-    const testRecipe: Recipe = {
-        id: 'test-recipe',
-        name: '测试菜谱 - 红烧肉',
-        cuisine: '中式',
-        ingredients: ['五花肉 500g', '生抽 2勺', '老抽 1勺', '冰糖 30g', '料酒 1勺', '葱段 适量', '姜片 适量'],
-        steps: [
-            { step: 1, description: '五花肉切块,冷水下锅焯水去腥', time: 5 },
-            { step: 2, description: '热锅下油,放入冰糖炒糖色', time: 3 },
-            { step: 3, description: '下入肉块翻炒上色', time: 5 },
-            { step: 4, description: '加入生抽、老抽、料酒调色调味', time: 2 },
-            { step: 5, description: '加入开水没过肉块,大火烧开转小火炖煮', time: 45 }
-        ],
-        cookingTime: 60,
-        difficulty: 'medium',
-        tips: ['糖色要炒到微微冒烟', '炖煮时要小火慢炖', '最后大火收汁']
-    }
-
-    selectedRecipe.value = testRecipe
-}
+// 测试弹窗功能 - 暂时未使用
+// const testModal = () => {
+//     // 创建一个测试菜谱
+//     const testRecipe: Recipe = {
+//         id: 'test-recipe',
+//         name: '测试菜谱 - 红烧肉',
+//         cuisine: '中式',
+//         ingredients: ['五花肉 500g', '生抽 2勺', '老抽 1勺', '冰糖 30g', '料酒 1勺', '葱段 适量', '姜片 适量'],
+//         steps: [
+//             { step: 1, description: '五花肉切块,冷水下锅焯水去腥', time: 5 },
+//             { step: 2, description: '热锅下油,放入冰糖炒糖色', time: 3 },
+//             { step: 3, description: '下入肉块翻炒上色', time: 5 },
+//             { step: 4, description: '加入生抽、老抽、料酒调色调味', time: 2 },
+//             { step: 5, description: '加入开水没过肉块,大火烧开转小火炖煮', time: 45 }
+//         ],
+//         cookingTime: 60,
+//         difficulty: 'medium',
+//         tips: ['糖色要炒到微微冒烟', '炖煮时要小火慢炖', '最后大火收汁']
+//     }
+
+//     selectedRecipe.value = testRecipe
+// }
 
 // 键盘事件处理
 const handleKeydown = (event: KeyboardEvent) => {

+ 1 - 1
tsconfig.json

@@ -15,7 +15,7 @@
     "noUnusedLocals": true,
     "noUnusedParameters": true,
     "noFallthroughCasesInSwitch": true,
-    "types": ["vite/client"],
+    "types": ["vite/client", "node"],
     "baseUrl": ".",
     "paths": {
       "@/*": ["src/*"]