微信小程序笔记(制作进入小程序二维码,调用腾讯OCR识别车牌,获取用户资料)

最近被要求制作一个微信小程序用作为工厂的入厂登记,功能大概就是访客来厂前需要扫描二维码进入小程序,授权微信个人资料,以获取昵称以及绑定的手机号码,小程序内有拍照识别来访车牌号功能,以此就需要用到标题中的三个功能,而现在写下笔记记录一下

1 制作进入小程序二维码

1.1 大致流程

制作进入小程序二维码,查看官方文档,发现可以有三个API获取小程序二维码,除了数量的限制与否,并没细究它们的区别,所以最终使用的是 getWXACodeUnlimit 这个API接口
查看文档发现,它是一个使用 POST 方法请求https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=ACCESS_TOKEN 获取二维码,其中:

  • URL 中的 ACCESS_TOKEN 需要另外自行获取
  • 可传入的参数有:
    • scene:用户扫描该码进入小程序/小游戏后,可以获取到二维码中的 scene 值,再做处理逻辑,scene 的参数值需要进行 encodeURIComponent
    • page:跳转页面,必须是小程序已经发布的页面,如 pages/index/index,默认是首页
    • width:数值是 Number,表示二维码的宽度,默认为 430px
    • 还有一些感觉不常用的就不列出来了,需要的可转到官方文档

其中小程序获取 scene 的值,有些餐厅点餐,座位上会有特定的二维码,扫码后得到特定的座位号从而服务员得知送餐位置,应该就是依靠这个功能实现的。

Page({
  onLoad (query) {
    // scene 需要使用 decodeURIComponent 才能获取到生成二维码时传入的 scene
    const scene = decodeURIComponent(query.scene)
  }
})

1.2 获取 ACCESS_TOKEN

获取 ACCESS_TOKEN 接口调用凭证,是通过 GET 方法请求 https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET,其中URL 中的 appid 以及 secret 都可以到小程序控制后台中获取,使用浏览器即可获取。

1.3 保存二维码图片

这个 POST 请求我是使用Java 进行请求的,并转为图片,具体源码:

package top.seiei.accessxcx.util

import java.io.BufferedReader;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.URL;
import java.net.URLConnection;
import java.util.List;
import java.util.Map;

public class HttpRequest {
	/**
     * 向指定 URL 发送POST方法的请求
     * @param url 发送请求的 URL
     * @param param 请求参数
     * @return 所代表远程资源的响应结果
     */
     public static String sendPost(String url, String param) {
        PrintWriter out = null;
        InputStream in = null;
        FileOutputStream fw = null;
        String result = "";
        try {
            URL realUrl = new URL(url);
            // 打开和URL之间的连接
            URLConnection conn = realUrl.openConnection();
            // 设置通用的请求属性
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            conn.setRequestProperty("content-type","application/json");
            // 发送POST请求必须设置如下两行
            conn.setDoOutput(true);
            conn.setDoInput(true);
            /* 获取URLConnection对象对应的输出流 */
            out = new PrintWriter(conn.getOutputStream());
            // 中文有乱码的需要将PrintWriter改为如下
            //out=new OutputStreamWriter(conn.getOutputStream(),"UTF-8")
            // 发送请求参数
            out.print(param);
            // flush输出流的缓冲
            out.flush();
            // 定义BufferedReader输入流来读取URL的响应
            in = conn.getInputStream();
            fw = new FileOutputStream("F:\\Desert.jpg");
	        byte[] buf = new byte[1024];
	        int ln = 0;
	        while ((ln = in.read(buf)) != -1) {
	        	fw.write(buf, 0, ln);
	        }
        } catch (Exception e) {
            System.out.println("发送 POST 请求出现异常!"+e);
            e.printStackTrace();
        }
        //使用finally块来关闭输出流、输入流
        finally {
            try {
                if(out!=null){
                    out.close();
                }
                if(in!=null){
                    in.close();
                }
                if(fw!=null){
                    fw.close();
                }
            }
            catch(IOException ex){
                ex.printStackTrace();
            }
        }
        System.out.println("post推送结果:"+result);
        return result;	
     }

