diff --git a/yudao-admin-server/pom.xml b/yudao-admin-server/pom.xml index 847e626a0..40943697f 100644 --- a/yudao-admin-server/pom.xml +++ b/yudao-admin-server/pom.xml @@ -17,6 +17,13 @@ https://github.com/YunaiV/ruoyi-vue-pro + + + cn.iocoder.boot + yudao-module-member-impl + ${revision} + + cn.iocoder.boot diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/AdminServerApplication.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/AdminServerApplication.java index 810869768..35f6a1d8d 100644 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/AdminServerApplication.java +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/AdminServerApplication.java @@ -4,7 +4,8 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SuppressWarnings("SpringComponentScan") // 忽略 IDEA 无法识别 ${yudao.info.base-package} 和 ${yudao.core-service.base-package} -@SpringBootApplication(scanBasePackages = {"${yudao.info.base-package}", "${yudao.core-service.base-package}"}) +@SpringBootApplication(scanBasePackages = {"${yudao.info.base-package}", "${yudao.core-service.base-package}", + "${yudao.info.member-package}"}) // TODO 芋艿:重构 public class AdminServerApplication { public static void main(String[] args) { diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/framework/security/SecurityConfiguration.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/framework/security/SecurityConfiguration.java index e99c106b4..a5086b92e 100644 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/framework/security/SecurityConfiguration.java +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/framework/security/SecurityConfiguration.java @@ -23,19 +23,28 @@ public class SecurityConfiguration { public Customizer.ExpressionInterceptUrlRegistry> authorizeRequestsCustomizer() { return registry -> { // 验证码的接口 - registry.antMatchers(api("/system/captcha/**")).anonymous(); + registry.antMatchers(buildAdminApi("/system/captcha/**")).anonymous(); // 获得租户编号的接口 - registry.antMatchers(api("/system/tenant/get-id-by-name")).anonymous(); + registry.antMatchers(buildAdminApi("/system/tenant/get-id-by-name")).anonymous(); // Spring Boot Admin Server 的安全配置 registry.antMatchers(adminSeverContextPath).anonymous() .antMatchers(adminSeverContextPath + "/**").anonymous(); // 短信回调 API - registry.antMatchers(api("/system/sms/callback/**")).anonymous(); + registry.antMatchers(buildAdminApi("/system/sms/callback/**")).anonymous(); + + // 设置 App API 无需认证 + registry.antMatchers(buildAppApi("/**")); }; } - private String api(String url) { - return webProperties.getApiPrefix() + url; + private String buildAdminApi(String url) { + // TODO 芋艿:多模块 + return webProperties.getAdminApi().getPrefix() + url; + } + + private String buildAppApi(String url) { + // TODO 芋艿:多模块 + return webProperties.getAppApi().getPrefix() + url; } } diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/framework/activiti/config/BpmActivitiConfiguration.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/framework/activiti/config/BpmActivitiConfiguration.java index ccb7cad78..c18893f16 100644 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/framework/activiti/config/BpmActivitiConfiguration.java +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/framework/activiti/config/BpmActivitiConfiguration.java @@ -11,10 +11,12 @@ import cn.iocoder.yudao.adminserver.modules.system.service.dept.SysDeptService; import cn.iocoder.yudao.adminserver.modules.system.service.permission.SysPermissionService; import cn.iocoder.yudao.adminserver.modules.system.service.user.SysUserService; import org.activiti.api.runtime.shared.identity.UserGroupManager; +import org.activiti.core.common.spring.identity.ActivitiUserGroupManagerImpl; import org.activiti.spring.boot.ProcessEngineConfigurationConfigurer; import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.security.core.userdetails.UserDetailsService; import java.util.Collections; import java.util.List; @@ -28,7 +30,15 @@ import static org.activiti.spring.boot.ProcessEngineAutoConfiguration.BEHAVIOR_F public class BpmActivitiConfiguration { /** - * BPM 模块的 ProcessEngineConfigurationConfigurer 实现类,主要设置各种监听器、用户组管理 + * 空用户组的 Bean + */ + @Bean + public UserGroupManager userGroupManager() { + return new EmptyUserGroupManager(); + } + + /** + * BPM 模块的 ProcessEngineConfigurationConfigurer 实现类,主要设置各种监听器 */ @Bean public ProcessEngineConfigurationConfigurer bpmProcessEngineConfigurationConfigurer( @@ -36,8 +46,6 @@ public class BpmActivitiConfiguration { return configuration -> { // 注册监听器,例如说 BpmActivitiEventListener configuration.setEventListeners(Collections.singletonList(taskActivitiEventListener)); - // 用户组 - configuration.setUserGroupManager(new EmptyUserGroupManager()); }; } diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/auth/impl/SysAuthServiceImpl.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/auth/impl/SysAuthServiceImpl.java index 438bd1e75..3f795f83d 100644 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/auth/impl/SysAuthServiceImpl.java +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/auth/impl/SysAuthServiceImpl.java @@ -60,8 +60,6 @@ import static java.util.Collections.singleton; @Slf4j public class SysAuthServiceImpl implements SysAuthService { - private static final UserTypeEnum USER_TYPE_ENUM = UserTypeEnum.ADMIN; - @Resource @Lazy // 延迟加载,因为存在相互依赖的问题 private AuthenticationManager authenticationManager; @@ -83,7 +81,6 @@ public class SysAuthServiceImpl implements SysAuthService { @Resource private SysSocialCoreService socialService; - @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { // 获取 username 对应的 SysUserDO @@ -216,7 +213,7 @@ public class SysAuthServiceImpl implements SysAuthService { // 如果未绑定 SysSocialUserDO 用户,则无法自动登录,进行报错 String unionId = socialService.getAuthUserUnionId(authUser); - List socialUsers = socialService.getAllSocialUserList(reqVO.getType(), unionId, USER_TYPE_ENUM); + List socialUsers = socialService.getAllSocialUserList(reqVO.getType(), unionId, getUserType()); if (CollUtil.isEmpty(socialUsers)) { throw exception(AUTH_THIRD_LOGIN_NOT_BIND); } @@ -232,7 +229,7 @@ public class SysAuthServiceImpl implements SysAuthService { LoginUser loginUser = this.buildLoginUser(user); // 绑定社交用户(更新) - socialService.bindSocialUser(loginUser.getId(), reqVO.getType(), authUser, USER_TYPE_ENUM); + socialService.bindSocialUser(loginUser.getId(), reqVO.getType(), authUser, getUserType()); // 缓存登录用户到 Redis 中,返回 sessionId 编号 return userSessionCoreService.createUserSession(loginUser, userIp, userAgent); @@ -248,7 +245,7 @@ public class SysAuthServiceImpl implements SysAuthService { LoginUser loginUser = this.login0(reqVO.getUsername(), reqVO.getPassword()); // 绑定社交用户(新增) - socialService.bindSocialUser(loginUser.getId(), reqVO.getType(), authUser, USER_TYPE_ENUM); + socialService.bindSocialUser(loginUser.getId(), reqVO.getType(), authUser, getUserType()); // 缓存登录用户到 Redis 中,返回 sessionId 编号 return userSessionCoreService.createUserSession(loginUser, userIp, userAgent); @@ -261,7 +258,7 @@ public class SysAuthServiceImpl implements SysAuthService { Assert.notNull(authUser, "授权用户不为空"); // 绑定社交用户(新增) - socialService.bindSocialUser(userId, reqVO.getType(), authUser, USER_TYPE_ENUM); + socialService.bindSocialUser(userId, reqVO.getType(), authUser, getUserType()); } @Override @@ -277,12 +274,17 @@ public class SysAuthServiceImpl implements SysAuthService { this.createLogoutLog(loginUser.getId(), loginUser.getUsername()); } + @Override + public UserTypeEnum getUserType() { + return UserTypeEnum.ADMIN; + } + private void createLogoutLog(Long userId, String username) { SysLoginLogCreateReqDTO reqDTO = new SysLoginLogCreateReqDTO(); reqDTO.setLogType(SysLoginLogTypeEnum.LOGOUT_SELF.getType()); reqDTO.setTraceId(TracerUtils.getTraceId()); reqDTO.setUserId(userId); - reqDTO.setUserType(USER_TYPE_ENUM.getValue()); + reqDTO.setUserType(getUserType().getValue()); reqDTO.setUsername(username); reqDTO.setUserAgent(ServletUtils.getUserAgent()); reqDTO.setUserIp(ServletUtils.getClientIP()); diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/user/impl/SysUserServiceImpl.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/user/impl/SysUserServiceImpl.java index d5b2ad18b..98ca0160e 100644 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/user/impl/SysUserServiceImpl.java +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/user/impl/SysUserServiceImpl.java @@ -23,6 +23,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import com.google.common.annotations.VisibleForTesting; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; @@ -47,7 +48,7 @@ public class SysUserServiceImpl implements SysUserService { @Value("${sys.user.init-password:yudaoyuanma}") private String userInitPassword; - @Resource + @Resource(name = "sysUserMapper") // userMapper 存在重名 private SysUserMapper userMapper; @Resource diff --git a/yudao-admin-server/src/main/resources/application-local.yaml b/yudao-admin-server/src/main/resources/application-local.yaml index 9932671dc..411f2a6a3 100644 --- a/yudao-admin-server/src/main/resources/application-local.yaml +++ b/yudao-admin-server/src/main/resources/application-local.yaml @@ -174,6 +174,18 @@ logging: cn.iocoder.yudao.coreservice.modules.system.dal.mysql: debug cn.iocoder.yudao.coreservice.modules.tool.dal.mysql: debug +--- #################### 微信公众号相关配置 #################### +wx: # 参见 https://github.com/Wechat-Group/WxJava/blob/develop/spring-boot-starters/wx-java-mp-spring-boot-starter/README.md 文档 + mp: + # 公众号配置(必填) + app-id: wx041349c6f39b268b + secret: 5abee519483bc9f8cb37ce280e814bd0 + # 存储配置,解决 AccessToken 的跨节点的共享 + config-storage: + type: RedisTemplate # 采用 RedisTemplate 操作 Redis,会自动从 Spring 中获取 + key-prefix: wx # Redis Key 的前缀 TODO 芋艿:解决下 Redis key 管理的配置 + http-client-type: HttpClient # 采用 HttpClient 请求微信公众号平台 + --- #################### 芋道相关配置 #################### # 芋道配置项,设置当前项目所有自定义的配置 diff --git a/yudao-admin-server/src/main/resources/application.yaml b/yudao-admin-server/src/main/resources/application.yaml index 7652dd5be..09bbc33ad 100644 --- a/yudao-admin-server/src/main/resources/application.yaml +++ b/yudao-admin-server/src/main/resources/application.yaml @@ -48,11 +48,17 @@ yudao: info: version: 1.0.0 base-package: cn.iocoder.yudao.adminserver + member-package: cn.iocoder.yudao.module.member core-service: base-package: cn.iocoder.yudao.coreservice web: - api-prefix: /api - controller-package: ${yudao.info.base-package} + admin-api: + prefix: /api + controller: ${yudao.info.base-package} + app-api: + prefix: /app-api + controller: cn.iocoder.yudao.module.member.controller.app + swagger: title: 管理后台 description: 提供管理员管理的所有功能 @@ -72,7 +78,13 @@ yudao: - cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants tenant: # 多租户相关配置项 tables: # 配置需要开启多租户的表;如果实体已经继承 TenantBaseDO 类,则无需重复配置 - url: + url: ## TODO 芋艿:迁移到 web 配置项下, admin-ui: http://dashboard.yudao.iocoder.cn # Admin 管理后台 UI 的地址 + sms-code: # 短信验证码相关的配置项 + expire-times: 10m + send-frequency: 1m + send-maximum-quantity-per-day: 10 + begin-code: 9999 # 这里配置 9999 的原因是,测试方便。 + end-code: 9999 # 这里配置 9999 的原因是,测试方便。 debug: false diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/infra/service/file/InfFileCoreService.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/infra/service/file/InfFileCoreService.java index a594bcef4..8ba8b57fe 100644 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/infra/service/file/InfFileCoreService.java +++ b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/infra/service/file/InfFileCoreService.java @@ -9,7 +9,6 @@ import cn.iocoder.yudao.coreservice.modules.infra.dal.dataobject.file.InfFileDO; */ public interface InfFileCoreService { - /** * 保存文件,并返回文件的访问路径 * diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/system/service/sms/impl/SysSmsCoreServiceImpl.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/system/service/sms/impl/SysSmsCoreServiceImpl.java index 3893ba340..787d2a1d9 100644 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/system/service/sms/impl/SysSmsCoreServiceImpl.java +++ b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/system/service/sms/impl/SysSmsCoreServiceImpl.java @@ -2,8 +2,6 @@ package cn.iocoder.yudao.coreservice.modules.system.service.sms.impl; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.StrUtil; -import cn.iocoder.yudao.coreservice.modules.member.dal.dataobject.user.MbrUserDO; -import cn.iocoder.yudao.coreservice.modules.member.service.user.MbrUserCoreService; import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.sms.SysSmsTemplateDO; import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.user.SysUserDO; import cn.iocoder.yudao.coreservice.modules.system.mq.message.sms.SysSmsSendMessage; @@ -43,8 +41,6 @@ public class SysSmsCoreServiceImpl implements SysSmsCoreService { @Resource private SysUserCoreService sysUserCoreService; @Resource - private MbrUserCoreService mbrUserCoreService; - @Resource private SysSmsTemplateCoreService smsTemplateCoreService; @Resource private SysSmsLogCoreService smsLogCoreService; @@ -72,10 +68,11 @@ public class SysSmsCoreServiceImpl implements SysSmsCoreService { public Long sendSingleSmsToMember(String mobile, Long userId, String templateCode, Map templateParams) { // 如果 mobile 为空,则加载用户编号对应的手机号 if (StrUtil.isEmpty(mobile)) { - MbrUserDO user = mbrUserCoreService.getUser(userId); - if (user != null) { - mobile = user.getMobile(); - } +// MbrUserDO user = mbrUserCoreService.getUser(userId); +// if (user != null) { +// mobile = user.getMobile(); +// } + // TODO 芋艿:重构 } // 执行发送 return this.sendSingleSms(mobile, userId, UserTypeEnum.MEMBER.getValue(), templateCode, templateParams); diff --git a/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/config/YudaoMybatisAutoConfiguration.java b/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/config/YudaoMybatisAutoConfiguration.java index b03fc58e4..d589ac768 100644 --- a/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/config/YudaoMybatisAutoConfiguration.java +++ b/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/config/YudaoMybatisAutoConfiguration.java @@ -15,7 +15,8 @@ import org.springframework.context.annotation.Configuration; * @author 芋道源码 */ @Configuration -@MapperScan(value = {"${yudao.info.base-package}", "${yudao.core-service.base-package}"}, annotationClass = Mapper.class, +@MapperScan(value = {"${yudao.info.base-package}", "${yudao.core-service.base-package}", "${yudao.info.member-package}"}, + annotationClass = Mapper.class, lazyInitialization = "${mybatis.lazy-initialization:false}") // Mapper 懒加载,目前仅用于单元测试 public class YudaoMybatisAutoConfiguration { diff --git a/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/config/YudaoSecurityAutoConfiguration.java b/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/config/YudaoSecurityAutoConfiguration.java index 684cfed9a..ae8b12422 100644 --- a/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/config/YudaoSecurityAutoConfiguration.java +++ b/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/config/YudaoSecurityAutoConfiguration.java @@ -7,6 +7,9 @@ import cn.iocoder.yudao.framework.security.core.handler.AccessDeniedHandlerImpl; import cn.iocoder.yudao.framework.security.core.handler.AuthenticationEntryPointImpl; import cn.iocoder.yudao.framework.security.core.handler.LogoutSuccessHandlerImpl; import cn.iocoder.yudao.framework.security.core.service.SecurityAuthFrameworkService; +import cn.iocoder.yudao.framework.security.core.service.SecurityAuthService; +import cn.iocoder.yudao.framework.security.core.service.SecurityAuthServiceImpl; +import cn.iocoder.yudao.framework.web.config.WebProperties; import cn.iocoder.yudao.framework.web.core.handler.GlobalExceptionHandler; import org.springframework.beans.factory.config.MethodInvokingFactoryBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; @@ -20,6 +23,7 @@ import org.springframework.security.web.access.AccessDeniedHandler; import org.springframework.security.web.authentication.logout.LogoutSuccessHandler; import javax.annotation.Resource; +import java.util.List; /** * Spring Security 自动配置类,主要用于相关组件的配置 @@ -29,7 +33,7 @@ import javax.annotation.Resource; * * @author 芋道源码 */ -@Configuration +@Configuration(proxyBeanMethods = false) @EnableConfigurationProperties(SecurityProperties.class) public class YudaoSecurityAutoConfiguration { @@ -64,8 +68,8 @@ public class YudaoSecurityAutoConfiguration { * 退出处理类 Bean */ @Bean - public LogoutSuccessHandler logoutSuccessHandler(SecurityAuthFrameworkService securityFrameworkService) { - return new LogoutSuccessHandlerImpl(securityProperties, securityFrameworkService); + public LogoutSuccessHandler logoutSuccessHandler(SecurityAuthService securityAuthService) { + return new LogoutSuccessHandlerImpl(securityProperties, securityAuthService); } /** @@ -83,9 +87,18 @@ public class YudaoSecurityAutoConfiguration { * Token 认证过滤器 Bean */ @Bean - public JWTAuthenticationTokenFilter authenticationTokenFilter(SecurityAuthFrameworkService securityFrameworkService, + public JWTAuthenticationTokenFilter authenticationTokenFilter(SecurityAuthService securityAuthService, GlobalExceptionHandler globalExceptionHandler) { - return new JWTAuthenticationTokenFilter(securityProperties, securityFrameworkService, globalExceptionHandler); + return new JWTAuthenticationTokenFilter(securityProperties, securityAuthService, globalExceptionHandler); + } + + /** + * 安全认证的 Service Bean + */ + @Bean + public SecurityAuthService securityAuthService(List securityFrameworkServices, + WebProperties webProperties) { + return new SecurityAuthServiceImpl(securityFrameworkServices, webProperties); } /** diff --git a/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/config/YudaoWebSecurityConfigurerAdapter.java b/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/config/YudaoWebSecurityConfigurerAdapter.java index a0f1c87cc..a00b2c2a6 100644 --- a/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/config/YudaoWebSecurityConfigurerAdapter.java +++ b/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/config/YudaoWebSecurityConfigurerAdapter.java @@ -65,13 +65,15 @@ public class YudaoWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdap */ @Resource private JWTAuthenticationTokenFilter authenticationTokenFilter; + /** * 自定义的权限映射 Bean * * @see #configure(HttpSecurity) */ @Resource - private Customizer.ExpressionInterceptUrlRegistry> authorizeRequestsCustomizer; + private Customizer.ExpressionInterceptUrlRegistry> + authorizeRequestsCustomizer; /** * 由于 Spring Security 创建 AuthenticationManager 对象时,没声明 @Bean 注解,导致无法被注入 @@ -89,8 +91,8 @@ public class YudaoWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdap */ @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { - auth.userDetailsService(userDetailsService) - .passwordEncoder(passwordEncoder); + auth + .userDetailsService(userDetailsService).passwordEncoder(passwordEncoder); } /** @@ -123,16 +125,16 @@ public class YudaoWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdap // 一堆自定义的 Spring Security 处理器 .exceptionHandling().authenticationEntryPoint(authenticationEntryPoint) .accessDeniedHandler(accessDeniedHandler).and() - .logout().logoutUrl(api("/logout")).logoutSuccessHandler(logoutSuccessHandler); // 登出 + .logout().logoutUrl(buildAdminApi("/logout")).logoutSuccessHandler(logoutSuccessHandler); // 登出 // 设置每个请求的权限 ①:全局共享规则 httpSecurity.authorizeRequests() // 登录的接口,可匿名访问 - .antMatchers(api("/login")).anonymous() + .antMatchers(buildAdminApi("/login")).anonymous() // 静态资源,可匿名访问 .antMatchers(HttpMethod.GET, "/*.html", "/**/*.html", "/**/*.css", "/**/*.js").permitAll() // 文件的获取接口,可匿名访问 - .antMatchers(api("/infra/file/get/**")).anonymous() + .antMatchers(buildAdminApi("/infra/file/get/**")).anonymous() // Swagger 接口文档 .antMatchers("/swagger-ui.html").anonymous() .antMatchers("/swagger-resources/**").anonymous() @@ -143,11 +145,11 @@ public class YudaoWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdap .antMatchers("/actuator/**").anonymous() // Druid 监控 TODO 芋艿:等对接了 druid admin 后,在调整下。 .antMatchers("/druid/**").anonymous() - // oAuth2 auth2/login/gitee - .antMatchers(api("/auth2/login/**")).anonymous() - .antMatchers(api("/auth2/authorization/**")).anonymous() + // oAuth2 auth2/login/gitee TODO 芋艿:貌似可以删除 + .antMatchers(buildAdminApi("/auth2/login/**")).anonymous() + .antMatchers(buildAdminApi("/auth2/authorization/**")).anonymous() .antMatchers("/api/callback/**").anonymous() - // 设置每个请求的权限 ②:每个项目的自定义规则 + // 设置每个请求的权限 ②:每个项目的自定义规则 TODO 芋艿:改造成多个,方便每个模块自定义规则 .and().authorizeRequests(authorizeRequestsCustomizer) // 设置每个请求的权限 ③:兜底规则,必须认证 .authorizeRequests().anyRequest().authenticated() @@ -156,8 +158,14 @@ public class YudaoWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdap httpSecurity.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class); } - private String api(String url) { - return webProperties.getApiPrefix() + url; + private String buildAdminApi(String url) { + // TODO 芋艿:多模块 + return webProperties.getAdminApi().getPrefix() + url; + } + + private String buildAppApi(String url) { + // TODO 芋艿:多模块 + return webProperties.getAppApi().getPrefix() + url; } } diff --git a/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/filter/JWTAuthenticationTokenFilter.java b/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/filter/JWTAuthenticationTokenFilter.java index c83318b0d..61685e902 100644 --- a/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/filter/JWTAuthenticationTokenFilter.java +++ b/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/filter/JWTAuthenticationTokenFilter.java @@ -2,17 +2,15 @@ package cn.iocoder.yudao.framework.security.core.filter; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils; import cn.iocoder.yudao.framework.security.config.SecurityProperties; import cn.iocoder.yudao.framework.security.core.LoginUser; -import cn.iocoder.yudao.framework.security.core.service.SecurityAuthFrameworkService; +import cn.iocoder.yudao.framework.security.core.service.SecurityAuthService; import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils; import cn.iocoder.yudao.framework.web.core.handler.GlobalExceptionHandler; -import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils; import lombok.AllArgsConstructor; -import org.springframework.stereotype.Component; import org.springframework.web.filter.OncePerRequestFilter; -import javax.annotation.Resource; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; @@ -30,7 +28,7 @@ public class JWTAuthenticationTokenFilter extends OncePerRequestFilter { private final SecurityProperties securityProperties; - private final SecurityAuthFrameworkService authService; + private final SecurityAuthService authService; private final GlobalExceptionHandler globalExceptionHandler; @@ -42,10 +40,10 @@ public class JWTAuthenticationTokenFilter extends OncePerRequestFilter { if (StrUtil.isNotEmpty(token)) { try { // 验证 token 有效性 - LoginUser loginUser = authService.verifyTokenAndRefresh(token); + LoginUser loginUser = authService.verifyTokenAndRefresh(request, token); // 模拟 Login 功能,方便日常开发调试 if (loginUser == null) { - loginUser = this.mockLoginUser(token); + loginUser = this.mockLoginUser(request, token); } // 设置当前用户 if (loginUser != null) { @@ -67,10 +65,11 @@ public class JWTAuthenticationTokenFilter extends OncePerRequestFilter { * * 注意,在线上环境下,一定要关闭该功能!!! * + * @param request 请求 * @param token 模拟的 token,格式为 {@link SecurityProperties#getTokenSecret()} + 用户编号 * @return 模拟的 LoginUser */ - private LoginUser mockLoginUser(String token) { + private LoginUser mockLoginUser(HttpServletRequest request, String token) { if (!securityProperties.getMockEnable()) { return null; } @@ -79,7 +78,7 @@ public class JWTAuthenticationTokenFilter extends OncePerRequestFilter { return null; } Long userId = Long.valueOf(token.substring(securityProperties.getMockSecret().length())); - return authService.mockLogin(userId); + return authService.mockLogin(request, userId); } } diff --git a/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/handler/LogoutSuccessHandlerImpl.java b/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/handler/LogoutSuccessHandlerImpl.java index 1bf8091be..e61b351c2 100644 --- a/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/handler/LogoutSuccessHandlerImpl.java +++ b/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/handler/LogoutSuccessHandlerImpl.java @@ -2,16 +2,14 @@ package cn.iocoder.yudao.framework.security.core.handler; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import cn.iocoder.yudao.framework.security.config.SecurityProperties; -import cn.iocoder.yudao.framework.security.core.service.SecurityAuthFrameworkService; -import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils; import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils; +import cn.iocoder.yudao.framework.security.config.SecurityProperties; +import cn.iocoder.yudao.framework.security.core.service.SecurityAuthService; +import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils; import lombok.AllArgsConstructor; import org.springframework.security.core.Authentication; import org.springframework.security.web.authentication.logout.LogoutSuccessHandler; -import org.springframework.stereotype.Component; -import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -26,14 +24,14 @@ public class LogoutSuccessHandlerImpl implements LogoutSuccessHandler { private final SecurityProperties securityProperties; - private final SecurityAuthFrameworkService securityFrameworkService; + private final SecurityAuthService authService; @Override public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) { // 执行退出 String token = SecurityFrameworkUtils.obtainAuthorization(request, securityProperties.getTokenHeader()); if (StrUtil.isNotBlank(token)) { - securityFrameworkService.logout(token); + authService.logout(request, token); } // 返回成功 ServletUtils.writeJSON(response, CommonResult.success(null)); diff --git a/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/service/SecurityAuthFrameworkService.java b/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/service/SecurityAuthFrameworkService.java index 28c8f6dc0..1f76e161f 100644 --- a/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/service/SecurityAuthFrameworkService.java +++ b/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/service/SecurityAuthFrameworkService.java @@ -1,10 +1,11 @@ package cn.iocoder.yudao.framework.security.core.service; +import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; import cn.iocoder.yudao.framework.security.core.LoginUser; import org.springframework.security.core.userdetails.UserDetailsService; /** - * Security 框架 Auth Service 接口,定义 security 组件需要的功能 + * Security 框架 Auth Service 接口,定义不同用户类型的 {@link UserTypeEnum} 需要实现的方法 * * @author 芋道源码 */ @@ -34,4 +35,11 @@ public interface SecurityAuthFrameworkService extends UserDetailsService { */ void logout(String token); + /** + * 获得用户类型。每个用户类型,对应一个 SecurityAuthFrameworkService 实现类。 + * + * @return 用户类型 + */ + UserTypeEnum getUserType(); + } diff --git a/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/service/SecurityAuthService.java b/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/service/SecurityAuthService.java new file mode 100644 index 000000000..4fee9cd0d --- /dev/null +++ b/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/service/SecurityAuthService.java @@ -0,0 +1,43 @@ +package cn.iocoder.yudao.framework.security.core.service; + +import cn.iocoder.yudao.framework.security.core.LoginUser; + +import javax.servlet.http.HttpServletRequest; + +/** + * 安全认证的 Service 接口,对 security 组件提供统一的 Auth 相关的方法。 + * 主要是会基于 {@link HttpServletRequest} 参数,匹配对应的 {@link SecurityAuthFrameworkService} 实现,然后调用其方法。 + * 因此,在方法的定义上,和 {@link SecurityAuthFrameworkService} 差不多。 + * + * @author 芋道源码 + */ +public interface SecurityAuthService { + + /** + * 校验 token 的有效性,并获取用户信息 + * 通过后,刷新 token 的过期时间 + * + * @param request 请求 + * @param token token + * @return 用户信息 + */ + LoginUser verifyTokenAndRefresh(HttpServletRequest request, String token); + + /** + * 模拟指定用户编号的 LoginUser + * + * @param request 请求 + * @param userId 用户编号 + * @return 登录用户 + */ + LoginUser mockLogin(HttpServletRequest request, Long userId); + + /** + * 基于 token 退出登录 + * + * @param request 请求 + * @param token token + */ + void logout(HttpServletRequest request, String token); + +} diff --git a/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/service/SecurityAuthServiceImpl.java b/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/service/SecurityAuthServiceImpl.java new file mode 100644 index 000000000..d9ab8eb0e --- /dev/null +++ b/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/service/SecurityAuthServiceImpl.java @@ -0,0 +1,64 @@ +package cn.iocoder.yudao.framework.security.core.service; + +import cn.hutool.core.lang.Assert; +import cn.hutool.core.util.StrUtil; +import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; +import cn.iocoder.yudao.framework.security.core.LoginUser; +import cn.iocoder.yudao.framework.web.config.WebProperties; + +import javax.servlet.http.HttpServletRequest; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 安全认证的 Service 实现类,基于请求地址,计算到对应的 {@link UserTypeEnum} 枚举,从而拿到对应的 {@link SecurityAuthFrameworkService} 实现 + * + * @author 芋道源码 + */ +public class SecurityAuthServiceImpl implements SecurityAuthService { + + private final Map services = new HashMap<>(); + private final WebProperties properties; + + public SecurityAuthServiceImpl(List serviceList, WebProperties properties) { + serviceList.forEach(service -> services.put(service.getUserType(), service)); + this.properties = properties; + } + + @Override + public LoginUser verifyTokenAndRefresh(HttpServletRequest request, String token) { + return selectService(request).verifyTokenAndRefresh(token); + } + + @Override + public LoginUser mockLogin(HttpServletRequest request, Long userId) { + return selectService(request).mockLogin(userId); + } + + @Override + public void logout(HttpServletRequest request, String token) { + selectService(request).logout(token); + } + + private SecurityAuthFrameworkService selectService(HttpServletRequest request) { + // 第一步,获得用户类型 + UserTypeEnum userType = getUserType(request); + // 第二步,获得 SecurityAuthFrameworkService + SecurityAuthFrameworkService service = services.get(userType); + Assert.notNull(service, "URI({}) 用户类型({}) 找不到 SecurityAuthFrameworkService 实现类", + request.getRequestURI(), userType); + return service; + } + + private UserTypeEnum getUserType(HttpServletRequest request) { + if (request.getRequestURI().startsWith(properties.getAdminApi().getPrefix())) { + return UserTypeEnum.ADMIN; + } + if (request.getRequestURI().startsWith(properties.getAppApi().getPrefix())) { + return UserTypeEnum.MEMBER; + } + throw new IllegalArgumentException(StrUtil.format("URI({}) 找不到匹配的用户类型", request.getRequestURI())); + } + +} diff --git a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/apilog/core/filter/ApiAccessLogFilter.java b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/apilog/core/filter/ApiAccessLogFilter.java index 57133c840..3295e34c1 100644 --- a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/apilog/core/filter/ApiAccessLogFilter.java +++ b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/apilog/core/filter/ApiAccessLogFilter.java @@ -2,6 +2,7 @@ package cn.iocoder.yudao.framework.apilog.core.filter; import cn.hutool.core.exceptions.ExceptionUtil; import cn.hutool.core.map.MapUtil; +import cn.hutool.core.util.StrUtil; import cn.hutool.extra.servlet.ServletUtil; import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants; import cn.iocoder.yudao.framework.common.pojo.CommonResult; @@ -25,6 +26,8 @@ import java.io.IOException; import java.util.Date; import java.util.Map; +import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.*; + /** * API 访问日志 Filter * @@ -42,7 +45,8 @@ public class ApiAccessLogFilter extends OncePerRequestFilter { @Override protected boolean shouldNotFilter(HttpServletRequest request) { // 只过滤 API 请求的地址 - return !request.getRequestURI().startsWith(webProperties.getApiPrefix()); + return !StrUtil.startWithAny(request.getRequestURI(), webProperties.getAppApi().getPrefix(), + webProperties.getAppApi().getPrefix()); } @Override @@ -73,7 +77,7 @@ public class ApiAccessLogFilter extends OncePerRequestFilter { this.buildApiAccessLogDTO(accessLog, request, beginTime, queryString, requestBody, ex); apiAccessLogFrameworkService.createApiAccessLogAsync(accessLog); } catch (Throwable th) { - log.error("[createApiAccessLog][url({}) log({}) 发生异常]", request.getRequestURI(), JsonUtils.toJsonString(accessLog), th); + log.error("[createApiAccessLog][url({}) log({}) 发生异常]", request.getRequestURI(), toJsonString(accessLog), th); } } @@ -99,7 +103,7 @@ public class ApiAccessLogFilter extends OncePerRequestFilter { accessLog.setApplicationName(applicationName); accessLog.setRequestUrl(request.getRequestURI()); Map requestParams = MapUtil.builder().put("query", queryString).put("body", requestBody).build(); - accessLog.setRequestParams(JsonUtils.toJsonString(requestParams)); + accessLog.setRequestParams(toJsonString(requestParams)); accessLog.setRequestMethod(request.getMethod()); accessLog.setUserAgent(ServletUtils.getUserAgent(request)); accessLog.setUserIp(ServletUtil.getClientIP(request)); diff --git a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/config/WebProperties.java b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/config/WebProperties.java index 2edc3e883..23a4aff4a 100644 --- a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/config/WebProperties.java +++ b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/config/WebProperties.java @@ -5,6 +5,8 @@ import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.validation.annotation.Validated; import org.springframework.web.servlet.config.annotation.PathMatchConfigurer; +import javax.validation.Valid; +import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; @ConfigurationProperties(prefix = "yudao.web") @@ -12,26 +14,37 @@ import javax.validation.constraints.NotNull; @Data public class WebProperties { - /** - * API 前缀,实现所有 Controller 提供的 RESTFul API 的统一前缀 - * - * - * 意义:通过该前缀,避免 Swagger、Actuator 意外通过 Nginx 暴露出来给外部,带来安全性问题 - * 这样,Nginx 只需要配置转发到 /api/* 的所有接口即可。 - * - * @see YudaoWebAutoConfiguration#configurePathMatch(PathMatchConfigurer) - */ - @NotNull(message = "API 前缀不能为空") - private String apiPrefix; + @NotNull(message = "APP API 不能为空") + private Api appApi; + @NotNull(message = "Admin API 不能为空") + private Api adminApi; - /** - * Controller 所在包 - * - * 主要目的是,给该 Controller 设置指定的 {@link #apiPrefix} - * - * 因为我们有多个 modules 包里会包含 Controller,所以只需要写到 cn.iocoder.yudao 这样的层级 - */ - @NotNull(message = "Controller 所在包不能为空") - private String controllerPackage; + @Data + @Valid + public static class Api { + + /** + * API 前缀,实现所有 Controller 提供的 RESTFul API 的统一前缀 + * + * + * 意义:通过该前缀,避免 Swagger、Actuator 意外通过 Nginx 暴露出来给外部,带来安全性问题 + * 这样,Nginx 只需要配置转发到 /api/* 的所有接口即可。 + * + * @see YudaoWebAutoConfiguration#configurePathMatch(PathMatchConfigurer) + */ + @NotEmpty(message = "API 前缀不能为空") + private String prefix; + + /** + * Controller 所在包 + * + * 主要目的是,给该 Controller 设置指定的 {@link #prefix} + * + * 因为我们有多个 modules 包里会包含 Controller,所以只需要写到 cn.iocoder.yudao 这样的层级 + */ + @NotEmpty(message = "Controller 所在包不能为空") + private String controller; + + } } diff --git a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/config/YudaoWebAutoConfiguration.java b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/config/YudaoWebAutoConfiguration.java index 5d390cdb1..c3bcb2009 100644 --- a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/config/YudaoWebAutoConfiguration.java +++ b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/config/YudaoWebAutoConfiguration.java @@ -38,10 +38,19 @@ public class YudaoWebAutoConfiguration implements WebMvcConfigurer { @Override public void configurePathMatch(PathMatchConfigurer configurer) { - // 设置 API 前缀,仅仅匹配 controller 包下的 - configurer.addPathPrefix(webProperties.getApiPrefix(), clazz -> - clazz.isAnnotationPresent(RestController.class) - && clazz.getPackage().getName().startsWith(webProperties.getControllerPackage())); // 仅仅匹配 controller 包 + configurePathMatch(configurer, webProperties.getAdminApi()); + configurePathMatch(configurer, webProperties.getAppApi()); + } + + /** + * 设置 API 前缀,仅仅匹配 controller 包下的 + * + * @param configurer 配置 + * @param api API 配置 + */ + private void configurePathMatch(PathMatchConfigurer configurer, WebProperties.Api api) { + configurer.addPathPrefix(api.getPrefix(), clazz -> clazz.isAnnotationPresent(RestController.class) + && clazz.getPackage().getName().startsWith(api.getController())); // 仅仅匹配 controller 包 } @Bean diff --git a/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/user/MemberUserApi.java b/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/user/UserApi.java similarity index 60% rename from yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/user/MemberUserApi.java rename to yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/user/UserApi.java index 3ac616af8..ba742a259 100644 --- a/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/user/MemberUserApi.java +++ b/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/user/UserApi.java @@ -1,13 +1,13 @@ package cn.iocoder.yudao.module.member.api.user; -import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; +import cn.iocoder.yudao.module.member.api.user.dto.UserRespDTO; /** * 会员用户的 API 接口 * * @author 芋道源码 */ -public interface MemberUserApi { +public interface UserApi { /** * 获得会员用户信息 @@ -15,6 +15,6 @@ public interface MemberUserApi { * @param id 用户编号 * @return 用户信息 */ - MemberUserRespDTO getMemberUser(Long id); + UserRespDTO getUser(Long id); } diff --git a/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/user/dto/MemberUserRespDTO.java b/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/user/dto/UserRespDTO.java similarity index 93% rename from yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/user/dto/MemberUserRespDTO.java rename to yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/user/dto/UserRespDTO.java index 82eec958a..ef2ecde49 100644 --- a/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/user/dto/MemberUserRespDTO.java +++ b/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/user/dto/UserRespDTO.java @@ -7,7 +7,7 @@ import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; * * @author 芋道源码 */ -public class MemberUserRespDTO { +public class UserRespDTO { /** * 用户ID diff --git a/yudao-module-member/yudao-module-member-impl/pom.xml b/yudao-module-member/yudao-module-member-impl/pom.xml index d4b064f6a..de4650806 100644 --- a/yudao-module-member/yudao-module-member-impl/pom.xml +++ b/yudao-module-member/yudao-module-member-impl/pom.xml @@ -18,16 +18,18 @@ + + cn.iocoder.boot + yudao-module-member-api + ${revision} + + cn.iocoder.boot yudao-core-service - - cn.iocoder.boot - yudao-spring-boot-starter-biz-dict - cn.iocoder.boot yudao-spring-boot-starter-biz-sms @@ -38,11 +40,6 @@ - - cn.iocoder.boot - yudao-spring-boot-starter-web - - cn.iocoder.boot yudao-spring-boot-starter-security @@ -59,32 +56,12 @@ yudao-spring-boot-starter-redis - - - cn.iocoder.boot - yudao-spring-boot-starter-config - - - - cn.iocoder.boot yudao-spring-boot-starter-mq - - - cn.iocoder.boot - yudao-spring-boot-starter-protection - - - - - cn.iocoder.boot - yudao-spring-boot-starter-monitor - - cn.iocoder.boot diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/api/package-info.java b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/api/package-info.java new file mode 100644 index 000000000..5f97979b8 --- /dev/null +++ b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/api/package-info.java @@ -0,0 +1 @@ +package cn.iocoder.yudao.module.member.api; diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/api/user/UserApiImpl.java b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/api/user/UserApiImpl.java new file mode 100644 index 000000000..656642e51 --- /dev/null +++ b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/api/user/UserApiImpl.java @@ -0,0 +1,30 @@ +package cn.iocoder.yudao.module.member.api.user; + +import cn.iocoder.yudao.module.member.api.user.dto.UserRespDTO; +import cn.iocoder.yudao.module.member.convert.user.UserConvert; +import cn.iocoder.yudao.module.member.dal.dataobject.user.UserDO; +import cn.iocoder.yudao.module.member.service.user.UserService; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import javax.annotation.Resource; + +/** + * 会员用户的 API 实现类 + * + * @author 芋道源码 + */ +@Service +@Validated +public class UserApiImpl implements UserApi { + + @Resource + private UserService userService; + + @Override + public UserRespDTO getUser(Long id) { + UserDO user = userService.getUser(id); + return UserConvert.INSTANCE.convert2(user); + } + +} diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/admin/address/package-info.java b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/admin/address/package-info.java new file mode 100644 index 000000000..652bbb6f1 --- /dev/null +++ b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/admin/address/package-info.java @@ -0,0 +1 @@ +package cn.iocoder.yudao.module.member.controller.admin.address; diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/admin/user/package-info.java b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/admin/user/package-info.java new file mode 100644 index 000000000..23b3c23c4 --- /dev/null +++ b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/admin/user/package-info.java @@ -0,0 +1 @@ +package cn.iocoder.yudao.module.member.controller.admin.user; diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/package-info.java b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/package-info.java new file mode 100644 index 000000000..c8c102186 --- /dev/null +++ b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/package-info.java @@ -0,0 +1 @@ +package cn.iocoder.yudao.module.member.controller.app.address; diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/AppAuthController.java b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/AppAuthController.java index 76437eb9d..3876e708b 100644 --- a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/AppAuthController.java +++ b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/AppAuthController.java @@ -5,8 +5,8 @@ import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated; import cn.iocoder.yudao.module.member.controller.app.auth.vo.*; -import cn.iocoder.yudao.userserver.modules.system.service.auth.SysAuthService; -import cn.iocoder.yudao.userserver.modules.system.service.sms.SysSmsCodeService; +import cn.iocoder.yudao.module.member.service.auth.AuthService; +import cn.iocoder.yudao.module.member.service.sms.SysSmsCodeService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiImplicitParams; @@ -31,7 +31,8 @@ import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUti public class AppAuthController { @Resource - private SysAuthService authService; + private AuthService authService; + @Resource private SysSmsCodeService smsCodeService; @Resource @@ -55,7 +56,7 @@ public class AppAuthController { @PostMapping("/send-sms-code") @ApiOperation(value = "发送手机验证码") - public CommonResult sendSmsCode(@RequestBody @Valid SysAuthSendSmsReqVO reqVO) { + public CommonResult sendSmsCode(@RequestBody @Valid AppAuthSendSmsReqVO reqVO) { smsCodeService.sendSmsCode(reqVO.getMobile(), reqVO.getScene(), getClientIP()); return success(true); } diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthCheckCodeReqVO.java b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthCheckCodeReqVO.java index 64cc22a3c..6d33b18ed 100644 --- a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthCheckCodeReqVO.java +++ b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthCheckCodeReqVO.java @@ -2,7 +2,7 @@ package cn.iocoder.yudao.module.member.controller.app.auth.vo; import cn.iocoder.yudao.framework.common.validation.InEnum; import cn.iocoder.yudao.framework.common.validation.Mobile; -import cn.iocoder.yudao.userserver.modules.system.enums.sms.SysSmsSceneEnum; +import cn.iocoder.yudao.module.member.enums.sms.SysSmsSceneEnum; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.AllArgsConstructor; @@ -15,6 +15,7 @@ import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; import javax.validation.constraints.Pattern; +// TODO 芋艿:code review 相关逻辑 @ApiModel("APP 端 - 校验验证码 Request VO") @Data @NoArgsConstructor @@ -37,4 +38,5 @@ public class AppAuthCheckCodeReqVO { @NotNull(message = "发送场景不能为空") @InEnum(SysSmsSceneEnum.class) private Integer scene; + } diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthResetPasswordReqVO.java b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthResetPasswordReqVO.java index 5ae291fdb..9f48ee624 100644 --- a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthResetPasswordReqVO.java +++ b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthResetPasswordReqVO.java @@ -13,6 +13,7 @@ import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.Pattern; +// TODO 芋艿:code review 相关逻辑 @ApiModel("APP 端 - 重置密码 Request VO") @Data @NoArgsConstructor diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppSendSmsReqVO.java b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthSendSmsReqVO.java similarity index 88% rename from yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppSendSmsReqVO.java rename to yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthSendSmsReqVO.java index 7a7620d63..9e53351fe 100644 --- a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppSendSmsReqVO.java +++ b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthSendSmsReqVO.java @@ -2,7 +2,7 @@ package cn.iocoder.yudao.module.member.controller.app.auth.vo; import cn.iocoder.yudao.framework.common.validation.InEnum; import cn.iocoder.yudao.framework.common.validation.Mobile; -import cn.iocoder.yudao.userserver.modules.system.enums.sms.SysSmsSceneEnum; +import cn.iocoder.yudao.module.member.enums.sms.SysSmsSceneEnum; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; @@ -13,7 +13,7 @@ import javax.validation.constraints.NotNull; @ApiModel("APP 端 - 发送手机验证码 Response VO") @Data @Accessors(chain = true) -public class AppSendSmsReqVO { +public class AppAuthSendSmsReqVO { @ApiModelProperty(value = "手机号", example = "15601691234") @Mobile diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthUpdatePasswordReqVO.java b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthUpdatePasswordReqVO.java index cbbd17fec..4bbecbc31 100644 --- a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthUpdatePasswordReqVO.java +++ b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthUpdatePasswordReqVO.java @@ -11,6 +11,7 @@ import org.hibernate.validator.constraints.Length; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotEmpty; +// TODO 芋艿:code review 相关逻辑 @ApiModel("APP 端 - 修改密码 Request VO") @Data @NoArgsConstructor diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/AppUserController.java b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/AppUserController.java index 758eb7b00..cf5b5348c 100644 --- a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/AppUserController.java +++ b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/AppUserController.java @@ -1,13 +1,12 @@ package cn.iocoder.yudao.module.member.controller.app.user; -import cn.iocoder.yudao.userserver.modules.member.controller.user.vo.MbrUserInfoRespVO; -import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated; -import cn.iocoder.yudao.userserver.modules.member.service.user.MbrUserService; -import cn.iocoder.yudao.userserver.modules.member.controller.user.vo.MbrUserUpdateMobileReqVO; -import cn.iocoder.yudao.userserver.modules.system.enums.sms.SysSmsSceneEnum; -import cn.iocoder.yudao.userserver.modules.system.service.sms.SysSmsCodeService; +import cn.iocoder.yudao.module.member.controller.app.user.vo.AppUserInfoRespVO; +import cn.iocoder.yudao.module.member.controller.app.user.vo.AppUserUpdateMobileReqVO; +import cn.iocoder.yudao.module.member.convert.user.UserConvert; +import cn.iocoder.yudao.module.member.dal.dataobject.user.UserDO; +import cn.iocoder.yudao.module.member.service.user.UserService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; @@ -17,13 +16,12 @@ import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; import javax.validation.Valid; - import java.io.IOException; +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.*; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP; import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; -import static cn.iocoder.yudao.userserver.modules.member.enums.MbrErrorCodeConstants.FILE_IS_EMPTY; +import static cn.iocoder.yudao.module.member.enums.MemberErrorCodeConstants.FILE_IS_EMPTY; @Api(tags = "APP 端 - 用户个人中心") @RestController @@ -33,39 +31,40 @@ import static cn.iocoder.yudao.userserver.modules.member.enums.MbrErrorCodeConst public class AppUserController { @Resource - private MbrUserService userService; + private UserService userService; @PutMapping("/update-nickname") @ApiOperation("修改用户昵称") @PreAuthenticated - public CommonResult updateNickname(@RequestParam("nickname") String nickname) { - userService.updateNickname(getLoginUserId(), nickname); + public CommonResult updateUserNickname(@RequestParam("nickname") String nickname) { + userService.updateUserNickname(getLoginUserId(), nickname); return success(true); } @PutMapping("/update-avatar") @ApiOperation("修改用户头像") @PreAuthenticated - public CommonResult updateAvatar(@RequestParam("avatarFile") MultipartFile file) throws IOException { + public CommonResult updateUserAvatar(@RequestParam("avatarFile") MultipartFile file) throws IOException { if (file.isEmpty()) { - throw ServiceExceptionUtil.exception(MbrErrorCodeConstants.FILE_IS_EMPTY); + throw exception(FILE_IS_EMPTY); } - String avatar = userService.updateAvatar(getLoginUserId(), file.getInputStream()); + String avatar = userService.updateUserAvatar(getLoginUserId(), file.getInputStream()); return success(avatar); } @GetMapping("/get") @ApiOperation("获得基本信息") @PreAuthenticated - public CommonResult getUserInfo() { - return success(userService.getUserInfo(getLoginUserId())); + public CommonResult getUserInfo() { + UserDO user = userService.getUser(getLoginUserId()); + return success(UserConvert.INSTANCE.convert(user)); } @PostMapping("/update-mobile") @ApiOperation(value = "修改用户手机") @PreAuthenticated - public CommonResult updateMobile(@RequestBody @Valid MbrUserUpdateMobileReqVO reqVO) { - userService.updateMobile(getLoginUserId(), reqVO); + public CommonResult updateMobile(@RequestBody @Valid AppUserUpdateMobileReqVO reqVO) { + userService.updateUserMobile(getLoginUserId(), reqVO); return success(true); } diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/vo/AppUserUpdateMobileReqVO.java b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/vo/AppUserUpdateMobileReqVO.java index fe91566c9..ded94ef1a 100644 --- a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/vo/AppUserUpdateMobileReqVO.java +++ b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/vo/AppUserUpdateMobileReqVO.java @@ -38,6 +38,8 @@ public class AppUserUpdateMobileReqVO { @Pattern(regexp = "^[0-9]+$", message = "手机验证码必须都是数字") private String oldCode; + // TODO @芋艿:oldMobile 应该不用传递 + @ApiModelProperty(value = "原手机号",required = true,example = "15823654487") @NotBlank(message = "手机号不能为空") @Length(min = 8, max = 11, message = "手机号码长度为 8-11 位") diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/convert/auth/SysAuthConvert.java b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/convert/auth/AuthConvert.java similarity index 63% rename from yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/convert/auth/SysAuthConvert.java rename to yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/convert/auth/AuthConvert.java index df9a353a0..419a70e0b 100644 --- a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/convert/auth/SysAuthConvert.java +++ b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/convert/auth/AuthConvert.java @@ -1,21 +1,21 @@ package cn.iocoder.yudao.module.member.convert.auth; -import cn.iocoder.yudao.coreservice.modules.member.dal.dataobject.user.MbrUserDO; import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; import cn.iocoder.yudao.framework.security.core.LoginUser; +import cn.iocoder.yudao.module.member.dal.dataobject.user.UserDO; import org.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.factory.Mappers; @Mapper -public interface SysAuthConvert { +public interface AuthConvert { - SysAuthConvert INSTANCE = Mappers.getMapper(SysAuthConvert.class); + AuthConvert INSTANCE = Mappers.getMapper(AuthConvert.class); @Mapping(source = "mobile", target = "username") - LoginUser convert0(MbrUserDO bean); + LoginUser convert0(UserDO bean); - default LoginUser convert(MbrUserDO bean) { + default LoginUser convert(UserDO bean) { // 目的,为了设置 UserTypeEnum.MEMBER.getValue() return convert0(bean).setUserType(UserTypeEnum.MEMBER.getValue()); } diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/convert/user/UserConvert.java b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/convert/user/UserConvert.java index 139b6ef33..a490edfaf 100644 --- a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/convert/user/UserConvert.java +++ b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/convert/user/UserConvert.java @@ -1,6 +1,8 @@ package cn.iocoder.yudao.module.member.convert.user; -import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO; +import cn.iocoder.yudao.module.member.api.user.dto.UserRespDTO; +import cn.iocoder.yudao.module.member.controller.app.user.vo.AppUserInfoRespVO; +import cn.iocoder.yudao.module.member.dal.dataobject.user.UserDO; import org.mapstruct.Mapper; import org.mapstruct.factory.Mappers; @@ -9,6 +11,7 @@ public interface UserConvert { UserConvert INSTANCE = Mappers.getMapper(UserConvert.class); - AppUserInfoRespVO convert(MemberUserDO bean); + AppUserInfoRespVO convert(UserDO bean); + UserRespDTO convert2(UserDO bean); } diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/user/MemberUserDO.java b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/user/UserDO.java similarity index 90% rename from yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/user/MemberUserDO.java rename to yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/user/UserDO.java index 0b77f4e1e..f45168044 100644 --- a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/user/MemberUserDO.java +++ b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/user/UserDO.java @@ -10,19 +10,19 @@ import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import java.util.Date; /** - * 会员中心的用户 DO + * 会员用户 DO * * uk_mobile 索引:基于 {@link #mobile} 字段 * * @author 芋道源码 */ -@TableName(value = "member_user", autoResultMap = true) +@TableName(value = "mbr_user", autoResultMap = true) @Data @EqualsAndHashCode(callSuper = true) @Builder @NoArgsConstructor @AllArgsConstructor -public class MemberUserDO extends TenantBaseDO { +public class UserDO extends TenantBaseDO { /** * 用户ID diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/sms/SysSmsCodeMapper.java b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/sms/SysSmsCodeMapper.java index 80079117f..ccdbcf6ce 100644 --- a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/sms/SysSmsCodeMapper.java +++ b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/sms/SysSmsCodeMapper.java @@ -3,10 +3,9 @@ package cn.iocoder.yudao.module.member.dal.mysql.sms; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX; import cn.iocoder.yudao.module.member.dal.dataobject.sms.SysSmsCodeDO; -import cn.iocoder.yudao.userserver.modules.system.dal.dataobject.sms.SysSmsCodeDO; import org.apache.ibatis.annotations.Mapper; -// TODO @芋艿: +// TODO @芋艿:拿到 system 模块下 @Mapper public interface SysSmsCodeMapper extends BaseMapperX { diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/user/MbrUserMapper.java b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/user/MbrUserMapper.java deleted file mode 100644 index 49b6a9f8e..000000000 --- a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/user/MbrUserMapper.java +++ /dev/null @@ -1,19 +0,0 @@ -package cn.iocoder.yudao.module.member.dal.mysql.user; - -import cn.iocoder.yudao.coreservice.modules.member.dal.dataobject.user.MbrUserDO; -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; -import org.apache.ibatis.annotations.Mapper; - -/** - * MbrUserDO Mapper - * - * @author 芋道源码 - */ -@Mapper -public interface MbrUserMapper extends BaseMapperX { - - default MbrUserDO selectByMobile(String mobile) { - return selectOne(MbrUserDO::getMobile, mobile); - } - -} diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/user/UserMapper.java b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/user/UserMapper.java new file mode 100644 index 000000000..d962811e6 --- /dev/null +++ b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/user/UserMapper.java @@ -0,0 +1,19 @@ +package cn.iocoder.yudao.module.member.dal.mysql.user; + +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.module.member.dal.dataobject.user.UserDO; +import org.apache.ibatis.annotations.Mapper; + +/** + * 会员 User Mapper + * + * @author 芋道源码 + */ +@Mapper +public interface UserMapper extends BaseMapperX { + + default UserDO selectByMobile(String mobile) { + return selectOne(UserDO::getMobile, mobile); + } + +} diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/dal/package-info.java b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/dal/package-info.java index 06c6545ca..5b05c46f1 100644 --- a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/dal/package-info.java +++ b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/dal/package-info.java @@ -3,5 +3,7 @@ * 1. data object:数据对象 * 2. redis:Redis 的 CRUD 操作 * 3. mysql:MySQL 的 CRUD 操作 + * + * 其中,MySQL 的表以 mbr_ 作为前缀 */ package cn.iocoder.yudao.module.member.dal; diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/dal/redis/package-info.java b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/dal/redis/package-info.java index f5d6e64d2..8dfa9fb20 100644 --- a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/dal/redis/package-info.java +++ b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/dal/redis/package-info.java @@ -1 +1,4 @@ +/** + * 占位,后续有类后,可以删除,避免 package 无法提交到 Git 上 + */ package cn.iocoder.yudao.module.member.dal.redis; diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/framework/security/SecurityConfiguration.java b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/framework/security/SecurityConfiguration.java deleted file mode 100644 index 32368f8d1..000000000 --- a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/framework/security/SecurityConfiguration.java +++ /dev/null @@ -1,29 +0,0 @@ -package cn.iocoder.yudao.module.member.framework.security; - -import cn.iocoder.yudao.framework.web.config.WebProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.security.config.Customizer; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer; - -import javax.annotation.Resource; - -@Configuration -public class SecurityConfiguration { - - @Resource - private WebProperties webProperties; - - @Bean - public Customizer.ExpressionInterceptUrlRegistry> authorizeRequestsCustomizer() { - return registry -> { - registry.antMatchers(api("/**")).permitAll(); // 默认 API 都是用户可访问 - }; - } - - private String api(String url) { - return webProperties.getApiPrefix() + url; - } - -} diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/auth/SysAuthService.java b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/auth/AuthService.java similarity index 74% rename from yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/auth/SysAuthService.java rename to yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/auth/AuthService.java index a864e1ed9..98b87c505 100644 --- a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/auth/SysAuthService.java +++ b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/auth/AuthService.java @@ -6,13 +6,13 @@ import cn.iocoder.yudao.module.member.controller.app.auth.vo.*; import javax.validation.Valid; /** - * 用户前台的认证 Service 接口 + * 会员的认证 Service 接口 * * 提供用户的账号密码登录、token 的校验等认证相关的功能 * * @author 芋道源码 */ -public interface SysAuthService extends SecurityAuthFrameworkService { +public interface AuthService extends SecurityAuthFrameworkService { /** * 手机 + 密码登录 @@ -22,7 +22,7 @@ public interface SysAuthService extends SecurityAuthFrameworkService { * @param userAgent 用户 UA * @return 身份令牌,使用 JWT 方式 */ - String login(@Valid SysAuthLoginReqVO reqVO, String userIp, String userAgent); + String login(@Valid AppAuthLoginReqVO reqVO, String userIp, String userAgent); /** * 手机 + 验证码登陆 @@ -32,7 +32,7 @@ public interface SysAuthService extends SecurityAuthFrameworkService { * @param userAgent 用户 UA * @return 身份令牌,使用 JWT 方式 */ - String smsLogin(@Valid SysAuthSmsLoginReqVO reqVO, String userIp, String userAgent); + String smsLogin(@Valid AppAuthSmsLoginReqVO reqVO, String userIp, String userAgent); /** @@ -43,7 +43,7 @@ public interface SysAuthService extends SecurityAuthFrameworkService { * @param userAgent 用户 UA * @return 身份令牌,使用 JWT 方式 */ - String socialLogin(@Valid MbrAuthSocialLoginReqVO reqVO, String userIp, String userAgent); + String socialLogin(@Valid AppAuthSocialLoginReqVO reqVO, String userIp, String userAgent); /** * 社交登录,使用 手机号 + 手机验证码 @@ -53,7 +53,7 @@ public interface SysAuthService extends SecurityAuthFrameworkService { * @param userAgent 用户 UA * @return 身份令牌,使用 JWT 方式 */ - String socialLogin2(@Valid MbrAuthSocialLogin2ReqVO reqVO, String userIp, String userAgent); + String socialLogin2(@Valid AppAuthSocialLogin2ReqVO reqVO, String userIp, String userAgent); /** * 社交绑定,使用 code 授权码 @@ -61,18 +61,19 @@ public interface SysAuthService extends SecurityAuthFrameworkService { * @param userId 用户编号 * @param reqVO 绑定信息 */ - void socialBind(Long userId, @Valid MbrAuthSocialBindReqVO reqVO); + void socialBind(Long userId, @Valid AppAuthSocialBindReqVO reqVO); /** * 修改用户密码 * @param userId 用户id * @param userReqVO 用户请求实体类 */ - void updatePassword(Long userId,MbrAuthUpdatePasswordReqVO userReqVO); + void updatePassword(Long userId, AppAuthUpdatePasswordReqVO userReqVO); /** * 忘记密码 * @param userReqVO 用户请求实体类 */ - void resetPassword(MbrAuthResetPasswordReqVO userReqVO); + void resetPassword(AppAuthResetPasswordReqVO userReqVO); + } diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/auth/SysAuthServiceImpl.java b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/auth/AuthServiceImpl.java similarity index 72% rename from yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/auth/SysAuthServiceImpl.java rename to yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/auth/AuthServiceImpl.java index fd68cff5e..a28b6572d 100644 --- a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/auth/SysAuthServiceImpl.java +++ b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/auth/AuthServiceImpl.java @@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.member.service.auth; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.lang.Assert; -import cn.iocoder.yudao.coreservice.modules.member.dal.dataobject.user.MbrUserDO; import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.social.SysSocialUserDO; import cn.iocoder.yudao.coreservice.modules.system.enums.logger.SysLoginLogTypeEnum; import cn.iocoder.yudao.coreservice.modules.system.enums.logger.SysLoginResultEnum; @@ -12,22 +11,20 @@ import cn.iocoder.yudao.coreservice.modules.system.service.logger.dto.SysLoginLo import cn.iocoder.yudao.coreservice.modules.system.service.social.SysSocialCoreService; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; -import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil; import cn.iocoder.yudao.framework.common.util.monitor.TracerUtils; import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils; import cn.iocoder.yudao.framework.security.core.LoginUser; -import cn.iocoder.yudao.userserver.modules.member.dal.mysql.user.MbrUserMapper; -import cn.iocoder.yudao.userserver.modules.member.service.user.MbrUserService; import cn.iocoder.yudao.module.member.controller.app.auth.vo.*; -import cn.iocoder.yudao.userserver.modules.system.convert.auth.SysAuthConvert; -import cn.iocoder.yudao.userserver.modules.system.enums.sms.SysSmsSceneEnum; -import cn.iocoder.yudao.userserver.modules.system.service.auth.SysAuthService; -import cn.iocoder.yudao.userserver.modules.system.service.sms.SysSmsCodeService; +import cn.iocoder.yudao.module.member.convert.auth.AuthConvert; +import cn.iocoder.yudao.module.member.dal.dataobject.user.UserDO; +import cn.iocoder.yudao.module.member.dal.mysql.user.UserMapper; +import cn.iocoder.yudao.module.member.enums.sms.SysSmsSceneEnum; +import cn.iocoder.yudao.module.member.service.sms.SysSmsCodeService; +import cn.iocoder.yudao.module.member.service.user.UserService; import com.google.common.annotations.VisibleForTesting; import lombok.extern.slf4j.Slf4j; import me.zhyd.oauth.model.AuthUser; import org.springframework.context.annotation.Lazy; -import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.authentication.DisabledException; @@ -46,25 +43,23 @@ import java.util.Objects; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP; -import static cn.iocoder.yudao.userserver.modules.system.enums.SysErrorCodeConstants.*; +import static cn.iocoder.yudao.module.member.enums.SysErrorCodeConstants.*; /** - * Auth Service 实现类 + * 会员的认证 Service 接口 * * @author 芋道源码 */ @Service @Slf4j -public class SysAuthServiceImpl implements SysAuthService { - - private static final UserTypeEnum USER_TYPE_ENUM = UserTypeEnum.MEMBER; +public class AuthServiceImpl implements AuthService { @Resource @Lazy // 延迟加载,因为存在相互依赖的问题 private AuthenticationManager authenticationManager; @Resource - private MbrUserService userService; + private UserService userService; @Resource private SysSmsCodeService smsCodeService; @Resource @@ -74,28 +69,24 @@ public class SysAuthServiceImpl implements SysAuthService { @Resource private SysSocialCoreService socialService; - @Resource - private StringRedisTemplate stringRedisTemplate; @Resource private PasswordEncoder passwordEncoder; @Resource - private MbrUserMapper userMapper; - - private static final UserTypeEnum userTypeEnum = UserTypeEnum.MEMBER; + private UserMapper userMapper; @Override public UserDetails loadUserByUsername(String mobile) throws UsernameNotFoundException { // 获取 username 对应的 SysUserDO - MbrUserDO user = userService.getUserByMobile(mobile); + UserDO user = userService.getUserByMobile(mobile); if (user == null) { throw new UsernameNotFoundException(mobile); } // 创建 LoginUser 对象 - return SysAuthConvert.INSTANCE.convert(user); + return AuthConvert.INSTANCE.convert(user); } @Override - public String login(SysAuthLoginReqVO reqVO, String userIp, String userAgent) { + public String login(AppAuthLoginReqVO reqVO, String userIp, String userAgent) { // 使用手机 + 密码,进行登录。 LoginUser loginUser = this.login0(reqVO.getMobile(), reqVO.getPassword()); @@ -105,80 +96,77 @@ public class SysAuthServiceImpl implements SysAuthService { @Override @Transactional - public String smsLogin(SysAuthSmsLoginReqVO reqVO, String userIp, String userAgent) { + public String smsLogin(AppAuthSmsLoginReqVO reqVO, String userIp, String userAgent) { // 校验验证码 smsCodeService.useSmsCode(reqVO.getMobile(), SysSmsSceneEnum.LOGIN_BY_SMS.getScene(), reqVO.getCode(), userIp); // 获得获得注册用户 - MbrUserDO user = userService.createUserIfAbsent(reqVO.getMobile(), userIp); + UserDO user = userService.createUserIfAbsent(reqVO.getMobile(), userIp); Assert.notNull(user, "获取用户失败,结果为空"); // 执行登陆 this.createLoginLog(user.getMobile(), SysLoginLogTypeEnum.LOGIN_SMS, SysLoginResultEnum.SUCCESS); - LoginUser loginUser = SysAuthConvert.INSTANCE.convert(user); + LoginUser loginUser = AuthConvert.INSTANCE.convert(user); // 缓存登录用户到 Redis 中,返回 sessionId 编号 return userSessionCoreService.createUserSession(loginUser, userIp, userAgent); } @Override - public String socialLogin(MbrAuthSocialLoginReqVO reqVO, String userIp, String userAgent) { + public String socialLogin(AppAuthSocialLoginReqVO reqVO, String userIp, String userAgent) { // 使用 code 授权码,进行登录 AuthUser authUser = socialService.getAuthUser(reqVO.getType(), reqVO.getCode(), reqVO.getState()); org.springframework.util.Assert.notNull(authUser, "授权用户不为空"); // 如果未绑定 SysSocialUserDO 用户,则无法自动登录,进行报错 String unionId = socialService.getAuthUserUnionId(authUser); - List socialUsers = socialService.getAllSocialUserList(reqVO.getType(), unionId, USER_TYPE_ENUM); + List socialUsers = socialService.getAllSocialUserList(reqVO.getType(), unionId, getUserType()); if (CollUtil.isEmpty(socialUsers)) { - throw ServiceExceptionUtil.exception(SysErrorCodeConstants.AUTH_THIRD_LOGIN_NOT_BIND); + throw exception(AUTH_THIRD_LOGIN_NOT_BIND); } // 自动登录 - MbrUserDO user = userService.getUser(socialUsers.get(0).getUserId()); + UserDO user = userService.getUser(socialUsers.get(0).getUserId()); if (user == null) { - throw ServiceExceptionUtil.exception(SysErrorCodeConstants.USER_NOT_EXISTS); + throw exception(USER_NOT_EXISTS); } this.createLoginLog(user.getMobile(), SysLoginLogTypeEnum.LOGIN_SOCIAL, SysLoginResultEnum.SUCCESS); // 创建 LoginUser 对象 - LoginUser loginUser = SysAuthConvert.INSTANCE.convert(user); + LoginUser loginUser = AuthConvert.INSTANCE.convert(user); // 绑定社交用户(更新) - socialService.bindSocialUser(loginUser.getId(), reqVO.getType(), authUser, USER_TYPE_ENUM); + socialService.bindSocialUser(loginUser.getId(), reqVO.getType(), authUser, getUserType()); // 缓存登录用户到 Redis 中,返回 sessionId 编号 return userSessionCoreService.createUserSession(loginUser, userIp, userAgent); } @Override - public String socialLogin2(MbrAuthSocialLogin2ReqVO reqVO, String userIp, String userAgent) { + public String socialLogin2(AppAuthSocialLogin2ReqVO reqVO, String userIp, String userAgent) { AuthUser authUser = socialService.getAuthUser(reqVO.getType(), reqVO.getCode(), reqVO.getState()); org.springframework.util.Assert.notNull(authUser, "授权用户不为空"); // 使用手机号、手机验证码登录 - SysAuthSmsLoginReqVO loginReqVO = SysAuthSmsLoginReqVO - .builder() - .mobile(reqVO.getMobile()) - .code(reqVO.getSmsCode()) - .build(); + AppAuthSmsLoginReqVO loginReqVO = AppAuthSmsLoginReqVO.builder() + .mobile(reqVO.getMobile()).code(reqVO.getSmsCode()).build(); String sessionId = this.smsLogin(loginReqVO, userIp, userAgent); LoginUser loginUser = userSessionCoreService.getLoginUser(sessionId); // 绑定社交用户(新增) - socialService.bindSocialUser(loginUser.getId(), reqVO.getType(), authUser, USER_TYPE_ENUM); + socialService.bindSocialUser(loginUser.getId(), reqVO.getType(), authUser, getUserType()); return sessionId; } @Override - public void socialBind(Long userId, MbrAuthSocialBindReqVO reqVO) { + public void socialBind(Long userId, AppAuthSocialBindReqVO reqVO) { // 使用 code 授权码,进行登录 AuthUser authUser = socialService.getAuthUser(reqVO.getType(), reqVO.getCode(), reqVO.getState()); org.springframework.util.Assert.notNull(authUser, "授权用户不为空"); // 绑定社交用户(新增) - socialService.bindSocialUser(userId, reqVO.getType(), authUser, USER_TYPE_ENUM); + socialService.bindSocialUser(userId, reqVO.getType(), authUser, getUserType()); } private LoginUser login0(String username, String password) { @@ -191,14 +179,14 @@ public class SysAuthServiceImpl implements SysAuthService { authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password)); } catch (BadCredentialsException badCredentialsException) { this.createLoginLog(username, logTypeEnum, SysLoginResultEnum.BAD_CREDENTIALS); - throw ServiceExceptionUtil.exception(SysErrorCodeConstants.AUTH_LOGIN_BAD_CREDENTIALS); + throw exception(AUTH_LOGIN_BAD_CREDENTIALS); } catch (DisabledException disabledException) { this.createLoginLog(username, logTypeEnum, SysLoginResultEnum.USER_DISABLED); - throw ServiceExceptionUtil.exception(SysErrorCodeConstants.AUTH_LOGIN_USER_DISABLED); + throw exception(AUTH_LOGIN_USER_DISABLED); } catch (AuthenticationException authenticationException) { log.error("[login0][username({}) 发生未知异常]", username, authenticationException); this.createLoginLog(username, logTypeEnum, SysLoginResultEnum.UNKNOWN_ERROR); - throw ServiceExceptionUtil.exception(SysErrorCodeConstants.AUTH_LOGIN_FAIL_UNKNOWN); + throw exception(AUTH_LOGIN_FAIL_UNKNOWN); } // 登录成功的日志 Assert.notNull(authentication.getPrincipal(), "Principal 不会为空"); @@ -208,7 +196,7 @@ public class SysAuthServiceImpl implements SysAuthService { private void createLoginLog(String mobile, SysLoginLogTypeEnum logTypeEnum, SysLoginResultEnum loginResult) { // 获得用户 - MbrUserDO user = userService.getUserByMobile(mobile); + UserDO user = userService.getUserByMobile(mobile); // 插入登录日志 SysLoginLogCreateReqDTO reqDTO = new SysLoginLogCreateReqDTO(); reqDTO.setLogType(logTypeEnum.getType()); @@ -246,10 +234,11 @@ public class SysAuthServiceImpl implements SysAuthService { return; } - // 重新加载 MbrUserDO 信息 - MbrUserDO user = userService.getUser(loginUser.getId()); + // 重新加载 UserDO 信息 + UserDO user = userService.getUser(loginUser.getId()); if (user == null || CommonStatusEnum.DISABLE.getStatus().equals(user.getStatus())) { - throw ServiceExceptionUtil.exception(SysErrorCodeConstants.AUTH_TOKEN_EXPIRED); // 校验 token 时,用户被禁用的情况下,也认为 token 过期,方便前端跳转到登录界面 + // 校验 token 时,用户被禁用的情况下,也认为 token 过期,方便前端跳转到登录界面 + throw exception(AUTH_TOKEN_EXPIRED); } // 刷新 LoginUser 缓存 @@ -258,8 +247,8 @@ public class SysAuthServiceImpl implements SysAuthService { @Override public LoginUser mockLogin(Long userId) { - // 获取用户编号对应的 MbrUserDO - MbrUserDO user = userService.getUser(userId); + // 获取用户编号对应的 UserDO + UserDO user = userService.getUser(userId); if (user == null) { throw new UsernameNotFoundException(String.valueOf(userId)); } @@ -268,7 +257,7 @@ public class SysAuthServiceImpl implements SysAuthService { this.createLoginLog(user.getMobile(), SysLoginLogTypeEnum.LOGIN_MOCK, SysLoginResultEnum.SUCCESS); // 创建 LoginUser 对象 - return SysAuthConvert.INSTANCE.convert(user); + return AuthConvert.INSTANCE.convert(user); } @Override @@ -285,27 +274,32 @@ public class SysAuthServiceImpl implements SysAuthService { } @Override - public void updatePassword(Long userId,MbrAuthUpdatePasswordReqVO reqVO) { + public UserTypeEnum getUserType() { + return UserTypeEnum.MEMBER; + } + + @Override + public void updatePassword(Long userId, AppAuthUpdatePasswordReqVO reqVO) { // 检验旧密码 - MbrUserDO userDO = checkOldPassword(userId, reqVO.getOldPassword()); + UserDO userDO = checkOldPassword(userId, reqVO.getOldPassword()); // 更新用户密码 - MbrUserDO mbrUserDO = MbrUserDO.builder().build(); - mbrUserDO.setId(userDO.getId()); - mbrUserDO.setPassword(passwordEncoder.encode(reqVO.getPassword())); + UserDO mbrUserDO = UserDO.builder().id(userDO.getId()) + .password(passwordEncoder.encode(reqVO.getPassword())).build(); userMapper.updateById(mbrUserDO); } @Override - public void resetPassword(MbrAuthResetPasswordReqVO reqVO) { + public void resetPassword(AppAuthResetPasswordReqVO reqVO) { // 检验用户是否存在 - MbrUserDO userDO = checkUserIfExists(reqVO.getMobile()); + UserDO userDO = checkUserIfExists(reqVO.getMobile()); // 使用验证码 - smsCodeService.useSmsCode(reqVO.getMobile(),SysSmsSceneEnum.FORGET_MOBILE_BY_SMS.getScene(),reqVO.getCode(),getClientIP()); + smsCodeService.useSmsCode(reqVO.getMobile(),SysSmsSceneEnum.FORGET_MOBILE_BY_SMS.getScene(), reqVO.getCode(), + getClientIP()); // 更新密码 - MbrUserDO mbrUserDO = MbrUserDO.builder().build(); + UserDO mbrUserDO = UserDO.builder().build(); mbrUserDO.setId(userDO.getId()); mbrUserDO.setPassword(passwordEncoder.encode(reqVO.getPassword())); userMapper.updateById(mbrUserDO); @@ -316,36 +310,35 @@ public class SysAuthServiceImpl implements SysAuthService { * * @param id 用户 id * @param oldPassword 旧密码 - * @return MbrUserDO 用户实体 + * @return MemberUserDO 用户实体 */ @VisibleForTesting - public MbrUserDO checkOldPassword(Long id, String oldPassword) { - MbrUserDO user = userMapper.selectById(id); + public UserDO checkOldPassword(Long id, String oldPassword) { + UserDO user = userMapper.selectById(id); if (user == null) { - throw ServiceExceptionUtil.exception(SysErrorCodeConstants.USER_NOT_EXISTS); + throw exception(USER_NOT_EXISTS); } // 参数:未加密密码,编码后的密码 if (!passwordEncoder.matches(oldPassword,user.getPassword())) { - throw ServiceExceptionUtil.exception(SysErrorCodeConstants.USER_PASSWORD_FAILED); + throw exception(USER_PASSWORD_FAILED); } return user; } - public MbrUserDO checkUserIfExists(String mobile) { - MbrUserDO user = userMapper.selectByMobile(mobile); + public UserDO checkUserIfExists(String mobile) { + UserDO user = userMapper.selectByMobile(mobile); if (user == null) { - throw ServiceExceptionUtil.exception(SysErrorCodeConstants.USER_NOT_EXISTS); + throw exception(USER_NOT_EXISTS); } return user; } - private void createLogoutLog(Long userId, String username) { SysLoginLogCreateReqDTO reqDTO = new SysLoginLogCreateReqDTO(); reqDTO.setLogType(SysLoginLogTypeEnum.LOGOUT_SELF.getType()); reqDTO.setTraceId(TracerUtils.getTraceId()); reqDTO.setUserId(userId); - reqDTO.setUserType(USER_TYPE_ENUM.getValue()); + reqDTO.setUserType(getUserType().getValue()); reqDTO.setUsername(username); reqDTO.setUserAgent(ServletUtils.getUserAgent()); reqDTO.setUserIp(getClientIP()); diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/package-info.java b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/package-info.java deleted file mode 100644 index 6223e6e6c..000000000 --- a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/package-info.java +++ /dev/null @@ -1 +0,0 @@ -package cn.iocoder.yudao.module.member.service; diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/sms/SysSmsCodeService.java b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/sms/SysSmsCodeService.java index 8f0eaf6f3..e06e9a246 100644 --- a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/sms/SysSmsCodeService.java +++ b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/sms/SysSmsCodeService.java @@ -2,8 +2,8 @@ package cn.iocoder.yudao.module.member.service.sms; import cn.iocoder.yudao.framework.common.exception.ServiceException; import cn.iocoder.yudao.framework.common.validation.Mobile; -import cn.iocoder.yudao.userserver.modules.system.dal.dataobject.sms.SysSmsCodeDO; -import cn.iocoder.yudao.userserver.modules.system.enums.sms.SysSmsSceneEnum; +import cn.iocoder.yudao.module.member.dal.dataobject.sms.SysSmsCodeDO; +import cn.iocoder.yudao.module.member.enums.sms.SysSmsSceneEnum; /** * 短信验证码 Service 接口 @@ -40,7 +40,6 @@ public interface SysSmsCodeService { */ void sendSmsCodeLogin(Long userId); - /** * 检查验证码是否有效 * @param mobile 手机 diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/sms/SysSmsCodeServiceImpl.java b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/sms/SysSmsCodeServiceImpl.java index 43b7a1753..41049656d 100644 --- a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/sms/SysSmsCodeServiceImpl.java +++ b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/sms/SysSmsCodeServiceImpl.java @@ -1,15 +1,14 @@ package cn.iocoder.yudao.module.member.service.sms; import cn.hutool.core.map.MapUtil; -import cn.iocoder.yudao.coreservice.modules.member.dal.dataobject.user.MbrUserDO; import cn.iocoder.yudao.coreservice.modules.system.service.sms.SysSmsCoreService; import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil; -import cn.iocoder.yudao.userserver.modules.member.service.user.MbrUserService; -import cn.iocoder.yudao.userserver.modules.system.dal.dataobject.sms.SysSmsCodeDO; -import cn.iocoder.yudao.userserver.modules.system.dal.mysql.sms.SysSmsCodeMapper; -import cn.iocoder.yudao.userserver.modules.system.enums.sms.SysSmsSceneEnum; -import cn.iocoder.yudao.userserver.modules.system.framework.sms.SmsCodeProperties; -import cn.iocoder.yudao.userserver.modules.system.service.sms.SysSmsCodeService; +import cn.iocoder.yudao.module.member.dal.dataobject.sms.SysSmsCodeDO; +import cn.iocoder.yudao.module.member.dal.dataobject.user.UserDO; +import cn.iocoder.yudao.module.member.dal.mysql.sms.SysSmsCodeMapper; +import cn.iocoder.yudao.module.member.enums.sms.SysSmsSceneEnum; +import cn.iocoder.yudao.module.member.framework.sms.SmsCodeProperties; +import cn.iocoder.yudao.module.member.service.user.UserService; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; @@ -17,9 +16,8 @@ import javax.annotation.Resource; import java.util.Date; import static cn.hutool.core.util.RandomUtil.randomInt; -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP; -import static cn.iocoder.yudao.userserver.modules.system.enums.SysErrorCodeConstants.*; +import static cn.iocoder.yudao.module.member.enums.SysErrorCodeConstants.*; /** * 短信验证码 Service 实现类 @@ -37,7 +35,7 @@ public class SysSmsCodeServiceImpl implements SysSmsCodeService { private SysSmsCodeMapper smsCodeMapper; @Resource - private MbrUserService mbrUserService; + private UserService userService; @Resource private SysSmsCoreService smsCoreService; @@ -62,9 +60,9 @@ public class SysSmsCodeServiceImpl implements SysSmsCodeService { public void checkMobileIsRegister(String mobile, Integer scene) { // 检测手机号是否已被使用 - MbrUserDO userByMobile = mbrUserService.getUserByMobile(mobile); - if (userByMobile != null){ - throw ServiceExceptionUtil.exception(SysErrorCodeConstants.USER_SMS_CODE_IS_EXISTS); + UserDO user = userService.getUserByMobile(mobile); + if (user != null) { + throw ServiceExceptionUtil.exception(USER_SMS_CODE_IS_EXISTS); } // 发送短信 @@ -76,11 +74,11 @@ public class SysSmsCodeServiceImpl implements SysSmsCodeService { SysSmsCodeDO lastSmsCode = smsCodeMapper.selectLastByMobile(mobile, null,null); if (lastSmsCode != null) { if (lastSmsCode.getTodayIndex() >= smsCodeProperties.getSendMaximumQuantityPerDay()) { // 超过当天发送的上限。 - throw ServiceExceptionUtil.exception(SysErrorCodeConstants.USER_SMS_CODE_EXCEED_SEND_MAXIMUM_QUANTITY_PER_DAY); + throw ServiceExceptionUtil.exception(USER_SMS_CODE_EXCEED_SEND_MAXIMUM_QUANTITY_PER_DAY); } if (System.currentTimeMillis() - lastSmsCode.getCreateTime().getTime() < smsCodeProperties.getSendFrequency().toMillis()) { // 发送过于频繁 - throw ServiceExceptionUtil.exception(SysErrorCodeConstants.USER_SMS_CODE_SEND_TOO_FAST); + throw ServiceExceptionUtil.exception(USER_SMS_CODE_SEND_TOO_FAST); } // TODO 芋艿:提升,每个 IP 每天可发送数量 // TODO 芋艿:提升,每个 IP 每小时可发送数量 @@ -97,13 +95,12 @@ public class SysSmsCodeServiceImpl implements SysSmsCodeService { @Override public void useSmsCode(String mobile, Integer scene, String code, String usedIp) { - // 检测验证码是否有效 SysSmsCodeDO lastSmsCode = this.checkCodeIsExpired(mobile, code, scene); // 判断验证码是否已被使用 if (Boolean.TRUE.equals(lastSmsCode.getUsed())) { - throw ServiceExceptionUtil.exception(SysErrorCodeConstants.USER_SMS_CODE_USED); + throw ServiceExceptionUtil.exception(USER_SMS_CODE_USED); } // 使用验证码 @@ -113,9 +110,9 @@ public class SysSmsCodeServiceImpl implements SysSmsCodeService { @Override public void sendSmsCodeLogin(Long userId) { - MbrUserDO user = mbrUserService.getUser(userId); + UserDO user = userService.getUser(userId); if (user == null){ - throw ServiceExceptionUtil.exception(SysErrorCodeConstants.USER_NOT_EXISTS); + throw ServiceExceptionUtil.exception(USER_NOT_EXISTS); } // 发送验证码 this.sendSmsCode(user.getMobile(),SysSmsSceneEnum.CHANGE_MOBILE_BY_SMS.getScene(), getClientIP()); @@ -128,15 +125,13 @@ public class SysSmsCodeServiceImpl implements SysSmsCodeService { // 若验证码不存在,抛出异常 if (lastSmsCode == null) { - throw ServiceExceptionUtil.exception(SysErrorCodeConstants.USER_SMS_CODE_NOT_FOUND); + throw ServiceExceptionUtil.exception(USER_SMS_CODE_NOT_FOUND); } if (System.currentTimeMillis() - lastSmsCode.getCreateTime().getTime() >= smsCodeProperties.getExpireTimes().toMillis()) { // 验证码已过期 - throw ServiceExceptionUtil.exception(SysErrorCodeConstants.USER_SMS_CODE_EXPIRED); + throw ServiceExceptionUtil.exception(USER_SMS_CODE_EXPIRED); } - return lastSmsCode; - } } diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/user/MbrUserService.java b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/user/UserService.java similarity index 57% rename from yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/user/MbrUserService.java rename to yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/user/UserService.java index be02945c9..454e19dc6 100644 --- a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/user/MbrUserService.java +++ b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/user/UserService.java @@ -1,18 +1,18 @@ package cn.iocoder.yudao.module.member.service.user; -import cn.iocoder.yudao.coreservice.modules.member.dal.dataobject.user.MbrUserDO; -import cn.iocoder.yudao.userserver.modules.member.controller.user.vo.MbrUserInfoRespVO; import cn.iocoder.yudao.framework.common.validation.Mobile; -import cn.iocoder.yudao.userserver.modules.member.controller.user.vo.MbrUserUpdateMobileReqVO; +import cn.iocoder.yudao.module.member.controller.app.user.vo.AppUserInfoRespVO; +import cn.iocoder.yudao.module.member.controller.app.user.vo.AppUserUpdateMobileReqVO; +import cn.iocoder.yudao.module.member.dal.dataobject.user.UserDO; import java.io.InputStream; /** - * 前台用户 Service 接口 + * 会员用户 Service 接口 * * @author 芋道源码 */ -public interface MbrUserService { +public interface UserService { /** * 通过手机查询用户 @@ -20,7 +20,7 @@ public interface MbrUserService { * @param mobile 手机 * @return 用户对象 */ - MbrUserDO getUserByMobile(String mobile); + UserDO getUserByMobile(String mobile); /** * 基于手机号创建用户。 @@ -30,7 +30,7 @@ public interface MbrUserService { * @param registerIp 注册 IP * @return 用户对象 */ - MbrUserDO createUserIfAbsent(@Mobile String mobile, String registerIp); + UserDO createUserIfAbsent(@Mobile String mobile, String registerIp); /** * 更新用户的最后登陆信息 @@ -46,14 +46,14 @@ public interface MbrUserService { * @param id 用户ID * @return 用户对象信息 */ - MbrUserDO getUser(Long id); + UserDO getUser(Long id); /** * 修改用户昵称 * @param userId 用户id * @param nickname 用户新昵称 */ - void updateNickname(Long userId, String nickname); + void updateUserNickname(Long userId, String nickname); /** * 修改用户头像 @@ -61,21 +61,13 @@ public interface MbrUserService { * @param inputStream 头像文件 * @return 头像url */ - String updateAvatar(Long userId, InputStream inputStream); - - /** - * 根据用户id,获取用户头像与昵称 - * - * @param userId 用户id - * @return 用户响应实体类 - */ - MbrUserInfoRespVO getUserInfo(Long userId); + String updateUserAvatar(Long userId, InputStream inputStream); /** * 修改手机 * @param userId 用户id * @param reqVO 请求实体 */ - void updateMobile(Long userId, MbrUserUpdateMobileReqVO reqVO); + void updateUserMobile(Long userId, AppUserUpdateMobileReqVO reqVO); } diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/user/MbrUserServiceImpl.java b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/user/UserServiceImpl.java similarity index 51% rename from yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/user/MbrUserServiceImpl.java rename to yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/user/UserServiceImpl.java index de5313598..a899b79e6 100644 --- a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/user/MbrUserServiceImpl.java +++ b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/user/UserServiceImpl.java @@ -3,17 +3,15 @@ package cn.iocoder.yudao.module.member.service.user; 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.coreservice.modules.member.dal.dataobject.user.MbrUserDO; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil; -import cn.iocoder.yudao.userserver.modules.member.controller.user.vo.MbrUserInfoRespVO; -import cn.iocoder.yudao.userserver.modules.member.controller.user.vo.MbrUserUpdateMobileReqVO; -import cn.iocoder.yudao.userserver.modules.member.convert.user.UserProfileConvert; -import cn.iocoder.yudao.userserver.modules.member.dal.mysql.user.MbrUserMapper; -import cn.iocoder.yudao.userserver.modules.member.service.user.MbrUserService; -import cn.iocoder.yudao.userserver.modules.system.dal.dataobject.sms.SysSmsCodeDO; -import cn.iocoder.yudao.userserver.modules.system.enums.sms.SysSmsSceneEnum; -import cn.iocoder.yudao.userserver.modules.system.service.sms.SysSmsCodeService; +import cn.iocoder.yudao.module.member.controller.app.user.vo.AppUserUpdateMobileReqVO; +import cn.iocoder.yudao.module.member.dal.dataobject.sms.SysSmsCodeDO; +import cn.iocoder.yudao.module.member.dal.dataobject.user.UserDO; +import cn.iocoder.yudao.module.member.dal.mysql.user.UserMapper; +import cn.iocoder.yudao.module.member.enums.SysErrorCodeConstants; +import cn.iocoder.yudao.module.member.enums.sms.SysSmsSceneEnum; +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; @@ -27,41 +25,38 @@ import java.util.Date; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP; -import static cn.iocoder.yudao.userserver.modules.member.enums.MbrErrorCodeConstants.USER_NOT_EXISTS; -import static cn.iocoder.yudao.userserver.modules.system.enums.SysErrorCodeConstants.USER_SMS_CODE_IS_UNUSED; +import static cn.iocoder.yudao.module.member.enums.MemberErrorCodeConstants.USER_NOT_EXISTS; /** - * User Service 实现类 + * 会员 User Service 实现类 * * @author 芋道源码 */ @Service @Valid @Slf4j -public class MbrUserServiceImpl implements MbrUserService { +public class UserServiceImpl implements UserService { @Resource - private MbrUserMapper userMapper; + private UserMapper memberUserMapper; @Resource private InfFileCoreService fileCoreService; + @Resource + private SysSmsCodeService smsCodeService; @Resource private PasswordEncoder passwordEncoder; - @Resource - private SysSmsCodeService smsCodeService; - - @Override - public MbrUserDO getUserByMobile(String mobile) { - return userMapper.selectByMobile(mobile); + public UserDO getUserByMobile(String mobile) { + return memberUserMapper.selectByMobile(mobile); } @Override - public MbrUserDO createUserIfAbsent(String mobile, String registerIp) { + public UserDO createUserIfAbsent(String mobile, String registerIp) { // 用户已经存在 - MbrUserDO user = userMapper.selectByMobile(mobile); + UserDO user = memberUserMapper.selectByMobile(mobile); if (user != null) { return user; } @@ -69,94 +64,84 @@ public class MbrUserServiceImpl implements MbrUserService { return this.createUser(mobile, registerIp); } - private MbrUserDO createUser(String mobile, String registerIp) { + private UserDO createUser(String mobile, String registerIp) { // 生成密码 String password = IdUtil.fastSimpleUUID(); // 插入用户 - MbrUserDO user = new MbrUserDO(); + UserDO user = new UserDO(); user.setMobile(mobile); user.setStatus(CommonStatusEnum.ENABLE.getStatus()); // 默认开启 user.setPassword(passwordEncoder.encode(password)); // 加密密码 user.setRegisterIp(registerIp); - userMapper.insert(user); + memberUserMapper.insert(user); return user; } @Override public void updateUserLogin(Long id, String loginIp) { - userMapper.updateById(new MbrUserDO().setId(id).setLoginIp(loginIp).setLoginDate(new Date())); + memberUserMapper.updateById(new UserDO().setId(id) + .setLoginIp(loginIp).setLoginDate(new Date())); } @Override - public MbrUserDO getUser(Long id) { - return userMapper.selectById(id); + public UserDO getUser(Long id) { + return memberUserMapper.selectById(id); } @Override - public void updateNickname(Long userId, String nickname) { - MbrUserDO user = this.checkUserExists(userId); + public void updateUserNickname(Long userId, String nickname) { + UserDO user = this.checkUserExists(userId); // 仅当新昵称不等于旧昵称时进行修改 if (nickname.equals(user.getNickname())){ return; } - MbrUserDO userDO = new MbrUserDO(); + UserDO userDO = new UserDO(); userDO.setId(user.getId()); userDO.setNickname(nickname); - userMapper.updateById(userDO); + memberUserMapper.updateById(userDO); } @Override - public String updateAvatar(Long userId, InputStream avatarFile) { + public String updateUserAvatar(Long userId, InputStream avatarFile) { this.checkUserExists(userId); // 创建文件 String avatar = fileCoreService.createFile(IdUtil.fastUUID(), IoUtil.readBytes(avatarFile)); // 更新头像路径 - MbrUserDO userDO = MbrUserDO.builder() - .id(userId) - .avatar(avatar) - .build(); - userMapper.updateById(userDO); + memberUserMapper.updateById(UserDO.builder().id(userId).avatar(avatar).build()); return avatar; } - @Override - public MbrUserInfoRespVO getUserInfo(Long userId) { - MbrUserDO user = this.checkUserExists(userId); - // 拼接返回结果 - return UserProfileConvert.INSTANCE.convert(user); - } - - @Override @Transactional(rollbackFor = Exception.class) - public void updateMobile(Long userId, MbrUserUpdateMobileReqVO reqVO) { + public void updateUserMobile(Long userId, AppUserUpdateMobileReqVO reqVO) { // 检测用户是否存在 checkUserExists(userId); // 校验旧手机和旧验证码 - SysSmsCodeDO sysSmsCodeDO = smsCodeService.checkCodeIsExpired(reqVO.getOldMobile(), reqVO.getOldCode(), SysSmsSceneEnum.CHANGE_MOBILE_BY_SMS.getScene()); - // 判断旧code是否未被使用,如果是,抛出异常 + SysSmsCodeDO sysSmsCodeDO = smsCodeService.checkCodeIsExpired(reqVO.getOldMobile(), reqVO.getOldCode(), + SysSmsSceneEnum.CHANGE_MOBILE_BY_SMS.getScene()); + // 判断旧 code 是否未被使用,如果是,抛出异常 if (Boolean.FALSE.equals(sysSmsCodeDO.getUsed())){ throw ServiceExceptionUtil.exception(SysErrorCodeConstants.USER_SMS_CODE_IS_UNUSED); } // 使用新验证码 - smsCodeService.useSmsCode(reqVO.getMobile(), SysSmsSceneEnum.CHANGE_MOBILE_BY_SMS.getScene(), reqVO.getCode(),getClientIP()); + smsCodeService.useSmsCode(reqVO.getMobile(), SysSmsSceneEnum.CHANGE_MOBILE_BY_SMS.getScene(), + reqVO.getCode(),getClientIP()); // 更新用户手机 - MbrUserDO userDO = MbrUserDO.builder().id(userId).mobile(reqVO.getMobile()).build(); - userMapper.updateById(userDO); + memberUserMapper.updateById(UserDO.builder().id(userId).mobile(reqVO.getMobile()).build()); } @VisibleForTesting - public MbrUserDO checkUserExists(Long id) { + public UserDO checkUserExists(Long id) { if (id == null) { return null; } - MbrUserDO user = userMapper.selectById(id); + UserDO user = memberUserMapper.selectById(id); if (user == null) { throw exception(USER_NOT_EXISTS); - }else{ - return user; } + return user; } + } diff --git a/yudao-module-member/yudao-module-member-impl/src/test/java/cn/iocoder/yudao/module/member/service/auth/SysAuthServiceTest.java b/yudao-module-member/yudao-module-member-impl/src/test/java/cn/iocoder/yudao/module/member/service/auth/SysAuthServiceTest.java index ff1c8a7c6..aa38ab936 100644 --- a/yudao-module-member/yudao-module-member-impl/src/test/java/cn/iocoder/yudao/module/member/service/auth/SysAuthServiceTest.java +++ b/yudao-module-member/yudao-module-member-impl/src/test/java/cn/iocoder/yudao/module/member/service/auth/SysAuthServiceTest.java @@ -1,20 +1,18 @@ package cn.iocoder.yudao.module.member.service.auth; -import cn.iocoder.yudao.coreservice.modules.member.dal.dataobject.user.MbrUserDO; import cn.iocoder.yudao.coreservice.modules.system.service.auth.SysUserSessionCoreService; import cn.iocoder.yudao.coreservice.modules.system.service.logger.SysLoginLogCoreService; import cn.iocoder.yudao.coreservice.modules.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.userserver.BaseDbAndRedisUnitTest; -import cn.iocoder.yudao.userserver.modules.member.dal.mysql.user.MbrUserMapper; -import cn.iocoder.yudao.userserver.modules.member.service.user.MbrUserService; -import cn.iocoder.yudao.module.member.controller.app.auth.vo.MbrAuthResetPasswordReqVO; -import cn.iocoder.yudao.module.member.controller.app.auth.vo.MbrAuthUpdatePasswordReqVO; -import cn.iocoder.yudao.userserver.modules.system.service.auth.SysAuthService; -import cn.iocoder.yudao.userserver.modules.system.service.auth.impl.SysAuthServiceImpl; -import cn.iocoder.yudao.userserver.modules.system.service.sms.SysSmsCodeService; +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.UserDO; +import cn.iocoder.yudao.module.member.dal.mysql.user.UserMapper; +import cn.iocoder.yudao.module.member.service.sms.SysSmsCodeService; +import cn.iocoder.yudao.module.member.service.user.UserService; +import cn.iocoder.yudao.module.member.test.BaseDbAndRedisUnitTest; import org.junit.jupiter.api.Test; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.context.annotation.Import; @@ -34,17 +32,17 @@ import static org.mockito.Mockito.when; // TODO @芋艿:单测的 review,等逻辑都达成一致后 /** - * {@link SysAuthService} 的单元测试类 + * {@link AuthService} 的单元测试类 * * @author 宋天 */ -@Import({SysAuthServiceImpl.class, YudaoRedisAutoConfiguration.class}) +@Import({AuthServiceImpl.class, YudaoRedisAutoConfiguration.class}) public class SysAuthServiceTest extends BaseDbAndRedisUnitTest { @MockBean private AuthenticationManager authenticationManager; @MockBean - private MbrUserService userService; + private UserService userService; @MockBean private SysSmsCodeService smsCodeService; @MockBean @@ -58,21 +56,21 @@ public class SysAuthServiceTest extends BaseDbAndRedisUnitTest { @MockBean private PasswordEncoder passwordEncoder; @Resource - private MbrUserMapper mbrUserMapper; + private UserMapper mbrUserMapper; @Resource - private SysAuthServiceImpl authService; + private AuthServiceImpl authService; @Test public void testUpdatePassword_success(){ // 准备参数 - MbrUserDO userDO = randomMbrUserDO(); + UserDO userDO = randomUserDO(); mbrUserMapper.insert(userDO); // 新密码 String newPassword = randomString(); // 请求实体 - MbrAuthUpdatePasswordReqVO reqVO = MbrAuthUpdatePasswordReqVO.builder() + AppAuthUpdatePasswordReqVO reqVO = AppAuthUpdatePasswordReqVO.builder() .oldPassword(userDO.getPassword()) .password(newPassword) .build(); @@ -83,14 +81,14 @@ public class SysAuthServiceTest extends BaseDbAndRedisUnitTest { when(passwordEncoder.encode(newPassword)).thenReturn(newPassword); // 更新用户密码 - authService.updatePassword(userDO.getId(),reqVO); + authService.updatePassword(userDO.getId(), reqVO); assertEquals(mbrUserMapper.selectById(userDO.getId()).getPassword(),newPassword); } @Test public void testResetPassword_success(){ // 准备参数 - MbrUserDO userDO = randomMbrUserDO(); + UserDO userDO = randomUserDO(); mbrUserMapper.insert(userDO); // 随机密码 @@ -102,7 +100,7 @@ public class SysAuthServiceTest extends BaseDbAndRedisUnitTest { when(passwordEncoder.encode(password)).thenReturn(password); // 更新用户密码 - MbrAuthResetPasswordReqVO reqVO = new MbrAuthResetPasswordReqVO(); + AppAuthResetPasswordReqVO reqVO = new AppAuthResetPasswordReqVO(); reqVO.setMobile(userDO.getMobile()); reqVO.setPassword(password); reqVO.setCode(code); @@ -115,12 +113,12 @@ public class SysAuthServiceTest extends BaseDbAndRedisUnitTest { // ========== 随机对象 ========== @SafeVarargs - private static MbrUserDO randomMbrUserDO(Consumer... consumers) { - Consumer consumer = (o) -> { + private static UserDO randomUserDO(Consumer... consumers) { + Consumer consumer = (o) -> { o.setStatus(randomEle(CommonStatusEnum.values()).getStatus()); // 保证 status 的范围 o.setPassword(randomString()); }; - return randomPojo(MbrUserDO.class, ArrayUtils.append(consumer, consumers)); + return randomPojo(UserDO.class, ArrayUtils.append(consumer, consumers)); } diff --git a/yudao-module-member/yudao-module-member-impl/src/test/java/cn/iocoder/yudao/module/member/service/package-info.java b/yudao-module-member/yudao-module-member-impl/src/test/java/cn/iocoder/yudao/module/member/service/package-info.java deleted file mode 100644 index 6223e6e6c..000000000 --- a/yudao-module-member/yudao-module-member-impl/src/test/java/cn/iocoder/yudao/module/member/service/package-info.java +++ /dev/null @@ -1 +0,0 @@ -package cn.iocoder.yudao.module.member.service; diff --git a/yudao-module-member/yudao-module-member-impl/src/test/java/cn/iocoder/yudao/module/member/service/user/MbrUserServiceImplTest.java b/yudao-module-member/yudao-module-member-impl/src/test/java/cn/iocoder/yudao/module/member/service/user/MbrUserServiceImplTest.java index ecd728ef0..96c562fa9 100644 --- a/yudao-module-member/yudao-module-member-impl/src/test/java/cn/iocoder/yudao/module/member/service/user/MbrUserServiceImplTest.java +++ b/yudao-module-member/yudao-module-member-impl/src/test/java/cn/iocoder/yudao/module/member/service/user/MbrUserServiceImplTest.java @@ -2,18 +2,17 @@ package cn.iocoder.yudao.module.member.service.user; import cn.hutool.core.util.RandomUtil; import cn.iocoder.yudao.coreservice.modules.infra.service.file.InfFileCoreService; -import cn.iocoder.yudao.coreservice.modules.member.dal.dataobject.user.MbrUserDO; 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.userserver.BaseDbAndRedisUnitTest; -import cn.iocoder.yudao.userserver.modules.member.controller.user.vo.MbrUserInfoRespVO; -import cn.iocoder.yudao.userserver.modules.member.controller.user.vo.MbrUserUpdateMobileReqVO; -import cn.iocoder.yudao.userserver.modules.member.dal.mysql.user.MbrUserMapper; -import cn.iocoder.yudao.userserver.modules.member.service.user.impl.MbrUserServiceImpl; -import cn.iocoder.yudao.userserver.modules.system.dal.dataobject.sms.SysSmsCodeDO; -import cn.iocoder.yudao.userserver.modules.system.service.auth.impl.SysAuthServiceImpl; -import cn.iocoder.yudao.userserver.modules.system.service.sms.SysSmsCodeService; +import cn.iocoder.yudao.module.member.controller.app.user.vo.AppUserUpdateMobileReqVO; +import cn.iocoder.yudao.module.member.dal.dataobject.sms.SysSmsCodeDO; +import cn.iocoder.yudao.module.member.dal.dataobject.user.UserDO; +import cn.iocoder.yudao.module.member.dal.mysql.user.UserMapper; +import cn.iocoder.yudao.module.member.enums.sms.SysSmsSceneEnum; +import cn.iocoder.yudao.module.member.service.auth.AuthServiceImpl; +import cn.iocoder.yudao.module.member.service.sms.SysSmsCodeService; +import cn.iocoder.yudao.module.member.test.BaseDbAndRedisUnitTest; import org.junit.jupiter.api.Test; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.context.annotation.Import; @@ -27,30 +26,29 @@ import java.util.function.Consumer; import static cn.hutool.core.util.RandomUtil.*; import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomString; -import static cn.iocoder.yudao.userserver.modules.system.enums.sms.SysSmsSceneEnum.CHANGE_MOBILE_BY_SMS; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.Mockito.*; // TODO @芋艿:单测的 review,等逻辑都达成一致后 /** - * {@link MbrUserServiceImpl} 的单元测试类 + * {@link UserServiceImpl} 的单元测试类 * * @author 宋天 */ -@Import({MbrUserServiceImpl.class, YudaoRedisAutoConfiguration.class}) +@Import({UserServiceImpl.class, YudaoRedisAutoConfiguration.class}) public class MbrUserServiceImplTest extends BaseDbAndRedisUnitTest { @Resource - private MbrUserServiceImpl mbrUserService; + private UserServiceImpl mbrUserService; @Resource private StringRedisTemplate stringRedisTemplate; @Resource - private MbrUserMapper userMapper; + private UserMapper userMapper; @MockBean - private SysAuthServiceImpl authService; + private AuthServiceImpl authService; @MockBean private InfFileCoreService fileCoreService; @@ -64,35 +62,24 @@ public class MbrUserServiceImplTest extends BaseDbAndRedisUnitTest { @Test public void testUpdateNickName_success(){ // mock 数据 - MbrUserDO userDO = randomMbrUserDO(); + UserDO userDO = randomUserDO(); userMapper.insert(userDO); // 随机昵称 String newNickName = randomString(); // 调用接口修改昵称 - mbrUserService.updateNickname(userDO.getId(),newNickName); + mbrUserService.updateUserNickname(userDO.getId(),newNickName); // 查询新修改后的昵称 String nickname = mbrUserService.getUser(userDO.getId()).getNickname(); // 断言 assertEquals(newNickName,nickname); } - @Test - public void testGetUserInfo_success(){ - // mock 数据 - MbrUserDO userDO = randomMbrUserDO(); - userMapper.insert(userDO); - - // 查询用户昵称与头像 - MbrUserInfoRespVO userInfo = mbrUserService.getUserInfo(userDO.getId()); - System.out.println(userInfo); - } - @Test public void testUpdateAvatar_success(){ // mock 数据 - MbrUserDO dbUser = randomMbrUserDO(); + UserDO dbUser = randomUserDO(); userMapper.insert(dbUser); // 准备参数 @@ -103,7 +90,7 @@ public class MbrUserServiceImplTest extends BaseDbAndRedisUnitTest { String avatar = randomString(); when(fileCoreService.createFile(anyString(), eq(avatarFileBytes))).thenReturn(avatar); // 调用 - String str = mbrUserService.updateAvatar(userId, avatarFile); + String str = mbrUserService.updateUserAvatar(userId, avatarFile); // 断言 assertEquals(avatar, str); } @@ -112,11 +99,10 @@ public class MbrUserServiceImplTest extends BaseDbAndRedisUnitTest { public void updateMobile_success(){ // mock数据 String oldMobile = randomNumbers(11); - MbrUserDO userDO = randomMbrUserDO(); + UserDO userDO = randomUserDO(); userDO.setMobile(oldMobile); userMapper.insert(userDO); - // 旧手机和旧验证码 SysSmsCodeDO codeDO = new SysSmsCodeDO(); String oldCode = RandomUtil.randomString(4); @@ -129,12 +115,12 @@ public class MbrUserServiceImplTest extends BaseDbAndRedisUnitTest { // 更新手机号 String newMobile = randomNumbers(11); String newCode = randomNumbers(4); - MbrUserUpdateMobileReqVO reqVO = new MbrUserUpdateMobileReqVO(); + AppUserUpdateMobileReqVO reqVO = new AppUserUpdateMobileReqVO(); reqVO.setMobile(newMobile); reqVO.setCode(newCode); reqVO.setOldMobile(oldMobile); reqVO.setOldCode(oldCode); - mbrUserService.updateMobile(userDO.getId(),reqVO); + mbrUserService.updateUserMobile(userDO.getId(),reqVO); assertEquals(mbrUserService.getUser(userDO.getId()).getMobile(),newMobile); } @@ -142,11 +128,11 @@ public class MbrUserServiceImplTest extends BaseDbAndRedisUnitTest { // ========== 随机对象 ========== @SafeVarargs - private static MbrUserDO randomMbrUserDO(Consumer... consumers) { - Consumer consumer = (o) -> { + private static UserDO randomUserDO(Consumer... consumers) { + Consumer consumer = (o) -> { o.setStatus(randomEle(CommonStatusEnum.values()).getStatus()); // 保证 status 的范围 }; - return randomPojo(MbrUserDO.class, ArrayUtils.append(consumer, consumers)); + return randomPojo(UserDO.class, ArrayUtils.append(consumer, consumers)); } } diff --git a/yudao-module-member/yudao-module-member-impl/src/test/java/cn/iocoder/yudao/module/member/test/BaseDbAndRedisUnitTest.java b/yudao-module-member/yudao-module-member-impl/src/test/java/cn/iocoder/yudao/module/member/test/BaseDbAndRedisUnitTest.java index 50d19ad4e..a9278498d 100644 --- a/yudao-module-member/yudao-module-member-impl/src/test/java/cn/iocoder/yudao/module/member/test/BaseDbAndRedisUnitTest.java +++ b/yudao-module-member/yudao-module-member-impl/src/test/java/cn/iocoder/yudao/module/member/test/BaseDbAndRedisUnitTest.java @@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.member.test; import cn.iocoder.yudao.framework.datasource.config.YudaoDataSourceAutoConfiguration; import cn.iocoder.yudao.framework.mybatis.config.YudaoMybatisAutoConfiguration; import cn.iocoder.yudao.framework.redis.config.YudaoRedisAutoConfiguration; -import cn.iocoder.yudao.userserver.config.RedisTestConfiguration; import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure; import com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration; import org.redisson.spring.starter.RedissonAutoConfiguration; diff --git a/yudao-module-member/yudao-module-member-impl/src/test/resources/application-unit-test.yaml b/yudao-module-member/yudao-module-member-impl/src/test/resources/application-unit-test.yaml index d306a7af4..237068e6e 100644 --- a/yudao-module-member/yudao-module-member-impl/src/test/resources/application-unit-test.yaml +++ b/yudao-module-member/yudao-module-member-impl/src/test/resources/application-unit-test.yaml @@ -42,3 +42,8 @@ mybatis: --- #################### 芋道相关配置 #################### # 芋道配置项,设置当前项目所有自定义的配置 +yudao: + info: + base-package: cn.iocoder.yudao.module.member.dal.mysql + core-service: + base-package: cn.iocoder.yudao.module.member.dal.mysql # TODO 芋艿:要清理掉 diff --git a/yudao-user-server/src/main/resources/application-dev.yaml b/yudao-user-server/src/main/resources/application-dev.yaml index 7e6aa355e..f44bc4935 100644 --- a/yudao-user-server/src/main/resources/application-dev.yaml +++ b/yudao-user-server/src/main/resources/application-dev.yaml @@ -124,6 +124,19 @@ logging: file: name: ${user.home}/logs/${spring.application.name}.log # 日志文件名,全路径 + +--- #################### 微信公众号相关配置 #################### +wx: # 参见 https://github.com/Wechat-Group/WxJava/blob/develop/spring-boot-starters/wx-java-mp-spring-boot-starter/README.md 文档 + mp: + # 公众号配置(必填) + app-id: wx041349c6f39b268b + secret: 5abee519483bc9f8cb37ce280e814bd0 + # 存储配置,解决 AccessToken 的跨节点的共享 + config-storage: + type: RedisTemplate # 采用 RedisTemplate 操作 Redis,会自动从 Spring 中获取 + key-prefix: wx # Redis Key 的前缀 TODO 芋艿:解决下 Redis key 管理的配置 + http-client-type: HttpClient # 采用 HttpClient 请求微信公众号平台 + --- #################### 芋道相关配置 #################### # 芋道配置项,设置当前项目所有自定义的配置 diff --git a/yudao-user-server/src/main/resources/application.yaml b/yudao-user-server/src/main/resources/application.yaml index 209543380..1d789232d 100644 --- a/yudao-user-server/src/main/resources/application.yaml +++ b/yudao-user-server/src/main/resources/application.yaml @@ -66,11 +66,6 @@ yudao: constants-class-list: - cn.iocoder.yudao.userserver.modules.member.enums.MbrErrorCodeConstants - cn.iocoder.yudao.userserver.modules.system.enums.SysErrorCodeConstants - sms-code: # 短信验证码相关的配置项 - expire-times: 10m - send-frequency: 1m - send-maximum-quantity-per-day: 10 - begin-code: 9999 # 这里配置 9999 的原因是,测试方便。 - end-code: 9999 # 这里配置 9999 的原因是,测试方便。 + debug: false