Files
cheflinkuser/src/pages/home/components/tabbar-browse/tabbar-browse.vue
T
2026-02-26 09:32:03 +08:00

205 lines
5.8 KiB
Vue

<script setup lang="ts">
import useEventEmit from "@/hooks/useEventEmit";
import {CollectionType, EventEnum} from "@/constant/enums";
import { debounce } from 'throttle-debounce'
import Search from "../tabbar-home/components/search.vue";
import { useConfigStore, useUserStore } from "@/store";
import MsgBox from "../tabbar-home/components/msg-box.vue";
import Collection from "@/components/collection/index.vue";
import BrowseSkeleton from "./components/browse-skeleton.vue";
import {
appMerchantDishNearbyListPost,
appSearchSearchRecipePost,
appCollectCollectPost,
} from "@/service";
import {thumbnailImg} from "@/utils/utils";
const configStore = useConfigStore();
const userStore = useUserStore();
const emit = defineEmits(["toggleNotOpen"]);
const loading = ref(false);
const { t } = useI18n();
function navigateTo(url: string) {
if(userStore.checkLogin()) {
uni.navigateTo({
url,
});
}
}
function toggleNotOpen() {
emit("toggleNotOpen");
}
async function initData() {
if(!recipeData.value) {
loading.value = true;
}
getRecipeData()
// 获取菜品数据
appMerchantDishNearbyList()
}
// 获取菜谱数据
const recipeData = ref([]);
function getRecipeData() {
appSearchSearchRecipePost({
body: {
pageNum: 1,
pageSize: 10,
}
}).then(res=> {
console.log('菜谱数据', res)
recipeData.value = res.rows;
}).finally(()=> {
loading.value = false;
})
}
// 收藏菜品
function handleSubmitCollectRecipe(item: any) {
collectRecipe(item)
}
// 防抖处理函数
const collectRecipe = debounce(1000, (item: any) => {
appCollectCollectPost({
body: {
targetId: item.id,
targetType: CollectionType.RECIPE
}
}).then(res=> {
item.isCollect = !item.isCollect;
})
}, {
atBegin: true, // 立即触发
});
function navigateToRecipeDetail(id: string | number) {
navigateTo(`/pages-user/pages/recipe/index?id=${id}`)
}
// 获取附近的菜品
const dishData = ref([]);
function appMerchantDishNearbyList() {
appMerchantDishNearbyListPost({
params: {
pageNum: 1,
pageSize: 10,
},
body: {
lat: userStore.userLocation.latitude,
lng: userStore.userLocation.longitude,
}
}).then(res=> {
console.log('菜品数据', res)
dishData.value = res.rows;
})
}
function handleClickDish(item: any) {
navigateTo(`/pages-store/pages/store/index?id=${item.merchantId}`)
}
async function getPlatformDefaultStoreInfo() {}
defineExpose({
initData,
init: getPlatformDefaultStoreInfo,
});
</script>
<template>
<view
class="bg-#fff"
:style="[
{
height: configStore.windowHeight + 'px',
},
]"
>
<z-paging ref="paging">
<template #top>
<status-bar />
</template>
<view
v-show="loading"
class="animate-in fade-in animate-ease-out animate-duration-300"
>
<browse-skeleton />
</view>
<view
v-show="!loading"
class="animate-in fade-in animate-ease-in animate-duration-300"
>
<view class="flex-center-sb px-30rpx pt-16rpx">
<view class="text-56rpx text-#333 lh-56rpx font-bold">{{
t("tabBar.browse")
}}</view>
<msg-box @toggleNotOpen="toggleNotOpen" />
</view>
<view class="px-30rpx mt-44rpx">
<search />
</view>
<view class="mt-50rpx px-30rpx">
<view @click="navigateTo('/pages-user/pages/recipe/list')" class="flex-center-sb">
<text class="text-36rpx lh-36rpx text-#333 font-bold">{{
t("pages.browse.titleRecipes")
}}</text>
<image src="@img/chef/116.png" class="w-64rpx h-64rpx"></image>
</view>
<scroll-view scroll-x="true" class="mt-16rpx">
<view class="flex gap-30rpx">
<template v-for="item in recipeData">
<view @click="navigateToRecipeDetail(item.id)" class="w-312rpx">
<image
:src="thumbnailImg(item?.recipeImage?.split(',')[0])"
class="w-310rpx h-296rpx rounded-24rpx mb-26rpx bg-common"
mode="aspectFill"
></image>
<view class="flex-center-sb">
<text class="text-30rpx lh-30rpx text-#333 line-clamp-1 tracking-[.04em] font-500"
>{{ item.recipeName }}</text
>
<view class="w-40rpx h-40rpx ml-14rpx shrink-0">
<collection
:is-collected="item.isCollect"
@collectionChange="handleSubmitCollectRecipe(item)"
/>
</view>
</view>
</view>
</template>
</view>
</scroll-view>
<view
class="mt-50rpx mb-28rpx text-36rpx lh-36rpx text-#333 font-bold"
>{{ t("pages.browse.titleCuisine") }}</view
>
<view class="grid grid-cols-2 gap-x-30rpx gap-y-46rpx pb-40rpx">
<template v-for="item in dishData">
<view @click="handleClickDish(item)" class="w-330rpx overflow-hidden">
<image
:src="thumbnailImg(item?.dishImage?.split(',')[0])"
class="w-full h-186rpx rounded-24rpx mb-16rpx bg-common"
mode="aspectFill"
></image>
<text class="text-30rpx lh-30rpx text-#333 line-clamp-1 tracking-[.04em] font-500"
>{{ item.dishName }}</text
>
</view>
</template>
</view>
</view>
</view>
<template #bottom>
<view class="h-50px"></view>
<view :style="[configStore.iosSafeBottomPlaceholder]"></view>
</template>
</z-paging>
</view>
</template>
<style scoped lang="scss"></style>