新装手机号校验

This commit is contained in:
zhuyijun 2023-04-05 21:53:22 +08:00
parent 8563bd69a1
commit 14bc88ab97
5 changed files with 223 additions and 84 deletions

View File

@ -83,7 +83,7 @@ public class SmsTaskPO {
* 需要封装正确格式化: 您s好张三您有一个新的快递
*/
@ApiModelProperty(value = "发送内容")
@Size(max = 500, message = "发送内容长度不能超过500")
@Size(max = 1000, message = "发送内容长度不能超过500")
@TableField(value = "content", condition = LIKE)
private String content;

View File

@ -17,6 +17,7 @@ import cn.zyjblogs.sms.task.service.SmsSendStatusService;
import cn.zyjblogs.sms.task.service.SmsTaskService;
import cn.zyjblogs.sms.task.service.SmsTemplateService;
import cn.zyjblogs.sms.task.vo.SmsTaskVO;
import cn.zyjblogs.starter.common.entity.constant.MobileRegularExp;
import cn.zyjblogs.starter.common.entity.context.BaseContext;
import cn.zyjblogs.starter.common.entity.dto.Kv;
import cn.zyjblogs.starter.common.entity.response.HttpCode;
@ -35,6 +36,7 @@ import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Matcher;
@ -64,6 +66,15 @@ public class SmsTaskServiceImpl extends ServiceImpl<SmsTaskMapper,SmsTaskPO> imp
//1验证必要参数
Asserts.notEmpty(data.getTelNum(), "请填写短信接收人");
Iterator<String> it = data.getTelNum().iterator();
List<String> noPhones = new ArrayList<>();
while (it.hasNext()) {
String phone = it.next();
if (!MobileRegularExp.isMobileNumber(phone)){
it.remove();
noPhones.add(phone);
}
}
// 验证定时发送的时间至少大于当前时间+5分钟 是为了防止 定时调度或者是保存数据跟不上
if (data.getSendTime() != null) {
@ -80,7 +91,7 @@ public class SmsTaskServiceImpl extends ServiceImpl<SmsTaskMapper,SmsTaskPO> imp
smsTask.setStatus(TaskStatus.WAITING);
smsTask.setTemplateParams(JSON.toJSONString(data.getTemplateParams()));
this.save(smsTask);
List<SmsResponse> list = null;
List<SmsResponse> list;
try {
list = smsGranter.sendSms(template.getProviderType(), SmsRequest.builder()
.smsContent(smsTask.getContent())
@ -98,10 +109,10 @@ public class SmsTaskServiceImpl extends ServiceImpl<SmsTaskMapper,SmsTaskPO> imp
updateStatus(smsTask.getId(),TaskStatus.FAIL);
return BeanUtils.map(smsTask,SmsTaskVO.class);
}
LocalDateTime now = LocalDateTime.now();
String userId = BaseContext.getUserId();
List<SmsSendStatusPO> sendStatusList = new LinkedList<>();
if (!CollectionUtils.isEmpty(list)){
List<SmsSendStatusPO> sendStatusList = new LinkedList<>();
LocalDateTime now = LocalDateTime.now();
String userId = BaseContext.getUserId();
list.forEach(smsResponse -> sendStatusList.add(SmsSendStatusPO.builder()
.taskId(data.getId())
.bizId(smsResponse.getBizId())
@ -116,6 +127,22 @@ public class SmsTaskServiceImpl extends ServiceImpl<SmsTaskMapper,SmsTaskPO> imp
.editUserId(userId)
.editUserId(userId)
.build()));
}
if (!CollectionUtils.isEmpty(noPhones)){
noPhones.forEach(noPhone -> sendStatusList.add(SmsSendStatusPO.builder()
.taskId(data.getId())
.code("-1")
.telNum(noPhone)
.sendStatus(SendStatus.FAIL)
.message("手机号格式不正确")
.createTime(now)
.createUserId(userId)
.editUserId(userId)
.editUserId(userId)
.build()));
}
if (!CollectionUtils.isEmpty(sendStatusList)){
smsSendStatusService.saveBatch(sendStatusList);
}
updateStatus(smsTask.getId(),TaskStatus.SUCCESS);
@ -123,6 +150,8 @@ public class SmsTaskServiceImpl extends ServiceImpl<SmsTaskMapper,SmsTaskPO> imp
return BeanUtils.map(smsTask,SmsTaskVO.class);
}
public void updateStatus(String taskId, TaskStatus success) {
SmsTaskPO updateTask = new SmsTaskPO();
updateTask.setId(taskId);
@ -138,7 +167,7 @@ public class SmsTaskServiceImpl extends ServiceImpl<SmsTaskMapper,SmsTaskPO> imp
return StringUtils.EMPTY;
}
StringBuffer sb = new StringBuffer();
StringBuilder sb = new StringBuilder();
Matcher m = Pattern.compile(regex).matcher(template);
int index = 0;
while (m.find()) {
@ -163,21 +192,32 @@ public class SmsTaskServiceImpl extends ServiceImpl<SmsTaskMapper,SmsTaskPO> imp
return sb.toString();
}
public static void main(String[] args) {
System.out.println(JSON.toJSONString(SmsTaskDTO.builder()
.id("xx010")
.draft(false)
.sourceType(SourceType.SERVICE)
.templateId("1")
.topic("登录验证")
.templateParams(List.of(Kv.<String, String>builder().k("code").v("999999").build()))
.telNum(List.of("13476152541"))
.build()));
// System.out.println(JSON.toJSONString(SmsTaskDTO.builder()
// .id("xx010")
// .draft(false)
// .sourceType(SourceType.SERVICE)
// .templateId("1")
// .topic("登录验证")
// .templateParams(List.of(Kv.<String, String>builder().k("code").v("999999").build()))
// .telNum(List.of("13476152541"))
// .build()));
SmsTaskDTO smsRequest = new SmsTaskDTO();
List<Kv<String,String>> list = new ArrayList<>();
list.add(Kv.<String,String>builder().k("var").v("atg").build());
list.add(Kv.<String,String>builder().k("var").v("1234").build());
list.add(Kv.<String,String>builder().k("var").v("01").build());
list.add(Kv.<String,String>builder().k("var").v("5").build());
list.add(Kv.<String,String>builder().k("k").v("$5").build());
System.out.println(processTemplate("${var}您好!验证码是:${var}(序号${var}),有效时间为${var}分钟。尝试次数: ${k}", ProviderType.ALI.getRegex(), list));
list.add(Kv.<String,String>builder().k("ll").v("$5").build());
smsRequest.setTemplateParams(list);
List<Kv<String, String>> templateParams = smsRequest.getTemplateParams();
Iterator<Kv<String, String>> iterator = templateParams.iterator();
while (iterator.hasNext()){
Kv<String, String> next = iterator.next();
if (next.getK().equals("ll")){
iterator.remove();
}
}
System.out.println(JSON.toJSONString(smsRequest.getTemplateParams()));
// System.out.println(processTemplate("${var}您好!验证码是:${var}(序号${var}),有效时间为${var}分钟。尝试次数: ${k}", ProviderType.ALI.getRegex(), list));
}
}

View File

@ -1,8 +1,8 @@
zyjblogs:
config:
nacos:
host: ${ZYJBLOGS_CONFIG_NACOS_HOST:127.0.0.1}
port: ${ZYJBLOGS_CONFIG_NACOS_PORT:8848}
host: ${ZYJBLOGS_CONFIG_NACOS_HOST:zyjblogs.cn}
port: ${ZYJBLOGS_CONFIG_NACOS_PORT:9999}
username: ${ZYJBLOGS_CONFIG_NACOS_USERNAME:nacos}
password: ${ZYJBLOGS_CONFIG_NACOS_PASSWORD:nacos}
password: ${ZYJBLOGS_CONFIG_NACOS_PASSWORD:1317453947ju}

View File

@ -9,17 +9,6 @@ spring:
allow-bean-definition-overriding: true
application:
name: zyjblogs-sms
redis:
host: 127.0.0.1
port: 6379
password:
timeout: 10000 #连接超时时间(毫秒)
lettuce:
pool:
max-active: 8 # 连接池最大连接数
max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制)
min-idle: 0 # 连接池中的最小空闲连接
max-idle: 8 # 连接池中的最大空闲连接
cloud:
nacos:
config:
@ -39,59 +28,59 @@ spring:
password: ${spring.cloud.nacos.config.password}
namespace: ${spring.cloud.nacos.config.namespace}
group: public
sharding-sphere:
datasource:
names: write-ds,read-ds-0
write-ds:
jdbc-url: jdbc:mysql://127.0.0.1:3306/zyjblogs_sms?allowPublicKeyRetrieval=true&useSSL=false&allowMultiQueries=true&serverTimezone=Asia/Shanghai&useSSL=false&autoReconnect=true&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: 123456
connectionTimeoutMilliseconds: 3000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 50
minPoolSize: 1
maintenanceIntervalMilliseconds: 30000\
hikari:
minimum-idle: 10
maximum-pool-size: 100
auto-commit: true
idle-timeout: 1800000
pool-name: DatebookHikariCP
max-lifetime: 1800000
connection-timeout: 60000
connection-test-query: SELECT 1
read-ds-0:
jdbc-url: jdbc:mysql://127.0.0.1:3306/zyjblogs_sms?allowPublicKeyRetrieval=true&useSSL=false&allowMultiQueries=true&serverTimezone=Asia/Shanghai&useSSL=false&autoReconnect=true&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
username: read
password: 123456
connectionTimeoutMilliseconds: 3000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 50
minPoolSize: 1
maintenanceIntervalMilliseconds: 30000
hikari:
minimum-idle: 10
maximum-pool-size: 100
auto-commit: true
idle-timeout: 1800000
pool-name: DatebookHikariCP
max-lifetime: 1800000
connection-timeout: 60000
connection-test-query: SELECT 1
sharding:
master-slave-rules:
master0:
master-data-source-name: write-ds
slave-data-source-names: read-ds-0
props:
sql:
show: true
# sharding-sphere:
# datasource:
# names: write-ds,read-ds-0
# write-ds:
# jdbc-url: jdbc:mysql://127.0.0.1:3306/zyjblogs_sms?allowPublicKeyRetrieval=true&useSSL=false&allowMultiQueries=true&serverTimezone=Asia/Shanghai&useSSL=false&autoReconnect=true&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull
# type: com.zaxxer.hikari.HikariDataSource
# driver-class-name: com.mysql.cj.jdbc.Driver
# username: root
# password: 123456
# connectionTimeoutMilliseconds: 3000
# idleTimeoutMilliseconds: 60000
# maxLifetimeMilliseconds: 1800000
# maxPoolSize: 50
# minPoolSize: 1
# maintenanceIntervalMilliseconds: 30000\
# hikari:
# minimum-idle: 10
# maximum-pool-size: 100
# auto-commit: true
# idle-timeout: 1800000
# pool-name: DatebookHikariCP
# max-lifetime: 1800000
# connection-timeout: 60000
# connection-test-query: SELECT 1
# read-ds-0:
# jdbc-url: jdbc:mysql://127.0.0.1:3306/zyjblogs_sms?allowPublicKeyRetrieval=true&useSSL=false&allowMultiQueries=true&serverTimezone=Asia/Shanghai&useSSL=false&autoReconnect=true&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull
# type: com.zaxxer.hikari.HikariDataSource
# driver-class-name: com.mysql.cj.jdbc.Driver
# username: read
# password: 123456
# connectionTimeoutMilliseconds: 3000
# idleTimeoutMilliseconds: 60000
# maxLifetimeMilliseconds: 1800000
# maxPoolSize: 50
# minPoolSize: 1
# maintenanceIntervalMilliseconds: 30000
# hikari:
# minimum-idle: 10
# maximum-pool-size: 100
# auto-commit: true
# idle-timeout: 1800000
# pool-name: DatebookHikariCP
# max-lifetime: 1800000
# connection-timeout: 60000
# connection-test-query: SELECT 1
# sharding:
# master-slave-rules:
# master0:
# master-data-source-name: write-ds
# slave-data-source-names: read-ds-0
# props:
# sql:
# show: true
logging:
config: classpath:logback-spring.xml

