@@ -26,8 +26,8 @@ class ExecutorConfig {
|
||||
@Value("${spring.notify.queueCapacity}")
|
||||
private int queueCapacity;
|
||||
|
||||
@Bean(name = "nofityAsync")
|
||||
public Executor nofityAsync() {
|
||||
@Bean(name = "notifyAsync")
|
||||
public Executor notifyAsync() {
|
||||
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
|
||||
executor.setCorePoolSize(corePoolSize);
|
||||
executor.setMaxPoolSize(maxPoolSize);
|
||||
|
||||
@@ -34,20 +34,20 @@ public class LitemallNotifyService {
|
||||
/**
|
||||
* 短信模版通知
|
||||
* @param phoneNumber 接收通知的电话号码
|
||||
* @param params 通知模版内容里的参数,类似"您的验证码为{1}"中{1}的值
|
||||
* @param notifyType 通知类别,通过该枚举值在配置文件中获取相应的模版ID
|
||||
* @param params 通知模版内容里的参数,类似"您的验证码为{1}"中{1}的值
|
||||
*/
|
||||
public void notifySMSTemplate(String phoneNumber, String[] params, NotifyUtils.NotifyType notifyType) {
|
||||
public void notifySMSTemplate(String phoneNumber, NotifyUtils.NotifyType notifyType, String[] params) {
|
||||
if (!sendSMSEnable)
|
||||
return;
|
||||
|
||||
int templateId = -1;
|
||||
switch (notifyType) {
|
||||
case PAY_COMPLATED:
|
||||
templateId = Integer.parseInt(environment.getProperty("spring.sms.template.pay.complated"));
|
||||
case PAY_SUCCEED:
|
||||
templateId = Integer.parseInt(environment.getProperty("spring.sms.template.paySucceed"));
|
||||
break;
|
||||
case VERIFICATIONCODE:
|
||||
templateId = Integer.parseInt(environment.getProperty("spring.sms.template.verificationcode"));
|
||||
case CAPTCHA:
|
||||
templateId = Integer.parseInt(environment.getProperty("spring.sms.template.captcha"));
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -55,6 +55,19 @@ public class LitemallNotifyService {
|
||||
smsSendService.sendSMSWithTemplate(phoneNumber, templateId, params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 短信模版通知
|
||||
* @param phoneNumber 接收通知的电话号码
|
||||
* @param templateId 模板ID
|
||||
* @param params 通知模版内容里的参数,类似"您的验证码为{1}"中{1}的值
|
||||
*/
|
||||
public void notifySMSTemplate(String phoneNumber, int templateId, String[] params) {
|
||||
if (!sendSMSEnable)
|
||||
return;
|
||||
|
||||
smsSendService.sendSMSWithTemplate(phoneNumber, templateId, params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送邮件通知,接收者在spring.mail.sendto中指定
|
||||
* @param setSubject 邮件标题
|
||||
|
||||
@@ -27,7 +27,7 @@ class MailSendService {
|
||||
* @param setSubject 邮件标题
|
||||
* @param setText 邮件内容
|
||||
*/
|
||||
@Async("nofityAsync")
|
||||
@Async("notifyAsync")
|
||||
public void sendEmail(String setSubject, String setText) {
|
||||
try {
|
||||
final MimeMessage mimeMessage = mailSender.createMimeMessage();
|
||||
@@ -40,7 +40,7 @@ class MailSendService {
|
||||
mailSender.send(mimeMessage);
|
||||
|
||||
} catch (Exception ex) {
|
||||
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,8 +3,12 @@ package org.linlinjava.litemall.core.notify;
|
||||
public class NotifyUtils {
|
||||
/**
|
||||
* 该枚举定义了所有的需要通知的事件,调用通知时作为参数
|
||||
*
|
||||
* PAY_SUCCEED 支付成功,通常用于用户支付成功
|
||||
* CAPTCHA 验证码,通常用于登录、注册、找回密码
|
||||
*/
|
||||
public enum NotifyType {
|
||||
PAY_COMPLATED, REGISTER, VERIFICATIONCODE,
|
||||
PAY_SUCCEED,
|
||||
CAPTCHA
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,14 +23,14 @@ class SMSSendService {
|
||||
@Value("${spring.sms.sign}")
|
||||
private String smsSign;
|
||||
|
||||
@Async("nofityAsync")
|
||||
@Async("notifyAsync")
|
||||
public void sendSMS(String phoneNumber, String content) {
|
||||
try {
|
||||
SmsSingleSender ssender = new SmsSingleSender(appid, appkey);
|
||||
SmsSingleSenderResult result = ssender.send(0, "86", phoneNumber,
|
||||
content, "", "");
|
||||
|
||||
System.out.println(result);
|
||||
// System.out.println(result);
|
||||
} catch (HTTPException e) {
|
||||
// HTTP响应码错误
|
||||
e.printStackTrace();
|
||||
@@ -43,13 +43,13 @@ class SMSSendService {
|
||||
}
|
||||
}
|
||||
|
||||
@Async("nofityAsync")
|
||||
@Async("notifyAsync")
|
||||
public void sendSMSWithTemplate(String phoneNumber, int templateId, String[] params) {
|
||||
try {
|
||||
SmsSingleSender ssender = new SmsSingleSender(appid, appkey);
|
||||
SmsSingleSenderResult result = ssender.sendWithParam("86", phoneNumber,
|
||||
templateId, params, smsSign, "", ""); // 签名参数未提供或者为空时,会使用默认签名发送短信
|
||||
System.out.println(result);
|
||||
// System.out.println(result);
|
||||
} catch (HTTPException e) {
|
||||
// HTTP响应码错误
|
||||
e.printStackTrace();
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
package org.linlinjava.litemall.core.util;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.mail.javamail.JavaMailSenderImpl;
|
||||
import org.springframework.mail.javamail.MimeMessageHelper;
|
||||
|
||||
import javax.mail.internet.MimeMessage;
|
||||
|
||||
public class MailUtils {
|
||||
private static final Log logger = LogFactory.getLog(MailUtils.class);
|
||||
private static MailUtils mailUtils;
|
||||
|
||||
private JavaMailSenderImpl mailSender;
|
||||
|
||||
// TODO 邮箱相关后置后续应移到数据库,在后台配置完成,暂时先完成功能
|
||||
// 通知邮件送达地址
|
||||
private static final String SEND_TO = "ex@qq.com";
|
||||
|
||||
private MailUtils() {
|
||||
mailSender = new JavaMailSenderImpl();
|
||||
// 配置发送邮箱设置,请按照自己邮箱填写
|
||||
mailSender.setHost("smtp.exmail.qq.com");
|
||||
mailSender.setUsername("ex@ex.com.cn");
|
||||
mailSender.setPassword("ex");
|
||||
mailSender.setDefaultEncoding("UTF-8");
|
||||
}
|
||||
|
||||
public static MailUtils getMailUtils() {
|
||||
if (mailUtils == null)
|
||||
mailUtils = new MailUtils();
|
||||
|
||||
return mailUtils;
|
||||
}
|
||||
|
||||
public boolean sendEmail(String setSubject, String setText) {
|
||||
try {
|
||||
final MimeMessage mimeMessage = mailSender.createMimeMessage();
|
||||
final MimeMessageHelper message = new MimeMessageHelper(mimeMessage);
|
||||
message.setFrom(mailSender.getUsername());
|
||||
message.setTo(SEND_TO);
|
||||
message.setSubject(setSubject);
|
||||
message.setText(setText);
|
||||
mailSender.send(mimeMessage);
|
||||
|
||||
return true;
|
||||
} catch (Exception ex) {
|
||||
logger.error("通知邮件发送出错" + ex.getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,22 +1,23 @@
|
||||
|
||||
#\u90AE\u4EF6\u53D1\u9001\u914D\u7F6E
|
||||
# 邮件发送配置
|
||||
sprint.mail.enable=false
|
||||
spring.mail.host=smtp.exmail.qq.com
|
||||
spring.mail.username=ex@ex.com.cn
|
||||
spring.mail.password=
|
||||
spring.mail.sendto=ex@qq.com
|
||||
spring.mail.username=xxxxxx
|
||||
spring.mail.password=xxxxxx
|
||||
spring.mail.sendto=example@qq.com
|
||||
|
||||
#\u77ED\u4FE1\u53D1\u9001\u914D\u7F6E
|
||||
# 短信发送配置
|
||||
spring.sms.enable=false
|
||||
spring.sms.appid=
|
||||
spring.sms.appkey=
|
||||
spring.sms.sign=
|
||||
spring.sms.appid=111111
|
||||
spring.sms.appkey=xxxxxx
|
||||
spring.sms.sign=xxxxxx
|
||||
|
||||
#\u77ED\u4FE1\u6A21\u7248\u6D88\u606F\u914D\u7F6E\uFF0C\u8BF7\u5728\u817E\u8BAF\u77ED\u4FE1\u5E73\u53F0\u914D\u7F6E\u597D\u5404\u4E2A\u901A\u77E5\u6D88\u606F\u7684\u6A21\u7248\uFF0C\u7136\u540E\u5C06\u6A21\u7248ID\u4E00\u4E00\u8D4B\u503C,LitemallNotifyService,NotifyType\u679A\u4E3E\u4E2D\u4E0E\u8FD9\u91CC\u4E00\u4E00\u5BF9\u5E94
|
||||
spring.sms.template.pay.complated=156349
|
||||
spring.sms.template.verificationcode=156433
|
||||
# 短信模板消息配置
|
||||
# 请在腾讯短信平台配置通知消息模板,然后这里设置不同短信模板ID
|
||||
# 请参考LitemallNotifyService.notifySMSTemplate
|
||||
spring.sms.template.paySucceed=111111
|
||||
spring.sms.template.captcha=222222
|
||||
|
||||
#\u53D1\u9001\u7EBF\u7A0B\u6C60\u914D\u7F6E
|
||||
# 发送线程池配置
|
||||
spring.notify.corePoolSize=5
|
||||
spring.notify.maxPoolSize=100
|
||||
spring.notify.queueCapacity=50
|
||||
@@ -0,0 +1,41 @@
|
||||
package org.linlinjava.litemall.core;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.linlinjava.litemall.core.notify.LitemallNotifyService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.web.WebAppConfiguration;
|
||||
|
||||
/**
|
||||
* 测试邮件发送服务
|
||||
*
|
||||
* 注意LitemallNotifyService采用异步线程操作
|
||||
* 因此测试的时候需要睡眠一会儿,保证任务执行
|
||||
*
|
||||
* 开发者需要确保:
|
||||
* 1. 在相应的邮件服务器设置正确notify.properties已经设置正确
|
||||
* 2. 在相应的邮件服务器设置正确
|
||||
*/
|
||||
@WebAppConfiguration
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringBootTest
|
||||
public class MailTest {
|
||||
|
||||
@Autowired
|
||||
private LitemallNotifyService litemallNotifyService;
|
||||
|
||||
@Test
|
||||
public void testMail() {
|
||||
litemallNotifyService.notifyMailMessage("订单信息", "订单1111111已付款,请发货");
|
||||
|
||||
try {
|
||||
Thread.sleep(5000);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package org.linlinjava.litemall.core;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.linlinjava.litemall.core.notify.LitemallNotifyService;
|
||||
import org.linlinjava.litemall.core.notify.NotifyUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.web.WebAppConfiguration;
|
||||
|
||||
/**
|
||||
* 测试短信发送服务
|
||||
*
|
||||
* 注意LitemallNotifyService采用异步线程操作
|
||||
* 因此测试的时候需要睡眠一会儿,保证任务执行
|
||||
*
|
||||
* 开发者需要确保:
|
||||
* 1. 在腾讯云短信平台设置短信签名和短信模板notify.properties已经设置正确
|
||||
* 2. 在腾讯云短信平台设置短信签名和短信模板
|
||||
* 3. 在当前测试类设置好正确的手机号码
|
||||
*/
|
||||
@WebAppConfiguration
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringBootTest
|
||||
public class SmsTest {
|
||||
|
||||
@Autowired
|
||||
private LitemallNotifyService litemallNotifyService;
|
||||
|
||||
// @Test
|
||||
public void testSingle() {
|
||||
String phone = "xxxxxxxxxxx";
|
||||
// 这里的短信签名必须在短信管理平台内设置正确并且相符合
|
||||
String msg = "【xxx】你的验证码为:123456,请与2分钟内填写,如非本人操作,请忽略本短信。";
|
||||
litemallNotifyService.notifySMSMessage(phone, msg);
|
||||
|
||||
try {
|
||||
Thread.sleep(5000);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCaptcha() {
|
||||
String phone = "xxxxxxxxxxx";
|
||||
String[] params = new String[] {"123456"};
|
||||
|
||||
litemallNotifyService.notifySMSTemplate(phone, NotifyUtils.NotifyType.CAPTCHA, params);
|
||||
|
||||
try {
|
||||
Thread.sleep(5000);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPaySucceed() {
|
||||
String phone = "xxxxxxxxxxx";
|
||||
String[] params = new String[] {"123456"};
|
||||
|
||||
litemallNotifyService.notifySMSTemplate(phone, NotifyUtils.NotifyType.PAY_SUCCEED, params);
|
||||
|
||||
try {
|
||||
Thread.sleep(5000);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -293,7 +293,7 @@ public class WxOrderController {
|
||||
// 根据订单商品总价计算运费,满88则免运费,否则8元;
|
||||
BigDecimal freightPrice = new BigDecimal(0.00);
|
||||
if (checkedGoodsPrice.compareTo(new BigDecimal(88.00)) < 0) {
|
||||
freightPrice = new BigDecimal(0.00);
|
||||
freightPrice = new BigDecimal(8.00);
|
||||
}
|
||||
|
||||
// 可以使用的其他钱,例如用户积分
|
||||
@@ -488,16 +488,12 @@ public class WxOrderController {
|
||||
WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest();
|
||||
orderRequest.setOutTradeNo(order.getOrderSn());
|
||||
orderRequest.setOpenid(openid);
|
||||
// TODO 更有意义的显示名称
|
||||
orderRequest.setBody("订单:" + order.getOrderSn());
|
||||
// 元转成分
|
||||
Integer fee = 0;
|
||||
// 这里演示仅支付1分
|
||||
// 实际项目取消下面两行注释
|
||||
BigDecimal actualPrice = order.getActualPrice();
|
||||
fee = actualPrice.multiply(new BigDecimal(100)).intValue();
|
||||
orderRequest.setTotalFee(fee);
|
||||
// TODO 用户IP地址
|
||||
orderRequest.setSpbillCreateIp(IpUtil.getIpAddr(request));
|
||||
|
||||
result = wxPayService.createOrder(orderRequest);
|
||||
@@ -546,7 +542,6 @@ public class WxOrderController {
|
||||
}
|
||||
|
||||
// 检查支付订单金额
|
||||
// TODO 这里1分钱需要改成实际订单金额
|
||||
if (!totalFee.equals(order.getActualPrice().toString())) {
|
||||
throw new Exception(order.getOrderSn() + " : 支付金额不符合 totalFee=" + totalFee);
|
||||
}
|
||||
@@ -557,8 +552,9 @@ public class WxOrderController {
|
||||
orderService.updateById(order);
|
||||
|
||||
//TODO 发送邮件和短信通知,这里采用异步发送
|
||||
litemallNotifyService.notifyMailMessage("订单通知", order.toString());
|
||||
litemallNotifyService.notifySMSTemplate(order.getMobile(), new String[]{""}, NotifyUtils.NotifyType.PAY_COMPLATED);
|
||||
// 订单支付成功以后,会发送短信给用户,以及发送邮件给管理员
|
||||
litemallNotifyService.notifyMailMessage("新订单通知", order.toString());
|
||||
litemallNotifyService.notifySMSTemplate(order.getMobile(), NotifyUtils.NotifyType.PAY_SUCCEED, new String[]{orderSn});
|
||||
|
||||
return WxPayNotifyResponse.success("处理成功!");
|
||||
} catch (Exception e) {
|
||||
|
||||
Reference in New Issue
Block a user