package com.ruoyi.common.weiXin; import cn.hutool.core.date.DateUtil; import cn.hutool.http.HttpUtil; import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; import com.ruoyi.common.core.redis.RedisCache; import com.ruoyi.common.utils.DateUtils; import com.ruoyi.common.utils.ImgUpload; import com.ruoyi.common.utils.http.HttpUtils; import com.ruoyi.common.weiXin.domain.WxMessageDto; import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Component; import org.springframework.web.client.RestTemplate; import java.io.BufferedInputStream; import java.io.PrintWriter; import java.net.HttpURLConnection; import java.net.URL; import java.util.*; import static java.util.concurrent.TimeUnit.SECONDS; /** * 微信授权工具类 */ @Component public class WeiXinUtils { //日志 private final Logger logger = LoggerFactory.getLogger(this.getClass()); @Autowired private RedisCache redisCache; /** * 获取openid与session_key * @param code * @return */ public JSONObject getWebAuthorizeInfo(String code){ try { String url = "https://api.weixin.qq.com/sns/jscode2session?" + "appid=" + WeiXinParamConfig.APP_ID + "&" + "secret=" + WeiXinParamConfig.APP_SECRET + "&" + "js_code=" + code + "&" + "grant_type=authorization_code"; String result = HttpUtils.sendGet(url); return JSONUtil.parseObj(result); } catch (Exception e) { e.printStackTrace(); } return null; } /** *获取access_token */ public String getToken(){ JSONObject jsonObject = new JSONObject(); String access_token = ""; Integer expires_in = 0;//有效期 try { if (redisCache.hasKey("xcx:access_token")){ return redisCache.getCacheObject("xcx:access_token").toString(); } String url = "https://api.weixin.qq.com/cgi-bin/token"; String result = HttpUtils.sendGet(url,"grant_type=client_credential&" + "appid="+WeiXinParamConfig.APP_ID+"&" + "secret="+WeiXinParamConfig.APP_SECRET); jsonObject = JSONUtil.parseObj(result); if (ObjectUtils.isNotEmpty(jsonObject)){ access_token = jsonObject.getStr("access_token"); expires_in = jsonObject.getInt("expires_in"); } redisCache.setCacheObject("xcx:access_token", access_token, expires_in, SECONDS); return access_token; }catch (Exception e){ e.printStackTrace(); return access_token; } } /** * 测试本地 获取接口调用凭证 * @return */ private String postTypeForAccessToken(){ String requestUrl = "https://api.weixin.qq.com/cgi-bin/stable_token"; cn.hutool.json.JSONObject body = JSONUtil.createObj(); body.put("grant_type","client_credential"); body.put("appid", WeiXinParamConfig.APP_ID); body.put("secret", WeiXinParamConfig.APP_SECRET); body.put("force_refresh",true); String result = HttpUtil.post(requestUrl,body.toString()); logger.info("{} 小程序获取access_token结果 -> {}", DateUtils.getTime(), result); return result; } /** 连接超时时间,默认10秒 */ private static int socketTimeout = 10000; // 传输超时时间,默认30秒 private static int connectTimeout = 30000; /** * 小程序订阅消息发送 * @param templateId 模板id * @param openId 接收者(用户)的 openid * @param data 模板内容 * @param page 跳转页面 * @return */ public int sendSubscribeMessage(String templateId, String openId, Map data, String page){ RestTemplate restTemplate = new RestTemplate(); //这里简单起见我们每次都获取最新的access_token(应该在access_token快过期时再重新获取) String url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=" + this.getToken(); //拼接推送的模版 WxMessageDto weiXinMessageDto = new WxMessageDto(); // 所需下发的订阅模板id weiXinMessageDto.setTemplate_id(templateId); // 点击模板卡片后的跳转页面 if (StringUtils.isNotBlank(page)){ weiXinMessageDto.setPage(page); } // 接收者(用户)的 openid weiXinMessageDto.setTouser(openId); // 模板内容 weiXinMessageDto.setData(data); weiXinMessageDto.setMiniprogram_state("formal"); System.out.println("========发送订阅消息内容====" + weiXinMessageDto.toString()); ResponseEntity responseEntity = restTemplate.postForEntity(url, weiXinMessageDto, String.class); String body = responseEntity.getBody(); logger.error("推送消息返回结果:" + body); com.alibaba.fastjson.JSONObject jsonObject = com.alibaba.fastjson.JSONObject.parseObject(body); if (ObjectUtils.isNotEmpty(jsonObject)){ String errcode = jsonObject.getString("errcode"); if (errcode.equals("0")){ return 0; } } return 1; } /** * 小程序录入发货信息 * @param paySn 支付单号(订单号) * @param openId 支付人openid * @return 结果 */ public String deliveryInfo(String paySn, String openId){ try { //获取token String accessToken = this.getToken(); String url = "https://api.weixin.qq.com/wxa/sec/order/upload_shipping_info?access_token=" + accessToken; // post参数 JSONObject jsonObject = new JSONObject(); HashMap orderKey = new HashMap<>(); orderKey.put("order_number_type" , 1); // 1.使用下单商户号和商户侧单号;枚举值2.使用微信支付单号 orderKey.put("mchid", "1671247339"); // 商户号 orderKey.put("out_trade_no", paySn); // 内部订单支付单号 jsonObject.put("order_key", orderKey); jsonObject.put("logistics_type", 2); // 1.物流配送,2.同城配送,3.虚拟商品,4.用户自提 jsonObject.put("delivery_mode", 1); // 1.同意发货,2.分拆发货 List> shippingList = new ArrayList<>(); // 物流信息 Map shipping = new HashMap<>(); // shipping.put("tracking_no", expressCode ); // 物流单号 // shipping.put("express_company", companyCode); // 物流公司编码 shipping.put("item_desc", "商品配送中"); // 商品信息描述 shippingList.add(shipping); // HashMap contact = new HashMap<>(); // //contact.put("consignor_contact"); // 寄件人电话 // contact.put("receiver_contact", receivePhone ); // 收件人电话 // shipping.put("contact", contact ); jsonObject.put("shipping_list", shippingList); jsonObject.put("upload_time", DateUtil.format(DateUtils.getNowDate(), "yyyy-MM-dd'T'HH:mm:ss.SSS'+08:00'")); HashMap payer = new HashMap<>(); payer.put("openid", openId); jsonObject.put("payer", payer); // 结果 String res = HttpUtil.createPost(url). body(jsonObject.toString()).execute().body(); com.alibaba.fastjson.JSONObject result = com.alibaba.fastjson.JSONObject.parseObject(res); logger.info("小程序发货信息录入结果: {}", res); if ("0".equals(result.getString("errcode"))){ return "SUCCESS"; }else{ return "FAIL"; } }catch (Exception e){ e.printStackTrace(); } return "FAIL"; } /** * 获取业务员小程序码 * * @param salesmanId 业务员ID * @param key key * @return 图片链接 */ public String getQRCode(String salesmanId, String key){ String qrCodeUrl = ""; try { //获取token String accessToken = this.getToken(); String codeUrl = "https://api.weixin.qq.com/wxa/getwxacode?access_token="+ accessToken; String path = WeiXinParamConfig.SALESMAN_BINDING_PATH+salesmanId; //post参数 JSONObject jsonObject = new JSONObject(); jsonObject.put("path", path); Map lineColor = new HashMap<>(); lineColor.put("r", 4); lineColor.put("g", 157); lineColor.put("b", 150); jsonObject.put("line_color", lineColor); jsonObject.put("env_version", "release");// 正式版为 "release",体验版为 "trial",开发版为 "develop" String params = jsonObject.toString(); URL url = new URL(codeUrl); HttpURLConnection httpUrlConnection = (HttpURLConnection) url.openConnection(); // 提交模式 httpUrlConnection.setRequestMethod("POST"); // 发送POST请求必须设置如下两行 httpUrlConnection.setDoOutput(true); httpUrlConnection.setDoInput(true); // 获取URLConnection对象对应的输出流 PrintWriter printWriter = new PrintWriter(httpUrlConnection.getOutputStream()); printWriter.write(params); printWriter.flush(); //获取数据 BufferedInputStream bis = new BufferedInputStream(httpUrlConnection.getInputStream()); //文件上传,返回小程序码url qrCodeUrl = new ImgUpload().upload(bis, key); } catch (Exception e) { e.printStackTrace(); } return qrCodeUrl; } }