diff --git a/litemall-core/src/main/java/org/linlinjava/litemall/core/notify/ExecutorConfig.java b/litemall-core/src/main/java/org/linlinjava/litemall/core/notify/ExecutorConfig.java index 421a6b1c..143fc191 100644 --- a/litemall-core/src/main/java/org/linlinjava/litemall/core/notify/ExecutorConfig.java +++ b/litemall-core/src/main/java/org/linlinjava/litemall/core/notify/ExecutorConfig.java @@ -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); diff --git a/litemall-core/src/main/java/org/linlinjava/litemall/core/notify/LitemallNotifyService.java b/litemall-core/src/main/java/org/linlinjava/litemall/core/notify/LitemallNotifyService.java index 52de1cef..fcdaecbd 100644 --- a/litemall-core/src/main/java/org/linlinjava/litemall/core/notify/LitemallNotifyService.java +++ b/litemall-core/src/main/java/org/linlinjava/litemall/core/notify/LitemallNotifyService.java @@ -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 邮件标题 diff --git a/litemall-core/src/main/java/org/linlinjava/litemall/core/notify/MailSendService.java b/litemall-core/src/main/java/org/linlinjava/litemall/core/notify/MailSendService.java index 3c8edac7..85a0311d 100644 --- a/litemall-core/src/main/java/org/linlinjava/litemall/core/notify/MailSendService.java +++ b/litemall-core/src/main/java/org/linlinjava/litemall/core/notify/MailSendService.java @@ -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(); } } } diff --git a/litemall-core/src/main/java/org/linlinjava/litemall/core/notify/NotifyUtils.java b/litemall-core/src/main/java/org/linlinjava/litemall/core/notify/NotifyUtils.java index 571d28e9..6ffaf236 100644 --- a/litemall-core/src/main/java/org/linlinjava/litemall/core/notify/NotifyUtils.java +++ b/litemall-core/src/main/java/org/linlinjava/litemall/core/notify/NotifyUtils.java @@ -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 } } diff --git a/litemall-core/src/main/java/org/linlinjava/litemall/core/notify/SMSSendService.java b/litemall-core/src/main/java/org/linlinjava/litemall/core/notify/SMSSendService.java index 95f79803..6b2375fd 100644 --- a/litemall-core/src/main/java/org/linlinjava/litemall/core/notify/SMSSendService.java +++ b/litemall-core/src/main/java/org/linlinjava/litemall/core/notify/SMSSendService.java @@ -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(); diff --git a/litemall-core/src/main/java/org/linlinjava/litemall/core/util/MailUtils.java b/litemall-core/src/main/java/org/linlinjava/litemall/core/util/MailUtils.java deleted file mode 100644 index 15d34c85..00000000 --- a/litemall-core/src/main/java/org/linlinjava/litemall/core/util/MailUtils.java +++ /dev/null @@ -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; - } - } -} diff --git a/litemall-core/src/main/resources/notify.properties b/litemall-core/src/main/resources/notify.properties index 9579ab7a..5eabb730 100644 --- a/litemall-core/src/main/resources/notify.properties +++ b/litemall-core/src/main/resources/notify.properties @@ -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 \ No newline at end of file diff --git a/litemall-core/src/test/java/org/linlinjava/litemall/core/MailTest.java b/litemall-core/src/test/java/org/linlinjava/litemall/core/MailTest.java new file mode 100644 index 00000000..3a3aee6e --- /dev/null +++ b/litemall-core/src/test/java/org/linlinjava/litemall/core/MailTest.java @@ -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(); + } + } + + +} diff --git a/litemall-core/src/test/java/org/linlinjava/litemall/core/SmsTest.java b/litemall-core/src/test/java/org/linlinjava/litemall/core/SmsTest.java new file mode 100644 index 00000000..f8b6d2ad --- /dev/null +++ b/litemall-core/src/test/java/org/linlinjava/litemall/core/SmsTest.java @@ -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(); + } + } + +} diff --git a/litemall-wx-api/src/main/java/org/linlinjava/litemall/wx/web/WxOrderController.java b/litemall-wx-api/src/main/java/org/linlinjava/litemall/wx/web/WxOrderController.java index ee1cd33e..47a4a39f 100644 --- a/litemall-wx-api/src/main/java/org/linlinjava/litemall/wx/web/WxOrderController.java +++ b/litemall-wx-api/src/main/java/org/linlinjava/litemall/wx/web/WxOrderController.java @@ -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) {