嗨森逛服务
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
hai-server/hai-service/src/main/java/com/hai/config/WeChatQrcodeUtils.java

366 lines
12 KiB

package com.hai.config;
import com.alibaba.fastjson.JSONObject;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.DecodeHintType;
import com.google.zxing.Result;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.QRCodeReader;
import com.hai.common.utils.HttpsUtils;
import com.hai.common.utils.RedisUtil;
import com.hai.common.utils.ResponseMsgUtil;
import com.hai.model.TextMessage;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.result.WxMpQrCodeTicket;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
import static org.apache.catalina.manager.Constants.CHARSET;
/**
* @serviceName WeChatQrcodeUtils.java
* @author Sum1Dream
* @version 1.0.0
* @Description // 生成带参数的二维码
* @createTime 16:11 2022/9/2
**/
@Slf4j
@Component
public class WeChatQrcodeUtils {
@Autowired
private WxMpService wxMpService;
@Resource
private RedisUtil redisUtil;
/**
* <pre>
* 创建临时二维码ticket
* @param sceneId 场景值ID,临时二维码时为32位非0整型
* @param expireSeconds 该二维码有效时间,以秒为单位。 最大不超过2592000(即30天),此字段如果不填,则默认有效期为30秒。
* @auther: cao_wencao
* @date: 2019/2/18 16:58
* </pre>
*/
public WxMpQrCodeTicket qrCodeCreateTmpTicket(int sceneId, Integer expireSeconds) throws WxErrorException {
WxMpQrCodeTicket wxMpQrCodeTicket = wxMpService.getQrcodeService().qrCodeCreateTmpTicket(sceneId, expireSeconds);
return wxMpQrCodeTicket;
}
/**
* <pre>
* 创建临时二维码ticket
* @param sceneStr 场景值ID(字符串形式的ID),字符串类型,长度限制为1到64
* @param expireSeconds 该二维码有效时间,以秒为单位。 最大不超过2592000(即30天),此字段如果不填,则默认有效期为30秒。
* @auther: cao_wencao
* @date: 2019/2/18 17:01
* </pre>
*/
public WxMpQrCodeTicket qrCodeCreateTmpTicket(String sceneStr, Integer expireSeconds) throws WxErrorException {
WxMpQrCodeTicket wxMpQrCodeTicket = wxMpService.getQrcodeService().qrCodeCreateTmpTicket(sceneStr, expireSeconds);
return wxMpQrCodeTicket;
}
/**
* <pre>
* 创建永久二维码ticket
* @param sceneId 场景值ID,最大值为100000(目前参数只支持1--100000)
* @auther: cao_wencao
* @date: 2019/2/18 17:03
* </pre>
*/
public WxMpQrCodeTicket qrCodeCreateLastTicket(int sceneId) throws WxErrorException {
return wxMpService.getQrcodeService().qrCodeCreateLastTicket(sceneId);
}
/**
* <pre>
* 创建永久字符串二维码ticket
* @param sceneStr 参数。字符串类型长度现在为1到64
* @auther: cao_wencao
* @date: 2019/2/18 17:05
* </pre>
*/
public WxMpQrCodeTicket qrCodeCreateLastTicket(String sceneStr) throws WxErrorException {
return wxMpService.getQrcodeService().qrCodeCreateLastTicket(sceneStr);
}
// 创建微信二维码
public JSONObject createWxQrCode(String sceneStr) {
JSONObject object = new JSONObject();
JSONObject objectScene = new JSONObject();
JSONObject objectActionInfo = new JSONObject();
objectScene.put("scene_str" , sceneStr);
objectActionInfo.put("scene" , objectScene);
object.put("action_name" , "QR_STR_SCENE");
object.put("expire_seconds" , 2592000);
object.put("action_info" , objectActionInfo);
if (redisUtil.get("WxToken") == null) {
getWxToken();
}
return HttpsUtils.doPost("https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=" + redisUtil.get("WxToken"), object);
}
// 获取微信Token存入redis
public void getWxToken() {
// 获取access_token
Map<String, Object> params = new HashMap<>();
params.put("appid", CommonSysConst.getSysConfig().getWxH5AppId());
params.put("secret", CommonSysConst.getSysConfig().getWxH5AppSecret());
params.put("grant_type", "client_credential");
JSONObject accessTokenObject = HttpsUtils.doGet("https://api.weixin.qq.com/cgi-bin/token", params);
if (accessTokenObject != null && accessTokenObject.getString("access_token") != null) {
redisUtil.set("WxToken" , accessTokenObject.getString("access_token") , 7000);
}
}
/**
* <pre>
* 换取二维码图片文件,jpg格式
* @param ticket 二维码ticket
* @auther: cao_wencao
* @date: 2019/2/18 17:07
* </pre>
*/
public File qrCodePicture(WxMpQrCodeTicket ticket) throws WxErrorException {
return wxMpService.getQrcodeService().qrCodePicture(ticket);
}
/**
* <pre>
* 换取二维码图片url地址(可以选择是否生成压缩的网址)
* @param ticket 二维码ticket
* @param needShortUrl 是否需要压缩的二维码地址
* @auther: cao_wencao
* @date: 2019/2/18 17:10
* </pre>
*/
public String qrCodePictureUrl(String ticket, boolean needShortUrl) throws WxErrorException {
String qrCodeUrl = wxMpService.getQrcodeService().qrCodePictureUrl(ticket, needShortUrl);
return qrCodeUrl;
}
/**
* <pre>
* 换取二维码图片url地址
* @param ticket 二维码ticket
* @auther: cao_wencao
* @date: 2019/2/18 17:11
* </pre>
*/
public String qrCodePictureUrl(String ticket) throws WxErrorException {
String url = wxMpService.getQrcodeService().qrCodePictureUrl(ticket);
return url;
}
/**
* 处理 subscribe 类型的event
*
* @param map
* @return
*/
public String handleEventSubscribe(Map<String, String> map) {
String resXmlStr = getReturnMsgSubscribe(map);
return resXmlStr;
}
/**
* @Author Sum1Dream
* @Name getReturnMsgSubscribe
* @Description // 处理文本
* @Date 16:34 2022/9/21
* @Param [decryptMap]
* @Return java.lang.String
*/
public String getReturnMsgSubscribe(Map<String, String> decryptMap) {
TextMessage textMessage = new TextMessage();
textMessage.setToUserName(decryptMap.get("FromUserName"));
textMessage.setFromUserName(decryptMap.get("ToUserName"));
textMessage.setCreateTime(System.currentTimeMillis());
textMessage.setMsgType("text");
textMessage.setContent(decryptMap.get("content"));
return getXmlString(textMessage);
}
/**
* @Author Sum1Dream
* @Name getXmlString
* @Description // 处理xml文件
* @Date 16:34 2022/9/21
* @Param [textMessage]
* @Return java.lang.String
*/
public String getXmlString(TextMessage textMessage) {
String xml = "";
if (textMessage != null) {
xml = "<xml>";
xml += "<ToUserName><![CDATA[";
xml += textMessage.getToUserName();
xml += "]]></ToUserName>";
xml += "<FromUserName><![CDATA[";
xml += textMessage.getFromUserName();
xml += "]]></FromUserName>";
xml += "<CreateTime>";
xml += textMessage.getCreateTime();
xml += "</CreateTime>";
xml += "<MsgType><![CDATA[";
xml += textMessage.getMsgType();
xml += "]]></MsgType>";
xml += "<Content><![CDATA[";
xml += textMessage.getContent();
xml += "]]></Content>";
xml += "</xml>";
}
return xml;
}
/**
* @Author Sum1Dream
* @Name paramPars
* @Description // 微信二维码参数解析
* @Date 13:50 2022/9/22
* @Param [param]
* @Return com.alibaba.fastjson.JSONObject
*/
public JSONObject paramPars(String param) {
String[] paramArray = param.split("&");
JSONObject object = new JSONObject();
for (String s : paramArray) {
String[] array = s.split("=");
object.put(array[0] , array[1]);
}
return object;
}
/**
* @Author Sum1Dream
* @Name downloadQrCode
* @Description // 下载微信二维码到本地
* @Date 15:03 2023/3/8
* @Param [wxQrUrl]
* @Return java.lang.String
*/
public String downloadQrCode(String wxQrUrl) throws Exception {
//定义一个URL对象,就是你想下载的图片的URL地址
URL urld = new URL(wxQrUrl);
//打开连接
HttpURLConnection conn = (HttpURLConnection) urld.openConnection();
//设置请求方式为"GET"
conn.setRequestMethod("GET");
//超时响应时间为10秒
conn.setConnectTimeout(10 * 1000);
//通过输入流获取图片数据
InputStream is = conn.getInputStream();
//得到图片的二进制数据,以二进制封装得到数据,具有通用性
byte[] data = readInputStream(is);
//创建一个文件对象用来保存图片,默认保存当前工程根目录
String downloadQrCodeImgUrl = CommonSysConst.getSysConfig().getFileUrl() + "/downloadQrCodeImg.jpg";
File imageFile = new File(downloadQrCodeImgUrl);
//创建输出流
FileOutputStream outStream = new FileOutputStream(imageFile);
//写入数据
outStream.write(data);
//关闭输出流,释放资源
outStream.close();
return downloadQrCodeImgUrl;
}
/**
* @Author Sum1Dream
* @Name decoderQRCode
* @Description // 解析二维码内容
* @Date 15:06 2023/3/8
* @Param [downloadQrCodeImgUrl]
* @Return java.lang.String
*/
public String decoderQRCode(String downloadQrCodeImgUrl) throws Exception {
BufferedImage image;
image = ImageIO.read(new File(downloadQrCodeImgUrl));
if (image == null) {
return null;
}
BufferedImageLuminanceSource source = new BufferedImageLuminanceSource(image);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
Result result;
Hashtable hints = new Hashtable();
hints.put(DecodeHintType.CHARACTER_SET, CHARSET);
QRCodeReader reader = new QRCodeReader();
result = reader.decode(bitmap, hints);
return result.getText();
}
/**
* @Author Sum1Dream
* @Name readInputStream
* @Description // 读取插入内容
* @Date 15:03 2023/3/8
* @Param [inStream]
* @Return byte[]
*/
public static byte[] readInputStream(InputStream inStream) throws Exception {
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
//创建一个Buffer字符串
byte[] buffer = new byte[6024];
//每次读取的字符串长度,如果为-1,代表全部读取完毕
int len;
//使用一个输入流从buffer里把数据读取出来
while ((len = inStream.read(buffer)) != -1) {
//用输出流往buffer里写入数据,中间参数代表从哪个位置开始读,len代表读取的长度
outStream.write(buffer, 0, len);
}
//关闭输入流
inStream.close();
//把outStream里的数据写入内存
return outStream.toByteArray();
}
public String qrCodeImgUrl(String type , String code , String encryptType) throws Exception {
// 组装 二维码参数
String sceneId = "type=" + type + "&code=" + code + "&encryptType=" + encryptType;
// 获取二维码参数
JSONObject wxQr = createWxQrCode(sceneId);
return wxQr.getString("url");
}
public String qrCodeImgUrl(String type , String code) throws Exception {
// 组装 二维码参数
String sceneId = "type=" + type + "&code=" + code;
// 获取二维码参数
JSONObject wxQr = createWxQrCode(sceneId);
return wxQr.getString("url");
}
}