package com.ads.common.handler; import cn.hutool.core.util.StrUtil; import cn.hutool.crypto.SecureUtil; import cn.hutool.http.HttpUtil; import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; import com.ads.common.constant.CodeConstant; import com.ads.common.constant.UrlConstant; import com.ads.common.enums.ErrCodeEnum; import com.ads.common.exception.BusinessException; import com.ads.common.exception.WechatApiErrException; import com.ads.common.util.FileUtil; import com.ads.common.util.RedisUtil; import com.ads.common.util.aes.AesException; import com.ads.common.util.aes.WXBizMsgCrypt; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; import org.springframework.web.multipart.MultipartFile; import javax.annotation.PostConstruct; import java.io.File; import java.io.IOException; import java.util.*; import static com.ads.common.util.CodecUtil.encryptMD5; /** * 微信接口 * * @author huzhihao * @date 2021-12-22 11:47 **/ @Slf4j @Configuration public class WeChatHandler { @Value("${app.appId}") String appId_; @Value("${app.appSecret}") String appSecret_; @Value("${app.token}") String token_; @Value("${app.encodingAESKey}") String encodingAesKey_; static String appId, appSecret, token, encodingAesKey; private volatile static WXBizMsgCrypt instance = null; /** * [初始化] * * @param * @return void * @author huzhihao * @date 2021/12/22 14:05 */ @PostConstruct public void init() { appId = appId_; appSecret = appSecret_; token = token_; encodingAesKey = encodingAesKey_; } /** * [获取WXBizMsgCrypt实例] * * @param * @return com.example.wechat_event_demo.qq.weixin.mp.aes.WXBizMsgCrypt * @author huzhihao * @date 2021/12/22 14:05 */ public static WXBizMsgCrypt getWXBizMsgCrypt() throws AesException { if (instance == null) { synchronized (WXBizMsgCrypt.class) { if (instance == null) { instance = new WXBizMsgCrypt(token, encodingAesKey, appId); } } } return instance; } /** * [校验] * * @param signature * @param timestamp * @param nonce * @param echostr * @return java.lang.String * @author huzhihao * @date 2021/12/27 14:02 */ public static String callbackValidate(String signature, String timestamp, String nonce, String echostr) { log.info(signature); List list = new ArrayList<>(); list.add(token); list.add(timestamp); list.add(nonce); Collections.sort(list); String str = ""; for (String s : list) { str += s; } String sha1Str = SecureUtil.sha1(str); if (Objects.equals(sha1Str, signature)) { return echostr; } return null; } /** * [解码] * * @param encrypt * @return java.lang.String * @author huzhihao * @date 2021/12/22 14:05 */ public static String decrypt(String encrypt) throws AesException { WXBizMsgCrypt wxBizMsgCrypt = WeChatHandler.getWXBizMsgCrypt(); return wxBizMsgCrypt.decrypt(encrypt); } /** * [缓存获取access_token] * * @return java.lang.String * @author huzhihao * @date 2021/12/22 15:40 */ public static String accessToken() { String accessToken = getAccessToken(); log.info("===>缓存获取access_token"+accessToken); return accessToken; } /** * [查询access_token] * * @return java.lang.String * @author huzhihao * @date 2021/12/22 15:52 */ static String getAccessToken() { String url = UrlConstant.URL_HSAY_OPEN; HashMap params = new HashMap<>(); String appCode ="HSAY_SHARE_COUPON"; Long timestamp = (new Date()).getTime(); String sign = encryptMD5(appCode + "hsay-wx-app-0302" + timestamp); params.put("timestamp",timestamp); params.put("appCode",appCode); params.put("sign",sign); String param = JSONUtil.toJsonStr(params); log.info("===>请求access_token"); try{ String res = HttpUtil.post(url, param); JSONObject jsonObject = JSONUtil.parseObj(res); if(jsonObject.getInt("code")==200){ log.info("===>请求access_token成功"); String data = jsonObject.getStr("data"); return JSONUtil.parseObj(data).getStr("accessToken"); }else{ throw new BusinessException("获取token失败:"+jsonObject.getStr("msg")); } } catch (Exception e){ throw new BusinessException("获取token失败"); } // String url = StrUtil.format( // UrlConstant.ACCESS_TOKEN, // appId, // appSecret // ); // String res = HttpUtil.get(url); // JSONObject jsonObject = JSONUtil.parseObj(res); // String accessToken = jsonObject.getStr(CodeConstant.WECHAT.ACCESS_TOKEN); // if (StrUtil.isBlank(accessToken)) { // String errCode = jsonObject.getStr(CodeConstant.WECHAT.ERR_CODE); // throw new RuntimeException("请求access_token失败!"); // } // log.info("===>请求access_token成功"); // return accessToken; } /** * [验证access_token] * * @param accessToken * @return java.lang.Boolean * @author huzhihao * @date 2021/12/22 15:53 */ static Boolean validateAccessToken(String accessToken) { if (StrUtil.isBlank(accessToken)) { return false; } String url = StrUtil.format( UrlConstant.IP_LIST, accessToken ); String res = HttpUtil.get(url); JSONObject jsonObject = JSONUtil.parseObj(res); String ipList = jsonObject.getStr(CodeConstant.WECHAT.IP_LIST); if (StrUtil.isNotBlank(ipList)) { return true; } return false; } /** * [通用get请求] * * @param url_ 请求地址 * @param resStr 返回中需要提取的字符串 * @return java.lang.String * @author huzhihao * @date 2021/12/22 14:52 */ public static String httpGetMethod(String url_, String resStr) { String access_token = (String) RedisUtil.get(CodeConstant.REDIS.ACCESS_TOKEN); return httpGetMethod(url_, access_token, resStr); } /** * [通用get请求] * * @param url_ 请求地址 * @param token_ access_token * @param resStr 返回中需要提取的字符串 * @return java.lang.String * @author huzhihao * @date 2021/12/22 14:52 */ public static String httpGetMethod(String url_, String token_, String resStr) { //装配新的url String url = StrUtil.format( url_, token_ ); //发送请求 log.info("===>通用get请求,url = {}", url); String res = HttpUtil.get(url); log.info("===>通用get请求,返回值 = {}", res); JSONObject jsonObject = JSONUtil.parseObj(res); String errCode = jsonObject.getStr(CodeConstant.WECHAT.ERR_CODE); String errMsg = jsonObject.getStr(CodeConstant.WECHAT.ERR_MSG); if (errCode != null && !ErrCodeEnum.OK.getCode().equals(errCode)) { if (StrUtil.isBlank(errMsg)) { errMsg = ErrCodeEnum.get(errCode); } throw new WechatApiErrException(errMsg); } return jsonObject.getStr(resStr); } /** * [通用post请求] * * @param url_ 请求地址 * @param param_ 请求参数 * @param clazz 接收返回的类 * @return java.lang.Object * @author huzhihao * @date 2021/12/22 14:54 */ public static Object httpPostMethod(String url_, Object param_, Class clazz) { String access_token = (String) RedisUtil.get(CodeConstant.REDIS.ACCESS_TOKEN); return httpPostMethod(url_, access_token, param_, clazz); } /** * [通用post请求] * * @param url_ 请求地址 * @param token_ access_token * @param param_ 请求参数 * @param clazz 接收返回的类 * @return java.lang.Object * @author huzhihao * @date 2021/12/22 14:54 */ public static Object httpPostMethod(String url_, String token_, Object param_, Class clazz) { //装配新的url String url = StrUtil.format( url_, token_ ); //发送请求 String res, param; if (param_ == null) { param = "{}"; } else { param = JSONUtil.toJsonStr(param_); } log.info("===>通用post请求,url = {},param = {}", url, param); res = HttpUtil.post(url, param); log.info("===>通用post请求,返回值 = {}", res); JSONObject jsonObject = JSONUtil.parseObj(res); String errCode = jsonObject.getStr(CodeConstant.WECHAT.ERR_CODE); String errMsg = jsonObject.getStr(CodeConstant.WECHAT.ERR_MSG); if (errCode != null && !ErrCodeEnum.OK.getCode().equals(errCode)) { if (StrUtil.isBlank(errMsg)) { errMsg = ErrCodeEnum.get(errCode); } throw new WechatApiErrException(errMsg); } //转换返回值为指定类型 return JSONUtil.toBean(jsonObject, clazz); } /** * [上传图片到微信获取链接地址] * * @param mfile * @return java.lang.String * @author huzhihao * @date 2021/12/24 16:15 */ public static String httpUpload(MultipartFile mfile) { log.info("===>上传图片到微信获取链接地址,{}", mfile); //装配新的url String url = StrUtil.format( UrlConstant.IMG_UPLOAD, accessToken() ); //构建参数 if (!FileUtil.checkFileSize(mfile.getSize(), 2, "M")) { throw new BusinessException("图片最大支持2MB"); } File file = FileUtil.multipartFileToFile(mfile); HashMap paramMap = new HashMap<>(); paramMap.put(CodeConstant.WECHAT.RESP_TYPE, CodeConstant.STRING.STR_1); paramMap.put(CodeConstant.WECHAT.UPLOAD_TYPE, CodeConstant.STRING.STR_0); Map files = new HashMap<>(); files.put("file", file); //发送请求 String res = null; try { res = FileUtil.uploadFile(url, null, paramMap, files); } catch (IOException e) { throw new WechatApiErrException("上传失败!"); } //获取返回值 JSONObject resJson = JSONUtil.parseObj(res); String errCode = resJson.getStr(CodeConstant.WECHAT.ERR_CODE); String errMsg = resJson.getStr(CodeConstant.WECHAT.ERR_MSG); if (errCode != null && !ErrCodeEnum.OK.getCode().equals(errCode)) { if (StrUtil.isBlank(errMsg)) { errMsg = ErrCodeEnum.get(errCode); } throw new WechatApiErrException(errMsg); } String imgInfo = resJson.getStr(CodeConstant.WECHAT.IMG_INFO); JSONObject imgInfoJson = JSONUtil.parseObj(imgInfo); return imgInfoJson.getStr(CodeConstant.WECHAT.TEMP_IMG_URL); } }