Commit c8390918 authored by Menethil's avatar Menethil
Browse files

优化微信模版消息通知

parent 0aeb3678
......@@ -71,38 +71,40 @@ public class NotifyService {
}
/**
* 微信模版消息通知
* 微信模版消息通知,不跳转
* <p>
* 该方法会尝试从数据库获取缓存的FormId去发送消息
*
* @param touser 接收者openId
* @param formId 表单ID或者 prepayId
* @param notifyType 通知类别,通过该枚举值在配置文件中获取相应的模版ID
* @param params 通知模版内容里的参数,类似"您的验证码为{1}"中{1}的值
*/
@Async
public void notifyWxTemplate(String touser, String formId, NotifyType notifyType, String[] params) {
public void notifyWxTemplate(String touser, NotifyType notifyType, String[] params) {
if (wxTemplateSender == null)
return;
String templateId = getTemplateId(notifyType, wxTemplate);
wxTemplateSender.sendWechatMsg(touser, templateId, formId, "", "", params);
wxTemplateSender.sendWechatMsg(touser, templateId, params);
}
/**
* 微信模版消息通知
* 微信模版消息通知,带跳转
* <p>
* 该方法会尝试从数据库获取缓存的FormId去发送消息
*
* @param touser 接收者openId
* @param notifyType 通知类别,通过该枚举值在配置文件中获取相应的模版ID
* @param params 通知模版内容里的参数,类似"您的验证码为{1}"中{1}的值
* @param page 点击消息跳转的页面
*/
@Async
public void notifyWxTemplate(String touser, NotifyType notifyType, String[] params) {
public void notifyWxTemplate(String touser, NotifyType notifyType, String[] params, String page) {
if (wxTemplateSender == null)
return;
String templateId = getTemplateId(notifyType, wxTemplate);
wxTemplateSender.sendWechatMsg(touser, templateId, params);
wxTemplateSender.sendWechatMsg(touser, templateId, params, page);
}
/**
......@@ -135,57 +137,57 @@ public class NotifyService {
return null;
}
public MailSender getMailSender() {
return mailSender;
}
// public MailSender getMailSender() {
// return mailSender;
// }
public void setMailSender(MailSender mailSender) {
this.mailSender = mailSender;
}
public String getSendFrom() {
return sendFrom;
}
// public String getSendFrom() {
// return sendFrom;
// }
public void setSendFrom(String sendFrom) {
this.sendFrom = sendFrom;
}
public String getSendTo() {
return sendTo;
}
// public String getSendTo() {
// return sendTo;
// }
public void setSendTo(String sendTo) {
this.sendTo = sendTo;
}
public SmsSender getSmsSender() {
return smsSender;
}
// public SmsSender getSmsSender() {
// return smsSender;
// }
public void setSmsSender(SmsSender smsSender) {
this.smsSender = smsSender;
}
public List<Map<String, String>> getSmsTemplate() {
return smsTemplate;
}
// public List<Map<String, String>> getSmsTemplate() {
// return smsTemplate;
// }
public void setSmsTemplate(List<Map<String, String>> smsTemplate) {
this.smsTemplate = smsTemplate;
}
public WxTemplateSender getWxTemplateSender() {
return wxTemplateSender;
}
// public WxTemplateSender getWxTemplateSender() {
// return wxTemplateSender;
// }
public void setWxTemplateSender(WxTemplateSender wxTemplateSender) {
this.wxTemplateSender = wxTemplateSender;
}
public List<Map<String, String>> getWxTemplate() {
return wxTemplate;
}
// public List<Map<String, String>> getWxTemplate() {
// return wxTemplate;
// }
public void setWxTemplate(List<Map<String, String>> wxTemplate) {
this.wxTemplate = wxTemplate;
......
package org.linlinjava.litemall.core.notify;
import cn.binarywang.wx.miniapp.api.WxMaService;
import org.json.JSONObject;
import cn.binarywang.wx.miniapp.bean.WxMaTemplateMessage;
import me.chanjar.weixin.common.exception.WxErrorException;
import org.linlinjava.litemall.db.domain.LitemallUserFormid;
import org.linlinjava.litemall.db.service.LitemallUserFormIdService;
import org.springframework.beans.factory.annotation.Autowired;
import javax.net.ssl.*;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ConnectException;
import java.net.URL;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
/**
* 微信模版消息通知
......@@ -28,145 +21,57 @@ public class WxTemplateSender {
LitemallUserFormIdService formIdService;
/**
* 发送微信消息(模板消息)
* 发送微信消息(模板消息),不带跳转
*
* @param touser 用户 OpenID
* @param templatId 模板消息ID
* @param parms 详细内容
*/
public void sendWechatMsg(String touser, String templatId, String[] parms) {
LitemallUserFormid userFormid = formIdService.queryByOpenId(touser);
if (userFormid == null)
return;
sendWechatMsg(touser, templatId, userFormid.getFormid(), "", "", parms);
formIdService.delUserFormid(userFormid.getId());
sendMsg(touser, templatId, parms, "", "", "");
}
/**
* 发送微信消息(模板消息)
* 发送微信消息(模板消息),带跳转
*
* @param touser 用户 OpenID
* @param templatId 模板消息ID
* @param formId payId或者表单ID
* @param clickurl URL置空,则在发送后,点击模板消息会进入一个空白页面(ios),或无法点击(android)。
* @param topcolor 标题颜色
* @param parms 详细内容
* @return
* @param page 跳转页面
*/
public String sendWechatMsg(String touser, String templatId, String formId, String clickurl, String topcolor, String[] parms) {
try {
String tmpurl = "https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token=" + wxMaService.getAccessToken();
JSONObject json = new JSONObject();
json.put("touser", touser);
json.put("template_id", templatId);
json.put("form_id", formId);
json.put("url", clickurl);
json.put("topcolor", topcolor);
json.put("data", createParmData(parms));
JSONObject result = httpsRequest(tmpurl, "POST", json.toString());
// log.info("发送微信消息返回信息:" + resultJson.get("errcode"));
String errmsg = (String) result.get("errmsg");
if (!"ok".equals(errmsg)) { //如果为errmsg为ok,则代表发送成功,公众号推送信息给用户了。
return "error";
}
} catch (Exception e) {
e.printStackTrace();
return "error";
}
return "success";
public void sendWechatMsg(String touser, String templatId, String[] parms, String page) {
sendMsg(touser, templatId, parms, page, "", "");
}
/**
* 根据参数生成对应的 json 数据
*
* @param parms
* @return
*/
private JSONObject createParmData(String[] parms) {
JSONObject json = new JSONObject();
for (int i = 1; i <= parms.length; i++) {
JSONObject json2 = new JSONObject();
json2.put("value", parms[i - 1]);
private void sendMsg(String touser, String templatId, String[] parms, String page, String color, String emphasisKeyword) {
LitemallUserFormid userFormid = formIdService.queryByOpenId(touser);
if (userFormid == null)
return;
json.put("keyword" + i, json2);
}
return json;
}
WxMaTemplateMessage msg = new WxMaTemplateMessage();
msg.setTemplateId(templatId);
msg.setToUser(touser);
msg.setFormId(userFormid.getFormid());
msg.setPage(page);
msg.setColor(color);
msg.setEmphasisKeyword(emphasisKeyword);
msg.setData(createMsgData(parms));
/**
* 发送https请求
*
* @param requestUrl 请求地址
* @param requestMethod 请求方式(GET、POST)
* @param outputStr 提交的数据
* @return JSONObject(通过JSONObject.get ( key)的方式获取json对象的属性值)
*/
private JSONObject httpsRequest(String requestUrl, String requestMethod, String outputStr) {
JSONObject jsonObject = null;
try {
// 创建SSLContext对象,并使用我们指定的信任管理器初始化
TrustManager[] tm = {new MyX509TrustManager()};
SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
sslContext.init(null, tm, new SecureRandom());
// 从上述SSLContext对象中得到SSLSocketFactory对象
SSLSocketFactory ssf = sslContext.getSocketFactory();
URL url = new URL(requestUrl);
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
conn.setSSLSocketFactory(ssf);
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setUseCaches(false);
// 设置请求方式(GET/POST)
conn.setRequestMethod(requestMethod);
// 当outputStr不为null时向输出流写数据
if (null != outputStr) {
OutputStream outputStream = conn.getOutputStream();
// 注意编码格式
outputStream.write(outputStr.getBytes("UTF-8"));
outputStream.close();
}
// 从输入流读取返回内容
InputStream inputStream = conn.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String str = null;
StringBuffer buffer = new StringBuffer();
while ((str = bufferedReader.readLine()) != null) {
buffer.append(str);
}
// 释放资源
bufferedReader.close();
inputStreamReader.close();
inputStream.close();
inputStream = null;
conn.disconnect();
jsonObject = new JSONObject(buffer.toString());
} catch (ConnectException ce) {
// log.error("连接超时:{}", ce);
} catch (Exception e) {
// log.error("https请求异常:{}", e);
wxMaService.getMsgService().sendTemplateMsg(msg);
formIdService.updateUserFormId(userFormid);
} catch (WxErrorException e) {
e.printStackTrace();
}
return jsonObject;
}
/**
* 微信请求 - 信任管理器
*/
private class MyX509TrustManager implements X509TrustManager {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
private List<WxMaTemplateMessage.Data> createMsgData(String[] parms) {
List<WxMaTemplateMessage.Data> dataList = new ArrayList<>();
for (int i = 1; i <= parms.length; i++) {
dataList.add(new WxMaTemplateMessage.Data("keyword" + i, parms[i - 1]));
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
return dataList;
}
}
......@@ -22,9 +22,8 @@ public class WxTemplateTest {
@Test
public void testPaySucceed() {
String touser = "xx";
String formId = "";
String[] params = new String[]{"xxx"};
notifyService.notifyWxTemplate(touser, formId, NotifyType.PAY_SUCCEED, params);
notifyService.notifyWxTemplate(touser, NotifyType.PAY_SUCCEED, params);
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
......
......@@ -27,20 +27,26 @@ public class LitemallUserFormIdService {
}
/**
* 添加一个 FormId
* 更新或删除FormId
*
* @param userFormid
*/
public void addUserFormid(LitemallUserFormid userFormid) {
formidMapper.insertSelective(userFormid);
public void updateUserFormId(LitemallUserFormid userFormid) {
//更新或者删除缓存
if (userFormid.getIsprepay() && userFormid.getUseamount() > 1) {
userFormid.setUseamount(userFormid.getUseamount() - 1);
formidMapper.updateByPrimaryKey(userFormid);
} else {
formidMapper.deleteByPrimaryKey(userFormid.getId());
}
}
/**
* 删除一个 FormId
* 添加一个 FormId
*
* @param userFormidId
* @param userFormid
*/
public void delUserFormid(Integer userFormidId) {
formidMapper.deleteByPrimaryKey(userFormidId);
public void addUserFormid(LitemallUserFormid userFormid) {
formidMapper.insertSelective(userFormid);
}
}
......@@ -85,6 +85,9 @@ public class WxOrderController {
@Autowired
private NotifyService notifyService;
@Autowired
LitemallUserFormIdService formIdService;
public WxOrderController() {
}
......@@ -500,6 +503,18 @@ public class WxOrderController {
orderRequest.setSpbillCreateIp(IpUtil.getIpAddr(request));
result = wxPayService.createOrder(orderRequest);
//缓存prepayID用于后续模版通知
String prepayId = result.getPackageValue();
prepayId = prepayId.replace("prepay_id=", "");
LitemallUserFormid userFormid = new LitemallUserFormid();
userFormid.setOpenid(user.getWeixinOpenid());
userFormid.setFormid(prepayId);
userFormid.setIsprepay(true);
userFormid.setUseamount(3);
userFormid.setExpireTime(LocalDateTime.now().plusDays(7));
formIdService.addUserFormid(userFormid);
} catch (Exception e) {
e.printStackTrace();
return ResponseUtil.fail(403, "订单不能支付");
......@@ -563,6 +578,20 @@ public class WxOrderController {
*/
notifyService.notifySmsTemplateSync(order.getMobile(), NotifyType.PAY_SUCCEED, new String[]{orderSn.substring(8, 14)});
/**
* 请依据自己的模版消息配置更改参数
*/
String[] parms = new String[]{
order.getOrderSn(),
order.getOrderPrice().toString(),
order.getAddTime().toString(),
order.getMobile(),
order.getAddress(),
order.getConsignee()
};
notifyService.notifyWxTemplate(result.getOpenid(), NotifyType.PAY_SUCCEED, parms, "/pages/index/index?orderId=" + order.getId());
return WxPayNotifyResponse.success("处理成功!");
} catch (Exception e) {
logger.error("微信回调结果异常,异常原因 " + e.getMessage());
......
......@@ -40,6 +40,7 @@ public class WxUserFormId {
userFormid.setUseamount(1);
userFormid.setExpireTime(LocalDateTime.now().plusDays(7));
formIdService.addUserFormid(userFormid);
return ResponseUtil.ok();
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment