Files
cheflinkuser/src/pages-store/pages/order/checkout.vue
T
2026-03-03 09:42:22 +08:00

1610 lines
54 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script setup lang="ts">
import { useConfigStore, useUserStore } from "@/store";
import { dayjs } from "@/plugin/index";
import Config from '@/config/index'
import CheckoutSkeleton from "./components/checkout-skeleton.vue";
import ChangePhone from "./components/change-phone.vue";
import PriceDetail from "./components/price-detail.vue";
import VisitMethod from "@/components/visit-method/index.vue";
import {ref} from "vue";
import {
appMerchantCartListByMerchantIdPost,
appMerchantCartCalculateSavingsPost,
appMerchantDetailMerchantIdGet,
appUserAddressListPost,
type MerchantCartVo,
type MerchantVo,
appMerchantOrderCalculatePriceCartPost,
appUserCardSelectDefaultPost, appMerchantOrderCreateOrderCartPost, appMerchantOrderPayOrderPost,
appMerchantOrderCreateOrderCartBatchPost,
appMerchantOrderCalculatePriceCartBatchPost,
appMerchantCartListMerchantPost,
appMerchantOrderPayOrderBatchPost
} from "@/service";
import useEventEmit from "@/hooks/useEventEmit";
import {EventEnum} from "@/constant/enums";
import { getDistanceInMiles} from "@/utils/utils";
const { t } = useI18n();
const configStore = useConfigStore();
const userStore = useUserStore();
// 送达偏好
const visitMethodRef = ref();
const visitMethod = ref({
value: 2,
label: t("components.visit.putItAtTheDoor"),
});
function chooseVisitMethod() {
visitMethodRef.value?.onOpen(visitMethod.value.value);
}
function handleVisitMethodConfirm(data: { value: number; label: string }) {
visitMethod.value = data;
}
// 联系方式(这里默认值取用户信息的手机号区号)
const contact = ref({
phone: userStore.userInfo.phone,
areaCode: "+1",
});
const changePhoneRef = ref<InstanceType<typeof ChangePhone>>();
function openChangePhone() {
if (changePhoneRef.value) {
changePhoneRef.value.onOpen(contact.value);
}
}
function confirmPhone(data: { phone: string; areaCode: string }) {
contact.value = data;
formData.value.phone = data.phone;
}
// 配送时间 1 即刻配送 2 预约配送
const deliveryTimeType = ref(1);
// 配送时间配置
const deliveryMinutes = ref(0); // 预计送达时间(分钟)
// 自取时间配置
const selfPickupMinutes = ref(0); // 自取时间(分钟)
const deliveryWindowMinutes = ref(30); // 配送时间窗口(分钟)
// 预约配送日期配送
const userSelectedDeliveryTimeDate = ref(null);
// 预约自取时间
const userSelectedSelfPickupTimeDate = ref(null);
// 显示用的配送时间(即刻配送=当前时间加预计时间)(预约配送=预约时间+预计时间分钟)
const showDeliveryTime = computed(() => {
// 配送
if (deliveryTimeType.value === 1) {
// 即刻配送:当前时间 + 预计送达时间
let time = 0
if(deliveryMethod.value === 0) {
time = deliveryMinutes.value
} else {
time = selfPickupMinutes.value
}
const deliveryStart = dayjs().add(Number(time), "minute");
const deliveryEnd = deliveryStart.add(
deliveryWindowMinutes.value,
"minute"
);
return `${deliveryStart.format("HH:mm")}-${deliveryEnd.format("HH:mm")}`;
}
if (deliveryTimeType.value === 2) {
return deliveryMethod.value === 0 ? userSelectedDeliveryTimeDate : '123';
}
return "";
});
// 切换配送时间点击事件
function toggleDeliveryTimeType(type: number) {
if (type === 2) {
if (userSelectedDeliveryTimeDate.value) {
deliveryTimeType.value = type;
}
// 跳转到时间选择页面
console.log(storeDetail.value.merch);
uni.navigateTo({
url: "/pages/address/reservation-time?storeBusinessHours=" + storeDetail.value.businessHours,
});
} else {
deliveryTimeType.value = type;
}
}
const diyTime = ref({})
useEventEmit(EventEnum.CHOOSE_APPOINTMENT_TIME, (data) => {
console.log('CHOOSE_APPOINTMENT_TIME', data)
if(data) {
diyTime.value = data;
deliveryTimeType.value = 2
// 配送还是自取
if(deliveryMethod.value === 0) {
userSelectedDeliveryTimeDate.value = dayjs(data.date).format('MM-DD') + ' ' + data.timeSlot;
} else {
userSelectedSelfPickupTimeDate.value = dayjs(data.date).format('MM-DD') + ' ' + data.timeSlot;
}
}
})
// 设置配送时间(分钟)
const setDeliveryMinutes = (minutes: number) => {
deliveryMinutes.value = minutes;
};
// 设置配送时间窗口(分钟)
const setDeliveryWindowMinutes = (minutes: number) => {
deliveryWindowMinutes.value = minutes;
};
const deliveryMethod = ref(0);
// 配送方式
const showDeliverySwitch = ref(false)
const deliveryMethodOptions = [
t("pages-store.store.delivery"),
t("pages-store.store.pickup"),
];
function handleClickSegmented(index: number) {
console.log("切换配送方式:", index);
if(+storeDetail.value.deliveryService !== 1 && index === 0) {
uni.showToast({
title: t('pages-store.store.toast.deliveryService'),
icon: 'none'
})
return
}
if(+storeDetail.value.selfPickup !== 1 && index === 1) {
uni.showToast({
title: t('pages-store.store.toast.selfPickup'),
icon: 'none'
})
return
}
if(index !== deliveryMethod.value) {
deliveryMethod.value = index
// 重置配送类型
deliveryTimeType.value = 1
appMerchantOrderCalculatePriceCart()
}
}
// 折叠面板
const collapseValue = ref([""]);
// 当前选中的小费
const selectedTipIndex = ref(5);
const diyTipValue = ref('')
const tipOptions = ref([
{
label: "5%",
value: 5,
},
{
label: "10%",
value: 10,
},
{
label: "15%",
value: 15,
},
]);
function selectedTipChange(item: any) {
if(item.value === selectedTipIndex.value) return
diyTipValue.value = ''
selectedTipIndex.value = item.value
appMerchantOrderCalculatePriceCart()
}
function handleConfirmTip() {
if(diyTipValue.value) {
appMerchantOrderCalculatePriceCart()
}
}
// 是否选择了配送周卡
const isWeeklyDelivery = ref(false);
// 切换配送周卡
const toggleWeeklyDelivery = (value: boolean) => {
if(value === isWeeklyDelivery.value) return
isWeeklyDelivery.value = value;
appMerchantOrderCalculatePriceCart()
};
// 价格明细
const priceDetailRef = ref<InstanceType<typeof PriceDetail>>();
// 打开价格明细
const openPriceDetail = () => {
priceDetailRef.value?.onOpen(priceData.value, cartSavingsData.value?.savings || 0);
};
function navigateTo(url: string) {
uni.navigateTo({ url })
}
// 支付参数
const payMethodOptions = ref({
orderId: '',
cardId: '',
payMethod: 1, // 支付方式 1信用卡 2余额
payPassword: '',
})
useEventEmit(EventEnum.CHOOSE_PAYMENT_METHOD, (data) => {
if(data) {
if(data.payMethod === 1) {
payMethodOptions.value.cardId = data.cardId
payMethodOptions.value.cardNumber = data.cardNumber
payMethodOptions.value.payMethod = 1
} else {
payMethodOptions.value.payMethod = 2
}
}
})
const storeId = ref('')
const orderType = ref('') // 订单类型:batch-批量下单,normal-普通下单
const batchCartIds = ref([]) // 批量下单的购物车ID列表
const formData = ref<CreateOrderCartBo>({
orderRemark: '',
phone: '',
receiveMethod: 0,
startScheduledTime: 0,
endScheduledTime: 0,
tipDiscount: 0,
weeklyDeliveryFee: 0,
})
// 是否需要餐具
const needTableware = ref(false)
onLoad((options: any)=> {
loading.value = true
// 判断是批量下单还是普通下单
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
needTableware.value = options.needTableware === 'true'
// 默认取用户信息中的手机号作为收货手机号
formData.value.phone = userStore.userInfo.phone || ''
contact.value.areaCode = userStore.userInfo.areaCode || ''
// 获取用户地址列表
getAddressList()
// 查询当前店铺购物车详情
getCartInfo()
// 获取商家详情信息
getStoreDetail()
// 查询用户默认信用卡
appUserCardSelectDefault()
}
})
onShow(()=> {
// 刷新购物车列表
getAddressList()
})
// 页面加载状态
const loading = ref(true);
onMounted(() => {
userStore.getUserInfo()
const currentHour = dayjs().hour();
if (currentHour >= 11 && currentHour <= 14) {
setDeliveryMinutes(60);
} else if (currentHour >= 17 && currentHour <= 20) {
// 晚餐高峰期,配送时间延长
setDeliveryMinutes(50);
} else {
// 非高峰期,正常配送时间
setDeliveryMinutes(40);
}
});
const cartDataList = ref<MerchantCartVo[]>([])
function getCartInfo() {
appMerchantCartListByMerchantIdPost({
params: {
merchantId: storeId.value,
}
}).then((res: any)=> {
console.log('购物车列表', res)
cartDataList.value = res.data
// 购物车有菜品,查询菜品会员折扣价
if(cartDataList.value.length > 0) {
appMerchantCartCalculateSavings()
// 查询购物车下单价格
appMerchantOrderCalculatePriceCart()
}
}).finally(()=> {
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: cartIds
}).then(res=> {
console.log('菜品会员折扣价', res)
cartSavingsData.value = res.data
})
}
// 获取商家详情信息
// 商家是否支持配送
const storeIsDeliveryService = computed(()=> {
if(!storeDetail.value) return false
return +storeDetail.value.deliveryService === 1
})
// 商家是否支持自提
const storeIsSelfPickup = computed(()=> {
if(!storeDetail.value) return false
return +storeDetail.value.selfPickup === 1
})
const storeDetail = ref<MerchantVo>({})
// 用户距离商家的距离信息
const storeDistance = ref(null)
function getStoreDetail() {
appMerchantDetailMerchantIdGet({
params: {
merchantId: storeId.value,
}
}).then((res: any) => {
console.log('商家详情', res)
storeDetail.value = res.data as MerchantVo
// 配送时间(是否支持配送)
if(+storeDetail.value.deliveryService === 1) {
// 配送时间
deliveryMinutes.value = res.data.deliveryTime || 0
}
if(+storeDetail.value.selfPickup === 1) {
// 自提时间
selfPickupMinutes.value = res.data.pickupTime
}
// 商户的经纬度存在,并且用户的经纬度也存在
if(res.data.latitude && res.data.longitude && userStore.userLocation.latitude && userStore.userLocation.longitude) {
let distance = getDistanceInMiles(res.data.latitude, res.data.longitude, userStore.userLocation.latitude, userStore.userLocation.longitude)
console.log('距离商家距离', distance)
storeDistance.value = distance
}
// 判断配送和自取的开通状态
const hasDelivery = +storeDetail.value.deliveryService === 1
const hasPickup = +storeDetail.value.selfPickup === 1
if (!hasDelivery && !hasPickup) {
// 两个都没开通,不显示切换组件
showDeliverySwitch.value = false
} else if (!hasDelivery && hasPickup) {
// 只开通自取,默认选中自取
deliveryMethod.value = 1
showDeliverySwitch.value = true
} else if (hasDelivery && !hasPickup) {
// 只开通配送,默认选中配送
deliveryMethod.value = 0
showDeliverySwitch.value = true
} else {
// 两个都开通,默认选中配送
deliveryMethod.value = 0
showDeliverySwitch.value = true
}
}).catch((error) => {
console.error('获取商家详情失败:', error);
})
}
const priceData = ref({})
function appMerchantOrderCalculatePriceCart() {
// 优先使用新选择的地址id
const targetAddressId = selectedAddressId.value || currentAddressId.value
// if(!targetAddressId) return
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
})
}
}
// 获取用户地址列表
const addressesList = ref([])
// 当前选中的地址id
const currentAddressId = ref('')
// 新选择的地址id(优先使用)
const selectedAddressId = ref('')
// 当前选中的地址信息
const addressInfo = computed(()=> {
if(addressesList.value.length === 0) return {}
// 优先使用新选择的地址id,如果没有则使用默认的地址id
const targetId = selectedAddressId.value || currentAddressId.value
return addressesList.value.find(item => String(item.id) === String(targetId)) || {};
});
function getAddressList() {
appUserAddressListPost({
params: {
pageNum: 1,
pageSize: 100,
}
}).then(res => {
console.log('获取用户地址列表', res)
addressesList.value = res.rows
if(addressesList.value.length > 0) {
currentAddressId.value = addressesList.value[0].id
let data = addressesList.value[0]
// 回显用户地址中的送达偏好
// 回显送达偏好
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()
}
}
})
}
function chooseAddress() {
// 优先使用新选择的地址id
const targetAddressId = selectedAddressId.value || currentAddressId.value
uni.navigateTo({
url: '/pages-store/pages/order/choose-address?id=' + targetAddressId,
events: {
// 为指定事件添加一个监听器,获取被打开页面传送到当前页面的数据
acceptDataFromOpenedPage: function(data) {
console.log('获取被打开页面传送到当前页面的数据', data)
// 将新选择的地址id存储到selectedAddressId中
selectedAddressId.value = data.data
// 回显送达偏好
if(+data.deliveryType === 1) {
visitMethod.value.label = t('components.visit.leaveItToMePersonally')
}
if(+data.deliveryType === 2) {
visitMethod.value.label = t('components.visit.putItAtTheDoor')
}
// 重新计算价格
appMerchantOrderCalculatePriceCart()
},
},
})
}
function appUserCardSelectDefault() {
appUserCardSelectDefaultPost({}).then(res=> {
console.log('查询用户默认信用卡', res)
payMethodOptions.value.cardId = res.data?.cardId || ''
payMethodOptions.value.cardNumber = res.data?.cardNumber || ''
})
}
// 是否显示周配送费选项
const isShowWeeklyDelivery = computed(()=> {
let time = userStore?.userInfo?.weeklyDeliveryExpire;
// 如果值为null,返回true
if (time === null) return true;
// 如果值不存在(如undefined),也返回true(根据你的需求可调整)
if (!time) return true;
// 检测是否到期:已过期返回true,未过期返回false
return dayjs().isAfter(dayjs(Number(time)));
})
const passwordInputRef = ref(null)
const resOrderId = ref('')
const resOrderIds = ref([]) // 批量下单返回的订单ID列表
function handleGoSettle() {
// 优先使用新选择的地址id
const targetAddressId = selectedAddressId.value || currentAddressId.value
if(!targetAddressId) {
uni.showToast({
title: t('pages-store.checkout.pleaseSelectAddress'),
icon: 'none'
})
return
}
if(payMethodOptions.value.payMethod === 1 && !payMethodOptions.value.cardId) {
uni.showToast({
title: t('pages-store.checkout.pleaseSelectCreditCard'),
icon: 'none'
})
return
}
// 批量下单
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
} 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 {
// 如果是余额支付,弹出支付密码弹窗
if(payMethodOptions.value.payMethod === 2) {
passwordInputRef.value?.showPasswordInput()
} else {
appMerchantOrderPayOrderBatch()
}
}
} 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()
}
}
}
}
function payPawSuccess(password: string) {
payMethodOptions.value.payPassword = password
if(orderType.value === 'batch') {
appMerchantOrderPayOrderBatch()
} else {
appMerchantOrderPayOrder()
}
}
function appMerchantOrderPayOrder() {
appMerchantOrderPayOrderPost({
body: {
...payMethodOptions.value,
orderId: resOrderId.value
}
}).then(res=> {
console.log('支付结果', res)
uni.showToast({
title: t('pages-store.checkout.paymentSuccess'),
icon: 'none'
})
setTimeout(()=> {
uni.navigateBack({
delta: 2,
})
}, 500)
})
}
// 批量订单支付
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') {
throw new Error('输入必须是有效的时间字符串,格式如 "HH:mm-HH:mm"');
}
// 验证格式是否正确
const timeFormatRegex = /^([01]\d|2[0-3]):([0-5]\d)-([01]\d|2[0-3]):([0-5]\d)$/;
if (!timeFormatRegex.test(timeStr)) {
throw new Error('时间格式不正确,请使用 "HH:mm-HH:mm" 格式,例如 "17:57-18:27"');
}
// 分割时间字符串
const [startTimeStr, endTimeStr] = timeStr.split('-');
// 获取当前日期
const today = dayjs().format('YYYY-MM-DD');
// 解析开始和结束时间
const startTime = dayjs(`${today} ${startTimeStr}`);
const endTime = dayjs(`${today} ${endTimeStr}`);
// 验证时间是否有效
if (!startTime.isValid()) {
throw new Error(`开始时间 ${startTimeStr} 无效`);
}
if (!endTime.isValid()) {
throw new Error(`结束时间 ${endTimeStr} 无效`);
}
// 验证结束时间是否晚于开始时间
if (endTime.isBefore(startTime)) {
throw new Error('结束时间不能早于开始时间');
}
// 返回时间戳(毫秒)
return {
startTimestamp: startTime.valueOf(),
endTimestamp: endTime.valueOf()
};
}
/**
* CreateOrderCartBo
*/
export interface CreateOrderCartBo {
/**
* 配送地址id
*/
addressId?: number;
/**
* 区号
*/
areaCode?: string;
/**
* 购物车id列表
*/
cartIds?: number[];
/**
* 优惠券id
*/
couponId?: number;
/**
* 派送方式(如放门口或者交到顾客手中)
*/
deliveryMethod?: string;
/**
* 交付时间类型(1-立即交付 2-预约交付)
*/
deliveryType?: number;
/**
* 订单备注
*/
orderRemark?: string;
/**
* 手机号
*/
phone: string;
/**
* 收货方式(1-派送 2-自取)
*/
receiveMethod: number;
/**
* 预约时间- 开始
*/
startScheduledTime?: number;
/**
* 预约时间- 结束
*/
endScheduledTime?: number;
/**
* 小费比例
*/
tipDiscount?: number;
/**
* 是否支付周配送费(1-是 2-否)
*/
weeklyDeliveryFee?: number;
[property: string]: any;
}
const couponInfo = ref(null)
function navigateToCoupon() {
uni.navigateTo({
url: '/pages-user/pages/coupon/list?id=' + storeId.value,
events: {
// 为指定事件添加一个监听器,获取被打开页面传送到当前页面的数据
selectedCoupon: function(data) {
console.log(data)
if(data) {
couponInfo.value = data
// 重新计算价格
appMerchantOrderCalculatePriceCart()
}
},
},
})
}
function handleClose() {
couponInfo.value = null
// 重新计算价格
appMerchantOrderCalculatePriceCart()
}
</script>
<template>
<navbar />
<view
class="animate-in fade-in animate-ease-out animate-duration-300"
v-show="loading"
>
<!-- 骨架屏 -->
<CheckoutSkeleton
/></view>
<view
class="animate-in fade-in animate-ease-in animate-duration-300"
v-if="!loading"
>
<!-- 页面标题 -->
<view class="px-30rpx pt-20rpx">
<view class="text-46rpx font-bold text-#333 mb-52rpx">{{ t("pages-store.checkout.title") }}</view>
<!-- 配送方式选择 -->
<!-- <l-segmented
@click="handleClickSegmented"
:value="deliveryMethod"
:options="deliveryMethodOptions"
shape="round"
bg-color="#F2F2F2"
active-color="#333"
/> -->
</view>
<!-- 地址信息 -->
<view class="mt-4rpx">
<view
class="animate-in fade-in animate-ease-out animate-duration-300"
v-show="deliveryMethod === 0"
>
<!-- 收货地址 -->
<view @click="chooseAddress" class="flex-center-sb border-bottom py-36rpx px-30rpx">
<!-- 地址图标 -->
<view class="flex items-center">
<image
src="@img/chef/145.png"
mode="aspectFill"
class="w-44rpx h-44rpx shrink-0 relative z-1"
/>
<!-- 地址信息 -->
<view v-if="addressesList.length > 0 && addressInfo" class="ml-28rpx">
<view
class="text-32rpx lh-32rpx font-500 text-#333 block mb-8rpx"
>
<text class="line-clamp-1">{{ addressInfo.formattedAddress }}</text>
</view>
<view class="text-28rpx lh-28rpx text-#6D6D6D">{{
addressInfo.displayName
}}</view>
</view>
<view v-else class="ml-28rpx text-32rpx lh-32rpx font-500 text-#333">{{ t('pages-store.checkout.addAddress') }}</view>
</view>
<image
src="@img/chef/142.png"
mode="aspectFill"
class="w-32rpx h-32rpx shrink-0"
/>
</view>
<!-- 配送偏好 -->
<view
@click="chooseVisitMethod"
class="flex-center-sb border-bottom py-36rpx px-30rpx"
>
<view class="flex items-center">
<image
src="@img/chef/1333.png"
mode="aspectFill"
class="w-44rpx h-44rpx shrink-0 relative z-1"
/>
<view class="ml-28rpx text-32rpx lh-32rpx font-500 text-#333">
{{ visitMethod.label }}
</view>
</view>
<image
src="@img/chef/142.png"
mode="aspectFill"
class="w-32rpx h-32rpx shrink-0"
/>
</view>
<!-- 联系电话 -->
<view
@click="openChangePhone"
class="flex-center-sb border-bottom py-36rpx px-30rpx"
>
<view class="flex items-center">
<image
src="@img/chef/1334.png"
mode="aspectFill"
class="w-44rpx h-44rpx shrink-0 relative z-1"
/>
<view class="ml-28rpx text-32rpx lh-32rpx font-500 text-#333">
{{ contact.areaCode }} {{ formData.phone }}
</view>
</view>
<image
src="@img/chef/142.png"
mode="aspectFill"
class="w-32rpx h-32rpx shrink-0"
/>
</view>
</view>
<view
class="animate-in fade-in animate-ease-in animate-duration-300"
v-show="deliveryMethod === 1"
>
<!-- 门店地址 -->
<view class="flex items-center border-bottom py-36rpx px-30rpx">
<image
src="@img/chef/1337.png"
mode="aspectFill"
class="w-44rpx h-44rpx shrink-0 relative z-1"
/>
<view class="ml-28rpx">
<text class="text-32rpx lh-32rpx font-500 text-#333 block mb-8rpx"
>{{ storeDetail?.merchantName }}</text
>
<text class="text-28rpx lh-28rpx text-#6D6D6D line-clamp-1"
>{{ storeDetail?.merchantAddress }}</text
>
</view>
</view>
<!-- 门店距离 -->
<view class="flex items-center border-bottom py-36rpx px-30rpx">
<image
src="@img/chef/145.png"
mode="aspectFill"
class="w-44rpx h-44rpx shrink-0 relative z-1"
/>
<view class="ml-28rpx">
<text
class="text-32rpx lh-32rpx font-500 text-#333 block mb-8rpx"
>{{ t("pages-store.checkout.distance") }}</text
>
<text class="text-28rpx lh-28rpx text-#6D6D6D">
<template v-if="storeDistance">
{{ storeDistance }} {{ t('common.mile') }}
</template>
<template v-else>{{ t('pages-store.checkout.enableLocationForDistance') }}</template>
</text>
</view>
</view>
</view>
<!-- 个人配送选项 -->
<view class="flex-center-sb py-36rpx px-30rpx">
<view class="flex items-center">
<image
src="@img/chef/146.png"
mode="aspectFill"
class="w-44rpx h-44rpx shrink-0 relative z-1"
/>
<view class="ml-28rpx text-32rpx lh-32rpx font-500 text-#333">
<template v-if="deliveryMethod === 0">
{{ t("pages-store.checkout.deliveryTime") }}
</template>
<template v-if="deliveryMethod === 1">
{{ t('pages-store.checkout.pickupTime') }}
</template>
</view>
</view>
<!-- 时间 -->
<view class="text-32rpx lh-32rpx font-500 text-#333">
<!--配送-->
<template v-if="deliveryMethod === 0">
<!--即刻配送-->
<template v-if="deliveryTimeType === 1">
{{ showDeliveryTime }}
</template>
<template v-else>
{{ userSelectedDeliveryTimeDate }}
</template>
</template>
<!--自取-->
<template v-if="deliveryMethod === 1">
<!--即刻配送-->
<template v-if="deliveryTimeType === 1">
{{ showDeliveryTime }}
</template>
<template v-else>
{{ userSelectedSelfPickupTimeDate }}
</template>
</template>
</view>
</view>
<!--配送-->
<template v-if="storeIsDeliveryService && deliveryMethod === 0">
<view class="flex-center-sb pb-36rpx px-30rpx gap-22rpx">
<view
@click="toggleDeliveryTimeType(1)"
:class="[deliveryTimeType === 1 ? 'border-#333' : 'border-#D8D8D8']"
class="w-full h-152rpx text-28rpx lh-28rpx border-solid border-1px rounded-20rpx center"
>
<view class="text-center">
<view class="text-#333 mb-12rpx">
{{ t("pages-store.checkout.immediateDelivery") }}
</view>
<view class="text-#7D7D7D">{{ storeDetail?.deliveryTime }}{{ t('common.minutes') }}</view>
</view>
</view>
<view
@click="toggleDeliveryTimeType(2)"
:class="[deliveryTimeType === 2 ? 'border-#333' : 'border-#D8D8D8']"
class="w-full h-152rpx text-28rpx lh-28rpx border-solid border-1px rounded-20rpx center"
>
<view class="text-center">
<view class="text-#333 mb-12rpx">
{{ t("pages-store.checkout.appointmentDelivery") }}
</view>
<view class="text-#7D7D7D">
<template v-if="!userSelectedDeliveryTimeDate">
{{ t("pages-store.checkout.chooseTime") }}
</template>
<template v-else>
{{ userSelectedDeliveryTimeDate }}
</template>
</view>
</view>
</view>
</view>
</template>
<!--自取-->
<template v-if="storeIsSelfPickup && deliveryMethod === 1">
<view class="flex-center-sb pb-36rpx px-30rpx gap-22rpx">
<view
@click="toggleDeliveryTimeType(1)"
:class="[deliveryTimeType === 1 ? 'border-#333' : 'border-#D8D8D8']"
class="w-full h-152rpx text-28rpx lh-28rpx border-solid border-1px rounded-20rpx center"
>
<view class="text-center">
<view class="text-#333 mb-12rpx">
{{ t('pages-store.checkout.immediatePickup') }}
</view>
<view class="text-#7D7D7D">{{ storeDetail?.pickupTime }}{{ t('common.minutes') }}</view>
</view>
</view>
<view
@click="toggleDeliveryTimeType(2)"
:class="[deliveryTimeType === 2 ? 'border-#333' : 'border-#D8D8D8']"
class="w-full h-152rpx text-28rpx lh-28rpx border-solid border-1px rounded-20rpx center"
>
<view class="text-center">
<view class="text-#333 mb-12rpx">
{{ t('pages-store.checkout.appointmentPickup') }}
</view>
<view class="text-#7D7D7D">
<template v-if="!userSelectedSelfPickupTimeDate">
{{ t("pages-store.checkout.chooseTime") }}
</template>
<template v-else>
{{ userSelectedSelfPickupTimeDate }}
</template>
</view>
</view>
</view>
</view>
</template>
</view>
<!-- 分隔线 -->
<view class="w-full h-10rpx bg-#F6F6F6"></view>
<!-- 订单信息摘要 -->
<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
>
<wd-collapse v-model="collapseValue">
<wd-collapse-item name="item3">
<template #title="{ expanded, disabled, isFirst }">
<view class="flex-center-sb">
<view class="flex items-center">
<image
class="w-80rpx h-80rpx rounded-50% mr-24rpx"
:src="storeDetail?.logo"
mode="aspectFill"
/>
<view>
<view class="text-30rpx lh-30rpx text-#333 font-500"
>{{ storeDetail?.merchantName }}</view
>
<view
class="text-28rpx lh-28rpx text-#7D7D7D font-400 mt-16rpx"
>{{ cartDataList.length }} {{ t('pages-user.cart.items') }}</view
>
</view>
</view>
<image
:class="[expanded ? 'rotate--90' : 'rotate-90']"
src="@img/chef/142.png"
mode="aspectFill"
class="w-32rpx h-32rpx shrink-0 transition-all duration-300"
/>
</view>
</template>
<template v-for="(item , index) in cartDataList">
<view
class="w-full border-bottom h-136rpx flex-center-sb pl-46rpx pr-30rpx"
>
<view class="flex items-center">
<view
class="w-48rpx h-48rpx rounded-8rpx bg-#F2F2F2 center mr-40rpx"
>{{ index + 1 }}</view
>
<view>
<view class="text-32rpx lh-32rpx text-#333 font-500"
>{{ item.merchantDishVo?.dishName }}</view
>
<view v-if="item.sideDishList?.length > 0"
class="text-28rpx lh-28rpx text-#7D7D7D font-400 mt-12rpx"
>
<template v-for="dish in item.sideDishList">
<text class="mr-6rpx">{{ dish.merchantSideDishItemVo?.name }}</text>
<text class="text-#00A76D mx-6rpx">+${{ dish.merchantSideDishItemVo?.price }}</text>
</template>
</view>
</view>
</view>
<view class="text-32rpx lh-32rpx text-#333 font-500">${{ item.merchantDishVo?.discountPrice }}</view>
</view>
</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">
<view class="flex items-center">
<image
src="@img/chef/105.png"
mode="aspectFill"
class="w-44rpx h-44rpx relative z-1"
/>
<view class="ml-28rpx text-32rpx lh-32rpx font-500 text-#333">
{{ couponInfo? couponInfo.snapshotNameZh : t('pages-store.checkout.addCoupon') }}
</view>
</view>
<view v-if="couponInfo" @click.stop="handleClose" class="i-carbon:close-filled"></view>
</view>
<image
src="@img/chef/142.png"
mode="aspectFill"
class="w-32rpx h-32rpx shrink-0"
/>
</view>
<template v-if="deliveryMethod === 0">
<!-- 小费 -->
<view class="border-bottom py-36rpx px-30rpx">
<view class="flex items-center mb-28rpx">
<image
src="@img/chef/1335.png"
mode="aspectFill"
class="w-44rpx h-44rpx relative z-1"
/>
<view class="ml-28rpx text-32rpx lh-32rpx font-500 text-#333">
{{ t('pages-store.checkout.chooseTips') }}
</view>
</view>
<view class="flex-center-sb gap-22rpx">
<template v-for="(item, index) in tipOptions">
<view
@click="selectedTipChange(item)"
:class="[
selectedTipIndex === item.value
? 'border-#333'
: 'border-#D8D8D8',
]"
class="w-full h-72rpx text-28rpx lh-28rpx text-#333 rounded-20rpx border-solid border-1px center"
>
{{ item.label }}
</view>
</template>
<view
@click="selectedTipChange({ value: 0 })"
:class="[
selectedTipIndex === 0
? 'border-#333'
: 'border-#D8D8D8',
]"
class="w-full h-72rpx text-28rpx lh-28rpx text-#333 rounded-20rpx border-solid border-1px center"
>
<view class="px-10rpx center">
<wd-input
no-border
use-prefix-slot
@blur="handleConfirmTip"
custom-class="!center !text-30rpx !bg-transparent flex-1 !text-center"
placeholderStyle="font-size: 28rpx;color: #333; text-align: center;"
:placeholder="t('pages-store.checkout.other')"
v-model="diyTipValue"
@confirm="handleConfirmTip"
>
<template #suffix>
<text v-if="diyTipValue.length > 0">%</text>
</template>
</wd-input>
</view>
</view>
</view>
</view>
<!-- 配送费周卡 -->
<!-- <view v-if="isShowWeeklyDelivery" class="border-bottom px-30rpx py-36rpx">-->
<!-- <view class="flex-center-sb">-->
<!-- <text class="text-32rpx lh-32rpx font-500 text-#333"-->
<!-- >{{ t('pages-store.checkout.tips') }}?</text-->
<!-- >-->
<!-- <view-->
<!-- class="flex items-center gap-50rpx text-32rpx lh-32rpx font-500 text-#333"-->
<!-- >-->
<!-- <view @click="toggleWeeklyDelivery(true)" class="flex items-center">-->
<!-- &lt;!&ndash; 单选按钮是 &ndash;&gt;-->
<!-- <image-->
<!-- :src="-->
<!-- isWeeklyDelivery-->
<!-- ? '/static/images/chef/133.png'-->
<!-- : '/static/images/chef/134.png'-->
<!-- "-->
<!-- class="w-36rpx h-36rpx shrink-0 mr-10rpx"-->
<!-- mode="aspectFit"-->
<!-- />-->
<!-- {{ t('pages-store.checkout.yes') }}-->
<!-- </view>-->
<!-- <view-->
<!-- @click="toggleWeeklyDelivery(false)"-->
<!-- class="flex items-center"-->
<!-- >-->
<!-- &lt;!&ndash; 单选按钮否 &ndash;&gt;-->
<!-- <image-->
<!-- :src="-->
<!-- !isWeeklyDelivery-->
<!-- ? '/static/images/chef/133.png'-->
<!-- : '/static/images/chef/134.png'-->
<!-- "-->
<!-- class="w-36rpx h-36rpx shrink-0 mr-10rpx"-->
<!-- mode="aspectFit"-->
<!-- />-->
<!-- {{ t('pages-store.checkout.no') }}-->
<!-- </view>-->
<!-- </view>-->
<!-- </view>-->
<!-- <view class="text-28rpx lh-28rpx text-#7D7D7D mt-24rpx">-->
<!-- {{ t('pages-store.checkout.tipsDesc') }}-->
<!-- </view>-->
<!-- </view>-->
</template>
<!-- 费用明细 -->
<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 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">
<text>{{ t('pages-store.order.taxesAndOtherFees') }}</text>
<image
src="@img/chef/1336.png"
class="w-28rpx h-28rpx shrink-0 ml-10rpx mt-4rpx"
mode="aspectFit"
/>
</view>
<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 v-if="orderType === 'batch'">${{ priceData?.totalPaidAmount || '0.00' }}</text>
<text v-else>${{ priceData?.paidAmount || '0.00' }}</text>
</view>
</view>
<!-- 支付方式 -->
<view
@click="navigateTo('/pages-user/pages/choose-paymethod/index')"
class="flex-center-sb border-bottom text-32rpx lh-32rpx font-500 text-#333 py-36rpx px-30rpx"
>
<view class="flex items-center">
<image
src="@img/chef/138.png"
class="w-44rpx h-44rpx mr-28rpx shrink-0"
mode="aspectFit"
/>
<text class="">
<template v-if="payMethodOptions.payMethod === 1">{{ t('pages-user.choosePaymethod.creditCard') }}</template>
<template v-else>{{ t('pages-user.choosePaymethod.wallet') }}</template>
</text>
</view>
<view class="flex items-center">
<view class="mr-12px">
<template v-if="payMethodOptions.payMethod === 1">
<!--判断用户是否有信用卡-->
<text v-if="!payMethodOptions.cardId">{{ t("pages-user.member.creditCard") }}</text>
<text v-else>{{ payMethodOptions.cardNumber }}</text>
</template>
<template v-else-if="payMethodOptions.payMethod === 2">
<text>{{ t('pages-user.choosePaymethod.wallet') }}</text>
</template>
</view>
<image
src="@img/chef/142.png"
class="w-32rpx h-32rpx shrink-0"
mode="aspectFit"
/>
</view>
</view>
</view>
<view class="h-204rpx"></view>
<!-- 底部支付按钮 -->
<view class="fixed z-9 bottom-0 left-0 right-0 bg-white">
<view @click="navigateTo('/pages-user/pages/member/index')" v-if="cartSavingsData && cartSavingsData.savings > 0" class="h-76rpx bg-#CE7138 pl-56rpx flex items-center">
<image
src="@img/chef/1289.png"
class="mr-10rpx w-32rpx h-32rpx shrink-0"
></image>
<text class="text-[#fff] text-24rpx lh-24rpx">
{{ t('pages-store.store.use') }} {{ Config.appName }} {{ t('pages-store.store.tips3') }} ${{ cartSavingsData?.savings }} {{ t('pages-store.store.discount') }}
</text>
</view>
<view class="px-30rpx py-18rpx">
<wd-button
@click="handleGoSettle"
custom-class="!h-92rpx !text-30rpx !text-#fff !lh-92rpx !rounded-16rpx"
block
>{{ t('common.goSettle') }}
</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> -->
</view>
<view :style="[configStore.iosSafeBottomPlaceholder]"></view>
</view>
<!-- 修改配送偏好 -->
<visit-method ref="visitMethodRef" @confirm="handleVisitMethodConfirm" />
<!-- 修改手机号 -->
<change-phone ref="changePhoneRef" @confirm="confirmPhone" />
<!-- 价格明细 -->
<price-detail ref="priceDetailRef" />
<password-container @success="payPawSuccess" ref="passwordInputRef" />
</view>
</template>
<style>
page {
background-color: #fff;
}
</style>
<style scoped lang="scss">
:deep(.wd-collapse-item) {
&::after {
display: none;
background-color: transparent !important;
}
}
:deep(.wd-collapse-item__header.is-expanded) {
&::after {
background-color: transparent !important;
}
}
:deep(.wd-collapse-item__body) {
padding: 0 !important;
}
</style>