Files
aishangjia-uniapp/pages/checkout/cashier/index.vue
2023-08-04 13:14:48 +08:00

610 lines
15 KiB
Vue
Executable File
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>
<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>