修改样式,修复bug
This commit is contained in:
@@ -222,6 +222,7 @@
|
||||
"browse": {
|
||||
"brandTag": "CHEFLINK Selected",
|
||||
"moreRecipes": "More Recipes",
|
||||
"nearbyEmpty": "No nearby data",
|
||||
"titleCuisine": "Nearby Cuisine",
|
||||
"titleRecipes": "Selected Recipes"
|
||||
},
|
||||
|
||||
@@ -222,7 +222,8 @@
|
||||
"browse": {
|
||||
"brandTag": "CHEFLINK 严选",
|
||||
"moreRecipes": "更多食谱",
|
||||
"titleCuisine": "附近的美食",
|
||||
"nearbyEmpty": "附近暂无美食",
|
||||
"titleCuisine": "附近美食",
|
||||
"titleRecipes": "选择食谱"
|
||||
},
|
||||
"home": {
|
||||
|
||||
+2
-2
@@ -2,8 +2,8 @@
|
||||
"name" : "CHEFLINK delivery",
|
||||
"appid" : "__UNI__06509BE",
|
||||
"description" : "",
|
||||
"versionName" : "3.2.3",
|
||||
"versionCode" : 323,
|
||||
"versionName" : "3.2.4",
|
||||
"versionCode" : 324,
|
||||
"transformPx" : false,
|
||||
/* 5+App特有相关 */
|
||||
"app-plus" : {
|
||||
|
||||
@@ -971,7 +971,7 @@ function handleGoSettle() {
|
||||
}
|
||||
})
|
||||
|
||||
let data = {
|
||||
const data: Record<string, any> = {
|
||||
addressId: targetAddressId,
|
||||
phone: formData.value.phone,
|
||||
areaCode: contact.value.areaCode,
|
||||
@@ -982,8 +982,6 @@ function handleGoSettle() {
|
||||
deliveryType: deliveryTimeType.value, // 1-立即交付 2-预约交付
|
||||
orderRemark: formData.value.orderRemark,
|
||||
receiveMethod: deliveryMethod.value === 0 ? 1 : 2, // 收货方式(1-派送 2-自取)
|
||||
startScheduledTime: '', //
|
||||
endScheduledTime: '', //
|
||||
needTableware: needTableware.value ? 1 : 2, // 餐具 1是 2否
|
||||
}
|
||||
|
||||
@@ -992,24 +990,21 @@ function handleGoSettle() {
|
||||
data.startScheduledTime = result.startTimestamp
|
||||
data.endScheduledTime = result.endTimestamp
|
||||
} else {
|
||||
const startMap: Record<string, number> = {}
|
||||
const endMap: Record<string, number> = {}
|
||||
cartDataList.value.forEach((m: any) => {
|
||||
const ap = merchantAppointmentMap.value[String(m.id)]
|
||||
if (ap?.startTime && ap?.endTime) {
|
||||
startMap[String(m.id)] = ap.startTime
|
||||
endMap[String(m.id)] = ap.endTime
|
||||
}
|
||||
})
|
||||
data.merchantStartScheduledTimeMap = startMap
|
||||
data.merchantEndScheduledTimeMap = endMap
|
||||
const scheduled = buildScheduledTimePayload(
|
||||
cartDataList.value as any[],
|
||||
merchantAppointmentMap.value
|
||||
)
|
||||
data.startScheduledTime = scheduled.startScheduledTime
|
||||
data.endScheduledTime = scheduled.endScheduledTime
|
||||
data.merchantStartScheduledTimeMap = scheduled.startMap
|
||||
data.merchantEndScheduledTimeMap = scheduled.endMap
|
||||
}
|
||||
console.log('批量下单参数', data)
|
||||
appMerchantOrderCreateOrderCartBatchPost({
|
||||
body: data
|
||||
}).then(res=> {
|
||||
console.log('批量下单成功', res)
|
||||
resOrderIds.value = res.data.orderIds || []
|
||||
resOrderIds.value = res.data?.orderIds || res.data || []
|
||||
// 如果是余额支付,弹出支付密码弹窗
|
||||
if(payMethodOptions.value.payMethod === 2) {
|
||||
passwordInputRef.value?.showPasswordInput()
|
||||
@@ -1019,6 +1014,11 @@ function handleGoSettle() {
|
||||
} else {
|
||||
appMerchantOrderPayOrderBatch()
|
||||
}
|
||||
}).catch((err: any) => {
|
||||
uni.showToast({
|
||||
title: err?.msg || err?.message || '下单失败',
|
||||
icon: 'none',
|
||||
})
|
||||
})
|
||||
} else {
|
||||
// 如果是余额支付,弹出支付密码弹窗
|
||||
@@ -1045,7 +1045,7 @@ function handleGoSettle() {
|
||||
}
|
||||
}
|
||||
|
||||
let data = {
|
||||
const data: Record<string, any> = {
|
||||
addressId: targetAddressId,
|
||||
phone: formData.value.phone,
|
||||
areaCode: contact.value.areaCode,
|
||||
@@ -1055,15 +1055,12 @@ function handleGoSettle() {
|
||||
deliveryType: deliveryTimeType.value, // 1-立即交付 2-预约交付
|
||||
orderRemark: formData.value.orderRemark,
|
||||
receiveMethod: deliveryMethod.value === 0 ? 1 : 2, // 收货方式(1-派送 2-自取)
|
||||
startScheduledTime: '', //
|
||||
endScheduledTime: '', //
|
||||
tipDiscount: tipAmount, // 小费金额(美元),自取订单不需要小费
|
||||
// weeklyDeliveryFee: isWeeklyDelivery.value ? 1 : 2, // 是否支付周配送费(1-是 2-否)
|
||||
needTableware: needTableware.value ? 1 : 2, // 餐具 1是 2否
|
||||
}
|
||||
|
||||
// 如果是预约派送
|
||||
if(deliveryTimeType.value === 1) {
|
||||
if (deliveryTimeType.value === 1) {
|
||||
const result = getTimeStamps(showDeliveryTime.value);
|
||||
data.startScheduledTime = result.startTimestamp
|
||||
data.endScheduledTime = result.endTimestamp
|
||||
@@ -1178,6 +1175,33 @@ function appMerchantOrderPayOrderBatch() {
|
||||
})
|
||||
}
|
||||
|
||||
/** 从商户预约映射中提取创单所需的顶层预约时间(文档要求 deliveryType=2 必传) */
|
||||
function buildScheduledTimePayload(
|
||||
merchants: Array<{ id?: string | number }>,
|
||||
appointmentMap: Record<string, MerchantAppointmentSlot>
|
||||
) {
|
||||
const startMap: Record<string, number> = {};
|
||||
const endMap: Record<string, number> = {};
|
||||
let startScheduledTime: number | undefined;
|
||||
let endScheduledTime: number | undefined;
|
||||
|
||||
merchants.forEach((m) => {
|
||||
const ap = appointmentMap[String(m.id)];
|
||||
if (!ap?.startTime || !ap?.endTime) return;
|
||||
const merchantId = String(m.id);
|
||||
const start = Number(ap.startTime);
|
||||
const end = Number(ap.endTime);
|
||||
startMap[merchantId] = start;
|
||||
endMap[merchantId] = end;
|
||||
if (startScheduledTime === undefined) {
|
||||
startScheduledTime = start;
|
||||
endScheduledTime = end;
|
||||
}
|
||||
});
|
||||
|
||||
return { startScheduledTime, endScheduledTime, startMap, endMap };
|
||||
}
|
||||
|
||||
function getTimeStamps(timeStr: string) {
|
||||
// 验证输入是否为空
|
||||
if (!timeStr || typeof timeStr !== 'string') {
|
||||
|
||||
@@ -38,15 +38,28 @@ const storeShareTopStyle = computed(() => ({
|
||||
top: `${configStore.statusBarHeight + uni.upx2px(16)}px`,
|
||||
}))
|
||||
|
||||
const storeBannerSrc = computed(() => {
|
||||
const storeBannerImages = computed(() => {
|
||||
const raw = storeDetail.value?.shopImages
|
||||
if (typeof raw === 'string' && raw.trim()) {
|
||||
return raw.split(',')[0].trim()
|
||||
const list = raw.split(',').map((item) => item.trim()).filter(Boolean)
|
||||
if (list.length > 0) return list
|
||||
}
|
||||
const logo = storeDetail.value?.logo
|
||||
return typeof logo === 'string' ? logo : ''
|
||||
return typeof logo === 'string' && logo.trim() ? [logo.trim()] : []
|
||||
})
|
||||
|
||||
const storeBannerCurrent = ref(0)
|
||||
function onStoreBannerChange(e: { detail?: { current?: number } }) {
|
||||
storeBannerCurrent.value = e.detail?.current ?? 0
|
||||
}
|
||||
|
||||
watch(
|
||||
() => storeDetail.value?.id,
|
||||
() => {
|
||||
storeBannerCurrent.value = 0
|
||||
},
|
||||
)
|
||||
|
||||
const deliveryNoticeTexts = computed(() => {
|
||||
const texts: string[] = []
|
||||
if (+storeDetail.value?.deliveryService === 1 && deliveryMethod.value === 0) {
|
||||
@@ -672,13 +685,34 @@ function handleShare() {
|
||||
>
|
||||
<view class="store-main__inner">
|
||||
<view class="store-banner">
|
||||
<image
|
||||
v-if="storeBannerSrc"
|
||||
:src="storeBannerSrc"
|
||||
class="store-banner__img"
|
||||
mode="aspectFill"
|
||||
/>
|
||||
<swiper
|
||||
v-if="storeBannerImages.length > 0"
|
||||
class="store-banner__swiper"
|
||||
:circular="storeBannerImages.length > 1"
|
||||
:autoplay="storeBannerImages.length > 1"
|
||||
:indicator-dots="storeBannerImages.length > 1"
|
||||
indicator-color="rgba(255,255,255,0.45)"
|
||||
indicator-active-color="#ffffff"
|
||||
@change="onStoreBannerChange"
|
||||
>
|
||||
<swiper-item
|
||||
v-for="(img, idx) in storeBannerImages"
|
||||
:key="`${img}-${idx}`"
|
||||
>
|
||||
<image
|
||||
:src="img"
|
||||
class="store-banner__img"
|
||||
mode="scaleToFill"
|
||||
/>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
<view v-else class="store-banner__img store-banner__img--empty" />
|
||||
<view
|
||||
v-if="storeBannerImages.length > 1"
|
||||
class="store-banner__counter"
|
||||
>
|
||||
{{ storeBannerCurrent + 1 }}/{{ storeBannerImages.length }}
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view
|
||||
@@ -1034,6 +1068,11 @@ page {
|
||||
background: #e8e8e8;
|
||||
}
|
||||
|
||||
.store-banner__swiper {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.store-banner__img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
@@ -1044,6 +1083,19 @@ page {
|
||||
background: #e8e8e8;
|
||||
}
|
||||
|
||||
.store-banner__counter {
|
||||
position: absolute;
|
||||
right: 24rpx;
|
||||
bottom: 20rpx;
|
||||
z-index: 2;
|
||||
padding: 6rpx 16rpx;
|
||||
border-radius: 999rpx;
|
||||
background: rgba(0, 0, 0, 0.45);
|
||||
color: #fff;
|
||||
font-size: 22rpx;
|
||||
line-height: 28rpx;
|
||||
}
|
||||
|
||||
.store-delivery-notice {
|
||||
background: #fff7ed;
|
||||
border-bottom: 1rpx solid #ffe8cc;
|
||||
|
||||
@@ -3,7 +3,7 @@ import Search from "../tabbar-home/components/search.vue";
|
||||
import { useConfigStore, useUserStore } from "@/store";
|
||||
import BrowseSkeleton from "./components/browse-skeleton.vue";
|
||||
import {
|
||||
appMerchantDishNearbyListPost,
|
||||
appMerchantNearbyListPost,
|
||||
appSearchSearchRecipePost,
|
||||
} from "@/service";
|
||||
import {thumbnailImg} from "@/utils/utils";
|
||||
@@ -28,8 +28,7 @@ async function initData() {
|
||||
loading.value = true;
|
||||
}
|
||||
getRecipeData()
|
||||
// 获取菜品数据
|
||||
appMerchantDishNearbyList()
|
||||
getNearbyStoreList()
|
||||
}
|
||||
|
||||
// 获取菜谱数据
|
||||
@@ -56,38 +55,44 @@ function navigateToRecipeList() {
|
||||
navigateTo('/pages-user/pages/recipe/list')
|
||||
}
|
||||
|
||||
// 获取附近的菜品
|
||||
const dishData = ref<any[]>([]);
|
||||
function appMerchantDishNearbyList() {
|
||||
appMerchantDishNearbyListPost({
|
||||
params: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
},
|
||||
// 获取附近店铺
|
||||
const nearbyStoreList = ref<any[]>([]);
|
||||
const nearbyStoreLoaded = ref(false);
|
||||
function getNearbyStoreList() {
|
||||
nearbyStoreLoaded.value = false;
|
||||
appMerchantNearbyListPost({
|
||||
body: {
|
||||
lat: String(userStore.userLocation.latitude ?? ''),
|
||||
lng: String(userStore.userLocation.longitude ?? ''),
|
||||
}
|
||||
}).then(res=> {
|
||||
console.log('菜品数据', res)
|
||||
dishData.value = res.rows;
|
||||
lat: userStore.userLocation.latitude,
|
||||
lng: userStore.userLocation.longitude,
|
||||
},
|
||||
})
|
||||
}
|
||||
function handleClickDish(item: any) {
|
||||
navigateTo(`/pages-store/pages/store/index?id=${item.merchantId}`)
|
||||
.then((res) => {
|
||||
console.log("附近店铺", res);
|
||||
nearbyStoreList.value = res.data || [];
|
||||
})
|
||||
.catch(() => {
|
||||
nearbyStoreList.value = [];
|
||||
})
|
||||
.finally(() => {
|
||||
nearbyStoreLoaded.value = true;
|
||||
});
|
||||
}
|
||||
|
||||
function getMerchantName(item: any) {
|
||||
return item?.merchantVo?.merchantName || item?.merchantName||item?.dishName || '--'
|
||||
function handleClickStore(item: any) {
|
||||
navigateTo(`/pages-store/pages/store/index?id=${item.id}`);
|
||||
}
|
||||
|
||||
function getMerchantLogo(item: any) {
|
||||
return item?.merchantVo?.logo || item?.logo || item?.dishImage?.split?.(',')?.[0] || item?.dishImage || ''
|
||||
function getStoreName(item: any) {
|
||||
return item?.merchantName || "--";
|
||||
}
|
||||
|
||||
function getMerchantRate(item: any) {
|
||||
const rating = Number(item?.merchantVo?.rating ?? item?.rating ?? 0)
|
||||
return Number.isFinite(rating) && rating > 0 ? rating.toFixed(1) : '5.0'
|
||||
function getStoreLogo(item: any) {
|
||||
return item?.logo || "";
|
||||
}
|
||||
|
||||
function getStoreRate(item: any) {
|
||||
const rating = Number(item?.rating ?? 0);
|
||||
return Number.isFinite(rating) && rating > 0 ? rating.toFixed(1) : "5.0";
|
||||
}
|
||||
|
||||
function getPreviewRecipeList() {
|
||||
@@ -161,17 +166,28 @@ defineExpose({
|
||||
</view>
|
||||
|
||||
<view class="section-title mt-54rpx">{{ t("pages.browse.titleCuisine") }}</view>
|
||||
<scroll-view scroll-x class="store-scroll mt-28rpx pb-40rpx" :show-scrollbar="false" :enable-flex="true">
|
||||
<scroll-view
|
||||
v-if="nearbyStoreList.length > 0"
|
||||
scroll-x
|
||||
class="store-scroll mt-28rpx pb-40rpx"
|
||||
:show-scrollbar="false"
|
||||
:enable-flex="true"
|
||||
>
|
||||
<view class="store-track">
|
||||
<view v-for="item in dishData" :key="item.id" @click="handleClickDish(item)" class="store-card">
|
||||
<view
|
||||
v-for="item in nearbyStoreList"
|
||||
:key="item.id"
|
||||
@click="handleClickStore(item)"
|
||||
class="store-card"
|
||||
>
|
||||
<image
|
||||
:src="thumbnailImg(getMerchantLogo(item))"
|
||||
:src="thumbnailImg(getStoreLogo(item))"
|
||||
class="store-card__cover"
|
||||
mode="aspectFill"
|
||||
/>
|
||||
<view class="store-card__right">
|
||||
<view class="store-card__name line-clamp-2">{{ getMerchantName(item) }}</view>
|
||||
<view class="store-card__rating">★★★★★ {{ getMerchantRate(item) }}</view>
|
||||
<view class="store-card__name line-clamp-2">{{ getStoreName(item) }}</view>
|
||||
<view class="store-card__rating">★★★★★ {{ getStoreRate(item) }}</view>
|
||||
<view class="store-card__brand">{{ t("pages.browse.brandTag") }}</view>
|
||||
<view class="store-card__arrow center">
|
||||
<i class="i-carbon:chevron-right text-30rpx text-white"></i>
|
||||
@@ -180,6 +196,15 @@ defineExpose({
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
<view
|
||||
v-else-if="nearbyStoreLoaded && !loading"
|
||||
class="store-empty mt-28rpx pb-40rpx"
|
||||
>
|
||||
<view class="store-empty__icon-wrap center">
|
||||
<i class="i-carbon:location-off store-empty__icon"></i>
|
||||
</view>
|
||||
<text class="store-empty__text">{{ t("pages.browse.nearbyEmpty") }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
@@ -335,4 +360,35 @@ defineExpose({
|
||||
border-radius: 50%;
|
||||
background: #111;
|
||||
}
|
||||
|
||||
.store-empty {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-height: 220rpx;
|
||||
padding: 48rpx 32rpx;
|
||||
border-radius: 20rpx;
|
||||
background: #f7f7f7;
|
||||
}
|
||||
|
||||
.store-empty__icon-wrap {
|
||||
width: 96rpx;
|
||||
height: 96rpx;
|
||||
border-radius: 50%;
|
||||
background: #ececec;
|
||||
}
|
||||
|
||||
.store-empty__icon {
|
||||
font-size: 44rpx;
|
||||
color: #b0b0b0;
|
||||
}
|
||||
|
||||
.store-empty__text {
|
||||
margin-top: 24rpx;
|
||||
font-size: 28rpx;
|
||||
line-height: 40rpx;
|
||||
color: #8a8a8a;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user