工厂类的使用,不关心底层实现工具,外层只负责调用
如题, 专做记录-虽然不太明白具体实现,以此做记录
设计结构
注意: 以下具体配置均已混淆, 实际使用请使用真实配置信息;
配置yml
litemall: # 开发者应该设置成自己的wx相关信息
wx:
app-id: wx4d5ef10fb90757SS
app-secret: b8cc185ca92b311e0c8fee85c89062SS
mch-id: 1560901111
mch-key: 111111111111111111111111111111
notify-url: https://www.xxxx.vip/qdd/wx/order/pay-notify
# 商户证书文件路径
# 请参考“商户证书”一节 https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=4_3
key-path: xxxxx
#通知相关配置
notify:
mail:
# 邮件通知配置,邮箱一般用于接收业务通知例如收到新的订单,sendto 定义邮件接收者,通常为商城运营人员
enable: false
host: smtp.exmail.qq.com
username: ex@ex.com.cn
password: XXXXXXXXXXXXX
sendfrom: ex@ex.com.cn
sendto: ex@qq.com
# 短消息模版通知配置
# 短信息用于通知客户,例如发货短信通知,注意配置格式;template-name,template-templateId 请参考 NotifyType 枚举值
sms:
enable: true
# 如果是腾讯云短信,则设置active的值tencent
# 如果是阿里云短信,则设置active的值aliyun
active: aliyun
tencent:
appid: 111111111
appkey: xxxxxxxxxxxxxx
aliyun:
regionId: cn-hangzhou
accessKeyId: LTAI4Fc5aio7M474NCfaXXX
accessKeySecret: KiqZzpQz3Mcl6xrfpFSj6Kd80bXXXX
sign: XX科技
template:
- name: paySucceed
templateId: 156300
- name: captcha
templateId: 156400
- name: ship
templateId: SMS_177552500
- name: refund
templateId: 159447
- name: reviewTimeOut
templateId: SMS_177547600
- name: reviewShip
templateId: SMS_177542600
- name: reviewSucceed
templateId: SMS_177537600
- name: payNotify
templateId: SMS_177537600
# 微信模版通知配置
# 微信模版用于通知客户或者运营者,注意配置格式;template-name,template-templateId 请参考 NotifyType 枚举值
wx:
enable: false
template:
- name: paySucceed
templateId: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
- name: captcha
templateId: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
- name: ship
templateId: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
- name: refund
templateId: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
与配置映射的java类型
package org.linlinjava.litemall.core.notify.config;import org.springframework.boot.context.properties.ConfigurationProperties;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@ConfigurationProperties(prefix = "litemall.notify")
public class NotifyProperties {
private Mail mail;
private Sms sms;
private Wx wx;
public Mail getMail() {
return mail;
}
public void setMail(Mail mail) {
this.mail = mail;
}
public Sms getSms() {
return sms;
}
public void setSms(Sms sms) {
this.sms = sms;
}
public Wx getWx() {
return wx;
}
public void setWx(Wx wx) {
this.wx = wx;
}
public static class Mail {
private boolean enable;
private String host;
private String username;
private String password;
private String sendfrom;
private String sendto;
public boolean isEnable() {
return enable;
}
public void setEnable(boolean enable) {
this.enable = enable;
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getSendfrom() {
return sendfrom;
}
public void setSendfrom(String sendfrom) {
this.sendfrom = sendfrom;
}
public String getSendto() {
return sendto;
}
public void setSendto(String sendto) {
this.sendto = sendto;
}
}
public static class Sms {
private boolean enable;
private String active;
private String sign;
private Tencent tencent;
private Aliyun aliyun;
private List<Map<String, String>> template = new ArrayList<>();
public boolean isEnable() {
return enable;
}
public void setEnable(boolean enable) {
this.enable = enable;
}
public List<Map<String, String>> getTemplate() {
return template;
}
public void setTemplate(List<Map<String, String>> template) {
this.template = template;
}
public String getActive() {
return active;
}
public void setActive(String active) {
this.active = active;
}
public String getSign() {
return sign;
}
public void setSign(String sign) {
this.sign = sign;
}
public Tencent getTencent() {
return tencent;
}
public void setTencent(Tencent tencent) {
this.tencent = tencent;
}
public Aliyun getAliyun() {
return aliyun;
}
public void setAliyun(Aliyun aliyun) {
this.aliyun = aliyun;
}
public static class Tencent {
private int appid;
private String appkey;
public int getAppid() {
return appid;
}
public void setAppid(int appid) {
this.appid = appid;
}
public String getAppkey() {
return appkey;
}
public void setAppkey(String appkey) {
this.appkey = appkey;
}
}
public static class Aliyun {
private String regionId;
private String accessKeyId;
private String accessKeySecret;
public String getRegionId() {
return regionId;
}
public void setRegionId(String regionId) {
this.regionId = regionId;
}
public String getAccessKeyId() {
return accessKeyId;
}
public void setAccessKeyId(String accessKeyId) {
this.accessKeyId = accessKeyId;
}
public String getAccessKeySecret() {
return accessKeySecret;
}
public void setAccessKeySecret(String accessKeySecret) {
this.accessKeySecret = accessKeySecret;
}
}
}
public static class Wx {
private boolean enable;
private List<Map<String, String>> template = new ArrayList<>();
public boolean isEnable() {
return enable;
}
public void setEnable(boolean enable) {
this.enable = enable;
}
public List<Map<String, String>> getTemplate() {
return template;
}
public void setTemplate(List<Map<String, String>> template) {
this.template = template;
}
}
}
读取配置的java 类
package org.linlinjava.litemall.core.notify.config;import com.github.qcloudsms.SmsSingleSender;
import org.linlinjava.litemall.core.notify.AliyunSmsSender;
import org.linlinjava.litemall.core.notify.NotifyService;
import org.linlinjava.litemall.core.notify.TencentSmsSender;
import org.linlinjava.litemall.core.notify.WxTemplateSender;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.JavaMailSenderImpl;
@Configuration
@EnableConfigurationProperties(NotifyProperties.class)
public class NotifyAutoConfiguration {
private final NotifyProperties properties;
public NotifyAutoConfiguration(NotifyProperties properties) {
this.properties = properties;
}
@Bean
public NotifyService notifyService() {
NotifyService notifyService = new NotifyService();
NotifyProperties.Mail mailConfig = properties.getMail();
if (mailConfig.isEnable()) {
notifyService.setMailSender(mailSender());
notifyService.setSendFrom(mailConfig.getSendfrom());
notifyService.setSendTo(mailConfig.getSendto());
}
NotifyProperties.Sms smsConfig = properties.getSms();
if (smsConfig.isEnable()) {
if(smsConfig.getActive().equals("tencent")) {
notifyService.setSmsSender(tencentSmsSender());
}
else if(smsConfig.getActive().equals("aliyun")) {
notifyService.setSmsSender(aliyunSmsSender());
}
notifyService.setSmsTemplate(smsConfig.getTemplate());
}
NotifyProperties.Wx wxConfig = properties.getWx();
if (wxConfig.isEnable()) {
notifyService.setWxTemplateSender(wxTemplateSender());
notifyService.setWxTemplate(wxConfig.getTemplate());
}
return notifyService;
}
@Bean
public JavaMailSender mailSender() {
NotifyProperties.Mail mailConfig = properties.getMail();
JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
mailSender.setHost(mailConfig.getHost());
mailSender.setUsername(mailConfig.getUsername());
mailSender.setPassword(mailConfig.getPassword());
return mailSender;
}
@Bean
public WxTemplateSender wxTemplateSender() {
WxTemplateSender wxTemplateSender = new WxTemplateSender();
return wxTemplateSender;
}
@Bean
public TencentSmsSender tencentSmsSender() {
NotifyProperties.Sms smsConfig = properties.getSms();
TencentSmsSender smsSender = new TencentSmsSender();
NotifyProperties.Sms.Tencent tencent = smsConfig.getTencent();
smsSender.setSender(new SmsSingleSender(tencent.getAppid(), tencent.getAppkey()));
smsSender.setSign(smsConfig.getSign());
return smsSender;
}
@Bean
public AliyunSmsSender aliyunSmsSender() {
NotifyProperties.Sms smsConfig = properties.getSms();
AliyunSmsSender smsSender = new AliyunSmsSender();
NotifyProperties.Sms.Aliyun aliyun = smsConfig.getAliyun();
smsSender.setSign(smsConfig.getSign());
smsSender.setRegionId(aliyun.getRegionId());
smsSender.setAccessKeyId(aliyun.getAccessKeyId());
smsSender.setAccessKeySecret(aliyun.getAccessKeySecret());
return smsSender;
}
}
发送动作: 抽象java类
package org.linlinjava.litemall.core.notify;public interface SmsSender {
/**
* 发送短信息
*
* @param phone 接收通知的电话号码
* @param content 短消息内容
*/
SmsResult send(String phone, String content);
/**
* 通过短信模版发送短信息
*
* @param phone 接收通知的电话号码
* @param templateId 通知模板ID
* @param params 通知模版内容里的参数,类似"您的验证码为{1}"中{1}的值
*/
SmsResult sendWithTemplate(String phone, String templateId, String[] params);
}
实际发送类: 腾讯短信, 阿里云短信....
package org.linlinjava.litemall.core.notify;import com.github.qcloudsms.SmsSingleSender;
import com.github.qcloudsms.SmsSingleSenderResult;
import com.github.qcloudsms.httpclient.HTTPException;
import lombok.extern.slf4j.Slf4j;
import java.io.IOException;
/*
* 腾讯云短信服务
*/
@Slf4j
public class TencentSmsSender implements SmsSender {
private SmsSingleSender sender;
private String sign;
public SmsSingleSender getSender() {
return sender;
}
public void setSender(SmsSingleSender sender) {
this.sender = sender;
}
@Override
public SmsResult send(String phone, String content) {
try {
SmsSingleSenderResult result = sender.send(0, "86", phone, content, "", "");
log.debug(result.toString());
SmsResult smsResult = new SmsResult();
smsResult.setSuccessful(true);
smsResult.setResult(result);
return smsResult;
} catch (HTTPException | IOException e) {
log.error(e.getMessage(), e);
}
SmsResult smsResult = new SmsResult();
smsResult.setSuccessful(false);
return smsResult;
}
@Override
public SmsResult sendWithTemplate(String phone, String templateId, String[] params) {
try {
SmsSingleSenderResult result = sender.sendWithParam("86", phone, Integer.parseInt(templateId), params, this.sign, "", "");
log.debug(result.toString());
SmsResult smsResult = new SmsResult();
smsResult.setSuccessful(true);
smsResult.setResult(result);
return smsResult;
} catch (HTTPException | IOException e) {
log.error(e.getMessage(), e);
}
SmsResult smsResult = new SmsResult();
smsResult.setSuccessful(false);
return smsResult;
}
public void setSign(String sign) {
this.sign = sign;
}
}
package org.linlinjava.litemall.core.notify;import com.aliyuncs.CommonRequest;
import com.aliyuncs.CommonResponse;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.exceptions.ServerException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.linlinjava.litemall.core.util.JacksonUtil;
import java.util.HashMap;
import java.util.Map;
/*
* 阿里云短信服务
*/
@Slf4j
public class AliyunSmsSender implements SmsSender {
private String regionId;
private String accessKeyId;
private String accessKeySecret;
private String sign;
public String getRegionId() {
return regionId;
}
public void setRegionId(String regionId) {
this.regionId = regionId;
}
public String getAccessKeyId() {
return accessKeyId;
}
public void setAccessKeyId(String accessKeyId) {
this.accessKeyId = accessKeyId;
}
public String getAccessKeySecret() {
return accessKeySecret;
}
public void setAccessKeySecret(String accessKeySecret) {
this.accessKeySecret = accessKeySecret;
}
public String getSign() {
return sign;
}
public void setSign(String sign) {
this.sign = sign;
}
@Override
public SmsResult send(String phone, String content) {
SmsResult smsResult = new SmsResult();
smsResult.setSuccessful(false);
return smsResult;
}
@Override
public SmsResult sendWithTemplate(String phone, String templateId, String[] params) {
IClientProfile profile = DefaultProfile.getProfile(this.regionId, this.accessKeyId, this.accessKeySecret);
IAcsClient client = null;
try{
client = new DefaultAcsClient(profile);
} catch (Exception e){
e.printStackTrace();
log.error("打印异常: "+ ExceptionUtils.getStackTrace(e));
}
CommonRequest request = new CommonRequest();
request.setMethod(MethodType.POST);
request.setDomain("dysmsapi.aliyuncs.com");
request.setVersion("2017-05-25");
request.setAction("SendSms");
request.putQueryParameter("RegionId", this.regionId);
request.putQueryParameter("PhoneNumbers", phone);
request.putQueryParameter("SignName", this.sign);
request.putQueryParameter("TemplateCode", templateId);
/*
NOTE:阿里云短信和腾讯云短信这里存在不一致
腾讯云短信模板参数是数组,因此短信模板形式如 “短信参数{1}, 短信参数{2}”
阿里云短信模板参数是JSON,因此短信模板形式如“短信参数{param1}, 短信参数{param2}”
为了保持统一,我们假定阿里云短信里面的参数是code,code1,code2...
如果开发者在阿里云短信申请的模板参数是其他命名,请开发者自行调整这里的代码,或者直接写死。
*/
String templateParam = "{}";
if(params.length == 1){
Map<String, String> data = new HashMap<>();
data.put("code", params[0]);
templateParam = JacksonUtil.toJson(data);
}
else if(params.length > 1){
Map<String, String> data = new HashMap<>();
data.put("code", params[0]);
for(int i = 1; i < params.length; i++){
data.put("code" + i, params[i]);
}
templateParam = JacksonUtil.toJson(data);
}
request.putQueryParameter("TemplateParam", templateParam);
try {
CommonResponse response = client.getCommonResponse(request);
SmsResult smsResult = new SmsResult();
smsResult.setSuccessful(true);
smsResult.setResult(response);
log.debug("发送成功: 发送结果:"+smsResult);
return smsResult;
} catch (ServerException e) {
e.printStackTrace();
} catch (ClientException e) {
e.printStackTrace();
}
SmsResult smsResult = new SmsResult();
smsResult.setSuccessful(false);
log.debug("发送失败: 发送结果:"+smsResult);
return smsResult;
}
}
package org.linlinjava.litemall.core.notify;import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaTemplateData;
import cn.binarywang.wx.miniapp.bean.WxMaTemplateMessage;
import lombok.extern.slf4j.Slf4j;
import org.linlinjava.litemall.db.domain.LitemallUserFormid;
import org.linlinjava.litemall.db.service.LitemallUserFormIdService;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.ArrayList;
import java.util.List;
/**
* 微信模版消息通知
*/
@Slf4j
public class WxTemplateSender {
@Autowired
private WxMaService wxMaService;
@Autowired
private LitemallUserFormIdService formIdService;
/**
* 发送微信消息(模板消息),不带跳转
*
* @param touser 用户 OpenID
* @param templatId 模板消息ID
* @param parms 详细内容
*/
public void sendWechatMsg(String touser, String templatId, String[] parms) {
sendMsg(touser, templatId, parms, "", "", "");
}
/**
* 发送微信消息(模板消息),带跳转
*
* @param touser 用户 OpenID
* @param templatId 模板消息ID
* @param parms 详细内容
* @param page 跳转页面
*/
public void sendWechatMsg(String touser, String templatId, String[] parms, String page) {
sendMsg(touser, templatId, parms, page, "", "");
}
private void sendMsg(String touser, String templatId, String[] parms, String page, String color,
String emphasisKeyword) {
LitemallUserFormid userFormid = formIdService.queryByOpenId(touser);
if (userFormid == null)
return;
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));
try {
wxMaService.getMsgService().sendTemplateMsg(msg);
if (formIdService.updateUserFormId(userFormid) == 0) {
log.warn("更新数据已失效");
}
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}
private List<WxMaTemplateData> createMsgData(String[] parms) {
List<WxMaTemplateData> dataList = new ArrayList<WxMaTemplateData>();
for (int i = 1; i <= parms.length; i++) {
dataList.add(new WxMaTemplateData("keyword" + i, parms[i - 1]));
}
return dataList;
}
}
其他: 枚举类型,返回结果等java类
package org.linlinjava.litemall.core.notify;public enum NotifyType {
PAY_SUCCEED("paySucceed"), //支付成功通知
SHIP("ship"), // 发货通知
REFUND("refund"),
CAPTCHA("captcha"), // 小程序后台服务验证码不支持
PAY_TIMEOUT("payTimeOut"), //订单支付超时提醒
REVIEW_TIMEOUT("reviewTimeOut"), //评鉴超时提醒
REVIEW_SHIP("reviewShip"), //评鉴发货通知
REVIEW_SUCCEED("reviewSucceed"), //评鉴审核成功
PAY_NOTIFY("payNotify") // 支付成功通知
;
private String type;
NotifyType(String type) {
this.type = type;
}
public String getType() {
return this.type;
}
}
package org.linlinjava.litemall.core.notify;/**
* 发送短信的返回结果
*/
public class SmsResult {
private boolean successful;
private Object result;
/**
* 短信是否发送成功
*
* @return
*/
public boolean isSuccessful() {
return successful;
}
public void setSuccessful(boolean successful) {
this.successful = successful;
}
public Object getResult() {
return result;
}
public void setResult(Object result) {
this.result = result;
}
}
发送测试类
package org.linlinjava.litemall.admin;import org.junit.Test;
import org.junit.runner.RunWith;
import org.linlinjava.litemall.core.notify.NotifyService;
import org.linlinjava.litemall.core.notify.NotifyType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.core.env.Environment;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
@WebAppConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class AdminConfigTest {
@Autowired
private Environment environment;
@Autowired
private NotifyService notifyService;
@Test
public void test() {
// 测试获取application-core.yml配置信息
System.out.println(environment.getProperty("litemall.express.appId"));
// 测试获取application-db.yml配置信息
System.out.println(environment.getProperty("spring.datasource.druid.url"));
// 测试获取application-admin.yml配置信息
// System.out.println(environment.getProperty(""));
// 测试获取application.yml配置信息
System.out.println(environment.getProperty("logging.level.org.linlinjava.litemall.admin"));
}
@Test
public void testSend() {
System.out.println("开始发送");
//TODO 发送邮件和短信通知,这里采用异步发送
// 发货会发送通知短信给用户: *
// "您的订单已经发货,快递公司 {1},快递单 {2} ,请注意查收"
notifyService.notifySmsTemplate("187581512XX", NotifyType.SHIP, new String[]{"STO", "3718162138269"});
System.out.println("结束发送");
}
}
以上是 工厂类的使用,不关心底层实现工具,外层只负责调用 的全部内容, 来源链接: utcz.com/z/511160.html