fix:修复bug

This commit is contained in:
2026-03-03 09:42:22 +08:00
parent e9655643d6
commit 9f2d2f8764
17 changed files with 1232 additions and 210 deletions
+380 -66
View File
@@ -16,6 +16,10 @@ import {
type MerchantVo,
appMerchantOrderCalculatePriceCartPost,
appUserCardSelectDefaultPost, appMerchantOrderCreateOrderCartPost, appMerchantOrderPayOrderPost,
appMerchantOrderCreateOrderCartBatchPost,
appMerchantOrderCalculatePriceCartBatchPost,
appMerchantCartListMerchantPost,
appMerchantOrderPayOrderBatchPost
} from "@/service";
import useEventEmit from "@/hooks/useEventEmit";
import {EventEnum} from "@/constant/enums";
@@ -27,8 +31,8 @@ const userStore = useUserStore();
// 送达偏好
const visitMethodRef = ref();
const visitMethod = ref({
value: 0,
label: t("components.visit.leaveItToMePersonally"),
value: 2,
label: t("components.visit.putItAtTheDoor"),
});
function chooseVisitMethod() {
visitMethodRef.value?.onOpen(visitMethod.value.value);
@@ -236,6 +240,8 @@ useEventEmit(EventEnum.CHOOSE_PAYMENT_METHOD, (data) => {
const storeId = ref('')
const orderType = ref('') // 订单类型:batch-批量下单,normal-普通下单
const batchCartIds = ref([]) // 批量下单的购物车ID列表
const formData = ref<CreateOrderCartBo>({
orderRemark: '',
phone: '',
@@ -249,7 +255,26 @@ const formData = ref<CreateOrderCartBo>({
const needTableware = ref(false)
onLoad((options: any)=> {
loading.value = true
if(options.storeId) {
// 判断是批量下单还是普通下单
if(options.type == 'batch' && options.cartIds) {
// 批量下单模式
orderType.value = 'batch'
batchCartIds.value = options.cartIds.split(',')
console.log("下单类型",options.type);
// 默认取用户信息中的手机号作为收货手机号
formData.value.phone = userStore.userInfo.phone || ''
contact.value.areaCode = userStore.userInfo.areaCode || ''
// 获取用户地址列表
getAddressList()
// 查询批量购物车详情
getBatchCartInfo()
// 查询用户默认信用卡
appUserCardSelectDefault()
} else if(options.storeId) {
// 普通下单模式
orderType.value = 'normal'
storeId.value = options.storeId as string
formData.value.orderRemark = options.orderRemark as string
@@ -310,11 +335,77 @@ function getCartInfo() {
loading.value = false
})
}
// 批量下单:查询购物车详情
async function getBatchCartInfo() {
try {
// 根据购物车ID列表,按店铺分组查询
const cartIds = batchCartIds.value
console.log('批量购物车ID列表', cartIds)
// 1. 先获取所有店铺列表
const merchantRes = await appMerchantCartListMerchantPost({});
console.log('批量模式-购物车店铺列表', merchantRes);
if (!merchantRes.data || merchantRes.data.length === 0) {
cartDataList.value = [];
return;
}
// 2. 对每个店铺查询完整的商品信息
const merchantPromises = merchantRes.data.map(async (merchant: any) => {
try {
const cartRes = await appMerchantCartListByMerchantIdPost({
params: {
merchantId: merchant.id
}
});
console.log(`批量模式-店铺 ${merchant.merchantName} 的商品列表`, cartRes);
// 只保留选中的商品(根据 cartIds 过滤)
const filteredItems = (cartRes.data || []).filter((item: any) =>
cartIds.includes(String(item.id))
);
// 如果该店铺有选中的商品,才返回
if (filteredItems.length > 0) {
return {
...merchant,
merchantCartVoList: filteredItems
};
}
return null;
} catch (error) {
console.error(`获取店铺 ${merchant.id} 商品失败`, error);
return null;
}
});
// 3. 等待所有店铺的商品信息加载完成,并过滤掉 null
const results = await Promise.all(merchantPromises);
cartDataList.value = results.filter(item => item !== null);
console.log('批量模式-最终购物车数据', cartDataList.value);
// 查询菜品会员折扣价
if(cartIds.length > 0) {
appMerchantCartCalculateSavings()
// 注意:价格计算会在地址加载完成后自动调用
// 这里不需要立即调用 appMerchantOrderCalculatePriceCart()
}
} catch (error) {
console.error('获取批量购物车详情失败', error)
cartDataList.value = [];
} finally {
loading.value = false
}
}
// 查询菜品会员折扣价
const cartSavingsData = ref({})
function appMerchantCartCalculateSavings() {
const cartIds = orderType.value == 'batch' ? batchCartIds.value : cartDataList.value.map(item => item.id)
appMerchantCartCalculateSavingsPost({
body: cartDataList.value.map(item => item.id)
body: cartIds
}).then(res=> {
console.log('菜品会员折扣价', res)
cartSavingsData.value = res.data
@@ -390,21 +481,43 @@ function appMerchantOrderCalculatePriceCart() {
// 优先使用新选择的地址id
const targetAddressId = selectedAddressId.value || currentAddressId.value
// if(!targetAddressId) return
appMerchantOrderCalculatePriceCartPost({
body: {
addressId: targetAddressId,
cartIds: cartDataList.value.map(item => item.id),
receiveMethod: deliveryMethod.value === 0 ? 1 : 2,
couponId: couponInfo.value ? couponInfo.value.id : '',
tipDiscount: deliveryMethod.value === 1 ? 0 : (diyTipValue.value ? Number(diyTipValue.value) / 100 : (selectedTipIndex.value || 0) / 100), // 小费比例,自取订单不需要小费
// weeklyDeliveryFee: isWeeklyDelivery.value ? 1 : 2, // 是否支付周配送费(1-是 2-否)
phone: formData.value.phone,
areaCode: contact.value.areaCode,
}
}).then(res=> {
console.log('购物车下单价格', res)
priceData.value = res.data
})
const cartIds = orderType.value == 'batch' ? batchCartIds.value : cartDataList.value.map(item => item.id)
// 批量模式使用批量计算价格接口
if(orderType.value == 'batch') {
appMerchantOrderCalculatePriceCartBatchPost({
body: {
addressId: targetAddressId,
cartIds: cartIds,
receiveMethod: deliveryMethod.value === 0 ? 1 : 2,
couponId: couponInfo.value ? couponInfo.value.id : '',
tipDiscount: deliveryMethod.value === 1 ? 0 : (diyTipValue.value ? Number(diyTipValue.value) / 100 : (selectedTipIndex.value || 0) / 100), // 小费比例,自取订单不需要小费
phone: formData.value.phone,
areaCode: contact.value.areaCode,
}
}).then(res=> {
console.log('批量购物车下单价格', res)
priceData.value = res.data
})
} else {
// 普通模式使用单店铺计算价格接口
appMerchantOrderCalculatePriceCartPost({
body: {
addressId: targetAddressId,
cartIds: cartIds,
receiveMethod: deliveryMethod.value === 0 ? 1 : 2,
couponId: couponInfo.value ? couponInfo.value.id : '',
tipDiscount: deliveryMethod.value === 1 ? 0 : (diyTipValue.value ? Number(diyTipValue.value) / 100 : (selectedTipIndex.value || 0) / 100), // 小费比例,自取订单不需要小费
// weeklyDeliveryFee: isWeeklyDelivery.value ? 1 : 2, // 是否支付周配送费(1-是 2-否)
phone: formData.value.phone,
areaCode: contact.value.areaCode,
}
}).then(res=> {
console.log('购物车下单价格', res)
priceData.value = res.data
})
}
}
// 获取用户地址列表
@@ -439,9 +552,16 @@ function getAddressList() {
// 回显送达偏好
if(+data.deliveryRemark === 1) {
visitMethod.value.label = t('components.visit.leaveItToMePersonally')
visitMethod.value.value = 1
}
if(+data.deliveryRemark === 2) {
visitMethod.value.label = t('components.visit.putItAtTheDoor')
visitMethod.value.value = 2
}
// 如果是批量模式,地址加载完成后重新计算价格
if(orderType.value === 'batch') {
appMerchantOrderCalculatePriceCart()
}
}
})
@@ -495,6 +615,7 @@ const isShowWeeklyDelivery = computed(()=> {
const passwordInputRef = ref(null)
const resOrderId = ref('')
const resOrderIds = ref([]) // 批量下单返回的订单ID列表
function handleGoSettle() {
// 优先使用新选择的地址id
const targetAddressId = selectedAddressId.value || currentAddressId.value
@@ -512,59 +633,116 @@ function handleGoSettle() {
})
return
}
if(!resOrderId.value) {
let data = {
addressId: targetAddressId,
phone: formData.value.phone,
areaCode: contact.value.areaCode,
cartIds: cartDataList.value.map(item => item.id),
couponId: couponInfo.value ? couponInfo.value.id : '',
deliveryMethod: visitMethod.value.label, // 派送方式(如放门口或者交到顾客手中)
deliveryType: deliveryTimeType.value, // 1-立即交付 2-预约交付
orderRemark: formData.value.orderRemark,
receiveMethod: deliveryMethod.value === 0 ? 1 : 2, // 收货方式(1-派送 2-自取)
startScheduledTime: '', //
endScheduledTime: '', //
tipDiscount: deliveryMethod.value === 1 ? 0 : (diyTipValue.value ? Number(diyTipValue.value) / 100 : (selectedTipIndex.value || 0) / 100), // 小费比例,自取订单不需要小费
// weeklyDeliveryFee: isWeeklyDelivery.value ? 1 : 2, // 是否支付周配送费(1-是 2-否)
needTableware: needTableware.value ? 1 : 2, // 餐具 1是 2否
}
// 批量下单
if(orderType.value == 'batch') {
if(resOrderIds.value.length === 0) {
let data = {
addressId: targetAddressId,
phone: formData.value.phone,
areaCode: contact.value.areaCode,
cartIds: batchCartIds.value,
couponId: couponInfo.value ? couponInfo.value.id : '',
deliveryMethod: visitMethod.value.label, // 派送方式(如放门口或者交到顾客手中)
deliveryType: deliveryTimeType.value, // 1-立即交付 2-预约交付
orderRemark: formData.value.orderRemark,
receiveMethod: deliveryMethod.value === 0 ? 1 : 2, // 收货方式(1-派送 2-自取)
startScheduledTime: '', //
endScheduledTime: '', //
tipDiscount: deliveryMethod.value === 1 ? 0 : (diyTipValue.value ? Number(diyTipValue.value) / 100 : (selectedTipIndex.value || 0) / 100), // 小费比例,自取订单不需要小费
needTableware: needTableware.value ? 1 : 2, // 餐具 1是 2否
}
// 如果是预约派送
if(deliveryTimeType.value === 1) {
const result = getTimeStamps(showDeliveryTime.value);
data.startScheduledTime = result.startTimestamp
data.endScheduledTime = result.endTimestamp
// 如果是预约派送
if(deliveryTimeType.value === 1) {
const result = getTimeStamps(showDeliveryTime.value);
data.startScheduledTime = result.startTimestamp
data.endScheduledTime = result.endTimestamp
} else {
data.startScheduledTime = diyTime.value.startTime
data.endScheduledTime = diyTime.value.endTime
}
console.log('批量下单参数', data)
appMerchantOrderCreateOrderCartBatchPost({
body: data
}).then(res=> {
console.log('批量下单成功', res)
resOrderIds.value = res.data.orderIds || []
// 如果是余额支付,弹出支付密码弹窗
if(payMethodOptions.value.payMethod === 2) {
passwordInputRef.value?.showPasswordInput()
} else {
appMerchantOrderPayOrderBatch()
}
})
} else {
data.startScheduledTime = diyTime.value.startTime
data.endScheduledTime = diyTime.value.endTime
// 如果是余额支付,弹出支付密码弹窗
if(payMethodOptions.value.payMethod === 2) {
passwordInputRef.value?.showPasswordInput()
} else {
appMerchantOrderPayOrderBatch()
}
}
console.log('下单参数', data)
appMerchantOrderCreateOrderCartPost({
body: data
}).then(res=> {
console.log('下单成功', res)
resOrderId.value = res.data || ''
} else {
// 普通下单
if(!resOrderId.value) {
let data = {
addressId: targetAddressId,
phone: formData.value.phone,
areaCode: contact.value.areaCode,
cartIds: cartDataList.value.map(item => item.id),
couponId: couponInfo.value ? couponInfo.value.id : '',
deliveryMethod: visitMethod.value.label, // 派送方式(如放门口或者交到顾客手中)
deliveryType: deliveryTimeType.value, // 1-立即交付 2-预约交付
orderRemark: formData.value.orderRemark,
receiveMethod: deliveryMethod.value === 0 ? 1 : 2, // 收货方式(1-派送 2-自取)
startScheduledTime: '', //
endScheduledTime: '', //
tipDiscount: deliveryMethod.value === 1 ? 0 : (diyTipValue.value ? Number(diyTipValue.value) / 100 : (selectedTipIndex.value || 0) / 100), // 小费比例,自取订单不需要小费
// weeklyDeliveryFee: isWeeklyDelivery.value ? 1 : 2, // 是否支付周配送费(1-是 2-否)
needTableware: needTableware.value ? 1 : 2, // 餐具 1是 2否
}
// 如果是预约派送
if(deliveryTimeType.value === 1) {
const result = getTimeStamps(showDeliveryTime.value);
data.startScheduledTime = result.startTimestamp
data.endScheduledTime = result.endTimestamp
} else {
data.startScheduledTime = diyTime.value.startTime
data.endScheduledTime = diyTime.value.endTime
}
console.log('下单参数', data)
appMerchantOrderCreateOrderCartPost({
body: data
}).then(res=> {
console.log('下单成功', res)
resOrderId.value = res.data || ''
// 如果是余额支付,弹出支付密码弹窗
if(payMethodOptions.value.payMethod === 2) {
passwordInputRef.value?.showPasswordInput()
} else {
appMerchantOrderPayOrder()
}
})
} else {
// 如果是余额支付,弹出支付密码弹窗
if(payMethodOptions.value.payMethod === 2) {
passwordInputRef.value?.showPasswordInput()
} else {
appMerchantOrderPayOrder()
}
})
} else {
// 如果是余额支付,弹出支付密码弹窗
if(payMethodOptions.value.payMethod === 2) {
passwordInputRef.value?.showPasswordInput()
} else {
appMerchantOrderPayOrder()
}
}
}
function payPawSuccess(password: string) {
payMethodOptions.value.payPassword = password
appMerchantOrderPayOrder()
if(orderType.value === 'batch') {
appMerchantOrderPayOrderBatch()
} else {
appMerchantOrderPayOrder()
}
}
function appMerchantOrderPayOrder() {
@@ -588,6 +766,37 @@ function appMerchantOrderPayOrder() {
})
}
// 批量订单支付
function appMerchantOrderPayOrderBatch() {
// 使用批量支付接口
appMerchantOrderPayOrderBatchPost({
body: {
orderIds: resOrderIds.value,
cardId: payMethodOptions.value.cardId,
payMethod: payMethodOptions.value.payMethod,
payPassword: payMethodOptions.value.payPassword
}
}).then(res=> {
console.log('批量支付结果', res)
uni.showToast({
title: t('pages-store.checkout.paymentSuccess'),
icon: 'none'
})
setTimeout(()=> {
uni.navigateBack({
delta: 2,
})
}, 500)
}).catch(err => {
console.error('批量支付失败', err)
uni.showToast({
title: '支付失败',
icon: 'none'
})
})
}
function getTimeStamps(timeStr: string) {
// 验证输入是否为空
if (!timeStr || typeof timeStr !== 'string') {
@@ -980,7 +1189,7 @@ function handleClose() {
<view class="w-full h-10rpx bg-#F6F6F6"></view>
<!-- 订单信息摘要 -->
<view class="pt-36rpx pb-36rpx">
<view class="pt-36rpx pb-36rpx" v-if="orderType === 'normal' && cartDataList.length > 0">
<text
class="px-30rpx text-32rpx lh-32rpx font-500 text-#333 block mb-10rpx"
>{{ t("pages-store.checkout.orderInfoSummary") }}</text
@@ -1042,7 +1251,102 @@ function handleClose() {
</template>
</wd-collapse-item>
</wd-collapse>
</view>
<!-- 批量模式多店铺列表 -->
<view class="pt-36rpx pb-36rpx" v-if="orderType === 'batch' && cartDataList.length > 0">
<text
class="px-30rpx text-32rpx lh-32rpx font-500 text-#333 block mb-20rpx"
>{{ t("pages-store.checkout.orderInfoSummary") }}</text
>
<view class="px-30rpx">
<view
v-for="(merchant, merchantIndex) in cartDataList"
:key="merchant.id"
class="mb-20rpx rounded-16rpx border-1rpx border-solid border-[#E8E8E8] overflow-hidden"
>
<!-- 店铺头部 -->
<view class="p-20rpx flex items-center bg-#F6F6F6">
<image
class="w-60rpx h-60rpx rounded-50% mr-20rpx"
:src="merchant.logo"
mode="aspectFill"
/>
<view>
<view class="text-28rpx lh-28rpx text-#333 font-500"
>{{ merchant.merchantName }}</view
>
<view
class="text-24rpx lh-24rpx text-#7D7D7D font-400 mt-8rpx"
>{{ merchant.merchantCartVoList.length }} {{ t('pages-user.cart.items') }}</view
>
</view>
</view>
<!-- 商品列表 -->
<view class="px-20rpx">
<view
v-for="(item, itemIndex) in merchant.merchantCartVoList"
:key="item.id"
class="py-20rpx flex items-start"
:class="itemIndex < merchant.merchantCartVoList.length - 1 ? 'border-bottom border-[#F2F2F2]' : ''"
>
<!-- 商品图片 -->
<image
:src="item.merchantDishVo?.dishImage?.split(',')[0]"
mode="aspectFill"
class="w-100rpx h-100rpx shrink-0 rounded-12rpx"
></image>
<!-- 商品信息 -->
<view class="ml-16rpx flex-1">
<view class="text-[#333333] text-26rpx lh-36rpx font-500 line-clamp-2">{{
item.merchantDishVo?.dishName
}}</view>
<!-- 配菜信息 -->
<view class="text-[#7D7D7D] text-22rpx lh-26rpx mt-8rpx" v-if="item.sideDishList?.length > 0">
<template v-for="dish in item.sideDishList">
<text class="mr-6rpx">
{{ dish?.merchantSideDishItemVo?.name || '' }}
</text>
<text v-if="dish?.merchantSideDishItemVo?.price" class="text-#00A76D mr-10rpx">+${{ dish?.merchantSideDishItemVo?.price }}</text>
</template>
</view>
<!-- 价格和数量 -->
<view class="flex items-center justify-between mt-12rpx">
<view class="flex items-center">
<text class="text-[#333333] text-28rpx font-500"
>${{ item.merchantDishVo?.discountPrice }}</text>
<text
v-if="item.merchantDishVo?.originalPrice && item.merchantDishVo?.originalPrice !== item.merchantDishVo?.discountPrice"
class="text-[#7D7D7D] text-22rpx line-through ml-8rpx"
>${{ item.merchantDishVo?.originalPrice }}</text>
</view>
<view class="text-[#7D7D7D] text-22rpx">
x{{ item.count }}
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
<!-- 批量模式且没有数据时的提示 -->
<view class="pt-36rpx pb-36rpx" v-if="orderType === 'batch' && cartDataList.length === 0">
<text
class="px-30rpx text-32rpx lh-32rpx font-500 text-#333 block mb-10rpx"
>{{ t("pages-store.checkout.orderInfoSummary") }}</text
>
<view class="px-30rpx py-40rpx text-center">
<text class="text-28rpx text-#7D7D7D">已选择 {{ batchCartIds.length }} 件商品</text>
</view>
</view>
<view class="pt-36rpx pb-36rpx" >
<!-- 优惠券 -->
<view @click="navigateToCoupon" class="flex-center-sb border-bottom py-36rpx px-30rpx gap-20rpx">
<view class="flex-center-sb flex-1">
@@ -1173,7 +1477,8 @@ function handleClose() {
<view class="border-bottom px-30rpx py-32rpx">
<view class="flex-center-sb mb-40rpx text-32rpx lh-32rpx text-#333">
<text>{{ t('pages-store.order.subtotal') }}</text>
<text>${{ priceData?.actualAmount }}</text>
<text v-if="orderType === 'batch'">${{ priceData?.totalActualAmount || '0.00' }}</text>
<text v-else>${{ priceData?.actualAmount || '0.00' }}</text>
</view>
<view class="flex-center-sb mb-40rpx text-32rpx lh-32rpx text-#333">
<view @click="openPriceDetail" class="flex items-center">
@@ -1184,13 +1489,17 @@ function handleClose() {
mode="aspectFit"
/>
</view>
<view>
<text>${{ (Number(priceData?.tax) + Number(priceData?.tip) + Number(priceData?.deliveryFee)).toFixed(2) }}</text>
<view v-if="orderType === 'batch'">
<text>${{ (Number(priceData?.totalTax || 0) + Number(priceData?.totalTip || 0) + Number(priceData?.totalDeliveryFee || 0)).toFixed(2) }}</text>
</view>
<view v-else>
<text>${{ (Number(priceData?.tax || 0) + Number(priceData?.tip || 0) + Number(priceData?.deliveryFee || 0)).toFixed(2) }}</text>
</view>
</view>
<view class="flex-center-sb text-32rpx lh-32rpx text-#333 font-500">
<text>{{ t('pages-store.order.total') }}</text>
<text>${{ priceData?.paidAmount }}</text>
<text v-if="orderType === 'batch'">${{ priceData?.totalPaidAmount || '0.00' }}</text>
<text v-else>${{ priceData?.paidAmount || '0.00' }}</text>
</view>
</view>
@@ -1245,19 +1554,24 @@ function handleClose() {
</view>
<view class="px-30rpx py-18rpx">
<wd-button
v-if="showDeliverySwitch"
@click="handleGoSettle"
custom-class="!h-92rpx !text-30rpx !text-#fff !lh-92rpx !rounded-16rpx"
block
>{{ t('common.goSettle') }}
</wd-button>
<wd-button
<!-- <wd-button
v-if="showDeliverySwitch"
@click="handleGoSettle"
custom-class="!h-92rpx !text-30rpx !text-#fff !lh-92rpx !rounded-16rpx"
block
>{{ t('common.goSettle') }}
</wd-button> -->
<!-- <wd-button
v-else
custom-class="!h-92rpx !text-30rpx !text-#fff !lh-92rpx !rounded-16rpx"
block
>{{ t('pages-store.checkout.notActivated') }}
</wd-button>
</wd-button> -->
</view>
<view :style="[configStore.iosSafeBottomPlaceholder]"></view>
</view>