|
@@ -5,14 +5,18 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
import com.storlead.framework.common.constant.RedisKeySaltConstant;
|
|
import com.storlead.framework.common.constant.RedisKeySaltConstant;
|
|
|
import com.storlead.framework.common.enums.ErrorMsgCode;
|
|
import com.storlead.framework.common.enums.ErrorMsgCode;
|
|
|
-import com.storlead.framework.common.result.BizResult;
|
|
|
|
|
|
|
+import com.storlead.framework.common.result.Result;
|
|
|
import com.storlead.framework.common.util.RandomCodeUtil;
|
|
import com.storlead.framework.common.util.RandomCodeUtil;
|
|
|
import com.storlead.framework.redis.RedisService;
|
|
import com.storlead.framework.redis.RedisService;
|
|
|
import com.storlead.sms.constants.SmsTemplateConstants;
|
|
import com.storlead.sms.constants.SmsTemplateConstants;
|
|
|
import com.storlead.sms.mapper.SmsLogMapper;
|
|
import com.storlead.sms.mapper.SmsLogMapper;
|
|
|
import com.storlead.sms.pojo.entity.SmsLogEntity;
|
|
import com.storlead.sms.pojo.entity.SmsLogEntity;
|
|
|
-import com.storlead.sms.server.SmsLogService;
|
|
|
|
|
|
|
+import com.storlead.sms.spi.SmsCaptchaScene;
|
|
|
|
|
+import com.storlead.sms.spi.SmsCaptchaService;
|
|
|
|
|
+import com.storlead.sms.spi.SmsLogService;
|
|
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
+import org.springframework.util.StringUtils;
|
|
|
|
|
|
|
|
import javax.annotation.Resource;
|
|
import javax.annotation.Resource;
|
|
|
import java.util.Date;
|
|
import java.util.Date;
|
|
@@ -20,69 +24,112 @@ import java.util.Objects;
|
|
|
import java.util.concurrent.TimeUnit;
|
|
import java.util.concurrent.TimeUnit;
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
- * <p>
|
|
|
|
|
- * 短信日志 服务实现类
|
|
|
|
|
- * </p>
|
|
|
|
|
- *
|
|
|
|
|
- * @author chenkq
|
|
|
|
|
- * @since 2022-05-27
|
|
|
|
|
|
|
+ * 短信日志与验证码(发送/校验)
|
|
|
*/
|
|
*/
|
|
|
|
|
+@Slf4j
|
|
|
@Service
|
|
@Service
|
|
|
-public class SmsLogServiceImpl extends ServiceImpl<SmsLogMapper, SmsLogEntity> implements SmsLogService {
|
|
|
|
|
|
|
+public class SmsLogServiceImpl extends ServiceImpl<SmsLogMapper, SmsLogEntity>
|
|
|
|
|
+ implements SmsLogService, SmsCaptchaService {
|
|
|
|
|
|
|
|
@Resource
|
|
@Resource
|
|
|
private RedisService redisService;
|
|
private RedisService redisService;
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
|
- public BizResult sendLoginSmsCode(String mobile) {
|
|
|
|
|
- //
|
|
|
|
|
- int count = this.count(new LambdaQueryWrapper<SmsLogEntity>().eq(SmsLogEntity::getMobile,mobile).eq(SmsLogEntity::getType,Integer.valueOf(10)).apply(" TO_DAYS(send_time) = TO_DAYS(NOW()) "));
|
|
|
|
|
|
|
+ public Result<?> sendCaptcha(String mobile, SmsCaptchaScene scene) {
|
|
|
|
|
+ if (!StringUtils.hasText(mobile)) {
|
|
|
|
|
+ return Result.error(ErrorMsgCode.D_400009);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (scene == null) {
|
|
|
|
|
+ return Result.error(ErrorMsgCode.PARAMETER_FAIL);
|
|
|
|
|
+ }
|
|
|
|
|
+ int type = scene.getSmsLogType();
|
|
|
|
|
+ int count = this.count(new LambdaQueryWrapper<SmsLogEntity>()
|
|
|
|
|
+ .eq(SmsLogEntity::getMobile, mobile)
|
|
|
|
|
+ .eq(SmsLogEntity::getType, type)
|
|
|
|
|
+ .apply(" TO_DAYS(send_time) = TO_DAYS(NOW()) "));
|
|
|
if (count >= SmsTemplateConstants.SEND_MAXIMIZE) {
|
|
if (count >= SmsTemplateConstants.SEND_MAXIMIZE) {
|
|
|
- return BizResult.error(ErrorMsgCode.D_400001);
|
|
|
|
|
|
|
+ return Result.error(ErrorMsgCode.D_400001);
|
|
|
}
|
|
}
|
|
|
- Object var1 = redisService.getCacheObject(RedisKeySaltConstant.REDIS_LOGIN_VALID_CODE_KEY+mobile);
|
|
|
|
|
- if (Objects.nonNull(var1)) {
|
|
|
|
|
- SmsLogEntity smsLog = (SmsLogEntity) var1;
|
|
|
|
|
|
|
+ String cacheKey = captchaRedisKey(scene, mobile);
|
|
|
|
|
+ Object cached = redisService.getCacheObject(cacheKey);
|
|
|
|
|
+ if (Objects.nonNull(cached)) {
|
|
|
|
|
+ SmsLogEntity smsLog = (SmsLogEntity) cached;
|
|
|
Long currentTime = System.currentTimeMillis();
|
|
Long currentTime = System.currentTimeMillis();
|
|
|
Long sendTime = smsLog.getSendTime().getTime();
|
|
Long sendTime = smsLog.getSendTime().getTime();
|
|
|
if ((currentTime - sendTime) / 1000 < smsLog.getValidTime()) {
|
|
if ((currentTime - sendTime) / 1000 < smsLog.getValidTime()) {
|
|
|
- return BizResult.error(ErrorMsgCode.D_400002);
|
|
|
|
|
|
|
+ return Result.error(ErrorMsgCode.D_400002);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
int checkCode = RandomCodeUtil.RandomCheckCode();
|
|
int checkCode = RandomCodeUtil.RandomCheckCode();
|
|
|
-
|
|
|
|
|
try {
|
|
try {
|
|
|
boolean res = sendMobileVerifyCode(mobile, checkCode);
|
|
boolean res = sendMobileVerifyCode(mobile, checkCode);
|
|
|
if (!res) {
|
|
if (!res) {
|
|
|
- return BizResult.error(ErrorMsgCode.D_400003);
|
|
|
|
|
|
|
+ return Result.error(ErrorMsgCode.D_400003);
|
|
|
}
|
|
}
|
|
|
- log.error("SmsLog ---- = "+checkCode);
|
|
|
|
|
|
|
+ log.error("SmsLog ---- = " + checkCode);
|
|
|
SmsLogEntity smsLog = new SmsLogEntity();
|
|
SmsLogEntity smsLog = new SmsLogEntity();
|
|
|
smsLog.setVerifyCode(String.valueOf(checkCode));
|
|
smsLog.setVerifyCode(String.valueOf(checkCode));
|
|
|
smsLog.setMobile(mobile);
|
|
smsLog.setMobile(mobile);
|
|
|
- smsLog.setType(Integer.valueOf(10));
|
|
|
|
|
- //无需关注id 验证的是手机号码
|
|
|
|
|
|
|
+ smsLog.setType(type);
|
|
|
smsLog.setUserId(null);
|
|
smsLog.setUserId(null);
|
|
|
smsLog.setValidTime(60);
|
|
smsLog.setValidTime(60);
|
|
|
smsLog.setSendTime(new Date());
|
|
smsLog.setSendTime(new Date());
|
|
|
smsLog.setStatus(1);
|
|
smsLog.setStatus(1);
|
|
|
this.baseMapper.insert(smsLog);
|
|
this.baseMapper.insert(smsLog);
|
|
|
- redisService.setCacheObject(RedisKeySaltConstant.REDIS_LOGIN_VALID_CODE_KEY+mobile,smsLog,120L, TimeUnit.MINUTES);
|
|
|
|
|
|
|
+ redisService.setCacheObject(cacheKey, smsLog, 120L, TimeUnit.MINUTES);
|
|
|
} catch (Exception e) {
|
|
} catch (Exception e) {
|
|
|
- return BizResult.error(e.getMessage());
|
|
|
|
|
|
|
+ return Result.error(e.getMessage());
|
|
|
|
|
+ }
|
|
|
|
|
+ return Result.ok();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public Result<?> verifyCaptcha(String mobile, String code, SmsCaptchaScene scene, boolean consumeAfterSuccess) {
|
|
|
|
|
+ if (!StringUtils.hasText(mobile) || !StringUtils.hasText(code)) {
|
|
|
|
|
+ return Result.error(ErrorMsgCode.PARAMETER_FAIL);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (scene == null) {
|
|
|
|
|
+ return Result.error(ErrorMsgCode.PARAMETER_FAIL);
|
|
|
|
|
+ }
|
|
|
|
|
+ String cacheKey = captchaRedisKey(scene, mobile);
|
|
|
|
|
+ Object cached = redisService.getCacheObject(cacheKey);
|
|
|
|
|
+ if (cached == null) {
|
|
|
|
|
+ return Result.error(ErrorMsgCode.D_400004);
|
|
|
}
|
|
}
|
|
|
- return BizResult.ok();
|
|
|
|
|
|
|
+ SmsLogEntity smsLog = (SmsLogEntity) cached;
|
|
|
|
|
+ if (smsLog.getSendTime() != null && smsLog.getValidTime() != null) {
|
|
|
|
|
+ long elapsedSec = (System.currentTimeMillis() - smsLog.getSendTime().getTime()) / 1000;
|
|
|
|
|
+ if (elapsedSec > smsLog.getValidTime()) {
|
|
|
|
|
+ return Result.error(ErrorMsgCode.D_400006);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ String expect = smsLog.getVerifyCode() == null ? "" : smsLog.getVerifyCode().trim();
|
|
|
|
|
+ String actual = code.trim();
|
|
|
|
|
+ if (!actual.equals(expect)) {
|
|
|
|
|
+ return Result.error(ErrorMsgCode.D_400008);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (consumeAfterSuccess) {
|
|
|
|
|
+ redisService.deleteObject(cacheKey);
|
|
|
|
|
+ }
|
|
|
|
|
+ return Result.ok();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public Result<?> sendLoginSmsCode(String mobile) {
|
|
|
|
|
+ return sendCaptcha(mobile, SmsCaptchaScene.LOGIN);
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
- * 发送手机验证码短信
|
|
|
|
|
- *
|
|
|
|
|
- * @param mobile 手机
|
|
|
|
|
- * @param checkCode 验证码
|
|
|
|
|
|
|
+ * 与历史 Redis 键兼容:LOGIN 场景沿用 {@link RedisKeySaltConstant#REDIS_LOGIN_VALID_CODE_KEY}。
|
|
|
*/
|
|
*/
|
|
|
|
|
+ private String captchaRedisKey(SmsCaptchaScene scene, String mobile) {
|
|
|
|
|
+ if (scene == SmsCaptchaScene.LOGIN) {
|
|
|
|
|
+ return RedisKeySaltConstant.REDIS_LOGIN_VALID_CODE_KEY + mobile;
|
|
|
|
|
+ }
|
|
|
|
|
+ return "sms_captcha_" + scene.name() + "_" + mobile;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
public boolean sendMobileVerifyCode(String mobile, Integer checkCode) throws ClientException {
|
|
public boolean sendMobileVerifyCode(String mobile, Integer checkCode) throws ClientException {
|
|
|
return true;
|
|
return true;
|
|
|
- // return SmsUtil.sendSms(smsProperties.getSmsCheckCodeTemplate(), JSON.toJSONString(ImmutableMap.of("number", checkCode)), mobile,smsProperties.getSmsAccessKeyId(),smsProperties.getSmsAccessKeyIdSecret());
|
|
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|