xiaoyong931011
2023-07-27 f6c1f7b6bc16ed4829a6e85ea376b2fd2367c74d
src/main/java/cc/mrbird/febs/pay/util/WechatEventUtil.java
@@ -15,9 +15,7 @@
import org.dom4j.io.SAXReader;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.*;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
@@ -28,10 +26,11 @@
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.client.RestTemplate;
import java.io.InputStream;
import java.util.*;
import java.util.concurrent.TimeUnit;
/**
 * <pre>
@@ -46,6 +45,10 @@
    @Autowired
    private AgentProducer agentProducer;
    @Autowired
    RestTemplate restTemplate;
    private static Logger log = LoggerFactory.getLogger(WechatEventUtil.class);
@@ -92,7 +95,7 @@
        log.info("事件处理:event:{}、msgType:{}、toUserName:{}、fromUserName:{}", eventType, msgType, toUserName, fromUserName);
        if ("event".equals(msgType)) {
            if ("subscribe".equals(eventType)) {
                result = imgTextMsg(toUserName, fromUserName, "欢迎光临", "欢迎光临【药王谷铺子】,点击左下角【药王谷铺子】-【商城】,进入商城。", "图片地址", "点击后跳转的路径");
                result = imgTextMsg(toUserName, fromUserName, "欢迎光临", "欢迎光临【药王谷铺子】,点击左下角【药王谷铺子】-【商城】,进入商城。", "图片地址", "http://ywgouth.meiao.biz/");
                log.info("新增关注事件:toUserName{}、fromUserName{}", toUserName, fromUserName);
                StringBuffer stringBuffer = new StringBuffer();
                if(map.containsKey("EventKey")){
@@ -113,6 +116,21 @@
                agentProducer.sendMemberSubMsg(fromUserName);
            } else if ("unsubscribe".equals(eventType)) {
                log.info("取消关注事件:toUserName{}、fromUserName{}", toUserName, fromUserName);
            }else if ("SCAN".equals(eventType)) {
                log.info("扫码关注事件:toUserName{}、fromUserName{}", toUserName, fromUserName);
                if(map.containsKey("EventKey")){
                    StringBuffer stringBuffer = new StringBuffer();
                    /**
                     * 扫带参数二维码
                     */
                    String eventKey = map.get("EventKey");
                    if(StrUtil.isNotEmpty(eventKey)){
                        stringBuffer.append(eventKey);
                        stringBuffer.append("@");
                        stringBuffer.append(fromUserName);
                        agentProducer.sendMemberSubScanMsg(stringBuffer.toString());
                    }
                }
            }
        }
        return result;
