WechatTemplate

/**
 * @description: 微信接口
 **/
@Component
@Slf4j
@RefreshScope
public class WeChatTemplate {

    @Value("${wx.appid:wxxxxxxcfaa}")
    private String appid;
    @Value("${wx.secret:2xxxx98fb5f1axxxx99c4xx0}")
    private String secret;
    @Value("${wx.message.templateId}")
    private String templateId;
    @Value("${wx.message.url}")
    private String url;

    @Autowired
    private RedisTemplate redisTemplate;

    public static final String ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token";
    public static final String USERS_URL = "https://api.weixin.qq.com/cgi-bin/user/get";
    public static final String MESSAGE_URL = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=";
    public static final String USER_INFO_URL = "https://api.weixin.qq.com/cgi-bin/user/info";
    public static final String OPRNID_URL = "https://api.weixin.qq.com/sns/oauth2/access_token";

    public static final String ACCESS_TOKEN_CACHE = "wx:token";

    public String getOpenId(String code) {
        Map<String, Object> params = new HashMap<>(8);
        params.put("appid", appid);
        params.put("secret", secret);
        params.put("code", code);
        params.put("grant_type", "authorization_code");
        String access = HttpUtil.get(OPRNID_URL, params);
        log.debug("wx access_token {}", access);
        return (String) JSON.parseObject(access).get("openid");
    }

    public String getAccessToken() {
        String token = (String) redisTemplate.opsForValue().get(ACCESS_TOKEN_CACHE);
        if (token != null) {
            return token;
        }
        String result = HttpUtil.get(ACCESS_TOKEN_URL, Map.of("grant_type", "client_credential",
                "appid", appid,
                "secret", secret));
        token = (String) JSON.parseObject(result).get("access_token");
        if (ObjectUtil.isNull(token)) {
            throw new FrameworkException(JSON.parseObject(result).get("errcode").toString());
        }
        redisTemplate.opsForValue().set(ACCESS_TOKEN_CACHE, token, Long.valueOf(JSON.parseObject(result).get("expires_in").toString()) - 10, TimeUnit.SECONDS);
        return token;
    }

    public WxUsers getWxUsers(String nextOpenId) {
        String accessToken = getAccessToken();
        Map<String, Object> param = Map.of("access_token", accessToken);
        if (StringUtils.isNotEmpty(nextOpenId)) {
            param.put("next_openid", nextOpenId);
        }
        String result = HttpUtil.get(USERS_URL, param);
        return JSON.parseObject(result, WxUsers.class);
    }

    public WxUserInfo getWxUserInfo(String openId) {
        String accessToken = getAccessToken();
        Map<String, Object> param = Map.of("access_token", accessToken, "openid", openId, "lang", "zh_CN");
        String result = HttpUtil.get(USER_INFO_URL, param);
        log.debug(result);
        return JSON.parseObject(result, WxUserInfo.class);
    }

    public void pushMessage(String openId, Map data) {
        String accessToken = getAccessToken();
        Map<String, Object> param = new HashMap<>();
        param.put("touser", openId);
        param.put("template_id", templateId);
        param.put("url", url + (String) data.get("id"));
        param.put("data", data);
        String result = HttpUtil.post(MESSAGE_URL + accessToken, JSON.toJSONString(param));
        log.debug(result);
    }

    @Async
    public void pushMessageAllUsers(Map data) {
        log.info("发送开播提醒开始!");
        WxUsers wxUsers = getWxUsers(null);
        List<String> openIds = wxUsers.getData().get("openid");
        if (StringUtils.isEmpty(wxUsers.getErrcode())) {
            int total = wxUsers.getTotal();
            String nextOpenId = wxUsers.getNextOpenid();
            if (total > 10000) {
                while (total > 10000) {
                    WxUsers users = getWxUsers(nextOpenId);
                    openIds.addAll(wxUsers.getData().get("openid"));
                    nextOpenId = users.getNextOpenid();
                    total = total - 10000;
                }
            }
        }
        if (CollectionUtils.isNotEmpty(openIds)) {
            openIds.parallelStream().forEach(openId -> {
                pushMessage(openId, data);
            });
        }
        log.info("发送开播提醒结束!");
    }

    public static final String TICKET_URL = "https://api.weixin.qq.com/cgi-bin/ticket/getticket";

    public Map jsSDKConfig(String webUrl) {
        String result = HttpUtil.get(TICKET_URL, Map.of("access_token", getAccessToken(), "type", "jsapi"));
        String ticket = (String) JSON.parseObject(result).get("ticket");
        Map<String, String> ret = new HashMap<String, String>();
        String nonceStr = createNonceStr();
        String timestamp = createTimestamp();
        String data;
        String signature = "";

        // 注意这里参数名必须全部小写,且必须有序
        data = "jsapi_ticket=" + ticket + "&noncestr=" + nonceStr + "&timestamp=" + timestamp + "&url=" + webUrl;
        try {
            MessageDigest crypt = MessageDigest.getInstance("SHA-1");
            crypt.reset();
            crypt.update(data.getBytes("UTF-8"));
            signature = byteToHex(crypt.digest());
        } catch (Exception e) {

        }
        ret.put("jsapi_ticket", ticket);
        ret.put("nonceStr", nonceStr);
        ret.put("timestamp", timestamp);
        ret.put("signature", signature);
        ret.put("appid", appid);
        return ret;
    }

    // 字节数组转换为十六进制字符串
    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;
    }

    // 生成随机字符串
    private static String createNonceStr() {
        return UUID.randomUUID().toString();
    }

    // 生成时间戳
    private static String createTimestamp() {
        return Long.toString(System.currentTimeMillis() / 1000);
    }

}

 

posted @ 2020-07-01 17:34  豆苗稀  阅读(243)  评论(0编辑  收藏  举报