記錄一些與小程式相關的內容,例如登入,傳送訂閱訊息等
1. 登入相關
1.1. 獲取openid
/**
* code:由小程式生成
* appid:小程式id
* secret:金鑰
**/
public String getOpenid(String code) {
String data = "appid=" + appid + "&" +
"secret=" + secret + "&" +
"js_code=" + code + "&" +
"grant_type=" + "authorization_code";
JSONObject jsonObject = JSONObject.parseObject(HttpUtil.get("https://api.weixin.qq.com/sns/jscode2session?" + data));
return jsonObject.getString("openid");
}
1.2. 登入
這塊主要是獲取openid後,查詢是否存在與該openid繫結的賬號,有則呼叫登入,返回登入資訊,如果沒有,則直接註冊新使用者
1.3. 獲取手機號
手機號登入與openid直接登入相同,我這邊寫的是,先呼叫openid登入,如果當前使用者未註冊,則先不註冊,將openid存入redis,返回openidToken,前端調起手機號選擇,使用者選擇手機號後,呼叫手機號登入,將code與openidToken返回,後端獲取手機號就可以獲取到使用者手機號了,現在可以建立新使用者,存入openid與手機號
public String getPhone(String code) {
// 獲取token
String appletToken = String.valueOf(getAccessToken());
// 構建引數
Map<String,Object> paramMap = new HashMap<>();
paramMap.put("code",code);
String res = HttpRequest.post("https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=" + appletToken)
.header("Content-Type", "application/json").body(JSONUtils.toJSONString(paramMap)).execute().body();
return JSONObject.parseObject(res).getJSONObject("phone_info").getString("phoneNumber");
}
public String getAccessToken() {
String result;
if (redisUtil.hasKey("AppletToken")) {
return redisUtil.get("AppletToken").toString();
}
try {
String baseUrl = "https://api.weixin.qq.com/cgi-bin/token";
HashMap<String, Object> requestParam = new HashMap<>();
requestParam.put("grant_type", "client_credential");
// 小程式唯一憑證id appid
requestParam.put("appid", appid);
// 小程式 appSecret
requestParam.put("secret", secret);
// 傳送GET請求讀取呼叫微信介面獲取openid使用者唯一標識
result = HttpUtil.get(baseUrl, requestParam);
} catch (Exception e) {
throw new ServiceException(GENERATE_TOKEN_ERROR);
}
String token = JSON.parseObject(result).getString("access_token");
//將token存到redis,有效期100分鐘。官方介面返回的token有效期120分鐘
redisUtil.set("AppletToken", token, 100 * MyConstants.MINUTER);
return token;
}
2. 傳送訂閱訊息
2.1. 建立引數
public Map<String, Object> createParams(String name,String phone,String time,String reason){
Map<String, Object> objMap = new HashMap<>(5);
Map<String, String> map = new HashMap<>(1);
map.put("value", name);
objMap.put("thing1", map);
map = new HashMap<>(1);
map.put("value", phone);
objMap.put("phone_number7", map);
map = new HashMap<>(1);
map.put("value", time);
objMap.put("time2", map);
map = new HashMap<>(1);
map.put("value", reason);
objMap.put("thing11", map);
return objMap;
}
2.2. 傳送訂閱訊息
public void msgSend(String templateId, String page, Map<String, Object> data,String openId) {
try {
// getAccessToken()在上面有貼過,這裡就不貼了,直接呼叫
String accessToken = getAccessToken();
// region 推送小程式資訊
String msgUrl = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=" + accessToken;
// 請求引數處理
Map<String, Object> params = new HashMap<>(6);
// 目標使用者
params.put("touser", openId);
// 這個templateId需要在微信公眾號中建立模板,之後使用模板id傳送,與簡訊類似
params.put("template_id", templateId);
// page則為使用者收到訊息後點選訊息跳轉的頁面,例如/index
params.put("page", page);
params.put("lang", "zh_CN");
params.put("miniprogram_state", "formal");
// 模板引數,2.1呼叫生成後傳入當前方法
params.put("data", data);
String res = HttpRequest.post(msgUrl)
.header("Content-Type", "application/json")
// 這個toJSONString很關鍵
.body(JSONUtils.toJSONString(params)).execute().body();
JSONObject msgResultObject = JSONObject.parseObject(res);
if (!"0".equals(msgResultObject.get("errcode").toString())) {
throw new RuntimeException("傳送訂閱訊息失敗," + msgResultObject.get("errmsg"));
}
} catch (Exception e) {
throw new RuntimeException("傳送訂閱訊息失敗," + e);
}
}