Files
jurong_circle_front_app/pages/home/pay.vue
Sun_sun 1f4c2c75eb 2025-10-23
支付页面
2025-10-23 10:18:06 +08:00

611 lines
15 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.

<template>
<view class="pay-container">
<scroll-view scroll-y="true" style="height: 100%;">
<view class="scroll-container">
<view class="box-bg u-p-b-40">
<view class="address">
<view class="text" @click="handleSelectAddress">
<image style="width: 40rpx;height: 40rpx;" src="/static/icon/Map pin2.png" mode=""></image>
<view class="u-m-l-10">{{selectAddressLabel}}</view>
</view>
<view class="right-icon" @click="handleAddressManage">
<image style="width: 100%;height: 100%;" src="/static/icon/Chevron right Menu.png" mode="">
</image>
</view>
</view>
<view class="count-select u-p-l-10 u-p-r-10" v-for="item in dataInfo.items">
<view class="pre-view">
<u-image :src="getImageUrl(item.image_url)" height="100%" width="100%">
<template v-slot:error>
<view style="font-size: 24rpx;">暂无图片</view>
</template>
</u-image>
</view>
<view class="text">
{{item.product_name}}
<view>融豆{{item.rongdou_price}}</view>
<view>积分{{item.points_price}}</view>
<view>数量X{{item.quantity}}</view>
</view>
</view>
</view>
<view class="box-bg description u-m-t-20">
<view class="item">
<view class="title">
订单编号
</view>
<view class="value">
{{dataInfo.order_no}}
</view>
</view>
<view class="item">
<view class="title">
创建时间
</view>
<view class="value">
{{dataInfo.created_at}}
</view>
</view>
</view>
<view class="box-bg u-m-t-20 discount">
选择优惠券
<u-input class="u-m-t-20" :disabled="discountOptions.length==0"
:placeholder="discountOptions.length==0?'暂无优惠券':'请选择优惠券'" v-model="discountLabel" type="select"
:border="true" @click="handleSelectCoupon" />
<view class="u-m-t-10" style="font-weight: 500;font-size: 20rpx;">选择优惠券后自动换算扣除</view>
</view>
<view class="box-bg pay-method u-m-t-20" v-if="dataInfo.items?.length && dataInfo.items.length!=0">
<view class="title u-m-b-20">
支付方式
</view>
<view class="item" v-if="dataInfo?.items[0].payment_methods.includes('rongdou')"
@click="handleChangeMethod(0)">
<view class="title">
融豆
</view>
<view class="value">
<u-checkbox v-model="rongdouChecked" shape="circle" active-color="#305def"></u-checkbox>
</view>
</view>
<view class="item" v-if="dataInfo?.items[0].payment_methods.includes('points')"
@click="handleChangeMethod(1)">
<view class="title">
积分
</view>
<view class="value">
<u-checkbox v-model="pointsChecked" shape="circle" active-color="#305def"></u-checkbox>
</view>
</view>
<view class="item" v-if="dataInfo?.items[0].payment_methods.includes('mixed')"
@click="handleChangeMethod(2)">
<view class="title">
融豆+积分
</view>
<view class="value">
<u-checkbox v-model="rpChecked" shape="circle" active-color="#305def"></u-checkbox>
</view>
</view>
<view class="item" v-if="dataInfo?.items[0].payment_methods.includes('alipay')"
@click="handleChangeMethod(3)">
<view class="title">
支付宝
</view>
<view class="value">
<u-checkbox v-model="alipayChecked" shape="circle" active-color="#305def"></u-checkbox>
</view>
</view>
<view class="item" v-if="dataInfo?.items[0].payment_methods.includes('wechatpay')"
@click="handleChangeMethod(4)">
<view class="title">
微信
</view>
<view class="value">
<u-checkbox v-model="wechatpayChecked" shape="circle" active-color="#305def"></u-checkbox>
</view>
</view>
</view>
</view>
</scroll-view>
<view class="box-bottom" id="boxBottom">
<view class="text">
实际支付
<image v-if="rpChecked || pointsChecked" src="/static/icon/jifen.png" class="icon" mode=""></image>
<image v-else-if="rongdouChecked || wechatpayChecked || alipayChecked" src="/static/icon/rongdou.png"
class="icon" mode=""></image>
{{allPayNum}}
</view>
<view class="btn">
<u-button @click="handleSubmit">确认支付</u-button>
</view>
</view>
<!-- 地址选择 -->
<u-select v-model="showSelectAddress" :list="addressOptions" @confirm="confirm"></u-select>
<!-- 优惠券选择 -->
<u-select v-model="showDiscount" :list="discountOptions" @confirm="confirmDiscount"></u-select>
<!-- 关闭提示 -->
<u-modal @confirm="handleBack" v-model="showBack" content="是否关闭订单,确认返回后可在个人中心查看我的订单完成支付"
:show-cancel-button="true"></u-modal>
<!-- 消息提示 -->
<u-toast ref="msgRef" />
</view>
</template>
<script setup>
import {
computed,
onMounted,
ref,
getCurrentInstance
} from 'vue';
import {
onLoad,
onBackPress,
onPullDownRefresh
} from '@dcloudio/uni-app'
import {
mallAPI
} from '../../api/mall';
import {
addressAPI
} from '../../api/address'
import {
getImageUrl,
arrayContainsAll
} from '../../util/common.js'
const msgRef = ref()
const showBack = ref(false)
onBackPress((options) => {
if (options.from === 'navigateBack') {
return false;
} else {
showBack.value = true
return true;
}
})
const handleBack = () => {
uni.navigateBack();
}
const instance = getCurrentInstance();
const scrollHeight = ref(0)
const loadHeight = () => {
uni.getSystemInfo({
success(res) {
let screenHeight = res.screenHeight
uni.createSelectorQuery().in(instance.proxy).select("#boxBottom").boundingClientRect((
data) => {
scrollHeight.value = screenHeight - data.height
}).exec()
}
})
}
// 收获地址
const showSelectAddress = ref(false)
const addressOptions = ref([])
const selectAddressId = ref()
const selectAddressLabel = ref()
const handleSelectAddress = () => {
// 地址信息
addressAPI.getList().then(res => {
addressOptions.value = res.data.map(item => {
if (item.is_default) {
selectAddressId.value = item.id
selectAddressLabel.value = item.receiver_name + " | " + item.province_name +
item
.city_name + item.district_name + item.detailed_address
}
return {
value: item.id,
label: item.receiver_name + " | " + item.province_name + item.city_name + item
.district_name + item.detailed_address
}
})
showSelectAddress.value = true
})
}
const confirm = (val) => {
selectAddressId.value = val[0].value
selectAddressLabel.value = val[0].label
}
const handleAddressManage = () => {
uni.navigateTo({
url: '/pages/my/shippingAddress'
})
}
// 优惠券
const showDiscount = ref(false)
const discountLabel = ref('')
const discountOptions = ref([])
const couponRecordId = ref()
const handleSelectCoupon = async () => {
await loadCoupon()
if (discountOptions.value.length == 0) return
showDiscount.value = true
}
const confirmDiscount = (val) => {
couponRecordId.value = val[0].value
discountLabel.value = val[0].label
calculateAllPay()
}
// 支付方式
const rongdouChecked = ref(false)
const pointsChecked = ref(false)
const rpChecked = ref(false)
const alipayChecked = ref(false)
const wechatpayChecked = ref(false)
const allPayNum = ref(null)
const clearChecked = () => {
rongdouChecked.value = false
pointsChecked.value = false
rpChecked.value = false
alipayChecked.value = false
wechatpayChecked.value = false
}
const handleChangeMethod = (val) => {
clearChecked()
if (val == 0) { // 融豆
rongdouChecked.value = true
}
if (val == 1) { // 积分
pointsChecked.value = true
}
if (val == 2) { // 融豆+积分
rpChecked.value = true
}
if (val == 3) { // 支付宝
alipayChecked.value = true
}
if (val == 4) { // 微信
wechatpayChecked.value = true
}
calculateAllPay() // 计算实际支付
}
// 计算实际支付
const calculateAllPay = () => {
if (rongdouChecked.value) { // 融豆
allPayNum.value = dataInfo.value.items[0].rongdou_price * dataInfo.value.items[0].quantity
// 选择优惠券
if (couponRecordId.value) {
let couponInfo = couponList.value.filter(item => item.couponInfo.id == couponRecordId.value)[0]
.couponInfo
handle1to1(couponInfo)
}
} else if (pointsChecked.value) { // 积分
allPayNum.value = dataInfo.value.items[0].points_price * dataInfo.value.items[0].quantity
// 选择优惠券
if (couponRecordId.value) {
let couponInfo = couponList.value.filter(item => item.couponInfo.id == couponRecordId.value)[0]
.couponInfo
handle1to10000(couponInfo)
}
} else if (rpChecked.value) { // 融豆+积分
allPayNum.value = dataInfo.value.items[0].points_price * dataInfo.value.items[0].quantity
// 选择优惠券
if (couponRecordId.value) {
let couponInfo = couponList.value.filter(item => item.couponInfo.id == couponRecordId.value)[0]
.couponInfo
handle1to10000(couponInfo)
}
} else if (alipayChecked.value) { // 支付宝
allPayNum.value = dataInfo.value.items[0].price * dataInfo.value.items[0].quantity
// 选择优惠券
if (couponRecordId.value) {
let couponInfo = couponList.value.filter(item => item.couponInfo.id == couponRecordId.value)[0]
.couponInfo
handle1to1(couponInfo)
}
} else if (wechatpayChecked.value) { // 微信
allPayNum.value = dataInfo.value.items[0].price * dataInfo.value.items[0].quantity
// 选择优惠券
if (couponRecordId.value) {
let couponInfo = couponList.value.filter(item => item.couponInfo.id == couponRecordId.value)[0]
.couponInfo
handle1to1(couponInfo)
}
}
if (allPayNum.value < 0) allPayNum.value = 0
}
const handle1to1 = (couponInfo) => {
if (couponInfo.type == 'discount_for_a_amount') { // 满减
if (allPayNum.value > couponInfo.for_a_amount) {
allPayNum.value -= couponInfo.discount
}
} else if (couponInfo.type == 'deduction') { // 抵扣
allPayNum.value -= couponInfo.price
} else if (couponInfo.type == 'discount') { // 折扣
allPayNum.value *= couponInfo.precent * 0.01
}
}
const handle1to10000 = (couponInfo) => {
if (couponInfo.type == 'discount_for_a_amount') { // 满减
if (allPayNum.value > (couponInfo.for_a_amount * 10000)) {
allPayNum.value -= couponInfo.discount * 10000
}
} else if (couponInfo.type == 'deduction') { // 抵扣
allPayNum.value -= couponInfo.price * 10000
} else if (couponInfo.type == 'discount') { // 折扣
allPayNum.value = allPayNum.value * couponInfo.precent * 0.01
}
}
const isPay = ref(false)
const handleSubmit = () => {
if (isPay.value) {
msgRef.value.show({
title: '请不要重复支付',
type: 'error'
})
return
}
if (!selectAddressId.value) {
msgRef.value.show({
title: '请选择收货地址',
type: 'error'
})
return
}
const orderData = {
orderId: preOrderId.value,
addressId: selectAddressId.value,
pointsAmount: allPayNum.value,
beansAmount: allPayNum.value,
couponRecordId: couponRecordId.value
}
if (rongdouChecked.value) {
orderData.paymentMethod = 'beans'
handlePay(orderData)
return
}
if (pointsChecked.value) {
orderData.paymentMethod = 'points'
handlePay(orderData)
return
}
if (rpChecked.value) {
orderData.paymentMethod = 'mixed'
handlePay(orderData)
return
}
if (alipayChecked.value) {
msgRef.value.show({
title: '暂不支持支付宝支付',
type: 'primary'
})
return
}
if (wechatpayChecked.value) {
msgRef.value.show({
title: '暂不支持微信支付',
type: 'primary'
})
return
}
msgRef.value.show({
title: '请选择支付方式',
type: 'warning'
})
}
const handlePay = (orderData) => {
mallAPI.payment(orderData).then(res => {
if (res.success) {
msgRef.value.show({
title: '支付成功',
type: 'success'
})
isPay.value = true
setTimeout(() => {
uni.navigateBack()
}, 1000)
}
})
}
const dataInfo = ref({})
const couponList = ref({})
const loadData = async () => {
// 订单信息
await mallAPI.getOrder(preOrderId.value).then(res => {
dataInfo.value = res.data
dataInfo.value.items.forEach(item => {
if (item.payment_methods.includes('rongdou') && item.payment_methods.includes(
'points')) item.payment_methods.push('mixed')
})
})
uni.stopPullDownRefresh()
}
const loadCoupon = () => {
// 折扣信息
mallAPI.getCouponList(userId.value).then(res => {
couponList.value = res.coupon
// 排除已经使用的优惠券 和 排除商品不可使用的优惠券
let pIds = dataInfo.value.items.map(item => {
return item.product_id
})
couponList.value = couponList.value.filter(item => {
if (item.use_time == null && arrayContainsAll(item.couponInfo.products_id, pIds))
return true
return false
})
discountOptions.value = couponList.value.map(item => {
if (item.couponInfo.type === 'discount_for_a_amount') {
return {
value: item.coupon_id,
label: "满减券:满" + item.couponInfo.for_a_amount + "元减" + item.couponInfo
.discount + "元"
}
} else if (item.couponInfo.type === 'deduction') {
return {
value: item.coupon_id,
label: "抵扣券:抵扣" + item.couponInfo.price + "元"
}
} else if (item.couponInfo.type === 'discount') {
return {
value: item.coupon_id,
label: "折扣券:折扣" + item.couponInfo.precent + "%"
}
}
})
})
}
const preOrderId = ref()
const userId = ref()
// 刷新
onPullDownRefresh(async () => {
console.log(111);
loadData()
})
onLoad((val) => {
preOrderId.value = val.preOrderId
})
onMounted(() => {
loadHeight()
userId.value = uni.getStorageSync("user").id
loadData()
loadCoupon()
})
</script>
<style lang="scss" scoped>
.pay-container {
width: 100%;
height: 100%;
background: #E4ECFF;
.scroll-container {
padding-bottom: 200rpx;
.box-bg {
background: #F5F8FF;
}
.address {
display: flex;
align-items: center;
padding: 20rpx 10rpx;
justify-content: space-between;
.text {
display: flex;
align-items: center;
// border: 1px solid #000;
flex: 1;
}
.right-icon {
width: 40rpx;
height: 40rpx;
}
}
.count-select {
display: flex;
margin-top: 10rpx;
.pre-view {
width: 160rpx;
height: 160rpx;
}
.text {
margin-left: 20rpx;
display: flex;
flex-direction: column;
justify-content: center;
}
.icon {
height: 30rpx;
width: 30rpx;
}
}
.description {
padding: 30rpx 40rpx;
.item {
display: flex;
justify-content: space-between;
margin-bottom: 30rpx;
}
}
.discount {
padding: 30rpx 40rpx;
}
.pay-method {
padding: 30rpx 40rpx;
.title {
font-weight: 400;
font-style: Regular;
font-size: 28rpx;
leading-trim: NONE;
line-height: 48rpx;
}
.item {
display: flex;
justify-content: space-between;
margin-bottom: 30rpx;
}
}
}
.box-bottom {
width: 100%;
padding: 20rpx 40rpx;
display: flex;
justify-content: space-between;
align-items: center;
position: absolute;
bottom: 0;
background: #F5F8FF;
.text {
display: flex;
align-items: center;
.icon {
height: 30rpx;
width: 30rpx;
}
}
.btn {}
}
}
</style>