本文是由 Vue 的 SPA 对接到外接设备的驱动进行交互,须要从后端接口获取领取链接传输到外接设备(大屏幕的智能设施)生成二维码。(当然也能够通过领取链接本人转成二维码)
首先定义一个单选组,有两种领取形式:“微信”,“支付宝”领取形式。paySucceed 为 true 示意领取胜利,则提醒领取胜利,暗藏掉领取单选
<el-radio-group v-model="payWay" @change="payWayChange" v-if='paySucceed === false'>
<el-radio label="wechat" > 微信 </el-radio>
<el-radio label="ali"> 支付宝 </el-radio>
</el-radio-group>
payWayChange 校验
因为外接设备的电脑驱动服务次要是通过 websocket
进行数据交互的,所以须要在一开始通过 webSocket.OPEN 去验证 websocket 以后浏览器与驱动 / 设施是否失常连贯中,如没连贯上进行提醒并中断以后的操作。
当然在校验的时候须要重置(初始化)外接设备、领取状态、定时器。
开始领取
获取领取的一些参数并通过接口 (getPayStatus)
获取到领取的 url 链接,调用 openQRcode
传递链接到外接设备上, 显示出二维码进行领取(这里能够应用 qrcode 的 js 库转成二维码图片跳转页面的模式显示出二维码)。
在这里是调用 openQRcode
办法只是个举例,外接设备个别都会有提供本人驱动以及对接驱动的 js,依照本人的理论状况来。
领取中(轮询)
当二维码胜利显示后立刻调用 queryStatus()
利用获取到的订单号为参数进入一个领取状态的查问(应用 setTimeout
轮询)queryStatus
外部是一个没通过包装的申请,当申请返回 payStatus 示意以后未领取实现,或在领取中,否则为领取胜利。
每隔 3 秒轮询一次(尾递归 queryStatus
获取领取状态 胜利
or 失败
):
window.pollTimer = setTimeout(() => {return queryStatus(); // 轮询查问领取状态 3s
}, 3000)
在 queryStatus 中的申请应用了 axios
,是因为这里的 post 包装申请 pending 过程中主动加上了“加载中。。。”的全屏界面动画, 因为轮询是一直进行的不能显示加载动画,否则会造成每次获取状态都会始终呈现加载动画敞开 / 显示的闪屏成果,所以这里应用原生 axios
领取实现
领取胜利后就进行提醒,达成递归终止条件,革除掉计时器,重置领取的状态。最初 5s 计时器是为了给个小提早,避免设施上领取胜利后就秒关掉了界面,没有显示领取胜利的问题
if ((res.payStatus == 2) || (res.payStatus == 1)) { // 领取胜利,敞开弹窗
that.paySucceed = true;
window.pollTimer && window.clearTimeout(window.pollTimer);
// 领取胜利后干些事件。。。setTimeout(() => {that.common.cancelAll();
that.resetPay();}, 5000)
}
payWayChange (val) {
// 革除计时器轮询状态
clearTimeout(window.pollTimer);
window.pollTimer = null;
if (webSocket.readyState != webSocket.OPEN) {
this.$message({
message: '请正确连贯设施或设施驱动未启动,请查看',
type: 'error'
});
this.resetPay();
return;
}
this.common.cancelAll(); // 敞开电子屏领取页
// 参数
let params = {
type: val === 'wechat' ? 'WeChatPay' : 'AliPay',
data: {
paymentType:1,
id:'123',
payMoney: '30.0',
payWay: this.payWay,
}
}
let that = this;
function queryStatus () {window.clearTimeout(window.pollTimer)
axios({// 应用 axios,不显示加载中提醒
method: 'post',
url: 'getPayStatus',
withCredentials: true,
timeout: 0,
hideLoading: true,
headers: {
"Content-Type": "application/json;charset=UTF-8",
"token": sessionStorage.getItem('token')
},
data: {
typeCode: val === 'wechat' ? 'WeChat' : 'ali',
token: sessionStorage.getItem('token'),
data: {order: params.order,}
},
}).then((res) => {if (res.payStatus == 0) {window.pollTimer = setTimeout(() => {return queryStatus(); // 轮询查问领取状态 3s
}, 3000)
}
if ((res.payStatus == 2) || (res.payStatus == 1)) { // 领取胜利,敞开弹窗
that.paySucceed = true;
window.pollTimer && window.clearTimeout(window.pollTimer)
// 领取胜利后干些事件。。。setTimeout(() => {that.common.cancelAll();
that.resetPay();}, 5000)
}
})
}
that.post({params,// 参数})
.then(res => { // 获取领取链接和订单信息
params = params.data;
params.order = res.order;
window.delayTimer = null;
window.clearTimeout(window.delayTimer);
window.delayTimer = setTimeout(() => {
// 关上领取二维码
this.common.openQRcode(encodeURI(JSON.stringify(params)) ,encodeURI(res.url))
}, 1000);
queryStatus();// 开始轮询领取的状态});
},
resetPay () {
this.paySucceed = false;
window.pollTimer && window.clearTimeout(window.pollTimer); // 革除计时器轮询状态
},