大家有没有好奇过饭店扫码点餐的时候,小程序是如何打开的?商家是怎么确认桌号的?为什么有的码微信可以扫,支付宝也可以扫?
本篇文章将会给大家介绍:如何使用二维码实现一码多扫
官方文档地址:https://developers.weixin.qq.com/miniprogram/introduction/qrcode.html
微信扫码打开小程序如何配置请参见:https://ata.alibaba-inc.com/articles/226107
官方文档地址:https://open.dingtalk.com/document/orgapp-client/scheme-of-mini-programs
钉钉小程序的打开方式很简单,是通过小程序schema打开的,配置如下:
dingtalk://dingtalkclient/action/open_micro_app?corpId=%s&appId=%s&page=%s
官方文档地址:https://opendocs.alipay.com/mini/03cj40
支付宝小程序也是通过schema配置打开,配置如下:
alipays://platformapi/startapp?appId=%s&page=%s
第一种,通过路径携带参数,例如http://www.qq.com/123456 ,其中123456就可以当做参数
第二中,通过"?"携带参数,例如http://www.qq.com/aa?param1=111
Page({ onl oad(query) { const q = decodeURIComponent(query.q) // 获取到二维码原始链接内容 const scancode_time = parseInt(query.scancode_time) // 获取用户扫码时间 UNIX 时间戳 } })
直接放在page上,例如:dingtalk://dingtalkclient/action/open_micro_app?page=/page/Index/index?id=2
同钉钉
1、钉钉、支付宝小程序扫码的原理一样,使用schema就可以打开小程序,而微信小程序是使用规则匹配的方式;
2、钉钉小程序有企业隔离的问题,如果用户不在当前企业下,是打不开小程序的;
3、钉钉、支付宝小程序的schema较长,不建议使用schema生成二维码,否则码会很密不容易扫描;
4、微信小程序在配置扫码规则时已经确定了是哪个小程序,而钉钉和支付宝是通过AppID参数的方式确定;
5、微信小程序配置扫码规则时需要校验文件,而钉钉、支付宝小程序不需要;
6、整体来说,钉钉、支付宝小程序实现较为简单,微信小程序扫码实现起来较为复杂;
在实现扫码功能之前,我们需要先知道扫码的原理。在微信、支付宝、钉钉这些超级APP中,都内置了一个专属浏览器。而二维码的本质就是一个链接,扫码的动作就是在浏览器中输入这个链接然后点击搜索。
那么根据这个原理,我们可以得出一个结论:扫码的动作是可以直接调用后台接口的。所以我们只需要统一这几个端的扫码接口,那么就可以实现一码多扫了。
通过第一章节我们知道,钉钉和支付宝的打开逻辑简单,配置好schema就行;而微信只在配置的时候调用一次接口,所以返回校验文件内容。实现思路是:
/** * 扫码打开各类小程序 * * @param bizType 业务类型 * @param param1 参数1 * @param param2 参数2 * ... * @return */ @GetMapping("/scan/{bizType}") public Object scan( @PathVariable(name = "bizType") String bizType, @RequestParam(required = false) String param1, @RequestParam(required = false) String param2) { //如果是微信校验文件的请求,一般是http://www.test.com/scan/xxx.txt格式 //此时该参数会占用bizType参数 if (bizType.contains(".txt")) { //直接返回对应的校验文件内容 return "xxx"; } //如果是钉钉或支付宝的请求,则生成schema ModelAndView modelAndView = new ModelAndView("scan"); //获取钉钉小程序的AppId,可以写在配置文件中 String dingAppId = "xxx"; //获取钉钉组织corpId,可以写在配置文件中 String corpId = "xxx"; //生成钉钉的schema String dingTalkSchema = "dingtalk://dingtalkclient/action/open_micro_app?corpId="+corpId+"&appId=" + dingAppId + "&page=pages/Index/index?param1=" + param1 + "¶m2=" + param2; modelAndView.addObject("dingTalkSchema", dingTalkSchema); //获取支付宝小程序的AppId,可以写在配置文件中 String alipayAppId = "xxx"; //生成支付宝的schema String alipaySchema = "alipays://platformapi/startapp?appId=" + alipayAppId + "&page=pages/Index/index?param1=" + param1 + "¶m2=" + param2; modelAndView.addObject("dingTalkSchema", alipaySchema); return modelAndView; }
<script> window.dingTalkSchema = '${dingTalkSchema}' window.alipaySchema = '${alipaySchema}' //判断当前浏览器内核 var userAgentStr = window.navigator.userAgent; if (/AlipayClient/.test(userAgentStr)) { console.log('Alipay(支付宝)'); window.location.href = window.alipayPage } else if (/DingTalk/.test(userAgentStr)) { console.log('DingTalk(钉钉)'); window.location.href = window.dingTalkPage } </script>
上面有说道,如果用户不在目标企业下,是打不开该小程序的。所以为了优化用户的体验问题,我们可以修改一下流程:
这个流程可以全部通过js代码实现,逻辑如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"/> <meta http-equiv="X-UA-Compatible" content="IE=edge"/> <meta name="viewport" content="width=device-width, initial-scale=1.0"/> <!-- 方案二 ,该方法依赖jquery库--> <script src="https://g.alicdn.com/dingding/dingtalk-jsapi/2.10.3/dingtalk.open.js"></script> <script> </script> </head> <style> </style> <body> </body> <script> window.corpId = '${corpId}' window.appId = '${appId}' window.page = '${page}' dd.ready(function () { dd.runtime.permission.requestAuthCode({ corpId: window.corpId, onSuccess: function (result) { dd.biz.navigation.replace({ url: "dingtalk://dingtalkclient/action/open_micro_app?corpId=" + window.corpId + "&appId=" + window.appId + "&page=" + window.page, onSuccess: function (res) { // 调用成功时回调 console.log(res) }, onFail: function (err) { // 调用失败时回调 console.log(err) } }); }, onFail: function (err) { //目前只能使用文字进行判断 if (err.errorMessage.indexOf('用户不在当前企业') != -1) { dd.biz.navigation.replace({ url: "https://wx-in-i.dingtalk.com/invite-page/weixin.html?bizSource=____source____&corpId=" + window.corpId, onSuccess: function (res) { // 调用成功时回调 console.log(res) }, onFail: function (err) { // 调用失败时回调 console.log(err) } }); } else { dd.biz.navigation.replace({ url: "dingtalk://dingtalkclient/action/open_micro_app?corpId=" + window.corpId + "&appId=" + window.appId + "&page=" + window.page, onSuccess: function (res) { // 调用成功时回调 console.log(res) }, onFail: function (err) { // 调用失败时回调 console.log(err) } }); } } }) }); </script> </html>