	public void main(String[] args) throws Exception {
		String access_token = "xxxx";
		String url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" + access_token;
		String param = "{ \"scene\":\"1254066020\"}";
		HttpRequest.sendPost(url, param);
	}
}

2 调用腾讯OCR识别车牌

2.1 大致流程

识别车牌号这边我是调用了腾讯OCR 车牌号识别 这个功能,看官方文档,发现它也是一个 POST 请求,它大致有两种方式申请,一是直接上传图片文件,而是上传图片 URL,由于使用的是微信小程序中的 wx.uploadFile api,并不太确认上传的具体数据内容,所以我这里一开始选择的是上传图片给后台服务器,再返回图片URL给腾讯OCR识别,获取结果。

2.2 制作 authorization 权限签名

在请求车牌识别时,需要在请求头中设置 authorization,在 官方文档 中,已经有示例演示如何获取 authorization,我这边使用的是 Java 示例获取,只需申请账号获取 主要的 appidsecretIdsecretKey 即可。

package top.seiei.accessxcx.util

import java.io.BufferedReader;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.URL;
import java.net.URLConnection;
import java.util.List;
import java.util.Map;

public class HttpRequest {
	/**
     * 向指定 URL 发送POST方法的请求
     * @param url 发送请求的 URL
     * @param param 请求参数
     * @return 所代表远程资源的响应结果
     */
     public static String sendPost(String url, String param) {
        PrintWriter out = null;
        BufferedReader in = null;
        String result = "";
       String authorization = "xxxxx";
        try {
            URL realUrl = new URL(url);
            // 打开和URL之间的连接
            URLConnection conn = realUrl.openConnection();
            // 设置通用的请求属性
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("host", "recognition.image.myqcloud.com");
            conn.setRequestProperty("user-agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            conn.setRequestProperty("content-type","application/json");
            conn.setRequestProperty("Authorization", authorization);
            // 发送POST请求必须设置如下两行
            conn.setDoOutput(true);
            conn.setDoInput(true);
            /* 获取URLConnection对象对应的输出流 */
            out = new PrintWriter(conn.getOutputStream());
            //2.中文有乱码的需要将PrintWriter改为如下
            //out=new OutputStreamWriter(conn.getOutputStream(),"UTF-8")
            // 发送请求参数
            out.print(param);
            // flush输出流的缓冲
            out.flush();
            // 定义BufferedReader输入流来读取URL的响应
            in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            System.out.println("发送 POST 请求出现异常!"+e);
            e.printStackTrace();
        }
        //使用finally块来关闭输出流、输入流
        finally{
            try{
                if(out!=null){
                    out.close();
                }
                if(in!=null){
                    in.close();
                }
            }
            catch(IOException ex){
                ex.printStackTrace();
            }
        }
        System.out.println("post推送结果:"+result);
        return result;
     }

	public void main(String[] args) throws Exception {
		String appid = "xxxx";
		String imgurl = "https://www.etscn.com.cn:40443/oa/microapp/20180927102519.jpg"
		String url = "http://recognition.image.myqcloud.com/ocr/plate";
		String param = "{ \"appid\":\"" + appid + "\", \"url\":\"" + imgurl + "\"}";;
		HttpRequest.sendPost(url, param);
	}
}

3 获取用户资料

3.1 大致流程

我这里需要获取用户信息有微信昵称和手机号,查看文档发现这两个东西是需要分开获取,分开请求用户授权的,也就是说用户信息并不包括其绑定的手机号码,手机号码需要另外获取,而且还不能在小程序中直接调用API弹出弹窗进行请求授权,要使用独特的按钮让用户点击触发弹窗事件,而且最后还需要解码获取具体数据。

3.2 获取用户信息

查看文档,获取用户信息需要使用 <button open-type="getUserInfo"></button> 这个组件按钮让用户点击,而不能使用直接调用 wx.authorize({scope: "scope.userInfo"}) 这个接口来触发弹窗让用户授权。

点击按钮之后,可以在其绑定的事件中以形如 e.detail.userInfo 的形式获取得到一个包含昵称,位置,图像等信息的数据,

与此同时通过调用 wx.getSetting 这个接口,它的成功回调函数,可以获取到 authSetting 这个 用户授权结果 的键值模式,得到用户的授权后,此时可由形如 res.authSetting['scope.userInfo'] 是否返回 true 来确认是否授权成功。

授权之后就无需次次让用户点击按钮获取用户信息了,可以直接调用 wx.getUserInfo 接口,它的成功回调函数来获取用户信息,此时就可以成功获取到了。

3.3 获取用户绑定手机号

获取用户绑定的手机号,查看官方文档,发现需要 session_keyivencryptData 这三个数据,其中:

