Selaa lähdekoodia

多模块重构 4:system 模块的调整,实现 sms API~~

YunaiV 3 vuotta sitten
vanhempi
commit
16c2590483
14 muutettua tiedostoa jossa 270 lisäystä ja 83 poistoa
  1. 1 2
      pom.xml
  2. 9 8
      yudao-admin-server/pom.xml
  3. 8 4
      yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/convert/auth/AuthConvert.java
  4. 7 6
      yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/auth/MemberAuthServiceImpl.java
  5. 9 14
      yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/user/MemberUserServiceImpl.java
  6. 10 13
      yudao-module-member/yudao-module-member-impl/src/test/java/cn/iocoder/yudao/module/member/service/auth/MemberAuthServiceTest.java
  7. 10 11
      yudao-module-member/yudao-module-member-impl/src/test/java/cn/iocoder/yudao/module/member/service/user/MemberUserServiceImplTest.java
  8. 40 0
      yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/sms/SmsCodeApi.java
  9. 36 0
      yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/sms/dto/SmsCodeCheckReqDTO.java
  10. 36 0
      yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/sms/dto/SmsCodeSendReqDTO.java
  11. 41 0
      yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/sms/dto/SmsCodeUseReqDTO.java
  12. 39 0
      yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/api/sms/SmsCodeApiImpl.java
  13. 11 15
      yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/service/sms/SmsCodeService.java
  14. 13 10
      yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/service/sms/SmsCodeServiceImpl.java

+ 1 - 2
pom.xml

@@ -14,9 +14,8 @@
         <module>yudao-user-server</module>
         <module>yudao-core-service</module>
         <module>yudao-module-member</module>
-        <module>yudao-module-bpm</module>
+<!--        <module>yudao-module-bpm</module>-->
         <module>yudao-module-system</module>
-        <module>yudao-module-system-api</module>
     </modules>
 
     <name>${artifactId}</name>

+ 9 - 8
yudao-admin-server/pom.xml

@@ -57,14 +57,15 @@
         </dependency>
 
         <!-- 默认引入bpm-activiti. 可以替换为bpm-flowable -->
-        <dependency>
-            <groupId>cn.iocoder.boot</groupId>
-            <artifactId>yudao-module-bpm-activiti</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>cn.iocoder.boot</groupId>
-            <artifactId>yudao-module-bpm-core-service-impl</artifactId>
-        </dependency>
+        <!-- TODO 芋艿:临时注释,测试通过后,打开 -->
+<!--        <dependency>-->
+<!--            <groupId>cn.iocoder.boot</groupId>-->
+<!--            <artifactId>yudao-module-bpm-activiti</artifactId>-->
+<!--        </dependency>-->
+<!--        <dependency>-->
+<!--            <groupId>cn.iocoder.boot</groupId>-->
+<!--            <artifactId>yudao-module-bpm-core-service-impl</artifactId>-->
+<!--        </dependency>-->
         <!-- Web 相关 -->
         <dependency>
             <groupId>cn.iocoder.boot</groupId>

+ 8 - 4
yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/convert/auth/AuthConvert.java

@@ -2,13 +2,13 @@ package cn.iocoder.yudao.module.member.convert.auth;
 
 import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
 import cn.iocoder.yudao.framework.security.core.LoginUser;
-import cn.iocoder.yudao.module.member.controller.app.auth.vo.AppAuthSocialBindReqVO;
-import cn.iocoder.yudao.module.member.controller.app.auth.vo.AppAuthSocialLogin2ReqVO;
-import cn.iocoder.yudao.module.member.controller.app.auth.vo.AppAuthSocialLoginReqVO;
-import cn.iocoder.yudao.module.member.controller.app.auth.vo.AppAuthSocialUnbindReqVO;
+import cn.iocoder.yudao.module.member.controller.app.auth.vo.*;
 import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
+import cn.iocoder.yudao.module.system.api.sms.dto.SmsCodeSendReqDTO;
+import cn.iocoder.yudao.module.system.api.sms.dto.SmsCodeUseReqDTO;
 import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO;
 import cn.iocoder.yudao.module.system.api.social.dto.SocialUserUnbindReqDTO;
+import cn.iocoder.yudao.module.system.enums.sms.SmsSceneEnum;
 import org.mapstruct.Mapper;
 import org.mapstruct.Mapping;
 import org.mapstruct.factory.Mappers;
