Commit 71b9104a13fddcd03d37e49c76b9e42f5c3db379
1 parent
d784b113
增加短信验证码的功能
Showing
17 changed files
with
255 additions
and
16 deletions
yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/SysAuthController.http
| @@ -6,3 +6,12 @@ Content-Type: application/json | @@ -6,3 +6,12 @@ Content-Type: application/json | ||
| 6 | "mobile": "15601691300", | 6 | "mobile": "15601691300", |
| 7 | "password": "admin123" | 7 | "password": "admin123" |
| 8 | } | 8 | } |
| 9 | + | ||
| 10 | +### 请求 /send-sms-code 接口 => 成功 | ||
| 11 | +POST {{userServerUrl}}/send-sms-code | ||
| 12 | +Content-Type: application/json | ||
| 13 | + | ||
| 14 | +{ | ||
| 15 | + "mobile": "15601691300", | ||
| 16 | + "scene": 1 | ||
| 17 | +} |
yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/SysAuthController.java
| @@ -3,6 +3,7 @@ package cn.iocoder.yudao.userserver.modules.system.controller.auth; | @@ -3,6 +3,7 @@ package cn.iocoder.yudao.userserver.modules.system.controller.auth; | ||
| 3 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; | 3 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 4 | import cn.iocoder.yudao.userserver.modules.system.controller.auth.vo.*; | 4 | import cn.iocoder.yudao.userserver.modules.system.controller.auth.vo.*; |
| 5 | import cn.iocoder.yudao.userserver.modules.system.service.auth.SysAuthService; | 5 | import cn.iocoder.yudao.userserver.modules.system.service.auth.SysAuthService; |
| 6 | +import cn.iocoder.yudao.userserver.modules.system.service.sms.SysSmsCodeService; | ||
| 6 | import io.swagger.annotations.Api; | 7 | import io.swagger.annotations.Api; |
| 7 | import io.swagger.annotations.ApiImplicitParam; | 8 | import io.swagger.annotations.ApiImplicitParam; |
| 8 | import io.swagger.annotations.ApiImplicitParams; | 9 | import io.swagger.annotations.ApiImplicitParams; |
| @@ -27,6 +28,8 @@ public class SysAuthController { | @@ -27,6 +28,8 @@ public class SysAuthController { | ||
| 27 | 28 | ||
| 28 | @Resource | 29 | @Resource |
| 29 | private SysAuthService authService; | 30 | private SysAuthService authService; |
| 31 | + @Resource | ||
| 32 | + private SysSmsCodeService smsCodeService; | ||
| 30 | 33 | ||
| 31 | @PostMapping("/login") | 34 | @PostMapping("/login") |
| 32 | @ApiOperation("使用手机 + 密码登录") | 35 | @ApiOperation("使用手机 + 密码登录") |
| @@ -45,10 +48,8 @@ public class SysAuthController { | @@ -45,10 +48,8 @@ public class SysAuthController { | ||
| 45 | @PostMapping("/send-sms-code") | 48 | @PostMapping("/send-sms-code") |
| 46 | @ApiOperation("发送手机验证码") | 49 | @ApiOperation("发送手机验证码") |
| 47 | public CommonResult<Boolean> sendSmsCode(@RequestBody @Valid MbrAuthSendSmsReqVO reqVO) { | 50 | public CommonResult<Boolean> sendSmsCode(@RequestBody @Valid MbrAuthSendSmsReqVO reqVO) { |
| 48 | -// passportManager.sendSmsCode(sendSmsCodeDTO, HttpUtil.getIp(request)); | ||
| 49 | -// // 返回成功 | ||
| 50 | -// return success(true); | ||
| 51 | - return null; | 51 | + smsCodeService.sendSmsCode(reqVO.getMobile(), reqVO.getScene(), getClientIP()); |
| 52 | + return success(true); | ||
| 52 | } | 53 | } |
| 53 | 54 | ||
| 54 | @PostMapping("/reset-password") | 55 | @PostMapping("/reset-password") |
yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/MbrAuthSendSmsReqVO.java
| 1 | package cn.iocoder.yudao.userserver.modules.system.controller.auth.vo; | 1 | package cn.iocoder.yudao.userserver.modules.system.controller.auth.vo; |
| 2 | 2 | ||
| 3 | +import cn.iocoder.yudao.framework.common.validation.InEnum; | ||
| 3 | import cn.iocoder.yudao.framework.common.validation.Mobile; | 4 | import cn.iocoder.yudao.framework.common.validation.Mobile; |
| 5 | +import cn.iocoder.yudao.userserver.modules.system.enums.sms.SysSmsSceneEnum; | ||
| 4 | import io.swagger.annotations.ApiModel; | 6 | import io.swagger.annotations.ApiModel; |
| 5 | import io.swagger.annotations.ApiModelProperty; | 7 | import io.swagger.annotations.ApiModelProperty; |
| 6 | import lombok.Data; | 8 | import lombok.Data; |
| @@ -19,6 +21,7 @@ public class MbrAuthSendSmsReqVO { | @@ -19,6 +21,7 @@ public class MbrAuthSendSmsReqVO { | ||
| 19 | 21 | ||
| 20 | @ApiModelProperty(value = "发送场景", example = "1", notes = "对应 MbrSmsSceneEnum 枚举") | 22 | @ApiModelProperty(value = "发送场景", example = "1", notes = "对应 MbrSmsSceneEnum 枚举") |
| 21 | @NotNull(message = "发送场景不能为空") | 23 | @NotNull(message = "发送场景不能为空") |
| 24 | + @InEnum(SysSmsSceneEnum.class) | ||
| 22 | private Integer scene; | 25 | private Integer scene; |
| 23 | 26 | ||
| 24 | } | 27 | } |
yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/dal/dataobject/package-info.java
0 → 100644
| 1 | +package cn.iocoder.yudao.userserver.modules.system.dal.dataobject; |
yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/dal/mysql/sms/MbrSmsCodeDO.java renamed to yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/dal/dataobject/sms/SysSmsCodeDO.java
| 1 | -package cn.iocoder.yudao.userserver.modules.member.dal.mysql.sms; | 1 | +package cn.iocoder.yudao.userserver.modules.system.dal.dataobject.sms; |
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; | 3 | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; |
| 4 | import com.baomidou.mybatisplus.annotation.TableName; | 4 | import com.baomidou.mybatisplus.annotation.TableName; |
| 5 | -import lombok.Data; | ||
| 6 | -import lombok.EqualsAndHashCode; | 5 | +import lombok.*; |
| 7 | import lombok.experimental.Accessors; | 6 | import lombok.experimental.Accessors; |
| 8 | 7 | ||
| 9 | import java.util.Date; | 8 | import java.util.Date; |
| @@ -15,11 +14,13 @@ import java.util.Date; | @@ -15,11 +14,13 @@ import java.util.Date; | ||
| 15 | * | 14 | * |
| 16 | * @author 芋道源码 | 15 | * @author 芋道源码 |
| 17 | */ | 16 | */ |
| 18 | -@TableName("mbr_sms_code") | 17 | +@TableName("sys_sms_code") |
| 19 | @Data | 18 | @Data |
| 20 | @EqualsAndHashCode(callSuper = true) | 19 | @EqualsAndHashCode(callSuper = true) |
| 21 | -@Accessors(chain = true) | ||
| 22 | -public class MbrSmsCodeDO extends BaseDO { | 20 | +@Builder |
| 21 | +@NoArgsConstructor | ||
| 22 | +@AllArgsConstructor | ||
| 23 | +public class SysSmsCodeDO extends BaseDO { | ||
| 23 | 24 | ||
| 24 | /** | 25 | /** |
| 25 | * 编号 | 26 | * 编号 |
| @@ -36,7 +37,7 @@ public class MbrSmsCodeDO extends BaseDO { | @@ -36,7 +37,7 @@ public class MbrSmsCodeDO extends BaseDO { | ||
| 36 | /** | 37 | /** |
| 37 | * 发送场景 | 38 | * 发送场景 |
| 38 | * | 39 | * |
| 39 | - * 枚举 {@link MbrSmsCodeDO} | 40 | + * 枚举 {@link SysSmsCodeDO} |
| 40 | */ | 41 | */ |
| 41 | private Integer scene; | 42 | private Integer scene; |
| 42 | /** | 43 | /** |
yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/dal/mysql/package-info.java
0 → 100644
| 1 | +package cn.iocoder.yudao.userserver.modules.system.dal.mysql; |
yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/dal/mysql/sms/SysSmsCodeMapper.java
0 → 100644
| 1 | +package cn.iocoder.yudao.userserver.modules.system.dal.mysql.sms; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; | ||
| 4 | +import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX; | ||
| 5 | +import cn.iocoder.yudao.userserver.modules.system.dal.dataobject.sms.SysSmsCodeDO; | ||
| 6 | +import org.apache.ibatis.annotations.Mapper; | ||
| 7 | + | ||
| 8 | +@Mapper | ||
| 9 | +public interface SysSmsCodeMapper extends BaseMapperX<SysSmsCodeDO> { | ||
| 10 | + | ||
| 11 | + /** | ||
| 12 | + * 获得手机号的最后一个手机验证码 | ||
| 13 | + * | ||
| 14 | + * @param mobile 手机号 | ||
| 15 | + * @param scene 发送场景,选填 | ||
| 16 | + * @return 手机验证码 | ||
| 17 | + */ | ||
| 18 | + default SysSmsCodeDO selectLastByMobile(String mobile, Integer scene) { | ||
| 19 | + return selectOne(new QueryWrapperX<SysSmsCodeDO>() | ||
| 20 | + .eq("mobile", mobile) | ||
| 21 | + .eqIfPresent("scene", scene) | ||
| 22 | + .orderByDesc("id") | ||
| 23 | + .last("LIMIT 1")); | ||
| 24 | + } | ||
| 25 | + | ||
| 26 | +} |
yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/dal/redis/package-info.java
0 → 100644
| 1 | +package cn.iocoder.yudao.userserver.modules.system.dal.redis; |
yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/enums/SysErrorCodeConstants.java
| @@ -14,4 +14,11 @@ public interface SysErrorCodeConstants { | @@ -14,4 +14,11 @@ public interface SysErrorCodeConstants { | ||
| 14 | ErrorCode AUTH_LOGIN_USER_DISABLED = new ErrorCode(1005000001, "登录失败,账号被禁用"); | 14 | ErrorCode AUTH_LOGIN_USER_DISABLED = new ErrorCode(1005000001, "登录失败,账号被禁用"); |
| 15 | ErrorCode AUTH_LOGIN_FAIL_UNKNOWN = new ErrorCode(1005000002, "登录失败"); // 登录失败的兜底,未知原因 | 15 | ErrorCode AUTH_LOGIN_FAIL_UNKNOWN = new ErrorCode(1005000002, "登录失败"); // 登录失败的兜底,未知原因 |
| 16 | 16 | ||
| 17 | + // ========== SMS CODE 模块 1005001000 ========== | ||
| 18 | + ErrorCode USER_SMS_CODE_NOT_FOUND = new ErrorCode(1005001000, "验证码不存在"); | ||
| 19 | + ErrorCode USER_SMS_CODE_EXPIRED = new ErrorCode(1005001001, "验证码已过期"); | ||
| 20 | + ErrorCode USER_SMS_CODE_USED = new ErrorCode(1005001002, "验证码已使用"); | ||
| 21 | + ErrorCode USER_SMS_CODE_NOT_CORRECT = new ErrorCode(1005001003, "验证码不正确"); | ||
| 22 | + ErrorCode USER_SMS_CODE_EXCEED_SEND_MAXIMUM_QUANTITY_PER_DAY = new ErrorCode(1005001004, "超过每日短信发送数量"); | ||
| 23 | + ErrorCode USER_SMS_CODE_SEND_TOO_FAST = new ErrorCode(1005001005, "短信发送过于频率"); | ||
| 17 | } | 24 | } |
yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/enums/sms/MbrSmsSceneEnum.java renamed to yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/enums/sms/SysSmsSceneEnum.java
| 1 | -package cn.iocoder.yudao.userserver.modules.member.enums.sms; | 1 | +package cn.iocoder.yudao.userserver.modules.system.enums.sms; |
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.common.core.IntArrayValuable; | 3 | import cn.iocoder.yudao.framework.common.core.IntArrayValuable; |
| 4 | import lombok.AllArgsConstructor; | 4 | import lombok.AllArgsConstructor; |
| @@ -13,13 +13,13 @@ import java.util.Arrays; | @@ -13,13 +13,13 @@ import java.util.Arrays; | ||
| 13 | */ | 13 | */ |
| 14 | @Getter | 14 | @Getter |
| 15 | @AllArgsConstructor | 15 | @AllArgsConstructor |
| 16 | -public enum MbrSmsSceneEnum implements IntArrayValuable { | 16 | +public enum SysSmsSceneEnum implements IntArrayValuable { |
| 17 | 17 | ||
| 18 | LOGIN_BY_SMS(1, "手机号登陆"), | 18 | LOGIN_BY_SMS(1, "手机号登陆"), |
| 19 | CHANGE_MOBILE_BY_SMS(2, "更换手机号"), | 19 | CHANGE_MOBILE_BY_SMS(2, "更换手机号"), |
| 20 | ; | 20 | ; |
| 21 | 21 | ||
| 22 | - public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(MbrSmsSceneEnum::getScene).toArray(); | 22 | + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(SysSmsSceneEnum::getScene).toArray(); |
| 23 | 23 | ||
| 24 | private final Integer scene; | 24 | private final Integer scene; |
| 25 | private final String name; | 25 | private final String name; |
yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/framework/package-info.java
0 → 100644
yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/framework/sms/SmsCodeConfiguration.java
0 → 100644
| 1 | +package cn.iocoder.yudao.userserver.modules.system.framework.sms; | ||
| 2 | + | ||
| 3 | +import org.springframework.boot.context.properties.EnableConfigurationProperties; | ||
| 4 | +import org.springframework.context.annotation.Configuration; | ||
| 5 | + | ||
| 6 | +@Configuration | ||
| 7 | +@EnableConfigurationProperties(SmsCodeProperties.class) | ||
| 8 | +public class SmsCodeConfiguration { | ||
| 9 | +} |
yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/framework/sms/SmsCodeProperties.java
0 → 100644
| 1 | +package cn.iocoder.yudao.userserver.modules.system.framework.sms; | ||
| 2 | + | ||
| 3 | +import lombok.Data; | ||
| 4 | +import org.springframework.boot.context.properties.ConfigurationProperties; | ||
| 5 | +import org.springframework.validation.annotation.Validated; | ||
| 6 | + | ||
| 7 | +import javax.validation.constraints.NotEmpty; | ||
| 8 | +import javax.validation.constraints.NotNull; | ||
| 9 | +import java.time.Duration; | ||
| 10 | +import java.util.Collection; | ||
| 11 | + | ||
| 12 | +@ConfigurationProperties(prefix = "yudao.sms-code") | ||
| 13 | +@Validated | ||
| 14 | +@Data | ||
| 15 | +public class SmsCodeProperties { | ||
| 16 | + | ||
| 17 | + /** | ||
| 18 | + * 过期时间 | ||
| 19 | + */ | ||
| 20 | + @NotNull(message = "过期时间不能为空") | ||
| 21 | + private Duration expireTimes; | ||
| 22 | + /** | ||
| 23 | + * 短信发送频率 | ||
| 24 | + */ | ||
| 25 | + @NotNull(message = "短信发送频率不能为空") | ||
| 26 | + private Duration sendFrequency; | ||
| 27 | + /** | ||
| 28 | + * 每日发送最大数量 | ||
| 29 | + */ | ||
| 30 | + @NotNull(message = "每日发送最大数量不能为空") | ||
| 31 | + private Integer sendMaximumQuantityPerDay; | ||
| 32 | + /** | ||
| 33 | + * 验证码最小值 | ||
| 34 | + */ | ||
| 35 | + @NotNull(message = "验证码最小值不能为空") | ||
| 36 | + private Integer beginCode; | ||
| 37 | + /** | ||
| 38 | + * 验证码最大值 | ||
| 39 | + */ | ||
| 40 | + @NotNull(message = "验证码最大值不能为空") | ||
| 41 | + private Integer endCode; | ||
| 42 | + | ||
| 43 | +} |
yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/sms/SysSmsCodeService.java
0 → 100644
| 1 | +package cn.iocoder.yudao.userserver.modules.system.service.sms; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.common.exception.ServiceException; | ||
| 4 | +import cn.iocoder.yudao.framework.common.validation.Mobile; | ||
| 5 | +import cn.iocoder.yudao.userserver.modules.system.enums.sms.SysSmsSceneEnum; | ||
| 6 | + | ||
| 7 | +/** | ||
| 8 | + * 短信验证码 Service 接口 | ||
| 9 | + * | ||
| 10 | + * @author 芋道源码 | ||
| 11 | + */ | ||
| 12 | +public interface SysSmsCodeService { | ||
| 13 | + | ||
| 14 | + /** | ||
| 15 | + * 创建短信验证码,并进行发送 | ||
| 16 | + * | ||
| 17 | + * @param mobile 手机号 | ||
| 18 | + * @param scene 发送场景 {@link SysSmsSceneEnum} | ||
| 19 | + * @param createIp 发送 IP | ||
| 20 | + */ | ||
| 21 | + void sendSmsCode(@Mobile String mobile, Integer scene, String createIp); | ||
| 22 | + | ||
| 23 | + /** | ||
| 24 | + * 验证短信验证码,并进行使用 | ||
| 25 | + * 如果正确,则将验证码标记成已使用 | ||
| 26 | + * 如果错误,则抛出 {@link ServiceException} 异常 | ||
| 27 | + * | ||
| 28 | + * @param mobile 手机号 | ||
| 29 | + * @param scene 发送场景 | ||
| 30 | + * @param code 验证码 | ||
| 31 | + * @param usedIp 使用 IP | ||
| 32 | + */ | ||
| 33 | + void useSmsCode(@Mobile String mobile, Integer scene, String code, String usedIp); | ||
| 34 | + | ||
| 35 | +} |
yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/sms/impl/SysSmsCodeServiceImpl.java
0 → 100644
| 1 | +package cn.iocoder.yudao.userserver.modules.system.service.sms.impl; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.userserver.modules.system.dal.dataobject.sms.SysSmsCodeDO; | ||
| 4 | +import cn.iocoder.yudao.userserver.modules.system.dal.mysql.sms.SysSmsCodeMapper; | ||
| 5 | +import cn.iocoder.yudao.userserver.modules.system.framework.sms.SmsCodeProperties; | ||
| 6 | +import cn.iocoder.yudao.userserver.modules.system.service.sms.SysSmsCodeService; | ||
| 7 | +import org.springframework.stereotype.Service; | ||
| 8 | +import org.springframework.validation.annotation.Validated; | ||
| 9 | + | ||
| 10 | +import javax.annotation.Resource; | ||
| 11 | +import java.util.Date; | ||
| 12 | + | ||
| 13 | +import static cn.hutool.core.util.RandomUtil.randomInt; | ||
| 14 | +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | ||
| 15 | +import static cn.iocoder.yudao.userserver.modules.system.enums.SysErrorCodeConstants.*; | ||
| 16 | + | ||
| 17 | +/** | ||
| 18 | + * 短信验证码 Service 实现类 | ||
| 19 | + * | ||
| 20 | + * @author 芋道源码 | ||
| 21 | + */ | ||
| 22 | +@Service | ||
| 23 | +@Validated | ||
| 24 | +public class SysSmsCodeServiceImpl implements SysSmsCodeService { | ||
| 25 | + | ||
| 26 | + @Resource | ||
| 27 | + private SmsCodeProperties smsCodeProperties; | ||
| 28 | + | ||
| 29 | + @Resource | ||
| 30 | + private SysSmsCodeMapper smsCodeMapper; | ||
| 31 | + | ||
| 32 | + @Override | ||
| 33 | + public void sendSmsCode(String mobile, Integer scene, String createIp) { | ||
| 34 | + // 创建验证码 | ||
| 35 | + String code = this.createSmsCode(mobile, scene, createIp); | ||
| 36 | + // 发送验证码 | ||
| 37 | + // TODO 芋艿:重要,发送短信验证码 | ||
| 38 | + } | ||
| 39 | + | ||
| 40 | + private String createSmsCode(String mobile, Integer scene, String ip) { | ||
| 41 | + // 校验是否可以发送验证码,不用筛选场景 | ||
| 42 | + SysSmsCodeDO lastSmsCode = smsCodeMapper.selectLastByMobile(mobile, null); | ||
| 43 | + if (lastSmsCode != null) { | ||
| 44 | + if (lastSmsCode.getTodayIndex() >= smsCodeProperties.getSendMaximumQuantityPerDay()) { // 超过当天发送的上限。 | ||
| 45 | + throw exception(USER_SMS_CODE_EXCEED_SEND_MAXIMUM_QUANTITY_PER_DAY); | ||
| 46 | + } | ||
| 47 | + if (System.currentTimeMillis() - lastSmsCode.getCreateTime().getTime() | ||
| 48 | + < smsCodeProperties.getSendFrequency().toMillis()) { // 发送过于频繁 | ||
| 49 | + throw exception(USER_SMS_CODE_SEND_TOO_FAST); | ||
| 50 | + } | ||
| 51 | + // TODO 芋艿:提升,每个 IP 每天可发送数量 | ||
| 52 | + // TODO 芋艿:提升,每个 IP 每小时可发送数量 | ||
| 53 | + } | ||
| 54 | + | ||
| 55 | + // 创建验证码记录 | ||
| 56 | + String code = String.valueOf(randomInt(smsCodeProperties.getBeginCode(), smsCodeProperties.getEndCode() + 1)); | ||
| 57 | + SysSmsCodeDO newSmsCode = SysSmsCodeDO.builder().mobile(mobile).code(code) | ||
| 58 | + .scene(scene).todayIndex(lastSmsCode != null ? lastSmsCode.getTodayIndex() + 1 : 1) | ||
| 59 | + .createIp(ip).used(false).build(); | ||
| 60 | + smsCodeMapper.insert(newSmsCode); | ||
| 61 | + return code; | ||
| 62 | + } | ||
| 63 | + | ||
| 64 | + @Override | ||
| 65 | + public void useSmsCode(String mobile, Integer scene, String code, String usedIp) { | ||
| 66 | + // 校验验证码 | ||
| 67 | + SysSmsCodeDO lastSmsCode = smsCodeMapper.selectLastByMobile(mobile, scene); | ||
| 68 | + if (lastSmsCode == null) { // 若验证码不存在,抛出异常 | ||
| 69 | + throw exception(USER_SMS_CODE_NOT_FOUND); | ||
| 70 | + } | ||
| 71 | + if (System.currentTimeMillis() - lastSmsCode.getCreateTime().getTime() | ||
| 72 | + >= smsCodeProperties.getExpireTimes().toMillis()) { // 验证码已过期 | ||
| 73 | + throw exception(USER_SMS_CODE_EXPIRED); | ||
| 74 | + } | ||
| 75 | + if (lastSmsCode.getUsed()) { // 验证码已使用 | ||
| 76 | + throw exception(USER_SMS_CODE_USED); | ||
| 77 | + } | ||
| 78 | + if (!lastSmsCode.getCode().equals(code)) { | ||
| 79 | + throw exception(USER_SMS_CODE_NOT_CORRECT); | ||
| 80 | + } | ||
| 81 | + | ||
| 82 | + // 使用验证码 | ||
| 83 | + smsCodeMapper.updateById(SysSmsCodeDO.builder().id(lastSmsCode.getId()) | ||
| 84 | + .used(true).usedTime(new Date()).usedIp(usedIp).build()); | ||
| 85 | + } | ||
| 86 | + | ||
| 87 | +} |
yudao-user-server/src/main/resources/application.yaml
| @@ -58,5 +58,13 @@ yudao: | @@ -58,5 +58,13 @@ yudao: | ||
| 58 | db-schemas: ${spring.datasource.dynamic.datasource.master.name} | 58 | db-schemas: ${spring.datasource.dynamic.datasource.master.name} |
| 59 | error-code: # 错误码相关配置项 | 59 | error-code: # 错误码相关配置项 |
| 60 | constants-class-list: | 60 | constants-class-list: |
| 61 | + - cn.iocoder.yudao.userserver.modules.member.enums.MbrErrorCodeConstants | ||
| 62 | + - cn.iocoder.yudao.userserver.modules.system.enums.SysErrorCodeConstants | ||
| 63 | + sms-code: # 短信验证码相关的配置项 | ||
| 64 | + expire-times: 10m | ||
| 65 | + send-frequency: 1m | ||
| 66 | + send-maximum-quantity-per-day: 10 | ||
| 67 | + begin-code: 9999 # 这里配置 9999 的原因是,测试方便。 | ||
| 68 | + end-code: 9999 # 这里配置 9999 的原因是,测试方便。 | ||
| 61 | 69 | ||
| 62 | debug: false | 70 | debug: false |
更新日志.md
| @@ -10,13 +10,14 @@ | @@ -10,13 +10,14 @@ | ||
| 10 | ## [v1.1.1] 待定 | 10 | ## [v1.1.1] 待定 |
| 11 | 11 | ||
| 12 | * 支付 | 12 | * 支付 |
| 13 | +* 用户前台的社交登陆 | ||
| 13 | 14 | ||
| 14 | -## [v1.1.0] 待定 | 15 | +## [v1.1.0] 进行中 |
| 15 | 16 | ||
| 16 | * 新增管理后台的企业微信、钉钉等社交登录 | 17 | * 新增管理后台的企业微信、钉钉等社交登录 |
| 17 | * 新增用户前台(例如说,用户使用的小程序)的后端项目 `yudao-user-server` | 18 | * 新增用户前台(例如说,用户使用的小程序)的后端项目 `yudao-user-server` |
| 18 | * 新增公共服务 `yudao-core-service` 项目,通过 Jar 包的方式,提供 `yudao-user-server` 和 `yudao-admin-server` 的共享逻辑的复用。 | 19 | * 新增公共服务 `yudao-core-service` 项目,通过 Jar 包的方式,提供 `yudao-user-server` 和 `yudao-admin-server` 的共享逻辑的复用。 |
| 19 | -* 新增用户前台的手机登录、验证码登录、TODO | 20 | +* 新增用户前台的手机登录、验证码登录 |
| 20 | * 修复管理后台的用户头像上传 404 的问题 | 21 | * 修复管理后台的用户头像上传 404 的问题 |
| 21 | 22 | ||
| 22 | ## [v1.0.0] 2021.05.03 | 23 | ## [v1.0.0] 2021.05.03 |