1
0
mirror of synced 2025-12-07 22:08:17 +08:00
Files
cook/app/components/ChooseFood.vue
2025-10-06 18:43:58 +08:00

181 lines
4.9 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script lang="ts" setup>
import type { StuffItem } from '~/types'
import { storeToRefs } from 'pinia'
import { useEmojiAnimation } from '~/composables/animation'
import { useIncompatibleFoods } from '~/composables/incompatible-foods'
import { meat, staple, tools, vegetable } from '~/data/food'
const rStore = useRecipeStore()
const { curTool } = storeToRefs(rStore)
const curStuff = computed(() => rStore.selectedStuff)
// 食物相克检测
const { warningMessage, hasWarning, checkIncompatibility } = useIncompatibleFoods()
const recipeBtnRef = ref<HTMLButtonElement>()
const { playAnimation } = useEmojiAnimation(recipeBtnRef)
const { proxy } = useScriptGoogleTagManager()
const recipePanelRef = ref()
// 监听食材变化,自动检测相克
watch(curStuff, (newIngredients) => {
checkIncompatibility(newIngredients)
}, { deep: true })
// 页面初始化时也检查一次(处理已有选择的情况)
onMounted(() => {
if (curStuff.value.length > 0) {
checkIncompatibility(curStuff.value)
}
})
function toggleStuff(item: StuffItem, category = '', _e?: Event) {
rStore.toggleStuff(item.name)
if (curStuff.value.includes(item.name))
playAnimation(item.emoji)
proxy.dataLayer.push({
event: 'click',
category: `${category}_${item.name}`,
action: 'click_stuff',
label: '食材',
})
proxy.dataLayer.push({
event: 'click_stuff',
action: item.name,
})
}
</script>
<template>
<div>
<h2 m="t-4" text="xl" font="bold" p="1">
🥘 先选一下食材
</h2>
<!-- 食物相克警告提示 -->
<ion-toast
class="incompatible-warning-toast"
:message="warningMessage"
:is-open="hasWarning"
position="top"
:icon="ioniconsWarningOutline"
animated
>
<div
v-if="hasWarning"
class="incompatible-warning-box"
m="b-4" p="4"
border="~ 2 red-300 dark:red-600 rounded-xl"
text="red-800 dark:red-200 sm"
shadow="lg"
relative="~"
overflow="hidden"
>
<div flex="~ items-start gap-3">
<div text="2xl" flex="shrink-0" class="animate-pulse">
🚨
</div>
<div flex="1 col gap-1">
<div font="bold" text="base">
食物相克警告
</div>
<div leading="relaxed" whitespace="pre-line">
{{ warningMessage }}
</div>
</div>
</div>
</div>
</ion-toast>
<div>
<h2 opacity="90" text="base" font="bold" p="1">
🥬 菜菜们
</h2>
<div>
<VegetableTag
v-for="item, i in vegetable" :key="i"
:active="curStuff.includes(item.name)"
@click="toggleStuff(item, 'vegetable')"
>
<span v-if="item.emoji" class="inline-flex">{{ item.emoji }}</span>
<span v-else-if="item.image" class="inline-flex">
<img class="inline-flex" w="2" h="2" width="10" height="10" :src="item.image" :alt="item.name">
</span>
<span class="inline-flex" m="l-1">{{ item.name }}</span>
</VegetableTag>
</div>
</div>
<div m="y-4">
<h2 opacity="90" text="base" font="bold" p="1">
🥩 肉肉们
</h2>
<div>
<MeatTag
v-for="item, i in meat" :key="i"
:active="curStuff.includes(item.name)"
@click="toggleStuff(item, 'meat')"
>
<span>{{ item.emoji }}</span>
<span m="l-1">{{ item.name }}</span>
</MeatTag>
</div>
</div>
<div m="y-4">
<h2 opacity="90" text="base" font="bold" p="1">
🍚 主食也要一起下锅吗不选也行
</h2>
<div>
<StapleTag
v-for="item, i in staple" :key="i"
:active="curStuff.includes(item.name)"
@click="toggleStuff(item, 'staple')"
>
<span>{{ item.emoji }}</span>
<span m="l-1">{{ item.name }}</span>
</StapleTag>
</div>
</div>
<div m="t-4">
<h2 text="xl" font="bold" p="1">
🍳 再选一下厨具
</h2>
<div>
<ToolTag
v-for="item, i in tools" :key="i"
:active="curTool === item.name"
@click="rStore.clickTool(item)"
>
<span v-if="item.emoji" class="inline-flex">
{{ item.emoji }}
</span>
<span v-else-if="item.icon" class="inline-flex">
<div :class="item.icon" />
</span>
<span class="inline-flex" m="l-1">{{ item.label || item.name }}</span>
</ToolTag>
</div>
</div>
<RecipePanel ref="recipePanelRef" />
</div>
<Transition>
<BasketButton ref="recipeBtnRef" />
</Transition>
</template>
<style>
ion-toast.incompatible-warning-toast {
/* --background: #f4f4fa; */
--box-shadow: 3px 3px 10px 0 rgba(0, 0, 0, 0.2);
/* --color: #4b4a50; */
--background: rgba(254, 202, 202, 0.95);
--color: #7f1d1d;
}
</style>