View File

@ -0,0 +1,110 @@
package cn.zyjblogs.starter.common.entity.constant;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public enum MobileRegularExp {
CN("中国","^(\\+?0?86\\-?)?1[345789]\\d{9}$"),
TW("台湾","^(\\+?886\\-?|0)?9\\d{8}$"),
HK("香港","^(\\+?852\\-?)?[569]\\d{3}\\-?\\d{4}$"),
MS("马来西亚","^(\\+?6?01){1}(([145]{1}(\\-|\\s)?\\d{7,8})|([236789]{1}(\\s|\\-)?\\d{7}))$"),
PH("菲律宾","^(\\+?0?63\\-?)?\\d{10}$"),
TH("泰国","^(\\+?0?66\\-?)?\\d{10}$"),
SG("新加坡","^(\\+?0?65\\-?)?\\d{10}$"),
/* 以上是项目可能设计到的市场,一下是其他国家的手机号校验正则,欢迎补充*/
DZ("阿尔及利亚", "^(\\+?213|0)(5|6|7)\\d{8}$"),
SY("叙利亚","^(!?(\\+?963)|0)?9\\d{8}$"),
SA("沙特阿拉伯","^(!?(\\+?966)|0)?5\\d{8}$"),
US("美国","^(\\+?1)?[2-9]\\d{2}[2-9](?!11)\\d{6}$"),
CZ("捷克共和国","^(\\+?420)? ?[1-9][0-9]{2} ?[0-9]{3} ?[0-9]{3}$"),
DE("德国","^(\\+?49[ \\.\\-])?([\\(]{1}[0-9]{1,6}[\\)])?([0-9 \\.\\-\\/]{3,20})((x|ext|extension)[ ]?[0-9]{1,4})?$"),
DK("丹麦","^(\\+?45)?(\\d{8})$"),
GR("希腊","^(\\+?30)?(69\\d{8})$"),
AU("澳大利亚","^(\\+?61|0)4\\d{8}$"),
GB("英国","^(\\+?44|0)7\\d{9}$"),
CA("加拿大","^(\\+?1)?[2-9]\\d{2}[2-9](?!11)\\d{6}$"),
IN("印度","^(\\+?91|0)?[789]\\d{9}$"),
NZ("新西兰","^(\\+?64|0)2\\d{7,9}$"),
ZA("南非","^(\\+?27|0)\\d{9}$"),
ZM("赞比亚","^(\\+?26)?09[567]\\d{7}$"),
ES("西班牙","^(\\+?34)?(6\\d{1}|7[1234])\\d{7}$"),
FI("芬兰","^(\\+?358|0)\\s?(4(0|1|2|4|5)?|50)\\s?(\\d\\s?){4,8}\\d$"),
FR("法国","^(\\+?33|0)[67]\\d{8}$"),
IL("以色列","^(\\+972|0)([23489]|5[0248]|77)[1-9]\\d{6}"),
HU("匈牙利","^(\\+?36)(20|30|70)\\d{7}$"),
IT("意大利","^(\\+?39)?\\s?3\\d{2} ?\\d{6,7}$"),
JP("日本","^(\\+?81|0)\\d{1,4}[ \\-]?\\d{1,4}[ \\-]?\\d{4}$"),
NO("挪威","^(\\+?47)?[49]\\d{7}$"),
BE("比利时","^(\\+?32|0)4?\\d{8}$"),
PL("波兰","^(\\+?48)? ?[5-8]\\d ?\\d{3} ?\\d{2} ?\\d{2}$"),
BR("巴西","^(\\+?55|0)\\-?[1-9]{2}\\-?[2-9]{1}\\d{3,4}\\-?\\d{4}$"),
PT("葡萄牙","^(\\+?351)?9[1236]\\d{7}$"),
RU("俄罗斯","^(\\+?7|8)?9\\d{9}$"),
RS("塞尔维亚","^(\\+3816|06)[- \\d]{5,9}$"),
R("土耳其","^(\\+?90|0)?5\\d{9}$"),
VN("越南","^(\\+?84|0)?((1(2([0-9])|6([2-9])|88|99))|(9((?!5)[0-9])))([0-9]{7})$");
/**
* 国际名称
*/
private String national;
/**
* 正则表达式
*/
private String regularExp;
public String getNational() {
return national;
}
public void setNational(String national) {
this.national = national;
}
public String getRegularExp() {
return regularExp;
}
public void setRegularExp(String regularExp) {
this.regularExp = regularExp;
}
MobileRegularExp(String national, String regularExp) {
this.national = national;
this.regularExp = regularExp;
}
public static boolean isMobileNumber(String nationalCode, String mobileNumber) {
boolean isMobileNumber = false;
for (MobileRegularExp regularExp : MobileRegularExp.values()) {
Pattern pattern = Pattern.compile(regularExp.getRegularExp());
Matcher matcher = pattern.matcher(nationalCode + mobileNumber);
if (matcher.matches()) {
isMobileNumber = true;
// 枚举中把最常用的国际区号拍在前面可以减少校验开销
break;
}
}
return isMobileNumber;
}
public static boolean isMobileNumber(String mobileNumber) {
boolean isMobileNumber = false;
for (MobileRegularExp regularExp : MobileRegularExp.values()) {
Pattern pattern = Pattern.compile(regularExp.getRegularExp());
Matcher matcher = pattern.matcher(mobileNumber);
if (matcher.matches()) {
isMobileNumber = true;
// 枚举中把最常用的国际区号拍在前面可以减少校验开销
break;
}
}
return isMobileNumber;
}
public static void main(String[] args) {
System.out.println(MobileRegularExp.isMobileNumber("13476152541"));
}
}