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
c8390918
Commit
c8390918
authored
Jul 24, 2018
by
Menethil
Browse files
优化微信模版消息通知
parent
0aeb3678
Changes
6
Hide whitespace changes
Inline
Side-by-side
litemall-core/src/main/java/org/linlinjava/litemall/core/notify/NotifyService.java
View file @
c8390918
...
...
@@ -71,38 +71,40 @@ public class NotifyService {
}
/**
* 微信模版消息通知
* 微信模版消息通知,不跳转
* <p>
* 该方法会尝试从数据库获取缓存的FormId去发送消息
*
* @param touser 接收者openId
* @param formId 表单ID或者 prepayId
* @param notifyType 通知类别,通过该枚举值在配置文件中获取相应的模版ID
* @param params 通知模版内容里的参数,类似"您的验证码为{1}"中{1}的值
*/
@Async
public
void
notifyWxTemplate
(
String
touser
,
String
formId
,
NotifyType
notifyType
,
String
[]
params
)
{
public
void
notifyWxTemplate
(
String
touser
,
NotifyType
notifyType
,
String
[]
params
)
{
if
(
wxTemplateSender
==
null
)
return
;
String
templateId
=
getTemplateId
(
notifyType
,
wxTemplate
);
wxTemplateSender
.
sendWechatMsg
(
touser
,
templateId
,
formId
,
""
,
""
,
params
);
wxTemplateSender
.
sendWechatMsg
(
touser
,
templateId
,
params
);
}
/**
* 微信模版消息通知
* 微信模版消息通知
,带跳转
* <p>
* 该方法会尝试从数据库获取缓存的FormId去发送消息
*
* @param touser 接收者openId
* @param notifyType 通知类别,通过该枚举值在配置文件中获取相应的模版ID
* @param params 通知模版内容里的参数,类似"您的验证码为{1}"中{1}的值
* @param page 点击消息跳转的页面
*/
@Async
public
void
notifyWxTemplate
(
String
touser
,
NotifyType
notifyType
,
String
[]
params
)
{
public
void
notifyWxTemplate
(
String
touser
,
NotifyType
notifyType
,
String
[]
params
,
String
page
)
{
if
(
wxTemplateSender
==
null
)
return
;
String
templateId
=
getTemplateId
(
notifyType
,
wxTemplate
);
wxTemplateSender
.
sendWechatMsg
(
touser
,
templateId
,
params
);
wxTemplateSender
.
sendWechatMsg
(
touser
,
templateId
,
params
,
page
);
}
/**
...
...
@@ -135,57 +137,57 @@ public class NotifyService {
return
null
;
}
public
MailSender
getMailSender
()
{
return
mailSender
;
}
//
public MailSender getMailSender() {
//
return mailSender;
//
}
public
void
setMailSender
(
MailSender
mailSender
)
{
this
.
mailSender
=
mailSender
;
}
public
String
getSendFrom
()
{
return
sendFrom
;
}
//
public String getSendFrom() {
//
return sendFrom;
//
}
public
void
setSendFrom
(
String
sendFrom
)
{
this
.
sendFrom
=
sendFrom
;
}
public
String
getSendTo
()
{
return
sendTo
;
}
//
public String getSendTo() {
//
return sendTo;
//
}
public
void
setSendTo
(
String
sendTo
)
{
this
.
sendTo
=
sendTo
;
}
public
SmsSender
getSmsSender
()
{
return
smsSender
;
}
//
public SmsSender getSmsSender() {
//
return smsSender;
//
}
public
void
setSmsSender
(
SmsSender
smsSender
)
{
this
.
smsSender
=
smsSender
;
}
public
List
<
Map
<
String
,
String
>>
getSmsTemplate
()
{
return
smsTemplate
;
}
//
public List<Map<String, String>> getSmsTemplate() {
//
return smsTemplate;
//
}
public
void
setSmsTemplate
(
List
<
Map
<
String
,
String
>>
smsTemplate
)
{
this
.
smsTemplate
=
smsTemplate
;
}
public
WxTemplateSender
getWxTemplateSender
()
{
return
wxTemplateSender
;
}
//
public WxTemplateSender getWxTemplateSender() {
//
return wxTemplateSender;
//
}
public
void
setWxTemplateSender
(
WxTemplateSender
wxTemplateSender
)
{
this
.
wxTemplateSender
=
wxTemplateSender
;
}
public
List
<
Map
<
String
,
String
>>
getWxTemplate
()
{
return
wxTemplate
;
}
//
public List<Map<String, String>> getWxTemplate() {
//
return wxTemplate;
//
}
public
void
setWxTemplate
(
List
<
Map
<
String
,
String
>>
wxTemplate
)
{
this
.
wxTemplate
=
wxTemplate
;
...
...
litemall-core/src/main/java/org/linlinjava/litemall/core/notify/WxTemplateSender.java
View file @
c8390918
package
org.linlinjava.litemall.core.notify
;
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.service.LitemallUserFormIdService
;
import
org.springframework.beans.factory.annotation.Autowired
;
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
;
import
java.util.ArrayList
;
import
java.util.List
;
/**
* 微信模版消息通知
...
...
@@ -28,145 +21,57 @@ public class WxTemplateSender {
LitemallUserFormIdService
formIdService
;
/**
* 发送微信消息(模板消息)
* 发送微信消息(模板消息)
,不带跳转
*
* @param touser 用户 OpenID
* @param templatId 模板消息ID
* @param parms 详细内容
*/
public
void
sendWechatMsg
(
String
touser
,
String
templatId
,
String
[]
parms
)
{
LitemallUserFormid
userFormid
=
formIdService
.
queryByOpenId
(
touser
);
if
(
userFormid
==
null
)
return
;
sendWechatMsg
(
touser
,
templatId
,
userFormid
.
getFormid
(),
""
,
""
,
parms
);
formIdService
.
delUserFormid
(
userFormid
.
getId
());
sendMsg
(
touser
,
templatId
,
parms
,
""
,
""
,
""
);
}
/**
* 发送微信消息(模板消息)
* 发送微信消息(模板消息)
,带跳转
*
* @param touser 用户 OpenID
* @param templatId 模板消息ID
* @param formId payId或者表单ID
* @param clickurl URL置空,则在发送后,点击模板消息会进入一个空白页面(ios),或无法点击(android)。
* @param topcolor 标题颜色
* @param parms 详细内容
* @
return
* @
param page 跳转页面
*/
public
String
sendWechatMsg
(
String
touser
,
String
templatId
,
String
formId
,
String
clickurl
,
String
topcolor
,
String
[]
parms
)
{
try
{
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"
;
public
void
sendWechatMsg
(
String
touser
,
String
templatId
,
String
[]
parms
,
String
page
)
{
sendMsg
(
touser
,
templatId
,
parms
,
page
,
""
,
""
);
}
/**
* 根据参数生成对应的 json 数据
*
* @param parms
* @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
]);
private
void
sendMsg
(
String
touser
,
String
templatId
,
String
[]
parms
,
String
page
,
String
color
,
String
emphasisKeyword
)
{
LitemallUserFormid
userFormid
=
formIdService
.
queryByOpenId
(
touser
);
if
(
userFormid
==
null
)
return
;
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
{
// 创建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);
wxMaService
.
getMsgService
().
sendTemplateMsg
(
msg
);
formIdService
.
updateUserFormId
(
userFormid
);
}
catch
(
WxErrorException
e
)
{
e
.
printStackTrace
();
}
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
{
private
List
<
WxMaTemplateMessage
.
Data
>
createMsgData
(
String
[]
parms
)
{
List
<
WxMaTemplateMessage
.
Data
>
dataList
=
new
ArrayList
<>();
for
(
int
i
=
1
;
i
<=
parms
.
length
;
i
++)
{
dataList
.
add
(
new
WxMaTemplateMessage
.
Data
(
"keyword"
+
i
,
parms
[
i
-
1
]));
}
@Override
public
X509Certificate
[]
getAcceptedIssuers
()
{
return
null
;
}
return
dataList
;
}
}
litemall-core/src/test/java/org/linlinjava/litemall/core/WxTemplateTest.java
View file @
c8390918
...
...
@@ -22,9 +22,8 @@ public class WxTemplateTest {
@Test
public
void
testPaySucceed
()
{
String
touser
=
"xx"
;
String
formId
=
""
;
String
[]
params
=
new
String
[]{
"xxx"
};
notifyService
.
notifyWxTemplate
(
touser
,
formId
,
NotifyType
.
PAY_SUCCEED
,
params
);
notifyService
.
notifyWxTemplate
(
touser
,
NotifyType
.
PAY_SUCCEED
,
params
);
try
{
Thread
.
sleep
(
5000
);
}
catch
(
InterruptedException
e
)
{
...
...
litemall-db/src/main/java/org/linlinjava/litemall/db/service/LitemallUserFormIdService.java
View file @
c8390918
...
...
@@ -27,20 +27,26 @@ public class LitemallUserFormIdService {
}
/**
*
添加一个
FormId
*
更新或删除
FormId
*
* @param userFormid
*/
public
void
addUserFormid
(
LitemallUserFormid
userFormid
)
{
formidMapper
.
insertSelective
(
userFormid
);
public
void
updateUserFormId
(
LitemallUserFormid
userFormid
)
{
//更新或者删除缓存
if
(
userFormid
.
getIsprepay
()
&&
userFormid
.
getUseamount
()
>
1
)
{
userFormid
.
setUseamount
(
userFormid
.
getUseamount
()
-
1
);
formidMapper
.
updateByPrimaryKey
(
userFormid
);
}
else
{
formidMapper
.
deleteByPrimaryKey
(
userFormid
.
getId
());
}
}
/**
*
删除
一个 FormId
*
添加
一个 FormId
*
* @param userFormid
Id
* @param userFormid
*/
public
void
del
UserFormid
(
Integer
userFormid
Id
)
{
formidMapper
.
deleteByPrimaryKey
(
userFormid
Id
);
public
void
add
UserFormid
(
LitemallUserFormid
userFormid
)
{
formidMapper
.
insertSelective
(
userFormid
);
}
}
litemall-wx-api/src/main/java/org/linlinjava/litemall/wx/web/WxOrderController.java
View file @
c8390918
...
...
@@ -85,6 +85,9 @@ public class WxOrderController {
@Autowired
private
NotifyService
notifyService
;
@Autowired
LitemallUserFormIdService
formIdService
;
public
WxOrderController
()
{
}
...
...
@@ -500,6 +503,18 @@ public class WxOrderController {
orderRequest
.
setSpbillCreateIp
(
IpUtil
.
getIpAddr
(
request
));
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
)
{
e
.
printStackTrace
();
return
ResponseUtil
.
fail
(
403
,
"订单不能支付"
);
...
...
@@ -563,6 +578,20 @@ public class WxOrderController {
*/
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
(
"处理成功!"
);
}
catch
(
Exception
e
)
{
logger
.
error
(
"微信回调结果异常,异常原因 "
+
e
.
getMessage
());
...
...
litemall-wx-api/src/main/java/org/linlinjava/litemall/wx/web/WxUserFormId.java
View file @
c8390918
...
...
@@ -40,6 +40,7 @@ public class WxUserFormId {
userFormid
.
setUseamount
(
1
);
userFormid
.
setExpireTime
(
LocalDateTime
.
now
().
plusDays
(
7
));
formIdService
.
addUserFormid
(
userFormid
);
return
ResponseUtil
.
ok
();
}
}
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