feat: 增加作家注册功能

This commit is contained in:
xiongxiaoyang 2022-05-23 12:06:17 +08:00
parent e3cf41fbd8
commit 879673bca5
16 changed files with 195 additions and 15 deletions

View File

@ -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<Void> register(@Valid @RequestBody AuthorRegisterReqDto dto) {
dto.setUserId(UserHolder.getUserId());
return authorService.register(dto);
}
}

View File

@ -13,7 +13,7 @@ import java.security.NoSuchAlgorithmException;
import java.util.List;
/**
* 小说模块 API 接口
* 前台门户-小说模块 API 控制器
*
* @author xiongxiaoyang
* @date 2022/5/14

View File

@ -13,7 +13,7 @@ import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* 首页模块 API 接口
* 前台门户-首页模块 API 控制器
*
* @author xiongxiaoyang
* @date 2022/5/12

View File

@ -13,7 +13,7 @@ import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* 新闻模块 API 接口
* 前台门户-新闻模块 API 控制器
*
* @author xiongxiaoyang
* @date 2022/5/12

View File

@ -11,7 +11,7 @@ import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
/**
* 资源图片/视频/文档相关 控制器
* 前台门户-资源(图片/视频/文档)模块 API 控制器
*
* @author xiongxiaoyang
* @date 2022/5/17

View File

@ -17,7 +17,7 @@ import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
/**
* 会员模块相关 控制器
* 前台门户-会员模块 API 控制器
*
* @author xiongxiaoyang
* @date 2022/5/17

View File

@ -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 校验
}
}

View File

@ -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;
/**
* 前台多系统单点登录统一账号认证门户系统作家系统以及后面会扩展的漫画系统和视频系统等

View File

@ -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<String> 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);
}

View File

@ -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);
}

View File

@ -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");
}

View File

@ -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){
// 认证失败

View File

@ -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;
}

View File

@ -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<AuthorInfo> 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(){
// 调用此方法自动清除作家信息的缓存
}
}

View File

@ -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<Void> register(AuthorRegisterReqDto dto);
}

View File

@ -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<Void> 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();
}
}