  • session_key:查看文档(《wx.login》《code2Session》),通过在 app.jsonLauch 生命周期中使用 wx.login,它成功回调返回一个名叫 code 的值,再向 https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code 网页发起 GET 请求,从而获取用户的唯一标识(openid) 及本次登录的 会话密钥(session_key
  • iv 以及 encryptData 这两个数据则需要定义一个形如 <button open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber">获取手机号码</button> 的组件,让用户点击授权之后,在成功回调函数中便可得到这两个数值

获取以上数值后,通过解码便可得到对应的手机号,这里我使用的是后台Java进行解码,以下是对应测试代码:

import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import javax.crypto.*;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.*;

public class DecodeWXxcx {
	public static void main(String[] args) {
        String session_key = "XXX";
        String iv = "XXX";
        String encryptData = "XXX";
        String decrypt = decrypt(session_key, iv, encryptData);
        System.out.println(decrypt);
    }

    public static String decrypt(String session_key, String iv, String encryptData) {
        String decryptString = "";
        init();
        byte[] sessionKeyByte = Base64.decodeBase64(session_key);
        byte[] ivByte = Base64.decodeBase64(iv);
        byte[] encryptDataByte = Base64.decodeBase64(encryptData);

        try {
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
            Key key = new SecretKeySpec(sessionKeyByte, "AES");
            AlgorithmParameters algorithmParameters = AlgorithmParameters.getInstance("AES");
            algorithmParameters.init(new IvParameterSpec(ivByte));
            cipher.init(Cipher.DECRYPT_MODE, key, algorithmParameters);
            byte[] bytes = cipher.doFinal(encryptDataByte);
            decryptString = new String(bytes);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return decryptString;
    }

    private static boolean hasInited = false;

    public static void init() {
        if (hasInited) {
            return;
        }
        Security.addProvider(new BouncyCastleProvider());
        hasInited = true;
    }
}

引入的依赖有:

<dependency> 
	<groupId>org.bouncycastle</groupId>
	<artifactId>bcprov-jdk15on</artifactId>
	<version>1.55</version>
</dependency>
<dependency>
	<groupId>commons-codec</groupId>
	<artifactId>commons-codec</artifactId>
	<version>1.10</version>
</dependency>
  • 0
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
要在微信小程序调用腾讯地图,需要先在小程序管理后台进行配置并授权。以下是授权并获取位置的步骤: 1. 在小程序管理后台,打开“开发”->“接口设置”->“腾讯地图”,并勾选“使用腾讯地图”和“地图SDK”,保存并提交审核。 2. 在小程序引入腾讯地图SDK的JS文件: ``` <!-- 引入腾讯地图SDK --> <script src="https://map.qq.com/api/js?v=2.exp&key=你的腾讯地图Key"></script> ``` 3. 在小程序使用wx.getLocation()方法获取用户位置: ``` // 获取用户位置 wx.getLocation({ type: 'gcj02', success(res) { // 获取成功,可以使用腾讯地图SDK // 创建地图实例 var map = new qq.maps.Map(document.getElementById("map"), { center: new qq.maps.LatLng(res.latitude, res.longitude), zoom: 18 }); }, fail(res) { // 获取失败,提示用户授权地理位置 wx.showToast({ title: '请先授权地理位置', icon: 'none' }); } }); ``` 在上述代码,wx.getLocation()方法可以获取用户的经纬度信息,并可以指定返回的坐标系类型(gcj02表示国测局坐标系)。获取成功后,可以使用腾讯地图SDK创建地图实例,并将地图心位置设置为用户的当前位置。如果获取失败,可以提示用户授权地理位置。 注意:在小程序使用腾讯地图SDK需要先获取用户位置授权,可以在小程序使用wx.authorize()方法进行授权。另外,使用腾讯地图SDK需要在小程序管理后台绑定腾讯地图Key。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值