Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
N
notice-service
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
Packages
Packages
Container Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
SuperHive
back-end
notice-service
Commits
b34f5d7d
Commit
b34f5d7d
authored
Apr 16, 2020
by
huangcb
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Init
parent
1ef70a46
Changes
16
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
1652 additions
and
3 deletions
+1652
-3
RedisComponent.java
...m/esv/freight/notice/common/component/RedisComponent.java
+541
-0
DbDeletedEnum.java
.../java/com/esv/freight/notice/common/em/DbDeletedEnum.java
+1
-1
SmsCaptchaUtils.java
...a/com/esv/freight/notice/common/util/SmsCaptchaUtils.java
+53
-0
CacheConfig.java
src/main/java/com/esv/freight/notice/config/CacheConfig.java
+154
-0
SmsCaptchaController.java
...ht/notice/module/sms/controller/SmsCaptchaController.java
+101
-0
SmsCaptchaDao.java
.../com/esv/freight/notice/module/sms/dao/SmsCaptchaDao.java
+35
-0
CaptchaEnum.java
...ava/com/esv/freight/notice/module/sms/em/CaptchaEnum.java
+56
-0
SmsCaptchaEntity.java
...sv/freight/notice/module/sms/entity/SmsCaptchaEntity.java
+56
-0
CaptchaForm.java
...a/com/esv/freight/notice/module/sms/form/CaptchaForm.java
+31
-0
SmsCaptchaService.java
.../freight/notice/module/sms/service/SmsCaptchaService.java
+36
-0
SmsCaptchaServiceImpl.java
...notice/module/sms/service/impl/SmsCaptchaServiceImpl.java
+186
-0
application-dev.yml
src/main/resources/application-dev.yml
+19
-1
application-test.yml
src/main/resources/application-test.yml
+19
-1
SmsCaptchaDao.xml
src/main/resources/mapper/sms/SmsCaptchaDao.xml
+41
-0
SmsCaptchaUtilsTest.java
...m/esv/freight/notice/common/util/SmsCaptchaUtilsTest.java
+54
-0
SmsCaptchaControllerTest.java
...otice/module/sms/controller/SmsCaptchaControllerTest.java
+269
-0
No files found.
src/main/java/com/esv/freight/notice/common/component/RedisComponent.java
0 → 100644
View file @
b34f5d7d
This diff is collapsed.
Click to expand it.
src/main/java/com/esv/freight/notice/common/
constants
/DbDeletedEnum.java
→
src/main/java/com/esv/freight/notice/common/
em
/DbDeletedEnum.java
View file @
b34f5d7d
package
com
.
esv
.
freight
.
notice
.
common
.
constants
;
package
com
.
esv
.
freight
.
notice
.
common
.
em
;
/**
/**
* @description: DB记录是否删除标识
* @description: DB记录是否删除标识
...
...
src/main/java/com/esv/freight/notice/common/util/SmsCaptchaUtils.java
0 → 100644
View file @
b34f5d7d
package
com
.
esv
.
freight
.
notice
.
common
.
util
;
import
java.util.Random
;
/**
* @description: 短信验证码工具类
* @project: notice-service
* @name: com.esv.freight.notice.common.util.SmsCaptchaUtils
* @author: 黄朝斌
* @email: huangchaobin@esvtek.com
* @createTime: 2020/04/15 16:51
* @version:1.0
*/
public
class
SmsCaptchaUtils
{
/**
* 短信验证码字符序列
**/
private
static
final
char
[]
chars
=
{
'0'
,
'1'
,
'2'
,
'3'
,
'4'
,
'5'
,
'6'
,
'7'
,
'8'
,
'9'
};
/**
* 短信验证码默认长度
**/
public
static
final
int
DEFAULT_SIZE
=
6
;
/**
* description 获取默认长度(6位)的短信验证码
* param []
* return java.lang.String
* author Administrator
* createTime 2020/04/15 16:56
**/
public
static
String
getCaptcha
()
{
return
getCaptcha
(
DEFAULT_SIZE
);
}
/**
* description 获取指定长度的短信验证码
* param [size]
* return java.lang.String
* author Administrator
* createTime 2020/04/15 16:54
**/
public
static
String
getCaptcha
(
int
size
)
{
StringBuffer
stringBuffer
=
new
StringBuffer
();
for
(
int
i
=
0
;
i
<
size
;
i
++)
{
int
n
=
new
Random
().
nextInt
(
chars
.
length
);
stringBuffer
.
append
(
chars
[
n
]);
}
return
stringBuffer
.
toString
();
}
}
src/main/java/com/esv/freight/notice/config/CacheConfig.java
0 → 100644
View file @
b34f5d7d
package
com
.
esv
.
freight
.
notice
.
config
;
import
com.fasterxml.jackson.annotation.JsonAutoDetect
;
import
com.fasterxml.jackson.annotation.PropertyAccessor
;
import
com.fasterxml.jackson.databind.ObjectMapper
;
import
org.springframework.cache.CacheManager
;
import
org.springframework.cache.annotation.EnableCaching
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.data.redis.cache.RedisCacheConfiguration
;
import
org.springframework.data.redis.cache.RedisCacheManager
;
import
org.springframework.data.redis.connection.RedisConnectionFactory
;
import
org.springframework.data.redis.core.*
;
import
org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer
;
import
org.springframework.data.redis.serializer.RedisSerializationContext
;
import
org.springframework.data.redis.serializer.RedisSerializer
;
import
org.springframework.data.redis.serializer.StringRedisSerializer
;
import
java.time.Duration
;
/**
* @description: Cache配置类
* @project: freight-file-service
* @name: com.esv.freight.notice.config.CacheConfig
* @author: 黄朝斌
* @email: huangchaobin@esvtek.com
* @createTime: 2020/04/09 9:57
* @version:1.0
*/
@Configuration
@EnableCaching
public
class
CacheConfig
{
/**
* description 为SpringCache注册缓存管理器
* param [redisConnectionFactory]
* return org.springframework.cache.CacheManager
* author Administrator
* createTime 2020/03/19 14:26
**/
@Bean
public
CacheManager
cacheManager
(
RedisConnectionFactory
redisConnectionFactory
)
{
long
timeToLive
=
60L
;
RedisSerializer
<
String
>
redisSerializer
=
new
StringRedisSerializer
();
Jackson2JsonRedisSerializer
jackson2JsonRedisSerializer
=
new
Jackson2JsonRedisSerializer
(
Object
.
class
);
// 解决查询缓存转换异常的问题
ObjectMapper
om
=
new
ObjectMapper
();
om
.
setVisibility
(
PropertyAccessor
.
ALL
,
JsonAutoDetect
.
Visibility
.
ANY
);
om
.
enableDefaultTyping
(
ObjectMapper
.
DefaultTyping
.
NON_FINAL
);
jackson2JsonRedisSerializer
.
setObjectMapper
(
om
);
// 配置序列化(解决乱码的问题)
RedisCacheConfiguration
config
=
RedisCacheConfiguration
.
defaultCacheConfig
()
.
entryTtl
(
Duration
.
ofMinutes
(
timeToLive
))
.
serializeKeysWith
(
RedisSerializationContext
.
SerializationPair
.
fromSerializer
(
redisSerializer
))
.
serializeValuesWith
(
RedisSerializationContext
.
SerializationPair
.
fromSerializer
(
jackson2JsonRedisSerializer
));
RedisCacheManager
cacheManager
=
RedisCacheManager
.
builder
(
redisConnectionFactory
)
.
cacheDefaults
(
config
)
.
build
();
return
cacheManager
;
}
/**
* RedisTemplate相关配置
* @param factory
* @return
*/
@Bean
public
RedisTemplate
<
String
,
Object
>
redisTemplate
(
RedisConnectionFactory
factory
)
{
RedisTemplate
<
String
,
Object
>
template
=
new
RedisTemplate
<>();
// 配置连接工厂
template
.
setConnectionFactory
(
factory
);
//使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值(默认使用JDK的序列化方式)
Jackson2JsonRedisSerializer
jacksonSeial
=
new
Jackson2JsonRedisSerializer
(
Object
.
class
);
ObjectMapper
om
=
new
ObjectMapper
();
// 指定要序列化的域,field,get和set,以及修饰符范围,ANY是都有包括private和public
om
.
setVisibility
(
PropertyAccessor
.
ALL
,
JsonAutoDetect
.
Visibility
.
ANY
);
// 指定序列化输入的类型,类必须是非final修饰的,final修饰的类,比如String,Integer等会跑出异常
om
.
enableDefaultTyping
(
ObjectMapper
.
DefaultTyping
.
NON_FINAL
);
jacksonSeial
.
setObjectMapper
(
om
);
// 值采用json序列化
template
.
setValueSerializer
(
jacksonSeial
);
//使用StringRedisSerializer来序列化和反序列化redis的key值
template
.
setKeySerializer
(
new
StringRedisSerializer
());
// 设置hash key 和value序列化模式
template
.
setHashKeySerializer
(
new
StringRedisSerializer
());
template
.
setHashValueSerializer
(
jacksonSeial
);
template
.
afterPropertiesSet
();
return
template
;
}
/**
* 对hash类型的数据操作
*
* @param redisTemplate
* @return
*/
@Bean
public
HashOperations
<
String
,
String
,
Object
>
hashOperations
(
RedisTemplate
<
String
,
Object
>
redisTemplate
)
{
return
redisTemplate
.
opsForHash
();
}
/**
* 对redis字符串类型数据操作
*
* @param redisTemplate
* @return
*/
@Bean
public
ValueOperations
<
String
,
Object
>
valueOperations
(
RedisTemplate
<
String
,
Object
>
redisTemplate
)
{
return
redisTemplate
.
opsForValue
();
}
/**
* 对链表类型的数据操作
*
* @param redisTemplate
* @return
*/
@Bean
public
ListOperations
<
String
,
Object
>
listOperations
(
RedisTemplate
<
String
,
Object
>
redisTemplate
)
{
return
redisTemplate
.
opsForList
();
}
/**
* 对无序集合类型的数据操作
*
* @param redisTemplate
* @return
*/
@Bean
public
SetOperations
<
String
,
Object
>
setOperations
(
RedisTemplate
<
String
,
Object
>
redisTemplate
)
{
return
redisTemplate
.
opsForSet
();
}
/**
* 对有序集合类型的数据操作
*
* @param redisTemplate
* @return
*/
@Bean
public
ZSetOperations
<
String
,
Object
>
zSetOperations
(
RedisTemplate
<
String
,
Object
>
redisTemplate
)
{
return
redisTemplate
.
opsForZSet
();
}
}
src/main/java/com/esv/freight/notice/module/sms/controller/SmsCaptchaController.java
0 → 100644
View file @
b34f5d7d
package
com
.
esv
.
freight
.
notice
.
module
.
sms
.
controller
;
import
com.esv.freight.notice.common.exception.EException
;
import
com.esv.freight.notice.common.response.ECode
;
import
com.esv.freight.notice.common.response.EResponse
;
import
com.esv.freight.notice.module.sms.em.CaptchaEnum
;
import
com.esv.freight.notice.module.sms.form.CaptchaForm
;
import
com.esv.freight.notice.module.sms.service.SmsCaptchaService
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.lang3.StringUtils
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.validation.annotation.Validated
;
import
org.springframework.web.bind.annotation.PostMapping
;
import
org.springframework.web.bind.annotation.RequestBody
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RestController
;
import
java.util.regex.Matcher
;
import
java.util.regex.Pattern
;
import
static
java
.
util
.
regex
.
Pattern
.
compile
;
/**
* @description:
* @project: notice-service
* @name: com.esv.freight.notice.module.sms.controller.SmsCaptchaController
* @author: 黄朝斌
* @email: huangchaobin@esvtek.com
* @createTime: 2020/04/15 18:07
* @version:1.0
*/
@Slf4j
@RestController
@RequestMapping
(
"/sms/captcha"
)
public
class
SmsCaptchaController
{
private
SmsCaptchaService
smsCaptchaService
;
@Autowired
public
SmsCaptchaController
(
SmsCaptchaService
smsCaptchaService
)
{
this
.
smsCaptchaService
=
smsCaptchaService
;
}
/**
* description 发送短信验证码
* param [form]
* return com.esv.freight.notice.common.response.EResponse
* author Administrator
* createTime 2020/04/15 18:21
**/
@PostMapping
(
"/send"
)
public
EResponse
sendSmsCaptcha
(
@RequestBody
@Validated
CaptchaForm
form
)
throws
EException
{
// 校验参数
CaptchaEnum
captchaEnum
=
CaptchaEnum
.
getEnumByType
(
form
.
getType
());
if
(
CaptchaEnum
.
UNDEFINED
==
captchaEnum
)
{
return
EResponse
.
error
(
ECode
.
PARAM_ERROR
.
code
(),
"type类型不合法"
);
}
if
(!
this
.
isValidMobile
(
form
.
getPhone
()))
{
return
EResponse
.
error
(
1001
,
"无效的手机号"
);
}
smsCaptchaService
.
sendSmsCaptcha
(
form
);
return
EResponse
.
ok
();
}
/**
* description 校验短信验证码
* param [form]
* return com.esv.freight.notice.common.response.EResponse
* author Administrator
* createTime 2020/04/16 18:10
**/
@PostMapping
(
"/check"
)
public
EResponse
checkSmsCaptcha
(
@RequestBody
@Validated
CaptchaForm
form
)
throws
EException
{
// 校验参数
CaptchaEnum
captchaEnum
=
CaptchaEnum
.
getEnumByType
(
form
.
getType
());
if
(
CaptchaEnum
.
UNDEFINED
==
captchaEnum
)
{
return
EResponse
.
error
(
ECode
.
PARAM_ERROR
.
code
(),
"type类型不合法"
);
}
if
(!
this
.
isValidMobile
(
form
.
getPhone
()))
{
return
EResponse
.
error
(
1001
,
"无效的手机号"
);
}
if
(
StringUtils
.
isBlank
(
form
.
getCaptcha
()))
{
return
EResponse
.
error
(
ECode
.
PARAM_ERROR
.
code
(),
"验证码不能为空"
);
}
smsCaptchaService
.
checkSmsCaptcha
(
form
);
return
EResponse
.
ok
();
}
/**
* 正则验证手机号码
**/
private
boolean
isValidMobile
(
String
phone
)
{
Pattern
p
=
compile
(
"^[1][0-9]{10}$"
);
Matcher
m
=
p
.
matcher
(
phone
);
return
m
.
matches
();
}
}
src/main/java/com/esv/freight/notice/module/sms/dao/SmsCaptchaDao.java
0 → 100644
View file @
b34f5d7d
package
com
.
esv
.
freight
.
notice
.
module
.
sms
.
dao
;
import
com.esv.freight.notice.module.sms.entity.SmsCaptchaEntity
;
import
com.baomidou.mybatisplus.core.mapper.BaseMapper
;
import
org.apache.ibatis.annotations.Mapper
;
/**
* 短信验证码表
*
* @author 黄朝斌
* @email huangchaobin@esvtek.com
* @date 2020-04-15 16:46:31
*/
@Mapper
public
interface
SmsCaptchaDao
extends
BaseMapper
<
SmsCaptchaEntity
>
{
/**
* description 查询指定类型、手机号的最后一个验证码
* param [queryEntity]
* return com.esv.freight.notice.module.sms.entity.SmsCaptchaEntity
* author Administrator
* createTime 2020/04/16 15:56
**/
SmsCaptchaEntity
selectLatestCaptcha
(
SmsCaptchaEntity
queryEntity
);
/**
* description 失效指定类型、手机号的最后一个验证码
* param [updateEntity]
* return int
* author Administrator
* createTime 2020/04/16 18:05
**/
int
updateLatestCaptcha
(
SmsCaptchaEntity
updateEntity
);
}
src/main/java/com/esv/freight/notice/module/sms/em/CaptchaEnum.java
0 → 100644
View file @
b34f5d7d
package
com
.
esv
.
freight
.
notice
.
module
.
sms
.
em
;
import
org.apache.commons.lang3.StringUtils
;
/**
* @description: 短信验证码类型枚举
* @project: freight-file-service
* @name: com.esv.freight.notice.module.sms.em.CaptchaEnum
* @author: 黄朝斌
* @email: huangchaobin@esvtek.com
* @createTime: 2020/04/15 11:20
* @version:1.0
*/
public
enum
CaptchaEnum
{
UNDEFINED
(
"undefined"
,
"未定义"
),
LOGIN
(
"login"
,
"登录"
),
RESET_PWD
(
"reset_pwd"
,
"重置密码"
),
UPDATE_PWD
(
"update_pwd"
,
"修改密码"
);
private
String
type
;
private
String
name
;
CaptchaEnum
(
String
type
,
String
name
)
{
this
.
type
=
type
;
this
.
name
=
name
;
}
public
static
CaptchaEnum
getEnumByType
(
String
type
)
{
if
(
StringUtils
.
isBlank
(
type
)){
return
CaptchaEnum
.
UNDEFINED
;
}
for
(
CaptchaEnum
em
:
CaptchaEnum
.
values
())
{
if
(
em
.
type
.
equalsIgnoreCase
(
type
))
{
return
em
;
}
}
return
CaptchaEnum
.
UNDEFINED
;
}
public
String
getType
()
{
return
type
;
}
public
void
setType
(
String
type
)
{
this
.
type
=
type
;
}
public
String
getName
()
{
return
name
;
}
public
void
setName
(
String
name
)
{
this
.
name
=
name
;
}
}
src/main/java/com/esv/freight/notice/module/sms/entity/SmsCaptchaEntity.java
0 → 100644
View file @
b34f5d7d
package
com
.
esv
.
freight
.
notice
.
module
.
sms
.
entity
;
import
com.baomidou.mybatisplus.annotation.TableId
;
import
com.baomidou.mybatisplus.annotation.TableName
;
import
java.io.Serializable
;
import
java.util.Date
;
import
lombok.Data
;
/**
* 短信验证码表
*
* @author 黄朝斌
* @email huangchaobin@esvtek.com
* @date 2020-04-15 16:46:31
*/
@Data
@TableName
(
"base_sms_captcha"
)
public
class
SmsCaptchaEntity
implements
Serializable
{
private
static
final
long
serialVersionUID
=
1L
;
/**
*
*/
@TableId
private
Long
id
;
/**
* 手机号码
*/
private
String
phone
;
/**
* 验证码
*/
private
String
captcha
;
/**
* 验证码类型:login-登录、reset_pwd-重置密码、update_pwd-修改密码、undefined-未定义
*/
private
String
captchaType
;
/**
* 失效时间
*/
private
Date
invalidTime
;
/**
* 0-未删除,1-已删除
*/
private
Boolean
deleted
;
/**
* 创建时间
*/
private
Date
createTime
;
/**
* 验证时间
*/
private
Date
verifyTime
;
}
src/main/java/com/esv/freight/notice/module/sms/form/CaptchaForm.java
0 → 100644
View file @
b34f5d7d
package
com
.
esv
.
freight
.
notice
.
module
.
sms
.
form
;
import
lombok.Data
;
import
org.hibernate.validator.constraints.Length
;
import
javax.validation.constraints.NotBlank
;
/**
* @description:
* @project: notice-service
* @name: com.esv.freight.notice.module.sms.form.CaptchaForm
* @author: 黄朝斌
* @email: huangchaobin@esvtek.com
* @createTime: 2020/04/15 17:58
* @version:1.0
*/
@Data
public
class
CaptchaForm
{
@Length
(
min
=
11
,
max
=
11
,
message
=
"参数phone长度不合法"
)
@NotBlank
(
message
=
"参数phone不能为空"
)
private
String
phone
;
@Length
(
max
=
16
,
message
=
"参数type长度不合法"
)
@NotBlank
(
message
=
"参数type不能为空"
)
private
String
type
;
@Length
(
min
=
6
,
max
=
6
,
message
=
"参数captcha长度不合法"
)
private
String
captcha
;
}
src/main/java/com/esv/freight/notice/module/sms/service/SmsCaptchaService.java
0 → 100644
View file @
b34f5d7d
package
com
.
esv
.
freight
.
notice
.
module
.
sms
.
service
;
import
com.baomidou.mybatisplus.extension.service.IService
;
import
com.esv.freight.notice.common.exception.EException
;
import
com.esv.freight.notice.module.sms.entity.SmsCaptchaEntity
;
import
com.esv.freight.notice.module.sms.form.CaptchaForm
;
/**
* 短信验证码表
*
* @author 黄朝斌
* @email huangchaobin@esvtek.com
* @date 2020-04-15 16:46:31
*/
public
interface
SmsCaptchaService
extends
IService
<
SmsCaptchaEntity
>
{
/**
* description 发送短信验证码
* param [form]
* return void
* author Administrator
* createTime 2020/04/16 9:05
**/
void
sendSmsCaptcha
(
CaptchaForm
form
)
throws
EException
;
/**
* description 校验短信验证码
* param [form]
* return void
* author Administrator
* createTime 2020/04/16 17:23
**/
void
checkSmsCaptcha
(
CaptchaForm
form
)
throws
EException
;
}
src/main/java/com/esv/freight/notice/module/sms/service/impl/SmsCaptchaServiceImpl.java
0 → 100644
View file @
b34f5d7d
package
com
.
esv
.
freight
.
notice
.
module
.
sms
.
service
.
impl
;
import
com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
;
import
com.esv.freight.notice.common.component.RedisComponent
;
import
com.esv.freight.notice.common.em.DbDeletedEnum
;
import
com.esv.freight.notice.common.exception.EException
;
import
com.esv.freight.notice.common.util.DateUtils
;
import
com.esv.freight.notice.common.util.SmsCaptchaUtils
;
import
com.esv.freight.notice.module.sms.dao.SmsCaptchaDao
;
import
com.esv.freight.notice.module.sms.entity.SmsCaptchaEntity
;
import
com.esv.freight.notice.module.sms.form.CaptchaForm
;
import
com.esv.freight.notice.module.sms.service.SmsCaptchaService
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.cloud.context.config.annotation.RefreshScope
;
import
org.springframework.stereotype.Service
;
import
java.util.Date
;
import
java.util.concurrent.TimeUnit
;
@Service
(
"smsCaptchaService"
)
@RefreshScope
@Slf4j
public
class
SmsCaptchaServiceImpl
extends
ServiceImpl
<
SmsCaptchaDao
,
SmsCaptchaEntity
>
implements
SmsCaptchaService
{
@Value
(
"${spring.application.name}"
)
private
String
applicationName
;
/**
* 短信验证码频次,默认60秒
**/
@Value
(
"${sms.captcha.frequency:60}"
)
private
long
SMS_CAPTCHA_FREQUENCY
;
/**
* 短信验证码总数,默认20
**/
@Value
(
"${sms.captcha.total:20}"
)
private
int
SMS_CAPTCHA_TOTAL
;
/**
* 短信验证码有效期,默认10分钟
**/
@Value
(
"${sms.captcha.period:10}"
)
private
long
SMS_CAPTCHA_PERIOD
;
private
RedisComponent
redisComponent
;
@Autowired
public
SmsCaptchaServiceImpl
(
RedisComponent
redisComponent
)
{
this
.
redisComponent
=
redisComponent
;
}
@Override
public
void
sendSmsCaptcha
(
CaptchaForm
form
)
throws
EException
{
String
phone
=
form
.
getPhone
();
// 1.校验短信验证码
this
.
checkSendSmsCaptcha
(
form
);
// 2.获取短信验证码随机数
String
smsCaptcha
=
SmsCaptchaUtils
.
getCaptcha
();
// 3.TODO,调用第三方服务发送短信验证码
// 4.将短信验证码放入缓存
// 频次
redisComponent
.
set
(
this
.
getFrequencyCacheKey
(
phone
),
"yes"
,
SMS_CAPTCHA_FREQUENCY
);
// 值
redisComponent
.
set
(
this
.
getValueCacheKey
(
form
),
smsCaptcha
,
SMS_CAPTCHA_PERIOD
,
TimeUnit
.
MINUTES
);
// 总数量
int
total
;
if
(
redisComponent
.
hasKey
(
this
.
getTotalCacheKey
(
phone
)))
{
total
=
(
int
)
redisComponent
.
get
(
this
.
getTotalCacheKey
(
phone
))
+
1
;
}
else
{
total
=
1
;
}
redisComponent
.
set
(
this
.
getTotalCacheKey
(
phone
),
total
,
1
,
TimeUnit
.
DAYS
);
// 5.DB存储短信验证码
SmsCaptchaEntity
entity
=
new
SmsCaptchaEntity
();
entity
.
setPhone
(
phone
);
entity
.
setCaptcha
(
smsCaptcha
);
entity
.
setCaptchaType
(
form
.
getType
());
entity
.
setInvalidTime
(
DateUtils
.
plusMinutes
(
new
Date
(),
Integer
.
parseInt
(
String
.
valueOf
(
SMS_CAPTCHA_PERIOD
))));
this
.
baseMapper
.
insert
(
entity
);
}
@Override
public
void
checkSmsCaptcha
(
CaptchaForm
form
)
throws
EException
{
// 1.获取短信验证码
String
rightCaptcha
=
null
;
String
captchaCacheKey
=
this
.
getValueCacheKey
(
form
);
if
(
redisComponent
.
hasKey
(
captchaCacheKey
))
{
// 从缓存获取验证码
rightCaptcha
=
redisComponent
.
get
(
captchaCacheKey
).
toString
();
}
else
{
// 从DB查询短信验证码
SmsCaptchaEntity
queryEntity
=
new
SmsCaptchaEntity
();
queryEntity
.
setPhone
(
form
.
getPhone
());
queryEntity
.
setCaptchaType
(
form
.
getType
());
SmsCaptchaEntity
smsCaptchaEntity
=
this
.
baseMapper
.
selectLatestCaptcha
(
queryEntity
);
if
(
null
==
smsCaptchaEntity
)
{
throw
new
EException
(
1003
,
"验证码不存在或已失效"
);
}
Date
InvalidTime
=
smsCaptchaEntity
.
getInvalidTime
();
if
(
0
<=
InvalidTime
.
compareTo
(
new
Date
()))
{
rightCaptcha
=
smsCaptchaEntity
.
getCaptcha
();
}
}
// 2.校验短信验证码
if
(!
rightCaptcha
.
equals
(
form
.
getCaptcha
()))
{
throw
new
EException
(
1002
,
"验证码错误"
);
}
// 3.短信验证码正确,失效操作
if
(
redisComponent
.
hasKey
(
captchaCacheKey
))
{
redisComponent
.
del
(
captchaCacheKey
);
}
SmsCaptchaEntity
updateEntity
=
new
SmsCaptchaEntity
();
updateEntity
.
setDeleted
(
DbDeletedEnum
.
YES
.
getCode
());
updateEntity
.
setVerifyTime
(
new
Date
());
updateEntity
.
setPhone
(
form
.
getPhone
());
updateEntity
.
setCaptchaType
(
form
.
getType
());
this
.
baseMapper
.
updateLatestCaptcha
(
updateEntity
);
}
/**
* description 校验短信验证码
* param [form]
* return void
* author Administrator
* createTime 2020/04/16 9:29
**/
private
void
checkSendSmsCaptcha
(
CaptchaForm
form
)
throws
EException
{
String
phone
=
form
.
getPhone
();
// 校验频次
if
(
redisComponent
.
hasKey
(
this
.
getFrequencyCacheKey
(
phone
)))
{
throw
new
EException
(
1002
,
"获取短信验证码过于频繁,请稍后再试"
);
}
// 校验总数
Object
total
=
redisComponent
.
get
(
this
.
getTotalCacheKey
(
phone
));
if
(
null
!=
total
&&
SMS_CAPTCHA_TOTAL
<=
Integer
.
parseInt
(
total
.
toString
()))
{
throw
new
EException
(
1003
,
"当日短信验证码总数已达上限,请明天再试"
);
}
}
/**
* 获取短信验证码频次缓存key
**/
private
String
getFrequencyCacheKey
(
String
phone
)
{
StringBuffer
sb
=
new
StringBuffer
();
sb
.
append
(
applicationName
);
sb
.
append
(
"::sms::captcha::frequency::"
);
sb
.
append
(
phone
);
return
sb
.
toString
();
}
/**
* 获取短信验证码总数缓存key
**/
private
String
getTotalCacheKey
(
String
phone
)
{
StringBuffer
sb
=
new
StringBuffer
();
sb
.
append
(
applicationName
);
sb
.
append
(
"::sms::captcha::total::"
);
sb
.
append
(
DateUtils
.
getSysdateStr
(
DateUtils
.
DATE_FORMAT2
));
sb
.
append
(
"::"
);
sb
.
append
(
phone
);
return
sb
.
toString
();
}
/**
* 获取短信验证码内容缓存key
**/
private
String
getValueCacheKey
(
CaptchaForm
form
)
{
StringBuffer
sb
=
new
StringBuffer
();
sb
.
append
(
applicationName
);
sb
.
append
(
"::sms::captcha::value::"
);
sb
.
append
(
form
.
getPhone
());
sb
.
append
(
"::"
);
sb
.
append
(
form
.
getType
());
return
sb
.
toString
();
}
}
\ No newline at end of file
src/main/resources/application-dev.yml
View file @
b34f5d7d
...
@@ -21,6 +21,18 @@ spring:
...
@@ -21,6 +21,18 @@ spring:
log-slow-sql
:
true
log-slow-sql
:
true
slow-sql-millis
:
1000
slow-sql-millis
:
1000
merge-sql
:
false
merge-sql
:
false
redis
:
database
:
0
host
:
192.168.31.248
port
:
6379
password
:
timeout
:
1000
jedis
:
pool
:
max-active
:
8
max-wait
:
-1
max-idle
:
8
min-idle
:
0
#mybatis
#mybatis
mybatis-plus
:
mybatis-plus
:
mapper-locations
:
classpath*:/mapper/**/*Dao.xml
mapper-locations
:
classpath*:/mapper/**/*Dao.xml
...
@@ -40,4 +52,10 @@ mybatis-plus:
...
@@ -40,4 +52,10 @@ mybatis-plus:
#主键类型 AUTO:"数据库ID自增", INPUT:"用户输入ID", ID_WORKER:"全局唯一ID (数字类型唯一ID)", UUID:"全局唯一ID UUID";
#主键类型 AUTO:"数据库ID自增", INPUT:"用户输入ID", ID_WORKER:"全局唯一ID (数字类型唯一ID)", UUID:"全局唯一ID UUID";
id-type
:
AUTO
id-type
:
AUTO
logic-delete-value
:
1
logic-delete-value
:
1
logic-not-delete-value
:
0
logic-not-delete-value
:
0
\ No newline at end of file
#短信
sms
:
captcha
:
frequency
:
60
total
:
5
period
:
10
\ No newline at end of file
src/main/resources/application-test.yml
View file @
b34f5d7d
...
@@ -21,6 +21,18 @@ spring:
...
@@ -21,6 +21,18 @@ spring:
log-slow-sql
:
true
log-slow-sql
:
true
slow-sql-millis
:
1000
slow-sql-millis
:
1000
merge-sql
:
false
merge-sql
:
false
redis
:
database
:
0
host
:
192.168.31.248
port
:
6379
password
:
timeout
:
1000
jedis
:
pool
:
max-active
:
8
max-wait
:
-1
max-idle
:
8
min-idle
:
0
#mybatis
#mybatis
mybatis-plus
:
mybatis-plus
:
mapper-locations
:
classpath*:/mapper/**/*Dao.xml
mapper-locations
:
classpath*:/mapper/**/*Dao.xml
...
@@ -40,4 +52,10 @@ mybatis-plus:
...
@@ -40,4 +52,10 @@ mybatis-plus:
#主键类型 AUTO:"数据库ID自增", INPUT:"用户输入ID", ID_WORKER:"全局唯一ID (数字类型唯一ID)", UUID:"全局唯一ID UUID";
#主键类型 AUTO:"数据库ID自增", INPUT:"用户输入ID", ID_WORKER:"全局唯一ID (数字类型唯一ID)", UUID:"全局唯一ID UUID";
id-type
:
AUTO
id-type
:
AUTO
logic-delete-value
:
1
logic-delete-value
:
1
logic-not-delete-value
:
0
logic-not-delete-value
:
0
\ No newline at end of file
#短信
sms
:
captcha
:
frequency
:
60
total
:
20
period
:
10
\ No newline at end of file
src/main/resources/mapper/sms/SmsCaptchaDao.xml
0 → 100644
View file @
b34f5d7d
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper
namespace=
"com.esv.freight.notice.module.sms.dao.SmsCaptchaDao"
>
<!-- 可根据自己的需求,是否要使用 -->
<resultMap
type=
"com.esv.freight.notice.module.sms.entity.SmsCaptchaEntity"
id=
"smsCaptchaMap"
>
<result
property=
"id"
column=
"id"
/>
<result
property=
"phone"
column=
"phone"
/>
<result
property=
"captcha"
column=
"captcha"
/>
<result
property=
"captchaType"
column=
"captcha_type"
/>
<result
property=
"invalidTime"
column=
"invalid_time"
/>
<result
property=
"deleted"
column=
"deleted"
/>
<result
property=
"createTime"
column=
"create_time"
/>
<result
property=
"verifyTime"
column=
"verify_time"
/>
</resultMap>
<!-- 查询指定类型、手机号的最后一个验证码 -->
<select
id=
"selectLatestCaptcha"
parameterType=
"com.esv.freight.notice.module.sms.entity.SmsCaptchaEntity"
resultType=
"com.esv.freight.notice.module.sms.entity.SmsCaptchaEntity"
>
select phone, captcha, captcha_type, invalid_time
from base_sms_captcha
where deleted = false
and phone = #{phone}
and captcha_type = #{captchaType}
and invalid_time = (select max(invalid_time) from base_sms_captcha where deleted = false and phone = #{phone} and captcha_type = #{captchaType})
</select>
<!-- 失效指定类型、手机号的最后一个验证码 -->
<update
id=
"updateLatestCaptcha"
parameterType=
"com.esv.freight.notice.module.sms.entity.SmsCaptchaEntity"
>
update base_sms_captcha
set deleted = true,
verify_time = #{verifyTime}
where
deleted = false
and phone = #{phone}
and captcha_type = #{captchaType}
and verify_time is null
</update>
</mapper>
\ No newline at end of file
src/test/java/com/esv/freight/notice/common/util/SmsCaptchaUtilsTest.java
0 → 100644
View file @
b34f5d7d
package
com
.
esv
.
freight
.
notice
.
common
.
util
;
import
lombok.extern.slf4j.Slf4j
;
import
org.junit.After
;
import
org.junit.Assert
;
import
org.junit.Before
;
import
org.junit.Test
;
import
org.springframework.boot.test.context.SpringBootTest
;
/**
* @description:
* @project: notice-service
* @name: com.esv.freight.notice.common.util.SmsCaptchaUtilsTest
* @author: 黄朝斌
* @email: huangchaobin@esvtek.com
* @createTime: 2020/04/15 16:59
* @version:1.0
*/
@SpringBootTest
@Slf4j
public
class
SmsCaptchaUtilsTest
{
@Before
public
void
before
()
{
log
.
info
(
"=================================== Test Start ==================================="
);
}
@After
public
void
after
()
{
log
.
info
(
"=================================== Test End ==================================="
);
}
/**
* 获取默认长度的短信验证码
**/
@Test
public
void
getCaptcha_default_length_test
()
{
String
smsCaptcha
=
SmsCaptchaUtils
.
getCaptcha
();
log
.
info
(
"短信验证码:{}"
,
smsCaptcha
);
Assert
.
assertTrue
(
SmsCaptchaUtils
.
DEFAULT_SIZE
==
smsCaptcha
.
length
());
}
/**
* 获取指定长度的短信验证码
**/
@Test
public
void
getCaptcha_define_length_test
()
{
int
defineLength
=
4
;
String
smsCaptcha
=
SmsCaptchaUtils
.
getCaptcha
(
defineLength
);
log
.
info
(
"短信验证码:{}"
,
smsCaptcha
);
Assert
.
assertTrue
(
defineLength
==
smsCaptcha
.
length
());
}
}
src/test/java/com/esv/freight/notice/module/sms/controller/SmsCaptchaControllerTest.java
0 → 100644
View file @
b34f5d7d
This diff is collapsed.
Click to expand it.
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