@@ -236,16 +254,16 @@
     * @return
     */
    public String getTicket(String qrCodeParam) {
        RestTemplate restTemplate = new RestTemplate();
//        RestTemplate restTemplate = new RestTemplate();
        String ticket = null;
        // 拼接请求地址
        String CREATE_QRCODE_URL = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=TOKEN";
        String requestUrl = CREATE_QRCODE_URL.replace("TOKEN", "70_ECdQaX-QtNXZP9ugU_JEJGRYEADWrlQZNYrT2I2IRHsx6hx4_O8RY4VasWI97_ixia8vANTdnNRI_cT00toK7CX98513sQI8535eTFw3b-VQChEFZrRqTfNPdSoGYXgAIAVNM");
//        String requestUrl = CREATE_QRCODE_URL.replace("TOKEN", redisUtils.get(WechatConfigure.WX_ACCESS_TOKEN_REDIS_KEY).toString());
//        String requestUrl = CREATE_QRCODE_URL.replace("TOKEN", "70_ECdQaX-QtNXZP9ugU_JEJGRYEADWrlQZNYrT2I2IRHsx6hx4_O8RY4VasWI97_ixia8vANTdnNRI_cT00toK7CX98513sQI8535eTFw3b-VQChEFZrRqTfNPdSoGYXgAIAVNM");
        String requestUrl = CREATE_QRCODE_URL.replace("TOKEN", redisUtils.get(WechatConfigure.WX_ACCESS_TOKEN_REDIS_KEY).toString());
        // 创建临时带参二维码
        JSONObject jsonObject = restTemplate.postForObject(requestUrl,
                "{\"expire_seconds\": 604800, \"action_name\": \"QR_STR_SCENE\", \"action_info\": {\"scene\": {\"scene_str\": "+qrCodeParam+"}}}",
                "{\"expire_seconds\": 604800, \"action_name\": \"QR_LIMIT_STR_SCENE\", \"action_info\": {\"scene\": {\"scene_str\": "+qrCodeParam+"}}}",
                JSONObject.class);
//        JSONObject jsonObject = HttpsUtil.request(requestUrl, "POST", "{\"expire_seconds\": 604800, \"action_name\": \"QR_SCENE\", \"action_info\": {\"scene\": {\"scene_id\": 123}}}");
        if (ObjectUtil.isNotEmpty(jsonObject)) {
@@ -268,7 +286,7 @@
     * @return
     */
    //图片上传路径
    public  static  final String IMG_UPLOAD_PATH="/home/javaweb/webresource/ywg/wxcode";
    public  static  final String IMG_UPLOAD_PATH="/home/javaweb/webresource/ywg/h5/wxcode";
    public String getQRcode(String ticket) {
        String SHOW_QRCODE_URL = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=TICKET";
@@ -276,7 +294,7 @@
        String randomNum = MallUtils.getRandomNum(5);
        String imgName="/user_" + randomNum + "_acode_1.jpg";
        String urlPrefix="https://ywgpzapi.meiao.biz/ywg/wxcode";
        String urlPrefix="https://ywgouth.meiao.biz/wxcode";
        String imgPath=IMG_UPLOAD_PATH+imgName;
        if(!FileUtil.exist(imgPath)){
            try {
@@ -308,7 +326,157 @@
        return urlPrefix+"/"+imgName;
    }
//
//    String timestamp = String.format("%010d", System.currentTimeMillis() / 1000);
//
    public static String createSignature(String nocestr, String ticket, String timestamp, String url) {
        // 这里参数的顺序要按照 key 值 ASCII 码升序排序
        String s = "jsapi_ticket=" + ticket + "&noncestr=" + nocestr
                + "&timestamp=" + timestamp + "&url=" + url;
        return SHA1(s);
    }
//
    public static String SHA1(String decript) {
        try {
            MessageDigest digest = java.security.MessageDigest.getInstance("SHA-1");
            digest.update(decript.getBytes());
            byte messageDigest[] = digest.digest();
            // Create Hex String
            StringBuffer hexString = new StringBuffer();
            // 字节数组转换为 十六进制 数
            for (int i = 0; i < messageDigest.length; i++) {
                String shaHex = Integer.toHexString(messageDigest[i] & 0xFF);
                if (shaHex.length() < 2) {
                    hexString.append(0);
                }
                hexString.append(shaHex);
            }
            return hexString.toString();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return "";
    }
    public static void main(String[] args) {
    }
    //代码示例
    public Map<String, Object> ticket(String url) {
        String ticket = null;
        //从redis内获取  如果空说明第一次获取或已过期
        if(ObjectUtil.isEmpty(redisUtils.get("ticket"))){
            ticket = getTicket();
        }
        //生成10位时间戳
        String timestamp = String.format("%010d", System.currentTimeMillis() / 1000);
        String nonceStr = createNonceStr();
        String signature = createSignature(nonceStr, ticket, timestamp, url);
        Map<String, Object> map = new HashMap<>(16);
        map.put("timestamp", timestamp);
        map.put("nonceStr", nonceStr);
        map.put("signature", signature);
        return map;
    }
    private static final String str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
    public static String createNonceStr() {
        String nonceStr = "";
        for (int i = 0; i < 16; i++) {
            int beginIndex = (int) Math.round(Math.random() * 10);
            nonceStr += str.substring(beginIndex, beginIndex + 1);
        }
        return nonceStr;
    }
    /**
     *
     */
    private String getTicket() {
        //从redis 获取access_token
        String accessToken = redisUtils.get(WechatConfigure.WX_ACCESS_TOKEN_REDIS_KEY).toString();
        if (StrUtil.isBlank(accessToken)) {
            //获取access_token  自行实现
            return null;
        }
        //请求接口
        String url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket";
        Map<String, String> param = new HashMap<>(16);
        param.put("access_token", accessToken);
        param.put("type", "jsapi");
        String getAccessTokenUrl = url
                + "?access_token=" + accessToken
                + "&type=jsapi";
        JSONObject jsonObject = restTemplate.getForObject(getAccessTokenUrl, JSONObject.class);
        int errcode = jsonObject.getInteger("errcode");
        String errmsg = jsonObject.getString("errmsg");
        if (errcode == 0 && "ok".equals(errmsg)) {
            String ticket = jsonObject.getString("ticket");
            Integer expiresIn = jsonObject.getInteger("expires_in");
            redisUtils.set("ticket", ticket, expiresIn);
            return ticket;
        }
        return null;
    }
    /**
     *SHA1签名算法
     */
//    public static String SHA1(String decript) {
//        try {
//            MessageDigest digest = java.security.MessageDigest.getInstance("SHA-1");
//            digest.update(decript.getBytes());
//            byte messageDigest[] = digest.digest();
//            // Create Hex String
//            StringBuffer hexString = new StringBuffer();
//            // 字节数组转换为 十六进制 数
//            for (int i = 0; i < messageDigest.length; i++) {
//                String shaHex = Integer.toHexString(messageDigest[i] & 0xFF);
//                if (shaHex.length() < 2) {
//                    hexString.append(0);
//                }
//                hexString.append(shaHex);
//            }
//            return hexString.toString();
//
//        } catch (NoSuchAlgorithmException e) {
//            e.printStackTrace();
//        }
//        return "";
//    }
    /**
     * 生成签名
     *
     * @param data 待签名数据
     * @return 签名
     */
    public static String generateSignature(final Map<String, String> data) throws Exception {
        Set<String> keySet = data.keySet();
        String[] keyArray = keySet.toArray(new String[keySet.size()]);
        Arrays.sort(keyArray);
        StringBuilder sb = new StringBuilder();
        for (String k : keyArray) {
            String value = data.get(k).toString();
            if (k.equals("sign")) {
                continue;
            }
            if (value.trim().length() > 0) // 参数值为空,则不参与签名
            {
                sb.append(k).append("=").append(value.trim()).append("&");
            }
        }
        return sb.toString();
    }
}