610 lines
15 KiB
Vue
Executable File
610 lines
15 KiB
Vue
Executable File
<template>
|
||
<view>
|
||
<view v-if="!isLoading" class="container" :style="appThemeStyle">
|
||
<!-- 订单信息 -->
|
||
<view class="order-info">
|
||
<!-- 支付剩余时间 -->
|
||
<view class="order-countdown">
|
||
<text class="m-r-6">剩余时间</text>
|
||
<count-down :date="expirationTime" separator="zh" theme="text" />
|
||
</view>
|
||
<!-- 付款金额 -->
|
||
<view class="order-amount">
|
||
<text class="unit">¥</text>
|
||
<text class="amount">{{ totalPrice }}</text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 支付方式 -->
|
||
<view class="payment-method">
|
||
<view v-for="(item, index) in methods" :key="index" class="pay-item dis-flex flex-x-between"
|
||
@click="handleSelectPayType(index)">
|
||
<view class="item-left dis-flex flex-y-center">
|
||
<view class="item-left_icon" :class="[item.method]">
|
||
<text class="iconfont" :class="[item.icon]"></text>
|
||
</view>
|
||
<view class="item-left_text">
|
||
<text>{{ item.method }}</text>
|
||
</view>
|
||
<view v-if="item.method === '余额支付'" class="user-balance">
|
||
<text v-if="personal">(可用¥{{ personal.balance }}元)</text>
|
||
</view>
|
||
</view>
|
||
<view class="item-right col-m" v-if="curPaymentItem && curPaymentItem.method == item.method">
|
||
<text class="iconfont icon-check"></text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 确认按钮 -->
|
||
<view class="footer-fixed">
|
||
<view class="btn-wrapper">
|
||
<view class="btn-item btn-item-main" :class="{ disabled }" @click="handleSubmit()">确认支付</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 支付确认弹窗 -->
|
||
<!-- #ifdef H5 -->
|
||
<u-modal v-if="tempUnifyData" v-model="showConfirmModal" title="支付确认" show-cancel-button confirm-text="已完成支付"
|
||
:confirm-color="appTheme.mainBg" negative-top="100" :asyncClose="true"
|
||
@confirm="onTradeQuery(tempUnifyData.outTradeNo, tempUnifyData.method)">
|
||
<view class="modal-content">
|
||
<text>请在{{ PayMethodClientNameEnum[tempUnifyData.method] }}内完成支付,如果您已经支付成功,请点击“已完成支付”按钮</text>
|
||
</view>
|
||
</u-modal>
|
||
<!-- #endif -->
|
||
</view>
|
||
<empty v-else :isLoading="isLoading" tips="订单不存在" />
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
import storage from '@/utils/storage'
|
||
import {
|
||
inArray,
|
||
urlEncode
|
||
} from '@/utils/util'
|
||
import {
|
||
Alipay,
|
||
Wechat
|
||
} from '@/core/payment'
|
||
import CountDown from '@/components/countdown'
|
||
import {
|
||
PayMethodEnum
|
||
} from '@/common/enum/payment'
|
||
import {
|
||
PayStatusEnum
|
||
} from '@/common/enum/order'
|
||
import * as OrderApi from '@/api/order.js'
|
||
import * as PaymentApi from '@/api/payment.js'
|
||
import {
|
||
dateFormat
|
||
} from '@/utils/util.js'
|
||
import Empty from '@/components/empty'
|
||
// import * as CashierApi from '@/api/cashier'
|
||
import * as UserApi from '@/api/user.js'
|
||
|
||
// 支付方式对应的图标
|
||
const PayMethodIconEnum = {
|
||
[PayMethodEnum.WECHAT.value]: 'icon-wechat-pay',
|
||
[PayMethodEnum.ALIPAY.value]: 'icon-alipay',
|
||
[PayMethodEnum.BALANCE.value]: 'icon-balance-pay'
|
||
}
|
||
|
||
// 支付方式的终端名称
|
||
const PayMethodClientNameEnum = {
|
||
[PayMethodEnum.WECHAT.value]: '微信',
|
||
[PayMethodEnum.ALIPAY.value]: '支付宝'
|
||
}
|
||
|
||
export default {
|
||
components: {
|
||
CountDown,
|
||
Empty
|
||
},
|
||
data() {
|
||
return {
|
||
orderIds: [],
|
||
// 加载中
|
||
isLoading: true,
|
||
// 确认按钮禁用
|
||
disabled: false,
|
||
// 枚举类
|
||
PayMethodEnum,
|
||
PayMethodIconEnum,
|
||
PayMethodClientNameEnum,
|
||
// 当前选中的支付方式
|
||
curPaymentItem: {
|
||
method: '余额支付'
|
||
},
|
||
// 当前订单ID
|
||
orderId: null,
|
||
// 当前结算订单信息
|
||
order: null,
|
||
deliveryTime: null,
|
||
// 订单过期时间
|
||
expirationTime: new Date(),
|
||
// 个人信息
|
||
personal: {
|
||
balance: '0.00'
|
||
},
|
||
totalPrice: 0,
|
||
// 当前客户端的支付方式列表(后端根据platform判断)
|
||
methods: [
|
||
{
|
||
id: 1,
|
||
method: '余额支付',
|
||
icon: 'icon-balance-pay'
|
||
},
|
||
// {
|
||
// id: 2,
|
||
// method: '支付宝',
|
||
// icon: 'icon-alipay'
|
||
// }
|
||
],
|
||
// 支付确认弹窗
|
||
showConfirmModal: false,
|
||
// #ifdef H5
|
||
// 当前微信支付信息 (临时数据, 仅用于H5端)
|
||
tempUnifyData: {
|
||
outTradeNo: '',
|
||
method: ''
|
||
},
|
||
// #endif
|
||
}
|
||
},
|
||
|
||
/**
|
||
* 生命周期函数--监听页面加载
|
||
*/
|
||
onLoad(option) {
|
||
this.orderIds = option.orderIds.split(',')
|
||
// 记录订单ID
|
||
// this.orderId = Number(orderId)
|
||
// this.deliveryTime = deliveryTime
|
||
// // 获取收银台信息
|
||
this.getCashierInfo()
|
||
},
|
||
|
||
onShow() {},
|
||
|
||
methods: {
|
||
|
||
// 获取收银台信息
|
||
getCashierInfo() {
|
||
const app = this
|
||
const { orderIds } = this
|
||
app.isLoading = true
|
||
console.log(orderIds);
|
||
// 加载订单
|
||
console.log("typeof(orderIds): ",typeof(orderIds));
|
||
const baoCanExpirationTime = uni.getStorageSync('baoCanExpirationTime')
|
||
console.log(baoCanExpirationTime);
|
||
OrderApi.listByIds(orderIds)
|
||
.then(res => {
|
||
console.log("res: ",res);
|
||
res.data.map(d => {
|
||
console.log("app.totalPrice: ",app.totalPrice);
|
||
console.log("d: ",d.payPrice);
|
||
app.totalPrice = app.totalPrice + d.payPrice
|
||
})
|
||
app.isLoading = false
|
||
// 处理订单过期时间(*1小时)
|
||
var expirationTime = new Date().getTime() + 60 * 60 * 1000 * 0.20
|
||
app.expirationTime = dateFormat('YYYY-mm-dd HH:MM:SS', new Date(expirationTime))
|
||
|
||
})
|
||
.catch(e => {
|
||
console.log("e: ", e);
|
||
})
|
||
// 查询余额
|
||
const agentUser = uni.getStorageSync('agentUser')
|
||
if(agentUser){
|
||
app.getAgentUser()
|
||
}else{
|
||
UserApi.getUser().then(res => app.personal = res.data)
|
||
}
|
||
|
||
},
|
||
|
||
getAgentUser(){
|
||
const app = this
|
||
const agentUser = uni.getStorageSync('agentUser')
|
||
if(agentUser){
|
||
UserApi.getAgentUser(agentUser.userId).then(res => {
|
||
app.personal = res.data
|
||
})
|
||
}
|
||
},
|
||
|
||
// 设置默认的支付方式
|
||
setDefaultPayType() {
|
||
const app = this
|
||
if (app.disabled) return
|
||
const defaultIndex = app.methods.findIndex(item => item.is_default == true)
|
||
defaultIndex > -1 && app.handleSelectPayType(defaultIndex)
|
||
},
|
||
|
||
// 判断当前订单是否为已支付
|
||
checkOrderPayStatus() {
|
||
const app = this
|
||
if (app.order.pay_status == PayStatusEnum.SUCCESS.value) {
|
||
app.$toast('恭喜您,订单已付款成功')
|
||
app.onSuccessNav()
|
||
}
|
||
},
|
||
|
||
// 选择支付方式
|
||
handleSelectPayType(index) {
|
||
this.curPaymentItem = this.methods[index]
|
||
console.log("this.curPaymentItem: ", this.curPaymentItem);
|
||
},
|
||
|
||
// 判断当前页面来源于浏览器返回
|
||
// #ifdef H5
|
||
performance() {
|
||
const app = this
|
||
// 判断订单状态, 异步回调会将订单状态变为已支付, 那么就不需要让用户手动查单了
|
||
if (app.order.pay_status == PayStatusEnum.PENDING.value) {
|
||
app.alipayPerformance()
|
||
app.wechatPerformance()
|
||
}
|
||
},
|
||
|
||
// H5端支付宝支付完成跳转回当前页面时触发
|
||
alipayPerformance() {
|
||
const app = this
|
||
app.tempUnifyData = Alipay.performance()
|
||
if (app.tempUnifyData) {
|
||
app.onTradeQuery(app.tempUnifyData.outTradeNo, app.tempUnifyData.method)
|
||
}
|
||
},
|
||
|
||
// H5端微信支付完成或返回时触发
|
||
wechatPerformance() {
|
||
const app = this
|
||
app.tempUnifyData = Wechat.performance(app.orderId)
|
||
if (app.tempUnifyData) {
|
||
app.showConfirmModal = true
|
||
}
|
||
},
|
||
// #endif
|
||
|
||
// 确认支付
|
||
handleSubmit() {
|
||
const app = this
|
||
const {
|
||
orderIds
|
||
} = this
|
||
// 判断是否选择了支付方式
|
||
if (!app.curPaymentItem) {
|
||
app.$toast('您还没有选择支付方式')
|
||
return
|
||
}
|
||
// 按钮禁用
|
||
if (app.disabled) return
|
||
// app.disabled = true
|
||
// .js
|
||
console.log("orderIds: ",orderIds);
|
||
console.log("curPaymentItem: ",app.curPaymentItem);
|
||
if(app.curPaymentItem.method == '余额支付'){
|
||
console.log("'ssss: ",'ssss');
|
||
PaymentApi.balanceBatch(orderIds).then(result => app.onSubmitCallback(result)).catch(err => app.$error(err.message))
|
||
}
|
||
// if(app.curPaymentItem.method == '支付宝'){
|
||
// PaymentApi.alipay(orderIds).then(result => app.onSubmitCallback(result)).catch(err => app.$error(err.message))
|
||
// }
|
||
|
||
|
||
|
||
// // 提交到后端API
|
||
// CashierApi.orderPay(app.orderId, {
|
||
// method: app.curPaymentItem.method,
|
||
// client: app.platform,
|
||
// extra: app.getExtraAsUnify(app.curPaymentItem.method)
|
||
// })
|
||
// .then(result => app.onSubmitCallback(result))
|
||
// .finally(err => setTimeout(() => app.disabled = false, 10))
|
||
},
|
||
|
||
// 获取第三方支付的扩展参数
|
||
getExtraAsUnify(method) {
|
||
if (method === PayMethodEnum.ALIPAY.value) {
|
||
return Alipay.extraAsUnify()
|
||
}
|
||
if (method === PayMethodEnum.WECHAT.value) {
|
||
return Wechat.extraAsUnify()
|
||
}
|
||
return {}
|
||
},
|
||
|
||
// 订单提交成功后回调
|
||
onSubmitCallback(result) {
|
||
const app = this
|
||
const method = app.curPaymentItem.method
|
||
const tradeNO = result.data
|
||
console.log("result订单提交成功后回调: ", tradeNO);
|
||
// 余额支付
|
||
if (method === '余额支付') {
|
||
app.onShowSuccess(result)
|
||
}
|
||
// 发起支付宝支付
|
||
if (method === '支付宝') {
|
||
my.tradePay({
|
||
// 调用统一收单交易创建接口(alipay.trade.create),获得返回字段支付宝交易号trade_no
|
||
tradeNO: tradeNO,
|
||
success: (res) => {
|
||
console.log("res11: ", res);
|
||
if (res.resultCode == "9000") {
|
||
payQuery(app.orderId).then(result => {
|
||
if(result.code == 0) {
|
||
app.$success('支付成功')
|
||
app.$navTo('pages/order/detail?orderId='+app.orderId)
|
||
}
|
||
})
|
||
|
||
// setPayStatus({
|
||
// orderId: app.orderId,
|
||
// payStatus: 20,
|
||
// payMethod: 20
|
||
// }).then(res => {
|
||
// console.log("updateOrder: ",res);
|
||
// app.$navTo('pages/order/index')
|
||
// })
|
||
}
|
||
if (res.resultCode == "6001") {
|
||
app.$navTo('pages/order/index')
|
||
}
|
||
// my.alert({
|
||
// content: JSON.stringify(res),
|
||
// });
|
||
},
|
||
fail: (res) => {
|
||
my.alert({
|
||
content: JSON.stringify(res),
|
||
});
|
||
}
|
||
});
|
||
|
||
// Alipay.payment(paymentData)
|
||
// .then(res => app.onPaySuccess(res))
|
||
// .catch(err => app.onPayFail(err))
|
||
}
|
||
// 发起微信支付
|
||
if (method === PayMethodEnum.WECHAT.value) {
|
||
console.log('paymentData', paymentData)
|
||
Wechat.payment({
|
||
orderKey: app.orderId,
|
||
...paymentData
|
||
})
|
||
.then(res => app.onPaySuccess(res))
|
||
.catch(err => app.onPayFail(err))
|
||
}
|
||
},
|
||
|
||
// 订单支付成功的回调方法
|
||
// 这里只是前端支付api返回结果success,实际订单是否支付成功 以后端的查单和异步通知为准
|
||
onPaySuccess({
|
||
res,
|
||
option: {
|
||
isRequireQuery,
|
||
outTradeNo,
|
||
method
|
||
}
|
||
}) {
|
||
const app = this
|
||
// 判断是否需要主动查单
|
||
// isRequireQuery为true代表需要主动查单
|
||
if (isRequireQuery) {
|
||
app.onTradeQuery(outTradeNo, method)
|
||
return true
|
||
}
|
||
this.onShowSuccess(res)
|
||
},
|
||
|
||
// 显示支付成功信息并页面跳转
|
||
onShowSuccess({
|
||
message
|
||
}) {
|
||
this.$toast(message || '订单支付成功')
|
||
this.onSuccessNav()
|
||
},
|
||
|
||
// 订单支付失败
|
||
onPayFail(err) {
|
||
console.log('onPayFail', err)
|
||
const errMsg = err.message || '订单未支付'
|
||
this.$error(errMsg)
|
||
},
|
||
|
||
// 已完成支付按钮事件: 请求后端查单
|
||
onTradeQuery(outTradeNo, method) {
|
||
const app = this
|
||
// 交易查询
|
||
// 查询第三方支付订单是否付款成功
|
||
CashierApi.tradeQuery({
|
||
outTradeNo,
|
||
method,
|
||
client: app.platform
|
||
})
|
||
.then(result => result.data.isPay ? app.onShowSuccess(result) : app.onPayFail(result))
|
||
.finally(() => app.showConfirmModal = false)
|
||
},
|
||
|
||
// 支付成功后的跳转
|
||
onSuccessNav() {
|
||
// 相应全局事件订阅: 刷新上级页面数据
|
||
uni.$emit('syncRefreshOrder', true)
|
||
// 获取上级页面
|
||
const { orderId,deliveryTime } = this
|
||
const pages = getCurrentPages()
|
||
const lastPage = pages.length < 2 ? null : pages[pages.length - 2]
|
||
const backRoutes = [
|
||
'pages/order/index',
|
||
'pages/order/detail'
|
||
]
|
||
// 取消临时报餐状态
|
||
uni.removeStorageSync('baoCanExpirationTime')
|
||
setTimeout(() => {
|
||
if (lastPage && inArray(lastPage.route, backRoutes)) {
|
||
uni.navigateBack()
|
||
} else {
|
||
this.$navTo('pages/index/index', {deliveryTime}, 'redirectTo')
|
||
}
|
||
}, 1200)
|
||
},
|
||
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style>
|
||
page {
|
||
background: #F4F4F4;
|
||
}
|
||
</style>
|
||
<style lang="scss" scoped>
|
||
.container {
|
||
background-color: #F4F4F4;
|
||
}
|
||
|
||
// 订单信息
|
||
.order-info {
|
||
padding: 80rpx 0;
|
||
text-align: center;
|
||
|
||
.order-countdown {
|
||
display: flex;
|
||
justify-content: center;
|
||
font-size: 26rpx;
|
||
color: #666666;
|
||
margin-bottom: 20rpx;
|
||
}
|
||
|
||
.order-amount {
|
||
margin: 0 auto;
|
||
max-width: 50%;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
color: #fb0f07;
|
||
|
||
.unit {
|
||
font-size: 30rpx;
|
||
margin-bottom: -18rpx;
|
||
}
|
||
|
||
.amount {
|
||
font-size: 56rpx;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 支付方式
|
||
.payment-method {
|
||
width: 94%;
|
||
margin: 0 auto 20rpx auto;
|
||
padding: 0 40rpx;
|
||
background-color: #ffffff;
|
||
border-radius: 20rpx;
|
||
|
||
.pay-item {
|
||
padding: 26rpx 0;
|
||
font-size: 28rpx;
|
||
border-bottom: 1rpx solid rgb(248, 248, 248);
|
||
|
||
&:last-child {
|
||
border-bottom: none;
|
||
}
|
||
|
||
.item-left_icon {
|
||
margin-right: 20rpx;
|
||
font-size: 44rpx;
|
||
|
||
&.wechat {
|
||
color: #00c800;
|
||
}
|
||
|
||
&.alipay {
|
||
color: #009fe8;
|
||
}
|
||
|
||
&.balance {
|
||
color: #ff9700;
|
||
}
|
||
}
|
||
|
||
.item-left_text {
|
||
font-size: 28rpx;
|
||
}
|
||
|
||
.item-right {
|
||
font-size: 32rpx;
|
||
}
|
||
|
||
.user-balance {
|
||
margin-left: 20rpx;
|
||
font-size: 26rpx;
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
|
||
// 支付确认弹窗
|
||
.modal-content {
|
||
padding: 40rpx 48rpx;
|
||
font-size: 30rpx;
|
||
line-height: 50rpx;
|
||
text-align: left;
|
||
color: #606266;
|
||
// height: 620rpx;
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
|
||
// 底部操作栏
|
||
.footer-fixed {
|
||
position: fixed;
|
||
bottom: var(--window-bottom);
|
||
left: 0;
|
||
right: 0;
|
||
z-index: 11;
|
||
box-shadow: 0 -4rpx 40rpx 0 rgba(151, 151, 151, 0.24);
|
||
background: #fff;
|
||
|
||
// 设置ios刘海屏底部横线安全区域
|
||
padding-bottom: constant(safe-area-inset-bottom);
|
||
padding-bottom: env(safe-area-inset-bottom);
|
||
|
||
.btn-wrapper {
|
||
height: 120rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
padding: 0 40rpx;
|
||
}
|
||
|
||
.btn-item {
|
||
flex: 1;
|
||
font-size: 28rpx;
|
||
height: 80rpx;
|
||
color: #fff;
|
||
border-radius: 50rpx;
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
}
|
||
|
||
.btn-item-main {
|
||
background: linear-gradient(to right, $main-bg, $main-bg2);
|
||
color: $main-text;
|
||
|
||
// 禁用按钮
|
||
&.disabled {
|
||
opacity: 0.6;
|
||
}
|
||
}
|
||
|
||
}
|
||
</style>
|