Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
X
xyqb-user2
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
head_group
xyqb-user2
Commits
18f93b0a
Commit
18f93b0a
authored
Apr 03, 2018
by
技术部-任文超
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
重构微信关联:
1、关闭独立的关联请求接口; 2、创建微信关联、解绑、冲突用户下线事务 3、捆绑该关联动作到用户账密登录接口和快速登录接口
parent
75ca7b4c
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
219 additions
and
51 deletions
+219
-51
Constants.java
src/main/java/cn/quantgroup/xyqb/Constants.java
+2
-0
ExceptionHandlingController.java
...antgroup/xyqb/controller/ExceptionHandlingController.java
+13
-0
WeChatController.java
...group/xyqb/controller/external/user/WeChatController.java
+12
-2
UserController.java
...ntgroup/xyqb/controller/internal/user/UserController.java
+68
-33
WechatRelateUserException.java
.../quantgroup/xyqb/exception/WechatRelateUserException.java
+19
-0
IWeChatUserRepository.java
.../cn/quantgroup/xyqb/repository/IWeChatUserRepository.java
+22
-1
ISessionService.java
...a/cn/quantgroup/xyqb/service/session/ISessionService.java
+12
-1
SessionServiceImpl.java
...ntgroup/xyqb/service/session/impl/SessionServiceImpl.java
+12
-0
IWechatService.java
...ava/cn/quantgroup/xyqb/service/wechat/IWechatService.java
+15
-2
WechatServiceImpl.java
...uantgroup/xyqb/service/wechat/impl/WechatServiceImpl.java
+44
-12
No files found.
src/main/java/cn/quantgroup/xyqb/Constants.java
View file @
18f93b0a
...
...
@@ -28,6 +28,8 @@ public interface Constants {
String
X_AUTH_TOKEN
=
"x-auth-token"
;
/** 登录账号/手机号参数名 */
String
PHONE_NO
=
"phoneNo"
;
/** 微信标识参数名 */
String
OPEN_ID
=
"openId"
;
// -- Start -- IPV4安全策略常量组
/** 账密不匹配错误 - 按账号计数 */
...
...
src/main/java/cn/quantgroup/xyqb/controller/ExceptionHandlingController.java
View file @
18f93b0a
...
...
@@ -3,6 +3,7 @@ package cn.quantgroup.xyqb.controller;
import
cn.quantgroup.xyqb.exception.PasswordErrorLimitException
;
import
cn.quantgroup.xyqb.exception.UserNotExistException
;
import
cn.quantgroup.xyqb.exception.VerificationCodeErrorException
;
import
cn.quantgroup.xyqb.exception.WechatRelateUserException
;
import
cn.quantgroup.xyqb.model.JsonResult
;
import
cn.quantgroup.xyqb.util.IPUtil
;
import
org.slf4j.Logger
;
...
...
@@ -63,6 +64,18 @@ public class ExceptionHandlingController implements IBaseController {
return
new
JsonResult
(
unee
.
getMessage
(),
401L
,
null
);
}
/**
* 微信关联异常
* @param wrue
* @return
*/
@ExceptionHandler
(
WechatRelateUserException
.
class
)
@ResponseStatus
(
HttpStatus
.
UNAUTHORIZED
)
public
JsonResult
wechatRelateUserException
(
WechatRelateUserException
wrue
)
{
LOGGER
.
info
(
"throw WechatRelateUserException,msg={},businessCode={},code={}"
,
wrue
.
getMessage
(),
1L
,
401L
);
return
new
JsonResult
(
wrue
.
getMessage
(),
401L
,
null
);
}
/**
* 其他全局异常
* @param e
...
...
src/main/java/cn/quantgroup/xyqb/controller/external/user/WeChatController.java
View file @
18f93b0a
...
...
@@ -27,6 +27,8 @@ import org.springframework.beans.factory.annotation.Value;
import
org.springframework.web.bind.annotation.PathVariable
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RestController
;
import
org.springframework.web.context.request.RequestContextHolder
;
import
org.springframework.web.context.request.ServletRequestAttributes
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
...
...
@@ -206,6 +208,9 @@ public class WeChatController implements IBaseController {
* @param response
*/
private
void
receiveCodeWithDefault
(
String
code
,
String
systemKey
,
String
schema
,
Long
registerFrom
,
String
redirect
,
HttpServletResponse
response
){
// 微信跳转请求入参监控
HttpServletRequest
request
=
((
ServletRequestAttributes
)
RequestContextHolder
.
getRequestAttributes
()).
getRequest
();
LOGGER
.
info
(
"[WeChatController][receiveCodeWithDefault]微信授权及跳转:code:{},systemKey:{},schema:{},registerFrom:{},redirect:{},request:{},response:{}"
,
code
,
systemKey
,
schema
,
registerFrom
,
redirect
,
request
,
response
);
/*
* 预处理(容错)
*/
...
...
@@ -220,6 +225,7 @@ public class WeChatController implements IBaseController {
// 从code获取token
Merchant
merchant
=
merchantService
.
findMerchantByName
(
systemKey
);
AccessTokenResponse
token
=
wechatService
.
getToken
(
code
);
LOGGER
.
info
(
"[WeChatController][receiveCodeWithDefault]微信授权及跳转:merchant:{},token:{}"
,
merchant
,
token
);
if
(
token
==
null
)
{
// 让用户登录,不关联微信, 构造不关联微信的url
redirectNormalUrl
(
response
,
merchant
,
registerFrom
,
domain
);
...
...
@@ -228,12 +234,14 @@ public class WeChatController implements IBaseController {
WechatUserInfo
userInfo
=
wechatService
.
getWechatUserInfoFromWechatServer
(
token
.
getAccessToken
(),
token
.
getOpenId
());
LOGGER
.
info
(
"[WeChatController][receiveCodeWithDefault]微信授权及跳转:WechatUserInfo - from wechat api:{}"
,
userInfo
);
if
(
userInfo
==
null
||
StringUtils
.
isEmpty
(
userInfo
.
getOpenId
()))
{
// 让用户登录,不关联微信, 构造不关联微信的url
redirectNormalUrl
(
response
,
merchant
,
registerFrom
,
domain
);
return
;
}
WechatUserInfo
userInfoInDb
=
wechatService
.
findWechatUserInfoFromDb
(
userInfo
.
getOpenId
());
LOGGER
.
info
(
"[WeChatController][receiveCodeWithDefault]微信授权及跳转:WechatUserInfo - from DB:{}"
,
userInfo
);
// welcome 首次登录
if
(
userInfoInDb
==
null
)
{
// 微信用户首次登录界面, 首先保存userInfo, 跳入到微信注册登录界面
...
...
@@ -287,6 +295,7 @@ public class WeChatController implements IBaseController {
}
private
String
createUserSession
(
User
user
,
Merchant
merchant
,
String
redirect
,
String
domain
,
Long
registerFrom
)
{
LOGGER
.
info
(
"[WeChatController][createUserSession]微信授权及跳转:user:{},merchant:{},redirect:{},domain:{},registerFrom:{}"
,
user
,
merchant
,
redirect
,
domain
,
registerFrom
);
if
(
StringUtils
.
isEmpty
(
redirect
)
||
"redirect"
.
equals
(
redirect
))
{
LOGGER
.
info
(
"微信登录:redirect为null,走正常流程."
);
if
(
"baitiao"
.
equals
(
merchant
.
getName
()))
{
...
...
@@ -311,19 +320,20 @@ public class WeChatController implements IBaseController {
private
String
loginInWechatWithSessionCreated
(
User
user
,
Merchant
merchant
,
String
target
,
Long
channelId
,
String
domain
,
Long
registerFrom
)
{
AuthBean
authBean
=
sessionService
.
createSession
(
channelId
,
registerFrom
,
""
,
user
,
merchant
);
LOGGER
.
info
(
"[WeChatController][loginInWechatWithSessionCreated]微信授权及跳转:user:{},merchant:{},target:{},channelId:{},domain:{},registerFrom:{}"
,
user
,
merchant
,
target
,
channelId
,
domain
,
registerFrom
);
return
domain
+
"/landing?token="
+
authBean
.
getToken
()
+
"®isterFrom="
+
registerFrom
+
"&channelId="
+
channelId
+
"&key="
+
merchant
.
getName
()
+
"&target="
+
target
;
}
private
void
redirectWechatLoginUrlWithoutLogin
(
HttpServletResponse
response
,
Merchant
merchant
,
WechatUserInfo
userInfo
,
Long
registerFrom
,
String
domain
)
{
String
redirectUrl
=
assembleWechatRedirectUrl
(
merchant
,
userInfo
,
registerFrom
,
domain
);
LOGGER
.
info
(
"
redirectWechatLoginUrlWithoutLogin
redirectUrl:[{}]"
,
redirectUrl
);
LOGGER
.
info
(
"
[WeChatController][redirectWechatLoginUrlWithoutLogin]微信授权及跳转:
redirectUrl:[{}]"
,
redirectUrl
);
response
.
setHeader
(
"Location"
,
redirectUrl
);
response
.
setStatus
(
301
);
}
private
void
redirectNormalUrl
(
HttpServletResponse
response
,
Merchant
merchant
,
Long
registerFrom
,
String
domain
)
{
String
redirectUrl
=
assembleNormalRedirectUrl
(
merchant
,
registerFrom
,
domain
);
LOGGER
.
info
(
"
redirectNormalUrl
redirectUrl:[{}]"
,
redirectUrl
);
LOGGER
.
info
(
"
[WeChatController][redirectNormalUrl]微信授权及跳转:
redirectUrl:[{}]"
,
redirectUrl
);
response
.
setHeader
(
"Location"
,
redirectUrl
);
response
.
setStatus
(
301
);
}
...
...
src/main/java/cn/quantgroup/xyqb/controller/internal/user/UserController.java
View file @
18f93b0a
...
...
@@ -12,6 +12,7 @@ import cn.quantgroup.xyqb.entity.UserDetail;
import
cn.quantgroup.xyqb.entity.WechatUserInfo
;
import
cn.quantgroup.xyqb.exception.UserNotExistException
;
import
cn.quantgroup.xyqb.exception.VerificationCodeErrorException
;
import
cn.quantgroup.xyqb.exception.WechatRelateUserException
;
import
cn.quantgroup.xyqb.model.JsonResult
;
import
cn.quantgroup.xyqb.model.UserModel
;
import
cn.quantgroup.xyqb.model.UserStatistics
;
...
...
@@ -45,6 +46,7 @@ import java.nio.charset.Charset;
import
java.util.HashMap
;
import
java.util.Map
;
import
java.util.Objects
;
import
java.util.Set
;
/**
* Http服务接口:用户注册、登录、重置密码
...
...
@@ -99,7 +101,6 @@ public class UserController implements IBaseController {
* @param userId
* @param key
* @param request
* @param openId
* @param dimension
* @return
*/
...
...
@@ -110,10 +111,10 @@ public class UserController implements IBaseController {
@RequestParam
(
required
=
false
,
defaultValue
=
"1"
)
Long
createdFrom
,
@RequestParam
(
required
=
false
,
defaultValue
=
""
)
String
userId
,
@RequestParam
(
required
=
false
,
defaultValue
=
"xyqb"
)
String
key
,
HttpServletRequest
request
,
String
openId
,
@RequestParam
(
required
=
false
)
String
dimension
)
{
LOGGER
.
info
(
"loginV1 -> channelId:{},appChennel:{},createdFrom:{},userId:{},key:{},
openId:{},dimension:{}"
,
channelId
,
appChannel
,
createdFrom
,
userId
,
key
,
openId
,
dimension
);
return
login
(
channelId
,
appChannel
,
createdFrom
,
userId
,
key
,
request
,
openId
,
dimension
);
@RequestParam
(
required
=
false
)
String
dimension
,
HttpServletRequest
request
)
{
LOGGER
.
info
(
"loginV1 -> channelId:{},appChennel:{},createdFrom:{},userId:{},key:{},
dimension:{}"
,
channelId
,
appChannel
,
createdFrom
,
userId
,
key
,
dimension
);
return
login
(
channelId
,
appChannel
,
createdFrom
,
userId
,
key
,
dimension
,
request
);
}
@LogHttpCaller
...
...
@@ -124,18 +125,17 @@ public class UserController implements IBaseController {
@RequestParam
(
required
=
false
,
defaultValue
=
"1"
)
Long
createdFrom
,
@RequestParam
(
required
=
false
,
defaultValue
=
""
)
String
userId
,
@RequestParam
(
required
=
false
,
defaultValue
=
"xyqb"
)
String
key
,
HttpServletRequest
request
,
String
openId
,
@RequestParam
(
required
=
false
)
String
dimension
)
{
LOGGER
.
info
(
"login -> channelId:{},appChannel:{},createdFrom:{},userId:{},key:{},
openId:{},dimension:{}"
,
channelId
,
appChannel
,
createdFrom
,
userId
,
key
,
openId
,
dimension
);
@RequestParam
(
required
=
false
)
String
dimension
,
HttpServletRequest
request
)
{
LOGGER
.
info
(
"login -> channelId:{},appChannel:{},createdFrom:{},userId:{},key:{},
dimension:{}"
,
channelId
,
appChannel
,
createdFrom
,
userId
,
key
,
dimension
);
Merchant
merchant
=
merchantService
.
findMerchantByName
(
key
);
if
(
merchant
==
null
)
{
return
JsonResult
.
buildErrorStateResult
(
"未知的连接"
,
null
);
}
if
(!
StringUtils
.
isEmpty
(
userId
)
&&
userId
.
length
()
>
10
)
{
return
loginWithUserId
(
channelId
,
appChannel
,
createdFrom
,
userId
,
merchant
,
dimension
);
return
loginWithUserId
(
channelId
,
appChannel
,
createdFrom
,
userId
,
merchant
,
dimension
,
request
);
}
else
{
return
loginWithHttpBasic
(
channelId
,
appChannel
,
createdFrom
,
merchant
,
request
,
openId
,
dimension
);
return
loginWithHttpBasic
(
channelId
,
appChannel
,
createdFrom
,
merchant
,
dimension
,
request
);
}
}
...
...
@@ -207,11 +207,13 @@ public class UserController implements IBaseController {
//广点通转化注册 - 发送消息 - 方法内过滤
MqUtils
.
sendRegisterMessageForGdt
(
phoneNo
,
clickId
);
}
if
(!
wechatRelateUserIfNecessary
(
user
,
request
)){
return
JsonResult
.
buildErrorStateResult
(
"登录时微信关联失败"
,
null
);
}
//增加登陆统计发送
UserStatistics
statistics
=
new
UserStatistics
(
user
,
dimension
,
3
,
channelId
);
MqUtils
.
sendLoanVest
(
statistics
);
return
new
JsonResult
(
sessionService
.
createSession
(
channelId
,
createdFrom
,
appChannel
,
user
,
merchant
));
// return createSession(channelId, createdFrom, appChannel, user);
}
/**
...
...
@@ -386,15 +388,16 @@ public class UserController implements IBaseController {
return
JsonResult
.
buildErrorStateResult
(
null
,
null
);
}
UserDetail
detail
=
userDetailService
.
findByUserId
(
user
.
getId
());
//UserDetail detail = userDetailRepository.findByUserId(user.getId());
UserModel
userModel
=
new
UserModel
(
user
,
detail
);
return
JsonResult
.
buildSuccessResult
(
"token校验成功"
,
userModel
);
}
private
JsonResult
loginWithHttpBasic
(
Long
channelId
,
String
appChannel
,
Long
createdFrom
,
Merchant
merchant
,
HttpServletRequest
request
,
String
openId
,
String
dimension
)
{
User
user
=
verificateUserNameAndPassword
(
request
,
openId
);
private
JsonResult
loginWithHttpBasic
(
Long
channelId
,
String
appChannel
,
Long
createdFrom
,
Merchant
merchant
,
String
dimension
,
HttpServletRequest
request
)
{
User
user
=
verificateUserNameAndPassword
(
request
);
if
(
user
==
null
)
{
return
JsonResult
.
buildErrorStateResult
(
"用户名或密码不正确"
,
null
);
}
else
if
(!
wechatRelateUserIfNecessary
(
user
,
request
)){
return
JsonResult
.
buildErrorStateResult
(
"登录时微信关联失败"
,
null
);
}
//增加登陆统计发送
UserStatistics
statistics
=
new
UserStatistics
(
user
,
dimension
,
1
,
channelId
);
...
...
@@ -403,7 +406,7 @@ public class UserController implements IBaseController {
return
new
JsonResult
(
sessionService
.
createSession
(
channelId
,
createdFrom
,
appChannel
,
user
,
merchant
));
}
private
User
verificateUserNameAndPassword
(
HttpServletRequest
request
,
String
openId
)
{
private
User
verificateUserNameAndPassword
(
HttpServletRequest
request
)
{
String
credential
=
request
.
getHeader
(
"authorization"
);
if
(
StringUtils
.
isBlank
(
credential
)
||
!
credential
.
startsWith
(
"Basic "
))
{
return
null
;
...
...
@@ -451,19 +454,48 @@ public class UserController implements IBaseController {
return
StringUtils
.
defaultString
(
targetPassword
,
""
).
equals
(
PasswordUtil
.
MD5
(
paramPass
.
toLowerCase
()
+
Constants
.
PASSWORD_SALT
));
}
private
JsonResult
loginWithUserId
(
Long
channelId
,
String
appChannel
,
Long
createdFrom
,
String
userId
,
Merchant
merchant
,
String
dimension
)
{
//查询用户
,存在则保存用户session信息,userId为uuid
private
JsonResult
loginWithUserId
(
Long
channelId
,
String
appChannel
,
Long
createdFrom
,
String
userId
,
Merchant
merchant
,
String
dimension
,
HttpServletRequest
request
)
{
//查询用户
User
user
=
userService
.
findByUuidInDb
(
userId
);
//用户信息存在,更新session中的最后访问时间,重新写入缓存.
if
(
null
!=
user
||
!
user
.
getEnable
())
{
//增加登陆统计发送
UserStatistics
statistics
=
new
UserStatistics
(
user
,
dimension
,
4
,
channelId
);
MqUtils
.
sendLoanVest
(
statistics
);
return
new
JsonResult
(
sessionService
.
createSession
(
channelId
,
createdFrom
,
appChannel
,
user
,
merchant
));
}
else
{
if
(
Objects
.
isNull
(
user
)
||
!
user
.
getEnable
())
{
LOGGER
.
error
(
"用户不存在,或者已经注销,userId:{}"
,
userId
);
return
JsonResult
.
buildErrorStateResult
(
"登录失败"
,
null
);
}
else
if
(!
wechatRelateUserIfNecessary
(
user
,
request
)){
return
JsonResult
.
buildErrorStateResult
(
"登录时微信关联失败"
,
null
);
}
//增加登陆统计发送
UserStatistics
statistics
=
new
UserStatistics
(
user
,
dimension
,
4
,
channelId
);
MqUtils
.
sendLoanVest
(
statistics
);
//更新session
return
new
JsonResult
(
sessionService
.
createSession
(
channelId
,
createdFrom
,
appChannel
,
user
,
merchant
));
}
/**
* 如果必要的话,关联用户和微信
* @param user - 用户标识
* @param request - 当前请求
* @return true - 继续登录,false - 微信关联失败,重新登录
*/
private
boolean
wechatRelateUserIfNecessary
(
User
user
,
HttpServletRequest
request
){
Objects
.
requireNonNull
(
request
,
"无效请求"
);
String
clientIp
=
IPUtil
.
getRemoteIP
(
request
);
Set
<
String
>
paramKeys
=
request
.
getParameterMap
().
keySet
();
boolean
ready
=
paramKeys
.
contains
(
Constants
.
OPEN_ID
);
if
(!
ready
){
return
true
;
}
else
if
(
Objects
.
isNull
(
user
)
||
Objects
.
isNull
(
user
.
getId
())
||
StringUtils
.
isBlank
(
request
.
getParameter
(
Constants
.
OPEN_ID
))){
LOGGER
.
warn
(
"微信关联失败,user:{}, request:{}"
,
user
,
request
);
return
false
;
}
Long
userId
=
user
.
getId
();
String
phoneNo
=
user
.
getPhoneNo
();
try
{
int
rows
=
wechatService
.
relateUser
(
userId
,
phoneNo
,
request
.
getParameter
(
Constants
.
OPEN_ID
));
return
rows
>
0
;
}
catch
(
Exception
e
){
LOGGER
.
error
(
"微信关联失败,user:{}, request:{}"
,
user
,
request
,
e
);
}
return
false
;
}
/**
...
...
@@ -471,15 +503,18 @@ public class UserController implements IBaseController {
* @param openId - 微信openId
* @return
*/
@LogHttpCaller
@RequestMapping
(
"/associate_wechat"
)
public
JsonResult
associateWithWechat
(
String
openId
)
{
public
JsonResult
associateWithWechat
(
String
openId
,
HttpServletRequest
request
)
{
User
user
=
getCurrentUserFromRedis
();
if
(
Objects
.
isNull
(
user
)
||
Objects
.
isNull
(
user
.
getId
())){
LOGGER
.
error
(
"[UserController][associateWithWechat][非法请求]微信关联,user:{},openId:{},request:{}"
,
user
,
openId
,
request
);
return
JsonResult
.
buildSuccessResult
(
"[非法请求]微信关联"
,
null
,
1L
);
/*if(Objects.isNull(user) || Objects.isNull(user.getId())){
LOGGER.warn("微信关联失败,用户未登录:user:[{}],openId:[{}]",user,openId);
return JsonResult.buildErrorStateResult("请登陆后重新操作", null);
}
Long userId = user.getId();
/* 判断用户是否已绑定其他微信 */
*//* 判断用户是否已绑定其他微信 *//*
WechatUserInfo userInfoInDb = wechatService.queryByUserId(userId);
if (Objects.nonNull(userInfoInDb)) {
if(Objects.equals(openId, userInfoInDb.getOpenId())){
...
...
@@ -494,7 +529,7 @@ public class UserController implements IBaseController {
wechatService.forbiddenUserWeChat(userId);
}
}
/* 执行绑定 */
*//* 执行绑定 *//*
WechatUserInfo userInfo = wechatService.findWechatUserInfoFromDb(openId);
LOGGER.info("微信关联:user:[{}],openId:[{}],wechatUserInfo:[{}]",user,openId,userInfo);
// 无微信信息
...
...
@@ -507,11 +542,11 @@ public class UserController implements IBaseController {
LOGGER.warn("微信关联失败,该微信已经被其他用户绑定:user:[{}],openId:[{}],wechatUserInfo:[{}]",user,openId,userInfo);
return JsonResult.buildErrorStateResult("该微信已经被其他用户绑定", null);
}
/*
*/
/*
* 未绑定信用钱包用户
*/
*/
/*
try {
int
rows
=
wechatService
.
binding
User
(
userId
,
user
.
getPhoneNo
(),
openId
);
int rows = wechatService.
relate
User(userId, user.getPhoneNo(), openId);
if(rows > 0){
LOGGER.info("微信关联成功:rows:{}, user:[{}],openId:[{}],wechatUserInfo:[{}]",rows,user,openId,userInfo);
return JsonResult.buildSuccessResult("微信关联成功", null);
...
...
@@ -523,7 +558,7 @@ public class UserController implements IBaseController {
// 不做绑定
LOGGER.warn("微信关联失败,保存遇到问题:user:[{}],openId:[{}],wechatUserInfo:[{}]",user,openId,userInfo, ex);
return JsonResult.buildErrorStateResult("微信关联失败", null);
}
}
*/
}
/**
...
...
src/main/java/cn/quantgroup/xyqb/exception/WechatRelateUserException.java
0 → 100644
View file @
18f93b0a
package
cn
.
quantgroup
.
xyqb
.
exception
;
/**
* 微信关联用户异常
* @author 任文超
* @time 2018-04-03
*/
public
class
WechatRelateUserException
extends
RuntimeException
{
private
static
final
long
serialVersionUID
=
-
1L
;
public
WechatRelateUserException
(
String
msg
,
Throwable
t
)
{
super
(
msg
,
t
);
}
public
WechatRelateUserException
(
String
msg
)
{
super
(
msg
);
}
}
src/main/java/cn/quantgroup/xyqb/repository/IWeChatUserRepository.java
View file @
18f93b0a
...
...
@@ -7,6 +7,8 @@ import org.springframework.data.jpa.repository.Modifying;
import
org.springframework.data.jpa.repository.Query
;
import
org.springframework.transaction.annotation.Transactional
;
import
static
org
.
springframework
.
transaction
.
annotation
.
Propagation
.
MANDATORY
;
/**
* Created by 11 on 2017/1/18.
*/
...
...
@@ -23,8 +25,27 @@ public interface IWeChatUserRepository extends JpaRepository<WechatUserInfo, Lon
@Modifying
int
removeByUserId
(
Long
userId
);
/**
* 关联用户
* @param userId - 用户标识
* @param phoneNo
* @param openId - 微信标识
* @return 记录更新行数
*/
@Transactional
@Modifying
@Query
(
value
=
"update wechat_userinfo set user_id=?1,phone_no=?2 where open_id=?3 and user_id is null"
,
nativeQuery
=
true
)
int
bindingUser
(
Long
userId
,
String
phoneNo
,
String
openId
);
int
relateUser
(
Long
userId
,
String
phoneNo
,
String
openId
);
/**
* 解除关联关系 -- 包括:1、当前微信旧的关联用户;2、当前用户旧的关联微信
* 强制事务
* @param openId - 微信标识
* @param userId - 用户标识
* @return 记录更新行数
*/
@Transactional
(
propagation
=
MANDATORY
)
@Modifying
@Query
(
value
=
"update wechat_userinfo set user_id=null,phone_no='*' where open_id=?1 or user_id=?2"
,
nativeQuery
=
true
)
int
dissociateUser
(
String
openId
,
Long
userId
);
}
src/main/java/cn/quantgroup/xyqb/service/session/ISessionService.java
View file @
18f93b0a
...
...
@@ -12,7 +12,18 @@ import cn.quantgroup.xyqb.model.session.SessionValue;
*/
public
interface
ISessionService
{
/**
* 更新session
* 用户信息存在,更新session中的最后访问时间,重新写入缓存.
* 存在则保存用户session信息,userId为uuid
*
* @param channelId
* @param createdFrom
* @param appChannel
* @param user
* @param merchant
* @return
*/
AuthBean
createSession
(
Long
channelId
,
Long
createdFrom
,
String
appChannel
,
User
user
,
Merchant
merchant
);
SessionStruct
createSessionAndPersist
(
User
user
,
LoginProperties
loginProperties
);
...
...
src/main/java/cn/quantgroup/xyqb/service/session/impl/SessionServiceImpl.java
View file @
18f93b0a
...
...
@@ -44,6 +44,18 @@ public class SessionServiceImpl implements ISessionService {
@Autowired
private
IUserService
userService
;
/**
* 更新session
* 用户信息存在,更新session中的最后访问时间,重新写入缓存.
* 存在则保存用户session信息,userId为uuid
*
* @param channelId
* @param createdFrom
* @param appChannel
* @param user
* @param merchant
* @return
*/
@Override
public
AuthBean
createSession
(
Long
channelId
,
Long
createdFrom
,
String
appChannel
,
User
user
,
Merchant
merchant
)
{
AuthBean
authBean
=
new
AuthBean
();
...
...
src/main/java/cn/quantgroup/xyqb/service/wechat/IWechatService.java
View file @
18f93b0a
...
...
@@ -17,8 +17,21 @@ public interface IWechatService {
WechatUserInfo
saveWechatUserInfo
(
WechatUserInfo
userInfo
);
int
bindingUser
(
Long
userId
,
String
phoneNo
,
String
openId
);
/**
* 关联用户和微信
* @param userId - 用户标识
* @param phoneNo
* @param openId - 微信标识
* @return
*/
int
relateUser
(
Long
userId
,
String
phoneNo
,
String
openId
);
/**
* 按userId查微信信息
* 此接口实现处不应加缓存,否则解绑时(在关联用户的事务中)不好清除
* @param userId - 用户标识
* @return
*/
WechatUserInfo
queryByUserId
(
Long
userId
);
int
forbiddenUserWeChat
(
Long
userId
);
...
...
src/main/java/cn/quantgroup/xyqb/service/wechat/impl/WechatServiceImpl.java
View file @
18f93b0a
package
cn
.
quantgroup
.
xyqb
.
service
.
wechat
.
impl
;
import
cn.quantgroup.xyqb.entity.WechatUserInfo
;
import
cn.quantgroup.xyqb.exception.WechatRelateUserException
;
import
cn.quantgroup.xyqb.model.webchat.AccessTokenResponse
;
import
cn.quantgroup.xyqb.repository.IWeChatUserRepository
;
import
cn.quantgroup.xyqb.service.http.IHttpService
;
import
cn.quantgroup.xyqb.service.session.ISessionService
;
import
cn.quantgroup.xyqb.service.wechat.IWechatService
;
import
cn.quantgroup.xyqb.util.ValidationUtil
;
import
com.alibaba.fastjson.JSON
;
import
com.alibaba.fastjson.JSONObject
;
import
lombok.extern.slf4j.Slf4j
;
...
...
@@ -14,12 +17,14 @@ import org.springframework.beans.factory.annotation.Qualifier;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.cache.annotation.CacheEvict
;
import
org.springframework.cache.annotation.Cacheable
;
import
org.springframework.cache.annotation.Caching
;
import
org.springframework.data.domain.Example
;
import
org.springframework.data.redis.core.RedisTemplate
;
import
org.springframework.stereotype.Service
;
import
org.springframework.transaction.annotation.Transactional
;
import
javax.annotation.PostConstruct
;
import
javax.annotation.Resource
;
import
java.util.Objects
;
import
java.util.Optional
;
import
java.util.concurrent.TimeUnit
;
...
...
@@ -32,19 +37,21 @@ import java.util.concurrent.TimeUnit;
public
class
WechatServiceImpl
implements
IWechatService
{
private
static
final
String
WECHAT_TOKEN_KEY_PREFIX
=
"wechat:token:"
;
private
static
final
String
WECHAT_USERINFO_KEY_PREFIX
=
"wechat:userinfo:"
;
@Autowired
private
IHttpService
httpService
;
@Autowired
@Qualifier
(
"stringRedisTemplate"
)
private
RedisTemplate
<
String
,
String
>
redisTemplate
;
@Value
(
"${wechat.appid}"
)
private
String
appId
;
@Value
(
"${wechat.secret}"
)
private
String
secret
;
@Autowired
private
IWeChatUserRepository
weChatUserRepository
;
private
String
accessTokenUrl
;
private
String
refreshTokenUrl
=
"https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=%s&grant_type=refresh_token&refresh_token=%s"
;
@Resource
private
IHttpService
httpService
;
@Resource
private
ISessionService
sessionService
;
@Resource
private
IWeChatUserRepository
weChatUserRepository
;
@Autowired
@Qualifier
(
"stringRedisTemplate"
)
private
RedisTemplate
<
String
,
String
>
redisTemplate
;
@PostConstruct
private
void
init
()
{
...
...
@@ -136,15 +143,36 @@ public class WechatServiceImpl implements IWechatService {
@Override
@CacheEvict
(
value
=
"WechatUserInfo"
,
key
=
"'openId:' + #openId"
,
cacheManager
=
"cacheManager"
)
@Transactional
(
rollbackFor
=
Exception
.
class
)
public
int
bindingUser
(
Long
userId
,
String
phoneNo
,
String
openId
)
{
if
(
Objects
.
isNull
(
userId
)
||
Objects
.
isNull
(
openId
)){
public
int
relateUser
(
Long
userId
,
String
phoneNo
,
String
openId
)
{
if
(
Objects
.
isNull
(
userId
)
||
Objects
.
isNull
(
openId
)
||
StringUtils
.
isBlank
(
openId
)){
log
.
error
(
"微信关联失败:非法入参:[service]:userId:{},phoneNo:{},openId:{}"
,
userId
,
phoneNo
,
openId
);
return
0
;
}
return
weChatUserRepository
.
bindingUser
(
userId
,
Optional
.
ofNullable
(
phoneNo
).
orElse
(
""
),
openId
);
/* 如果当前openId已关联其他用户,则解绑成功后要注销其登录session */
WechatUserInfo
wechatUserInfo
=
weChatUserRepository
.
findByUserId
(
userId
);
// 强制解除关联
int
dissociate
=
weChatUserRepository
.
dissociateUser
(
openId
,
userId
);
if
(
dissociate
<
1
){
log
.
error
(
"微信关联失败:解绑条数<1:[service]:userId:{},phoneNo:{},openId:{}"
,
userId
,
phoneNo
,
openId
);
throw
new
WechatRelateUserException
(
"微信关联失败"
);
}
int
relate
=
weChatUserRepository
.
relateUser
(
userId
,
Optional
.
ofNullable
(
phoneNo
).
orElse
(
""
),
openId
);
if
(
relate
<
1
){
log
.
error
(
"微信关联失败:绑定条数<1:[service]:userId:{},phoneNo:{},openId:{}"
,
userId
,
phoneNo
,
openId
);
throw
new
WechatRelateUserException
(
"微信关联失败"
);
}
else
if
(
Objects
.
nonNull
(
wechatUserInfo
)
&&
Objects
.
nonNull
(
wechatUserInfo
.
getUserId
())){
// 如果当前openId已关联其他用户,则解绑成功后要注销其登录session
sessionService
.
deleteByUserId
(
wechatUserInfo
.
getUserId
());
}
log
.
info
(
"微信关联成功:[service]:userId:{},phoneNo:{},openId:{},dissociate:{},relate:{}"
,
userId
,
phoneNo
,
openId
,
dissociate
,
relate
);
return
relate
;
}
@Override
public
WechatUserInfo
findWechatUserInfoByPhoneNo
(
String
phoneNo
)
{
if
(!
ValidationUtil
.
validatePhoneNo
(
phoneNo
)){
return
null
;
}
return
weChatUserRepository
.
findByPhoneNo
(
phoneNo
);
}
...
...
@@ -163,15 +191,19 @@ public class WechatServiceImpl implements IWechatService {
return
httpService
.
get
(
String
.
format
(
refreshTokenUrl
,
refreshToken
));
}
/**
* 按userId查微信信息
* 此处不应加缓存,否则解绑时不好清除
* @param userId - 用户标识
* @return
*/
@Override
@Cacheable
(
value
=
"WechatUserInfo"
,
key
=
"'userId:' + #userId"
,
unless
=
"#result == null"
,
cacheManager
=
"cacheManager"
)
public
WechatUserInfo
queryByUserId
(
Long
userId
)
{
return
weChatUserRepository
.
findByUserId
(
userId
);
}
@Override
@CacheEvict
(
value
=
"WechatUserInfo"
,
key
=
"'userId:' + #userId"
,
cacheManager
=
"cacheManager"
)
public
int
forbiddenUserWeChat
(
Long
userId
)
{
return
weChatUserRepository
.
removeByUserId
(
userId
);
}
...
...
Write
Preview
Markdown
is supported
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