Compare commits
2 Commits
41099f4190
...
new_ui
| Author | SHA1 | Date | |
|---|---|---|---|
| f214a61735 | |||
| 3fb5db48f2 |
+2
-2
@@ -2,8 +2,8 @@
|
|||||||
"name" : "CHEFLINK delivery",
|
"name" : "CHEFLINK delivery",
|
||||||
"appid" : "__UNI__06509BE",
|
"appid" : "__UNI__06509BE",
|
||||||
"description" : "",
|
"description" : "",
|
||||||
"versionName" : "3.2.9",
|
"versionName" : "3.3.2",
|
||||||
"versionCode" : 329,
|
"versionCode" : 332,
|
||||||
"transformPx" : false,
|
"transformPx" : false,
|
||||||
/* 5+App特有相关 */
|
/* 5+App特有相关 */
|
||||||
"app-plus" : {
|
"app-plus" : {
|
||||||
|
|||||||
@@ -1419,6 +1419,51 @@ const isUserMemberCheckout = computed(() => {
|
|||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function getCheckoutCartItemDiscountPrice(item: MerchantCartVo) {
|
||||||
|
return item.discountPrice ?? item.merchantDishVo?.discountPrice;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCheckoutCartItemOriginalPrice(item: MerchantCartVo) {
|
||||||
|
return item.originalPrice ?? item.merchantDishVo?.originalPrice;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCheckoutCartItemMemberPrice(item: MerchantCartVo) {
|
||||||
|
return item.memberPrice ?? item.merchantDishVo?.memberPrice;
|
||||||
|
}
|
||||||
|
|
||||||
|
function normalizeCheckoutPriceString(val: unknown) {
|
||||||
|
const s = String(val ?? '').trim();
|
||||||
|
if (!/^\d+(\.\d+)?$/.test(s)) return '0';
|
||||||
|
const [intRaw, decRaw = ''] = s.split('.');
|
||||||
|
const intPart = intRaw.replace(/^0+(?=\d)/, '') || '0';
|
||||||
|
const decPart = decRaw.slice(0, 2).padEnd(2, '0');
|
||||||
|
return `${intPart}.${decPart}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkoutPriceToCentString(val: unknown) {
|
||||||
|
const normalized = normalizeCheckoutPriceString(val);
|
||||||
|
const [intPart, decPart = '00'] = normalized.split('.');
|
||||||
|
return `${intPart}${decPart}`.replace(/^0+(?=\d)/, '') || '0';
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 与购物车列表一致:会员展示会员价,非会员展示折扣价 */
|
||||||
|
function getCheckoutLineDisplayPrice(item: MerchantCartVo) {
|
||||||
|
if (isUserMemberCheckout.value) {
|
||||||
|
return getCheckoutCartItemMemberPrice(item);
|
||||||
|
}
|
||||||
|
return getCheckoutCartItemDiscountPrice(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 与购物车列表一致:划线原价与当前展示价不一致时显示 */
|
||||||
|
function showCheckoutLineOriginalPrice(item: MerchantCartVo) {
|
||||||
|
const originalCent = checkoutPriceToCentString(getCheckoutCartItemOriginalPrice(item));
|
||||||
|
const currentCent =
|
||||||
|
isUserMemberCheckout.value && checkoutPriceToCentString(getCheckoutCartItemMemberPrice(item)) !== '0'
|
||||||
|
? checkoutPriceToCentString(getCheckoutCartItemMemberPrice(item))
|
||||||
|
: checkoutPriceToCentString(getCheckoutCartItemDiscountPrice(item));
|
||||||
|
return originalCent !== '0' && originalCent !== currentCent;
|
||||||
|
}
|
||||||
|
|
||||||
const cartTotalPieceCount = computed(() => {
|
const cartTotalPieceCount = computed(() => {
|
||||||
if (orderType.value === 'batch') {
|
if (orderType.value === 'batch') {
|
||||||
let n = 0;
|
let n = 0;
|
||||||
@@ -1773,7 +1818,13 @@ function handleClose(merchantId?: string) {
|
|||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="text-30rpx text-#333 font-500 shrink-0 ml-16rpx">${{ item.merchantDishVo?.discountPrice }}</view>
|
<view class="checkout-order-line-price shrink-0 ml-16rpx text-right">
|
||||||
|
<view class="text-30rpx text-#333 font-500">${{ getCheckoutLineDisplayPrice(item) }}</view>
|
||||||
|
<view
|
||||||
|
v-if="showCheckoutLineOriginalPrice(item)"
|
||||||
|
class="text-24rpx text-#7D7D7D line-through mt-4rpx"
|
||||||
|
>${{ getCheckoutCartItemOriginalPrice(item) }}</view>
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</wd-collapse-item>
|
</wd-collapse-item>
|
||||||
</wd-collapse>
|
</wd-collapse>
|
||||||
@@ -1863,11 +1914,11 @@ function handleClose(merchantId?: string) {
|
|||||||
<view class="flex items-center justify-between mt-12rpx">
|
<view class="flex items-center justify-between mt-12rpx">
|
||||||
<view class="flex items-center">
|
<view class="flex items-center">
|
||||||
<text class="text-[#333333] text-28rpx font-500"
|
<text class="text-[#333333] text-28rpx font-500"
|
||||||
>${{ item.merchantDishVo?.discountPrice }}</text>
|
>${{ getCheckoutLineDisplayPrice(item) }}</text>
|
||||||
<text
|
<text
|
||||||
v-if="item.merchantDishVo?.originalPrice && item.merchantDishVo?.originalPrice !== item.merchantDishVo?.discountPrice"
|
v-if="showCheckoutLineOriginalPrice(item)"
|
||||||
class="text-[#7D7D7D] text-22rpx line-through ml-8rpx"
|
class="text-[#7D7D7D] text-22rpx line-through ml-8rpx"
|
||||||
>${{ item.merchantDishVo?.originalPrice }}</text>
|
>${{ getCheckoutCartItemOriginalPrice(item) }}</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="text-[#7D7D7D] text-22rpx">
|
<view class="text-[#7D7D7D] text-22rpx">
|
||||||
x{{ item.count }}
|
x{{ item.count }}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
import { ref, computed } from 'vue'
|
import { ref, computed } from 'vue'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
import useEventEmit from "@/hooks/useEventEmit";
|
import useEventEmit from "@/hooks/useEventEmit";
|
||||||
import {CollectionType, EventEnum} from "@/constant/enums";
|
import { CollectionType, EventEnum } from "@/constant/enums";
|
||||||
import { useConfigStore, useUserStore } from "@/store";
|
import { useConfigStore, useUserStore } from "@/store";
|
||||||
import Config from '@/config/index'
|
import Config from '@/config/index'
|
||||||
import { debounce } from 'throttle-debounce'
|
import { debounce } from 'throttle-debounce'
|
||||||
@@ -26,7 +26,7 @@ import {
|
|||||||
appRecipeCategoryListGet
|
appRecipeCategoryListGet
|
||||||
} from "@/service";
|
} from "@/service";
|
||||||
import usePage from "@/hooks/usePage";
|
import usePage from "@/hooks/usePage";
|
||||||
import {getFeaturedDishList} from "@/pages-store/service";
|
import { getFeaturedDishList } from "@/pages-store/service";
|
||||||
import {
|
import {
|
||||||
buildQuickTopicUrl,
|
buildQuickTopicUrl,
|
||||||
isQuickTopicSlug,
|
isQuickTopicSlug,
|
||||||
@@ -44,12 +44,12 @@ const { t, locale } = useI18n();
|
|||||||
/** 首页运营图:按语言切换(中文 / 英文) */
|
/** 首页运营图:按语言切换(中文 / 英文) */
|
||||||
const HOME_PROMO_BANNERS = {
|
const HOME_PROMO_BANNERS = {
|
||||||
memberUpgrade: {
|
memberUpgrade: {
|
||||||
zh: 'https://www.howhowfresh.com/minio/ruoyi/2026/06/05/d4a0d40503ac4206a0387af1ab869de6.png',
|
zh: 'https://www.howhowfresh.com/minio/ruoyi/2026/06/18/edb822ef721642b39e52f19b2e5df949.png',
|
||||||
en: 'https://www.howhowfresh.com/minio/ruoyi/2026/06/05/c01f1664626d417a9a7ca6165a20f06f.png',
|
en: 'https://www.howhowfresh.com/minio/ruoyi/2026/06/18/6a8a43575f70425eb6b8071633708531.png',
|
||||||
},
|
},
|
||||||
deliveryTime: {
|
deliveryTime: {
|
||||||
zh: 'https://www.howhowfresh.com/minio/ruoyi/2026/06/03/c5673a8874594755bdde7ed7fcbd1982.jpg',
|
zh: 'https://www.howhowfresh.com/minio/ruoyi/2026/06/18/8a0fcfab0a6e4ff29fdecdc41e01ebdb.png',
|
||||||
en: 'https://www.howhowfresh.com/minio/ruoyi/2026/06/03/1da02f1e0af34cea91a4f643247176be.png',
|
en: 'https://www.howhowfresh.com/minio/ruoyi/2026/06/18/99c6b38e7f1e4337baee0ec5e42c76ba.png',
|
||||||
},
|
},
|
||||||
} as const
|
} as const
|
||||||
|
|
||||||
@@ -84,7 +84,7 @@ function getDishPromoLabel(item: Record<string, unknown>): string {
|
|||||||
|
|
||||||
|
|
||||||
function navigateTo(url: string) {
|
function navigateTo(url: string) {
|
||||||
if(userStore.checkLogin()) {
|
if (userStore.checkLogin()) {
|
||||||
uni.navigateTo({
|
uni.navigateTo({
|
||||||
url,
|
url,
|
||||||
});
|
});
|
||||||
@@ -95,7 +95,7 @@ const swiperList = ref<any[]>([])
|
|||||||
|
|
||||||
async function initData() {
|
async function initData() {
|
||||||
// 只在首次加载时显示骨架屏,避免切换时的白屏
|
// 只在首次加载时显示骨架屏,避免切换时的白屏
|
||||||
if(featuredList.value.length === 0) {
|
if (featuredList.value.length === 0) {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
}
|
}
|
||||||
getAppMarketActivityList()
|
getAppMarketActivityList()
|
||||||
@@ -168,9 +168,9 @@ function getAppFeaturedList() {
|
|||||||
lat: userStore.userLocation.latitude,
|
lat: userStore.userLocation.latitude,
|
||||||
lng: userStore.userLocation.longitude,
|
lng: userStore.userLocation.longitude,
|
||||||
}
|
}
|
||||||
}).then(res=> {
|
}).then(res => {
|
||||||
featuredList.value = res.data || []
|
featuredList.value = res.data || []
|
||||||
}).finally(()=> {
|
}).finally(() => {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -183,7 +183,7 @@ function getAppNearbyListPost() {
|
|||||||
lat: userStore.userLocation.latitude,
|
lat: userStore.userLocation.latitude,
|
||||||
lng: userStore.userLocation.longitude,
|
lng: userStore.userLocation.longitude,
|
||||||
}
|
}
|
||||||
}).then(res=> {
|
}).then(res => {
|
||||||
nearbyList.value = res.data || []
|
nearbyList.value = res.data || []
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -200,7 +200,7 @@ function toggleDiscount(value: number) {
|
|||||||
discount.value = value;
|
discount.value = value;
|
||||||
// paging.value.refresh()
|
// paging.value.refresh()
|
||||||
}
|
}
|
||||||
const {paging, dataList, queryList} = usePage(getList)
|
const { paging, dataList, queryList } = usePage(getList)
|
||||||
function getList(pageNum: number, pageSize: number) {
|
function getList(pageNum: number, pageSize: number) {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
getFeaturedDishList({
|
getFeaturedDishList({
|
||||||
@@ -208,7 +208,7 @@ function getList(pageNum: number, pageSize: number) {
|
|||||||
pageSize,
|
pageSize,
|
||||||
}).then(res => {
|
}).then(res => {
|
||||||
console.log('查询精选菜品列表', res)
|
console.log('查询精选菜品列表', res)
|
||||||
resolve({rows: res.rows})
|
resolve({ rows: res.rows })
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -263,8 +263,8 @@ function tabsTypeChange(id: string | number) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 是否展示精选商家和附近商家 true 显示 false隐藏
|
// 是否展示精选商家和附近商家 true 显示 false隐藏
|
||||||
const isShowMerchant = computed(()=> {
|
const isShowMerchant = computed(() => {
|
||||||
if(!selfPickup.value && !discount.value && !props.scoreRange && !props.price && !currentCategory.value) {
|
if (!selfPickup.value && !discount.value && !props.scoreRange && !props.price && !currentCategory.value) {
|
||||||
return true // 没有筛选条件时显示
|
return true // 没有筛选条件时显示
|
||||||
} else {
|
} else {
|
||||||
return true // 有筛选条件时隐藏
|
return true // 有筛选条件时隐藏
|
||||||
@@ -321,9 +321,9 @@ function handleClickSwiper(item: any) {
|
|||||||
case 5: // 充值活动
|
case 5: // 充值活动
|
||||||
navigateTo('/pages-user/pages/recharge/activity-detail?id=' + item.id)
|
navigateTo('/pages-user/pages/recharge/activity-detail?id=' + item.id)
|
||||||
break
|
break
|
||||||
// case 4:
|
// case 4:
|
||||||
// navigateTo('/pages/ai/chat/index')
|
// navigateTo('/pages/ai/chat/index')
|
||||||
// break
|
// break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -334,19 +334,19 @@ function navigateToDishes(item: any) {
|
|||||||
}
|
}
|
||||||
// 收藏菜品
|
// 收藏菜品
|
||||||
function handleDishCollectionClick(item: any) {
|
function handleDishCollectionClick(item: any) {
|
||||||
debouncedEmit(item.isCollect, item.id, CollectionType.DISH, ()=> {
|
debouncedEmit(item.isCollect, item.id, CollectionType.DISH, () => {
|
||||||
item.isCollect = !item.isCollect
|
item.isCollect = !item.isCollect
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
// 防抖处理函数
|
// 防抖处理函数
|
||||||
const debouncedEmit = debounce(1300, (isCollected: boolean, id: string, type: CollectionType, callback: ()=> void) => {
|
const debouncedEmit = debounce(1300, (isCollected: boolean, id: string, type: CollectionType, callback: () => void) => {
|
||||||
// 收藏接口
|
// 收藏接口
|
||||||
appCollectCollectPost({
|
appCollectCollectPost({
|
||||||
body: {
|
body: {
|
||||||
targetId: id,
|
targetId: id,
|
||||||
targetType: type
|
targetType: type
|
||||||
}
|
}
|
||||||
}).then(res=> {
|
}).then(res => {
|
||||||
callback()
|
callback()
|
||||||
})
|
})
|
||||||
}, {
|
}, {
|
||||||
@@ -355,210 +355,140 @@ const debouncedEmit = debounce(1300, (isCollected: boolean, id: string, type: Co
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<view
|
<view class="home-page-root" :style="[
|
||||||
class="home-page-root"
|
{
|
||||||
:style="[
|
height: configStore.windowHeight + 'px',
|
||||||
{
|
},
|
||||||
height: configStore.windowHeight + 'px',
|
]">
|
||||||
},
|
<z-paging @onRefresh="onRefresh" ref="paging" v-model="dataList" :auto="false" @query="queryList"
|
||||||
]"
|
@scroll="onPageScroll" :refresher-enabled="true" :auto-show-back-to-top="false">
|
||||||
>
|
<template #top>
|
||||||
<z-paging @onRefresh="onRefresh" ref="paging" v-model="dataList" :auto="false" @query="queryList" @scroll="onPageScroll" :refresher-enabled="true" :auto-show-back-to-top="false">
|
<status-bar />
|
||||||
<template #top>
|
<home-top-header :app-name="Config.appName" :location-text="userStore.userLocation.location"
|
||||||
<status-bar />
|
:cart-badge-total="cartBadgeTotal" :is-login="userStore.isLogin"
|
||||||
<home-top-header
|
@click-location="navigateTo('/pages-user/pages/search-address/index')" @click-cart="goCart" />
|
||||||
:app-name="Config.appName"
|
</template>
|
||||||
:location-text="userStore.userLocation.location"
|
<view class="animate-in fade-in animate-ease-out animate-duration-300"
|
||||||
:cart-badge-total="cartBadgeTotal"
|
v-show="loading && featuredList.length === 0">
|
||||||
:is-login="userStore.isLogin"
|
<home-skeleton />
|
||||||
@click-location="navigateTo('/pages-user/pages/search-address/index')"
|
</view>
|
||||||
@click-cart="goCart"
|
<view class="px-24rpx pt-12rpx pb-8rpx">
|
||||||
/>
|
<search />
|
||||||
</template>
|
<msg-box />
|
||||||
<view
|
<!-- 分类标签 -->
|
||||||
class="animate-in fade-in animate-ease-out animate-duration-300"
|
<view class="mt-28rpx" v-if="appMerchantLabelList.length > 0">
|
||||||
v-show="loading && featuredList.length === 0"
|
<class-bullet :categories="appMerchantLabelList" @itemClick="handleItemClick" />
|
||||||
>
|
|
||||||
<home-skeleton />
|
|
||||||
</view>
|
</view>
|
||||||
<view class="px-24rpx pt-12rpx pb-8rpx">
|
</view>
|
||||||
<search />
|
<!-- 轮播图:/app/marketActivity/list -->
|
||||||
<msg-box />
|
<swiper v-if="swiperList.length > 0" class="card-swiper" :circular="swiperList.length > 1"
|
||||||
<!-- 分类标签 -->
|
:autoplay="swiperList.length > 1">
|
||||||
<view class="mt-28rpx" v-if="appMerchantLabelList.length > 0">
|
<swiper-item v-for="(item, sIdx) in swiperList" :key="item.id ?? sIdx" @click="handleClickSwiper(item)">
|
||||||
<class-bullet :categories="appMerchantLabelList" @itemClick="handleItemClick" />
|
<image :src="item.activityImage" class="swiper-item-content w-full h-100%" mode="scaleToFill"></image>
|
||||||
|
</swiper-item>
|
||||||
|
</swiper>
|
||||||
|
|
||||||
|
<!-- 快捷入口(固定五项,跳转精选菜品专题页) -->
|
||||||
|
<tabs-type :current-id="currentCategory" class="mt-28rpx mb-24rpx home-tabs-quick"
|
||||||
|
@change-type="tabsTypeChange" />
|
||||||
|
|
||||||
|
<view class="home-promo-block px-24rpx">
|
||||||
|
<image :src="memberUpgradeBannerSrc" class="home-promo-banner-img" mode="widthFix" />
|
||||||
|
<view class="home-promo-actions">
|
||||||
|
<view class="home-promo-btn" @click="navigateTo('/pages-user/pages/member/index')">
|
||||||
|
<text class="home-promo-btn-text">{{ t('pages.home.open-member') }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="home-promo-btn" @click="navigateTo('/pages-user/pages/recharge/index')">
|
||||||
|
<text class="home-promo-btn-text">{{ t('pages.home.recharge-now') }}</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<!-- 轮播图:/app/marketActivity/list -->
|
<image :src="deliveryTimeBannerSrc" class="home-promo-banner-img" mode="widthFix" />
|
||||||
<swiper
|
</view>
|
||||||
v-if="swiperList.length > 0"
|
<!-- 精选商家和附近商家 -->
|
||||||
class="card-swiper"
|
<view class="animate-in fade-in animate-ease-in animate-duration-300" v-if="isShowMerchant">
|
||||||
:circular="swiperList.length > 1"
|
<!-- Featured on ChefLink 精选商家(浅底 + 横向卡片,对齐设计稿) -->
|
||||||
:autoplay="swiperList.length > 1"
|
<view v-if="featuredList.length > 0" class="featured-merchants-section mt-36rpx px-24rpx pt-8rpx pb-16rpx">
|
||||||
>
|
<view class="mb-24rpx px-6rpx text-28rpx lh-36rpx text-#1a1a1a">
|
||||||
<swiper-item
|
{{ t('pages.home.featured-on') }}
|
||||||
v-for="(item, sIdx) in swiperList"
|
|
||||||
:key="item.id ?? sIdx"
|
|
||||||
@click="handleClickSwiper(item)"
|
|
||||||
>
|
|
||||||
<image
|
|
||||||
:src="item.activityImage"
|
|
||||||
class="swiper-item-content w-full h-100%"
|
|
||||||
mode="scaleToFill"
|
|
||||||
></image>
|
|
||||||
</swiper-item>
|
|
||||||
</swiper>
|
|
||||||
|
|
||||||
<!-- 快捷入口(固定五项,跳转精选菜品专题页) -->
|
|
||||||
<tabs-type
|
|
||||||
:current-id="currentCategory"
|
|
||||||
class="mt-28rpx mb-24rpx home-tabs-quick"
|
|
||||||
@change-type="tabsTypeChange"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<view
|
|
||||||
class="home-member-banner"
|
|
||||||
:style="{ backgroundImage: `url(${memberUpgradeBannerSrc})` }"
|
|
||||||
>
|
|
||||||
<view class="home-member-banner__actions">
|
|
||||||
<view
|
|
||||||
class="home-member-banner__btn"
|
|
||||||
@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/recharge/index')"
|
|
||||||
>
|
|
||||||
<text class="home-member-banner__btn-text">{{ t('pages.home.recharge-now') }}</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<image
|
|
||||||
:src="deliveryTimeBannerSrc"
|
|
||||||
class="w-100% h-[200rpx] rounded-24rpx mt-4rpx"
|
|
||||||
mode="widthFix"
|
|
||||||
/>
|
|
||||||
<!-- 精选商家和附近商家 -->
|
|
||||||
<view class="animate-in fade-in animate-ease-in animate-duration-300" v-if="isShowMerchant">
|
|
||||||
<!-- Featured on ChefLink 精选商家(浅底 + 横向卡片,对齐设计稿) -->
|
|
||||||
<view v-if="featuredList.length > 0" class="featured-merchants-section mt-36rpx px-24rpx pt-8rpx pb-16rpx">
|
|
||||||
<view class="mb-24rpx px-6rpx text-28rpx lh-36rpx text-#1a1a1a">
|
|
||||||
{{ t('pages.home.featured-on') }}
|
|
||||||
</view>
|
|
||||||
<featured-on :list="featuredList" />
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- Nearby Merchants 附近商家 -->
|
|
||||||
<view v-if="nearbyList.length > 0" class="nearby-merchants-block mt-36rpx px-24rpx pb-16rpx">
|
|
||||||
<view class="mb-24rpx px-6rpx text-28rpx lh-36rpx text-#1a1a1a ">
|
|
||||||
{{ t('pages.home.nearby-merchants') }}
|
|
||||||
</view>
|
|
||||||
<nearby-merchants :list="nearbyList" />
|
|
||||||
</view>
|
</view>
|
||||||
|
<featured-on :list="featuredList" />
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- List 精选菜品瀑布流(浅底 + 白卡片 + 阴影,结构对齐设计稿) -->
|
<!-- Nearby Merchants 附近商家 -->
|
||||||
<view class="featured-dishes-section mt-36rpx px-24rpx pb-40rpx">
|
<view v-if="nearbyList.length > 0" class="nearby-merchants-block mt-36rpx px-24rpx pb-16rpx">
|
||||||
<view class="mb-24rpx px-6rpx text-28rpx lh-36rpx text-#1a1a1a "
|
<view class="mb-24rpx px-6rpx text-28rpx lh-36rpx text-#1a1a1a ">
|
||||||
>{{ t('pages.home.featured-dishes') }}</view>
|
{{ t('pages.home.nearby-merchants') }}
|
||||||
<view class="waterfall-row flex gap-16rpx items-start">
|
</view>
|
||||||
<view
|
<nearby-merchants :list="nearbyList" />
|
||||||
v-for="(col, colIndex) in featuredDishColumns"
|
</view>
|
||||||
:key="colIndex"
|
</view>
|
||||||
class="waterfall-col flex-1 min-w-0 flex flex-col gap-16rpx"
|
|
||||||
>
|
<!-- List 精选菜品瀑布流(浅底 + 白卡片 + 阴影,结构对齐设计稿) -->
|
||||||
<view
|
<view class="featured-dishes-section mt-36rpx px-24rpx pb-40rpx">
|
||||||
v-for="item in col"
|
<view class="mb-24rpx px-6rpx text-28rpx lh-36rpx text-#1a1a1a ">{{ t('pages.home.featured-dishes') }}</view>
|
||||||
:key="item.id || String(item.merchantId) + '-' + item.dishName"
|
<view class="waterfall-row flex gap-16rpx items-start">
|
||||||
@click="navigateToDishes(item)"
|
<view v-for="(col, colIndex) in featuredDishColumns" :key="colIndex"
|
||||||
class="featured-dish-card w-full"
|
class="waterfall-col flex-1 min-w-0 flex flex-col gap-16rpx">
|
||||||
>
|
<view v-for="item in col" :key="item.id || String(item.merchantId) + '-' + item.dishName"
|
||||||
<view class="featured-dish-image">
|
@click="navigateToDishes(item)" class="featured-dish-card w-full">
|
||||||
<view v-if="item.isNew == 1" class="dish-new-ribbon">
|
<view class="featured-dish-image">
|
||||||
<text class="dish-new-ribbon__text">NEW</text>
|
<view v-if="item.isNew == 1" class="dish-new-ribbon">
|
||||||
</view>
|
<text class="dish-new-ribbon__text">NEW</text>
|
||||||
<image
|
|
||||||
:src="item?.dishImage?.split(',')[0]"
|
|
||||||
mode="aspectFill"
|
|
||||||
class="featured-dish-img"
|
|
||||||
/>
|
|
||||||
<view
|
|
||||||
v-if="isSoldOutStock(item?.stock)"
|
|
||||||
class="featured-dish-sold-dim"
|
|
||||||
/>
|
|
||||||
<image
|
|
||||||
v-if="isSoldOutStock(item?.stock)"
|
|
||||||
src="/static/app/images/SoldOut.png"
|
|
||||||
mode="aspectFill"
|
|
||||||
class="featured-dish-sold-overlay"
|
|
||||||
/>
|
|
||||||
<view
|
|
||||||
@click.stop="handleDishCollectionClick(item)"
|
|
||||||
class="featured-dish-collect w-56rpx h-56rpx absolute z-4 top-12rpx right-12rpx center"
|
|
||||||
>
|
|
||||||
<image
|
|
||||||
v-if="!item.isCollect"
|
|
||||||
src="@img-store/1334.png"
|
|
||||||
mode="aspectFill"
|
|
||||||
class="w-44rpx h-44rpx featured-dish-collect-icon"
|
|
||||||
/>
|
|
||||||
<image
|
|
||||||
v-else
|
|
||||||
src="@img-store/1337.png"
|
|
||||||
mode="aspectFill"
|
|
||||||
class="w-44rpx h-44rpx featured-dish-collect-icon"
|
|
||||||
/>
|
|
||||||
</view>
|
|
||||||
</view>
|
</view>
|
||||||
<view class="featured-dish-body">
|
<image :src="item?.dishImage?.split(',')[0]" mode="aspectFill" class="featured-dish-img" />
|
||||||
<view class="featured-dish-meta flex items-start justify-between gap-12rpx mb-14rpx">
|
<view v-if="isSoldOutStock(item?.stock)" class="featured-dish-sold-dim" />
|
||||||
<view class="min-w-0 flex-1">
|
<image v-if="isSoldOutStock(item?.stock)" src="/static/app/images/SoldOut.png" mode="aspectFill"
|
||||||
<text class="featured-dish-price">US${{item?.originalPrice }}</text>
|
class="featured-dish-sold-overlay" />
|
||||||
<!-- <text
|
<view @click.stop="handleDishCollectionClick(item)"
|
||||||
|
class="featured-dish-collect w-56rpx h-56rpx absolute z-4 top-12rpx right-12rpx center">
|
||||||
|
<image v-if="!item.isCollect" src="@img-store/1334.png" mode="aspectFill"
|
||||||
|
class="w-44rpx h-44rpx featured-dish-collect-icon" />
|
||||||
|
<image v-else src="@img-store/1337.png" mode="aspectFill"
|
||||||
|
class="w-44rpx h-44rpx featured-dish-collect-icon" />
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="featured-dish-body">
|
||||||
|
<view class="featured-dish-meta flex items-start justify-between gap-12rpx mb-14rpx">
|
||||||
|
<view class="min-w-0 flex-1">
|
||||||
|
<text class="featured-dish-price">US${{ item?.originalPrice }}</text>
|
||||||
|
<!-- <text
|
||||||
v-if="Number(item?.originalPrice) > Number(item?.discountPrice)"
|
v-if="Number(item?.originalPrice) > Number(item?.discountPrice)"
|
||||||
class="featured-dish-original"
|
class="featured-dish-original"
|
||||||
>US${{ item?.originalPrice }}</text> -->
|
>US${{ item?.originalPrice }}</text> -->
|
||||||
</view>
|
|
||||||
<text class="featured-dish-sales shrink-0">{{ t('pages-store.store.sales') }}: {{ formatSalesCount(item?.salesCount) }}</text>
|
|
||||||
</view>
|
</view>
|
||||||
<view class="featured-dish-title line-clamp-2 mb-16rpx">
|
<text class="featured-dish-sales shrink-0">{{ t('pages-store.store.sales') }}: {{
|
||||||
{{ item?.dishName }}
|
formatSalesCount(item?.salesCount) }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="featured-dish-title line-clamp-2 mb-16rpx">
|
||||||
|
{{ item?.dishName }}
|
||||||
|
</view>
|
||||||
|
<view class="flex items-center justify-between gap-12rpx">
|
||||||
|
<view v-if="Number(item?.memberPrice) > 0" class="featured-dish-member shrink min-w-0">
|
||||||
|
<text class="featured-dish-member-inner">{{ t('pages-store.store.members') }}: US${{
|
||||||
|
item?.memberPrice
|
||||||
|
}}</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="flex items-center justify-between gap-12rpx">
|
<view v-else class="flex-1 min-w-0"></view>
|
||||||
<view
|
<view class="featured-dish-add shrink-0">
|
||||||
v-if="Number(item?.memberPrice) > 0"
|
<image src="/static/app/images/add_cart.png" class="featured-dish-add__icon" />
|
||||||
class="featured-dish-member shrink min-w-0"
|
|
||||||
>
|
|
||||||
<text class="featured-dish-member-inner">{{ t('pages-store.store.members') }}: US${{ item?.memberPrice }}</text>
|
|
||||||
</view>
|
|
||||||
<view v-else class="flex-1 min-w-0"></view>
|
|
||||||
<view class="featured-dish-add shrink-0">
|
|
||||||
<image
|
|
||||||
src="/static/app/images/add_cart.png"
|
|
||||||
class="featured-dish-add__icon"
|
|
||||||
/>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view
|
|
||||||
v-if="getDishPromoLabel(item as Record<string, unknown>)"
|
|
||||||
class="featured-dish-promo mt-16rpx"
|
|
||||||
>
|
|
||||||
<text class="featured-dish-promo-text">{{ getDishPromoLabel(item as Record<string, unknown>) }}</text>
|
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
<view v-if="getDishPromoLabel(item as Record<string, unknown>)" class="featured-dish-promo mt-16rpx">
|
||||||
|
<text class="featured-dish-promo-text">{{ getDishPromoLabel(item as Record<string, unknown>) }}</text>
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<template #bottom>
|
</view>
|
||||||
<view class="h-50px"></view>
|
<template #bottom>
|
||||||
<view :style="[configStore.iosSafeBottomPlaceholder]"></view>
|
<view class="h-50px"></view>
|
||||||
</template>
|
<view :style="[configStore.iosSafeBottomPlaceholder]"></view>
|
||||||
</z-paging>
|
</template>
|
||||||
|
</z-paging>
|
||||||
<!-- 回到顶部(购物车已并入顶栏,不再使用底部浮条) -->
|
<!-- 回到顶部(购物车已并入顶栏,不再使用底部浮条) -->
|
||||||
<view v-if="showBackToTop" @click="scrollToTop" class="home-back-top fixed left-30rpx w-88rpx h-88rpx bg-#14181B rounded-50% center shadow-lg">
|
<view v-if="showBackToTop" @click="scrollToTop"
|
||||||
|
class="home-back-top fixed left-30rpx w-88rpx h-88rpx bg-#14181B rounded-50% center shadow-lg">
|
||||||
<image src="@img/chef/119.png" class="w-40rpx h-40rpx shrink-0 rotate-180"></image>
|
<image src="@img/chef/119.png" class="w-40rpx h-40rpx shrink-0 rotate-180"></image>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -578,28 +508,29 @@ const debouncedEmit = debounce(1300, (isCollected: boolean, id: string, type: Co
|
|||||||
padding-right: 8rpx;
|
padding-right: 8rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.home-member-banner {
|
.home-promo-block {
|
||||||
position: relative;
|
display: flex;
|
||||||
width: 100%;
|
flex-direction: column;
|
||||||
height: 550rpx;
|
gap: 24rpx;
|
||||||
background-size: 100% 100%;
|
margin-top: 8rpx;
|
||||||
background-position: center;
|
margin-bottom: 8rpx;
|
||||||
background-repeat: no-repeat;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.home-member-banner__actions {
|
.home-promo-banner-img {
|
||||||
position: absolute;
|
display: block;
|
||||||
left: 0;
|
width: 100%;
|
||||||
right: 0;
|
border-radius: 24rpx;
|
||||||
bottom: 5rpx;
|
}
|
||||||
padding: 0 40rpx;
|
|
||||||
|
.home-promo-actions {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
gap: 24rpx;
|
gap: 24rpx;
|
||||||
|
padding: 0 8rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.home-member-banner__btn {
|
.home-promo-btn {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
height: 72rpx;
|
height: 72rpx;
|
||||||
padding: 0 24rpx;
|
padding: 0 24rpx;
|
||||||
@@ -610,7 +541,7 @@ const debouncedEmit = debounce(1300, (isCollected: boolean, id: string, type: Co
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.home-member-banner__btn-text {
|
.home-promo-btn-text {
|
||||||
font-size: 28rpx;
|
font-size: 28rpx;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
@@ -629,6 +560,7 @@ const debouncedEmit = debounce(1300, (isCollected: boolean, id: string, type: Co
|
|||||||
.card-swiper {
|
.card-swiper {
|
||||||
height: 420rpx;
|
height: 420rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.swiper-item-content {
|
.swiper-item-content {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|||||||
@@ -127,8 +127,10 @@ const isUserMember = computed(()=> {
|
|||||||
function handleTabClick(item: Tab) {
|
function handleTabClick(item: Tab) {
|
||||||
switch (item.code) {
|
switch (item.code) {
|
||||||
case "inviteFriends": {
|
case "inviteFriends": {
|
||||||
// R.both(checkNeedLogin, R.pipe(() => emits("inviteUser"), R.T))(item.isLogin)
|
R.both(
|
||||||
emits("inviteUser");
|
checkNeedLogin,
|
||||||
|
R.pipe(() => emits("inviteUser"), R.T)
|
||||||
|
)(item.isLogin);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "support": {
|
case "support": {
|
||||||
|
|||||||
Reference in New Issue
Block a user