Commit c8390918 authored by Menethil's avatar Menethil
Browse files

优化微信模版消息通知

parent 0aeb3678
...@@ -71,38 +71,40 @@ public class NotifyService { ...@@ -71,38 +71,40 @@ public class NotifyService {
} }
/** /**
* 微信模版消息通知 * 微信模版消息通知,不跳转
* <p>
* 该方法会尝试从数据库获取缓存的FormId去发送消息
* *
* @param touser 接收者openId * @param touser 接收者openId
* @param formId 表单ID或者 prepayId
* @param notifyType 通知类别,通过该枚举值在配置文件中获取相应的模版ID * @param notifyType 通知类别,通过该枚举值在配置文件中获取相应的模版ID
* @param params 通知模版内容里的参数,类似"您的验证码为{1}"中{1}的值 * @param params 通知模版内容里的参数,类似"您的验证码为{1}"中{1}的值
*/ */
@Async @Async
public void notifyWxTemplate(String touser, String formId, NotifyType notifyType, String[] params) { public void notifyWxTemplate(String touser, NotifyType notifyType, String[] params) {
if (wxTemplateSender == null) if (wxTemplateSender == null)
return; return;
String templateId = getTemplateId(notifyType, wxTemplate); String templateId = getTemplateId(notifyType, wxTemplate);
wxTemplateSender.sendWechatMsg(touser, templateId, formId, "", "", params); wxTemplateSender.sendWechatMsg(touser, templateId, params);
} }
/** /**
* 微信模版消息通知 * 微信模版消息通知,带跳转
* <p> * <p>
* 该方法会尝试从数据库获取缓存的FormId去发送消息 * 该方法会尝试从数据库获取缓存的FormId去发送消息
* *
* @param touser 接收者openId * @param touser 接收者openId
* @param notifyType 通知类别,通过该枚举值在配置文件中获取相应的模版ID * @param notifyType 通知类别,通过该枚举值在配置文件中获取相应的模版ID
* @param params 通知模版内容里的参数,类似"您的验证码为{1}"中{1}的值 * @param params 通知模版内容里的参数,类似"您的验证码为{1}"中{1}的值
* @param page 点击消息跳转的页面
*/ */
@Async @Async
public void notifyWxTemplate(String touser, NotifyType notifyType, String[] params) { public void notifyWxTemplate(String touser, NotifyType notifyType, String[] params, String page) {
if (wxTemplateSender == null) if (wxTemplateSender == null)
return; return;
String templateId = getTemplateId(notifyType, wxTemplate); String templateId = getTemplateId(notifyType, wxTemplate);
wxTemplateSender.sendWechatMsg(touser, templateId, params); wxTemplateSender.sendWechatMsg(touser, templateId, params, page);
} }
/** /**
...@@ -135,57 +137,57 @@ public class NotifyService { ...@@ -135,57 +137,57 @@ public class NotifyService {
return null; return null;
} }
public MailSender getMailSender() { // public MailSender getMailSender() {
return mailSender; // return mailSender;
} // }
public void setMailSender(MailSender mailSender) { public void setMailSender(MailSender mailSender) {
this.mailSender = mailSender; this.mailSender = mailSender;
} }
public String getSendFrom() { // public String getSendFrom() {
return sendFrom; // return sendFrom;
} // }
public void setSendFrom(String sendFrom) { public void setSendFrom(String sendFrom) {
this.sendFrom = sendFrom; this.sendFrom = sendFrom;
} }
public String getSendTo() { // public String getSendTo() {
return sendTo; // return sendTo;
} // }
public void setSendTo(String sendTo) { public void setSendTo(String sendTo) {
this.sendTo = sendTo; this.sendTo = sendTo;
} }
public SmsSender getSmsSender() { // public SmsSender getSmsSender() {
return smsSender; // return smsSender;
} // }
public void setSmsSender(SmsSender smsSender) { public void setSmsSender(SmsSender smsSender) {
this.smsSender = smsSender; this.smsSender = smsSender;
} }
public List<Map<String, String>> getSmsTemplate() { // public List<Map<String, String>> getSmsTemplate() {
return smsTemplate; // return smsTemplate;
} // }
public void setSmsTemplate(List<Map<String, String>> smsTemplate) { public void setSmsTemplate(List<Map<String, String>> smsTemplate) {
this.smsTemplate = smsTemplate; this.smsTemplate = smsTemplate;
} }
public WxTemplateSender getWxTemplateSender() { // public WxTemplateSender getWxTemplateSender() {
return wxTemplateSender; // return wxTemplateSender;
} // }
public void setWxTemplateSender(WxTemplateSender wxTemplateSender) { public void setWxTemplateSender(WxTemplateSender wxTemplateSender) {
this.wxTemplateSender = wxTemplateSender; this.wxTemplateSender = wxTemplateSender;
} }
public List<Map<String, String>> getWxTemplate() { // public List<Map<String, String>> getWxTemplate() {
return wxTemplate; // return wxTemplate;
} // }
public void setWxTemplate(List<Map<String, String>> wxTemplate) { public void setWxTemplate(List<Map<String, String>> wxTemplate) {
this.wxTemplate = wxTemplate; this.wxTemplate = wxTemplate;
......
package org.linlinjava.litemall.core.notify; package org.linlinjava.litemall.core.notify;
import cn.binarywang.wx.miniapp.api.WxMaService; 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.domain.LitemallUserFormid;
import org.linlinjava.litemall.db.service.LitemallUserFormIdService; import org.linlinjava.litemall.db.service.LitemallUserFormIdService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import javax.net.ssl.*; import java.util.ArrayList;
import java.io.BufferedReader; import java.util.List;
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;
/** /**
* 微信模版消息通知 * 微信模版消息通知
...@@ -28,145 +21,57 @@ public class WxTemplateSender { ...@@ -28,145 +21,57 @@ public class WxTemplateSender {
LitemallUserFormIdService formIdService; LitemallUserFormIdService formIdService;
/** /**
* 发送微信消息(模板消息) * 发送微信消息(模板消息),不带跳转
* *
* @param touser 用户 OpenID * @param touser 用户 OpenID
* @param templatId 模板消息ID * @param templatId 模板消息ID
* @param parms 详细内容 * @param parms 详细内容
*/ */
public void sendWechatMsg(String touser, String templatId, String[] parms) { public void sendWechatMsg(String touser, String templatId, String[] parms) {
LitemallUserFormid userFormid = formIdService.queryByOpenId(touser); sendMsg(touser, templatId, parms, "", "", "");
if (userFormid == null)
return;
sendWechatMsg(touser, templatId, userFormid.getFormid(), "", "", parms);
formIdService.delUserFormid(userFormid.getId());
} }
/** /**
* 发送微信消息(模板消息) * 发送微信消息(模板消息),带跳转
* *
* @param touser 用户 OpenID * @param touser 用户 OpenID
* @param templatId 模板消息ID * @param templatId 模板消息ID
* @param formId payId或者表单ID
* @param clickurl URL置空,则在发送后,点击模板消息会进入一个空白页面(ios),或无法点击(android)。
* @param topcolor 标题颜色
* @param parms 详细内容 * @param parms 详细内容
* @return * @param page 跳转页面
*/ */
public String sendWechatMsg(String touser, String templatId, String formId, String clickurl, String topcolor, String[] parms) { public void sendWechatMsg(String touser, String templatId, String[] parms, String page) {
try { sendMsg(touser, templatId, parms, page, "", "");
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";
} }
/** private void sendMsg(String touser, String templatId, String[] parms, String page, String color, String emphasisKeyword) {
* 根据参数生成对应的 json 数据 LitemallUserFormid userFormid = formIdService.queryByOpenId(touser);
* if (userFormid == null)
* @param parms return;
* @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]);
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 { try {
// 创建SSLContext对象,并使用我们指定的信任管理器初始化 wxMaService.getMsgService().sendTemplateMsg(msg);
TrustManager[] tm = {new MyX509TrustManager()}; formIdService.updateUserFormId(userFormid);
SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE"); } catch (WxErrorException e) {
sslContext.init(null, tm, new SecureRandom()); e.printStackTrace();
// 从上述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);
} }
return jsonObject;
} }
/** private List<WxMaTemplateMessage.Data> createMsgData(String[] parms) {
* 微信请求 - 信任管理器 List<WxMaTemplateMessage.Data> dataList = new ArrayList<>();
*/ for (int i = 1; i <= parms.length; i++) {
private class MyX509TrustManager implements X509TrustManager { dataList.add(new WxMaTemplateMessage.Data("keyword" + i, parms[i - 1]));
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
} }
@Override return dataList;
public X509Certificate[] getAcceptedIssuers() {
return null;
}
} }
} }
...@@ -22,9 +22,8 @@ public class WxTemplateTest { ...@@ -22,9 +22,8 @@ public class WxTemplateTest {
@Test @Test
public void testPaySucceed() { public void testPaySucceed() {
String touser = "xx"; String touser = "xx";
String formId = "";
String[] params = new String[]{"xxx"}; String[] params = new String[]{"xxx"};
notifyService.notifyWxTemplate(touser, formId, NotifyType.PAY_SUCCEED, params); notifyService.notifyWxTemplate(touser, NotifyType.PAY_SUCCEED, params);
try { try {
Thread.sleep(5000); Thread.sleep(5000);
} catch (InterruptedException e) { } catch (InterruptedException e) {
......
...@@ -27,20 +27,26 @@ public class LitemallUserFormIdService { ...@@ -27,20 +27,26 @@ public class LitemallUserFormIdService {
} }
/** /**
* 添加一个 FormId * 更新或删除FormId
* *
* @param userFormid * @param userFormid
*/ */
public void addUserFormid(LitemallUserFormid userFormid) { public void updateUserFormId(LitemallUserFormid userFormid) {
formidMapper.insertSelective(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) { public void addUserFormid(LitemallUserFormid userFormid) {
formidMapper.deleteByPrimaryKey(userFormidId); formidMapper.insertSelective(userFormid);
} }
} }
...@@ -85,6 +85,9 @@ public class WxOrderController { ...@@ -85,6 +85,9 @@ public class WxOrderController {
@Autowired @Autowired
private NotifyService notifyService; private NotifyService notifyService;
@Autowired
LitemallUserFormIdService formIdService;
public WxOrderController() { public WxOrderController() {
} }
...@@ -500,6 +503,18 @@ public class WxOrderController { ...@@ -500,6 +503,18 @@ public class WxOrderController {
orderRequest.setSpbillCreateIp(IpUtil.getIpAddr(request)); orderRequest.setSpbillCreateIp(IpUtil.getIpAddr(request));
result = wxPayService.createOrder(orderRequest); 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) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
return ResponseUtil.fail(403, "订单不能支付"); return ResponseUtil.fail(403, "订单不能支付");
...@@ -563,6 +578,20 @@ public class WxOrderController { ...@@ -563,6 +578,20 @@ public class WxOrderController {
*/ */
notifyService.notifySmsTemplateSync(order.getMobile(), NotifyType.PAY_SUCCEED, new String[]{orderSn.substring(8, 14)}); 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("处理成功!"); return WxPayNotifyResponse.success("处理成功!");
} catch (Exception e) { } catch (Exception e) {
logger.error("微信回调结果异常,异常原因 " + e.getMessage()); logger.error("微信回调结果异常,异常原因 " + e.getMessage());
......
...@@ -40,6 +40,7 @@ public class WxUserFormId { ...@@ -40,6 +40,7 @@ public class WxUserFormId {
userFormid.setUseamount(1); userFormid.setUseamount(1);
userFormid.setExpireTime(LocalDateTime.now().plusDays(7)); userFormid.setExpireTime(LocalDateTime.now().plusDays(7));
formIdService.addUserFormid(userFormid); formIdService.addUserFormid(userFormid);
return ResponseUtil.ok(); 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