@@ -31,4 +31,8 @@ public interface AuthConvert {
     SocialUserBindReqDTO convert(Long userId, Integer value, AppAuthSocialLoginReqVO reqVO);
     SocialUserUnbindReqDTO convert(Long userId, Integer value, AppAuthSocialUnbindReqVO reqVO);
 
+    SmsCodeSendReqDTO convert(AppAuthSendSmsReqVO reqVO);
+    SmsCodeUseReqDTO convert(AppAuthResetPasswordReqVO reqVO, SmsSceneEnum scene, String usedIp);
+    SmsCodeUseReqDTO convert(AppAuthSmsLoginReqVO reqVO, Integer scene, String userIp);
+
 }

+ 7 - 6
yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/auth/MemberAuthServiceImpl.java

@@ -15,6 +15,7 @@ import cn.iocoder.yudao.module.member.service.user.MemberUserService;
 import cn.iocoder.yudao.module.system.api.auth.UserSessionApi;
 import cn.iocoder.yudao.module.system.api.logger.LoginLogApi;
 import cn.iocoder.yudao.module.system.api.logger.dto.LoginLogCreateReqDTO;
+import cn.iocoder.yudao.module.system.api.sms.SmsCodeApi;
 import cn.iocoder.yudao.module.system.api.social.SocialUserApi;
 import cn.iocoder.yudao.module.system.enums.logger.LoginLogTypeEnum;
 import cn.iocoder.yudao.module.system.enums.logger.LoginResultEnum;
