462 lines
17 KiB
Vue
462 lines
17 KiB
Vue
<template>
|
||
<div class="wechat-payment-container" style="background: #fff;padding: 1rem;">
|
||
<div v-if="!isWx">请在微信浏览器中打开此页面进行支付</div>
|
||
<div v-if="payStatus!=0&&isWx" >
|
||
<div v-if="payStatus==1" class="text-center" >
|
||
<h1 style="font-size: 24px; color: #303133; margin-bottom: 10px;">支付中</h1>
|
||
<p style="color: #606266; margin-bottom: 30px;">{{ errorMessage }}</p>
|
||
</div>
|
||
|
||
<!-- 失败状态提示 -->
|
||
<div v-if="payStatus==3" class="text-center" >
|
||
<h1 style="font-size: 24px; color: #303133; margin-bottom: 10px;">支付失败</h1>
|
||
<p style="color: #606266; margin-bottom: 30px;">{{ errorMessage }}</p>
|
||
</div>
|
||
|
||
<div v-if="payStatus==2" class="text-center">
|
||
<i class="el-icon-circle-check success-icon"></i>
|
||
<h1 style="font-size: 24px; color: #303133; margin-bottom: 10px;">支付成功</h1>
|
||
<p style="color: #606266; margin-bottom: 30px;">感谢您的支持,我们将竭诚为您服务</p>
|
||
</div>
|
||
|
||
<!-- 操作按钮 -->
|
||
<div class="action-buttons">
|
||
<el-button type="primary" @click="goToSapp">
|
||
确认
|
||
</el-button>
|
||
</div>
|
||
|
||
<!-- 辅助信息 -->
|
||
<div style="text-align: center; color: #909399; margin-top: 40px; font-size: 14px;">
|
||
<p>如有问题,请联系客服</p>
|
||
<p style="margin-top: 5px;">客服电话: 400-025-7080</p>
|
||
</div>
|
||
</div>
|
||
|
||
<div v-if="isWx">
|
||
<el-form id="payPage" v-if="settleBillItem!=null" ref="form" :model="form" size="mini" label-width="80px">
|
||
<el-row :gutter="0" style="display: flex;flex-wrap: wrap;">
|
||
<el-col :span="24">
|
||
<div style="text-align:center">
|
||
<div style="display: inline-flex;" >
|
||
<span><img :src="shortLogo" style="width: 30px;height: 30px;margin-top: 0px;" /></span>
|
||
<span style="font-size: 20px;font-weight: bold;color: black;">探路供应链(江苏)有限公司</span>
|
||
</div>
|
||
<!-- <div v-if="!isWx" style="width:150px;margin: 0 auto;">
|
||
<img :src="wxPayQrImageUrl" width="100%" draggable="false"/>
|
||
</div>
|
||
<div v-if="!isWx" class="pay-title"><span style="color: black;font-size: 20px;">¥{{ settleBillItem.thisPayMoney }} </span></div>
|
||
<div v-if="!isWx" style="text-align: center;" >
|
||
<div>请使用微信[<span style="color:black;font-weight: bold;">24小时</span>]内完成支付</div>
|
||
</div> -->
|
||
</div>
|
||
</el-col>
|
||
<el-col :span="24">
|
||
<el-row :gutter="0" style="display: flex;flex-wrap: wrap;margin-top:10px">
|
||
<el-col :span="24">
|
||
<span class="item-label">账单编号:</span>
|
||
<span class="item-value" style="font-size:14px;font-weight: bold;">{{ settleBillItem.settleBillNo }}</span>
|
||
</el-col>
|
||
|
||
<!-- <el-col :span="12">
|
||
<span class="item-label">账单名称:</span><span class="item-value">{{ settleBillItem.settleBillName }}</span>
|
||
</el-col> -->
|
||
<el-col :span="24">
|
||
<span class="item-label">账单日期:</span><span class="item-value">{{ settleBillItem.createTime }}</span>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<span class="item-label">总票数:</span><span class="item-value">{{ settleBillItem.sendPieceSum }}</span>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<span class="item-label">总件数:</span><span class="item-value">{{ settleBillItem.pieceNumber }}</span>
|
||
</el-col>
|
||
|
||
<el-col :span="12">
|
||
<span class="item-label">结算重量:</span><span class="item-value">{{ settleBillItem.feeWeight }}KG</span>
|
||
</el-col>
|
||
|
||
<el-col :span="24">
|
||
<span class="item-label">应付金额:</span><span class="item-value">¥{{ settleBillItem.recMoney }}</span>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<span class="item-label">开票状态:</span>
|
||
<span class="item-value">
|
||
<span type="info" v-if="settleBillItem.openBillStatus==0">未开票</span>
|
||
<span type="info" v-if="settleBillItem.openBillStatus==1">已开票</span>
|
||
<span type="info" v-if="settleBillItem.openBillStatus==2">部分开票</span>
|
||
<span type="info" v-if="settleBillItem.openBillStatus==3">不开票</span>
|
||
<span type="info" v-if="settleBillItem.openBillStatus==4">已完成</span>
|
||
</span>
|
||
</el-col>
|
||
|
||
<!-- <el-col :span="12">
|
||
</el-col> -->
|
||
<el-col :span="12">
|
||
<span class="item-label">已付金额:</span><span class="item-value">¥{{ settleBillItem.recedMoney }}</span>
|
||
</el-col>
|
||
</el-row>
|
||
</el-col>
|
||
<el-col :span="24" v-for="item in settleBillItem.subBillList" :key="item.id">
|
||
<el-row :gutter="0" style="display: flex;flex-wrap: wrap;margin-top:10px">
|
||
<el-col :span="12">
|
||
<span class="item-label">运单号:</span><span class="item-value" style="font-size:14px;font-weight: bold;">{{ item.billCode }}</span>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<span class="item-label">寄件日期:</span><span class="item-value">{{ parseTime(item.waybillDetail.sendDate, '{y}-{m}-{d}') }}</span>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<span class="item-label">发件人:</span><span class="item-value">{{ item.waybillDetail.sendName }}</span>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<span class="item-label">快件类型:</span><span class="item-value">{{ item.waybillDetail.sendSiteName }}--{{ item.waybillDetail.dispatchUnderlingSiteName }}</span>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<span class="item-label">总运费:</span><span class="item-value">{{ item.waybillDetail.freight }} CNY</span>
|
||
</el-col>
|
||
|
||
<el-col :span="12" v-for="feeItem in item.feeitemList" :key="feeItem.id">
|
||
<span class="item-label">{{ feeItem.feeName }}:</span><span class="item-value">{{ feeItem.billFee }}{{feeItem.currency}}</span>
|
||
</el-col>
|
||
|
||
<el-col :span="12">
|
||
<span class="item-label">件数:</span><span class="item-value">{{ item.waybillDetail.parcelQty }}</span>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<span class="item-label">实际重量:</span><span class="item-value">{{ item.waybillDetail.billWeight }}KG</span>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<span class="item-label">产品类型:</span><span class="item-value">{{ item.waybillDetail.productTypeName }}</span>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<span class="item-label">寄件公司:</span><span class="item-value">{{ item.waybillDetail.sendCompany }}</span>
|
||
</el-col>
|
||
<el-col :span="24">
|
||
<span class="item-label">备注:</span><span class="item-value">{{ item.waybillDetail.remark }} {{ item.waybillDetail.feeRemark }}</span>
|
||
</el-col>
|
||
</el-row>
|
||
</el-col>
|
||
</el-row>
|
||
</el-form>
|
||
<div v-if="settleBillItem!=null&&payStatus==0" style="margin-bottom: 20px;">
|
||
<el-button type="primary" style="width: 100%;" @click="handleWeixinPay" >确认付款</el-button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
</template>
|
||
|
||
<script>
|
||
import axios from 'axios'
|
||
import shortLogoImg from '@/assets/logo/short_logo.png'
|
||
import { parseTime } from "@/utils/custom";
|
||
|
||
export default {
|
||
name: 'OnlinePay',
|
||
components: {},
|
||
data() {
|
||
return {
|
||
shortLogo: shortLogoImg,
|
||
settleBillItem:null,
|
||
billNo:null,
|
||
wxPayQrImageUrl:null,
|
||
|
||
isWx:false,
|
||
payStatus:null,
|
||
|
||
loadingVisible: false,
|
||
paymentSuccess: false,
|
||
errorMessage: '',
|
||
wechatPaymentParams: null,
|
||
// 表单参数
|
||
form: {},
|
||
|
||
};
|
||
},
|
||
created() {
|
||
this.payStatus=0;
|
||
|
||
const ua = window.navigator.userAgent.toLowerCase();
|
||
if (ua.match(/MicroMessenger/i)) {
|
||
this.isWx=true;
|
||
}
|
||
|
||
let code=this.$route.query.code;
|
||
let state=this.$route.query.state;
|
||
|
||
if (code) {
|
||
this.billNo=state;
|
||
this.requestPayment(code,state);
|
||
this.initPayOrder();
|
||
|
||
}else{
|
||
this.reset();
|
||
this.initPayOrder();
|
||
}
|
||
},
|
||
methods: {
|
||
// 表单重置
|
||
reset() {
|
||
this.form = {
|
||
payScope:null,
|
||
params:{
|
||
billCodeStr:null,
|
||
},
|
||
payRelList:[],
|
||
|
||
id: null,
|
||
payId: null,
|
||
payType: null,
|
||
recType: null,
|
||
payMan: null,
|
||
payManCode: null,
|
||
settleBillNo: null,
|
||
blAudit: null,
|
||
auditDate: null,
|
||
auditManCode: null,
|
||
auditSiteCode: null,
|
||
customerCode: null,
|
||
customerName: null,
|
||
payMoney: null,
|
||
payStatus: null,
|
||
payStatusDesc: null,
|
||
breakType: null,
|
||
breakReason: null,
|
||
breakEmpCode: null,
|
||
recManCode: null,
|
||
settleType: null,
|
||
refundDate: null,
|
||
refundManCode: null,
|
||
refundSeq: null,
|
||
refundMode: null,
|
||
refundMoney: null,
|
||
refundReason: null,
|
||
refundRemark: null,
|
||
refundOpManCode: null,
|
||
refundRegisterSiteCode: null,
|
||
refundRegisterManCode: null,
|
||
satisfyMoney: null,
|
||
satisfyReason: null,
|
||
allowanceMoney: null,
|
||
allowanceReason: null,
|
||
deductionMoney: null,
|
||
deductionReason: null,
|
||
otherMoney: null,
|
||
otherReason: null,
|
||
tradeDate: null,
|
||
remark: null,
|
||
delFlag: null,
|
||
createBy: null,
|
||
createTime: null,
|
||
updateBy: null,
|
||
updateTime: null,
|
||
createSite: null,
|
||
updateSite: null
|
||
};
|
||
this.resetForm("form");
|
||
},
|
||
initPayOrder(){
|
||
this.billNo = this.$route.query.bid;
|
||
axios.get(process.env.VUE_APP_BASE_API+'/oms2c/common/getBillPayInfo?settleBillNo='+this.billNo)
|
||
.then(response => {
|
||
this.loadingVisible = false;
|
||
if (response.data.code === 200) {
|
||
this.settleBillItem = response.data.data;
|
||
// console.log("===>this.settleBillItem==>",this.settleBillItem);
|
||
} else {
|
||
this.payStatus==3;
|
||
this.showPaymentResult(false, response.data.msg || '获取账单失败');
|
||
}
|
||
})
|
||
.catch(error => {
|
||
this.loadingVisible = false;
|
||
this.showPaymentResult(false, '网络错误,请稍后重试');
|
||
// console.error('获取账单失败:', error);
|
||
});
|
||
},
|
||
goToSapp(){
|
||
let sappUrl="weixin://dl/business/?appid=wx52e07a62a2f80000&path=pages/post/post"
|
||
window.location.href = sappUrl;
|
||
|
||
},
|
||
handleWeixinPay(){
|
||
this.billNo = this.$route.query.bid;
|
||
const authUrl = this.generateAuthUrl("https://oms.tanex56.com/onlinePay","snsapi_base",this.billNo);
|
||
window.location.href = authUrl;
|
||
},
|
||
requestPayment(code,state) {
|
||
this.loadingVisible = true;
|
||
this.payStatus==1;
|
||
// 调用后端API获取微信支付参数
|
||
axios.post(process.env.VUE_APP_BASE_API+'/oms2c/common/sumbitWxPayByCode', {
|
||
code: code,
|
||
settleBillNo: state
|
||
})
|
||
.then(response => {
|
||
this.loadingVisible = false;
|
||
if (response.data.code === 200) {
|
||
this.wechatPaymentParams = response.data.data;
|
||
this.invokeWechatPayment();
|
||
} else {
|
||
this.payStatus==3;
|
||
this.showPaymentResult(false, response.message || '获取支付参数失败');
|
||
}
|
||
})
|
||
.catch(error => {
|
||
this.loadingVisible = false;
|
||
this.showPaymentResult(false, '网络错误,请稍后重试');
|
||
console.error('获取微信支付参数失败:', error);
|
||
});
|
||
},
|
||
invokeWechatPayment() {
|
||
if (typeof WeixinJSBridge === 'undefined') {
|
||
if (document.addEventListener) {
|
||
document.addEventListener('WeixinJSBridgeReady', this.onBridgeReady, false);
|
||
} else if (document.attachEvent) {
|
||
document.attachEvent('WeixinJSBridgeReady', this.onBridgeReady);
|
||
document.attachEvent('onWeixinJSBridgeReady', this.onBridgeReady);
|
||
}
|
||
} else {
|
||
this.onBridgeReady();
|
||
}
|
||
},
|
||
onBridgeReady() {
|
||
const params = this.wechatPaymentParams;
|
||
WeixinJSBridge.invoke(
|
||
'getBrandWCPayRequest', {
|
||
"appId": params.appId, // 公众号ID,由商户传入
|
||
"timeStamp": params.timeStamp, // 时间戳,自1970年以来的秒数
|
||
"nonceStr": params.nonceStr, // 随机串
|
||
"package": params.package, // 预支付交易会话ID
|
||
"signType": params.signType, // 微信签名方式
|
||
"paySign": params.paySign // 微信签名
|
||
},
|
||
(res) => {
|
||
if (res.err_msg === 'get_brand_wcpay_request:ok') {
|
||
// 用户支付成功,这里可以调用后端接口确认支付状态
|
||
this.verifyPaymentStatus();
|
||
} else if (res.err_msg === 'get_brand_wcpay_request:cancel') {
|
||
this.payStatus==3;
|
||
this.showPaymentResult('用户取消支付');
|
||
} else {
|
||
this.payStatus==3;
|
||
this.showPaymentResult(`支付失败: ${res.err_msg}`);
|
||
}
|
||
}
|
||
);
|
||
},
|
||
verifyPaymentStatus() {
|
||
this.loadingVisible = true;
|
||
this.payStatus==1;
|
||
// 调用后端API验证支付状态
|
||
setTimeout(() => {
|
||
// 实际项目中应该调用后端API验证支付状态
|
||
// 这里使用模拟数据
|
||
// 调用接口查询是否成功
|
||
this.payStatus==2;
|
||
this.loadingVisible = false;
|
||
this.showPaymentResult("支付成功");
|
||
}, 1500);
|
||
},
|
||
showPaymentResult(message = '') {
|
||
this.errorMessage = message;
|
||
},
|
||
handleResultAction() {
|
||
if (this.paymentSuccess) {
|
||
// this.$router.push({ name: 'OrderSuccess', params: { orderId: this.orderInfo.orderId } });
|
||
}
|
||
},
|
||
/**
|
||
* 生成微信授权URL
|
||
* @param {string} redirectUri - 授权后重定向的URL
|
||
* @param {string} scope - 授权作用域,snsapi_base或snsapi_userinfo
|
||
* @param {string} state - 自定义参数
|
||
*/
|
||
generateAuthUrl(redirectUri, scope = 'snsapi_base', state = 'STATE') {
|
||
const appId = process.env.VUE_APP_WECHAT_APPID;
|
||
const encodedRedirectUri = encodeURIComponent(redirectUri);
|
||
return `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appId}&redirect_uri=${encodedRedirectUri}&response_type=code&scope=${scope}&state=${state}#wechat_redirect`;
|
||
},
|
||
}
|
||
};
|
||
</script>
|
||
|
||
<style scoped>
|
||
.wechat-payment-container {
|
||
padding-bottom: 80px;
|
||
}
|
||
|
||
|
||
.pay-dialog-center {
|
||
display: -webkit-box;
|
||
display: -ms-flexbox;
|
||
display: flex;
|
||
-webkit-box-pack: center;
|
||
-ms-flex-pack: center;
|
||
justify-content: center;
|
||
-webkit-box-align: center;
|
||
-ms-flex-align: center;
|
||
align-items: center;
|
||
}
|
||
|
||
.pay-title {
|
||
font-size: 18px;
|
||
font-weight: 500;
|
||
color: #2e2f33;
|
||
text-align: center;
|
||
}
|
||
|
||
.pay-count{
|
||
color: #2962ff;
|
||
}
|
||
|
||
.item-label{
|
||
font-size: 12px;
|
||
color: #2e2f33;
|
||
}
|
||
|
||
.item-value{
|
||
font-size: 12px;
|
||
font-weight: 500;
|
||
color: #2e2f33;
|
||
}
|
||
|
||
|
||
.success-container {
|
||
max-width: 600px;
|
||
margin: 100px auto;
|
||
padding: 30px;
|
||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
|
||
border-radius: 8px;
|
||
}
|
||
.success-icon {
|
||
font-size: 64px;
|
||
color: #67c23a;
|
||
margin-bottom: 20px;
|
||
}
|
||
.order-info {
|
||
margin: 20px 0;
|
||
padding: 15px;
|
||
background-color: #f5f7fa;
|
||
border-radius: 4px;
|
||
}
|
||
.action-buttons {
|
||
display: flex;
|
||
justify-content: center;
|
||
gap: 15px;
|
||
margin-top: 30px;
|
||
}
|
||
@media (max-width: 576px) {
|
||
.success-container {
|
||
margin: 30px 20px;
|
||
padding: 20px;
|
||
}
|
||
.action-buttons {
|
||
flex-direction: column;
|
||
gap: 10px;
|
||
}
|
||
.action-buttons .el-button {
|
||
width: 100%;
|
||
}
|
||
}
|
||
|
||
</style> |