修改样式
This commit is contained in:
@@ -1,23 +1,17 @@
|
||||
<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 recipePreviewLimit = 4;
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
@@ -29,10 +23,6 @@ function navigateTo(url: string) {
|
||||
}
|
||||
}
|
||||
|
||||
function toggleNotOpen() {
|
||||
emit("toggleNotOpen");
|
||||
}
|
||||
|
||||
async function initData() {
|
||||
if(!recipeData.value) {
|
||||
loading.value = true;
|
||||
@@ -43,13 +33,14 @@ async function initData() {
|
||||
}
|
||||
|
||||
// 获取菜谱数据
|
||||
const recipeData = ref([]);
|
||||
const recipeData = ref<any[]>([]);
|
||||
function getRecipeData() {
|
||||
appSearchSearchRecipePost({
|
||||
body: {
|
||||
params: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
}
|
||||
},
|
||||
body: {}
|
||||
}).then(res=> {
|
||||
console.log('菜谱数据', res)
|
||||
recipeData.value = res.rows;
|
||||
@@ -57,30 +48,16 @@ function getRecipeData() {
|
||||
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}`)
|
||||
}
|
||||
|
||||
function navigateToRecipeList() {
|
||||
navigateTo('/pages-user/pages/recipe/list')
|
||||
}
|
||||
|
||||
// 获取附近的菜品
|
||||
const dishData = ref([]);
|
||||
const dishData = ref<any[]>([]);
|
||||
function appMerchantDishNearbyList() {
|
||||
appMerchantDishNearbyListPost({
|
||||
params: {
|
||||
@@ -88,8 +65,8 @@ function appMerchantDishNearbyList() {
|
||||
pageSize: 10,
|
||||
},
|
||||
body: {
|
||||
lat: userStore.userLocation.latitude,
|
||||
lng: userStore.userLocation.longitude,
|
||||
lat: String(userStore.userLocation.latitude ?? ''),
|
||||
lng: String(userStore.userLocation.longitude ?? ''),
|
||||
}
|
||||
}).then(res=> {
|
||||
console.log('菜品数据', res)
|
||||
@@ -100,6 +77,27 @@ function handleClickDish(item: any) {
|
||||
navigateTo(`/pages-store/pages/store/index?id=${item.merchantId}`)
|
||||
}
|
||||
|
||||
function getMerchantName(item: any) {
|
||||
return item?.merchantVo?.merchantName || item?.merchantName||item?.dishName || '--'
|
||||
}
|
||||
|
||||
function getMerchantLogo(item: any) {
|
||||
return item?.merchantVo?.logo || item?.logo || item?.dishImage?.split?.(',')?.[0] || item?.dishImage || ''
|
||||
}
|
||||
|
||||
function getMerchantRate(item: any) {
|
||||
const rating = Number(item?.merchantVo?.rating ?? item?.rating ?? 0)
|
||||
return Number.isFinite(rating) && rating > 0 ? rating.toFixed(1) : '5.0'
|
||||
}
|
||||
|
||||
function getPreviewRecipeList() {
|
||||
return recipeData.value.slice(0, recipePreviewLimit)
|
||||
}
|
||||
|
||||
function showRecipeMore() {
|
||||
return recipeData.value.length > recipePreviewLimit
|
||||
}
|
||||
|
||||
async function getPlatformDefaultStoreInfo() {}
|
||||
|
||||
defineExpose({
|
||||
@@ -131,65 +129,57 @@ defineExpose({
|
||||
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">
|
||||
<view class="px-24rpx pt-16rpx">
|
||||
<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">
|
||||
<view class="browse-wrap px-24rpx">
|
||||
<view class="section-title mt-36rpx">{{ t("pages.browse.titleRecipes") }}</view>
|
||||
<view class="mt-28rpx">
|
||||
<scroll-view scroll-x class="recipe-scroll" :show-scrollbar="false" :enable-flex="true">
|
||||
<view class="recipe-track">
|
||||
<view
|
||||
v-for="item in getPreviewRecipeList()"
|
||||
:key="item.id"
|
||||
class="recipe-item"
|
||||
@click="navigateToRecipeDetail(item.id)"
|
||||
>
|
||||
<image
|
||||
:src="thumbnailImg(item?.recipeImage?.split(',')[0])"
|
||||
class="w-310rpx h-296rpx rounded-24rpx mb-26rpx bg-common"
|
||||
class="recipe-avatar"
|
||||
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>
|
||||
/>
|
||||
<text class="recipe-name line-clamp-1">{{ item.recipeName }}</text>
|
||||
</view>
|
||||
<view v-if="showRecipeMore()" class="recipe-more" @click="navigateToRecipeList">
|
||||
<view class="recipe-more__text-wrap">
|
||||
<text class="recipe-more__text">{{ t("pages.browse.moreRecipes") }}</text>
|
||||
</view>
|
||||
<i class="i-carbon:chevron-right recipe-more__icon"></i>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
|
||||
<view class="section-title mt-54rpx">{{ t("pages.browse.titleCuisine") }}</view>
|
||||
<scroll-view scroll-x class="store-scroll mt-28rpx pb-40rpx" :show-scrollbar="false" :enable-flex="true">
|
||||
<view class="store-track">
|
||||
<view v-for="item in dishData" :key="item.id" @click="handleClickDish(item)" class="store-card">
|
||||
<image
|
||||
:src="thumbnailImg(getMerchantLogo(item))"
|
||||
class="store-card__cover"
|
||||
mode="aspectFill"
|
||||
/>
|
||||
<view class="store-card__right">
|
||||
<view class="store-card__name line-clamp-2">{{ getMerchantName(item) }}</view>
|
||||
<view class="store-card__rating">★★★★★ {{ getMerchantRate(item) }}</view>
|
||||
<view class="store-card__brand">{{ t("pages.browse.brandTag") }}</view>
|
||||
<view class="store-card__arrow center">
|
||||
<i class="i-carbon:chevron-right text-30rpx text-white"></i>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
</view>
|
||||
</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>
|
||||
|
||||
@@ -201,4 +191,148 @@ defineExpose({
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
<style scoped lang="scss">
|
||||
.browse-wrap {
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 32rpx;
|
||||
line-height: 48rpx;
|
||||
// font-weight: 700;
|
||||
color: #1c1c1c;
|
||||
}
|
||||
|
||||
.recipe-scroll,
|
||||
.store-scroll {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.recipe-track {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 22rpx;
|
||||
padding-right: 24rpx;
|
||||
}
|
||||
|
||||
.recipe-item {
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.recipe-avatar {
|
||||
width: 112rpx;
|
||||
height: 112rpx;
|
||||
border-radius: 56rpx;
|
||||
background: #f1f1f1;
|
||||
}
|
||||
|
||||
.recipe-name {
|
||||
max-width: 140rpx;
|
||||
margin-top: 14rpx;
|
||||
text-align: center;
|
||||
font-size: 26rpx;
|
||||
line-height: 32rpx;
|
||||
color: #222;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.recipe-more {
|
||||
flex-shrink: 0;
|
||||
height: 112rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 4rpx;
|
||||
padding: 4rpx 8rpx;
|
||||
}
|
||||
|
||||
.recipe-more__text-wrap {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
gap: 6rpx;
|
||||
}
|
||||
|
||||
.recipe-more__text {
|
||||
font-size: 24rpx;
|
||||
line-height: 28rpx;
|
||||
color: #8a8a8a;
|
||||
font-weight: 500;
|
||||
writing-mode: vertical-rl;
|
||||
text-orientation: upright;
|
||||
letter-spacing: 2rpx;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.recipe-more__icon {
|
||||
font-size: 20rpx;
|
||||
color: #8a8a8a;
|
||||
}
|
||||
|
||||
.store-track {
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
gap: 22rpx;
|
||||
padding-right: 24rpx;
|
||||
}
|
||||
|
||||
.store-card {
|
||||
width: 404rpx;
|
||||
height: 220rpx;
|
||||
border-radius: 20rpx;
|
||||
overflow: hidden;
|
||||
background: #fff;
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.06);
|
||||
}
|
||||
|
||||
.store-card__cover {
|
||||
width: 184rpx;
|
||||
height: 220rpx;
|
||||
background: #f2f2f2;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.store-card__right {
|
||||
flex: 1;
|
||||
padding: 16rpx 14rpx 14rpx 16rpx;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.store-card__name {
|
||||
font-size: 28rpx;
|
||||
line-height: 34rpx;
|
||||
color: #191919;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.store-card__rating {
|
||||
margin-top: 8rpx;
|
||||
color: #111;
|
||||
font-size: 26rpx;
|
||||
line-height: 30rpx;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.store-card__brand {
|
||||
margin-top: 12rpx;
|
||||
color: #d39a48;
|
||||
font-size: 24rpx;
|
||||
line-height: 28rpx;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.store-card__arrow {
|
||||
position: absolute;
|
||||
right: 10rpx;
|
||||
bottom: 12rpx;
|
||||
width: 52rpx;
|
||||
height: 52rpx;
|
||||
border-radius: 50%;
|
||||
background: #111;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user