一、必須 需要前端傳入的數據:
template_id
form_id
openid(或者userid:通過userid獲取已經存入數據庫中的用戶openid)
我這里根據自己的一些業務創建了兩個入參實體:
1、
/**
* 說明:
*
* @author panhh
* @date 2019/7/18 10:32
*/
@Data
public class MsgPushRequest {
/**
* 用戶id :用戶查詢活用的openid
*/
@ApiModelProperty(value = "用戶id")
@NotEmpty(message = "userId不能為空")
private Long userId;
/**
* form_id 前端
*/
@ApiModelProperty(value = "必須的請求參數")
@NotEmpty(message = "formId不能為空")
private String formId;
/**
* 模板id 前台
*/
@ApiModelProperty(value = "template_id")
@NotEmpty(message = "templateId不能為空")
private String templateId;
/**
* 判斷要推送的消息是推送給用戶還是給商戶
* 1:對用戶 ;2:對商家
*/
@ApiModelProperty(value = "推送的消息面對商戶還是用戶")
@NotNull(message = "mark不能為空")
private Integer mark;
}
2、
/**
* 說明:
*
* @author panhh
* @date 2019/7/18 15:23
*/
@Data
public class OrderMsgRequest implements Serializable {
/**
* 訂單編號
*/
@ApiModelProperty(value = "訂單編號")
@NotEmpty(message = "訂單編號不能為空")
private String orderId;
/**
* 取餐時間
*/
@ApiModelProperty(value = "取餐時間")
@NotEmpty(message = "取餐時間不能為空")
private String eatTime;
/**
* 就餐類型
*/
@ApiModelProperty(value = "就餐類型")
@NotEmpty(message = "就餐類型不能為空")
private String eatStatus;
/**
* 下單時間
*/
@ApiModelProperty(value = "下單時間")
@NotEmpty(message = "下單時間不能為空")
private String orderCreateTime;
/**
* 取餐碼
*/
@ApiModelProperty(value = "取餐碼")
@NotEmpty(message = "取餐碼不能為空")
private String diningCode;
/**
* 溫馨提示
*/
@ApiModelProperty(value = "溫馨提示")
@NotEmpty(message = "'溫馨提示'不能為空")
private String tips;
/**
* 商戶名稱,給用戶推送消息需要,商戶則不需要
* 1:對用戶 ;2:對商家
*/
@ApiModelProperty(value = "商戶名稱,給用戶推送消息需要,商戶則不需要")
private String shopName ;
}
二、定義接口
/**
* 說明:消息推送相關接口
*
* @author panhh
* @date 2019/7/18 10:27
*/
@RestController
@Api(value = "message",description = "消息推送相關接口")
@RequestMapping("/msg/")
public class MsgController {
@Autowired
private MsgService msgService;
/**
* 向用戶推送消息
* @param msgPushRequest
* @return
*/
@PostMapping("/pushMessage")
public ResultVo msgPush2User(MsgPushRequest msgPushRequest, OrderMsgRequest orderMsgRequest){
System.out.println("msgPushRequest:"+msgPushRequest);
System.out.println("orderMsgRequest:"+orderMsgRequest);
String returnBody = msgService.msgPush2User(msgPushRequest, orderMsgRequest);
JSONObject bodyJson = JSONObject.parseObject(returnBody);
Set<String> keySet = bodyJson.keySet();
for (String key : keySet) {
if ("errcode".equals(key)){
return Result.error(ExceptionMsg.FAILED,returnBody);
}
}
return Result.success(returnBody);
}
}
三、業務層:
/**
* 說明:
*
* @author panhh
* @date 2019/7/18 10:29
*/
@Service
public class MsgService {
@Autowired
private RestTemplate restTemplate;
@Autowired
private IdWorkerUtils idWorkerUtils;
@Autowired
private MsgMapper msgMapper;
@Value("${message.appid}")
private String appid;
@Value("${message.appSecret}")
private String appSecret;
private int unique1 = 7;
private String accessToken;
/**
* 向用戶推送消息
* @param msgPushRequest
*/
public String msgPush2User(MsgPushRequest msgPushRequest, OrderMsgRequest orderMsgRequest) {
AccessTokenEntity accessTokenEntity = new AccessTokenEntity();
// 1、通過用戶id查詢用戶的openid
String openid = "testOpenId";
//2、從數據庫中獲取access_token,並判斷是否失效,失效的話重新獲取
//2.1、從數據庫中查詢並判斷
accessTokenEntity.setUnique1(unique1);
accessTokenEntity = this.msgMapper.getAccessToken(accessTokenEntity);
System.out.println("accessTokenEntity--->"+accessTokenEntity);
if (accessTokenEntity == null){
//為null-->獲取后添加
System.out.println("為null~~~~~~");
String accessTokenJson = getAccessToken();
//解析
JSONObject jsonObject = JSONObject.parseObject(accessTokenJson);
accessToken = (String) jsonObject.get("access_token");
Integer expiresIn = (Integer) jsonObject.get("expires_in");
System.out.println("access_token:"+accessToken);
System.out.println("expires_in:"+expiresIn);
//進行添加
saveAccessToken(accessToken, expiresIn);
}else {
//不為null-->則判斷是否過期
Long expiresTime = Long.valueOf(accessTokenEntity.getExpiresTime());
System.out.println("expiresTime---"+expiresTime);
long nowTime = System.currentTimeMillis();
System.out.println("nowTime---"+nowTime);
if (nowTime > expiresTime){
//已失效,重新獲取,然后更新
System.out.println("不為null 但~過期!~~~~~~");
String accessTokenJson = getAccessToken();
JSONObject jsonObject = JSONObject.parseObject(accessTokenJson);
accessToken = (String) jsonObject.get("access_token");
Integer expiresIn = (Integer) jsonObject.get("expires_in");
//更新
expiresTime = System.currentTimeMillis()+expiresIn;
accessTokenEntity.setExpiresTime(expiresTime+"");
accessTokenEntity.setAccessToken(accessToken);
//執行更新
if (this.msgMapper.updateAccessToken(accessTokenEntity) < 1){
throw new GlobalException(ExceptionMsg.FAILED);
};
}
}
//拼接url,和設置推送消息
WxmsgPushVo wxmsgPushVo = new WxmsgPushVo();
wxmsgPushVo.setTouser(openid);
wxmsgPushVo.setForm_id(msgPushRequest.getFormId());;
wxmsgPushVo.setTemplate_id(msgPushRequest.getTemplateId());
//封裝miniprogram對象
Miniprogram miniprogram = new Miniprogram();
miniprogram.setAppid(appid);
wxmsgPushVo.setMiniprogram(miniprogram);
//封裝data,需要判斷本條消息是給用戶還是給商戶 mark--> 1:對用戶;2:對商家
HashMap<String, TemplateData> map = new HashMap<>();
if (msgPushRequest.getMark() == 2){
//訂單號
TemplateData keyword1 = new TemplateData(orderMsgRequest.getOrderId());
map.put("keyword1",keyword1);
//就餐時間
TemplateData keyword2 = new TemplateData(orderMsgRequest.getEatTime());
map.put("keyword2",keyword2);
//就餐類型
TemplateData keyword3 = new TemplateData(orderMsgRequest.getEatStatus());
map.put("keyword3",keyword3);
//下單時間
TemplateData keyword4 = new TemplateData(orderMsgRequest.getOrderCreateTime());
map.put("keyword4",keyword4);
//取餐碼
TemplateData keyword5 = new TemplateData(orderMsgRequest.getDiningCode());
map.put("keyword5",keyword5);
//溫馨提示
TemplateData keyword6 = new TemplateData(orderMsgRequest.getTips());
map.put("keyword6",keyword6);
}else {
//取餐號
TemplateData keyword1 = new TemplateData(orderMsgRequest.getDiningCode());
map.put("keyword1",keyword1);
//門店名稱
TemplateData keyword2 = new TemplateData(orderMsgRequest.getShopName());
map.put("keyword2",keyword2);
//下單時間
TemplateData keyword3 = new TemplateData(orderMsgRequest.getOrderCreateTime());
map.put("keyword3",keyword3);
//溫馨提示 tips
TemplateData keyword4 = new TemplateData(orderMsgRequest.getTips());
map.put("keyword4",keyword4);
}
//setData
wxmsgPushVo.setData(map);
Object wxVoJson = JSONObject.toJSON(wxmsgPushVo);
System.out.println("wxVoJson--"+wxVoJson);
//發起請求
String pushUrl = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token="+accessToken;
System.out.println("pushUrl---"+pushUrl);
//返回值為推送結果
ResponseEntity<String> entity = restTemplate.postForEntity(pushUrl, wxVoJson, String.class);
String body = entity.getBody();
System.out.println("body---"+body);
return body;
}
/**
* 保存accessToken
* @param accessToken
* @param expiresIn
*/
private void saveAccessToken(String accessToken, Integer expiresIn) {
long id = idWorkerUtils.nextId();
long expiresTime = System.currentTimeMillis()+expiresIn * 1000 - 600 * 1000;
AccessTokenEntity accessTokenEntitySave = new AccessTokenEntity();
accessTokenEntitySave.setId(id);
accessTokenEntitySave.setAccessToken(accessToken);
accessTokenEntitySave.setExpiresTime(expiresTime+"");
accessTokenEntitySave.setUnique1(unique1);
//執行保存
if (msgMapper.saveAccessToken(accessTokenEntitySave) < 1){
throw new GlobalException(ExceptionMsg.FAILED);
};
}
/**
* 請求獲取accessToken
* @return
*/
private String getAccessToken() {
String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+appid+"&secret="+appSecret;
System.out.println("獲取access_token的url---"+url);
return restTemplate.getForObject(url, String.class);
}
}
四、通過appid和appSecret可以獲取accessToken,直接定義了一個方法
五、去除我自己的業務 ,簡要的步驟說明:1、通過appid和Appsecret發起請求獲取accessToken,2、設置模板的值;3、使用accessToken拼接請求鏈接,攜帶參數發起請求完成推送;4、處理推送的返回值。
六、最后說明,通過appid和appSecret可以獲取accessToken,然后拼接消息推送的url,然后發送請求就可以了。這里setData 的keyword1這些多少個是取決於你小程序選用的模板,我期中的mark判斷是判斷是給用戶還是給商家推送消息,因為這兩個消息模板不一樣;另外,我獲取的accessToken是存入數據庫的,第一次獲取會添加,后續獲取會直接查詢數據庫,但是要判斷是否過期,過期時間是微信訂的7200秒,業務就這樣,上面的每一步的注釋都比較清楚的。
希望你不忘初心,保持努力,掌握自己我命運!
