訂單狀態從「支付成功」變更為「已發貨」時,需異步推送微信模板消息給用戶,避免阻塞主線程影響響應速度。
@RequestMapping("order/updateOrder.do")
public String updateOrder(HttpServletRequest request, HttpServletResponse response) {
// ... 參數獲取與訂單更新 ...
try {
shopService.updateOrder(order);
if (Integer.parseInt(stats) == 3) { // 已發貨
// 匿名內部類啟動新線程
new Thread(() -> {
message.sendWxMessage(openId, tranNum, logisticCompany, logisticNum);
}).start();
}
} catch (Exception e) { e.printStackTrace(); }
return "redirect:/order/orderlist.do?currPage=1";
}
public interface Message {
void sendWxMessage(String openId, String tranNum, String logisticCompany, String logisticNum);
}
@Service("Message")
public class MessageImpl implements Message {
@Override
public void sendWxMessage(String openId, String tranNum, String logisticCompany, String logisticNum) {
// 1. 組裝模板消息 JSON
JSONObject params = JSONObject.fromObject(MsgTemplateBean.getMsgTemplateBean(tranNum, logisticCompany, logisticNum));
params.put("touser", openId);
// 2. 獲取 access_token
String token = getAccessToken();
if (token == null) {
Loger.logtxt("WxMessage", "獲取 access_token 失敗");
return;
}
// 3. 發送 POST 請求
String url = Constant.SEND_MESSAGE_URL + "?access_token=" + token;
String result = ConnectionUrlUtil.sendPost(url, params.toString());
// 4. 解析結果
JSONObject resp = JSONObject.fromObject(result);
if (resp.getInt("errcode") == 0) {
Loger.logtxt("WxMessage", "發送成功: " + params);
} else {
Loger.logtxt("WxMessage", "發送失敗: " + params + " 原因: " + resp.get("errmsg"));
}
}
private String getAccessToken() {
String url = Constant.TOKEN_URL + "?grant_type=client_credential&appid=" + Constant.APP_ID + "&secret=" + Constant.APP_SECRET;
String json = ConnectionUrlUtil.sendPost(url, "");
if (Tools.isNotEmpty(json)) {
JSONObject obj = JSONObject.fromObject(json);
return obj.optString("access_token", null);
}
return null;
}
}
@Async + ThreadPoolTaskExecutor,避免頻繁創建銷毀線程。access_token 有效期 2 小時,應用 Redis 緩存並定時刷新,減少 HTTP 請求。