diff --git a/src/locale/en.json b/src/locale/en.json index b7f1252..0064574 100644 --- a/src/locale/en.json +++ b/src/locale/en.json @@ -232,6 +232,8 @@ "featured-on": "Featured on CHEFLINK", "featured-dishes": "Featured Dishes", "nearby-merchants": "Nearby Merchants", + "open-member": "Become a Member", + "recharge-now": "Recharge Now", "quickTabs": { "memberZone": "Member Zone", "liveSeafoodAir": "Limited Live Seafood", diff --git a/src/locale/zh-Hans.json b/src/locale/zh-Hans.json index a4bcf0b..3666d53 100644 --- a/src/locale/zh-Hans.json +++ b/src/locale/zh-Hans.json @@ -232,6 +232,8 @@ "featured-on": "精选商家", "featured-dishes": "精选菜品", "nearby-merchants": "附近商家", + "open-member": "开通会员", + "recharge-now": "立即充值", "quickTabs": { "memberZone": "会员专区", "liveSeafoodAir": "限量空运活海鲜", diff --git a/src/manifest.json b/src/manifest.json index c3edfab..07165cb 100644 --- a/src/manifest.json +++ b/src/manifest.json @@ -2,8 +2,8 @@ "name" : "CHEFLINK delivery", "appid" : "__UNI__06509BE", "description" : "", - "versionName" : "3.1.9", - "versionCode" : 319, + "versionName" : "3.2.0", + "versionCode" : 320, "transformPx" : false, /* 5+App特有相关 */ "app-plus" : { diff --git a/src/pages-store/pages/store/components/store-main-skeleton.vue b/src/pages-store/pages/store/components/store-main-skeleton.vue new file mode 100644 index 0000000..3706f20 --- /dev/null +++ b/src/pages-store/pages/store/components/store-main-skeleton.vue @@ -0,0 +1,166 @@ + + + + + diff --git a/src/pages-store/pages/store/components/store-skeleton.vue b/src/pages-store/pages/store/components/store-skeleton.vue index 6397add..3714fe0 100644 --- a/src/pages-store/pages/store/components/store-skeleton.vue +++ b/src/pages-store/pages/store/components/store-skeleton.vue @@ -1,227 +1,127 @@ diff --git a/src/pages-store/pages/store/index.vue b/src/pages-store/pages/store/index.vue index 2a8a192..e5d8f73 100644 --- a/src/pages-store/pages/store/index.vue +++ b/src/pages-store/pages/store/index.vue @@ -3,33 +3,129 @@ import { debounce } from 'throttle-debounce' import dayjs from 'dayjs' import Config from '@/config/index' const { t, locale } = useI18n(); -import StoreSkeleton from './components/store-skeleton.vue'; -import { useScrollThreshold } from '@/hooks/useScrollThreshold' +import StoreSkeleton from './components/store-skeleton.vue' +import StoreMainSkeleton from './components/store-main-skeleton.vue' import { - appCollectCollectPost, appMerchantCartCalculateSavingsPost, appMerchantCartListByMerchantIdPost, + appCollectCollectPost, + appMerchantCartCalculateSavingsPost, + appMerchantCartListByMerchantIdPost, + appMerchantCartListMerchantPost, appMerchantDetailMerchantIdGet, appMerchantDishDishIdGet, - appMerchantMenuMenuListByUserPost, type MerchantCartVo, - type MerchantVo -} from "@/service"; -import {CollectionType} from "@/constant/enums"; -import {useUserStore} from "@/store"; -import { parseBusinessHoursUtils, getDistanceInMiles, parseMerchantCartPayload } from "@/utils/utils"; + appMerchantMenuMenuListByUserPost, + type MerchantCartVo, + type MerchantVo, +} from '@/service' +import { CollectionType } from '@/constant/enums' +import { useConfigStore, useUserStore } from '@/store' +import { formatSalesCount, getDistanceInMiles, parseMerchantCartPayload } from '@/utils/utils' import { formatDeliveryScheduleDays } from "@/utils/deliverySchedule"; 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 loading = ref(true) +/** 切换店铺时右侧内容区骨架屏 */ +const mainLoading = ref(false) +const userStore = useUserStore() +const configStore = useConfigStore() const storeID = ref('') -onLoad((options: any)=> { - console.log(options) - if(options.id) { - storeID.value = options.id +const merchantList = ref([]) +const activeMerchantId = ref('') + +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() - // getMenuList() + } else { + loading.value = false } }) @@ -137,13 +233,17 @@ function parseBusinessHours(businessHours: string) { } const storeDistance = ref(null) -function getStoreDetail() { - loading.value = true +function getStoreDetail(silent = false) { + if (!silent) { + loading.value = true + } else { + mainLoading.value = true + } appMerchantDetailMerchantIdGet({ params: { merchantId: storeID.value, } - }).then((res: any) => { + }).then(async (res: any) => { console.log('商家详情', res) storeDetail.value = res.data as MerchantVo @@ -184,7 +284,10 @@ function getStoreDetail() { dishListByQuery.value = [] hasMore.value = true 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 } - + ensureMerchantInSidebarList() + activeMerchantId.value = storeID.value }).catch((error) => { console.error('获取商家详情失败:', error); - }).finally(()=> { + }).finally(() => { loading.value = false + mainLoading.value = false }) } @@ -406,17 +511,11 @@ watch(activeTab, () => { loadDishList(false); }); -// 触底加载更多 -onReachBottom(() => { +function onMainScrollToLower() { if (hasMore.value && !isLoadingMore.value) { - loadDishList(true); + loadDishList(true) } -}); - -const showStatusBar = useScrollThreshold() -onPageScroll((e) => { - uni.$emit('page-scroll', e) -}) +} function navigateToDishes(item: any) { uni.navigateTo({ @@ -499,151 +598,150 @@ function handleShare() { - - - + + + - + - - - - - - - - - - - - - - - - - - {{ storeDetail?.merchantName }} - - - - - {{ storeDetail?.rating }} - - ({{ storeDetail?.commentCount }}) - - - - CHEFLINK - - - - - {{ t('common.sales') }}:{{ storeDetail?.totalOrderCount }} - + + + {{ t('pages.home.featured-on') }} - - - - - - - - - - + - - - - {{ coupon.nameZh }} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {{ coupon.nameZh }} + + + + + + {{ t('pages-store.store.claimNow') }} + + + + + + + + + {{ item.title }} - - {{ t('pages-store.store.claimNow') }} - - - - - - - - - {{ item.title }} - - - - - - + + + + + @@ -749,7 +851,7 @@ function handleShare() { -