* feat: 添加食物相克检测功能及相关数据支持 * chore: 修改 .gitignore 设置,并删除 recipe.json 的 git 引用 * style: 格式化 incompatible-foods.ts 文件中的代码,修改缩紧为 2 * fix: 修复导入语句,确保正确使用 Vue 的 ref 和 computed * refactor: 优化相克检测逻辑,使用 Set 提高性能 * refactor: 移除不必要的 IncompatibleRule 类型定义 * fix: 添加缺失字段检查,确保不完整数据不会被处理 * style: 使用 eslint 优化代码格式
89 lines
2.6 KiB
TypeScript
89 lines
2.6 KiB
TypeScript
import type { IncompatibleRule } from '~/types'
|
||
import { computed, onMounted, readonly, ref } from 'vue'
|
||
import incompatibleFoodsData from '~/data/incompatible-foods.json'
|
||
|
||
/**
|
||
* 食物相克检测 composable
|
||
*/
|
||
export function useIncompatibleFoods() {
|
||
// 用于存储从 JSON 加载的相克规则
|
||
const incompatibleRules = ref<IncompatibleRule[]>([])
|
||
// 用于存储并显示给用户的警告信息
|
||
const warningMessage = ref<string>('')
|
||
// 加载状态
|
||
const isLoading = ref(true)
|
||
|
||
/**
|
||
* 在组件挂载后,加载食物相克数据
|
||
*/
|
||
onMounted(() => {
|
||
try {
|
||
// 直接使用导入的数据
|
||
incompatibleRules.value = incompatibleFoodsData as IncompatibleRule[]
|
||
}
|
||
catch (error) {
|
||
console.error('Failed to load incompatible foods data:', error)
|
||
}
|
||
finally {
|
||
isLoading.value = false
|
||
}
|
||
})
|
||
|
||
/**
|
||
* 核心检测函数:检查当前选择的食材是否存在相克组合
|
||
* @param ingredients - 当前已选的食材列表
|
||
*/
|
||
const checkIncompatibility = (ingredients: string[]) => {
|
||
// 重置警告信息
|
||
warningMessage.value = ''
|
||
|
||
// 如果食材少于2个或规则还没加载完成,无需检测
|
||
if (ingredients.length < 2 || isLoading.value) {
|
||
return
|
||
}
|
||
|
||
const foundRules: IncompatibleRule[] = []
|
||
|
||
const ingredientSet = new Set(ingredients)
|
||
|
||
for (const rule of incompatibleRules.value) {
|
||
// 检查规则中的两种食物是否都存在于我们的食材 Set 中
|
||
if (ingredientSet.has(rule.foodA) && ingredientSet.has(rule.foodB)) {
|
||
foundRules.push(rule)
|
||
}
|
||
}
|
||
|
||
// 如果找到相克组合,生成警告信息
|
||
if (foundRules.length > 0) {
|
||
if (foundRules.length === 1) {
|
||
const rule = foundRules[0]!
|
||
warningMessage.value
|
||
= `🚨 危险组合!\n`
|
||
+ `【${rule.foodA}】+ 【${rule.foodB}】= 有毒?!\n`
|
||
+ `${rule.reason}\n`
|
||
+ `换个搭配会更安全哦~`
|
||
}
|
||
else {
|
||
const warnings = foundRules.map(rule =>
|
||
`【${rule.foodA}】+ 【${rule.foodB}】(${rule.reason})\n`,
|
||
).join('')
|
||
warningMessage.value
|
||
= `🚨 发现 ${foundRules.length} 个危险组合!\n`
|
||
+ `${warnings}`
|
||
+ `建议调整搭配哦~`
|
||
}
|
||
}
|
||
}
|
||
|
||
// 计算属性:是否有警告信息
|
||
const hasWarning = computed(() => Boolean(warningMessage.value))
|
||
|
||
return {
|
||
incompatibleRules: readonly(incompatibleRules),
|
||
warningMessage: readonly(warningMessage),
|
||
hasWarning,
|
||
isLoading: readonly(isLoading),
|
||
checkIncompatibility,
|
||
}
|
||
}
|