From 879673bca5f3a6152bd8978f42d36a2f2e0a3c11 Mon Sep 17 00:00:00 2001 From: xiongxiaoyang <773861846@qq.com> Date: Mon, 23 May 2022 12:06:17 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E4=BD=9C=E5=AE=B6?= =?UTF-8?q?=E6=B3=A8=E5=86=8C=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/author/AuthorController.java | 36 ++++++++++++ .../controller/front/BookController.java | 2 +- .../controller/front/HomeController.java | 2 +- .../controller/front/NewsController.java | 2 +- .../controller/front/ResourceController.java | 2 +- .../controller/front/UserController.java | 2 +- .../novel/core/auth/AdminAuthStrategy.java | 2 +- .../xxyopen/novel/core/auth/AuthStrategy.java | 4 +- .../novel/core/auth/AuthorAuthStrategy.java | 16 +++++- .../novel/core/auth/FrontAuthStrategy.java | 2 +- .../xxyopen/novel/core/config/WebConfig.java | 1 - .../core/interceptor/AuthInterceptor.java | 2 +- .../novel/dto/req/AuthorRegisterReqDto.java | 51 +++++++++++++++++ .../novel/manager/AuthorInfoCacheManager.java | 8 ++- .../xxyopen/novel/service/AuthorService.java | 21 +++++++ .../novel/service/impl/AuthorServiceImpl.java | 57 +++++++++++++++++++ 16 files changed, 195 insertions(+), 15 deletions(-) create mode 100644 src/main/java/io/github/xxyopen/novel/controller/author/AuthorController.java create mode 100644 src/main/java/io/github/xxyopen/novel/dto/req/AuthorRegisterReqDto.java create mode 100644 src/main/java/io/github/xxyopen/novel/service/AuthorService.java create mode 100644 src/main/java/io/github/xxyopen/novel/service/impl/AuthorServiceImpl.java diff --git a/src/main/java/io/github/xxyopen/novel/controller/author/AuthorController.java b/src/main/java/io/github/xxyopen/novel/controller/author/AuthorController.java new file mode 100644 index 0000000..d3a806c --- /dev/null +++ b/src/main/java/io/github/xxyopen/novel/controller/author/AuthorController.java @@ -0,0 +1,36 @@ +package io.github.xxyopen.novel.controller.author; + +import io.github.xxyopen.novel.core.auth.UserHolder; +import io.github.xxyopen.novel.core.common.resp.RestResp; +import io.github.xxyopen.novel.core.constant.ApiRouterConsts; +import io.github.xxyopen.novel.dto.req.AuthorRegisterReqDto; +import io.github.xxyopen.novel.service.AuthorService; +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * 作家后台-作家模块 API 控制器 + * @author xiongxiaoyang + * @date 2022/5/23 + */ +@RestController +@RequestMapping(ApiRouterConsts.API_AUTHOR_URL_PREFIX) +@RequiredArgsConstructor +public class AuthorController { + + private final AuthorService authorService; + + /** + * 作家注册接口 + */ + @PostMapping("register") + public RestResp register(@Valid @RequestBody AuthorRegisterReqDto dto) { + dto.setUserId(UserHolder.getUserId()); + return authorService.register(dto); + } + +} diff --git a/src/main/java/io/github/xxyopen/novel/controller/front/BookController.java b/src/main/java/io/github/xxyopen/novel/controller/front/BookController.java index 435b402..79fdf97 100644 --- a/src/main/java/io/github/xxyopen/novel/controller/front/BookController.java +++ b/src/main/java/io/github/xxyopen/novel/controller/front/BookController.java @@ -13,7 +13,7 @@ import java.security.NoSuchAlgorithmException; import java.util.List; /** - * 小说模块 API 接口 + * 前台门户-小说模块 API 控制器 * * @author xiongxiaoyang * @date 2022/5/14 diff --git a/src/main/java/io/github/xxyopen/novel/controller/front/HomeController.java b/src/main/java/io/github/xxyopen/novel/controller/front/HomeController.java index a8a1fc0..9dddca2 100644 --- a/src/main/java/io/github/xxyopen/novel/controller/front/HomeController.java +++ b/src/main/java/io/github/xxyopen/novel/controller/front/HomeController.java @@ -13,7 +13,7 @@ import org.springframework.web.bind.annotation.RestController; import java.util.List; /** - * 首页模块 API 接口 + * 前台门户-首页模块 API 控制器 * * @author xiongxiaoyang * @date 2022/5/12 diff --git a/src/main/java/io/github/xxyopen/novel/controller/front/NewsController.java b/src/main/java/io/github/xxyopen/novel/controller/front/NewsController.java index f6ee92e..db7bac3 100644 --- a/src/main/java/io/github/xxyopen/novel/controller/front/NewsController.java +++ b/src/main/java/io/github/xxyopen/novel/controller/front/NewsController.java @@ -13,7 +13,7 @@ import org.springframework.web.bind.annotation.RestController; import java.util.List; /** - * 新闻模块 API 接口 + * 前台门户-新闻模块 API 控制器 * * @author xiongxiaoyang * @date 2022/5/12 diff --git a/src/main/java/io/github/xxyopen/novel/controller/front/ResourceController.java b/src/main/java/io/github/xxyopen/novel/controller/front/ResourceController.java index 9bf26b6..edec679 100644 --- a/src/main/java/io/github/xxyopen/novel/controller/front/ResourceController.java +++ b/src/main/java/io/github/xxyopen/novel/controller/front/ResourceController.java @@ -11,7 +11,7 @@ import org.springframework.web.multipart.MultipartFile; import java.io.IOException; /** - * 资源(图片/视频/文档)相关 控制器 + * 前台门户-资源(图片/视频/文档)模块 API 控制器 * * @author xiongxiaoyang * @date 2022/5/17 diff --git a/src/main/java/io/github/xxyopen/novel/controller/front/UserController.java b/src/main/java/io/github/xxyopen/novel/controller/front/UserController.java index 041403b..39f597a 100644 --- a/src/main/java/io/github/xxyopen/novel/controller/front/UserController.java +++ b/src/main/java/io/github/xxyopen/novel/controller/front/UserController.java @@ -17,7 +17,7 @@ import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.*; /** - * 会员模块相关 控制器 + * 前台门户-会员模块 API 控制器 * * @author xiongxiaoyang * @date 2022/5/17 diff --git a/src/main/java/io/github/xxyopen/novel/core/auth/AdminAuthStrategy.java b/src/main/java/io/github/xxyopen/novel/core/auth/AdminAuthStrategy.java index 11f462e..88759cb 100644 --- a/src/main/java/io/github/xxyopen/novel/core/auth/AdminAuthStrategy.java +++ b/src/main/java/io/github/xxyopen/novel/core/auth/AdminAuthStrategy.java @@ -15,7 +15,7 @@ import org.springframework.stereotype.Component; public class AdminAuthStrategy implements AuthStrategy { @Override - public void auth(String token) throws BusinessException { + public void auth(String token, String requestUri) throws BusinessException { // TODO 平台后台 token 校验 } } \ No newline at end of file diff --git a/src/main/java/io/github/xxyopen/novel/core/auth/AuthStrategy.java b/src/main/java/io/github/xxyopen/novel/core/auth/AuthStrategy.java index 4a03405..9881c03 100644 --- a/src/main/java/io/github/xxyopen/novel/core/auth/AuthStrategy.java +++ b/src/main/java/io/github/xxyopen/novel/core/auth/AuthStrategy.java @@ -20,12 +20,12 @@ public interface AuthStrategy { /** * 请求用户认证 - * 如果后面需要扩展到对每一个URI都进行权限控制,那么此方法可以加一个参数来接收用户请求的URI * * @param token 登录 token + * @param requestUri 请求的 URI * @throws BusinessException 认证失败则抛出业务异常 */ - void auth(String token) throws BusinessException; + void auth(String token, String requestUri) throws BusinessException; /** * 前台多系统单点登录统一账号认证(门户系统、作家系统以及后面会扩展的漫画系统和视频系统等) diff --git a/src/main/java/io/github/xxyopen/novel/core/auth/AuthorAuthStrategy.java b/src/main/java/io/github/xxyopen/novel/core/auth/AuthorAuthStrategy.java index 1cfe433..31a1bfa 100644 --- a/src/main/java/io/github/xxyopen/novel/core/auth/AuthorAuthStrategy.java +++ b/src/main/java/io/github/xxyopen/novel/core/auth/AuthorAuthStrategy.java @@ -2,6 +2,7 @@ package io.github.xxyopen.novel.core.auth; import io.github.xxyopen.novel.core.common.constant.ErrorCodeEnum; import io.github.xxyopen.novel.core.common.exception.BusinessException; +import io.github.xxyopen.novel.core.constant.ApiRouterConsts; import io.github.xxyopen.novel.core.util.JwtUtils; import io.github.xxyopen.novel.dto.AuthorInfoDto; import io.github.xxyopen.novel.manager.AuthorInfoCacheManager; @@ -9,6 +10,7 @@ import io.github.xxyopen.novel.manager.UserInfoCacheManager; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; +import java.util.List; import java.util.Objects; /** @@ -27,14 +29,22 @@ public class AuthorAuthStrategy implements AuthStrategy { private final AuthorInfoCacheManager authorInfoCacheManager; + /** + * 不需要进行作家权限认证的 URI + * */ + private static final List EXCLUDE_URI = List.of(ApiRouterConsts.API_AUTHOR_URL_PREFIX + "/register"); + @Override - public void auth(String token) throws BusinessException { + public void auth(String token, String requestUri) throws BusinessException { // 统一账号认证 Long userId = authSSO(jwtUtils, userInfoCacheManager, token); - + if(EXCLUDE_URI.contains(requestUri)){ + // 该请求不需要进行作家权限认证 + return; + } // 作家权限认证 AuthorInfoDto authorInfo = authorInfoCacheManager.getAuthor(userId); - if(Objects.isNull(authorInfo)){ + if (Objects.isNull(authorInfo)) { // 作家账号不存在,无权访问作家专区 throw new BusinessException(ErrorCodeEnum.USER_UN_AUTH); } diff --git a/src/main/java/io/github/xxyopen/novel/core/auth/FrontAuthStrategy.java b/src/main/java/io/github/xxyopen/novel/core/auth/FrontAuthStrategy.java index 4013669..1022281 100644 --- a/src/main/java/io/github/xxyopen/novel/core/auth/FrontAuthStrategy.java +++ b/src/main/java/io/github/xxyopen/novel/core/auth/FrontAuthStrategy.java @@ -21,7 +21,7 @@ public class FrontAuthStrategy implements AuthStrategy { private final UserInfoCacheManager userInfoCacheManager; @Override - public void auth(String token) throws BusinessException { + public void auth(String token, String requestUri) throws BusinessException { // 统一账号认证 authSSO(jwtUtils,userInfoCacheManager,token); } diff --git a/src/main/java/io/github/xxyopen/novel/core/config/WebConfig.java b/src/main/java/io/github/xxyopen/novel/core/config/WebConfig.java index 80217b2..2bb0fae 100644 --- a/src/main/java/io/github/xxyopen/novel/core/config/WebConfig.java +++ b/src/main/java/io/github/xxyopen/novel/core/config/WebConfig.java @@ -42,7 +42,6 @@ public class WebConfig implements WebMvcConfigurer { // 放行登录注册相关请求接口 .excludePathPatterns(ApiRouterConsts.API_FRONT_USER_URL_PREFIX + "/register" , ApiRouterConsts.API_FRONT_USER_URL_PREFIX + "/login" - , ApiRouterConsts.API_AUTHOR_URL_PREFIX + "/register" ,ApiRouterConsts.API_ADMIN_URL_PREFIX + "/login"); } diff --git a/src/main/java/io/github/xxyopen/novel/core/interceptor/AuthInterceptor.java b/src/main/java/io/github/xxyopen/novel/core/interceptor/AuthInterceptor.java index 1718144..79b5566 100644 --- a/src/main/java/io/github/xxyopen/novel/core/interceptor/AuthInterceptor.java +++ b/src/main/java/io/github/xxyopen/novel/core/interceptor/AuthInterceptor.java @@ -49,7 +49,7 @@ public class AuthInterceptor implements HandlerInterceptor { // 开始认证 try { - authStrategy.get(authStrategyName).auth(token); + authStrategy.get(authStrategyName).auth(token,requestUri); return HandlerInterceptor.super.preHandle(request, response, handler); }catch (BusinessException exception){ // 认证失败 diff --git a/src/main/java/io/github/xxyopen/novel/dto/req/AuthorRegisterReqDto.java b/src/main/java/io/github/xxyopen/novel/dto/req/AuthorRegisterReqDto.java new file mode 100644 index 0000000..2517b11 --- /dev/null +++ b/src/main/java/io/github/xxyopen/novel/dto/req/AuthorRegisterReqDto.java @@ -0,0 +1,51 @@ +package io.github.xxyopen.novel.dto.req; + +import jakarta.validation.constraints.*; +import lombok.Data; + +/** + * 作家注册 请求DTO + * + * @author xiongxiaoyang + * @date 2022/5/23 + */ +@Data +public class AuthorRegisterReqDto { + + private Long userId; + + /** + * 笔名 + */ + @NotBlank(message="笔名不能为空!") + private String penName; + + /** + * 手机号码 + */ + @NotBlank(message="手机号不能为空!") + @Pattern(regexp="^1[3|4|5|6|7|8|9][0-9]{9}$",message="手机号格式不正确!") + private String telPhone; + + /** + * QQ或微信账号 + */ + @NotBlank(message="QQ或微信账号不能为空!") + private String chatAccount; + + /** + * 电子邮箱 + */ + @NotBlank(message="电子邮箱不能为空!") + @Email(message="邮箱格式不正确!") + private String email; + + /** + * 作品方向;0-男频 1-女频 + */ + @NotNull(message="作品方向不能为空!") + @Min(0) + @Max(1) + private Integer workDirection; + +} diff --git a/src/main/java/io/github/xxyopen/novel/manager/AuthorInfoCacheManager.java b/src/main/java/io/github/xxyopen/novel/manager/AuthorInfoCacheManager.java index 4de717b..871503f 100644 --- a/src/main/java/io/github/xxyopen/novel/manager/AuthorInfoCacheManager.java +++ b/src/main/java/io/github/xxyopen/novel/manager/AuthorInfoCacheManager.java @@ -7,6 +7,7 @@ import io.github.xxyopen.novel.dao.entity.AuthorInfo; import io.github.xxyopen.novel.dao.mapper.AuthorInfoMapper; import io.github.xxyopen.novel.dto.AuthorInfoDto; import lombok.RequiredArgsConstructor; +import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Component; @@ -28,7 +29,7 @@ public class AuthorInfoCacheManager { * 查询作家信息,并放入缓存中 */ @Cacheable(cacheManager = CacheConsts.REDIS_CACHE_MANAGER - , value = CacheConsts.AUTHOR_INFO_CACHE_NAME) + , value = CacheConsts.AUTHOR_INFO_CACHE_NAME, unless = "#result == null") public AuthorInfoDto getAuthor(Long userId) { QueryWrapper queryWrapper = new QueryWrapper<>(); queryWrapper @@ -43,5 +44,10 @@ public class AuthorInfoCacheManager { .status(authorInfo.getStatus()).build(); } + @CacheEvict(cacheManager = CacheConsts.REDIS_CACHE_MANAGER + , value = CacheConsts.AUTHOR_INFO_CACHE_NAME) + public void evictAuthorCache(){ + // 调用此方法自动清除作家信息的缓存 + } } diff --git a/src/main/java/io/github/xxyopen/novel/service/AuthorService.java b/src/main/java/io/github/xxyopen/novel/service/AuthorService.java new file mode 100644 index 0000000..672daa7 --- /dev/null +++ b/src/main/java/io/github/xxyopen/novel/service/AuthorService.java @@ -0,0 +1,21 @@ +package io.github.xxyopen.novel.service; + +import io.github.xxyopen.novel.core.common.resp.RestResp; +import io.github.xxyopen.novel.dto.req.AuthorRegisterReqDto; + +/** + * 作家模块 业务服务类 + * + * @author xiongxiaoyang + * @date 2022/5/23 + */ +public interface AuthorService { + + /** + * 作家注册 + * + * @param dto 注册参数 + * @return void + */ + RestResp register(AuthorRegisterReqDto dto); +} diff --git a/src/main/java/io/github/xxyopen/novel/service/impl/AuthorServiceImpl.java b/src/main/java/io/github/xxyopen/novel/service/impl/AuthorServiceImpl.java new file mode 100644 index 0000000..1419a02 --- /dev/null +++ b/src/main/java/io/github/xxyopen/novel/service/impl/AuthorServiceImpl.java @@ -0,0 +1,57 @@ +package io.github.xxyopen.novel.service.impl; + +import io.github.xxyopen.novel.core.common.resp.RestResp; +import io.github.xxyopen.novel.dao.entity.AuthorInfo; +import io.github.xxyopen.novel.dao.mapper.AuthorInfoMapper; +import io.github.xxyopen.novel.dto.AuthorInfoDto; +import io.github.xxyopen.novel.dto.req.AuthorRegisterReqDto; +import io.github.xxyopen.novel.manager.AuthorInfoCacheManager; +import io.github.xxyopen.novel.service.AuthorService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.time.LocalDateTime; +import java.util.Objects; + +/** + * 作家模块 服务实现类 + * + * @author xiongxiaoyang + * @date 2022/5/23 + */ +@Service +@RequiredArgsConstructor +@Slf4j +public class AuthorServiceImpl implements AuthorService { + + private final AuthorInfoCacheManager authorInfoCacheManager; + + private final AuthorInfoMapper authorInfoMapper; + + @Override + public RestResp register(AuthorRegisterReqDto dto) { + // 校验该用户是否已注册为作家 + AuthorInfoDto author = authorInfoCacheManager.getAuthor(dto.getUserId()); + if (Objects.nonNull(author)) { + // 该用户已经是作家,直接返回 + return RestResp.ok(); + } + // 保存作家注册信息 + AuthorInfo authorInfo = new AuthorInfo(); + authorInfo.setUserId(dto.getUserId()); + authorInfo.setChatAccount(dto.getChatAccount()); + authorInfo.setEmail(dto.getEmail()); + authorInfo.setInviteCode("0"); + authorInfo.setTelPhone(dto.getTelPhone()); + authorInfo.setPenName(dto.getPenName()); + authorInfo.setWorkDirection(dto.getWorkDirection()); + authorInfo.setCreateTime(LocalDateTime.now()); + authorInfo.setUpdateTime(LocalDateTime.now()); + authorInfoMapper.insert(authorInfo); + // 清除作家缓存 + authorInfoCacheManager.evictAuthorCache(); + return RestResp.ok(); + } + +}