修改样式
This commit is contained in:
@@ -232,6 +232,8 @@
|
|||||||
"featured-on": "Featured on CHEFLINK",
|
"featured-on": "Featured on CHEFLINK",
|
||||||
"featured-dishes": "Featured Dishes",
|
"featured-dishes": "Featured Dishes",
|
||||||
"nearby-merchants": "Nearby Merchants",
|
"nearby-merchants": "Nearby Merchants",
|
||||||
|
"open-member": "Become a Member",
|
||||||
|
"recharge-now": "Recharge Now",
|
||||||
"quickTabs": {
|
"quickTabs": {
|
||||||
"memberZone": "Member Zone",
|
"memberZone": "Member Zone",
|
||||||
"liveSeafoodAir": "Limited Live Seafood",
|
"liveSeafoodAir": "Limited Live Seafood",
|
||||||
|
|||||||
@@ -232,6 +232,8 @@
|
|||||||
"featured-on": "精选商家",
|
"featured-on": "精选商家",
|
||||||
"featured-dishes": "精选菜品",
|
"featured-dishes": "精选菜品",
|
||||||
"nearby-merchants": "附近商家",
|
"nearby-merchants": "附近商家",
|
||||||
|
"open-member": "开通会员",
|
||||||
|
"recharge-now": "立即充值",
|
||||||
"quickTabs": {
|
"quickTabs": {
|
||||||
"memberZone": "会员专区",
|
"memberZone": "会员专区",
|
||||||
"liveSeafoodAir": "限量空运活海鲜",
|
"liveSeafoodAir": "限量空运活海鲜",
|
||||||
|
|||||||
+2
-2
@@ -2,8 +2,8 @@
|
|||||||
"name" : "CHEFLINK delivery",
|
"name" : "CHEFLINK delivery",
|
||||||
"appid" : "__UNI__06509BE",
|
"appid" : "__UNI__06509BE",
|
||||||
"description" : "",
|
"description" : "",
|
||||||
"versionName" : "3.1.9",
|
"versionName" : "3.2.0",
|
||||||
"versionCode" : 319,
|
"versionCode" : 320,
|
||||||
"transformPx" : false,
|
"transformPx" : false,
|
||||||
/* 5+App特有相关 */
|
/* 5+App特有相关 */
|
||||||
"app-plus" : {
|
"app-plus" : {
|
||||||
|
|||||||
@@ -0,0 +1,166 @@
|
|||||||
|
<template>
|
||||||
|
<view class="store-main-sk">
|
||||||
|
<view class="sk-banner skeleton-item"></view>
|
||||||
|
<view class="sk-notice skeleton-item"></view>
|
||||||
|
<view class="sk-info-block">
|
||||||
|
<view class="sk-store-name skeleton-item"></view>
|
||||||
|
<view class="flex items-center gap-16rpx mt-12rpx">
|
||||||
|
<view class="sk-rating skeleton-item"></view>
|
||||||
|
<view class="sk-sales skeleton-item"></view>
|
||||||
|
</view>
|
||||||
|
<view class="flex items-center gap-16rpx mt-16rpx">
|
||||||
|
<view class="sk-coupon skeleton-item"></view>
|
||||||
|
<view class="sk-coupon skeleton-item"></view>
|
||||||
|
<view class="sk-coupon skeleton-item"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="flex items-center px-24rpx pb-24rpx gap-16rpx">
|
||||||
|
<view v-for="i in 4" :key="i" class="sk-tab skeleton-item"></view>
|
||||||
|
</view>
|
||||||
|
<view class="sk-dish-grid px-24rpx">
|
||||||
|
<view v-for="i in 4" :key="i" class="sk-dish-card">
|
||||||
|
<view class="sk-dish-img skeleton-item"></view>
|
||||||
|
<view class="sk-dish-body">
|
||||||
|
<view class="flex items-center justify-between mb-10rpx">
|
||||||
|
<view class="sk-price skeleton-item"></view>
|
||||||
|
<view class="sk-dish-sales skeleton-item"></view>
|
||||||
|
</view>
|
||||||
|
<view class="sk-title skeleton-item mb-12rpx"></view>
|
||||||
|
<view class="sk-title sk-title--short skeleton-item mb-14rpx"></view>
|
||||||
|
<view class="flex items-center justify-between">
|
||||||
|
<view class="sk-member skeleton-item"></view>
|
||||||
|
<view class="sk-add skeleton-item"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.skeleton-item {
|
||||||
|
background: linear-gradient(90deg, #ebebeb 25%, #d6d6d6 50%, #ebebeb 75%);
|
||||||
|
background-size: 200% 100%;
|
||||||
|
animation: sk-shimmer 1.4s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes sk-shimmer {
|
||||||
|
0% {
|
||||||
|
background-position: -200% 0;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
background-position: 200% 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.store-main-sk {
|
||||||
|
width: 100%;
|
||||||
|
min-height: 100%;
|
||||||
|
background: #f6f6f6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sk-banner {
|
||||||
|
width: 100%;
|
||||||
|
height: 360rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sk-notice {
|
||||||
|
width: 100%;
|
||||||
|
height: 66rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sk-info-block {
|
||||||
|
background: #fff;
|
||||||
|
padding: 20rpx 24rpx 16rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sk-store-name {
|
||||||
|
width: 60%;
|
||||||
|
height: 36rpx;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sk-rating {
|
||||||
|
width: 100rpx;
|
||||||
|
height: 24rpx;
|
||||||
|
border-radius: 6rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sk-sales {
|
||||||
|
width: 120rpx;
|
||||||
|
height: 24rpx;
|
||||||
|
border-radius: 6rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sk-coupon {
|
||||||
|
width: 100rpx;
|
||||||
|
height: 48rpx;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sk-tab {
|
||||||
|
width: 96rpx;
|
||||||
|
height: 56rpx;
|
||||||
|
border-radius: 28rpx;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sk-dish-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
gap: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sk-dish-card {
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sk-dish-img {
|
||||||
|
width: 100%;
|
||||||
|
height: 270rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sk-dish-body {
|
||||||
|
padding: 14rpx 14rpx 16rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sk-price {
|
||||||
|
width: 90rpx;
|
||||||
|
height: 28rpx;
|
||||||
|
border-radius: 6rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sk-dish-sales {
|
||||||
|
width: 60rpx;
|
||||||
|
height: 22rpx;
|
||||||
|
border-radius: 6rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sk-title {
|
||||||
|
width: 90%;
|
||||||
|
height: 26rpx;
|
||||||
|
border-radius: 6rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sk-title--short {
|
||||||
|
width: 60%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sk-member {
|
||||||
|
width: 120rpx;
|
||||||
|
height: 36rpx;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sk-add {
|
||||||
|
width: 48rpx;
|
||||||
|
height: 48rpx;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1,227 +1,127 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="store-skeleton">
|
<view class="store-skeleton">
|
||||||
<!-- 顶部导航栏 -->
|
<view class="store-sk-layout">
|
||||||
<view class="fixed top-0 left-0 z-9 w-full pt-6rpx">
|
<view class="store-sk-sidebar">
|
||||||
<status-bar />
|
<status-bar />
|
||||||
<view class="nav-bar">
|
<view class="sk-back skeleton-item"></view>
|
||||||
<view class="nav-btn skeleton-item"></view>
|
<view class="sk-head">
|
||||||
<view class="nav-btn skeleton-item"></view>
|
<view class="sk-head-icon skeleton-item"></view>
|
||||||
|
<view class="sk-head-text skeleton-item"></view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 占位 -->
|
|
||||||
<status-bar />
|
|
||||||
<view class="h-88rpx"></view>
|
|
||||||
|
|
||||||
<!-- 店铺 Logo -->
|
|
||||||
<view class="flex justify-center pt-20rpx">
|
|
||||||
<view class="logo-skeleton skeleton-item"></view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 店铺信息区域 -->
|
|
||||||
<view class="px-30rpx pt-24rpx pb-30rpx">
|
|
||||||
<view class="flex flex-col items-center">
|
|
||||||
<!-- 店铺名称 -->
|
|
||||||
<view class="name-skeleton skeleton-item mb-16rpx"></view>
|
|
||||||
<!-- 评分 + CHEFLINK -->
|
|
||||||
<view class="flex items-center mb-12rpx">
|
|
||||||
<view class="rating-skeleton skeleton-item mr-16rpx"></view>
|
|
||||||
<view class="cheflink-skeleton skeleton-item"></view>
|
|
||||||
</view>
|
|
||||||
<!-- 总销量 -->
|
|
||||||
<view class="sales-text-skeleton skeleton-item"></view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 配送信息卡片 -->
|
|
||||||
<view class="delivery-card-skeleton skeleton-item mt-30rpx"></view>
|
|
||||||
|
|
||||||
<!-- 优惠券标签行(占位) -->
|
|
||||||
<view class="flex items-center mt-24rpx">
|
|
||||||
<view class="coupon-tag-skeleton skeleton-item mr-16rpx"></view>
|
|
||||||
<view class="coupon-tag-skeleton skeleton-item mr-16rpx"></view>
|
|
||||||
<view class="coupon-tag-skeleton skeleton-item"></view>
|
|
||||||
<view class="flex-1"></view>
|
|
||||||
<view class="claim-skeleton skeleton-item"></view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 分类胶囊标签 -->
|
|
||||||
<view class="flex items-center px-30rpx pb-24rpx">
|
|
||||||
<view
|
<view
|
||||||
v-for="i in 4"
|
v-for="i in 4"
|
||||||
:key="i"
|
:key="i"
|
||||||
class="tab-chip-skeleton skeleton-item"
|
class="sk-merchant-item"
|
||||||
></view>
|
:class="{ 'sk-merchant-item--active': i === 1 }"
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 商品列表 -->
|
|
||||||
<view class="px-30rpx">
|
|
||||||
<view class="grid grid-cols-2 gap-24rpx">
|
|
||||||
<view
|
|
||||||
v-for="i in 4"
|
|
||||||
:key="i"
|
|
||||||
class="product-skeleton"
|
|
||||||
>
|
>
|
||||||
<!-- 商品图片 -->
|
<view class="sk-merchant-logo skeleton-item"></view>
|
||||||
<view class="product-img-skeleton skeleton-item"></view>
|
<view class="sk-merchant-name skeleton-item"></view>
|
||||||
<!-- 价格 + 销量 -->
|
|
||||||
<view class="flex items-center justify-between mt-16rpx">
|
|
||||||
<view class="price-skeleton skeleton-item"></view>
|
|
||||||
<view class="sales-skeleton skeleton-item"></view>
|
|
||||||
</view>
|
|
||||||
<!-- 商品名称 -->
|
|
||||||
<view class="product-name-skeleton skeleton-item mt-8rpx"></view>
|
|
||||||
<!-- 会员价 + 加购按钮 -->
|
|
||||||
<view class="flex items-center justify-between mt-12rpx">
|
|
||||||
<view class="member-skeleton skeleton-item"></view>
|
|
||||||
<view class="add-btn-skeleton skeleton-item"></view>
|
|
||||||
</view>
|
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
<store-main-skeleton />
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import StoreMainSkeleton from './store-main-skeleton.vue'
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.skeleton-item {
|
.skeleton-item {
|
||||||
background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
background: linear-gradient(90deg, #ebebeb 25%, #d6d6d6 50%, #ebebeb 75%);
|
||||||
background-size: 200% 100%;
|
background-size: 200% 100%;
|
||||||
animation: shimmer 1.5s infinite;
|
animation: sk-shimmer 1.4s ease-in-out infinite;
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes shimmer {
|
@keyframes sk-shimmer {
|
||||||
0% { background-position: -200% 0; }
|
0% {
|
||||||
100% { background-position: 200% 0; }
|
background-position: -200% 0;
|
||||||
}
|
}
|
||||||
|
100% {
|
||||||
.store-skeleton {
|
background-position: 200% 0;
|
||||||
background-color: #fff;
|
|
||||||
min-height: 100vh;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 顶部导航 */
|
|
||||||
.nav-bar {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
padding: 0 30rpx;
|
|
||||||
height: 88rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-btn {
|
|
||||||
width: 48rpx;
|
|
||||||
height: 48rpx;
|
|
||||||
border-radius: 24rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 店铺 Logo */
|
|
||||||
.logo-skeleton {
|
|
||||||
width: 128rpx;
|
|
||||||
height: 128rpx;
|
|
||||||
border-radius: 24rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 店铺信息 */
|
|
||||||
.name-skeleton {
|
|
||||||
width: 360rpx;
|
|
||||||
height: 44rpx;
|
|
||||||
border-radius: 8rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rating-skeleton {
|
|
||||||
width: 160rpx;
|
|
||||||
height: 24rpx;
|
|
||||||
border-radius: 6rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cheflink-skeleton {
|
|
||||||
width: 120rpx;
|
|
||||||
height: 24rpx;
|
|
||||||
border-radius: 6rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sales-text-skeleton {
|
|
||||||
width: 140rpx;
|
|
||||||
height: 24rpx;
|
|
||||||
border-radius: 6rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 配送信息卡片 */
|
|
||||||
.delivery-card-skeleton {
|
|
||||||
width: 100%;
|
|
||||||
height: 140rpx;
|
|
||||||
border-radius: 20rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 优惠券标签 */
|
|
||||||
.coupon-tag-skeleton {
|
|
||||||
width: 120rpx;
|
|
||||||
height: 52rpx;
|
|
||||||
border-radius: 8rpx;
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.claim-skeleton {
|
|
||||||
width: 100rpx;
|
|
||||||
height: 28rpx;
|
|
||||||
border-radius: 6rpx;
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 胶囊标签 */
|
|
||||||
.tab-chip-skeleton {
|
|
||||||
width: 100rpx;
|
|
||||||
height: 60rpx;
|
|
||||||
border-radius: 30rpx;
|
|
||||||
margin-right: 20rpx;
|
|
||||||
flex-shrink: 0;
|
|
||||||
|
|
||||||
&:last-child {
|
|
||||||
margin-right: 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 商品卡片 */
|
.store-skeleton {
|
||||||
.product-skeleton {
|
|
||||||
margin-bottom: 24rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.product-img-skeleton {
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 248rpx;
|
min-height: 100vh;
|
||||||
|
background: #f6f6f6;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.store-sk-layout {
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.store-sk-sidebar {
|
||||||
|
width: 146rpx;
|
||||||
|
flex-shrink: 0;
|
||||||
|
height: 100%;
|
||||||
|
background: #ececec;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
padding-bottom: 20rpx;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sk-back {
|
||||||
|
width: 48rpx;
|
||||||
|
height: 48rpx;
|
||||||
border-radius: 24rpx;
|
border-radius: 24rpx;
|
||||||
|
margin: 12rpx 0 8rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.price-skeleton {
|
.sk-head {
|
||||||
width: 120rpx;
|
display: flex;
|
||||||
height: 36rpx;
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10rpx;
|
||||||
|
padding: 8rpx 0 16rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sk-head-icon {
|
||||||
|
width: 26rpx;
|
||||||
|
height: 26rpx;
|
||||||
border-radius: 6rpx;
|
border-radius: 6rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sales-skeleton {
|
.sk-head-text {
|
||||||
width: 80rpx;
|
width: 80rpx;
|
||||||
height: 22rpx;
|
height: 20rpx;
|
||||||
border-radius: 6rpx;
|
border-radius: 6rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.product-name-skeleton {
|
.sk-merchant-item {
|
||||||
width: 85%;
|
width: 100%;
|
||||||
height: 34rpx;
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
padding: 16rpx 10rpx;
|
||||||
|
gap: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sk-merchant-item--active {
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sk-merchant-logo {
|
||||||
|
width: 68rpx;
|
||||||
|
height: 68rpx;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sk-merchant-name {
|
||||||
|
width: 72rpx;
|
||||||
|
height: 20rpx;
|
||||||
border-radius: 6rpx;
|
border-radius: 6rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.member-skeleton {
|
:deep(.store-main-sk) {
|
||||||
width: 160rpx;
|
flex: 1;
|
||||||
height: 42rpx;
|
min-width: 0;
|
||||||
border-radius: 8rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.add-btn-skeleton {
|
|
||||||
width: 52rpx;
|
|
||||||
height: 52rpx;
|
|
||||||
border-radius: 26rpx;
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -3,33 +3,129 @@ import { debounce } from 'throttle-debounce'
|
|||||||
import dayjs from 'dayjs'
|
import dayjs from 'dayjs'
|
||||||
import Config from '@/config/index'
|
import Config from '@/config/index'
|
||||||
const { t, locale } = useI18n();
|
const { t, locale } = useI18n();
|
||||||
import StoreSkeleton from './components/store-skeleton.vue';
|
import StoreSkeleton from './components/store-skeleton.vue'
|
||||||
import { useScrollThreshold } from '@/hooks/useScrollThreshold'
|
import StoreMainSkeleton from './components/store-main-skeleton.vue'
|
||||||
import {
|
import {
|
||||||
appCollectCollectPost, appMerchantCartCalculateSavingsPost, appMerchantCartListByMerchantIdPost,
|
appCollectCollectPost,
|
||||||
|
appMerchantCartCalculateSavingsPost,
|
||||||
|
appMerchantCartListByMerchantIdPost,
|
||||||
|
appMerchantCartListMerchantPost,
|
||||||
appMerchantDetailMerchantIdGet,
|
appMerchantDetailMerchantIdGet,
|
||||||
appMerchantDishDishIdGet,
|
appMerchantDishDishIdGet,
|
||||||
appMerchantMenuMenuListByUserPost, type MerchantCartVo,
|
appMerchantMenuMenuListByUserPost,
|
||||||
type MerchantVo
|
type MerchantCartVo,
|
||||||
} from "@/service";
|
type MerchantVo,
|
||||||
import {CollectionType} from "@/constant/enums";
|
} from '@/service'
|
||||||
import {useUserStore} from "@/store";
|
import { CollectionType } from '@/constant/enums'
|
||||||
import { parseBusinessHoursUtils, getDistanceInMiles, parseMerchantCartPayload } from "@/utils/utils";
|
import { useConfigStore, useUserStore } from '@/store'
|
||||||
|
import { formatSalesCount, getDistanceInMiles, parseMerchantCartPayload } from '@/utils/utils'
|
||||||
import { formatDeliveryScheduleDays } from "@/utils/deliverySchedule";
|
import { formatDeliveryScheduleDays } from "@/utils/deliverySchedule";
|
||||||
import CouponPopup from './components/coupon-popup.vue'
|
import CouponPopup from './components/coupon-popup.vue'
|
||||||
import {getMerchantCouponReceiveListApi} from "@/pages-user/service";
|
import {getMerchantCouponReceiveListApi} from "@/pages-user/service";
|
||||||
// import type { MerchantVo } from '@/service/types'
|
// import type { MerchantVo } from '@/service/types'
|
||||||
// 页面加载状态
|
// 页面加载状态
|
||||||
const loading = ref(true);
|
const loading = ref(true)
|
||||||
const userStore = useUserStore();
|
/** 切换店铺时右侧内容区骨架屏 */
|
||||||
|
const mainLoading = ref(false)
|
||||||
|
const userStore = useUserStore()
|
||||||
|
const configStore = useConfigStore()
|
||||||
|
|
||||||
const storeID = ref('')
|
const storeID = ref('')
|
||||||
onLoad((options: any)=> {
|
const merchantList = ref<MerchantVo[]>([])
|
||||||
console.log(options)
|
const activeMerchantId = ref<string | number>('')
|
||||||
if(options.id) {
|
|
||||||
storeID.value = options.id
|
const storeShareTopStyle = computed(() => ({
|
||||||
|
top: `${configStore.statusBarHeight + uni.upx2px(16)}px`,
|
||||||
|
}))
|
||||||
|
|
||||||
|
const storeBannerSrc = computed(() => {
|
||||||
|
const raw = storeDetail.value?.shopImages
|
||||||
|
if (typeof raw === 'string' && raw.trim()) {
|
||||||
|
return raw.split(',')[0].trim()
|
||||||
|
}
|
||||||
|
const logo = storeDetail.value?.logo
|
||||||
|
return typeof logo === 'string' ? logo : ''
|
||||||
|
})
|
||||||
|
|
||||||
|
const deliveryNoticeTexts = computed(() => {
|
||||||
|
const texts: string[] = []
|
||||||
|
if (+storeDetail.value?.deliveryService === 1 && deliveryMethod.value === 0) {
|
||||||
|
texts.push(
|
||||||
|
`${t('pages-store.store.tips4')} $ ${storeDetail.value?.minOrderPrice} ${t('pages-store.store.tips5')} $ ${storeDetail.value?.deliveryFee}${t('pages-store.store.start')}`,
|
||||||
|
)
|
||||||
|
const timeLine = `${storeDetail.value?.deliveryTime}${daySuffix(storeDetail.value?.deliveryTime)} · ${t('pages-store.store.earTime')}`
|
||||||
|
texts.push(deliveryScheduleDaysText.value || timeLine)
|
||||||
|
} else if (+storeDetail.value?.selfPickup === 1 && deliveryMethod.value === 1) {
|
||||||
|
if (cartDataList.value.length > 0 && cartSavingsData.value && (cartSavingsData.value as { savings?: number }).savings > 0) {
|
||||||
|
texts.push(
|
||||||
|
`${t('pages-store.store.use')} ${Config.appName} ${t('pages-store.store.tips3')} $${(cartSavingsData.value as { savings?: number }).savings} ${t('pages-store.store.discount')}`,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
texts.push(
|
||||||
|
`${storeDetail.value?.pickupTime}${t('common.minutes')} · ${t('pages-store.store.earTime')}`,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return texts.filter(Boolean)
|
||||||
|
})
|
||||||
|
|
||||||
|
async function loadMerchantList() {
|
||||||
|
try {
|
||||||
|
const res = await appMerchantCartListMerchantPost({})
|
||||||
|
merchantList.value = Array.isArray(res?.data) ? res.data : []
|
||||||
|
} catch {
|
||||||
|
merchantList.value = []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function ensureMerchantInSidebarList() {
|
||||||
|
const id = String(storeID.value || '')
|
||||||
|
if (!id || !storeDetail.value?.id) return
|
||||||
|
const exists = merchantList.value.some((m) => String(m.id) === id)
|
||||||
|
if (!exists) {
|
||||||
|
merchantList.value = [
|
||||||
|
{
|
||||||
|
id: storeDetail.value.id,
|
||||||
|
logo: storeDetail.value.logo,
|
||||||
|
merchantName: storeDetail.value.merchantName,
|
||||||
|
} as MerchantVo,
|
||||||
|
...merchantList.value,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function onSidebarChange(payload: { value: string | number }) {
|
||||||
|
switchMerchant(String(payload.value))
|
||||||
|
}
|
||||||
|
|
||||||
|
function switchMerchant(merchantId: string) {
|
||||||
|
if (!merchantId || merchantId === storeID.value) return
|
||||||
|
stopClosingTimer()
|
||||||
|
storeID.value = merchantId
|
||||||
|
activeMerchantId.value = merchantId
|
||||||
|
activeTab.value = 0
|
||||||
|
tabs.value = []
|
||||||
|
dishListByQuery.value = []
|
||||||
|
storeCouponList.value = []
|
||||||
|
hasMore.value = true
|
||||||
|
pageNum.value = 1
|
||||||
|
mainLoading.value = true
|
||||||
|
getStoreDetail(true)
|
||||||
|
getCartInfo()
|
||||||
|
}
|
||||||
|
|
||||||
|
onLoad(async (options: any) => {
|
||||||
|
await loadMerchantList()
|
||||||
|
if (options?.id) {
|
||||||
|
storeID.value = String(options.id)
|
||||||
|
activeMerchantId.value = storeID.value
|
||||||
|
} else if (merchantList.value.length > 0) {
|
||||||
|
storeID.value = String(merchantList.value[0].id)
|
||||||
|
activeMerchantId.value = storeID.value
|
||||||
|
}
|
||||||
|
if (storeID.value) {
|
||||||
getStoreDetail()
|
getStoreDetail()
|
||||||
// getMenuList()
|
} else {
|
||||||
|
loading.value = false
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -137,13 +233,17 @@ function parseBusinessHours(businessHours: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const storeDistance = ref(null)
|
const storeDistance = ref(null)
|
||||||
function getStoreDetail() {
|
function getStoreDetail(silent = false) {
|
||||||
|
if (!silent) {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
|
} else {
|
||||||
|
mainLoading.value = true
|
||||||
|
}
|
||||||
appMerchantDetailMerchantIdGet({
|
appMerchantDetailMerchantIdGet({
|
||||||
params: {
|
params: {
|
||||||
merchantId: storeID.value,
|
merchantId: storeID.value,
|
||||||
}
|
}
|
||||||
}).then((res: any) => {
|
}).then(async (res: any) => {
|
||||||
console.log('商家详情', res)
|
console.log('商家详情', res)
|
||||||
storeDetail.value = res.data as MerchantVo
|
storeDetail.value = res.data as MerchantVo
|
||||||
|
|
||||||
@@ -184,7 +284,10 @@ function getStoreDetail() {
|
|||||||
dishListByQuery.value = []
|
dishListByQuery.value = []
|
||||||
hasMore.value = true
|
hasMore.value = true
|
||||||
pageNum.value = 1
|
pageNum.value = 1
|
||||||
nextTick(() => loadDishList(false))
|
await loadDishList(false)
|
||||||
|
} else {
|
||||||
|
tabs.value = [{ title: t('pages.store.all'), key: '' }]
|
||||||
|
dishListByQuery.value = []
|
||||||
}
|
}
|
||||||
|
|
||||||
// 商户的经纬度存在,并且用户的经纬度也存在
|
// 商户的经纬度存在,并且用户的经纬度也存在
|
||||||
@@ -215,11 +318,13 @@ function getStoreDetail() {
|
|||||||
showDeliverySwitch.value = true
|
showDeliverySwitch.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ensureMerchantInSidebarList()
|
||||||
|
activeMerchantId.value = storeID.value
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
console.error('获取商家详情失败:', error);
|
console.error('获取商家详情失败:', error);
|
||||||
}).finally(()=> {
|
}).finally(() => {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
|
mainLoading.value = false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -406,17 +511,11 @@ watch(activeTab, () => {
|
|||||||
loadDishList(false);
|
loadDishList(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
// 触底加载更多
|
function onMainScrollToLower() {
|
||||||
onReachBottom(() => {
|
|
||||||
if (hasMore.value && !isLoadingMore.value) {
|
if (hasMore.value && !isLoadingMore.value) {
|
||||||
loadDishList(true);
|
loadDishList(true)
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
const showStatusBar = useScrollThreshold()
|
|
||||||
onPageScroll((e) => {
|
|
||||||
uni.$emit('page-scroll', e)
|
|
||||||
})
|
|
||||||
|
|
||||||
function navigateToDishes(item: any) {
|
function navigateToDishes(item: any) {
|
||||||
uni.navigateTo({
|
uni.navigateTo({
|
||||||
@@ -499,109 +598,110 @@ function handleShare() {
|
|||||||
<StoreSkeleton/>
|
<StoreSkeleton/>
|
||||||
</view>
|
</view>
|
||||||
<view
|
<view
|
||||||
class="animate-in fade-in animate-ease-in animate-duration-300"
|
class="animate-in fade-in animate-ease-in animate-duration-300 store-page"
|
||||||
v-if="!loading"
|
v-if="!loading"
|
||||||
>
|
>
|
||||||
<view class="store-box">
|
<view class="store-layout">
|
||||||
<!-- 顶部导航栏 -->
|
<!-- 左侧:返回 + Sidebar 切换店铺 -->
|
||||||
<view class="fixed top-0 left-0 z-9 w-full transition-all pt-6rpx" :class="[showStatusBar ? 'bg-#fff' : '']">
|
<view class="store-sidebar">
|
||||||
<status-bar />
|
<status-bar />
|
||||||
<view class="flex-center-sb px-30rpx h-88rpx">
|
<view class="store-sidebar__back" @click="navigateBack">
|
||||||
<image
|
<image
|
||||||
@click="navigateBack"
|
|
||||||
src="@img/chef/1327.png"
|
src="@img/chef/1327.png"
|
||||||
mode="aspectFill"
|
mode="aspectFill"
|
||||||
class="w-48rpx h-48rpx relative z-1"
|
class="store-sidebar__back-icon"
|
||||||
/>
|
/>
|
||||||
|
</view>
|
||||||
|
<view class="store-sidebar__head">
|
||||||
|
<image src="@img-store/1339.png" class="store-sidebar__head-icon" mode="aspectFit" />
|
||||||
|
<text class="store-sidebar__head-text">{{ t('pages.home.featured-on') }}</text>
|
||||||
|
</view>
|
||||||
|
<scroll-view scroll-y class="store-sidebar__scroll" :show-scrollbar="false">
|
||||||
|
<wd-sidebar
|
||||||
|
v-model="activeMerchantId"
|
||||||
|
custom-class="store-wd-sidebar"
|
||||||
|
@change="onSidebarChange"
|
||||||
|
>
|
||||||
|
<wd-sidebar-item
|
||||||
|
v-for="merchant in merchantList"
|
||||||
|
:key="String(merchant.id)"
|
||||||
|
:value="merchant.id"
|
||||||
|
:label="merchant.merchantName || ''"
|
||||||
|
custom-class="store-sidebar-item"
|
||||||
|
>
|
||||||
|
<template #icon>
|
||||||
|
<view class="store-sidebar-item__inner">
|
||||||
<image
|
<image
|
||||||
|
:src="merchant.logo"
|
||||||
|
class="store-sidebar-item__logo"
|
||||||
|
mode="aspectFill"
|
||||||
|
/>
|
||||||
|
<text class="store-sidebar-item__name">{{ merchant.merchantName }}</text>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
</wd-sidebar-item>
|
||||||
|
</wd-sidebar>
|
||||||
|
</scroll-view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 右侧:分享(绝对定位)+ 海报 + 配送通知 + 分类 + 商品 -->
|
||||||
|
<view class="store-main-wrap">
|
||||||
|
<image
|
||||||
|
v-if="!mainLoading"
|
||||||
@click="handleShare"
|
@click="handleShare"
|
||||||
src="@img-store/1335.png"
|
src="@img-store/1335.png"
|
||||||
mode="aspectFill"
|
mode="aspectFill"
|
||||||
class="w-48rpx h-48rpx relative z-1"
|
class="store-share-btn"
|
||||||
|
:style="storeShareTopStyle"
|
||||||
/>
|
/>
|
||||||
|
<view v-if="mainLoading" class="store-main store-main--loading">
|
||||||
|
<store-main-skeleton />
|
||||||
</view>
|
</view>
|
||||||
</view>
|
<scroll-view
|
||||||
|
v-else
|
||||||
<!-- 占位 -->
|
class="store-main"
|
||||||
<status-bar />
|
scroll-y
|
||||||
<view class="h-44rpx"></view>
|
:style="{ height: '100%' }"
|
||||||
|
:show-scrollbar="false"
|
||||||
<!-- 店铺 Logo -->
|
@scrolltolower="onMainScrollToLower"
|
||||||
<view class="flex justify-center ">
|
>
|
||||||
|
<view class="store-main__inner">
|
||||||
|
<view class="store-banner">
|
||||||
<image
|
<image
|
||||||
:src="storeDetail?.shopImages?.split(',')[0]"
|
v-if="storeBannerSrc"
|
||||||
|
:src="storeBannerSrc"
|
||||||
|
class="store-banner__img"
|
||||||
mode="aspectFill"
|
mode="aspectFill"
|
||||||
class="w-128rpx h-128rpx rounded-24rpx bg-common"
|
/>
|
||||||
|
<view v-else class="store-banner__img store-banner__img--empty" />
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view
|
||||||
|
v-if="showDeliverySwitch && deliveryNoticeTexts.length"
|
||||||
|
class="store-delivery-notice"
|
||||||
|
>
|
||||||
|
<wd-notice-bar
|
||||||
|
:text="deliveryNoticeTexts"
|
||||||
|
direction="vertical"
|
||||||
|
:delay="2"
|
||||||
|
:speed="50"
|
||||||
|
color="#CE7138"
|
||||||
|
background-color="#FFF7ED"
|
||||||
|
custom-class="store-delivery-notice__bar"
|
||||||
/>
|
/>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 店铺信息区域 -->
|
<!-- <view class="store-info-block"> -->
|
||||||
<view class="px-30rpx pt-24rpx pb-30rpx">
|
<!-- <view class="store-info-block__title">{{ storeDetail?.merchantName }}</view>
|
||||||
<view class="text-center">
|
<view class="store-info-block__meta">
|
||||||
<!-- 店铺名称 -->
|
<text class="store-info-block__rating">{{ storeDetail?.rating }}</text>
|
||||||
<view class="text-36rpx lh-44rpx text-#333 font-bold">
|
<text class="store-info-block__comment">({{ storeDetail?.commentCount }})</text>
|
||||||
{{ storeDetail?.merchantName }}
|
<text class="store-info-block__sales">
|
||||||
</view>
|
|
||||||
<!-- 评分 + CHEFLINK -->
|
|
||||||
<view class="center text-24rpx lh-24rpx mt-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>
|
|
||||||
</view>
|
|
||||||
<!-- 总销量 -->
|
|
||||||
<view class="text-24rpx lh-24rpx text-#7D7D7D text-center mt-12rpx">
|
|
||||||
{{ t('common.sales') }}:{{ storeDetail?.totalOrderCount }}
|
{{ t('common.sales') }}:{{ storeDetail?.totalOrderCount }}
|
||||||
</view>
|
</text>
|
||||||
</view>
|
</view> -->
|
||||||
|
|
||||||
<!-- 配送信息卡片 -->
|
<view v-if="storeCouponList.length" class="store-coupon-row">
|
||||||
<view v-if="showDeliverySwitch" class="delivery-info-card">
|
|
||||||
<template v-if="+storeDetail?.deliveryService === 1 && deliveryMethod === 0">
|
|
||||||
<view class="delivery-info-left">
|
|
||||||
<view>{{ t('pages-store.store.tips4') }} $ {{ storeDetail?.minOrderPrice }}</view>
|
|
||||||
<view>{{ t('pages-store.store.tips5') }} $ {{ storeDetail?.deliveryFee }}{{ t('pages-store.store.start') }}</view>
|
|
||||||
</view>
|
|
||||||
<view class="delivery-info-divider"></view>
|
|
||||||
<view class="delivery-info-right">
|
|
||||||
<view class="text-32rpx lh-40rpx text-#333 font-500">
|
|
||||||
{{ storeDetail?.deliveryTime }}{{ daySuffix(storeDetail?.deliveryTime) }}
|
|
||||||
</view>
|
|
||||||
<view class="text-24rpx lh-24rpx text-#7D7D7D mt-8rpx">{{ t('pages-store.store.earTime') }}</view>
|
|
||||||
<view
|
|
||||||
v-if="deliveryScheduleDaysText"
|
|
||||||
class="text-24rpx lh-32rpx text-#00A76D mt-8rpx"
|
|
||||||
>{{ deliveryScheduleDaysText }}</view>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
<template v-if="+storeDetail?.selfPickup === 1 && deliveryMethod === 1">
|
|
||||||
<view class="delivery-info-left">
|
|
||||||
<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>--</view>
|
|
||||||
</view>
|
|
||||||
<view class="delivery-info-divider"></view>
|
|
||||||
<view class="delivery-info-right">
|
|
||||||
<view class="text-32rpx lh-40rpx text-#333 font-500">{{ storeDetail?.pickupTime }}{{ t('common.minutes') }}</view>
|
|
||||||
<view class="text-24rpx lh-24rpx text-#7D7D7D mt-8rpx">{{ t('pages-store.store.earTime') }}</view>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 优惠券标签行 -->
|
|
||||||
<view class="mt-24rpx flex items-center" v-if="storeCouponList.length">
|
|
||||||
<scroll-view
|
<scroll-view
|
||||||
scroll-x
|
scroll-x
|
||||||
class="coupon-scroll flex-1"
|
class="coupon-scroll flex-1"
|
||||||
@@ -625,11 +725,10 @@ function handleShare() {
|
|||||||
<i class="i-carbon:chevron-right text-24rpx text-#CE7138"></i>
|
<i class="i-carbon:chevron-right text-24rpx text-#CE7138"></i>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
<!-- </view> -->
|
||||||
|
|
||||||
<!-- 分类标签(胶囊样式) -->
|
|
||||||
<scroll-view scroll-x class="w-full" :show-scrollbar="false" enable-flex>
|
<scroll-view scroll-x class="w-full" :show-scrollbar="false" enable-flex>
|
||||||
<view class="flex items-center px-30rpx pb-24rpx">
|
<view class="flex items-center px-24rpx pb-24rpx">
|
||||||
<view
|
<view
|
||||||
v-for="(item, index) in tabs"
|
v-for="(item, index) in tabs"
|
||||||
:key="item.key"
|
:key="item.key"
|
||||||
@@ -642,8 +741,7 @@ function handleShare() {
|
|||||||
</view>
|
</view>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
|
|
||||||
<!-- 商品列表 -->
|
<view v-if="tabs.length > 0" class="px-24rpx pb-180rpx">
|
||||||
<view v-if="tabs.length > 0" class="px-30rpx pb-180rpx">
|
|
||||||
<view v-if="currentDishList.length > 0" class="grid grid-cols-2 gap-24rpx items-start">
|
<view v-if="currentDishList.length > 0" class="grid grid-cols-2 gap-24rpx items-start">
|
||||||
<template v-for="item in currentDishList" :key="item.id">
|
<template v-for="item in currentDishList" :key="item.id">
|
||||||
<view @click="navigateToDishes(item)" class="dish-card" :class="{ 'dish-card--soldout': isSoldOutStock(item?.stock) }">
|
<view @click="navigateToDishes(item)" class="dish-card" :class="{ 'dish-card--soldout': isSoldOutStock(item?.stock) }">
|
||||||
@@ -682,15 +780,15 @@ function handleShare() {
|
|||||||
<!-- 卡片信息区 -->
|
<!-- 卡片信息区 -->
|
||||||
<view class="dish-card-body">
|
<view class="dish-card-body">
|
||||||
<!-- 价格 + 销量 -->
|
<!-- 价格 + 销量 -->
|
||||||
<view class="flex items-start justify-between gap-12rpx mb-14rpx">
|
<view class="flex items-center justify-between gap-12rpx mb-14rpx">
|
||||||
<view class="min-w-0 flex-1">
|
<view class="min-w-0 flex-1">
|
||||||
<text class="dish-price">$ {{ item.discountPrice }}</text>
|
<text class="dish-price">${{ item.discountPrice }}</text>
|
||||||
<text
|
<!-- <text
|
||||||
v-if="Number(item?.originalPrice) > Number(item?.discountPrice)"
|
v-if="Number(item?.originalPrice) > Number(item?.discountPrice)"
|
||||||
class="dish-original-price"
|
class="dish-original-price"
|
||||||
>$ {{ item.originalPrice }}</text>
|
>$ {{ item.originalPrice }}</text> -->
|
||||||
</view>
|
</view>
|
||||||
<text class="dish-sales shrink-0">{{ t('pages-store.store.sales') }}:{{ item.salesCount }}</text>
|
<view class="dish-sales shrink-0">{{ t('pages-store.store.sales') }}:{{ formatSalesCount(item.salesCount) }}</view>
|
||||||
</view>
|
</view>
|
||||||
<!-- 商品名称 -->
|
<!-- 商品名称 -->
|
||||||
<view class="dish-title line-clamp-2 mb-16rpx">
|
<view class="dish-title line-clamp-2 mb-16rpx">
|
||||||
@@ -708,7 +806,7 @@ function handleShare() {
|
|||||||
<view class="dish-add-btn center shrink-0">
|
<view class="dish-add-btn center shrink-0">
|
||||||
<image
|
<image
|
||||||
src="@img/chef/1285.png"
|
src="@img/chef/1285.png"
|
||||||
class="w-28rpx h-28rpx"
|
class="w-20rpx h-20rpx"
|
||||||
></image>
|
></image>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -729,10 +827,14 @@ function handleShare() {
|
|||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
</view>
|
</view>
|
||||||
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
<!-- 底部购物车浮窗 -->
|
<!-- 底部购物车浮窗 -->
|
||||||
<view
|
<view
|
||||||
v-if="userStore.isLogin && cartDataList.length > 0"
|
v-if="!mainLoading && userStore.isLogin && cartDataList.length > 0"
|
||||||
class="store-cart-float"
|
class="store-cart-float"
|
||||||
@click="navigateToCart"
|
@click="navigateToCart"
|
||||||
>
|
>
|
||||||
@@ -749,7 +851,7 @@ function handleShare() {
|
|||||||
<!-- 会员省钱提示条 -->
|
<!-- 会员省钱提示条 -->
|
||||||
<view
|
<view
|
||||||
@click="navigateTo('/pages-user/pages/member/index')"
|
@click="navigateTo('/pages-user/pages/member/index')"
|
||||||
v-if="cartDataList.length > 0 && cartSavingsData && cartSavingsData.savings > 0"
|
v-if="!mainLoading && cartDataList.length > 0 && cartSavingsData && cartSavingsData.savings > 0"
|
||||||
class="store-savings-bar"
|
class="store-savings-bar"
|
||||||
>
|
>
|
||||||
<image
|
<image
|
||||||
@@ -761,7 +863,6 @@ function handleShare() {
|
|||||||
</text>
|
</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
|
||||||
|
|
||||||
<coupon-popup
|
<coupon-popup
|
||||||
ref="couponPopupRef"
|
ref="couponPopupRef"
|
||||||
@@ -777,40 +878,217 @@ page {
|
|||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
/* ====== 配送信息卡片 ====== */
|
.store-page {
|
||||||
.delivery-info-card {
|
height: 100vh;
|
||||||
|
overflow: hidden;
|
||||||
|
background: #f6f6f6;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.store-layout {
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.store-sidebar {
|
||||||
|
width: 146rpx;
|
||||||
|
flex-shrink: 0;
|
||||||
|
height: 100%;
|
||||||
|
background: #ececec;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.store-sidebar__back {
|
||||||
|
flex-shrink: 0;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: center;
|
||||||
margin-top: 30rpx;
|
padding: 12rpx 0 8rpx;
|
||||||
padding: 24rpx 40rpx;
|
|
||||||
border: 2rpx solid #D8D8D8;
|
|
||||||
border-radius: 20rpx;
|
|
||||||
min-height: 140rpx;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.delivery-info-left {
|
.store-sidebar__back-icon {
|
||||||
flex: 1;
|
width: 48rpx;
|
||||||
text-align: center;
|
height: 48rpx;
|
||||||
font-size: 24rpx;
|
|
||||||
line-height: 36rpx;
|
|
||||||
color: #CE7138;
|
|
||||||
padding-right: 30rpx;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.delivery-info-divider {
|
.store-sidebar__head {
|
||||||
width: 2rpx;
|
|
||||||
height: 100rpx;
|
|
||||||
background: #D8D8D8;
|
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
|
||||||
|
|
||||||
.delivery-info-right {
|
|
||||||
flex: 1;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding-left: 30rpx;
|
justify-content: center;
|
||||||
|
gap: 8rpx;
|
||||||
|
padding: 8rpx 12rpx 16rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.store-sidebar__head-icon {
|
||||||
|
width: 26rpx;
|
||||||
|
height: 26rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.store-sidebar__head-text {
|
||||||
|
font-size: 22rpx;
|
||||||
|
line-height: 28rpx;
|
||||||
|
color: #333;
|
||||||
|
font-weight: 600;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.store-sidebar__scroll {
|
||||||
|
flex: 1;
|
||||||
|
height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.store-wd-sidebar) {
|
||||||
|
width: 100% !important;
|
||||||
|
height: auto !important;
|
||||||
|
background: transparent !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.store-sidebar-item) {
|
||||||
|
flex-direction: column !important;
|
||||||
|
align-items: center !important;
|
||||||
|
justify-content: flex-start !important;
|
||||||
|
padding: 16rpx 10rpx !important;
|
||||||
|
min-height: 168rpx !important;
|
||||||
|
background: transparent !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.store-sidebar-item.wd-sidebar-item--active) {
|
||||||
|
background: #fff !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.store-sidebar-item .wd-sidebar-item__icon) {
|
||||||
|
margin-right: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.store-sidebar-item .wd-badge) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.store-sidebar-item__inner {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.store-sidebar-item__logo {
|
||||||
|
width: 68rpx;
|
||||||
|
height: 68rpx;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
background: #f0f0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.store-sidebar-item__name {
|
||||||
|
margin-top: 10rpx;
|
||||||
|
width: 100%;
|
||||||
|
font-size: 20rpx;
|
||||||
|
line-height: 26rpx;
|
||||||
|
color: #333;
|
||||||
|
text-align: center;
|
||||||
|
word-break: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
.store-main-wrap {
|
||||||
|
position: relative;
|
||||||
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.store-share-btn {
|
||||||
|
position: absolute;
|
||||||
|
right: 24rpx;
|
||||||
|
width: 48rpx;
|
||||||
|
height: 48rpx;
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
.store-main {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
|
height: 100%;
|
||||||
|
background: #f6f6f6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.store-main--loading {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.store-main__inner {
|
||||||
|
min-height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.store-banner {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
height: 360rpx;
|
||||||
|
background: #e8e8e8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.store-banner__img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.store-banner__img--empty {
|
||||||
|
background: #e8e8e8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.store-delivery-notice {
|
||||||
|
background: #fff7ed;
|
||||||
|
border-bottom: 1rpx solid #ffe8cc;
|
||||||
|
margin-bottom: 16rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.store-delivery-notice__bar) {
|
||||||
|
padding: 16rpx 24rpx !important;
|
||||||
|
font-size: 24rpx !important;
|
||||||
|
line-height: 34rpx !important;
|
||||||
|
border-radius: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.store-delivery-notice__bar .wd-notice-bar__wrap) {
|
||||||
|
height: 34rpx;
|
||||||
|
line-height: 34rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.store-info-block {
|
||||||
|
padding: 20rpx 24rpx 8rpx;
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.store-info-block__title {
|
||||||
|
font-size: 32rpx;
|
||||||
|
line-height: 40rpx;
|
||||||
|
font-weight: 700;
|
||||||
|
color: #1a1a1a;
|
||||||
|
}
|
||||||
|
|
||||||
|
.store-info-block__meta {
|
||||||
|
margin-top: 10rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 8rpx;
|
||||||
|
font-size: 22rpx;
|
||||||
|
line-height: 28rpx;
|
||||||
|
color: #7d7d7d;
|
||||||
|
}
|
||||||
|
|
||||||
|
.store-info-block__rating {
|
||||||
|
color: #333;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.store-coupon-row {
|
||||||
|
margin-top: 20rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ====== 优惠券标签 ====== */
|
/* ====== 优惠券标签 ====== */
|
||||||
@@ -895,7 +1173,7 @@ page {
|
|||||||
.dish-card-image {
|
.dish-card-image {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 330rpx;
|
height: 270rpx;
|
||||||
background: #f0f0f0;
|
background: #f0f0f0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
@@ -908,18 +1186,18 @@ page {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.dish-card-body {
|
.dish-card-body {
|
||||||
padding: 20rpx 20rpx 22rpx;
|
padding: 14rpx 14rpx 16rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dish-price {
|
.dish-price {
|
||||||
color: #e02e24;
|
color: #e02e24;
|
||||||
font-size: 32rpx;
|
font-size: 24rpx;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
line-height: 1.2;
|
line-height: 1.3;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dish-original-price {
|
.dish-original-price {
|
||||||
margin-left: 10rpx;
|
margin-left: 6rpx;
|
||||||
color: #b3b3b3;
|
color: #b3b3b3;
|
||||||
font-size: 22rpx;
|
font-size: 22rpx;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
@@ -929,49 +1207,49 @@ page {
|
|||||||
|
|
||||||
.dish-sales {
|
.dish-sales {
|
||||||
color: #999;
|
color: #999;
|
||||||
font-size: 24rpx;
|
font-size: 22rpx;
|
||||||
line-height: 1.35;
|
line-height: 1.3;
|
||||||
max-width: 48%;
|
// max-width: 48%;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dish-title {
|
.dish-title {
|
||||||
color: #1a1a1a;
|
color: #1a1a1a;
|
||||||
font-size: 28rpx;
|
font-size: 24rpx;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
line-height: 1.45;
|
line-height: 1.35;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dish-member {
|
.dish-member {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
max-width: calc(100% - 88rpx);
|
max-width: calc(100% - 80rpx);
|
||||||
}
|
}
|
||||||
|
|
||||||
.dish-member-inner {
|
.dish-member-inner {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
padding: 6rpx 18rpx;
|
padding: 2rpx 12rpx;
|
||||||
border-radius: 999rpx;
|
border-radius: 999rpx;
|
||||||
background: linear-gradient(180deg, #fff5eb 0%, #ffe8d6 100%);
|
background: linear-gradient(180deg, #fff5eb 0%, #ffe8d6 100%);
|
||||||
color: #c45c1a;
|
color: #c45c1a;
|
||||||
font-size: 24rpx;
|
font-size: 22rpx;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
line-height: 1.35;
|
line-height: 1.3;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dish-add-btn {
|
.dish-add-btn {
|
||||||
width: 56rpx;
|
width: 48rpx;
|
||||||
height: 56rpx;
|
height: 48rpx;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
background: #14181b;
|
background: #14181b;
|
||||||
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.12);
|
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.12);
|
||||||
}
|
}
|
||||||
|
|
||||||
.dish-promo {
|
.dish-promo {
|
||||||
padding: 12rpx 16rpx;
|
padding: 10rpx 14rpx;
|
||||||
border-radius: 12rpx;
|
border-radius: 12rpx;
|
||||||
background: #fff0f0;
|
background: #fff0f0;
|
||||||
}
|
}
|
||||||
@@ -980,7 +1258,7 @@ page {
|
|||||||
color: #e02e24;
|
color: #e02e24;
|
||||||
font-size: 22rpx;
|
font-size: 22rpx;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
line-height: 1.4;
|
line-height: 1.35;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* NEW 绑带标签 */
|
/* NEW 绑带标签 */
|
||||||
@@ -1000,11 +1278,11 @@ page {
|
|||||||
left: -66rpx;
|
left: -66rpx;
|
||||||
width: 240rpx;
|
width: 240rpx;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: 22rpx;
|
font-size: 20rpx;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
letter-spacing: 2rpx;
|
letter-spacing: 2rpx;
|
||||||
line-height: 44rpx;
|
line-height: 40rpx;
|
||||||
background: #E23636;
|
background: #E23636;
|
||||||
transform: rotate(-45deg);
|
transform: rotate(-45deg);
|
||||||
}
|
}
|
||||||
@@ -1028,12 +1306,12 @@ page {
|
|||||||
z-index: 3;
|
z-index: 3;
|
||||||
left: 16rpx;
|
left: 16rpx;
|
||||||
top: 16rpx;
|
top: 16rpx;
|
||||||
padding: 0 14rpx;
|
padding: 0 12rpx;
|
||||||
height: 48rpx;
|
height: 44rpx;
|
||||||
border-radius: 24rpx;
|
border-radius: 22rpx;
|
||||||
background: rgba(20, 24, 27, 0.75);
|
background: rgba(20, 24, 27, 0.75);
|
||||||
color: #fff;
|
color: #fff;
|
||||||
font-size: 24rpx;
|
font-size: 22rpx;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|||||||
@@ -44,8 +44,8 @@ const { t, locale } = useI18n();
|
|||||||
/** 首页运营图:按语言切换(中文 / 英文) */
|
/** 首页运营图:按语言切换(中文 / 英文) */
|
||||||
const HOME_PROMO_BANNERS = {
|
const HOME_PROMO_BANNERS = {
|
||||||
memberUpgrade: {
|
memberUpgrade: {
|
||||||
zh: 'https://www.howhowfresh.com/minio/ruoyi/2026/06/03/0b9a7f865aba442e84e51034a3ec900c.png',
|
zh: 'https://www.howhowfresh.com/minio/ruoyi/2026/06/05/d4a0d40503ac4206a0387af1ab869de6.png',
|
||||||
en: 'https://www.howhowfresh.com/minio/ruoyi/2026/06/03/c5b9df3a922d4d17ae1b6eb8c1d7524a.png',
|
en: 'https://www.howhowfresh.com/minio/ruoyi/2026/06/05/c01f1664626d417a9a7ca6165a20f06f.png',
|
||||||
},
|
},
|
||||||
deliveryTime: {
|
deliveryTime: {
|
||||||
zh: 'https://www.howhowfresh.com/minio/ruoyi/2026/06/03/c5673a8874594755bdde7ed7fcbd1982.jpg',
|
zh: 'https://www.howhowfresh.com/minio/ruoyi/2026/06/03/c5673a8874594755bdde7ed7fcbd1982.jpg',
|
||||||
@@ -407,19 +407,30 @@ const debouncedEmit = debounce(1300, (isCollected: boolean, id: string, type: Co
|
|||||||
@change-type="tabsTypeChange"
|
@change-type="tabsTypeChange"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<view
|
||||||
<image
|
class="home-member-banner"
|
||||||
:src="memberUpgradeBannerSrc"
|
:style="{ backgroundImage: `url(${memberUpgradeBannerSrc})` }"
|
||||||
class="w-100% h-[340rpx]"
|
>
|
||||||
mode="widthFix"
|
<view class="home-member-banner__actions">
|
||||||
|
<view
|
||||||
|
class="home-member-banner__btn"
|
||||||
@click="navigateTo('/pages-user/pages/member/index')"
|
@click="navigateTo('/pages-user/pages/member/index')"
|
||||||
/>
|
>
|
||||||
|
<text class="home-member-banner__btn-text">{{ t('pages.home.open-member') }}</text>
|
||||||
|
</view>
|
||||||
|
<view
|
||||||
|
class="home-member-banner__btn"
|
||||||
|
@click="navigateTo('/pages-user/pages/balance/index')"
|
||||||
|
>
|
||||||
|
<text class="home-member-banner__btn-text">{{ t('pages.home.recharge-now') }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
<image
|
<image
|
||||||
:src="deliveryTimeBannerSrc"
|
:src="deliveryTimeBannerSrc"
|
||||||
class="w-100% h-[200rpx] rounded-24rpx mt-4rpx"
|
class="w-100% h-[200rpx] rounded-24rpx mt-4rpx"
|
||||||
mode="widthFix"
|
mode="widthFix"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<!-- 精选商家和附近商家 -->
|
<!-- 精选商家和附近商家 -->
|
||||||
<view class="animate-in fade-in animate-ease-in animate-duration-300" v-if="isShowMerchant">
|
<view class="animate-in fade-in animate-ease-in animate-duration-300" v-if="isShowMerchant">
|
||||||
<!-- Featured on ChefLink 精选商家(浅底 + 横向卡片,对齐设计稿) -->
|
<!-- Featured on ChefLink 精选商家(浅底 + 横向卡片,对齐设计稿) -->
|
||||||
@@ -558,6 +569,45 @@ const debouncedEmit = debounce(1300, (isCollected: boolean, id: string, type: Co
|
|||||||
padding-right: 8rpx;
|
padding-right: 8rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.home-member-banner {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
height: 550rpx;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
background-position: center;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
}
|
||||||
|
|
||||||
|
.home-member-banner__actions {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 5rpx;
|
||||||
|
padding: 0 40rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 24rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.home-member-banner__btn {
|
||||||
|
flex: 1;
|
||||||
|
height: 72rpx;
|
||||||
|
padding: 0 24rpx;
|
||||||
|
border-radius: 999rpx;
|
||||||
|
background: #21ae39;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.home-member-banner__btn-text {
|
||||||
|
font-size: 28rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #ffffff;
|
||||||
|
line-height: 1.2;
|
||||||
|
}
|
||||||
|
|
||||||
.nearby-merchants-block {
|
.nearby-merchants-block {
|
||||||
background: #f2f2f2;
|
background: #f2f2f2;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user