From 068b09d27221477643f4ed5a6cf0916e1e636389 Mon Sep 17 00:00:00 2001
From: ISFP_T <68358856@qq.com>
Date: Fri, 5 Jun 2026 16:13:54 +0800
Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=A0=B7=E5=BC=8F?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/locale/en.json | 2 +
src/locale/zh-Hans.json | 2 +
src/manifest.json | 4 +-
.../store/components/store-main-skeleton.vue | 166 ++++
.../pages/store/components/store-skeleton.vue | 274 +++----
src/pages-store/pages/store/index.vue | 714 ++++++++++++------
.../components/tabbar-home/tabbar-home.vue | 70 +-
7 files changed, 815 insertions(+), 417 deletions(-)
create mode 100644 src/pages-store/pages/store/components/store-main-skeleton.vue
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() {
-
-
-
+
+
+