开发背景:
.net混合开发的vue模板语法的单页面应用,所以不存在脚手架以及没有路由可以跳转。
项目描述:
需要写两个页面,在订单详情页需要点击“请输入手机号”进入手机号绑定页面,手机号绑定成功后自动跳转到订单详情页,如果该手机号已经绑定成功,则不显示“请输入手机号”(即不可点击进入下一个页面),只显示该手机号。
项目思路:
在单页面中使用v-show控制两个页面的切换,所以需要模拟真实两个页面的跳转,即改变hash值并且监听历史条目变化。
一、监听并且覆盖微信的回退事件
当两个页面在同一路由下,从“手机号绑定”页面点击微信的返回时不会进入“确认订单”页面,会直接返回,所以通过在url尾部添加可以识别的hash值并且使用方法进行监听,以此判断回到哪个页面。
知识点储备:
关于window.onpopstate事件其实是popstate事件在 window对象上的事件处理程序。每当处于激活状态的历史记录条目发生变化时,popstate事件就会在对应window对象上触发.
因为给url加上了hash值虽然不会重新发出http请求但是会改变浏览器的访问历史。所以即使进入了“手机号绑定”页面,popstate也能监听到。
代码:
在“请输入手机号”的点击事件中加上可以辨识的hash值
事件写在methods中
复制代码
inputPhoneNumber() {
this.index = false;
console.log("添加hash值");
location.hash = "second";
console.log("显示绑定手机号的hash值");
console.log(window.location);
},
复制代码
监听事件写在mouted钩子函数中
复制代码
mounted() {
var url = window.location.href;
window.onpopstate = function () {
console.log("监听回退事件");
if (location.hash.indexOf("#second") > -1) {
} else {
window.location.href = url;
}
}
}
复制代码
二、H5微信支付代码
思路:
1.在确认订单页面点击立即付款时,进行手机号是否绑定判断,如果填写手机号才可以进行下一步
2.调用接口向后台发送请求来拿去调用微信支付的参数(公众号商户付款的参数);
3.根据后台返回的参数进行判断,如果订单未完成,就调用微信支付的内置接口,如果存在订单,则跳转到订单完成页面。
4.根据微信支付返回参数进行判断,如果返回ok则调用后台接口进行轮询,查询订单是否完成。根据后台状态码进行成功失败的页面跳转。
代码:
付款按钮:
toPayMoney() {
console.log("触发立即付款按钮");
var that = this;
var returnUrl = location.href;
that.disabled = true;
if (!this.phone) {
that.dialogVisible = true;
that.infoMessage = "请先输入手机号";
console.log("确认订单,手机号不存在时");
} else {
console.log("确认订单,手机号存在时");
that.selectParams(); //查询参数
console.log("确认订单,手机号存在时,查询支付参数");
}
},
复制代码
查询支付的参数:
selectParams() {
var that = this;
var returnUrl = location.href;
$.ajax({
url: '/api/wxpay/unifiedorder',
type: "GET",
cache: false,
dataType: 'json',
data: { number: this.number },
success: function (data) {
if (data.code === 200) {
if (data.data.isValid == true) {
return location.href = "/pay/subscription/" + @Model.SubscriptionID +"/finish?tradeNo=" + @Model.Number;
} else {
var json =data.data.jsParams;
console.log("json" + (data.data.jsParams));
//调起微信支付
function onBridgeReady() {
WeixinJSBridge.invoke(
'getBrandWCPayRequest', {
"appId": json["appId"], //公众号名称,由商户传入
"timeStamp": json["timeStamp"], //时间戳,自1970年以来的秒数
"nonceStr": json["nonceStr"], //随机串
"package": json["package"],
"signType": json["signType"], //微信签名方式:
"paySign": json["paySign"] //微信签名
},
function checkPayRes(res) {
console.log("请求后台参数并且调用了微信支付");
//setInterval()
if (res.err_msg == "get_brand_wcpay_request:ok") {
that.polling();
// 使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返回 ok,但并不保证它绝对可靠。
} else {
}
}
);
}
if (typeof WeixinJSBridge === "undefined") {
if (document.addEventListener) {
document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
} else if (document.attachEvent) {
document.attachEvent('WeixinJSBridgeReady', onBridgeReady);
document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
}
} else {
onBridgeReady();
}
}
}
},
error: function (data) {
console.log("调用后台查询订单未成功");
}
})
},
复制代码
短轮询的函数
polling() {
var that = this;
$.ajax({
url: '/api/wxpay/unifiedorder',
type: "GET",
cache: false,
dataType: 'json',
data: { number: this.number },
success: function (data) {
if (code.data === 100) {
console.log("状态码101需要持续轮询查询");
setInterval(that.polling(), 1000);
} else if (code.data === 200) {
clearInterval(that.polling());
console.log("状态码200需要持续轮询查询");
console.log("支付成功");
location.href = "/pay/subscription/" + @Model.SubscriptionID +"/finish?tradeNo=" + @Model.Number;
} else {
console.log(data.msg);
}
}
})
}
复制代码
三、按钮加锁解锁
其实上面的代码已经包括了部分加锁与解锁功能,下面写一下思路:
- 使用button的 disabled属性
- 使用v-bind给每个按钮绑定变量。