package com.leenleda.project.manager.common.utils;
import com.alibaba.fastjson.JSONObject;
import com.leenleda.project.manager.common.config.LeenledaConfig;
import com.leenleda.project.manager.common.dto.response.JsTicketResponseDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLDecoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Formatter;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
/**
* @author pengbenlei
* @company leenleda
* @date 2021/3/29 9:49
* @description
*/
@Component
public class WechatUtil {
private static final String JSTICKET_CACHE_KEY="leenleda:wechat:jsticket:cache";
private static final int JSTICKET_CACHE_TIME=6200;
@Autowired
RedisUtil redisUtil;
@Resource
LeenledaConfig leenledaConfig;
private String getAccessToken() {
String accessToken = (String) redisUtil.get(leenledaConfig.getWechatAppId());
if (StringUtils.isEmpty(accessToken)) {
// 获取缓存
String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + leenledaConfig.getWechatAppId() + "&secret=85e05903abd1e3772e85de160120dc2d";
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> response = restTemplate.getForEntity(url, String.class);
JSONObject jsonObject = JSONObject.parseObject(response.getBody());
accessToken = jsonObject.getString("access_token");
redisUtil.set(leenledaConfig.getWechatAppId(), accessToken, 7200, TimeUnit.SECONDS);
}
return accessToken;
}
/**
* 发送公众号模板消息
* @param templeteId
* @param pageUrl
* @param openId
* @param data
*/
public void sendTemplateMsg(String templeteId, String pageUrl, String openId, String data) {
String token = getAccessToken();
String url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/bizsend?access_token=" + token;
JSONObject jsonObject = new JSONObject();
jsonObject.put("access_token", token);
jsonObject.put("touser", openId);
jsonObject.put("template_id", templeteId);
jsonObject.put("page", pageUrl);
jsonObject.put("data", data);
String requestJsonStr = JSONObject.toJSONString(jsonObject);
connectWeiXinInterface(url, requestJsonStr);
}
/**
* 获取微信js配置
* @param url
* @return
*/
public JsTicketResponseDto getConfig(String url) {
try {
url= URLDecoder.decode(url,"GBK");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
String ticket = getJsapiTicket();
String timestamp = create_timestamp();
String nonceStr = create_nonce_str();
String string1 = "jsapi_ticket=" + ticket + "&noncestr=" + nonceStr + "×tamp=" + timestamp +
"&url=" + url;
String signature = "";
try {
MessageDigest crypt = MessageDigest.getInstance("SHA-1");
crypt.reset();
crypt.update(string1.getBytes("UTF-8")); // 对string1 字符串进行SHA-1加密处理
signature = byteToHex(crypt.digest()); // 对加密后字符串转成16进制
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
Assert.isTrue(!StringUtils.isEmpty(signature),"生成js签名出错!");
JsTicketResponseDto jsTicketResponseDto = new JsTicketResponseDto(leenledaConfig.getWechatAppId(), timestamp, nonceStr, signature);
return jsTicketResponseDto;
}
public String getJsapiTicket() {
String ticket = redisUtil.getStr(JSTICKET_CACHE_KEY);
if (!StringUtils.isEmpty(ticket)) {
return ticket.replace(""", "");
}
String token = getAccessToken();
String url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + token + "&type=jsapi";
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> response = restTemplate.getForEntity(url, String.class);
JSONObject jsonObject = JSONObject.parseObject(response.getBody());
ticket = jsonObject.getString("ticket");
Assert.isTrue(!StringUtils.isEmpty(ticket), "获取jsticket出错!");
redisUtil.set(JSTICKET_CACHE_KEY, ticket, JSTICKET_CACHE_TIME, TimeUnit.SECONDS);
return ticket;
}
// 生成时间戳字符串
public static String create_timestamp() {
return Long.toString(System.currentTimeMillis() / 1000);
}
// 生成随机字符串
public static String create_nonce_str() {
return UUID.randomUUID().toString();
}
private static String byteToHex(final byte[] hash) {
Formatter formatter = new Formatter();
for (byte b : hash) {
formatter.format("%02x", b);
}
String result = formatter.toString();
formatter.close();
return result;
}
public static void connectWeiXinInterface(String action, String json) {
URL url;
try {
url = new URL(action);
HttpURLConnection http = (HttpURLConnection) url.openConnection();
http.setRequestMethod("POST");
http.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded");
http.setDoOutput(true);
http.setDoInput(true);
System.setProperty("sun.net.client.defaultConnectTimeout", "30000");// 连接超时30秒
System.setProperty("sun.net.client.defaultReadTimeout", "30000"); // 读取超时30秒
http.connect();
OutputStream os = http.getOutputStream();
os.write(json.getBytes("UTF-8"));// 传入参数
InputStream is = http.getInputStream();
int size = is.available();
byte[] jsonBytes = new byte[size];
is.read(jsonBytes);
String result = new String(jsonBytes, "UTF-8");
os.flush();
os.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}