转载注明出处:www.xdxxdxxdx.com,或者加入java学习群学习讨论:481845043
有时候我们需要从服务端推送一些消息到用户的手机上,比如在用户购买完以后,我们发个消息告诉他购买成功,商家会尽快发货。如下图所示。
有几个需要注意的:
1.小程序的模板消息是发送到微信的服务通知里面的,而不像公众号的模板消息,是直接依附于公众号的。
2.小程序的消息模板需要下发条件,确切的说,需要是在提交表单完以后得到formid,或者在调起支付后得到prepayId。一个formid可以下发一条消息,一个prepayId可以下发三条消息。而微信公众号的模板消息不需要下发条件。
在小程序中加入模板消息很简单,只需要经过如下几步,现在我们以微信支付成功后的模板消息为例来介绍实现方法。
一.申请消息模板
直接在小程序后台--》模板消息---》添加。就可以选用想要的模板了,还可以在模板里自定义参数。很是方便。以下是我选定交易成功的模板。
二.获取formId或者prepayId
第二步就是获取prepayId,或者如果你是在提交表单以后想要发送模板消息,则需要获取formId。
要获取formId,首先要在form元素添加report-submit=true属性,如下所示。
<form bindsubmit="submitInfo" report-submit=\'true\' ></form>
|
然后在form表单提交事件中获取到formId,如下所示。
submitInfo: function (e) {
console.log(\'GG 敌方军团已同意投降 4票赞成 0票反对\')
console.log(e.detail.formId);
}, |
至于获取prepayId,需要涉及到微信支付接口,会有专门文章来介绍,这边就不再赘述了。
三.调用sendTemplateMessage接口下发消息
1.首先,我们写一个模块类,让各页面来调用,主要就是调用服务端发送模板消息的方法。
模块类:templateMethod.js
const app = getApp();const templateId = { tradeTplId: \'UNgCJILBU6UIkrUEwoxyJDpN_SffcEhrfXlBlcsF0ww\',
}const template = function (name) {
return templateId[name];
}const send = function (SESSION, templateId, xcxOpenId, emphasisKeyword, page, prepayId, msgData, color) {
const _this = this;
wx.request({
method: \'POST\',
url: app.domain + app.api.xcxTempleSendReq,
header: {
\'content-type\': app.globalData.postHeader,
\'Cookie\': \'JSESSIONID=\' + SESSION + \';SESSION=\' + SESSION
},
data: {
page: page,
templateId: templateId,
xcxOpenId: xcxOpenId,
emphasisKeyword: emphasisKeyword,
prepayId: prepayId,
msgData: msgData,
color: color
},
success: function (res) {
console.log(res);
},
fail: function (res) {
console.log(res)
}
})
}module.exports = { send: send,
template: template
} |
其实就是将sendTemplateMessage接口需要的各参数传递给服务端,让服务端去调用sendTemplateMessage接口。其中xcxTempleSendReq所对应的服务端代码如下。
public String xcxTempleSend() {
HttpServletRequest req = ServletActionContext.getRequest();
String openId = req.getParameter("xcxOpenId");
String templateId = req.getParameter("templateId");
String page = req.getParameter("page");
String sceneID = req.getParameter("prepayId");
String msgData = req.getParameter("msgData");
String color = req.getParameter("color");
String emphasisKeyword = req.getParameter("emphasisKeyword");
String result = wxService.xcxSendTemplate(openId, templateId, page,
sceneID, msgData, color, emphasisKeyword);
OutPutMsg.outPutMsg(result.toString());
return null;
}
|
xcxSendTemplate的代码如下:
public String xcxSendTemplate(String openId, String templateId, String page, String sceneID, String msgData, String color,
String emphasisKeyword) {
System.err.println("发送订单消息模板");
String access_token = "";
if (redisDao.get("xcx_access_token") != null) {
access_token = redisDao.get("xcx_access_token");
} else {
String tokenStr = CommonUtil
.getTokenByUrl(ConfigUtil.XCX_TOKEN_URL);
JSONObject tokeJson = JSONObject.fromObject(tokenStr);
access_token = tokeJson.getString("access_token");
}
String template = "https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token="
+ access_token + "&type=wx_card";
Map<String, String> pmMap = new HashMap<String, String>();
pmMap.put("touser", openId);
pmMap.put("template_id", templateId);
pmMap.put("page", page);
System.err.println(page);
pmMap.put("form_id", sceneID);
pmMap.put("data", "msgData");
pmMap.put("emphasis_keyword", emphasisKeyword);
pmMap.put("color", color);
String pmStr = JSON.toJSONString(pmMap).replaceAll("\"msgData\"",
msgData);
String sendResult = CommonUtil.httpsRequest(template, "POST", pmStr);
System.err.println(sendResult);
return sendResult;
}
|
我们这边的策略是从redis中去获取小程序的access_token。然后组装各参数,最后调用sendTemplateMessage接口以发送消息。
最后再看看页面如何调用模块类的方法来发送消息的吧。
首先,引入模块类
const templateMethod = require(app.resource.util.templateMethod); |
然后,封装好参数,直接调用templateMethod 暴露出来的send方法,如下:
templateMethod.send(_this.data.userInfo.SESSION, templateMethod.template(\'tradeTplId\'), _this.data.userInfo.wechatUser.xcxOpenId, \'keyword3.DATA\', pageUrl, payJson.package.split(\'=\')[1], _this.generateMsgData(), \'\');
|
其中templateMethod.template(\'tradeTplId\')同样是调用templateMethod 的template方法获取该交易成功模板的模板Id.emphasisKeyword 表示的是强调突出的参数,这边是keyword3.DATA,也就是第三个参数,表示支付金额。这个参数将会被放大放在显眼位置,如文章刚开始的图片所示。pageUrl是用户点击该模板消息通知需要跳转的页面。这边我们传递的参数是用户订单列表页。payJson.package.split(\'=\')[1]是获取到了prepayId,_this.generateMsgData()是组装模板内容的方法。其具体的实现如下。
generateMsgData: function () {
const _this = this;
const tips = \'本次支付采用微信支付方式并在小程序《逸品生活NNWN》上进行支付-点击打开小程序,查看订单!\';
const note = \'仅作通知提醒使用,不成为支付或报销之依据!\';
const msgData = {};
msgData.keyword1 = {
value: _this.data.orderIdArray.join(\'、\'),
color: \'#173177\'
}
msgData.keyword2 = {
value: _this.data.subject,
color: \'#173177\'
}
msgData.keyword3 = {
value: _this.data.total,
color: \'#173177\'
}
msgData.keyword4 = {
value: tips,
color: \'#173177\'
}
msgData.keyword5 = {
value: note,
color: \'#173177\'
}
return JSON.stringify(msgData)
}
|
自此,整个模板消息发送的要点都讲完了。
PS:
1.本文讲的方法对很多地方做了一些封装,所以看起来感觉很麻烦。比如采用redis存储access_token;在小程序端封装templateMethod模块方法,给其他页面调用;还有就是封装generateMsgData()方法来组装模板内容。读者只需要知道大概的流程就可以,至于如何去传参,是在客户端封装参数还是在服务端封装参数,可以自行决定。
2.获取到prepayId后,我们可将其存储起来,跟客户或者订单相关联,当订单发货的时候,再次使用这个prepayId进行发货通知。