parent
ce74870900
commit
ef962770cb
@ -0,0 +1,28 @@ |
||||
package com.hfkj.common.utils; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
|
||||
/** |
||||
* @className: EasyExcelUtil |
||||
* @author: HuRui |
||||
* @date: 2023/3/10 |
||||
**/ |
||||
public class EasyExcelUtil { |
||||
|
||||
/** |
||||
* 生成头部 |
||||
* @param headList |
||||
* @return |
||||
*/ |
||||
public static List<List<String>> generationHead(List<String> headList) { |
||||
List<List<String>> list = new ArrayList<>(); |
||||
List<String> head; |
||||
for (String headStr : headList) { |
||||
head = new ArrayList<>(); |
||||
head.add(headStr); |
||||
list.add(head); |
||||
} |
||||
return list; |
||||
} |
||||
} |
@ -0,0 +1,53 @@ |
||||
package com.hfkj.config; |
||||
|
||||
/** |
||||
* @author sum1dream |
||||
*/ |
||||
public class TextMessage { |
||||
|
||||
private String toUserName; |
||||
private String fromUserName; |
||||
private String msgType; |
||||
private String content; |
||||
private Long createTime; |
||||
|
||||
public String getToUserName() { |
||||
return toUserName; |
||||
} |
||||
|
||||
public void setToUserName(String toUserName) { |
||||
this.toUserName = toUserName; |
||||
} |
||||
|
||||
public String getFromUserName() { |
||||
return fromUserName; |
||||
} |
||||
|
||||
public void setFromUserName(String fromUserName) { |
||||
this.fromUserName = fromUserName; |
||||
} |
||||
|
||||
public String getMsgType() { |
||||
return msgType; |
||||
} |
||||
|
||||
public void setMsgType(String msgType) { |
||||
this.msgType = msgType; |
||||
} |
||||
|
||||
public String getContent() { |
||||
return content; |
||||
} |
||||
|
||||
public void setContent(String content) { |
||||
this.content = content; |
||||
} |
||||
|
||||
public Long getCreateTime() { |
||||
return createTime; |
||||
} |
||||
|
||||
public void setCreateTime(Long createTime) { |
||||
this.createTime = createTime; |
||||
} |
||||
} |
@ -0,0 +1,358 @@ |
||||
package com.hfkj.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.hfkj.common.exception.ErrorCode; |
||||
import com.hfkj.common.exception.ErrorHelp; |
||||
import com.hfkj.common.exception.SysCode; |
||||
import com.hfkj.common.utils.HttpsUtils; |
||||
import com.hfkj.common.utils.RedisUtil; |
||||
import com.hfkj.sysenum.WeChatQrCodeActionNameEnum; |
||||
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.apache.commons.lang3.StringUtils; |
||||
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 token,String sceneStr , String actionName) { |
||||
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" , actionName); |
||||
object.put("expire_seconds" , 2592000); |
||||
object.put("action_info" , objectActionInfo); |
||||
return HttpsUtils.doPost("https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=" + token, object); |
||||
} |
||||
|
||||
|
||||
// 获取微信Token存入redis
|
||||
public String getWxToken() { |
||||
Object token = redisUtil.get("WxToken"); |
||||
if (null != token) { |
||||
return token.toString(); |
||||
}; |
||||
// 获取access_token
|
||||
Map<String, Object> params = new HashMap<>(); |
||||
params.put("appid", CommonSysConst.getSysConfig().getWechat_mp_appid()); |
||||
params.put("secret", CommonSysConst.getSysConfig().getWechat_mp_secret()); |
||||
params.put("grant_type", "client_credential"); |
||||
JSONObject accessTokenObject = HttpsUtils.doGet("https://api.weixin.qq.com/cgi-bin/token", params); |
||||
redisUtil.set("WxToken" , accessTokenObject.getString("access_token") , 7000); |
||||
return accessTokenObject.getString("access_token"); |
||||
} |
||||
|
||||
/** |
||||
* <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().getFile_url() + "/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(); |
||||
} |
||||
|
||||
/** |
||||
* 生成微信二维码链接 |
||||
* @param code 参数 |
||||
* @return |
||||
*/ |
||||
public String generateQrCodeImgUrl(String token,String code) { |
||||
// 组装 二维码参数
|
||||
String sceneId = "type=4&codeType=paymentCode&code=" + code; |
||||
// 获取二维码参数
|
||||
JSONObject response = createWxQrCode(token, sceneId , WeChatQrCodeActionNameEnum.actionName3.getName()); |
||||
if (StringUtils.isBlank(response.getString("url"))) { |
||||
throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "生成失败"); |
||||
} |
||||
return response.getString("url"); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,51 @@ |
||||
package com.hfkj.config; |
||||
|
||||
import me.chanjar.weixin.mp.api.WxMpService; |
||||
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl; |
||||
import me.chanjar.weixin.mp.config.WxMpConfigStorage; |
||||
import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl; |
||||
import org.springframework.context.annotation.Bean; |
||||
import org.springframework.context.annotation.Configuration; |
||||
|
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* @serviceName .java |
||||
* @author Sum1Dream |
||||
* @version 1.0.0 |
||||
* @Description //TODO
|
||||
* @createTime 16:24 2022/9/2 |
||||
**/ |
||||
@Configuration |
||||
public class WxMpConfig { |
||||
|
||||
/** |
||||
* 微信客户端配置存储 |
||||
* |
||||
* @return |
||||
*/ |
||||
@Bean |
||||
public WxMpConfigStorage wxMpConfigStorage() { |
||||
WxMpDefaultConfigImpl configStorage = new WxMpDefaultConfigImpl(); |
||||
// 公众号appId
|
||||
configStorage.setAppId(CommonSysConst.getSysConfig().getWechat_mp_appid()); |
||||
// 公众号appSecret
|
||||
configStorage.setSecret(CommonSysConst.getSysConfig().getWechat_mp_secret()); |
||||
return configStorage; |
||||
} |
||||
|
||||
/** |
||||
* @Author Sum1Dream |
||||
* @Name wxMpService |
||||
* @Description //TODO
|
||||
* @Date 16:24 2022/9/2 |
||||
* @Param [] |
||||
* @Return WxMpService |
||||
*/ |
||||
@Bean |
||||
public WxMpService wxMpService() { |
||||
WxMpService wxMpService = new WxMpServiceImpl(); |
||||
wxMpService.setWxMpConfigStorage(wxMpConfigStorage()); |
||||
return wxMpService; |
||||
} |
||||
} |
@ -0,0 +1,48 @@ |
||||
package com.hfkj.sysenum; |
||||
|
||||
/** |
||||
* 微信创建二维码 |
||||
*/ |
||||
public enum WeChatQrCodeActionNameEnum { |
||||
actionName0(0, "QR_SCENE" , "临时的整型参数值"), |
||||
actionName1(1, "QR_STR_SCENE" , "临时的字符串参数值"), |
||||
actionName2(2, "QR_LIMIT_SCENE" , "永久的整型参数值"), |
||||
actionName3(3, "QR_LIMIT_STR_SCENE" , "永久的字符串参数值"), |
||||
; |
||||
|
||||
private Integer number; |
||||
|
||||
private String name; |
||||
|
||||
private String actionInfo; |
||||
|
||||
WeChatQrCodeActionNameEnum(int number, String name , String actionInfo) { |
||||
this.number = number; |
||||
this.name = name; |
||||
this.actionInfo = actionInfo; |
||||
} |
||||
|
||||
public Integer getNumber() { |
||||
return number; |
||||
} |
||||
|
||||
public void setNumber(Integer number) { |
||||
this.number = number; |
||||
} |
||||
|
||||
public String getName() { |
||||
return name; |
||||
} |
||||
|
||||
public void setName(String name) { |
||||
this.name = name; |
||||
} |
||||
|
||||
public String getActionInfo() { |
||||
return actionInfo; |
||||
} |
||||
|
||||
public void setActionInfo(String actionInfo) { |
||||
this.actionInfo = actionInfo; |
||||
} |
||||
} |
Loading…
Reference in new issue