Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
S
spring-microservice-exam
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
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
汪想
spring-microservice-exam
Commits
131f4c8e
Commit
131f4c8e
authored
Jul 02, 2019
by
tangyi
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
优化
parent
eeaaf0e2
Show whitespace changes
Inline
Side-by-side
Showing
35 changed files
with
574 additions
and
102 deletions
+574
-102
CHANGELOG.md
CHANGELOG.md
+9
-0
CommonConstant.java
...om/github/tangyi/common/core/constant/CommonConstant.java
+16
-1
ServiceConstant.java
...m/github/tangyi/common/core/constant/ServiceConstant.java
+5
-0
LoginType.java
...n/java/com/github/tangyi/common/core/enums/LoginType.java
+45
-0
SecurityConstant.java
...hub/tangyi/common/security/constant/SecurityConstant.java
+5
-0
TenantTokenFilter.java
...thub/tangyi/common/security/filter/TenantTokenFilter.java
+0
-1
auth-service.yml
config-service/src/main/resources/config/auth-service.yml
+2
-0
exam-service.yml
config-service/src/main/resources/config/exam-service.yml
+2
-0
gateway-service.yml
config-service/src/main/resources/config/gateway-service.yml
+1
-0
monitor-service.yml
config-service/src/main/resources/config/monitor-service.yml
+2
-2
msc-service.yml
config-service/src/main/resources/config/msc-service.yml
+8
-16
user-service.yml
config-service/src/main/resources/config/user-service.yml
+3
-0
TokenRequestGlobalFilter.java
...thub/tangyi/gateway/filters/TokenRequestGlobalFilter.java
+2
-2
ValidateCodeFilter.java
...com/github/tangyi/gateway/filters/ValidateCodeFilter.java
+26
-7
AccessToken.java
...ain/java/com/github/tangyi/gateway/model/AccessToken.java
+5
-0
SwaggerConfig.java
...ain/java/com/github/tangyi/auth/config/SwaggerConfig.java
+32
-8
CustomTokenConverter.java
...com/github/tangyi/auth/security/CustomTokenConverter.java
+8
-2
CustomUserDetailsServiceImpl.java
...ub/tangyi/auth/security/CustomUserDetailsServiceImpl.java
+16
-10
SwaggerConfig.java
...ain/java/com/github/tangyi/exam/config/SwaggerConfig.java
+32
-8
MscServiceApplication.java
...ain/java/com/github/tangyi/msc/MscServiceApplication.java
+13
-1
SwaggerConfig.java
...main/java/com/github/tangyi/msc/config/SwaggerConfig.java
+32
-8
bootstrap.yml
...ice-api-impl/msc-service/src/main/resources/bootstrap.yml
+8
-8
pom.xml
service-api-impl/user-service/pom.xml
+6
-0
SwaggerConfig.java
...ain/java/com/github/tangyi/user/config/SwaggerConfig.java
+32
-8
MobileController.java
...a/com/github/tangyi/user/controller/MobileController.java
+40
-0
UserController.java
...ava/com/github/tangyi/user/controller/UserController.java
+20
-3
ValidateCodeController.java
...github/tangyi/user/controller/ValidateCodeController.java
+8
-11
UserMapper.java
...c/main/java/com/github/tangyi/user/mapper/UserMapper.java
+9
-0
MobileService.java
...in/java/com/github/tangyi/user/service/MobileService.java
+67
-0
UserService.java
...main/java/com/github/tangyi/user/service/UserService.java
+22
-6
UserMapper.xml
...mpl/user-service/src/main/resources/mapper/UserMapper.xml
+5
-0
SmsConstant.java
.../java/com/github/tangyi/msc/api/constant/SmsConstant.java
+5
-0
MscServiceClient.java
...ava/com/github/tangyi/msc/api/feign/MscServiceClient.java
+31
-0
MscServiceClientFallbackFactory.java
...sc/api/feign/factory/MscServiceClientFallbackFactory.java
+23
-0
MscServiceClientFallbackImpl.java
.../msc/api/feign/fallback/MscServiceClientFallbackImpl.java
+34
-0
No files found.
CHANGELOG.md
View file @
131f4c8e
Version v3.0.0 (2019-7-2)
--------------------------
改进:
*
优化swagger ui配置,增加租户标识请求头
*
完善手机号登录
Version v3.0.0 (2019-6-23)
--------------------------
...
...
common/common-core/src/main/java/com/github/tangyi/common/core/constant/CommonConstant.java
View file @
131f4c8e
...
...
@@ -126,7 +126,12 @@ public class CommonConstant {
/**
* 保存code的前缀
*/
public
static
final
String
DEFAULT_CODE_KEY
=
"DEFAULT_CODE_KEY"
;
public
static
final
String
DEFAULT_CODE_KEY
=
"DEFAULT_CODE_KEY_"
;
/**
* 验证码长度
*/
public
static
final
String
CODE_SIZE
=
"4"
;
/**
* Bearer
...
...
@@ -138,5 +143,15 @@ public class CommonConstant {
*/
public
static
final
String
GRANT_TYPE_PASSWORD
=
"password"
;
/**
* 手机号类型
*/
public
static
final
String
GRANT_TYPE_MOBILE
=
"mobile"
;
/**
* 租户编号请求头
*/
public
static
final
String
TENANT_CODE_HEADER
=
"Tenant-Code"
;
}
common/common-core/src/main/java/com/github/tangyi/common/core/constant/ServiceConstant.java
View file @
131f4c8e
...
...
@@ -22,4 +22,9 @@ public class ServiceConstant {
* 授权服务名称
*/
public
static
final
String
AUTH_SERVICE
=
"auth-service"
;
/**
* 消息中心服务名称
*/
public
static
final
String
MSC_SERVICE
=
"msc-service"
;
}
common/common-core/src/main/java/com/github/tangyi/common/core/enums/LoginType.java
0 → 100644
View file @
131f4c8e
package
com
.
github
.
tangyi
.
common
.
core
.
enums
;
import
lombok.AllArgsConstructor
;
import
lombok.Getter
;
/**
* 登录类型
*
* @author tangyi
* @date 2019/07/02 09:45
*/
@Getter
@AllArgsConstructor
public
enum
LoginType
{
/**
* 账号密码登录
*/
PWD
(
"PWD"
,
"账号密码登录"
),
/**
* 验证码登录
*/
SMS
(
"SMS"
,
"验证码登录"
),
/**
* QQ登录
*/
QQ
(
"QQ"
,
"QQ登录"
),
/**
* 微信登录
*/
WECHAT
(
"WX"
,
"微信登录"
);
/**
* 类型
*/
private
String
type
;
/**
* 描述
*/
private
String
description
;
}
common/common-security/src/main/java/com/github/tangyi/common/security/constant/SecurityConstant.java
View file @
131f4c8e
...
...
@@ -22,6 +22,11 @@ public class SecurityConstant {
public
static
final
int
DEFAULT_IMAGE_EXPIRE
=
60
;
/**
* 默认短信验证码过期时间
*/
public
static
final
int
DEFAULT_SMS_EXPIRE
=
5
*
60
;
/**
* 正常状态
*/
public
static
final
String
NORMAL
=
"0"
;
...
...
common/common-security/src/main/java/com/github/tangyi/common/security/filter/TenantTokenFilter.java
View file @
131f4c8e
...
...
@@ -33,7 +33,6 @@ public class TenantTokenFilter implements Filter {
if
(
tenantCode
==
null
)
tenantCode
=
SecurityConstant
.
DEFAULT_TENANT_CODE
;
TenantContextHolder
.
setTenantCode
(
tenantCode
);
log
.
info
(
"租户code:{}"
,
tenantCode
);
filterChain
.
doFilter
(
request
,
response
);
TenantContextHolder
.
clear
();
}
...
...
config-service/src/main/resources/config/auth-service.yml
View file @
131f4c8e
...
...
@@ -82,6 +82,8 @@ ignore:
-
/csrf
-
/actuator/**
-
/hystrix.sender
-
/v1/sms/**
-
/v1/user/findUserBySocial/**
-
/v1/user/findUserByUsername/**
-
/v1/tenant/findTenantByTenantCode/**
-
/v1/user/checkExist/**
...
...
config-service/src/main/resources/config/exam-service.yml
View file @
131f4c8e
...
...
@@ -106,7 +106,9 @@ ignore:
-
/csrf
-
/actuator/**
-
/hystrix.sender
-
/v1/sms/**
-
/v1/user/findUserByUsername/**
-
/v1/user/findUserBySocial/**
-
/v1/tenant/findTenantByTenantCode/**
-
/v1/menu/findMenuByRole/**
-
/v1/menu/findAllMenu
...
...
config-service/src/main/resources/config/gateway-service.yml
View file @
131f4c8e
...
...
@@ -75,6 +75,7 @@ preview:
-
updateInfo
-
attachment
-
api/exam
# 考试服务
-
api/msc
# 开启网关token转换
gateway
:
...
...
config-service/src/main/resources/config/monitor-service.yml
View file @
131f4c8e
...
...
@@ -2,9 +2,9 @@ server:
port
:
8085
turbine
:
appConfig
:
consul,auth-service,exam-service,user-service,gateway-service
appConfig
:
consul,auth-service,exam-service,user-service,gateway-service
,msc-service
aggregator
:
clusterConfig
:
CONSUL,AUTH-SERVICE,EXAM-SERVICE,USER-SERVICE,GATEWAY-SERVICE
clusterConfig
:
CONSUL,AUTH-SERVICE,EXAM-SERVICE,USER-SERVICE,GATEWAY-SERVICE
,MSC-SERVICE
spring
:
security
:
...
...
config-service/src/main/resources/config/msc-service.yml
View file @
131f4c8e
...
...
@@ -28,8 +28,8 @@ management:
show-details
:
ALWAYS
sms
:
appKey
:
appSecret
:
appKey
:
test
appSecret
:
test
regionId
:
cn-hangzhou
domain
:
dysmsapi.aliyuncs.com
...
...
@@ -43,27 +43,19 @@ ignore:
-
/csrf
-
/actuator/**
-
/hystrix.sender
-
/v1/user/findUserByUsername/**
-
/v1/tenant/findTenantByTenantCode/**
-
/v1/user/checkExist/**
-
/v1/user/updatePassword
-
/v1/menu/findMenuByRole/**
-
/v1/menu/findAllMenu
-
/v1/code/**
-
/v1/attachment/download
-
/v1/log/**
-
/authentication/**
-
/v1/authentication/**
-
/v1/sms/**
-
/**/*.css
-
/**/*.js
-
/social
-
/signin
-
/signup
-
/info
-
/health
-
/metrics/**
-
/loggers/**
# 集群ID生成配置
cluster
:
workId
:
${CLUSTER_WORKID:1}
dataCenterId
:
${CLUSTER_DATA_CENTER_ID:1}
logging
:
level
:
root
:
info
...
...
config-service/src/main/resources/config/user-service.yml
View file @
131f4c8e
...
...
@@ -130,7 +130,10 @@ ignore:
-
/csrf
-
/actuator/**
-
/hystrix.sender
-
/v1/sms/**
-
/v1/mobile/**
-
/v1/user/findUserByUsername/**
-
/v1/user/findUserBySocial/**
-
/v1/tenant/findTenantByTenantCode/**
-
/v1/menu/findMenuByRole/**
-
/v1/menu/findAllMenu
...
...
gateway-service/src/main/java/com/github/tangyi/gateway/filters/TokenRequestGlobalFilter.java
View file @
131f4c8e
...
...
@@ -69,8 +69,8 @@ public class TokenRequestGlobalFilter implements GlobalFilter, Ordered {
if
(
HttpMethod
.
POST
.
matches
(
request
.
getMethodValue
())
&&
StrUtil
.
containsAnyIgnoreCase
(
uri
.
getPath
(),
GatewayConstant
.
OAUTH_TOKEN_URL
,
GatewayConstant
.
REGISTER
,
GatewayConstant
.
MOBILE_TOKEN_URL
))
{
String
grantType
=
request
.
getQueryParams
().
getFirst
(
GatewayConstant
.
GRANT_TYPE
);
// 授权类型为密码模式
if
(
CommonConstant
.
GRANT_TYPE_PASSWORD
.
equals
(
grantType
)
||
GatewayConstant
.
GRANT_TYPE_REFRESH_TOKEN
.
equals
(
grantType
))
{
// 授权类型为密码
、手机号
模式
if
(
CommonConstant
.
GRANT_TYPE_PASSWORD
.
equals
(
grantType
)
||
CommonConstant
.
GRANT_TYPE_MOBILE
.
equals
(
grantType
)
||
GatewayConstant
.
GRANT_TYPE_REFRESH_TOKEN
.
equals
(
grantType
))
{
// 装饰器
ServerHttpResponseDecorator
decoratedResponse
=
new
ServerHttpResponseDecorator
(
exchange
.
getResponse
())
{
@Override
...
...
gateway-service/src/main/java/com/github/tangyi/gateway/filters/ValidateCodeFilter.java
View file @
131f4c8e
...
...
@@ -2,6 +2,7 @@ package com.github.tangyi.gateway.filters;
import
cn.hutool.core.util.StrUtil
;
import
com.github.tangyi.common.core.constant.CommonConstant
;
import
com.github.tangyi.common.core.enums.LoginType
;
import
com.github.tangyi.common.core.exceptions.InvalidValidateCodeException
;
import
com.github.tangyi.common.core.exceptions.ValidateCodeExpiredException
;
import
com.github.tangyi.gateway.constants.GatewayConstant
;
...
...
@@ -40,10 +41,10 @@ public class ValidateCodeFilter implements GlobalFilter, Ordered {
if
(
HttpMethod
.
POST
.
matches
(
request
.
getMethodValue
())
&&
StrUtil
.
containsAnyIgnoreCase
(
uri
.
getPath
(),
GatewayConstant
.
OAUTH_TOKEN_URL
,
GatewayConstant
.
REGISTER
,
GatewayConstant
.
MOBILE_TOKEN_URL
))
{
String
grantType
=
request
.
getQueryParams
().
getFirst
(
GatewayConstant
.
GRANT_TYPE
);
// 授权类型为密码模式、注册才校验验证码
if
(
CommonConstant
.
GRANT_TYPE_PASSWORD
.
equals
(
grantType
)
||
StrUtil
.
containsAnyIgnoreCase
(
uri
.
getPath
(),
GatewayConstant
.
REGISTER
))
{
// 授权类型为密码模式、
手机号、
注册才校验验证码
if
(
CommonConstant
.
GRANT_TYPE_PASSWORD
.
equals
(
grantType
)
||
CommonConstant
.
GRANT_TYPE_MOBILE
.
equals
(
grantType
)
||
StrUtil
.
containsAnyIgnoreCase
(
uri
.
getPath
(),
GatewayConstant
.
REGISTER
))
{
// 校验验证码
checkCode
(
request
);
checkCode
(
request
,
getLoginType
(
grantType
)
);
}
}
return
chain
.
filter
(
exchange
);
...
...
@@ -58,18 +59,23 @@ public class ValidateCodeFilter implements GlobalFilter, Ordered {
* 校验验证码
*
* @param serverHttpRequest serverHttpRequest
* @param loginType loginType
* @throws InvalidValidateCodeException
*/
private
void
checkCode
(
ServerHttpRequest
serverHttpRequest
)
throws
InvalidValidateCodeException
{
private
void
checkCode
(
ServerHttpRequest
serverHttpRequest
,
LoginType
loginType
)
throws
InvalidValidateCodeException
{
MultiValueMap
<
String
,
String
>
params
=
serverHttpRequest
.
getQueryParams
();
// 租户标识
String
tenantCode
=
serverHttpRequest
.
getHeaders
().
getFirst
(
"Tenant-Code"
);
// 验证码
String
code
=
params
.
getFirst
(
"code"
);
if
(
StrUtil
.
isBlank
(
code
))
throw
new
InvalidValidateCodeException
(
"请输入验证码"
);
throw
new
InvalidValidateCodeException
(
"请输入验证码
.
"
);
// 获取随机码
String
randomStr
=
params
.
getFirst
(
"randomStr"
);
// 随机数为空,则获取手机号
if
(
StrUtil
.
isBlank
(
randomStr
))
randomStr
=
params
.
getFirst
(
"mobile"
);
String
key
=
CommonConstant
.
DEFAULT_CODE_KEY
+
randomStr
;
String
key
=
tenantCode
+
":"
+
CommonConstant
.
DEFAULT_CODE_KEY
+
loginType
.
getType
()
+
"@"
+
randomStr
;
// 验证码过期
if
(!
redisTemplate
.
hasKey
(
key
))
throw
new
ValidateCodeExpiredException
(
GatewayConstant
.
EXPIRED_ERROR
);
...
...
@@ -83,9 +89,22 @@ public class ValidateCodeFilter implements GlobalFilter, Ordered {
}
if
(!
StrUtil
.
equals
(
saveCode
,
code
))
{
redisTemplate
.
delete
(
key
);
throw
new
InvalidValidateCodeException
(
"验证码错误
,请重新输入
"
);
throw
new
InvalidValidateCodeException
(
"验证码错误
.
"
);
}
redisTemplate
.
delete
(
key
);
}
/**
* 获取登录类型
*
* @param grantType grantType
* @return LoginType
*/
private
LoginType
getLoginType
(
String
grantType
)
{
if
(
CommonConstant
.
GRANT_TYPE_PASSWORD
.
equals
(
grantType
))
return
LoginType
.
PWD
;
if
(
CommonConstant
.
GRANT_TYPE_MOBILE
.
equals
(
grantType
))
return
LoginType
.
SMS
;
return
LoginType
.
PWD
;
}
}
gateway-service/src/main/java/com/github/tangyi/gateway/model/AccessToken.java
View file @
131f4c8e
...
...
@@ -62,4 +62,9 @@ public class AccessToken implements Serializable {
* 租户标识
*/
private
String
tenantCode
;
/**
* 登录类型
*/
private
String
loginType
;
}
service-api-impl/auth-service/src/main/java/com/github/tangyi/auth/config/SwaggerConfig.java
View file @
131f4c8e
...
...
@@ -34,15 +34,9 @@ public class SwaggerConfig implements WebMvcConfigurer {
@Bean
public
Docket
createRestApi
()
{
ParameterBuilder
tokenBuilder
=
new
ParameterBuilder
();
List
<
Parameter
>
parameterList
=
new
ArrayList
<>();
tokenBuilder
.
name
(
"Authorization"
)
.
defaultValue
(
"去其他请求中获取heard中token参数"
)
.
description
(
"令牌"
)
.
modelRef
(
new
ModelRef
(
"string"
))
.
parameterType
(
"header"
)
.
required
(
true
).
build
();
parameterList
.
add
(
tokenBuilder
.
build
());
parameterList
.
add
(
authorizationParameter
());
parameterList
.
add
(
tenantCodeParameter
());
return
new
Docket
(
DocumentationType
.
SWAGGER_2
)
.
apiInfo
(
apiInfo
())
.
select
()
...
...
@@ -52,6 +46,36 @@ public class SwaggerConfig implements WebMvcConfigurer {
.
globalOperationParameters
(
parameterList
);
}
/**
* Authorization 请求头
* @return Parameter
*/
private
Parameter
authorizationParameter
()
{
ParameterBuilder
tokenBuilder
=
new
ParameterBuilder
();
tokenBuilder
.
name
(
"Authorization"
)
.
defaultValue
(
"bearer authorization参数"
)
.
description
(
"令牌"
)
.
modelRef
(
new
ModelRef
(
"string"
))
.
parameterType
(
"header"
)
.
required
(
true
).
build
();
return
tokenBuilder
.
build
();
}
/**
* Tenant-Code 请求头
* @return Parameter
*/
private
Parameter
tenantCodeParameter
()
{
ParameterBuilder
tokenBuilder
=
new
ParameterBuilder
();
tokenBuilder
.
name
(
"Tenant-Code"
)
.
defaultValue
(
"租户标识"
)
.
description
(
"租户标识"
)
.
modelRef
(
new
ModelRef
(
"string"
))
.
parameterType
(
"header"
)
.
required
(
true
).
build
();
return
tokenBuilder
.
build
();
}
private
ApiInfo
apiInfo
()
{
return
new
ApiInfoBuilder
()
.
title
(
"Swagger API"
)
...
...
service-api-impl/auth-service/src/main/java/com/github/tangyi/auth/security/CustomTokenConverter.java
View file @
131f4c8e
package
com
.
github
.
tangyi
.
auth
.
security
;
import
com.github.tangyi.common.core.constant.CommonConstant
;
import
com.github.tangyi.common.core.enums.LoginType
;
import
com.github.tangyi.common.security.tenant.TenantContextHolder
;
import
org.springframework.security.oauth2.common.DefaultOAuth2AccessToken
;
import
org.springframework.security.oauth2.common.OAuth2AccessToken
;
...
...
@@ -20,12 +21,17 @@ public class CustomTokenConverter extends JwtAccessTokenConverter {
@Override
public
OAuth2AccessToken
enhance
(
OAuth2AccessToken
accessToken
,
OAuth2Authentication
authentication
)
{
if
(
authentication
.
getOAuth2Request
().
getGrantType
().
equalsIgnoreCase
(
CommonConstant
.
GRANT_TYPE_PASSWORD
))
{
final
Map
<
String
,
Object
>
additionalInfo
=
new
HashMap
<>();
String
grantType
=
authentication
.
getOAuth2Request
().
getGrantType
();
// 加入tenantCode
additionalInfo
.
put
(
"tenantCode"
,
TenantContextHolder
.
getTenantCode
());
((
DefaultOAuth2AccessToken
)
accessToken
).
setAdditionalInformation
(
additionalInfo
);
// 加入登录类型,用户名/手机号
if
(
grantType
.
equalsIgnoreCase
(
CommonConstant
.
GRANT_TYPE_PASSWORD
))
{
additionalInfo
.
put
(
"loginType"
,
LoginType
.
PWD
.
getType
());
}
else
if
(
grantType
.
equalsIgnoreCase
(
CommonConstant
.
GRANT_TYPE_MOBILE
))
{
additionalInfo
.
put
(
"loginType"
,
LoginType
.
SMS
.
getType
());
}
((
DefaultOAuth2AccessToken
)
accessToken
).
setAdditionalInformation
(
additionalInfo
);
return
super
.
enhance
(
accessToken
,
authentication
);
}
}
service-api-impl/auth-service/src/main/java/com/github/tangyi/auth/security/CustomUserDetailsServiceImpl.java
View file @
131f4c8e
...
...
@@ -49,12 +49,7 @@ public class CustomUserDetailsServiceImpl implements CustomUserDetailsService {
*/
@Override
public
UserDetails
loadUserByUsernameAndTenantCode
(
String
username
,
String
tenantCode
)
throws
UsernameNotFoundException
,
TenantNotFoundException
{
if
(
StringUtils
.
isBlank
(
tenantCode
))
throw
new
TenantNotFoundException
(
"租户code不能为空."
);
// 先获取租户信息
Tenant
tenant
=
userServiceClient
.
findTenantByTenantCode
(
tenantCode
);
if
(
tenant
==
null
)
throw
new
TenantNotFoundException
(
"租户不存在."
);
Tenant
tenant
=
this
.
validateTenantCode
(
tenantCode
);
UserVo
userVo
=
userServiceClient
.
findUserByUsername
(
username
,
tenantCode
);
if
(
userVo
==
null
)
throw
new
UsernameNotFoundException
(
"用户名不存在."
);
...
...
@@ -72,16 +67,27 @@ public class CustomUserDetailsServiceImpl implements CustomUserDetailsService {
*/
@Override
public
UserDetails
loadUserBySocialAndTenantCode
(
String
social
,
String
tenantCode
)
throws
UsernameNotFoundException
{
Tenant
tenant
=
this
.
validateTenantCode
(
tenantCode
);
UserVo
userVo
=
userServiceClient
.
findUserBySocial
(
social
,
tenantCode
);
if
(
userVo
==
null
)
throw
new
UsernameNotFoundException
(
"用户手机号未注册."
);
return
new
CustomUserDetails
(
social
,
userVo
.
getPassword
(),
CommonConstant
.
STATUS_NORMAL
.
equals
(
userVo
.
getStatus
()),
getAuthority
(
userVo
),
userVo
.
getTenantCode
());
}
/**
* 校验租户标识
*
* @param tenantCode tenantCode
* @return Tenant
*/
private
Tenant
validateTenantCode
(
String
tenantCode
)
throws
TenantNotFoundException
{
if
(
StringUtils
.
isBlank
(
tenantCode
))
throw
new
TenantNotFoundException
(
"租户code不能为空."
);
// 先获取租户信息
Tenant
tenant
=
userServiceClient
.
findTenantByTenantCode
(
tenantCode
);
if
(
tenant
==
null
)
throw
new
TenantNotFoundException
(
"租户不存在."
);
UserVo
userVo
=
userServiceClient
.
findUserBySocial
(
social
,
tenantCode
);
if
(
userVo
==
null
)
throw
new
UsernameNotFoundException
(
"用户名不存在."
);
return
new
CustomUserDetails
(
social
,
userVo
.
getPassword
(),
CommonConstant
.
STATUS_NORMAL
.
equals
(
userVo
.
getStatus
()),
getAuthority
(
userVo
),
userVo
.
getTenantCode
());
return
tenant
;
}
/**
...
...
service-api-impl/exam-service/src/main/java/com/github/tangyi/exam/config/SwaggerConfig.java
View file @
131f4c8e
...
...
@@ -34,15 +34,9 @@ public class SwaggerConfig implements WebMvcConfigurer {
@Bean
public
Docket
createRestApi
()
{
ParameterBuilder
tokenBuilder
=
new
ParameterBuilder
();
List
<
Parameter
>
parameterList
=
new
ArrayList
<>();
tokenBuilder
.
name
(
"Authorization"
)
.
defaultValue
(
"去其他请求中获取heard中token参数"
)
.
description
(
"令牌"
)
.
modelRef
(
new
ModelRef
(
"string"
))
.
parameterType
(
"header"
)
.
required
(
true
).
build
();
parameterList
.
add
(
tokenBuilder
.
build
());
parameterList
.
add
(
authorizationParameter
());
parameterList
.
add
(
tenantCodeParameter
());
return
new
Docket
(
DocumentationType
.
SWAGGER_2
)
.
apiInfo
(
apiInfo
())
.
select
()
...
...
@@ -52,6 +46,36 @@ public class SwaggerConfig implements WebMvcConfigurer {
.
globalOperationParameters
(
parameterList
);
}
/**
* Authorization 请求头
* @return Parameter
*/
private
Parameter
authorizationParameter
()
{
ParameterBuilder
tokenBuilder
=
new
ParameterBuilder
();
tokenBuilder
.
name
(
"Authorization"
)
.
defaultValue
(
"bearer authorization参数"
)
.
description
(
"令牌"
)
.
modelRef
(
new
ModelRef
(
"string"
))
.
parameterType
(
"header"
)
.
required
(
true
).
build
();
return
tokenBuilder
.
build
();
}
/**
* Tenant-Code 请求头
* @return Parameter
*/
private
Parameter
tenantCodeParameter
()
{
ParameterBuilder
tokenBuilder
=
new
ParameterBuilder
();
tokenBuilder
.
name
(
"Tenant-Code"
)
.
defaultValue
(
"租户标识"
)
.
description
(
"租户标识"
)
.
modelRef
(
new
ModelRef
(
"string"
))
.
parameterType
(
"header"
)
.
required
(
true
).
build
();
return
tokenBuilder
.
build
();
}
private
ApiInfo
apiInfo
()
{
return
new
ApiInfoBuilder
()
.
title
(
"Swagger API"
)
...
...
service-api-impl/msc-service/src/main/java/com/github/tangyi/msc/MscServiceApplication.java
View file @
131f4c8e
...
...
@@ -2,8 +2,20 @@ package com.github.tangyi.msc;
import
org.springframework.boot.SpringApplication
;
import
org.springframework.boot.autoconfigure.SpringBootApplication
;
import
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
;
import
org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker
;
import
org.springframework.cloud.client.discovery.EnableDiscoveryClient
;
import
org.springframework.cloud.openfeign.EnableFeignClients
;
import
org.springframework.context.annotation.ComponentScan
;
import
org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity
;
@SpringBootApplication
@SpringBootApplication
(
exclude
=
{
DataSourceAutoConfiguration
.
class
})
@EnableDiscoveryClient
// 扫描api包里的FeignClient
@EnableFeignClients
(
basePackages
=
{
"com.github.tangyi"
})
@ComponentScan
(
basePackages
=
{
"com.github.tangyi"
})
@EnableGlobalMethodSecurity
(
prePostEnabled
=
true
)
@EnableCircuitBreaker
public
class
MscServiceApplication
{
public
static
void
main
(
String
[]
args
)
{
...
...
service-api-impl/msc-service/src/main/java/com/github/tangyi/msc/config/SwaggerConfig.java
View file @
131f4c8e
...
...
@@ -34,15 +34,9 @@ public class SwaggerConfig implements WebMvcConfigurer {
@Bean
public
Docket
createRestApi
()
{
ParameterBuilder
tokenBuilder
=
new
ParameterBuilder
();
List
<
Parameter
>
parameterList
=
new
ArrayList
<>();
tokenBuilder
.
name
(
"Authorization"
)
.
defaultValue
(
"去其他请求中获取heard中token参数"
)
.
description
(
"令牌"
)
.
modelRef
(
new
ModelRef
(
"string"
))
.
parameterType
(
"header"
)
.
required
(
true
).
build
();
parameterList
.
add
(
tokenBuilder
.
build
());
parameterList
.
add
(
authorizationParameter
());
parameterList
.
add
(
tenantCodeParameter
());
return
new
Docket
(
DocumentationType
.
SWAGGER_2
)
.
apiInfo
(
apiInfo
())
.
select
()
...
...
@@ -52,6 +46,36 @@ public class SwaggerConfig implements WebMvcConfigurer {
.
globalOperationParameters
(
parameterList
);
}
/**
* Authorization 请求头
* @return Parameter
*/
private
Parameter
authorizationParameter
()
{
ParameterBuilder
tokenBuilder
=
new
ParameterBuilder
();
tokenBuilder
.
name
(
"Authorization"
)
.
defaultValue
(
"bearer authorization参数"
)
.
description
(
"令牌"
)
.
modelRef
(
new
ModelRef
(
"string"
))
.
parameterType
(
"header"
)
.
required
(
true
).
build
();
return
tokenBuilder
.
build
();
}
/**
* Tenant-Code 请求头
* @return Parameter
*/
private
Parameter
tenantCodeParameter
()
{
ParameterBuilder
tokenBuilder
=
new
ParameterBuilder
();
tokenBuilder
.
name
(
"Tenant-Code"
)
.
defaultValue
(
"租户标识"
)
.
description
(
"租户标识"
)
.
modelRef
(
new
ModelRef
(
"string"
))
.
parameterType
(
"header"
)
.
required
(
true
).
build
();
return
tokenBuilder
.
build
();
}
private
ApiInfo
apiInfo
()
{
return
new
ApiInfoBuilder
()
.
title
(
"Swagger API"
)
...
...
service-api-impl/msc-service/src/main/resources/bootstrap.yml
View file @
131f4c8e
# bootstrap.yml
文件中的内容不能放到application.yml中,否则config部分无法被加载
#
因为config部分的配置先于application.yml被加载,而bootstrap.yml中的配置会先于application.yml加载
# bootstrap.yml
文件中的内容不能放到application.yml中,否则config部分无法被加载
#
因为config部分的配置先于application.yml被加载,而bootstrap.yml中的配置会先于application.yml加载
spring
:
application
:
name
:
msc-service
cloud
:
#
使用consul作为注册中心
#
使用consul作为注册中心
consul
:
host
:
${CONSUL_HOST:localhost}
port
:
${CONSUL_PORT:8500}
# 使用配置服务中心的配置信息
config
:
fail-fast
:
true
#
在某些情况下,如果服务无法连接到配置服务器,则可能希望启动服务失败,客户端将以异常停止
fail-fast
:
true
#
在某些情况下,如果服务无法连接到配置服务器,则可能希望启动服务失败,客户端将以异常停止
retry
:
max-attempts
:
5
#
配置客户端重试,默认行为是重试6次,初始退避间隔为1000ms,指数乘数为
1.1
max-attempts
:
5
#
配置客户端重试,默认行为是重试6次,初始退避间隔为1000ms,指数乘数为1.1
discovery
:
#
默认false,设为true表示使用注册中心中的配置服务(服务发现)而不自己指定配置服务的地址(即uri)
#
默认false,设为true表示使用注册中心中的配置服务(服务发现)而不自己指定配置服务的地址(即uri)
enabled
:
true
#
指向配置中心在consul注册的服务名称(即:spring.application.name)
#
指向配置中心在consul注册的服务名称(即:spring.application.name)
service-id
:
config-service
\ No newline at end of file
service-api-impl/user-service/pom.xml
View file @
131f4c8e
...
...
@@ -36,6 +36,12 @@
<artifactId>
exam-api
</artifactId>
</dependency>
<!-- msc-api -->
<dependency>
<groupId>
com.github.tangyi
</groupId>
<artifactId>
msc-api
</artifactId>
</dependency>
<!-- web 服务 -->
<dependency>
<groupId>
org.springframework.boot
</groupId>
...
...
service-api-impl/user-service/src/main/java/com/github/tangyi/user/config/SwaggerConfig.java
View file @
131f4c8e
...
...
@@ -34,15 +34,9 @@ public class SwaggerConfig implements WebMvcConfigurer {
@Bean
public
Docket
createRestApi
()
{
ParameterBuilder
tokenBuilder
=
new
ParameterBuilder
();
List
<
Parameter
>
parameterList
=
new
ArrayList
<>();
tokenBuilder
.
name
(
"Authorization"
)
.
defaultValue
(
"去其他请求中获取heard中token参数"
)
.
description
(
"令牌"
)
.
modelRef
(
new
ModelRef
(
"string"
))
.
parameterType
(
"header"
)
.
required
(
true
).
build
();
parameterList
.
add
(
tokenBuilder
.
build
());
parameterList
.
add
(
authorizationParameter
());
parameterList
.
add
(
tenantCodeParameter
());
return
new
Docket
(
DocumentationType
.
SWAGGER_2
)
.
apiInfo
(
apiInfo
())
.
select
()
...
...
@@ -52,6 +46,36 @@ public class SwaggerConfig implements WebMvcConfigurer {
.
globalOperationParameters
(
parameterList
);
}
/**
* Authorization 请求头
* @return Parameter
*/
private
Parameter
authorizationParameter
()
{
ParameterBuilder
tokenBuilder
=
new
ParameterBuilder
();
tokenBuilder
.
name
(
"Authorization"
)
.
defaultValue
(
"bearer authorization参数"
)
.
description
(
"令牌"
)
.
modelRef
(
new
ModelRef
(
"string"
))
.
parameterType
(
"header"
)
.
required
(
true
).
build
();
return
tokenBuilder
.
build
();
}
/**
* Tenant-Code 请求头
* @return Parameter
*/
private
Parameter
tenantCodeParameter
()
{
ParameterBuilder
tokenBuilder
=
new
ParameterBuilder
();
tokenBuilder
.
name
(
"Tenant-Code"
)
.
defaultValue
(
"租户标识"
)
.
description
(
"租户标识"
)
.
modelRef
(
new
ModelRef
(
"string"
))
.
parameterType
(
"header"
)
.
required
(
true
).
build
();
return
tokenBuilder
.
build
();
}
private
ApiInfo
apiInfo
()
{
return
new
ApiInfoBuilder
()
.
title
(
"Swagger API"
)
...
...
service-api-impl/user-service/src/main/java/com/github/tangyi/user/controller/MobileController.java
0 → 100644
View file @
131f4c8e
package
com
.
github
.
tangyi
.
user
.
controller
;
import
com.github.tangyi.common.core.model.ResponseBean
;
import
com.github.tangyi.common.core.web.BaseController
;
import
com.github.tangyi.common.security.constant.SecurityConstant
;
import
com.github.tangyi.user.service.MobileService
;
import
io.swagger.annotations.Api
;
import
lombok.AllArgsConstructor
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.web.bind.annotation.*
;
/**
* 手机管理Controller
*
* @author tangyi
* @date 2019/07/02 09:34
*/
@Slf4j
@AllArgsConstructor
@Api
(
"手机管理"
)
@RestController
@RequestMapping
(
"/v1/mobile"
)
public
class
MobileController
extends
BaseController
{
private
final
MobileService
mobileService
;
/**
* 发送短信
*
* @param mobile mobile
* @param tenantCode tenantCode
* @return ResponseBean
* @author tangyi
* @date 2019/07/02 09:49:05
*/
@GetMapping
(
"sendSms/{mobile}"
)
public
ResponseBean
<
Boolean
>
sendSms
(
@PathVariable
String
mobile
,
@RequestHeader
(
SecurityConstant
.
TENANT_CODE_HEADER
)
String
tenantCode
)
{
return
mobileService
.
sendSms
(
mobile
,
tenantCode
);
}
}
service-api-impl/user-service/src/main/java/com/github/tangyi/user/controller/UserController.java
View file @
131f4c8e
...
...
@@ -31,6 +31,7 @@ import org.springframework.http.HttpHeaders;
import
org.springframework.security.access.prepost.PreAuthorize
;
import
org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
;
import
org.springframework.security.crypto.password.PasswordEncoder
;
import
org.springframework.security.oauth2.provider.OAuth2Authentication
;
import
org.springframework.web.bind.annotation.*
;
import
org.springframework.web.multipart.MultipartFile
;
...
...
@@ -38,7 +39,6 @@ import javax.servlet.http.HttpServletRequest;
import
javax.servlet.http.HttpServletResponse
;
import
javax.validation.Valid
;
import
javax.validation.constraints.NotBlank
;
import
java.security.Principal
;
import
java.time.LocalDateTime
;
import
java.util.ArrayList
;
import
java.util.List
;
...
...
@@ -89,9 +89,9 @@ public class UserController extends BaseController {
*/
@GetMapping
(
"info"
)
@ApiOperation
(
value
=
"获取用户信息"
,
notes
=
"获取当前登录用户详细信息"
)
public
ResponseBean
<
UserInfoDto
>
user
(
Principal
principal
)
{
public
ResponseBean
<
UserInfoDto
>
user
(
OAuth2Authentication
authentication
)
{
UserVo
userVo
=
new
UserVo
();
userVo
.
setUsername
(
principal
.
getName
());
userVo
.
setUsername
(
authentication
.
getName
());
userVo
.
setTenantCode
(
SysUtil
.
getTenantCode
());
return
new
ResponseBean
<>(
userService
.
findUserInfo
(
userVo
));
}
...
...
@@ -114,6 +114,23 @@ public class UserController extends BaseController {
}
/**
* 根据用户手机号获取用户详细信息
*
* @param social social
* @param tenantCode tenantCode
* @return UserVo
*/
@GetMapping
(
"/findUserBySocial/{social}"
)
@ApiOperation
(
value
=
"获取用户信息"
,
notes
=
"根据用户手机号获取用户详细信息"
)
@ApiImplicitParams
({
@ApiImplicitParam
(
name
=
"social"
,
value
=
"用户手机号"
,
required
=
true
,
dataType
=
"String"
,
paramType
=
"path"
),
@ApiImplicitParam
(
name
=
"tenantCode"
,
value
=
"租户标识"
,
required
=
true
,
dataType
=
"String"
),
})
public
UserVo
findUserBySocial
(
@PathVariable
String
social
,
@RequestParam
String
tenantCode
)
{
return
userService
.
selectUserVoBySocial
(
social
,
tenantCode
);
}
/**
* 获取分页数据
*
* @param pageNum pageNum
...
...
service-api-impl/user-service/src/main/java/com/github/tangyi/user/controller/ValidateCodeController.java
View file @
131f4c8e
package
com
.
github
.
tangyi
.
user
.
controller
;
import
com.github.tangyi.common.core.exceptions.CommonException
;
import
com.github.tangyi.common.core.web.BaseController
;
import
com.github.tangyi.user.service.UserService
;
import
com.google.code.kaptcha.Producer
;
import
io.swagger.annotations.Api
;
import
io.swagger.annotations.ApiImplicitParam
;
import
io.swagger.annotations.ApiImplicitParams
;
import
io.swagger.annotations.ApiOperation
;
import
lombok.AllArgsConstructor
;
import
org.apache.commons.io.IOUtils
;
import
org.apache.commons.lang.StringUtils
;
import
org.springframework.web.bind.annotation.GetMapping
;
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.bind.annotation.*
;
import
javax.imageio.ImageIO
;
import
javax.servlet.ServletOutputStream
;
...
...
@@ -44,18 +40,19 @@ public class ValidateCodeController extends BaseController {
* @date 2018/9/14 20:13
*/
@ApiOperation
(
value
=
"生成验证码"
,
notes
=
"生成验证码"
)
@ApiImplicitParam
(
name
=
"random"
,
value
=
"随机数"
,
required
=
true
,
dataType
=
"String"
,
paramType
=
"path"
)
@ApiImplicitParams
({
@ApiImplicitParam
(
name
=
"random"
,
value
=
"随机数"
,
required
=
true
,
dataType
=
"String"
,
paramType
=
"path"
),
@ApiImplicitParam
(
name
=
"tenantCode"
,
value
=
"租户标识"
,
required
=
true
,
dataType
=
"String"
)
})
@GetMapping
(
"/{random}"
)
public
void
produceCode
(
@PathVariable
String
random
,
HttpServletResponse
response
)
throws
Exception
{
if
(
StringUtils
.
isEmpty
(
random
))
throw
new
CommonException
(
"随机码不能为空!"
);
public
void
produceCode
(
@PathVariable
String
random
,
@RequestParam
String
tenantCode
,
HttpServletResponse
response
)
throws
Exception
{
response
.
setHeader
(
"Cache-Control"
,
"no-store, no-cache"
);
response
.
setContentType
(
"image/jpeg"
);
// 生成文字验证码
String
text
=
producer
.
createText
();
// 生成图片验证码
BufferedImage
image
=
producer
.
createImage
(
text
);
userService
.
saveImageCode
(
random
,
text
);
userService
.
saveImageCode
(
tenantCode
,
random
,
text
);
ServletOutputStream
out
=
response
.
getOutputStream
();
ImageIO
.
write
(
image
,
"JPEG"
,
out
);
IOUtils
.
closeQuietly
(
out
);
...
...
service-api-impl/user-service/src/main/java/com/github/tangyi/user/mapper/UserMapper.java
View file @
131f4c8e
...
...
@@ -27,6 +27,15 @@ public interface UserMapper extends CrudMapper<User> {
UserVo
selectUserVoByUsername
(
@Param
(
"username"
)
String
username
,
@Param
(
"tenantCode"
)
String
tenantCode
);
/**
* 通过用户手机号查询用户信息(含有角色信息)
*
* @param social 用户手机号
* @param tenantCode 租户标识
* @return userVo
*/
UserVo
selectUserVoBySocial
(
@Param
(
"social"
)
String
social
,
@Param
(
"tenantCode"
)
String
tenantCode
);
/**
* 查询用户数量
*
* @param userVo userVo
...
...
service-api-impl/user-service/src/main/java/com/github/tangyi/user/service/MobileService.java
0 → 100644
View file @
131f4c8e
package
com
.
github
.
tangyi
.
user
.
service
;
import
cn.hutool.core.util.RandomUtil
;
import
com.github.tangyi.common.core.constant.CommonConstant
;
import
com.github.tangyi.common.core.enums.LoginType
;
import
com.github.tangyi.common.core.model.ResponseBean
;
import
com.github.tangyi.common.core.vo.UserVo
;
import
com.github.tangyi.common.security.constant.SecurityConstant
;
import
com.github.tangyi.msc.api.constant.SmsConstant
;
import
com.github.tangyi.msc.api.dto.SmsDto
;
import
com.github.tangyi.msc.api.feign.MscServiceClient
;
import
lombok.AllArgsConstructor
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.data.redis.core.RedisTemplate
;
import
org.springframework.stereotype.Service
;
import
java.util.concurrent.TimeUnit
;
/**
* 手机管理Service
*
* @author tangyi
* @date 2019/07/02 09:35
*/
@Slf4j
@AllArgsConstructor
@Service
public
class
MobileService
{
private
final
UserService
userService
;
private
final
RedisTemplate
redisTemplate
;
private
final
MscServiceClient
mscServiceClient
;
/**
* 发送短信
*
* @param mobile mobile
* @param tenantCode tenantCode
* @return ResponseBean
* @author tangyi
* @date 2019/07/02 09:36:52
*/
public
ResponseBean
<
Boolean
>
sendSms
(
String
mobile
,
String
tenantCode
)
{
UserVo
userVo
=
userService
.
selectUserVoBySocial
(
mobile
,
tenantCode
);
if
(
userVo
==
null
)
{
log
.
info
(
"手机号未注册:{}"
,
mobile
);
return
new
ResponseBean
<>(
Boolean
.
FALSE
,
"手机号未注册."
);
}
Object
codeObj
=
redisTemplate
.
opsForValue
().
get
(
CommonConstant
.
DEFAULT_CODE_KEY
+
mobile
);
if
(
codeObj
!=
null
)
{
log
.
info
(
"手机号验证码未过期:{},{}"
,
mobile
,
codeObj
);
return
new
ResponseBean
<>(
Boolean
.
FALSE
,
"手机号未注册."
);
}
String
code
=
RandomUtil
.
randomNumbers
(
Integer
.
parseInt
(
CommonConstant
.
CODE_SIZE
));
log
.
debug
(
"手机号生成验证码成功:{},{}"
,
mobile
,
code
);
redisTemplate
.
opsForValue
().
set
(
tenantCode
+
":"
+
CommonConstant
.
DEFAULT_CODE_KEY
+
LoginType
.
SMS
.
getType
()
+
"@"
+
mobile
,
code
,
SecurityConstant
.
DEFAULT_SMS_EXPIRE
,
TimeUnit
.
SECONDS
);
// 调用消息中心服务,发送短信验证码
SmsDto
smsDto
=
new
SmsDto
();
smsDto
.
setReceiver
(
mobile
);
smsDto
.
setContent
(
String
.
format
(
SmsConstant
.
SMS_TEMPLATE
,
code
));
mscServiceClient
.
sendSms
(
smsDto
);
return
new
ResponseBean
<>(
Boolean
.
TRUE
,
code
);
}
}
service-api-impl/user-service/src/main/java/com/github/tangyi/user/service/UserService.java
View file @
131f4c8e
package
com
.
github
.
tangyi
.
user
.
service
;
import
com.github.tangyi.common.core.constant.CommonConstant
;
import
com.github.tangyi.common.core.enums.LoginType
;
import
com.github.tangyi.common.core.exceptions.CommonException
;
import
com.github.tangyi.common.core.service.CrudService
;
import
com.github.tangyi.common.core.utils.IdGen
;
...
...
@@ -90,11 +91,14 @@ public class UserService extends CrudService<UserMapper, User> {
* @date 2018/9/11 23:44
*/
public
UserInfoDto
findUserInfo
(
UserVo
userVo
)
{
String
tenantCode
=
userVo
.
getTenantCode
();
String
tenantCode
=
userVo
.
getTenantCode
()
,
username
=
userVo
.
getUsername
()
;
// 根据用户名查询用户信息
userVo
=
userMapper
.
selectUserVoByUsername
(
userVo
.
getUsername
(),
tenantCode
);
userVo
=
userMapper
.
selectUserVoByUsername
(
username
,
tenantCode
);
if
(
userVo
==
null
)
userVo
=
userMapper
.
selectUserVoBySocial
(
username
,
tenantCode
);
if
(
userVo
==
null
)
throw
new
CommonException
(
"查询用户信息失败."
);
UserInfoDto
user
=
new
UserInfoDto
();
if
(
userVo
!=
null
)
{
BeanUtils
.
copyProperties
(
userVo
,
user
);
// 用户角色
List
<
String
>
roles
=
new
ArrayList
<>();
...
...
@@ -123,7 +127,6 @@ public class UserService extends CrudService<UserMapper, User> {
this
.
initUserAvatar
(
user
,
userVo
);
user
.
setRoles
(
roles
.
toArray
(
new
String
[
0
]));
user
.
setPermissions
(
permissions
.
toArray
(
new
String
[
0
]));
}
return
user
;
}
...
...
@@ -215,15 +218,28 @@ public class UserService extends CrudService<UserMapper, User> {
}
/**
* 根据用户手机号查找
*
* @param social social
* @param tenantCode tenantCode
* @return UserVo
*/
@Cacheable
(
value
=
"user"
,
key
=
"#social"
)
public
UserVo
selectUserVoBySocial
(
String
social
,
String
tenantCode
)
{
return
userMapper
.
selectUserVoBySocial
(
social
,
tenantCode
);
}
/**
* 保存验证码
*
* @param tenantCode tenantCode
* @param random random
* @param imageCode imageCode
* @author tangyi
* @date 2018/9/14 20:12
*/
public
void
saveImageCode
(
String
random
,
String
imageCode
)
{
redisTemplate
.
opsForValue
().
set
(
CommonConstant
.
DEFAULT_CODE_KEY
+
random
,
imageCode
,
SecurityConstant
.
DEFAULT_IMAGE_EXPIRE
,
TimeUnit
.
SECONDS
);
public
void
saveImageCode
(
String
tenantCode
,
String
random
,
String
imageCode
)
{
redisTemplate
.
opsForValue
().
set
(
tenantCode
+
":"
+
CommonConstant
.
DEFAULT_CODE_KEY
+
LoginType
.
PWD
.
getType
()
+
"@"
+
random
,
imageCode
,
SecurityConstant
.
DEFAULT_IMAGE_EXPIRE
,
TimeUnit
.
SECONDS
);
}
/**
...
...
service-api-impl/user-service/src/main/resources/mapper/UserMapper.xml
View file @
131f4c8e
...
...
@@ -152,6 +152,11 @@
WHERE `user`.username = #{username} and `user`.tenant_code = #{tenantCode} and `user`.del_flag = 0
</select>
<select
id=
"selectUserVoBySocial"
resultMap=
"userVoResultMap"
>
<include
refid=
"selectUserVo"
/>
WHERE `user`.phone = #{social} and `user`.tenant_code = #{tenantCode} and `user`.del_flag = 0
</select>
<select
id=
"get"
resultMap=
"userResultMap"
>
SELECT
<include
refid=
"userColumns"
/>
...
...
service-api/msc-api/src/main/java/com/github/tangyi/msc/api/constant/SmsConstant.java
View file @
131f4c8e
...
...
@@ -5,4 +5,9 @@ package com.github.tangyi.msc.api.constant;
* @date 2019/6/22 13:18
*/
public
class
SmsConstant
{
/**
* 短信模板
*/
public
static
final
String
SMS_TEMPLATE
=
"验证码:%s,本验证码有效时间5分钟,请勿告知其他人。"
;
}
service-api/msc-api/src/main/java/com/github/tangyi/msc/api/feign/MscServiceClient.java
0 → 100644
View file @
131f4c8e
package
com
.
github
.
tangyi
.
msc
.
api
.
feign
;
import
com.github.tangyi.common.core.constant.ServiceConstant
;
import
com.github.tangyi.common.core.model.ResponseBean
;
import
com.github.tangyi.common.feign.config.CustomFeignConfig
;
import
com.github.tangyi.msc.api.dto.SmsDto
;
import
com.github.tangyi.msc.api.feign.factory.MscServiceClientFallbackFactory
;
import
org.springframework.cloud.openfeign.FeignClient
;
import
org.springframework.web.bind.annotation.PostMapping
;
import
org.springframework.web.bind.annotation.RequestBody
;
/**
* 消息中心服务
*
* @author tangyi
* @date 2019/07/02 16:04
*/
@FeignClient
(
value
=
ServiceConstant
.
MSC_SERVICE
,
configuration
=
CustomFeignConfig
.
class
,
fallbackFactory
=
MscServiceClientFallbackFactory
.
class
)
public
interface
MscServiceClient
{
/**
* 发送短信
*
* @param smsDto smsDto
* @return ResponseBean
* @author tangyi
* @date 2019/07/02 16:07:27
*/
@PostMapping
(
"/v1/sms/sendSms"
)
ResponseBean
<?>
sendSms
(
@RequestBody
SmsDto
smsDto
);
}
service-api/msc-api/src/main/java/com/github/tangyi/msc/api/feign/factory/MscServiceClientFallbackFactory.java
0 → 100644
View file @
131f4c8e
package
com
.
github
.
tangyi
.
msc
.
api
.
feign
.
factory
;
import
com.github.tangyi.msc.api.feign.MscServiceClient
;
import
com.github.tangyi.msc.api.feign.fallback.MscServiceClientFallbackImpl
;
import
feign.hystrix.FallbackFactory
;
import
org.springframework.stereotype.Component
;
/**
* 消息中心服务断路器工厂
*
* @author tangyi
* @date 2019/07/02 16:08
*/
@Component
public
class
MscServiceClientFallbackFactory
implements
FallbackFactory
<
MscServiceClient
>
{
@Override
public
MscServiceClient
create
(
Throwable
throwable
)
{
MscServiceClientFallbackImpl
mscServiceClientFallback
=
new
MscServiceClientFallbackImpl
();
mscServiceClientFallback
.
setThrowable
(
throwable
);
return
mscServiceClientFallback
;
}
}
service-api/msc-api/src/main/java/com/github/tangyi/msc/api/feign/fallback/MscServiceClientFallbackImpl.java
0 → 100644
View file @
131f4c8e
package
com
.
github
.
tangyi
.
msc
.
api
.
feign
.
fallback
;
import
com.github.tangyi.common.core.model.ResponseBean
;
import
com.github.tangyi.msc.api.dto.SmsDto
;
import
com.github.tangyi.msc.api.feign.MscServiceClient
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.stereotype.Component
;
/**
* 消息中心服务断路器
*
* @author tangyi
* @date 2019/07/02 16:09
*/
@Slf4j
@Component
public
class
MscServiceClientFallbackImpl
implements
MscServiceClient
{
private
Throwable
throwable
;
@Override
public
ResponseBean
<?>
sendSms
(
SmsDto
smsDto
)
{
log
.
error
(
"feign 发送短信失败:{}, {}, {}"
,
smsDto
.
getReceiver
(),
smsDto
.
getContent
(),
throwable
);
return
null
;
}
public
Throwable
getThrowable
()
{
return
throwable
;
}
public
void
setThrowable
(
Throwable
throwable
)
{
this
.
throwable
=
throwable
;
}
}
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