@@ -56,7 +57,7 @@ public class MemberAuthServiceImpl implements MemberAuthService {
     @Resource
     private MemberUserService userService;
     @Resource
-    private SysSmsCodeService smsCodeService;
+    private SmsCodeApi smsCodeApi;
     @Resource
     private LoginLogApi loginLogApi;
     @Resource
@@ -93,8 +94,7 @@ public class MemberAuthServiceImpl implements MemberAuthService {
     @Transactional
     public String smsLogin(AppAuthSmsLoginReqVO reqVO, String userIp, String userAgent) {
         // 校验验证码
-        smsCodeService.useSmsCode(reqVO.getMobile(), SmsSceneEnum.MEMBER_LOGIN.getScene(),
-                reqVO.getCode(), userIp);
+        smsCodeApi.useSmsCode(AuthConvert.INSTANCE.convert(reqVO, SmsSceneEnum.MEMBER_LOGIN.getScene(), userIp));
 
         // 获得获得注册用户
         MemberUserDO user = userService.createUserIfAbsent(reqVO.getMobile(), userIp);
@@ -292,8 +292,8 @@ public class MemberAuthServiceImpl implements MemberAuthService {
         MemberUserDO userDO = checkUserIfExists(reqVO.getMobile());
 
         // 使用验证码
-        smsCodeService.useSmsCode(reqVO.getMobile(), SmsSceneEnum.MEMBER_FORGET_PASSWORD.getScene(), reqVO.getCode(),
-                getClientIP());
+        smsCodeApi.useSmsCode(AuthConvert.INSTANCE.convert(reqVO, SmsSceneEnum.MEMBER_FORGET_PASSWORD,
+                getClientIP()));
 
         // 更新密码
         MemberUserDO mbrUserDO = MemberUserDO.builder().build();
@@ -304,7 +304,8 @@ public class MemberAuthServiceImpl implements MemberAuthService {
 
     @Override
     public void sendSmsCode(Long userId, AppAuthSendSmsReqVO reqVO) {
-        // TODO 芋艿:修改
+        // TODO 要根据不同的场景,校验是否有用户
+        smsCodeApi.sendSmsCode(AuthConvert.INSTANCE.convert(reqVO));
     }
 
     /**

+ 9 - 14
yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/user/MemberUserServiceImpl.java

@@ -4,14 +4,12 @@ import cn.hutool.core.io.IoUtil;
 import cn.hutool.core.util.IdUtil;
 import cn.iocoder.yudao.coreservice.modules.infra.service.file.InfFileCoreService;
 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
-import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
 import cn.iocoder.yudao.module.member.controller.app.user.vo.AppUserUpdateMobileReqVO;
-import cn.iocoder.yudao.module.member.dal.dataobject.sms.SmsCodeDO;
 import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
 import cn.iocoder.yudao.module.member.dal.mysql.user.MemberUserMapper;
-import cn.iocoder.yudao.module.member.enums.SysErrorCodeConstants;
+import cn.iocoder.yudao.module.system.api.sms.SmsCodeApi;
+import cn.iocoder.yudao.module.system.api.sms.dto.SmsCodeUseReqDTO;
 import cn.iocoder.yudao.module.system.enums.sms.SmsSceneEnum;
-import cn.iocoder.yudao.module.member.service.sms.SysSmsCodeService;
 import com.google.common.annotations.VisibleForTesting;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.security.crypto.password.PasswordEncoder;
@@ -43,7 +41,7 @@ public class MemberUserServiceImpl implements MemberUserService {
     @Resource
     private InfFileCoreService fileCoreService;
     @Resource
-    private SysSmsCodeService smsCodeService;
+    private SmsCodeApi smsCodeApi;
 
     @Resource
     private PasswordEncoder passwordEncoder;
@@ -111,22 +109,19 @@ public class MemberUserServiceImpl implements MemberUserService {
         return avatar;
     }
 
+    @Override
     @Transactional(rollbackFor = Exception.class)
     public void updateUserMobile(Long userId, AppUserUpdateMobileReqVO reqVO) {
         // 检测用户是否存在
         checkUserExists(userId);
+        // TODO 芋艿:oldMobile 应该不用传递
 
         // 校验旧手机和旧验证码
-        SmsCodeDO sysSmsCodeDO = smsCodeService.checkCodeIsExpired(reqVO.getOldMobile(), reqVO.getOldCode(),
-                SmsSceneEnum.MEMBER_UPDATE_MOBILE.getScene());
-        // 判断旧 code 是否未被使用,如果是,抛出异常
-        if (Boolean.FALSE.equals(sysSmsCodeDO.getUsed())){
-            throw ServiceExceptionUtil.exception(SysErrorCodeConstants.USER_SMS_CODE_IS_UNUSED);
-        }
-
+        smsCodeApi.useSmsCode(new SmsCodeUseReqDTO().setMobile(reqVO.getOldMobile()).setCode(reqVO.getOldCode())
+                .setScene(SmsSceneEnum.MEMBER_UPDATE_MOBILE.getScene()).setUsedIp(getClientIP()));
         // 使用新验证码
-        smsCodeService.useSmsCode(reqVO.getMobile(), SmsSceneEnum.MEMBER_UPDATE_MOBILE.getScene(),
-                reqVO.getCode(),getClientIP());
+        smsCodeApi.useSmsCode(new SmsCodeUseReqDTO().setMobile(reqVO.getMobile()).setCode(reqVO.getCode())
+                .setScene(SmsSceneEnum.MEMBER_UPDATE_MOBILE.getScene()).setUsedIp(getClientIP()));
 
         // 更新用户手机
         memberUserMapper.updateById(MemberUserDO.builder().id(userId).mobile(reqVO.getMobile()).build());

+ 10 - 13
yudao-module-member/yudao-module-member-impl/src/test/java/cn/iocoder/yudao/module/member/service/auth/SysAuthServiceTest.java → yudao-module-member/yudao-module-member-impl/src/test/java/cn/iocoder/yudao/module/member/service/auth/MemberAuthServiceTest.java

@@ -1,22 +1,21 @@
 package cn.iocoder.yudao.module.member.service.auth;
 
-import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
-import cn.iocoder.yudao.module.system.service.auth.SysUserSessionCoreService;
-import cn.iocoder.yudao.module.system.service.logger.SysLoginLogCoreService;
-import cn.iocoder.yudao.module.system.service.social.SysSocialCoreService;
 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
 import cn.iocoder.yudao.framework.common.util.collection.ArrayUtils;
 import cn.iocoder.yudao.framework.redis.config.YudaoRedisAutoConfiguration;
 import cn.iocoder.yudao.module.member.controller.app.auth.vo.AppAuthResetPasswordReqVO;
 import cn.iocoder.yudao.module.member.controller.app.auth.vo.AppAuthUpdatePasswordReqVO;
+import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
 import cn.iocoder.yudao.module.member.dal.mysql.user.MemberUserMapper;
-import cn.iocoder.yudao.module.member.service.sms.SysSmsCodeService;
 import cn.iocoder.yudao.module.member.service.user.MemberUserService;
 import cn.iocoder.yudao.module.member.test.BaseDbAndRedisUnitTest;
+import cn.iocoder.yudao.module.system.api.auth.UserSessionApi;
+import cn.iocoder.yudao.module.system.api.logger.LoginLogApi;
+import cn.iocoder.yudao.module.system.api.sms.SmsCodeApi;
+import cn.iocoder.yudao.module.system.api.social.SocialUserApi;
 import org.junit.jupiter.api.Test;
 import org.springframework.boot.test.mock.mockito.MockBean;
 import org.springframework.context.annotation.Import;
-import org.springframework.data.redis.core.StringRedisTemplate;
 import org.springframework.security.authentication.AuthenticationManager;
 import org.springframework.security.crypto.password.PasswordEncoder;
 
@@ -37,22 +36,20 @@ import static org.mockito.Mockito.when;
  * @author 宋天
  */
 @Import({MemberAuthServiceImpl.class, YudaoRedisAutoConfiguration.class})
-public class SysAuthServiceTest extends BaseDbAndRedisUnitTest {
+public class MemberAuthServiceTest extends BaseDbAndRedisUnitTest {
 
     @MockBean
     private AuthenticationManager authenticationManager;
     @MockBean
     private MemberUserService userService;
     @MockBean
-    private SysSmsCodeService smsCodeService;
+    private SmsCodeApi smsCodeApi;
     @MockBean
-    private SysLoginLogCoreService loginLogCoreService;
+    private LoginLogApi loginLogApi;
     @MockBean
-    private SysUserSessionCoreService userSessionCoreService;
+    private UserSessionApi userSessionApi;
     @MockBean
-    private SysSocialCoreService socialService;
-    @Resource
-    private StringRedisTemplate stringRedisTemplate;
+    private SocialUserApi socialUserApi;
     @MockBean
     private PasswordEncoder passwordEncoder;
     @Resource

+ 10 - 11
yudao-module-member/yudao-module-member-impl/src/test/java/cn/iocoder/yudao/module/member/service/user/UserServiceImplTest.java → yudao-module-member/yudao-module-member-impl/src/test/java/cn/iocoder/yudao/module/member/service/user/MemberUserServiceImplTest.java

@@ -6,13 +6,11 @@ import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
 import cn.iocoder.yudao.framework.common.util.collection.ArrayUtils;
 import cn.iocoder.yudao.framework.redis.config.YudaoRedisAutoConfiguration;
 import cn.iocoder.yudao.module.member.controller.app.user.vo.AppUserUpdateMobileReqVO;
-import cn.iocoder.yudao.module.member.dal.dataobject.sms.SmsCodeDO;
 import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
 import cn.iocoder.yudao.module.member.dal.mysql.user.MemberUserMapper;
-import cn.iocoder.yudao.module.system.enums.sms.SmsSceneEnum;
 import cn.iocoder.yudao.module.member.service.auth.MemberAuthServiceImpl;
-import cn.iocoder.yudao.module.member.service.sms.SysSmsCodeService;
 import cn.iocoder.yudao.module.member.test.BaseDbAndRedisUnitTest;
+import cn.iocoder.yudao.module.system.api.sms.SmsCodeApi;
 import org.junit.jupiter.api.Test;
 import org.springframework.boot.test.mock.mockito.MockBean;
 import org.springframework.context.annotation.Import;
@@ -36,7 +34,7 @@ import static org.mockito.Mockito.*;
  * @author 宋天
  */
 @Import({MemberUserServiceImpl.class, YudaoRedisAutoConfiguration.class})
-public class UserServiceImplTest extends BaseDbAndRedisUnitTest {
+public class MemberUserServiceImplTest extends BaseDbAndRedisUnitTest {
 
     @Resource
     private MemberUserServiceImpl mbrUserService;
@@ -57,7 +55,7 @@ public class UserServiceImplTest extends BaseDbAndRedisUnitTest {
     private PasswordEncoder passwordEncoder;
 
     @MockBean
-    private SmsCodeService smsCodeService;
+    private SmsCodeApi smsCodeApi;
 
     @Test
     public void testUpdateNickName_success(){
@@ -103,14 +101,15 @@ public class UserServiceImplTest extends BaseDbAndRedisUnitTest {
         userDO.setMobile(oldMobile);
         userMapper.insert(userDO);
 
+        // TODO 芋艿:需要修复该单元测试,重构多模块带来的
         // 旧手机和旧验证码
-        SmsCodeDO codeDO = new SmsCodeDO();
+//        SmsCodeDO codeDO = new SmsCodeDO();
         String oldCode = RandomUtil.randomString(4);
-        codeDO.setMobile(userDO.getMobile());
-        codeDO.setCode(oldCode);
-        codeDO.setScene(SmsSceneEnum.MEMBER_UPDATE_MOBILE.getScene());
-        codeDO.setUsed(Boolean.FALSE);
-        when(smsCodeService.checkCodeIsExpired(codeDO.getMobile(),codeDO.getCode(),codeDO.getScene())).thenReturn(codeDO);
+//        codeDO.setMobile(userDO.getMobile());
+//        codeDO.setCode(oldCode);
+//        codeDO.setScene(SmsSceneEnum.MEMBER_UPDATE_MOBILE.getScene());
+//        codeDO.setUsed(Boolean.FALSE);
+//        when(smsCodeService.checkCodeIsExpired(codeDO.getMobile(),codeDO.getCode(),codeDO.getScene())).thenReturn(codeDO);
 
         // 更新手机号
         String newMobile = randomNumbers(11);

+ 40 - 0
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/sms/SmsCodeApi.java

@@ -0,0 +1,40 @@
+package cn.iocoder.yudao.module.system.api.sms;
+
+import cn.iocoder.yudao.framework.common.exception.ServiceException;
+import cn.iocoder.yudao.module.system.api.sms.dto.SmsCodeCheckReqDTO;
+import cn.iocoder.yudao.module.system.api.sms.dto.SmsCodeSendReqDTO;
+import cn.iocoder.yudao.module.system.api.sms.dto.SmsCodeUseReqDTO;
+
+import javax.validation.Valid;
+
+/**
+ * 短信验证码 API 接口
+ *
+ * @author 芋道源码
+ */
+public interface SmsCodeApi {
+
+    /**
+     * 创建短信验证码,并进行发送
+     *
+     * @param reqDTO 发送请求
+     */
+    void sendSmsCode(@Valid SmsCodeSendReqDTO reqDTO);
+
+    /**
+     * 验证短信验证码,并进行使用
+     * 如果正确,则将验证码标记成已使用
+     * 如果错误,则抛出 {@link ServiceException} 异常
+     *
+     * @param reqDTO 使用请求
+     */
+    void useSmsCode(@Valid SmsCodeUseReqDTO reqDTO);
+
+    /**
+     * 检查验证码是否有效
+     *
+     * @param reqDTO 校验请求
+     */
+    void checkSmsCode(@Valid SmsCodeCheckReqDTO reqDTO);
+
+}

+ 36 - 0
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/sms/dto/SmsCodeCheckReqDTO.java

@@ -0,0 +1,36 @@
+package cn.iocoder.yudao.module.system.api.sms.dto;
+
+import cn.iocoder.yudao.framework.common.validation.InEnum;
+import cn.iocoder.yudao.framework.common.validation.Mobile;
+import cn.iocoder.yudao.module.system.enums.sms.SmsSceneEnum;
+import lombok.Data;
+
+import javax.validation.constraints.NotEmpty;
+
+/**
+ * 短信验证码的校验 Request DTO
+ *
+ * @author 芋道源码
+ */
+@Data
+public class SmsCodeCheckReqDTO {
+
+    /**
+     * 手机号
+     */
+    @Mobile
+    @NotEmpty(message = "手机号不能为空")
+    private String mobile;
+    /**
+     * 发送场景
+     */
+    @NotEmpty(message = "发送场景不能为空")
+    @InEnum(SmsSceneEnum.class)
+    private Integer scene;
+    /**
+     * 验证码
+     */
+    @NotEmpty(message = "验证码")
+    private String code;
+
+}

+ 36 - 0
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/sms/dto/SmsCodeSendReqDTO.java

@@ -0,0 +1,36 @@
+package cn.iocoder.yudao.module.system.api.sms.dto;
+
+import cn.iocoder.yudao.framework.common.validation.InEnum;
+import cn.iocoder.yudao.framework.common.validation.Mobile;
+import cn.iocoder.yudao.module.system.enums.sms.SmsSceneEnum;
+import lombok.Data;
+
+import javax.validation.constraints.NotEmpty;
+
+/**
+ * 短信验证码的发送 Request DTO
+ *
+ * @author 芋道源码
+ */
+@Data
+public class SmsCodeSendReqDTO {
+
+    /**
+     * 手机号
+     */
+    @Mobile
+    @NotEmpty(message = "手机号不能为空")
+    private String mobile;
+    /**
+     * 发送场景
+     */
+    @NotEmpty(message = "发送场景不能为空")
+    @InEnum(SmsSceneEnum.class)
+    private Integer scene;
+    /**
+     * 发送 IP
+     */
+    @NotEmpty(message = "发送 IP 不能为空")
+    private String createIp;
+
+}

+ 41 - 0
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/sms/dto/SmsCodeUseReqDTO.java

@@ -0,0 +1,41 @@
+package cn.iocoder.yudao.module.system.api.sms.dto;
+
+import cn.iocoder.yudao.framework.common.validation.InEnum;
+import cn.iocoder.yudao.framework.common.validation.Mobile;
+import cn.iocoder.yudao.module.system.enums.sms.SmsSceneEnum;
+import lombok.Data;
+
+import javax.validation.constraints.NotEmpty;
+
+/**
+ * 短信验证码的使用 Request DTO
+ *
+ * @author 芋道源码
+ */
+@Data
+public class SmsCodeUseReqDTO {
+
+    /**
+     * 手机号
+     */
+    @Mobile
+    @NotEmpty(message = "手机号不能为空")
+    private String mobile;
+    /**
+     * 发送场景
+     */
+    @NotEmpty(message = "发送场景不能为空")
+    @InEnum(SmsSceneEnum.class)
+    private Integer scene;
+    /**
+     * 验证码
+     */
+    @NotEmpty(message = "验证码")
+    private String code;
+    /**
+     * 使用 IP
+     */
+    @NotEmpty(message = "使用 IP 不能为空")
+    private String usedIp;
+
+}

+ 39 - 0
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/api/sms/SmsCodeApiImpl.java

@@ -0,0 +1,39 @@
+package cn.iocoder.yudao.module.system.api.sms;
+
+import cn.iocoder.yudao.module.system.api.sms.dto.SmsCodeCheckReqDTO;
+import cn.iocoder.yudao.module.system.api.sms.dto.SmsCodeSendReqDTO;
+import cn.iocoder.yudao.module.system.api.sms.dto.SmsCodeUseReqDTO;
+import cn.iocoder.yudao.module.system.service.sms.SmsCodeService;
+import org.springframework.stereotype.Service;
+import org.springframework.validation.annotation.Validated;
+
+import javax.annotation.Resource;
+
+/**
+ * 短信验证码 API 实现类
+ *
+ * @author 芋道源码
+ */
+@Service
+@Validated
+public class SmsCodeApiImpl implements SmsCodeApi {
+
+    @Resource
+    private SmsCodeService smsCodeService;
+
+    @Override
+    public void sendSmsCode(SmsCodeSendReqDTO reqDTO) {
+        smsCodeService.sendSmsCode(reqDTO);
+    }
+
+    @Override
+    public void useSmsCode(SmsCodeUseReqDTO reqDTO) {
+        smsCodeService.useSmsCode(reqDTO);
+    }
+
+    @Override
+    public void checkSmsCode(SmsCodeCheckReqDTO reqDTO) {
+        smsCodeService.checkSmsCode(reqDTO);
+    }
+
+}

+ 11 - 15
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/service/sms/SmsCodeService.java

@@ -1,8 +1,11 @@
 package cn.iocoder.yudao.module.system.service.sms;
 
 import cn.iocoder.yudao.framework.common.exception.ServiceException;
-import cn.iocoder.yudao.framework.common.validation.Mobile;
-import cn.iocoder.yudao.module.system.enums.sms.SmsSceneEnum;
+import cn.iocoder.yudao.module.system.api.sms.dto.SmsCodeCheckReqDTO;
+import cn.iocoder.yudao.module.system.api.sms.dto.SmsCodeSendReqDTO;
+import cn.iocoder.yudao.module.system.api.sms.dto.SmsCodeUseReqDTO;
+
+import javax.validation.Valid;
 
 /**
  * 短信验证码 Service 接口
@@ -14,31 +17,24 @@ public interface SmsCodeService {
     /**
      * 创建短信验证码,并进行发送
      *
-     * @param mobile   手机号
-     * @param scene    发送场景 {@link SmsSceneEnum}
-     * @param createIp 发送 IP
+     * @param reqDTO 发送请求
      */
-    void sendSmsCode(@Mobile String mobile, Integer scene, String createIp);
+    void sendSmsCode(@Valid SmsCodeSendReqDTO reqDTO);
 
     /**
      * 验证短信验证码,并进行使用
      * 如果正确,则将验证码标记成已使用
      * 如果错误,则抛出 {@link ServiceException} 异常
      *
-     * @param mobile 手机号
-     * @param scene  发送场景 {@link SmsSceneEnum}
-     * @param code   验证码
-     * @param usedIp 使用 IP
+     * @param reqDTO 使用请求
      */
-    void useSmsCode(@Mobile String mobile, Integer scene, String code, String usedIp);
+    void useSmsCode(@Valid SmsCodeUseReqDTO reqDTO);
 
     /**
      * 检查验证码是否有效
      *
-     * @param mobile 手机
-     * @param code 验证码
-     * @param scene 使用场景
+     * @param reqDTO 校验请求
      */
-    void checkSmsCode(String mobile, String code, Integer scene);
+    void checkSmsCode(@Valid SmsCodeCheckReqDTO reqDTO);
 
 }

+ 13 - 10
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/service/sms/SmsCodeServiceImpl.java

@@ -4,6 +4,9 @@ import cn.hutool.core.lang.Assert;
 import cn.hutool.core.map.MapUtil;
 import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
 import cn.iocoder.yudao.module.member.api.user.MemberUserApi;
+import cn.iocoder.yudao.module.system.api.sms.dto.SmsCodeCheckReqDTO;
+import cn.iocoder.yudao.module.system.api.sms.dto.SmsCodeSendReqDTO;
+import cn.iocoder.yudao.module.system.api.sms.dto.SmsCodeUseReqDTO;
 import cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsCodeDO;
 import cn.iocoder.yudao.module.system.dal.mysql.sms.SmsCodeMapper;
 import cn.iocoder.yudao.module.system.enums.sms.SmsSceneEnum;
@@ -42,13 +45,13 @@ public class SmsCodeServiceImpl implements SmsCodeService {
     private SmsSendService smsSendService;
 
     @Override
-    public void sendSmsCode(String mobile, Integer scene, String createIp) {
-        SmsSceneEnum sceneEnum = SmsSceneEnum.getCodeByScene(scene);
-        Assert.notNull(sceneEnum, "验证码场景({}) 查找不到配置", scene);
+    public void sendSmsCode(SmsCodeSendReqDTO reqDTO) {
+        SmsSceneEnum sceneEnum = SmsSceneEnum.getCodeByScene(reqDTO.getScene());
+        Assert.notNull(sceneEnum, "验证码场景({}) 查找不到配置", reqDTO.getScene());
         // 创建验证码
-        String code = createSmsCode(mobile, scene, createIp);
+        String code = createSmsCode(reqDTO.getMobile(), reqDTO.getScene(), reqDTO.getCreateIp());
         // 发送验证码
-        smsSendService.sendSingleSms(mobile, null, null,
+        smsSendService.sendSingleSms(reqDTO.getMobile(), null, null,
                 sceneEnum.getTemplateCode(), MapUtil.of("code", code));
     }
 
@@ -77,17 +80,17 @@ public class SmsCodeServiceImpl implements SmsCodeService {
     }
 
     @Override
-    public void useSmsCode(String mobile, Integer scene, String code, String usedIp) {
+    public void useSmsCode(SmsCodeUseReqDTO reqDTO) {
         // 检测验证码是否有效
-        SmsCodeDO lastSmsCode = this.checkSmsCode0(mobile, code, scene);
+        SmsCodeDO lastSmsCode = this.checkSmsCode0(reqDTO.getMobile(), reqDTO.getCode(), reqDTO.getScene());
         // 使用验证码
         smsCodeMapper.updateById(SmsCodeDO.builder().id(lastSmsCode.getId())
-                .used(true).usedTime(new Date()).usedIp(usedIp).build());
+                .used(true).usedTime(new Date()).usedIp(reqDTO.getUsedIp()).build());
     }
 
     @Override
-    public void checkSmsCode(String mobile, String code, Integer scene) {
-        checkSmsCode0(mobile, code, scene);
+    public void checkSmsCode(SmsCodeCheckReqDTO reqDTO) {
+        checkSmsCode0(reqDTO.getMobile(), reqDTO.getCode(), reqDTO.getScene());
     }
 
     public SmsCodeDO checkSmsCode0(String mobile, String code, Integer scene) {