Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
jinli gu
Litemall
Commits
6ac9478e
Commit
6ac9478e
authored
Jul 14, 2018
by
Menethil
Browse files
添加短信通知和邮件通知
parent
acdf7a65
Changes
10
Hide whitespace changes
Inline
Side-by-side
litemall-core/pom.xml
View file @
6ac9478e
...
...
@@ -42,9 +42,13 @@
<artifactId>
javax.mail
</artifactId>
</dependency>
<dependency>
<groupId>
com.github.qcloudsms
</groupId>
<artifactId>
qcloudsms
</artifactId>
<version>
1.0.5
</version>
</dependency>
</dependencies>
<build>
<resources>
<resource>
...
...
litemall-core/src/main/java/org/linlinjava/litemall/core/notify/ExecutorConfig.java
0 → 100644
View file @
6ac9478e
package
org.linlinjava.litemall.core.notify
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.scheduling.annotation.EnableAsync
;
import
org.springframework.scheduling.annotation.EnableScheduling
;
import
org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor
;
import
java.util.concurrent.Executor
;
import
java.util.concurrent.ThreadPoolExecutor
;
/**
* 异步线程池,用于异步发送通知
*/
@Configuration
@EnableScheduling
@EnableAsync
class
ExecutorConfig
{
@Value
(
"${spring.notify.corePoolSize}"
)
private
int
corePoolSize
;
@Value
(
"${spring.notify.maxPoolSize}"
)
private
int
maxPoolSize
;
@Value
(
"${spring.notify.queueCapacity}"
)
private
int
queueCapacity
;
@Bean
(
name
=
"nofityAsync"
)
public
Executor
nofityAsync
()
{
ThreadPoolTaskExecutor
executor
=
new
ThreadPoolTaskExecutor
();
executor
.
setCorePoolSize
(
corePoolSize
);
executor
.
setMaxPoolSize
(
maxPoolSize
);
executor
.
setQueueCapacity
(
queueCapacity
);
executor
.
setRejectedExecutionHandler
(
new
ThreadPoolExecutor
.
CallerRunsPolicy
());
executor
.
setThreadNamePrefix
(
"NotifyExecutor-"
);
executor
.
initialize
();
return
executor
;
}
}
litemall-core/src/main/java/org/linlinjava/litemall/core/notify/LitemallNotifyService.java
0 → 100644
View file @
6ac9478e
package
org.linlinjava.litemall.core.notify
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.context.annotation.PropertySource
;
import
org.springframework.core.env.Environment
;
import
org.springframework.stereotype.Service
;
/**
* Litemall商城通知服务类
*/
@PropertySource
(
value
=
"classpath:notify.properties"
)
@Service
(
"litemallNotifyService"
)
public
class
LitemallNotifyService
{
@Autowired
MailSendService
mailSendService
;
@Autowired
SMSSendService
smsSendService
;
@Autowired
Environment
environment
;
@Value
(
"${sprint.mail.enable}"
)
private
boolean
sendMailEnable
;
@Value
(
"${spring.sms.enable}"
)
private
boolean
sendSMSEnable
;
public
void
notifySMSMessage
(
String
phoneNumber
,
String
message
)
{
if
(!
sendSMSEnable
)
return
;
smsSendService
.
sendSMS
(
phoneNumber
,
message
);
}
/**
* 短信模版通知
* @param phoneNumber 接收通知的电话号码
* @param params 通知模版内容里的参数,类似"您的验证码为{1}"中{1}的值
* @param notifyType 通知类别,通过该枚举值在配置文件中获取相应的模版ID
*/
public
void
notifySMSTemplate
(
String
phoneNumber
,
String
[]
params
,
NotifyUtils
.
NotifyType
notifyType
)
{
if
(!
sendSMSEnable
)
return
;
int
templateId
=
-
1
;
switch
(
notifyType
)
{
case
PAY_COMPLATED:
templateId
=
Integer
.
parseInt
(
environment
.
getProperty
(
"spring.sms.template.pay.complated"
));
break
;
case
VERIFICATIONCODE:
templateId
=
Integer
.
parseInt
(
environment
.
getProperty
(
"spring.sms.template.verificationcode"
));
break
;
}
if
(
templateId
!=
-
1
)
smsSendService
.
sendSMSWithTemplate
(
phoneNumber
,
templateId
,
params
);
}
/**
* 发送邮件通知,接收者在spring.mail.sendto中指定
* @param setSubject 邮件标题
* @param setText 邮件内容
*/
public
void
notifyMailMessage
(
String
setSubject
,
String
setText
)
{
if
(!
sendMailEnable
)
return
;
mailSendService
.
sendEmail
(
setSubject
,
setText
);
}
}
litemall-core/src/main/java/org/linlinjava/litemall/core/notify/MailSendService.java
0 → 100644
View file @
6ac9478e
package
org.linlinjava.litemall.core.notify
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.context.annotation.PropertySource
;
import
org.springframework.mail.javamail.JavaMailSender
;
import
org.springframework.mail.javamail.MimeMessageHelper
;
import
org.springframework.scheduling.annotation.Async
;
import
org.springframework.stereotype.Service
;
import
javax.annotation.Resource
;
import
javax.mail.internet.MimeMessage
;
@PropertySource
(
value
=
"classpath:notify.properties"
)
@Service
(
"mailSendService"
)
class
MailSendService
{
@Resource
private
JavaMailSender
mailSender
;
@Value
(
"${spring.mail.username}"
)
private
String
from
;
@Value
(
"${spring.mail.sendto}"
)
private
String
sendto
;
/**
* 异步发送邮件通知
* @param setSubject 邮件标题
* @param setText 邮件内容
*/
@Async
(
"nofityAsync"
)
public
void
sendEmail
(
String
setSubject
,
String
setText
)
{
try
{
final
MimeMessage
mimeMessage
=
mailSender
.
createMimeMessage
();
final
MimeMessageHelper
message
=
new
MimeMessageHelper
(
mimeMessage
);
message
.
setFrom
(
from
);
message
.
setTo
(
sendto
);
message
.
setSubject
(
setSubject
);
message
.
setText
(
setText
);
mailSender
.
send
(
mimeMessage
);
}
catch
(
Exception
ex
)
{
}
}
}
litemall-core/src/main/java/org/linlinjava/litemall/core/notify/NotifyUtils.java
0 → 100644
View file @
6ac9478e
package
org.linlinjava.litemall.core.notify
;
public
class
NotifyUtils
{
/**
* 该枚举定义了所有的需要通知的事件,调用通知时作为参数
*/
public
enum
NotifyType
{
PAY_COMPLATED
,
REGISTER
,
VERIFICATIONCODE
,
}
}
litemall-core/src/main/java/org/linlinjava/litemall/core/notify/SMSSendService.java
0 → 100644
View file @
6ac9478e
package
org.linlinjava.litemall.core.notify
;
import
com.github.qcloudsms.SmsSingleSender
;
import
com.github.qcloudsms.SmsSingleSenderResult
;
import
com.github.qcloudsms.httpclient.HTTPException
;
import
org.json.JSONException
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.context.annotation.PropertySource
;
import
org.springframework.scheduling.annotation.Async
;
import
org.springframework.stereotype.Service
;
import
java.io.IOException
;
@PropertySource
(
value
=
"classpath:notify.properties"
)
@Service
(
"smsSendService"
)
class
SMSSendService
{
@Value
(
"${spring.sms.appid}"
)
private
int
appid
;
@Value
(
"${spring.sms.appkey}"
)
private
String
appkey
;
@Value
(
"${spring.sms.sign}"
)
private
String
smsSign
;
@Async
(
"nofityAsync"
)
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
);
}
catch
(
HTTPException
e
)
{
// HTTP响应码错误
e
.
printStackTrace
();
}
catch
(
JSONException
e
)
{
// json解析错误
e
.
printStackTrace
();
}
catch
(
IOException
e
)
{
// 网络IO错误
e
.
printStackTrace
();
}
}
@Async
(
"nofityAsync"
)
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
);
}
catch
(
HTTPException
e
)
{
// HTTP响应码错误
e
.
printStackTrace
();
}
catch
(
JSONException
e
)
{
// json解析错误
e
.
printStackTrace
();
}
catch
(
IOException
e
)
{
// 网络IO错误
e
.
printStackTrace
();
}
}
}
litemall-core/src/main/java/org/linlinjava/litemall/core/notify/WXTemplateMsgSendService.java
0 → 100644
View file @
6ac9478e
package
org.linlinjava.litemall.core.notify
;
import
org.json.JSONObject
;
import
org.springframework.context.annotation.PropertySource
;
import
org.springframework.stereotype.Service
;
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
;
/**
* 微信模版消息通知,未完成
*/
@PropertySource
(
value
=
"classpath:notify.properties"
)
@Service
(
"wxTemplateMsgSendService"
)
public
class
WXTemplateMsgSendService
{
/**
* 发送微信消息(模板消息)
*
* @param touser 用户 OpenID
* @param templatId 模板消息ID
* @param formId payId或者表单ID
* @param clickurl URL置空,则在发送后,点击模板消息会进入一个空白页面(ios),或无法点击(android)。
* @param topcolor 标题颜色
* @param data 详细内容
* @return
*/
public
String
sendWechatMsgToUser
(
String
token
,
String
touser
,
String
templatId
,
String
formId
,
String
clickurl
,
String
topcolor
,
JSONObject
data
)
{
String
tmpurl
=
"https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token="
+
token
;
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"
,
data
);
try
{
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"
;
}
/**
* 发送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);
}
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
{
}
@Override
public
X509Certificate
[]
getAcceptedIssuers
()
{
// return new X509Certificate[0];
return
null
;
}
}
}
litemall-core/src/main/resources/application.properties
View file @
6ac9478e
spring.profiles.active
=
dev
\ No newline at end of file
spring.profiles.active
=
dev
spring.message.encoding
=
UTF-8
\ No newline at end of file
litemall-core/src/main/resources/notify.properties
0 → 100644
View file @
6ac9478e
#\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
#\u77ED\u4FE1\u53D1\u9001\u914D\u7F6E
spring.sms.enable
=
false
spring.sms.appid
=
spring.sms.appkey
=
spring.sms.sign
=
#\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
#\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
litemall-wx-api/src/main/java/org/linlinjava/litemall/wx/web/WxOrderController.java
View file @
6ac9478e
...
...
@@ -9,8 +9,9 @@ import com.github.binarywang.wxpay.service.WxPayService;
import
org.apache.commons.io.IOUtils
;
import
org.apache.commons.logging.Log
;
import
org.apache.commons.logging.LogFactory
;
import
org.linlinjava.litemall.core.notify.LitemallNotifyService
;
import
org.linlinjava.litemall.core.notify.NotifyUtils
;
import
org.linlinjava.litemall.core.util.JacksonUtil
;
import
org.linlinjava.litemall.core.util.MailUtils
;
import
org.linlinjava.litemall.core.util.ResponseUtil
;
import
org.linlinjava.litemall.db.domain.*
;
import
org.linlinjava.litemall.db.service.*
;
...
...
@@ -80,6 +81,9 @@ public class WxOrderController {
@Autowired
private
WxPayService
wxPayService
;
@Autowired
private
LitemallNotifyService
litemallNotifyService
;
public
WxOrderController
()
{
}
...
...
@@ -485,7 +489,7 @@ public class WxOrderController {
orderRequest
.
setOutTradeNo
(
order
.
getOrderSn
());
orderRequest
.
setOpenid
(
openid
);
// TODO 更有意义的显示名称
orderRequest
.
setBody
(
"
litemall小商场-订单测试支付"
);
orderRequest
.
setBody
(
"
订单:"
+
order
.
getOrderSn
()
);
// 元转成分
Integer
fee
=
0
;
// 这里演示仅支付1分
...
...
@@ -552,8 +556,9 @@ public class WxOrderController {
order
.
setOrderStatus
(
OrderUtil
.
STATUS_PAY
);
orderService
.
updateById
(
order
);
//TODO 发送邮件通知,这里最好才用异步发送
MailUtils
.
getMailUtils
().
sendEmail
(
"订单通知"
,
order
.
toString
());
//TODO 发送邮件和短信通知,这里采用异步发送
litemallNotifyService
.
notifyMailMessage
(
"订单通知"
,
order
.
toString
());
litemallNotifyService
.
notifySMSTemplate
(
order
.
getMobile
(),
new
String
[]{
""
},
NotifyUtils
.
NotifyType
.
PAY_COMPLATED
);
return
WxPayNotifyResponse
.
success
(
"处理成功!"
);
}
catch
(
Exception
e
)
{
...
...
@@ -715,5 +720,4 @@ public class WxOrderController {
LitemallOrderGoods
orderGoods
=
orderGoodsList
.
get
(
0
);
return
ResponseUtil
.
ok
(
orderGoods
);
}
}
\ No newline at end of file
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment