first commit
This commit is contained in:
@@ -0,0 +1,703 @@
|
||||
<script setup lang="ts">
|
||||
import { debounce } from 'throttle-debounce'
|
||||
import dayjs from 'dayjs'
|
||||
import Config from '@/config/index'
|
||||
const { t } = useI18n();
|
||||
import StoreSkeleton from './components/store-skeleton.vue';
|
||||
import { useScrollThreshold } from '@/hooks/useScrollThreshold'
|
||||
import {
|
||||
appCollectCollectPost, appMerchantCartCalculateSavingsPost, appMerchantCartListByMerchantIdPost,
|
||||
appMerchantDetailMerchantIdGet,
|
||||
appMerchantMenuMenuListByUserPost, type MerchantCartVo,
|
||||
type MerchantVo
|
||||
} from "@/service";
|
||||
import {CollectionType} from "@/constant/enums";
|
||||
import {useUserStore} from "@/store";
|
||||
import { parseBusinessHoursUtils, getDistanceInMiles } from "@/utils/utils";
|
||||
import CouponPopup from './components/coupon-popup.vue'
|
||||
import {getMerchantCouponReceiveListApi} from "@/pages-user/service";
|
||||
// import type { MerchantVo } from '@/service/types'
|
||||
// 页面加载状态
|
||||
const loading = ref(true);
|
||||
const userStore = useUserStore();
|
||||
|
||||
const storeID = ref('')
|
||||
onLoad((options: any)=> {
|
||||
console.log(options)
|
||||
if(options.id) {
|
||||
storeID.value = options.id
|
||||
getStoreDetail()
|
||||
// getMenuList()
|
||||
}
|
||||
})
|
||||
|
||||
// 定时器用于更新闭店提示
|
||||
let closingTimer: NodeJS.Timeout | null = null
|
||||
|
||||
// 启动闭店提示定时器
|
||||
function startClosingTimer() {
|
||||
if (closingTimer) {
|
||||
clearInterval(closingTimer)
|
||||
}
|
||||
|
||||
closingTimer = setInterval(() => {
|
||||
if (storeDetail.value.businessHours) {
|
||||
closingInfo.value = parseBusinessHours(storeDetail.value.businessHours)
|
||||
// 如果不再显示提示,清除定时器
|
||||
if (!closingInfo.value.show) {
|
||||
clearInterval(closingTimer!)
|
||||
closingTimer = null
|
||||
}
|
||||
}
|
||||
}, 60000) // 每分钟更新一次
|
||||
}
|
||||
|
||||
// 停止闭店提示定时器
|
||||
function stopClosingTimer() {
|
||||
if (closingTimer) {
|
||||
clearInterval(closingTimer)
|
||||
closingTimer = null
|
||||
}
|
||||
}
|
||||
|
||||
onShow(()=> {
|
||||
nextTick(()=> {
|
||||
if(storeID.value) {
|
||||
// 查询当前店铺购物车信息
|
||||
getCartInfo()
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
// 页面卸载时清除定时器
|
||||
onUnmounted(() => {
|
||||
stopClosingTimer()
|
||||
})
|
||||
|
||||
// 获取商家详情信息
|
||||
const storeDetail = ref<MerchantVo>({})
|
||||
// 闭店提示信息
|
||||
const closingInfo = ref({ show: false, minutes: 0 })
|
||||
|
||||
// 解析营业时间并判断是否在闭店前30分钟
|
||||
function parseBusinessHours(businessHours: string) {
|
||||
if (!businessHours) return { show: false, minutes: 0 }
|
||||
|
||||
const now = dayjs()
|
||||
const currentDay = now.day() // 0=Sunday, 1=Monday, ..., 6=Saturday
|
||||
const dayNames = [t('pages-store.store.weekdays.sunday'), t('pages-store.store.weekdays.monday'), t('pages-store.store.weekdays.tuesday'), t('pages-store.store.weekdays.wednesday'), t('pages-store.store.weekdays.thursday'), t('pages-store.store.weekdays.friday'), t('pages-store.store.weekdays.saturday')]
|
||||
const todayName = dayNames[currentDay]
|
||||
|
||||
// 检查今天是否营业
|
||||
if (!businessHours.includes(todayName)) {
|
||||
return { show: false, minutes: 0 }
|
||||
}
|
||||
|
||||
// 提取时间范围,格式如:05:00-16:00
|
||||
const timeMatch = businessHours.match(/(\d{2}):(\d{2})-(\d{2}):(\d{2})/)
|
||||
if (!timeMatch) {
|
||||
return { show: false, minutes: 0 }
|
||||
}
|
||||
|
||||
const [, startHour, startMin, endHour, endMin] = timeMatch
|
||||
|
||||
// 使用dayjs创建今天的开店和闭店时间
|
||||
const openTime = now.hour(parseInt(startHour)).minute(parseInt(startMin)).second(0)
|
||||
const closeTime = now.hour(parseInt(endHour)).minute(parseInt(endMin)).second(0)
|
||||
|
||||
// 如果闭店时间小于开店时间,说明跨天营业,闭店时间应该是明天
|
||||
const actualCloseTime = closeTime.isBefore(openTime) ? closeTime.add(1, 'day') : closeTime
|
||||
|
||||
// 检查是否在营业时间内
|
||||
const isOpen = now.isAfter(openTime) && now.isBefore(actualCloseTime)
|
||||
|
||||
if (!isOpen) {
|
||||
return { show: false, minutes: 0 }
|
||||
}
|
||||
|
||||
// 计算闭店前30分钟的时间点
|
||||
const thirtyMinsBefore = actualCloseTime.subtract(30, 'minute')
|
||||
|
||||
// 判断是否在闭店前30分钟内
|
||||
if (now.isAfter(thirtyMinsBefore) && now.isBefore(actualCloseTime)) {
|
||||
const minutesLeft = actualCloseTime.diff(now, 'minute')
|
||||
return { show: true, minutes: minutesLeft }
|
||||
}
|
||||
|
||||
return { show: false, minutes: 0 }
|
||||
}
|
||||
|
||||
const storeDistance = ref(null)
|
||||
function getStoreDetail() {
|
||||
loading.value = true
|
||||
appMerchantDetailMerchantIdGet({
|
||||
params: {
|
||||
merchantId: storeID.value,
|
||||
}
|
||||
}).then((res: any) => {
|
||||
console.log('商家详情', res)
|
||||
storeDetail.value = res.data as MerchantVo
|
||||
|
||||
getMerchantCouponReceiveList()
|
||||
|
||||
// 解析营业时间并判断闭店提示
|
||||
if (res.data.businessHours) {
|
||||
closingInfo.value = parseBusinessHours(res.data.businessHours)
|
||||
// 如果需要显示闭店提示,启动定时器
|
||||
if (closingInfo.value.show) {
|
||||
startClosingTimer()
|
||||
}
|
||||
}
|
||||
|
||||
if(res.data.merchantMenuVoList && res.data.merchantMenuVoList.length > 0) {
|
||||
tabs.value = res.data.merchantMenuVoList.map((item) => {
|
||||
return {
|
||||
title: item.menuName,
|
||||
key: item.id
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 商户的经纬度存在,并且用户的经纬度也存在
|
||||
if(res.data.latitude && res.data.longitude && userStore.userLocation.latitude && userStore.userLocation.longitude) {
|
||||
let distance = getDistanceInMiles(res.data.latitude, res.data.longitude, userStore.userLocation.latitude, userStore.userLocation.longitude)
|
||||
console.log('距离商家距离', distance)
|
||||
storeDistance.value = distance
|
||||
}
|
||||
|
||||
// 判断配送和自取的开通状态
|
||||
const hasDelivery = +storeDetail.value.deliveryService === 1
|
||||
const hasPickup = +storeDetail.value.selfPickup === 1
|
||||
|
||||
if (!hasDelivery && !hasPickup) {
|
||||
// 两个都没开通,不显示切换组件
|
||||
showDeliverySwitch.value = false
|
||||
} else if (!hasDelivery && hasPickup) {
|
||||
// 只开通自取,默认选中自取
|
||||
deliveryMethod.value = 1
|
||||
showDeliverySwitch.value = true
|
||||
} else if (hasDelivery && !hasPickup) {
|
||||
// 只开通配送,默认选中配送
|
||||
deliveryMethod.value = 0
|
||||
showDeliverySwitch.value = true
|
||||
} else {
|
||||
// 两个都开通,默认选中配送
|
||||
deliveryMethod.value = 0
|
||||
showDeliverySwitch.value = true
|
||||
}
|
||||
|
||||
|
||||
}).catch((error) => {
|
||||
console.error('获取商家详情失败:', error);
|
||||
}).finally(()=> {
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
|
||||
const storeCouponList = ref([])
|
||||
function getMerchantCouponReceiveList() {
|
||||
getMerchantCouponReceiveListApi(storeID.value).then((res: any)=> {
|
||||
console.log('商家优惠券列表', res)
|
||||
storeCouponList.value = res.data
|
||||
})
|
||||
}
|
||||
|
||||
const cartDataList = ref<MerchantCartVo[]>([])
|
||||
function getCartInfo() {
|
||||
if(!userStore.isLogin) return
|
||||
appMerchantCartListByMerchantIdPost({
|
||||
params: {
|
||||
merchantId: storeID.value,
|
||||
}
|
||||
}).then((res: any)=> {
|
||||
console.log('购物车列表', res)
|
||||
cartDataList.value = res.data
|
||||
|
||||
// 购物车有菜品,查询菜品会员折扣价
|
||||
if(cartDataList.value.length > 0) {
|
||||
appMerchantCartCalculateSavings()
|
||||
}
|
||||
})
|
||||
}
|
||||
// 查询菜品会员折扣价
|
||||
const cartSavingsData = ref({})
|
||||
function appMerchantCartCalculateSavings() {
|
||||
appMerchantCartCalculateSavingsPost({
|
||||
body: cartDataList.value.map(item => item.id)
|
||||
}).then(res=> {
|
||||
console.log('菜品会员折扣价', res)
|
||||
cartSavingsData.value = res.data
|
||||
})
|
||||
}
|
||||
|
||||
// 优惠券列表(静态数据)
|
||||
const couponList = ref([
|
||||
{ id: 1, text: '20% Off' },
|
||||
{ id: 2, text: '30% Off' },
|
||||
{ id: 3, text: '$5 Off' },
|
||||
{ id: 4, text: '40% Off' },
|
||||
])
|
||||
|
||||
// 跳转到优惠券页面
|
||||
const couponPopupRef = ref()
|
||||
function handleClaimNow() {
|
||||
couponPopupRef.value.init()
|
||||
}
|
||||
|
||||
|
||||
// 用户查询菜单列表
|
||||
function getMenuList() {
|
||||
appMerchantMenuMenuListByUserPost({
|
||||
params: {
|
||||
merchantId: storeID.value,
|
||||
}
|
||||
}).then(res=> {
|
||||
console.log('商家菜单列表', res)
|
||||
// 这里可以处理商家菜单列表数据
|
||||
}).catch(error => {
|
||||
console.error('获取商家菜单列表失败:', error);
|
||||
})
|
||||
}
|
||||
|
||||
// 配送方式
|
||||
const deliveryMethod = ref(0);
|
||||
const deliveryMethodOptions = [t('pages-store.store.delivery'), t('pages-store.store.pickup')];
|
||||
const showDeliverySwitch = ref(true); // 是否显示配送方式切换组件
|
||||
function handleClickSegmented(index: number) {
|
||||
console.log("切换配送方式:", index);
|
||||
if(+storeDetail.value.deliveryService !== 1 && index === 0) {
|
||||
uni.showToast({
|
||||
title: t('pages-store.store.toast.deliveryService'),
|
||||
icon: 'none'
|
||||
})
|
||||
return
|
||||
}
|
||||
if(+storeDetail.value.selfPickup !== 1 && index === 1) {
|
||||
uni.showToast({
|
||||
title: t('pages-store.store.toast.selfPickup'),
|
||||
icon: 'none'
|
||||
})
|
||||
return
|
||||
}
|
||||
deliveryMethod.value = index
|
||||
}
|
||||
|
||||
const activeTab = ref(0);
|
||||
const tabs = ref([]);
|
||||
|
||||
const showStatusBar = useScrollThreshold()
|
||||
onPageScroll((e) => {
|
||||
uni.$emit('page-scroll', e)
|
||||
})
|
||||
|
||||
function navigateToDishes(item: any) {
|
||||
uni.navigateTo({
|
||||
url: '/pages-store/pages/store/dishes?id=' + item.id + '&storeId=' + storeID.value,
|
||||
})
|
||||
}
|
||||
function navigateBack() {
|
||||
uni.navigateBack({
|
||||
delta: 1,
|
||||
})
|
||||
}
|
||||
|
||||
function navigateToCart() {
|
||||
uni.navigateTo({
|
||||
url:
|
||||
'/pages-user/pages/cart/store-cart'
|
||||
+ '?storeId=' + storeID.value
|
||||
+ '&storeName=' + encodeURIComponent(storeDetail.value.merchantName),
|
||||
})
|
||||
}
|
||||
|
||||
// 收藏店铺
|
||||
function handleCollectionClick() {
|
||||
debouncedEmit(storeDetail.value.isCollect, storeDetail.value.id, CollectionType.STORE, ()=> {
|
||||
storeDetail.value.isCollect = !storeDetail.value.isCollect
|
||||
})
|
||||
}
|
||||
// 收藏菜品
|
||||
function handleDishCollectionClick(item: any) {
|
||||
debouncedEmit(item.isCollect, item.id, CollectionType.DISH, ()=> {
|
||||
item.isCollect = !item.isCollect
|
||||
})
|
||||
}
|
||||
// 防抖处理函数
|
||||
const debouncedEmit = debounce(1300, (isCollected: boolean, id: string, type: CollectionType, callback: ()=> void) => {
|
||||
// 收藏接口
|
||||
appCollectCollectPost({
|
||||
body: {
|
||||
targetId: id,
|
||||
targetType: type
|
||||
}
|
||||
}).then(res=> {
|
||||
callback()
|
||||
})
|
||||
}, {
|
||||
atBegin: true, // 立即触发
|
||||
})
|
||||
|
||||
function navigateTo(url: string) {
|
||||
uni.navigateTo({ url })
|
||||
}
|
||||
|
||||
// 分享商家
|
||||
function handleShare() {
|
||||
uni.shareWithSystem({
|
||||
summary: '',
|
||||
href: `${Config.shareLink}pages-store/pages/store/index?id=${storeID.value}`,
|
||||
success(){
|
||||
// 分享完成,请注意此时不一定是成功分享
|
||||
},
|
||||
fail(){
|
||||
// 分享失败
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<view
|
||||
class="animate-in fade-in animate-ease-out animate-duration-300"
|
||||
v-show="loading"
|
||||
>
|
||||
<!-- 骨架屏 -->
|
||||
<StoreSkeleton/>
|
||||
</view>
|
||||
<view
|
||||
class="animate-in fade-in animate-ease-in animate-duration-300"
|
||||
v-if="!loading"
|
||||
>
|
||||
<!-- 页面内容 -->
|
||||
<view class="store-box">
|
||||
<view class="relative">
|
||||
<!-- 状态栏 -->
|
||||
<view class="fixed top-0 left-0 z-9 w-full transition-all pt-6rpx" :class="[showStatusBar ? 'bg-#fff' : '']">
|
||||
<status-bar />
|
||||
<view class="flex-center-sb px-30rpx">
|
||||
<image
|
||||
@click="navigateBack"
|
||||
src="@img/chef/1327.png"
|
||||
mode="aspectFill"
|
||||
class="w-48rpx h-48rpx relative z-1"
|
||||
/>
|
||||
<view class="flex items-center">
|
||||
<image
|
||||
@click="navigateTo('/pages-store/pages/store/search/index?id=' + storeID)"
|
||||
src="@img-store/1333.png"
|
||||
mode="aspectFill"
|
||||
class="w-68rpx h-68rpx relative z-1 mr-20rpx"
|
||||
/>
|
||||
<view @click="handleCollectionClick" class="w-68rpx h-68rpx relative z-1 mr-20rpx">
|
||||
<image
|
||||
v-if="!storeDetail?.isCollect"
|
||||
src="@img-store/1334.png"
|
||||
mode="aspectFill"
|
||||
class="w-68rpx h-68rpx"
|
||||
/>
|
||||
<image
|
||||
v-else
|
||||
src="@img-store/1337.png"
|
||||
mode="aspectFill"
|
||||
class="w-68rpx h-68rpx"
|
||||
/>
|
||||
</view>
|
||||
<image
|
||||
@click="handleShare"
|
||||
src="@img-store/1335.png"
|
||||
mode="aspectFill"
|
||||
class="w-68rpx h-68rpx relative z-1"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="anchors"></view>
|
||||
<!-- 主图 -->
|
||||
<!-- <image-->
|
||||
<!-- :src="storeDetail?.shopImages?.split(',')[0]"-->
|
||||
<!-- mode="aspectFill"-->
|
||||
<!-- class="w-750rpx h-562rpx absolute top-0 left-0"-->
|
||||
<!-- />-->
|
||||
<status-bar />
|
||||
<wd-swiper class="bg-common" v-if="storeDetail && storeDetail?.shopImages?.split(',').length > 0" :list="storeDetail?.shopImages?.split(',')" height="562rpx" autoplay></wd-swiper>
|
||||
</view>
|
||||
|
||||
<view class="px-30rpx pt-40rpx pb-42rpx">
|
||||
<!-- 店铺信息 -->
|
||||
<view class="text-center">
|
||||
<view class="text-center text-40rpx lh-40rpx text-#333 font-bold">
|
||||
{{ storeDetail?.merchantName }}
|
||||
</view>
|
||||
<view class="center text-24rpx lh-24rpx my-16rpx">
|
||||
<view class="flex items-center">
|
||||
<text class="text-#333 font-500">{{ storeDetail?.rating }}</text>
|
||||
<image
|
||||
src="@img/chef/124.png"
|
||||
class="w-24rpx h-24rpx mx-4rpx"
|
||||
></image>
|
||||
<text class="text-#7D7D7D">({{ storeDetail?.commentCount }})</text>
|
||||
</view>
|
||||
<view class="flex items-center text-#CE7138 px-10rpx">
|
||||
<image
|
||||
src="@img-store/1339.png"
|
||||
class="w-24rpx h-24rpx mr-4rpx"
|
||||
></image>
|
||||
CHEFLINK
|
||||
</view>
|
||||
<text v-if="+storeDetail?.deliveryService === 1" class="text-#7D7D7D"> • {{ storeDetail?.deliveryTime }} {{ t('common.minutes') }}</text>
|
||||
</view>
|
||||
<view class="text-24rpx lh-24rpx text-#7D7D7D text-center mt-16rpx">
|
||||
{{ t('pages-store.store.title') }} US${{ storeDetail?.minOrderPrice }}
|
||||
</view>
|
||||
<!--根据商家营业时间计算处理-->
|
||||
<view class="text-24rpx lh-24rpx text-#7D7D7D text-center mt-16rpx">
|
||||
<template v-if="closingInfo.show">
|
||||
{{ t('pages-store.store.tips') }} {{ closingInfo.minutes }} {{ t('pages-store.store.tips1') }}
|
||||
</template>
|
||||
<template v-else>
|
||||
{{ parseBusinessHoursUtils(storeDetail?.businessHours) }}
|
||||
</template>
|
||||
<text v-if="storeDistance" class="ml-10rpx">
|
||||
{{ t('common.distance') }} {{ storeDistance }} {{ t('common.mile') }}
|
||||
</text>
|
||||
</view>
|
||||
<text v-if="storeDetail?.totalOrderCount > 0" class="mt-16rpx h-48rpx bg-#00A76D/18 rounded-8rpx px-22rpx mx-auto text-24rpx lh-24rpx text-#00A76D mr-20rpx">
|
||||
{{ t('common.sales') }} :{{ storeDetail?.totalOrderCount }}
|
||||
</text>
|
||||
<text v-if="storeDetail?.reorderedCount > 0" class="mt-16rpx h-48rpx bg-#00A76D/18 rounded-8rpx px-22rpx mx-auto text-24rpx lh-24rpx text-#00A76D">
|
||||
{{ storeDetail?.reorderedCount }} {{ t('pages-store.store.tips2') }}
|
||||
</text>
|
||||
</view>
|
||||
|
||||
<!-- 新功能插入区域 start -->
|
||||
<!-- 商家优惠券 -->
|
||||
<view class="py-24rpx mt-40rpx border-top border-bottom" v-if="storeCouponList.length">
|
||||
<view class="flex items-center justify-between mb-24rpx">
|
||||
<text class="text-28rpx lh-28rpx font-500 text-#333">{{ t('pages-store.store.merchantDiscounts') }}</text>
|
||||
<view @click="handleClaimNow" class="flex items-center">
|
||||
<text class="text-28rpx lh-28rpx font-500 text-#CE7138 mr-8rpx">{{ t('pages-store.store.claimNow') }}</text>
|
||||
<i class="i-carbon:chevron-right text-24rpx text-#CE7138"></i>
|
||||
</view>
|
||||
</view>
|
||||
<scroll-view
|
||||
scroll-x
|
||||
class="coupon-scroll"
|
||||
:show-scrollbar="false"
|
||||
enable-flex
|
||||
>
|
||||
<view class="coupon-container">
|
||||
<view
|
||||
v-for="(coupon, index) in storeCouponList"
|
||||
:key="coupon.id || index"
|
||||
class="coupon-item"
|
||||
>
|
||||
<view class="coupon-tag">
|
||||
<text class="coupon-text">{{ coupon.nameZh }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
<!-- 新功能插入区域 end -->
|
||||
|
||||
<!-- 自取 配送切换 -->
|
||||
<!-- <view v-if="showDeliverySwitch" class="w-318rpx mt-40rpx">
|
||||
<l-segmented :value="deliveryMethod" :options="deliveryMethodOptions" @click="handleClickSegmented" shape="round" bg-color="#F2F2F2" active-color="#333" />
|
||||
</view> -->
|
||||
<view v-if="showDeliverySwitch" class="border-#D8D8D8 border-solid border-1px rounded-20rpx min-h-164rpx mt-36rpx px-45rpx py-18rpx text-24rpx lh-24rpx flex-center-sb">
|
||||
<template v-if="+storeDetail?.deliveryService === 1 && deliveryMethod === 0">
|
||||
<view class="w-full h-full flex-1 text-center text-#CE7138 pr-44rpx">
|
||||
<view>{{ t('pages-store.store.tips4') }} ${{ storeDetail?.minOrderPrice }}</view>
|
||||
<view>{{ t('pages-store.store.tips5') }} ${{ storeDetail?.deliveryFee }}</view>
|
||||
</view>
|
||||
<view class="h-128rpx w-1rpx rotate-0 bg-#D8D8D8"></view>
|
||||
<view class="w-full flex-1 center flex-col pl-44rpx">
|
||||
<view class="text-#333 mb-8rpx">{{ storeDetail?.deliveryTime }} {{ t('common.minutes') }}</view>
|
||||
<view class="text-#7D7D7D">{{ t('pages-store.store.earTime') }}</view>
|
||||
</view>
|
||||
</template>
|
||||
<template v-if="+storeDetail?.selfPickup === 1 && deliveryMethod === 1">
|
||||
<view class="w-full h-full flex-1 text-center text-#CE7138 pr-44rpx">
|
||||
<view v-if="cartDataList.length > 0 && cartSavingsData && cartSavingsData.savings > 0">
|
||||
{{ t('pages-store.store.use') }} {{ Config.appName }} {{ t('pages-store.store.tips3') }} ${{ cartSavingsData.savings }} {{ t('pages-store.store.discount') }}
|
||||
</view>
|
||||
<view v-else class="">--</view>
|
||||
</view>
|
||||
<view class="h-128rpx w-1rpx rotate-0 bg-#D8D8D8"></view>
|
||||
<view class="w-full flex-1 center flex-col pl-44rpx">
|
||||
<view class="text-#333 mb-8rpx">{{ storeDetail?.pickupTime }}{{ t('common.minutes') }}</view>
|
||||
<view class="text-#7D7D7D">{{ t('pages-store.store.earTime') }}</view>
|
||||
</view>
|
||||
</template>
|
||||
</view>
|
||||
</view>
|
||||
<wd-tabs v-model="activeTab" slidable="always" autoLineWidth>
|
||||
<block v-for="item in tabs" :key="item">
|
||||
<wd-tab :title="item.title">
|
||||
</wd-tab>
|
||||
</block>
|
||||
</wd-tabs>
|
||||
<view class="box mt--6px"></view>
|
||||
|
||||
<view v-if="tabs.length > 0" class="px-30rpx pb-120rpx">
|
||||
<view v-if="storeDetail?.merchantMenuVoList[activeTab]?.dishList.length > 0" class="text-40rpx lh-40rpx font-500 my-36rpx">{{ t('pages-store.store.recommend') }}</view>
|
||||
<view v-if="storeDetail?.merchantMenuVoList[activeTab]?.dishList.length > 0" class="grid grid-cols-2 gap-30rpx">
|
||||
<template v-for="item in storeDetail?.merchantMenuVoList[activeTab]?.dishList">
|
||||
<view @click="navigateToDishes(item)" class="w-100% mb-10rpx">
|
||||
<view class="relative h-248rpx rounded-24rpx mb-28rpx">
|
||||
<view @click.stop="handleDishCollectionClick(item)" class="w-68rpx h-68rpx absolute z-2 top-0 right-0">
|
||||
<image
|
||||
v-if="!item.isCollect"
|
||||
src="@img-store/1334.png"
|
||||
mode="aspectFill"
|
||||
class="w-full h-full"
|
||||
/>
|
||||
<image
|
||||
v-else
|
||||
src="@img-store/1337.png"
|
||||
mode="aspectFill"
|
||||
class="w-full h-full"
|
||||
/>
|
||||
</view>
|
||||
<image
|
||||
:src="item?.dishImage?.split(',')[0]"
|
||||
mode="aspectFill"
|
||||
class="w-full h-full rounded-24rpx bg-common"
|
||||
/>
|
||||
</view>
|
||||
<view class="line-clamp-1 text-30rpx text-#333 font-500">
|
||||
{{ item.dishName }}
|
||||
</view>
|
||||
<view class="flex-center-sb mt-12rpx">
|
||||
<text class="text-26rpx lh-30rpx text-#333 font-500">US${{ item.discountPrice }}</text>
|
||||
<view class="member-price-tag text-[#FBE3C3] font-500 text-28rpx lh-28rpx center pl-6rpx break-all">
|
||||
<text class="!text-24rpx">{{ t('pages-store.store.members') }}: </text>
|
||||
${{ item.memberPrice }}
|
||||
</view>
|
||||
</view>
|
||||
<view class="flex-center-sb mt-12rpx">
|
||||
<view class="text-28rpx text-#999">
|
||||
<view class="line-through">US${{ item.originalPrice }}</view>
|
||||
<view>{{ t('pages-store.store.sales') }}:{{ item.salesCount }}</view>
|
||||
</view>
|
||||
|
||||
<view class="center w-64rpx h-64rpx rounded-50% bg-white shadow-lg">
|
||||
<image
|
||||
src="@img/chef/1285.png"
|
||||
class="w-30rpx h-30rpx shrink-0"
|
||||
></image>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
</view>
|
||||
<template v-else>
|
||||
<view class="py-100rpx center">
|
||||
<image class="w-250rpx h-250rpx" src="@img/chef/100.png"></image>
|
||||
</view>
|
||||
</template>
|
||||
</view>
|
||||
<view @click="navigateTo('/pages-user/pages/member/index')" v-if="cartDataList.length > 0 && cartSavingsData && cartSavingsData.savings > 0" class="h-96rpx bg-#CE7138 pl-56rpx flex items-center fixed bottom-0 left-0 w-full z-9">
|
||||
<image
|
||||
src="@img/chef/1289.png"
|
||||
class="mr-10rpx w-32rpx h-32rpx shrink-0"
|
||||
></image>
|
||||
<text class="text-[#fff] text-24rpx lh-24rpx">
|
||||
{{ t('pages-store.store.use') }} {{ Config.appName }} {{ t('pages-store.store.tips3') }} ${{ cartSavingsData.savings }} {{ t('pages-store.store.discount') }}
|
||||
</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view v-if="cartDataList.length > 0" @click="navigateToCart" class="fixed z-9 bottom-138rpx left-50% translate-x--50% px-26rpx h-88rpx bg-#14181B rounded-44rpx center text-28rpx text-#fff font-500">
|
||||
<image src="@img/chef/125.png" class="w-28rpx h-28rpx shrink-0"></image>
|
||||
<view class="ml-10rpx whitespace-nowrap line-clamp-1">{{ storeDetail.merchantName }}</view>
|
||||
<view class="w-8rpx h-8rpx rounded-50% bg-white mx-8rpx"></view>
|
||||
<text>{{ cartDataList.length }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
|
||||
|
||||
<coupon-popup
|
||||
ref="couponPopupRef"
|
||||
:coupon-list="storeCouponList"
|
||||
@confirm="getMerchantCouponReceiveList"
|
||||
/>
|
||||
</template>
|
||||
<style>
|
||||
page {
|
||||
background-color: #fff;
|
||||
}
|
||||
</style>
|
||||
<style scoped lang="scss">
|
||||
:deep(.wd-swiper__track) {
|
||||
border-radius: 0;
|
||||
}
|
||||
:deep(.wd-tabs__nav-container) {
|
||||
.is-active {
|
||||
color: #333 !important;
|
||||
font-weight: 500 !important;
|
||||
}
|
||||
}
|
||||
:deep(.wd-tabs__nav-item-text) {
|
||||
font-size: 30rpx !important;
|
||||
//color: #7D7D7D;
|
||||
padding-bottom: 32rpx !important;
|
||||
}
|
||||
|
||||
:deep(.wd-tabs__line) {
|
||||
border-radius: 0 !important;
|
||||
height: 10rpx !important;
|
||||
background-color: #333333 !important;
|
||||
}
|
||||
.box {
|
||||
border-bottom: 10rpx solid #F6F6F6 !important;
|
||||
}
|
||||
.member-price-tag {
|
||||
min-width: 190rpx;
|
||||
height: 42rpx;
|
||||
background-image: url("/static/images/chef/1282.png");
|
||||
background-size: 100% 100%;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.coupon-scroll {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.coupon-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.coupon-item {
|
||||
margin-right: 20rpx;
|
||||
flex-shrink: 0;
|
||||
|
||||
&:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.coupon-tag {
|
||||
min-width: 120rpx;
|
||||
height: 52rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0 28rpx;
|
||||
position: relative;
|
||||
background-image: url("/static/images/5008.png");
|
||||
background-size: 100% 100%;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.coupon-text {
|
||||
font-size: 24rpx;
|
||||
line-height: 24rpx;
|
||||
color: #CE7138;
|
||||
font-weight: 400;
|
||||
white-space: nowrap;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user