|
|
@@ -0,0 +1,155 @@
|
|
|
+package com.linkwechat.common.utils.createQrCode;
|
|
|
+
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import okhttp3.*;
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
+import org.springframework.beans.factory.annotation.Value;
|
|
|
+import org.springframework.stereotype.Component;
|
|
|
+
|
|
|
+import javax.servlet.http.HttpServletResponse;
|
|
|
+import java.io.IOException;
|
|
|
+import java.io.InputStream;
|
|
|
+import java.io.OutputStream;
|
|
|
+import java.util.concurrent.TimeUnit;
|
|
|
+
|
|
|
+
|
|
|
+@Component
|
|
|
+@Slf4j
|
|
|
+/**
|
|
|
+ * 本地生活生成小程序码
|
|
|
+ */
|
|
|
+public class WxMiniProgramGetQRCodeByCommonUtil {
|
|
|
+
|
|
|
+ //微信小程序的appid
|
|
|
+ @Value("${wechat.app_id}")
|
|
|
+ private String wechatAppId;
|
|
|
+
|
|
|
+
|
|
|
+ //微信小程序的appid
|
|
|
+ @Value("${wechat.secret}")
|
|
|
+ private String wechatSecret;
|
|
|
+ // 超时时间(秒)
|
|
|
+ private static final int TIMEOUT = 10;
|
|
|
+
|
|
|
+ // OkHttp客户端
|
|
|
+ private static final OkHttpClient client = new OkHttpClient.Builder()
|
|
|
+ .connectTimeout(TIMEOUT, TimeUnit.SECONDS)
|
|
|
+ .readTimeout(TIMEOUT, TimeUnit.SECONDS)
|
|
|
+ .writeTimeout(TIMEOUT, TimeUnit.SECONDS)
|
|
|
+ .build();
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取access_token
|
|
|
+ */
|
|
|
+ public String getAccessToken(String wechatAppId, String wechatSecret) throws IOException {
|
|
|
+ // 接口地址
|
|
|
+ String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential" +
|
|
|
+ "&appid=" + wechatAppId +
|
|
|
+ "&secret=" + wechatSecret;
|
|
|
+ // 发送GET请求
|
|
|
+ Request request = new Request.Builder().url(url).get().build();
|
|
|
+ Response response = client.newCall(request).execute();
|
|
|
+ String responseBody = response.body().string();
|
|
|
+
|
|
|
+ // 解析响应
|
|
|
+ JSONObject json = JSONObject.parseObject(responseBody);
|
|
|
+ if (json.containsKey("errcode") && json.getInteger("errcode") != 0) {
|
|
|
+ throw new RuntimeException("获取access_token失败:" + json.getString("errmsg"));
|
|
|
+ }
|
|
|
+ return json.getString("access_token");
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 生成小程序码
|
|
|
+ */
|
|
|
+ public void createQRCode(CreateQRCodeByCodeVO createQRCode, String wechatAppId, String wechatSecret, HttpServletResponse servletResponse) throws IOException {
|
|
|
+ log.info("进入生成方法:" + createQRCode.toString());
|
|
|
+ String accessToken =null;
|
|
|
+ // 1. 获取access_token
|
|
|
+ accessToken = getAccessToken(wechatAppId, wechatSecret);
|
|
|
+ // 2. 构建请求参数
|
|
|
+ JSONObject params = new JSONObject();
|
|
|
+ // 扫码进入的小程序页面路径
|
|
|
+ if(StringUtils.isNotBlank(createQRCode.getKeyName()) && StringUtils.isNotBlank(createQRCode.getKeyValue()) ){
|
|
|
+ params.put("scene", createQRCode.getKeyName()+"=" + createQRCode.getKeyValue());
|
|
|
+ }
|
|
|
+ if (StringUtils.isNotBlank(createQRCode.getSharePath())) {
|
|
|
+ params.put("page", createQRCode.getSharePath());
|
|
|
+ }
|
|
|
+ if (createQRCode.getWidth() != null && createQRCode.getWidth() > 0) {
|
|
|
+ params.put("width", createQRCode.getWidth());
|
|
|
+ }
|
|
|
+ if (createQRCode.getAuto_color() != null) {
|
|
|
+ params.put("auto_color", createQRCode.getAuto_color());
|
|
|
+ }
|
|
|
+ if (createQRCode.getLine_color() != null) {
|
|
|
+ params.put("line_color", createQRCode.getLine_color());
|
|
|
+ }
|
|
|
+ if (createQRCode.getIs_hyaline() != null) {
|
|
|
+ params.put("is_hyaline", createQRCode.getIs_hyaline());
|
|
|
+ }
|
|
|
+ //要打开的小程序版本。正式版为"release",体验版为"trial",开发版为"develop"
|
|
|
+ if (createQRCode.getEnv_version() != null) {
|
|
|
+ params.put("env_version", createQRCode.getEnv_version());
|
|
|
+ }
|
|
|
+ // 3. 发送POST请求
|
|
|
+ String url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" + accessToken;
|
|
|
+ RequestBody requestBody = RequestBody.create(
|
|
|
+ params.toJSONString(),
|
|
|
+ MediaType.parse("application/json; charset=utf-8")
|
|
|
+ );
|
|
|
+ Request request = new Request.Builder().url(url).post(requestBody).build();
|
|
|
+ try (Response response = client.newCall(request).execute();) {
|
|
|
+ if (!response.isSuccessful()) {
|
|
|
+ // 处理错误,微信返回的是JSON格式的错误信息
|
|
|
+ String errorBody = response.body().string();
|
|
|
+ log.error("生成二维码失败: {}, 错误信息: {}", response.code(), errorBody);
|
|
|
+ throw new RuntimeException("生成二维码失败: " + errorBody);
|
|
|
+ }
|
|
|
+ forwardResponse(response, servletResponse);
|
|
|
+
|
|
|
+ } catch (IOException e) {
|
|
|
+ log.error("请求微信接口异常", e);
|
|
|
+ throw new RuntimeException("请求微信接口异常", e);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 转发OkHttp Response到HttpServletResponse
|
|
|
+ */
|
|
|
+
|
|
|
+ private void forwardResponse(Response wechatResponse, HttpServletResponse servletResponse) {
|
|
|
+ // 设置状态码
|
|
|
+ servletResponse.setStatus(wechatResponse.code());
|
|
|
+
|
|
|
+ // 设置内容类型(如果微信响应中有)
|
|
|
+ if (wechatResponse.body() != null && wechatResponse.body().contentType() != null) {
|
|
|
+ servletResponse.setContentType(wechatResponse.body().contentType().toString());
|
|
|
+ }
|
|
|
+
|
|
|
+ // 写入响应体
|
|
|
+ try (InputStream inputStream = wechatResponse.body().byteStream();
|
|
|
+ OutputStream outputStream = servletResponse.getOutputStream()) {
|
|
|
+ byte[] buffer = new byte[4096];
|
|
|
+ int bytesRead;
|
|
|
+ while ((bytesRead = inputStream.read(buffer)) != -1) {
|
|
|
+ outputStream.write(buffer, 0, bytesRead);
|
|
|
+ }
|
|
|
+ log.info("生成小程序二维码成功",outputStream.toString());
|
|
|
+ } catch (IOException e) {
|
|
|
+ throw new RuntimeException(e);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 关闭微信响应
|
|
|
+ wechatResponse.close();
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|