1 package com.foxinmy.weixin4j.wxa.api;
2
3 import java.awt.Color;
4 import java.util.Properties;
5
6 import com.alibaba.fastjson.JSON;
7 import com.foxinmy.weixin4j.exception.WeixinException;
8 import com.foxinmy.weixin4j.http.ContentType;
9 import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
10 import com.foxinmy.weixin4j.token.TokenManager;
11
12 /**
13 * 获取二维码。
14 *
15 * <p>
16 * 通过后台接口可以获取小程序任意页面的二维码,扫描该二维码可以直接进入小程序对应的页面。
17 * 目前微信支持两种二维码,小程序码,小程序二维码。
18 * </p>
19 *
20 * @see <a href="https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/qr-code.html">获取二维码</a>
21 * @since 1.8
22 */
23 public class QrCodeApi extends TokenManagerApi {
24
25 public QrCodeApi(TokenManager tokenManager) {
26 this(tokenManager, null);
27 }
28
29 public QrCodeApi(TokenManager tokenManager, Properties properties) {
30 super(tokenManager, properties);
31 }
32
33 /**
34 * 获取小程序码.
35 *
36 * <p>接口A: 适用于需要的码数量较少的业务场景</p>
37 * <p>
38 * 注意:通过该接口生成的小程序码,永久有效,数量限制见微信小程序文档文末说明,请谨慎使用。
39 * 用户扫描该码进入小程序后,将直接进入 path 对应的页面。
40 * </p>
41 *
42 * @param path 不能为空,最大长度 128 字节
43 * @param width 二维码的宽度,默认值 430
44 * @param autoColor 自动配置线条颜色,如果颜色依然是黑色,则说明不建议配置主色调
45 * @param lineColor <code>authColor</code> 为 false 时生效
46 * @param hyaline 是否需要透明底色, 为true时,生成透明底色的小程序码
47 * @return image bytes of WXA code.
48 * @throws WeixinException indicates getting access token failed or getting WXA code failed.
49 *
50 * @see <a href="https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/qr-code/wxacode.get.html">获取小程序码</a>
51 */
52 public byte[] getWxaCode(
53 String path,
54 Integer width,
55 Boolean autoColor,
56 Color lineColor,
57 Boolean hyaline
58 ) throws WeixinException {
59 final String getWxaCodeUri = this.getAccessTokenRequestUri("wxa_getwxacode");
60 final WxaCodeParameter param = new WxaCodeParameter(path, width, autoColor, lineColor, hyaline);
61 return this.postAsImageBytes(getWxaCodeUri, param);
62 }
63
64 /**
65 * 获取小程序码.
66 *
67 * <p>接口B:适用于需要的码数量极多的业务场景</p>
68 * <p>
69 * 注意:通过该接口生成的小程序码,永久有效,数量暂无限制。
70 * 用户扫描该码进入小程序后,开发者需在对应页面获取的码中 scene 字段的值,再做处理逻辑。
71 * 使用如下代码可以获取到二维码中的 scene 字段的值。
72 * 调试阶段可以使用开发工具的条件编译自定义参数 scene=xxxx 进行模拟,
73 * 开发工具模拟时的 scene 的参数值需要进行 urlencode。
74 * <p>
75 * <pre>
76 * // 这是首页的 js
77 * Page({
78 * onLoad: function(options) {
79 * // options 中的 scene 需要使用 decodeURIComponent 才能获取到生成二维码时传入的 scene
80 * var scene = decodeURIComponent(options.scene)
81 * }
82 * })
83 * </pre>
84 *
85 * @param scene 最大32个可见字符,只支持数字,
86 * 大小写英文以及部分特殊字符:!#$&'()*+,/:;=?@-._~,
87 * 其它字符请自行编码为合法字符(因不支持%,中文无法使用 urlencode 处理,请使用其他编码方式)
88 * @param page 必须是已经发布的小程序存在的页面(否则报错),
89 * 例如 "pages/index/index",根路径前不要填加'/',
90 * 不能携带参数(参数请放在scene字段里),
91 * 如果不填写这个字段,默认跳主页面
92 * @param width 二维码的宽度,默认值 430
93 * @param autoColor 自动配置线条颜色,如果颜色依然是黑色,则说明不建议配置主色调,默认值 false
94 * @param lineColor <code>autoColor</code> 为 false 时生效,使用 rgb 设置颜色
95 * @param hyaline 是否需要透明底色,为true时,生成透明底色的小程序码
96 * @return image bytes of WXA code.
97 * @throws WeixinException indicates getting access token failed or getting WXA code failed.
98 *
99 * @see <a href="https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/qr-code/wxacode.getUnlimited.html">获取小程序码</a>
100 */
101 public byte[] getWxaCodeUnlimit(
102 String scene,
103 String page,
104 Integer width,
105 Boolean autoColor,
106 Color lineColor,
107 Boolean hyaline
108 ) throws WeixinException {
109 final String getWxaCodeUnlimitUri = this.getAccessTokenRequestUri("wxa_getwxacodeunlimit");
110 final WxaCodeUnlimitParameter param = new WxaCodeUnlimitParameter(scene, page, width, autoColor, lineColor, hyaline);
111 return this.postAsImageBytes(getWxaCodeUnlimitUri, param);
112 }
113
114 /**
115 * 获取小程序二维码.
116 *
117 * <p>接口C:适用于需要的码数量较少的业务场景</p>
118 * <p>
119 * 注意:通过该接口生成的小程序二维码,永久有效,数量限制见微信小程序文档文末说明,请谨慎使用。
120 * 用户扫描该码进入小程序后,将直接进入 path 对应的页面。
121 * </p>
122 *
123 * @param path 不能为空,最大长度 128 字节
124 * @param width 二维码的宽度,默认值 430
125 * @return image bytes of WXA QR code.
126 * @throws WeixinException indicates getting access token failed or getting WXA QR code failed.
127 *
128 * @see <a href="https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/qr-code/wxacode.createQRCode.html">获取小程序二维码</a>
129 */
130 public byte[] createWxaQrCode(
131 String path,
132 Integer width
133 ) throws WeixinException {
134 final String createWxaQrCode = this.getAccessTokenRequestUri("wxaapp_createwxaqrcode");
135 final WxaQrCodeParameter param = new WxaQrCodeParameter(path, width);
136 return this.postAsImageBytes(createWxaQrCode, param);
137 }
138
139 private byte[] postAsImageBytes(String uri, Object param) throws WeixinException {
140 final String body = JSON.toJSONString(param);
141 final WeixinResponse response = this.weixinExecutor.post(uri, body);
142 return toImageBytes(response);
143 }
144
145 private byte[] toImageBytes(WeixinResponse response) throws WeixinException {
146 final String contentType = response.getHeaders().getContentType();
147 if (contentType != null && contentType.equals(ContentType.APPLICATION_JSON.getMimeType().getType())) {
148 final WxaApiResult r = response.getAsObject(WxaApiResult.TYPE_REFERENCE);
149 throw r.toWeixinException();
150 } else {
151 return response.getContent();
152 }
153 }
154
155 }