|
|
@@ -1,4 +1,5 @@
|
|
|
<script setup lang="ts">
|
|
|
+import CouponItem from '../components/coupon/index.vue'
|
|
|
import router from '@/router'
|
|
|
|
|
|
definePage({
|
|
|
@@ -14,18 +15,63 @@ const orderInfo = ref<Api.shoppingCartOrderConfirm>()
|
|
|
const { totalProduct } = storeToRefs(useSmqjhCartStore())
|
|
|
const isPay = ref(false)
|
|
|
const remarks = ref('')
|
|
|
+const initialCouponId = ref<string | undefined>(undefined)
|
|
|
+const confirmedCouponId = ref<string | undefined>(undefined)
|
|
|
+const draftCouponId = ref<string | undefined>(undefined)
|
|
|
|
|
|
+const deliveryType = ref(1)
|
|
|
+
|
|
|
+// 优惠券选择
|
|
|
+const couponPopup = ref(false)
|
|
|
+const couponList = ref<Api.AppMemberCouponVO[]>([])
|
|
|
+const couponTabActive = ref(0)
|
|
|
+const availableCoupons = computed(() => couponList.value.filter(it => it.useStatus === 2))
|
|
|
+const unavailableCoupons = computed(() => couponList.value.filter(it => it.useStatus !== 2))
|
|
|
+const displayCoupons = computed(() => couponTabActive.value === 0 ? availableCoupons.value : unavailableCoupons.value)
|
|
|
+const confirmedCoupon = computed(() => couponList.value.find(it => it.allowanceId === confirmedCouponId.value))
|
|
|
+const draftCoupon = computed(() => couponList.value.find(it => it.allowanceId === draftCouponId.value))
|
|
|
+const hasManualCouponSelection = computed(() => confirmedCouponId.value !== initialCouponId.value)
|
|
|
+const currentCouponDiscount = computed(() => {
|
|
|
+ if (hasManualCouponSelection.value) {
|
|
|
+ return Number(confirmedCoupon.value?.discountMoney || 0)
|
|
|
+ }
|
|
|
+ return Number(orderInfo.value?.coupon || 0)
|
|
|
+})
|
|
|
const offsetPoints = computed(() => {
|
|
|
- const money = Math.round(Number(unref(orderInfo)?.transfee) * 100) + Math.round(Number(unref(orderInfo)?.price) * 100)
|
|
|
- if (Number(unref(orderInfo)?.offsetPoints) > money) {
|
|
|
- return money
|
|
|
+ const couponCents = Math.round(currentCouponDiscount.value * 100)
|
|
|
+ const money = Math.round(Number(unref(orderInfo)?.transfee) * 100) + Math.round(Number(unref(orderInfo)?.price) * 100) - couponCents
|
|
|
+ const cap = Math.max(0, money)
|
|
|
+ if (Number(unref(orderInfo)?.offsetPoints) > cap) {
|
|
|
+ return cap
|
|
|
}
|
|
|
return Number(unref(orderInfo)?.offsetPoints)
|
|
|
})
|
|
|
-const deliveryType = ref(1)
|
|
|
+const currentCouponName = computed(() => {
|
|
|
+ if (hasManualCouponSelection.value) {
|
|
|
+ return getCouponDisplayName(confirmedCoupon.value)
|
|
|
+ }
|
|
|
+ return getCouponDisplayName(orderInfo.value)
|
|
|
+})
|
|
|
+const displayTotalPrice = computed(() => {
|
|
|
+ if (!orderInfo.value) {
|
|
|
+ return 0
|
|
|
+ }
|
|
|
+ if (!hasManualCouponSelection.value) {
|
|
|
+ return Number(orderInfo.value.totalPrice || 0)
|
|
|
+ }
|
|
|
+ const goodsPrice = Number(orderInfo.value.price || 0)
|
|
|
+ const freight = Number(orderInfo.value.transfee || 0)
|
|
|
+ const pointsDiscount = offsetPoints.value / 100
|
|
|
+ return Math.max(0, Number((goodsPrice + freight - currentCouponDiscount.value - pointsDiscount).toFixed(2)))
|
|
|
+})
|
|
|
+const displayDiscountTotal = computed(() => Number((currentCouponDiscount.value + offsetPoints.value / 100).toFixed(2)))
|
|
|
+
|
|
|
onLoad((options: any) => {
|
|
|
- console.log(options.data)
|
|
|
orderInfo.value = JSON.parse(options.data)
|
|
|
+ couponList.value = orderInfo.value?.orderCouponItemDTOS || []
|
|
|
+ initialCouponId.value = orderInfo.value?.allowanceId
|
|
|
+ confirmedCouponId.value = initialCouponId.value
|
|
|
+ draftCouponId.value = initialCouponId.value
|
|
|
})
|
|
|
onShow(() => {
|
|
|
useUserStore().getuserAddresslist()
|
|
|
@@ -34,11 +80,15 @@ onShow(() => {
|
|
|
}
|
|
|
})
|
|
|
|
|
|
+function getCouponDisplayName(coupon?: Partial<Api.AppMemberCouponVO> & Record<string, any>) {
|
|
|
+ return coupon?.activityName || coupon?.couponName || ''
|
|
|
+}
|
|
|
+
|
|
|
async function getDevryList() {
|
|
|
const res = await Apis.xsb.delivery({
|
|
|
data: {
|
|
|
memberId: userInfo.value.id,
|
|
|
- shopId: SelectShopInfo.value.shopId,
|
|
|
+ shopId: Number(orderInfo.value?.skuList[0].shopId || SelectShopInfo.value?.shopId || 2),
|
|
|
addressId: selectedAddress.value?.id,
|
|
|
},
|
|
|
})
|
|
|
@@ -46,6 +96,23 @@ async function getDevryList() {
|
|
|
console.log(res)
|
|
|
}
|
|
|
|
|
|
+async function openCouponPopup() {
|
|
|
+ draftCouponId.value = confirmedCouponId.value
|
|
|
+ couponPopup.value = true
|
|
|
+}
|
|
|
+
|
|
|
+function handleSelectCoupon(item: Api.AppMemberCouponVO) {
|
|
|
+ if (item.useStatus !== 2 || !item.allowanceId) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ draftCouponId.value = item.allowanceId
|
|
|
+}
|
|
|
+
|
|
|
+function confirmCoupon() {
|
|
|
+ confirmedCouponId.value = draftCouponId.value
|
|
|
+ couponPopup.value = false
|
|
|
+}
|
|
|
+
|
|
|
async function handlePay() {
|
|
|
if (!selectedAddress.value) {
|
|
|
useGlobalToast().show({ msg: '请选择收货地址' })
|
|
|
@@ -64,11 +131,18 @@ async function handlePay() {
|
|
|
}
|
|
|
})
|
|
|
|
|
|
- const orderNumber = await useUserStore().getOrderPayMent(orderInfo.value.transfee, 'XSB', deliveryType.value, Number(orderInfo.value?.skuList[0].shopId || SelectShopInfo.value.shopId), orderItemList, unref(remarks))
|
|
|
+ const orderNumber = await useUserStore().getOrderPayMent(
|
|
|
+ orderInfo.value.transfee,
|
|
|
+ 'XSB',
|
|
|
+ deliveryType.value,
|
|
|
+ Number(orderInfo.value?.skuList[0].shopId || SelectShopInfo.value?.shopId),
|
|
|
+ orderItemList,
|
|
|
+ unref(remarks),
|
|
|
+ confirmedCouponId.value,
|
|
|
+ )
|
|
|
const res = await useUserStore().handleCommonPayMent(orderNumber)
|
|
|
await useUserStore().clearCart(orderInfo.value.skuList)
|
|
|
totalProduct.value = null
|
|
|
- console.log('进入微信支付', res)
|
|
|
if (res.payType !== 1) {
|
|
|
try {
|
|
|
await useUserStore().getWxCommonPayment(res)
|
|
|
@@ -90,7 +164,10 @@ async function handlePay() {
|
|
|
|
|
|
<template>
|
|
|
<view class="page px20rpx py20rpx">
|
|
|
- <view class="mb20rpx rounded-16rpx bg-white p24rpx" @click="router.push({ name: 'common-addressList', params: { type: 'select' } })">
|
|
|
+ <view
|
|
|
+ class="mb20rpx rounded-16rpx bg-white p24rpx"
|
|
|
+ @click="router.push({ name: 'common-addressList', params: { type: 'select' } })"
|
|
|
+ >
|
|
|
<view class="flex items-center justify-between">
|
|
|
<view v-if="!selectedAddress" class="flex items-center">
|
|
|
<wd-icon name="location" size="18px" />
|
|
|
@@ -128,10 +205,7 @@ async function handlePay() {
|
|
|
<CollapsePanel :line-height="150">
|
|
|
<view v-for="item in orderInfo?.skuList" :key="item.id" class="mb20rpx w-full flex items-center">
|
|
|
<view class="mr20rpx w120rpx flex-shrink-0">
|
|
|
- <image
|
|
|
- :src="item.pic"
|
|
|
- class="h120rpx w120rpx"
|
|
|
- />
|
|
|
+ <image :src="item.pic" class="h120rpx w120rpx" />
|
|
|
</view>
|
|
|
<view class="flex-1">
|
|
|
<view class="w-full flex items-center justify-between font-semibold">
|
|
|
@@ -170,6 +244,18 @@ async function handlePay() {
|
|
|
¥{{ orderInfo?.transfee }}
|
|
|
</view>
|
|
|
</view>
|
|
|
+ <view class="mb28rpx flex items-center justify-between text-28rpx" @click="openCouponPopup">
|
|
|
+ <view>优惠券</view>
|
|
|
+ <view class="flex items-center">
|
|
|
+ <view v-if="currentCouponDiscount > 0" class="text-[#FF4D3A] font-semibold">
|
|
|
+ -¥{{ currentCouponDiscount }}
|
|
|
+ </view>
|
|
|
+ <view v-else class="text-[#AAAAAA]">
|
|
|
+ {{ availableCoupons.length > 0 ? `${availableCoupons.length}张可用` : '暂无可用' }}
|
|
|
+ </view>
|
|
|
+ <wd-icon name="arrow-right" size="18px" color="#aaa" class="ml10rpx" />
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
<view class="flex items-center justify-between text-28rpx">
|
|
|
<view>积分({{ offsetPoints }})</view>
|
|
|
<view class="text-#FF4D3A font-semibold">
|
|
|
@@ -182,7 +268,7 @@ async function handlePay() {
|
|
|
总计:
|
|
|
</view>
|
|
|
<view class="text-#FF4D3A font-semibold">
|
|
|
- ¥ {{ orderInfo?.totalPrice }}
|
|
|
+ ¥ {{ displayTotalPrice }}
|
|
|
</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
@@ -195,19 +281,94 @@ async function handlePay() {
|
|
|
</view>
|
|
|
</view>
|
|
|
<view class="h250rpx" />
|
|
|
+
|
|
|
+ <!-- 优惠券选择弹窗 -->
|
|
|
+ <Zpopup v-model="couponPopup" :zindex="100" bg="#fff">
|
|
|
+ <view class="ios box-border w-full">
|
|
|
+ <view class="px-32rpx pt-32rpx">
|
|
|
+ <view class="mb-24rpx text-center text-32rpx font-semibold">
|
|
|
+ 优惠券
|
|
|
+ </view>
|
|
|
+ <view class="mb-24rpx flex items-center">
|
|
|
+ <view
|
|
|
+ class="mr-16rpx flex-1 rounded-full py-18rpx text-center text-28rpx"
|
|
|
+ :class="couponTabActive === 0 ? 'bg-[#9ED605] text-white font-semibold' : 'bg-[#F0F0F0] text-[#666]'"
|
|
|
+ @click="couponTabActive = 0"
|
|
|
+ >
|
|
|
+ 可用券({{ availableCoupons.length }})
|
|
|
+ </view>
|
|
|
+ <view
|
|
|
+ class="flex-1 rounded-full py-18rpx text-center text-28rpx"
|
|
|
+ :class="couponTabActive === 1 ? 'bg-[#9ED605] text-white font-semibold' : 'bg-[#F0F0F0] text-[#666]'"
|
|
|
+ @click="couponTabActive = 1"
|
|
|
+ >
|
|
|
+ 不可用券({{ unavailableCoupons.length }})
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="mb-20rpx flex items-center justify-between text-24rpx">
|
|
|
+ <view class="text-[#333]">
|
|
|
+ 优惠券共减
|
|
|
+ </view>
|
|
|
+ <view v-if="draftCoupon" class="text-right text-[#FF4D3A]">
|
|
|
+ {{ getCouponDisplayName(draftCoupon) }},可减-¥{{ draftCoupon.discountMoney }}
|
|
|
+ </view>
|
|
|
+ <view v-else-if="currentCouponDiscount > 0 && currentCouponName" class="text-right text-[#FF4D3A]">
|
|
|
+ {{ currentCouponName }},可减-¥{{ currentCouponDiscount }}
|
|
|
+ </view>
|
|
|
+ <view v-else class="text-[#AAAAAA]">
|
|
|
+ 暂未选择
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <scroll-view scroll-y class="box-border h-560rpx px-32rpx">
|
|
|
+ <view v-for="item in displayCoupons" :key="item.id" class="relative mb-20rpx">
|
|
|
+ <view class="relative" @click="handleSelectCoupon(item)">
|
|
|
+ <CouponItem :itemcoupon="item" :hide-all-btn="true" />
|
|
|
+ <view
|
|
|
+ class="absolute right-32rpx top-50% h-44rpx w-44rpx flex items-center justify-center -translate-y-50%"
|
|
|
+ >
|
|
|
+ <wd-icon v-if="draftCouponId === item.allowanceId" name="check-circle" size="44rpx" color="#FF4D3A" />
|
|
|
+ <view v-else class="h-40rpx w-40rpx border-2rpx border-[#ccc] rounded-full border-solid" />
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view
|
|
|
+ v-if="item.unavailableReason"
|
|
|
+ class="relative z-1 w-full rounded-b-16rpx bg-[#FFF4F3] px20rpx py18rpx text-24rpx -mt16rpx"
|
|
|
+ >
|
|
|
+ <view>
|
|
|
+ 不可用原因
|
|
|
+ </view>
|
|
|
+ <view>
|
|
|
+ {{ item.unavailableReason }}
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view v-if="displayCoupons.length === 0" class="py-80rpx text-center text-28rpx text-[#AAAAAA]">
|
|
|
+ 暂无优惠券
|
|
|
+ </view>
|
|
|
+ </scroll-view>
|
|
|
+ </view>
|
|
|
+ <template #footer>
|
|
|
+ <view class="box-border w-full px24rpx">
|
|
|
+ <wd-button size="large" block type="primary" @click="confirmCoupon">
|
|
|
+ 确定
|
|
|
+ </wd-button>
|
|
|
+ </view>
|
|
|
+ </template>
|
|
|
+ </Zpopup>
|
|
|
<view class="ios footer fixed bottom-0 left-0 box-border w-full rounded-t-16rpx bg-white px24rpx">
|
|
|
<view class="box-border w-full flex items-center justify-between py20rpx">
|
|
|
<view class="flex items-center text-#FF4D3A">
|
|
|
<view class="font-semibold10 flex items-baseline text-36rpx">
|
|
|
<text class="text-24rpx">
|
|
|
¥
|
|
|
- </text> {{ orderInfo?.totalPrice }}
|
|
|
+ </text> {{ displayTotalPrice }}
|
|
|
</view>
|
|
|
<view class="ml20rpx text-22rpx">
|
|
|
- 共减¥{{ offsetPoints / 100 }}
|
|
|
+ 共减¥{{ displayDiscountTotal }}
|
|
|
</view>
|
|
|
</view>
|
|
|
- <view class="w180rpx">
|
|
|
+ <view class="w180-btn w180rpx">
|
|
|
<wd-button size="large" :loading="isPay" loading-color="#9ED605" @click="handlePay">
|
|
|
立即支付
|
|
|
</wd-button>
|
|
|
@@ -218,14 +379,18 @@ async function handlePay() {
|
|
|
</template>
|
|
|
|
|
|
<style scoped lang="scss">
|
|
|
- .footer{
|
|
|
- box-shadow: 0rpx -6rpx 12rpx 2rpx rgba(0,0,0,0.05);
|
|
|
- }
|
|
|
- .page{
|
|
|
- :deep(){
|
|
|
- .wd-button{
|
|
|
+.footer {
|
|
|
+ box-shadow: 0rpx -6rpx 12rpx 2rpx rgba(0, 0, 0, 0.05);
|
|
|
+}
|
|
|
+
|
|
|
+.page {
|
|
|
+ .w180-btn {
|
|
|
+ :deep() {
|
|
|
+ .wd-button {
|
|
|
width: 180rpx !important;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+}
|
|
|
</style>
|