医院的项目已经做好了,之前上级说最好要跟微信建联好,于是决定加入实时发送微信推送的功能,也就是发送微信模板信息的功能,感觉这个在以后也会经常用到这个功能,所以在这里写一下随笔,第一步,要先去微信开放平台把想要的模板信息挑选出来,这里我就不得不吐槽一句,找了半天没找到想要的,最好不得不挑了个沾得上边得的,好像是因为医院的随访,会诊这些功能国家都有规定,不能随便命名,所以微信模板消息也就比较少了。功能本身其实不复杂,但是我们的登录是只有医生在管理端添加进医院了,填写了准确的预留手机号,且分配了职位,才能够登录进小程序.而有一个功能板块是医生邀请其他医生进行会诊,亦或是患者邀请医生进行线下或者线上就诊,所以这不可避免地出现有可能有医生没有openId,发送不了模板信息。还有一个问题是,患者表和医生分别存储在client表与user表,所以前端在传的时候要定义好发送者与接收者的identity身份标识,加快查询效率。
第一步还是和以往一样,用serect与appid拿到该站点的token。
String wxAppId = "w*********************f";
String wxSecret = "8*********************a1";
String accessToken = getAccessToken(wxAppId, wxSecret);
private String getAccessToken(String appId, String appSecret) {
com.alibaba.fastjson.JSONObject params = new com.alibaba.fastjson.JSONObject();
params.put("grant_type", "client_credential");
params.put("appid", appId);
params.put("secret", appSecret);
params.put("force_refresh", false);
HttpResponse accessTokenResponse = HttpRequest.post("https://api.weixin.qq.com/cgi-bin/stable_token" ).body(params.toJSONString()).execute();
com.alibaba.fastjson.JSONObject tokenJson = JSON.parseObject(accessTokenResponse.body());
if(!tokenJson.containsKey("access_token")){
throw new CommonException("******* 微信获取accessToken的错误返回结果 {}", accessTokenResponse.body());
}
String token = tokenJson.get("access_token").toString();
int expiresIn = Integer.parseInt(tokenJson.get("expires_in").toString());
return token;
}
判断用户的身份,查不到openId,就不查了,抛出异常。
List<ClientUser> clientUserList = new ArrayList<>();
List<BizUser> bizUserList = new ArrayList<>();
if (messageInfo.getReceptionIndentity().equals("0")) {
QueryWrapper<ClientUser> queryWrapperUserList = new QueryWrapper<>();
queryWrapperUserList.lambda().eq(ClientUser::getId, messageInfo.getUserId());
clientUserList = clientUserService.list(queryWrapperUserList);
} else if (messageInfo.getReceptionIndentity().equals("1")) {
QueryWrapper<BizUser> queryWrapperUserList = new QueryWrapper<>();
queryWrapperUserList.lambda().eq(BizUser::getId, messageInfo.getUserId());
bizUserList = bizUserService.list(queryWrapperUserList);
}
JSONArray userJsonArray = new JSONArray();
if (!clientUserList.isEmpty()) {
for (ClientUser clientUser : clientUserList) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("userId", clientUser.getId());
jsonObject.put("userOpenId", clientUser.getOpenId());
userJsonArray.put(jsonObject);
}
} else if (!bizUserList.isEmpty()) {
for (BizUser bizUser : bizUserList) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("userId", bizUser.getId());
jsonObject.put("userOpenId", bizUser.getOpenId());
userJsonArray.put(jsonObject);
}
} else {
throw new CommonException("用户列表为空");
}
根据和前端协商好的,使用对应模板发送信息。
com.alibaba.fastjson.JSONObject data = new com.alibaba.fastjson.JSONObject();//模板数据data
//发送微信推送
//根据模板设置data数据
String templateId = "";
switch (messageInfo.getTemplatePurpose()) {
case "INVITE":
templateId = INVITE_TEMPLATE_ID;
constructInviteData(messageInfo, templateId, data);
break;
case "INVITED":
break;
case "INVITERESULT":
templateId = INVITE_TEMPLATE_RESULT_ID;
constructInviteResultData(messageInfo, templateId, data);
break;
case "INVITEDOCTOR":
templateId=INVITEDOCTOR;
constructInviteDoctor(messageInfo, templateId, data);
default:
throw new CommonException("模版参数有误");
}
String finalTemplateId = templateId;
userJsonArray.forEach(thirdUser -> {
this.sendTemplate(data, accessToken, finalTemplateId, ((cn.hutool.json.JSONObject) thirdUser).get("userOpenId").toString(), "/pages/mine/index");
});
完整实现
public void sendMessageToUser(List<MessageInfo> messageInfos) {
//
String wxAppId = "w89888888888888*********f";
String wxSecret = "8b5*****************************a1";
String accessToken = getAccessToken(wxAppId, wxSecret);
for (MessageInfo messageInfo : messageInfos) {
//发送微信推送
//判断接收者是患者还是医生
List<ClientUser> clientUserList = new ArrayList<>();
List<BizUser> bizUserList = new ArrayList<>();
if (messageInfo.getReceptionIndentity().equals("0")) {
QueryWrapper<ClientUser> queryWrapperUserList = new QueryWrapper<>();
queryWrapperUserList.lambda().eq(ClientUser::getId, messageInfo.getUserId());
clientUserList = clientUserService.list(queryWrapperUserList);
} else if (messageInfo.getReceptionIndentity().equals("1")) {
QueryWrapper<BizUser> queryWrapperUserList = new QueryWrapper<>();
queryWrapperUserList.lambda().eq(BizUser::getId, messageInfo.getUserId());
bizUserList = bizUserService.list(queryWrapperUserList);
}
JSONArray userJsonArray = new JSONArray();
if (!clientUserList.isEmpty()) {
for (ClientUser clientUser : clientUserList) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("userId", clientUser.getId());
jsonObject.put("userOpenId", clientUser.getOpenId());
userJsonArray.put(jsonObject);
}
} else if (!bizUserList.isEmpty()) {
for (BizUser bizUser : bizUserList) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("userId", bizUser.getId());
jsonObject.put("userOpenId", bizUser.getOpenId());
userJsonArray.put(jsonObject);
}
} else {
throw new CommonException("用户列表为空");
}
com.alibaba.fastjson.JSONObject data = new com.alibaba.fastjson.JSONObject();//模板数据data
//发送微信推送
//根据模板设置data数据
String templateId = "";
switch (messageInfo.getTemplatePurpose()) {
case "INVITE":
templateId = INVITE_TEMPLATE_ID;
constructInviteData(messageInfo, templateId, data);
break;
case "INVITED":
break;
case "INVITERESULT":
templateId = INVITE_TEMPLATE_RESULT_ID;
constructInviteResultData(messageInfo, templateId, data);
break;
case "INVITEDOCTOR":
templateId=INVITEDOCTOR;
constructInviteDoctor(messageInfo, templateId, data);
default:
throw new CommonException("模版参数有误");
}
String finalTemplateId = templateId;
userJsonArray.forEach(thirdUser -> {
this.sendTemplate(data, accessToken, finalTemplateId, ((cn.hutool.json.JSONObject) thirdUser).get("userOpenId").toString(), "/pages/mine/index");
});
}
}
相对应的三个模板信息
public void constructInviteDoctor(MessageInfo messageInfo, String templateId, com.alibaba.fastjson.JSONObject data){
com.alibaba.fastjson.JSONObject thing1 = new com.alibaba.fastjson.JSONObject();
thing1.put("value", messageInfo.getConsultationType());
com.alibaba.fastjson.JSONObject thing9 = new com.alibaba.fastjson.JSONObject();
thing9.put("value", messageInfo.getConsulationName());
com.alibaba.fastjson.JSONObject time8 = new com.alibaba.fastjson.JSONObject();
time8.put("value", messageInfo.getConsulationTime());
com.alibaba.fastjson.JSONObject thing5 = new com.alibaba.fastjson.JSONObject();
thing5.put("value", messageInfo.getConsulationLaunchName());
com.alibaba.fastjson.JSONObject thing6 = new com.alibaba.fastjson.JSONObject();
thing6.put("value", messageInfo.getConsulationRemark());
data.put("thing1", thing1);
data.put("thing9", thing9);
data.put("time8", time8);
data.put("thing5", thing5);
data.put("thing6", thing6);
}
public void constructInviteResultData(MessageInfo messageInfo, String templateId, com.alibaba.fastjson.JSONObject data){
com.alibaba.fastjson.JSONObject thing1 = new com.alibaba.fastjson.JSONObject();
thing1.put("value", messageInfo.getBookingName());
com.alibaba.fastjson.JSONObject thing2 = new com.alibaba.fastjson.JSONObject();
thing2.put("value", messageInfo.getBookingStatus());
com.alibaba.fastjson.JSONObject time3 = new com.alibaba.fastjson.JSONObject();
time3.put("value", messageInfo.getBookingTime());
com.alibaba.fastjson.JSONObject thing4 = new com.alibaba.fastjson.JSONObject();
thing4.put("value",messageInfo.getBookingName()+ messageInfo.getBookingRemark());//萧医生 /接受/拒绝 了您的线下邀请
data.put("thing1", thing1);
data.put("thing2", thing2);
data.put("time3", time3);
data.put("thing4", thing4);
}
public void constructInviteData(MessageInfo messageInfo, String templateId, com.alibaba.fastjson.JSONObject data) {
com.alibaba.fastjson.JSONObject thing1 = new com.alibaba.fastjson.JSONObject();
thing1.put("value", messageInfo.getBookingTitle());
com.alibaba.fastjson.JSONObject thing2 = new com.alibaba.fastjson.JSONObject();
thing2.put("value", "请及时应邀");
com.alibaba.fastjson.JSONObject thing3 = new com.alibaba.fastjson.JSONObject();
thing3.put("value", messageInfo.getBookingName());
com.alibaba.fastjson.JSONObject time5 = new com.alibaba.fastjson.JSONObject();
time5.put("value", messageInfo.getBookingTime());
com.alibaba.fastjson.JSONObject phone_number4 = new com.alibaba.fastjson.JSONObject();
phone_number4.put("value", messageInfo.getBookingPhone());
data.put("thing1", thing1);
data.put("thing2", thing2);
data.put("thing3", thing3);
data.put("time5", time5);
data.put("phone_number4", phone_number4);
}
最后的发送信息
private void sendTemplate(com.alibaba.fastjson.JSONObject data, String accessToken, String templateId, String toUser, String page) {
com.alibaba.fastjson.JSONObject params = new com.alibaba.fastjson.JSONObject();
params.put("template_id", templateId);
params.put("touser", toUser);
params.put("data", data);
params.put("page", page); //"/pages/mine/index"
params.put("miniprogram_state", "formal");
params.put("lang", "zh_CN");
String url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=" + accessToken;
String response = HttpUtil.post(url, params.toJSONString());
com.alibaba.fastjson.JSONObject res = JSON.parseObject(response);
log.warn("*** 微信发送消息返回结果:"+ response);
}
接下来是前端,微信每点击一次授权就可以多一次弹窗,次数可以累加,但是如果用户不点击接受,没有次数,就不会给用户发送模板信息,所以需要找地方将授权的弹窗放置,且必须是用户主动点击。所以可以找那种页面点击跳转的按钮进行微信模板信息的授权,调用wx.requestSubscribeMessage这个api,往tmplIds,push进ID就可以了。
handleToOnlineVisit(){
const param = encodeURIComponent(JSON.stringify(this.doctorDetailInfo));
const templateInviteId='JEY2J41VcFP_dqDwPyYKD_0jSRWxfjwrIwwq93aKkR8'
const templateInvitedId='BtzZZ7j-5j6na-6IwoM8i8EK1UH6VrHNycM0Ntbr45M'
const templateInviteResult='JRCTpv43CSdn7g7I_GU5aMepOxDj-6WtroPIYFAMNfo'
const templIdsArray=[]
if(templateInviteId) templIdsArray.push(templateInviteId)
if(templateInvitedId) templIdsArray.push(templateInvitedId)
if(templateInviteResult) templIdsArray.push(templateInviteResult)
if(templIdsArray.length>0){
wx.requestSubscribeMessage({
tmplIds:[...templIdsArray],
success(res){
uni.navigateTo({
url: '/pages/mine/onlineVisit/index?param=' + param
})
}})}else{
uni.navigateTo({
url: '/pages/mine/onlineVisit/index?param=' + param
})
}
}
授权完毕接下来就是发送了,在封装接口的时候param特意将其不封装为param对象,而是list数组,原因就是方便如果得给多个人发送消息,就不用调多次接口,而是服务端循环list数组就可以了。
const inviteDoctorArray = [];
const nowTime = getDate(0);
const launchDoctorName = getUserInfo().name;
currentDoctorIdArray.forEach((record, index) => {
let param = {
userId: record,
receptionIndentity: '1',
templatePurpose: 'INVITEDOCTOR',
consulationName: this.consultationName,
consultationType: '新的会诊',
consulationTime: nowTime,
consulationRemark: '您有新的会诊,请及时应邀',
consulationLaunchName: launchDoctorName
};
inviteDoctorArray.push(param);
});
await sendTemplateMessageToUser(currentDoctorIdArray);
最后收到消息的感觉别提多开心