feat: 添加代码格式化
This commit is contained in:
BIN
.idea/.cache/.easy-yapi/.api.cache.v1.1.db
generated
Normal file
BIN
.idea/.cache/.easy-yapi/.api.cache.v1.1.db
generated
Normal file
Binary file not shown.
0
.idea/.cache/.easy-yapi/.cookies.v1.0.json
generated
Normal file
0
.idea/.cache/.easy-yapi/.cookies.v1.0.json
generated
Normal file
0
.idea/.cache/.easy-yapi/.http_content_cache
generated
Normal file
0
.idea/.cache/.easy-yapi/.http_content_cache
generated
Normal file
6
.idea/CoolRequestSetting.xml
generated
Normal file
6
.idea/CoolRequestSetting.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CoolRequestSetting">
|
||||
<option name="projectCachePath" value="project-e82c3cb9-7dfc-4fa6-b498-45789b6b3803" />
|
||||
</component>
|
||||
</project>
|
||||
2
.idea/misc.xml
generated
2
.idea/misc.xml
generated
@@ -15,7 +15,7 @@
|
||||
</set>
|
||||
</option>
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="zulu-17" project-jdk-type="JavaSDK">
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="corretto-17" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
</project>
|
||||
@@ -7,7 +7,9 @@ import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
@EnableFeignClients(basePackages = "cn.meowrain.aioj.backend.auth.clients")
|
||||
@SpringBootApplication
|
||||
public class AIOJAuthApplication {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(AIOJAuthApplication.class, args);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(AIOJAuthApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -8,9 +8,11 @@ import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
@FeignClient(name = "user-service", path = "/api/v1/user")
|
||||
public interface UserClient {
|
||||
@GetMapping("/inner/get-by-username")
|
||||
Result<UserAuthRespDTO> getUserByUserName(@RequestParam("userAccount") String userAccount);
|
||||
|
||||
@GetMapping("/inner/get-by-userid")
|
||||
public Result<UserAuthRespDTO> getUserById(@RequestParam("userId") String userid);
|
||||
@GetMapping("/inner/get-by-username")
|
||||
Result<UserAuthRespDTO> getUserByUserName(@RequestParam("userAccount") String userAccount);
|
||||
|
||||
@GetMapping("/inner/get-by-userid")
|
||||
public Result<UserAuthRespDTO> getUserById(@RequestParam("userId") String userid);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package cn.meowrain.aioj.backend.auth.common.constants;
|
||||
|
||||
public class RedisKeyConstants {
|
||||
public static String REFRESH_TOKEN_KEY_PREFIX = "refresh_token:%s";
|
||||
|
||||
public static String REFRESH_TOKEN_KEY_PREFIX = "refresh_token:%s";
|
||||
|
||||
}
|
||||
|
||||
@@ -5,16 +5,18 @@ import lombok.RequiredArgsConstructor;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public enum ChainMarkEnums {
|
||||
/**
|
||||
* 用户登录请求验证
|
||||
*/
|
||||
USER_LOGIN_REQ_PARAM_VERIFY("USER_LOGIN_REQ_PARAM_VERIFY");
|
||||
|
||||
@Getter
|
||||
private final String markName;
|
||||
/**
|
||||
* 用户登录请求验证
|
||||
*/
|
||||
USER_LOGIN_REQ_PARAM_VERIFY("USER_LOGIN_REQ_PARAM_VERIFY");
|
||||
|
||||
@Getter
|
||||
private final String markName;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return markName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return markName;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,33 +15,27 @@ import org.springframework.security.web.SecurityFilterChain;
|
||||
@EnableWebSecurity
|
||||
public class SecurityConfiguration {
|
||||
|
||||
@Bean
|
||||
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
|
||||
http
|
||||
.csrf(csrf -> csrf.disable())
|
||||
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
|
||||
.authorizeHttpRequests(auth -> auth
|
||||
.requestMatchers(
|
||||
"/v1/auth/**",
|
||||
"/doc.html",
|
||||
"/swagger-ui/**",
|
||||
"/swagger-resources/**",
|
||||
"/webjars/**",
|
||||
"/v3/api-docs/**",
|
||||
"/favicon.ico"
|
||||
)
|
||||
.permitAll()
|
||||
.anyRequest().authenticated());
|
||||
return http.build();
|
||||
}
|
||||
@Bean
|
||||
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
|
||||
http.csrf(csrf -> csrf.disable())
|
||||
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
|
||||
.authorizeHttpRequests(auth -> auth
|
||||
.requestMatchers("/v1/auth/**", "/doc.html", "/swagger-ui/**", "/swagger-resources/**", "/webjars/**",
|
||||
"/v3/api-docs/**", "/favicon.ico")
|
||||
.permitAll()
|
||||
.anyRequest()
|
||||
.authenticated());
|
||||
return http.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public PasswordEncoder passwordEncoder() {
|
||||
return new BCryptPasswordEncoder();
|
||||
}
|
||||
@Bean
|
||||
public PasswordEncoder passwordEncoder() {
|
||||
return new BCryptPasswordEncoder();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public AuthenticationManager authenticationManager(AuthenticationConfiguration configuration) throws Exception {
|
||||
return configuration.getAuthenticationManager();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public AuthenticationManager authenticationManager(AuthenticationConfiguration configuration) throws Exception {
|
||||
return configuration.getAuthenticationManager();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,23 +16,25 @@ import org.springframework.context.annotation.Configuration;
|
||||
@Configuration
|
||||
@EnableKnife4j
|
||||
public class SwaggerConfiguration implements ApplicationRunner {
|
||||
@Value("${server.port:8080}")
|
||||
private String serverPort;
|
||||
@Value("${server.servlet.context-path:}")
|
||||
private String contextPath;
|
||||
|
||||
@Bean
|
||||
public OpenAPI customerOpenAPI() {
|
||||
return new OpenAPI()
|
||||
.info(new Info()
|
||||
.title("AIOJ-renz微服务✨")
|
||||
.description("用户认证功能")
|
||||
.version("v1.0.0")
|
||||
.contact(new Contact().name("meowrain").email("meowrain@126.com"))
|
||||
.license(new License().name("MeowRain").url("https://meowrain.cn")));
|
||||
}
|
||||
@Override
|
||||
public void run(ApplicationArguments args) throws Exception {
|
||||
log.info("✨API Document: http://127.0.0.1:{}{}/doc.html", serverPort, contextPath);
|
||||
}
|
||||
@Value("${server.port:8080}")
|
||||
private String serverPort;
|
||||
|
||||
@Value("${server.servlet.context-path:}")
|
||||
private String contextPath;
|
||||
|
||||
@Bean
|
||||
public OpenAPI customerOpenAPI() {
|
||||
return new OpenAPI().info(new Info().title("AIOJ-renz微服务✨")
|
||||
.description("用户认证功能")
|
||||
.version("v1.0.0")
|
||||
.contact(new Contact().name("meowrain").email("meowrain@126.com"))
|
||||
.license(new License().name("MeowRain").url("https://meowrain.cn")));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(ApplicationArguments args) throws Exception {
|
||||
log.info("✨API Document: http://127.0.0.1:{}{}/doc.html", serverPort, contextPath);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -8,18 +8,22 @@ import org.springframework.stereotype.Component;
|
||||
@Data
|
||||
@ConfigurationProperties(value = JwtPropertiesConfiguration.PREFIX)
|
||||
public class JwtPropertiesConfiguration {
|
||||
public static final String PREFIX = "jwt";
|
||||
/**
|
||||
* JWT 密钥(必须 32 字节以上)
|
||||
*/
|
||||
private String secret;
|
||||
|
||||
/**
|
||||
* 过期时间(单位:毫秒)
|
||||
*/
|
||||
private long accessExpire; // access token TTL
|
||||
/**
|
||||
* 刷新令牌时间
|
||||
*/
|
||||
private long refreshExpire; // refresh token TTL
|
||||
public static final String PREFIX = "jwt";
|
||||
|
||||
/**
|
||||
* JWT 密钥(必须 32 字节以上)
|
||||
*/
|
||||
private String secret;
|
||||
|
||||
/**
|
||||
* 过期时间(单位:毫秒)
|
||||
*/
|
||||
private long accessExpire; // access token TTL
|
||||
|
||||
/**
|
||||
* 刷新令牌时间
|
||||
*/
|
||||
private long refreshExpire; // refresh token TTL
|
||||
|
||||
}
|
||||
|
||||
@@ -13,25 +13,24 @@ import org.springframework.web.bind.annotation.*;
|
||||
@RequestMapping("/v1/auth")
|
||||
public class AuthController {
|
||||
|
||||
private final AuthService authService;
|
||||
private final AuthService authService;
|
||||
|
||||
@PostMapping("/login")
|
||||
public Result<UserLoginResponseDTO> login(@RequestBody UserLoginRequestDTO userLoginRequest) {
|
||||
UserLoginResponseDTO userLoginResponse = authService.userLogin(userLoginRequest);
|
||||
return Results.success(userLoginResponse);
|
||||
@PostMapping("/login")
|
||||
public Result<UserLoginResponseDTO> login(@RequestBody UserLoginRequestDTO userLoginRequest) {
|
||||
UserLoginResponseDTO userLoginResponse = authService.userLogin(userLoginRequest);
|
||||
return Results.success(userLoginResponse);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@PostMapping("/refresh")
|
||||
public Result<UserLoginResponseDTO> refresh(@RequestParam String refreshToken) {
|
||||
return Results.success(authService.refreshToken(refreshToken));
|
||||
}
|
||||
|
||||
@PostMapping("/auth")
|
||||
public Result<String> auth(@RequestBody UserLoginRequestDTO userLoginRequest) {
|
||||
UserLoginResponseDTO userLoginResponseDTO = authService.userLogin(userLoginRequest);
|
||||
return Results.success(userLoginResponseDTO.getAccessToken());
|
||||
}
|
||||
@PostMapping("/refresh")
|
||||
public Result<UserLoginResponseDTO> refresh(@RequestParam String refreshToken) {
|
||||
return Results.success(authService.refreshToken(refreshToken));
|
||||
}
|
||||
|
||||
@PostMapping("/auth")
|
||||
public Result<String> auth(@RequestBody UserLoginRequestDTO userLoginRequest) {
|
||||
UserLoginResponseDTO userLoginResponseDTO = authService.userLogin(userLoginRequest);
|
||||
return Results.success(userLoginResponseDTO.getAccessToken());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -12,26 +12,28 @@ import org.springframework.stereotype.Component;
|
||||
@Component
|
||||
@Slf4j
|
||||
public class UserLoginRequestParamVerifyChain implements AbstractChianHandler<UserLoginRequestDTO> {
|
||||
@Override
|
||||
public void handle(UserLoginRequestDTO requestParam) {
|
||||
if (StringUtils.isAnyBlank(requestParam.getUserAccount(), requestParam.getUserPassword())) {
|
||||
throw new ClientException("参数为空", ErrorCode.PARAMS_ERROR);
|
||||
}
|
||||
if (requestParam.getUserAccount().length() < 4) {
|
||||
throw new ClientException("账号长度不小于4位", ErrorCode.PARAMS_ERROR);
|
||||
}
|
||||
if (requestParam.getUserPassword().length() < 8) {
|
||||
throw new ClientException("密码长度不小于8位", ErrorCode.PARAMS_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String mark() {
|
||||
return ChainMarkEnums.USER_LOGIN_REQ_PARAM_VERIFY.getMarkName();
|
||||
}
|
||||
@Override
|
||||
public void handle(UserLoginRequestDTO requestParam) {
|
||||
if (StringUtils.isAnyBlank(requestParam.getUserAccount(), requestParam.getUserPassword())) {
|
||||
throw new ClientException("参数为空", ErrorCode.PARAMS_ERROR);
|
||||
}
|
||||
if (requestParam.getUserAccount().length() < 4) {
|
||||
throw new ClientException("账号长度不小于4位", ErrorCode.PARAMS_ERROR);
|
||||
}
|
||||
if (requestParam.getUserPassword().length() < 8) {
|
||||
throw new ClientException("密码长度不小于8位", ErrorCode.PARAMS_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String mark() {
|
||||
return ChainMarkEnums.USER_LOGIN_REQ_PARAM_VERIFY.getMarkName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return 10;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return 10;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,4 +6,5 @@ import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class UserLoginRequestParamVerifyContext extends CommonChainContext<UserLoginRequestDTO> {
|
||||
|
||||
}
|
||||
|
||||
@@ -4,6 +4,9 @@ import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class UserLoginRequestDTO {
|
||||
private String userAccount;
|
||||
private String userPassword;
|
||||
|
||||
private String userAccount;
|
||||
|
||||
private String userPassword;
|
||||
|
||||
}
|
||||
|
||||
@@ -10,59 +10,59 @@ import java.util.Date;
|
||||
@Data
|
||||
public class UserAuthRespDTO {
|
||||
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
private Long id;
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 用户账号
|
||||
*/
|
||||
private String userAccount;
|
||||
/**
|
||||
* 用户密码
|
||||
*/
|
||||
private String userPassword;
|
||||
/**
|
||||
* 用户账号
|
||||
*/
|
||||
private String userAccount;
|
||||
|
||||
/**
|
||||
* 开放平台id
|
||||
*/
|
||||
private String unionId;
|
||||
/**
|
||||
* 用户密码
|
||||
*/
|
||||
private String userPassword;
|
||||
|
||||
/**
|
||||
* 公众号openId
|
||||
*/
|
||||
private String mpOpenId;
|
||||
/**
|
||||
* 开放平台id
|
||||
*/
|
||||
private String unionId;
|
||||
|
||||
/**
|
||||
* 用户昵称
|
||||
*/
|
||||
private String userName;
|
||||
/**
|
||||
* 公众号openId
|
||||
*/
|
||||
private String mpOpenId;
|
||||
|
||||
/**
|
||||
* 用户头像
|
||||
*/
|
||||
private String userAvatar;
|
||||
/**
|
||||
* 用户昵称
|
||||
*/
|
||||
private String userName;
|
||||
|
||||
/**
|
||||
* 用户简介
|
||||
*/
|
||||
private String userProfile;
|
||||
/**
|
||||
* 用户头像
|
||||
*/
|
||||
private String userAvatar;
|
||||
|
||||
/**
|
||||
* 用户角色:user/admin/ban
|
||||
*/
|
||||
private String userRole;
|
||||
/**
|
||||
* 用户简介
|
||||
*/
|
||||
private String userProfile;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private Date createTime;
|
||||
/**
|
||||
* 用户角色:user/admin/ban
|
||||
*/
|
||||
private String userRole;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
private Date updateTime;
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
private Date updateTime;
|
||||
|
||||
}
|
||||
|
||||
@@ -7,24 +7,28 @@ import java.util.Date;
|
||||
|
||||
@Data
|
||||
public class UserLoginResponseDTO implements Serializable {
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 用户账号
|
||||
*/
|
||||
private String userAccount;
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 开放平台id
|
||||
*/
|
||||
private String unionId;
|
||||
/**
|
||||
* 用户账号
|
||||
*/
|
||||
private String userAccount;
|
||||
|
||||
private String accessToken;
|
||||
private String refreshToken;
|
||||
private Long expire;
|
||||
/**
|
||||
* 开放平台id
|
||||
*/
|
||||
private String unionId;
|
||||
|
||||
private String accessToken;
|
||||
|
||||
private String refreshToken;
|
||||
|
||||
private Long expire;
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
}
|
||||
|
||||
@@ -7,4 +7,5 @@ import org.springframework.stereotype.Component;
|
||||
*/
|
||||
@Component
|
||||
public class JwtAuthenticationFilter {
|
||||
|
||||
}
|
||||
|
||||
@@ -4,17 +4,19 @@ import cn.meowrain.aioj.backend.auth.dto.req.UserLoginRequestDTO;
|
||||
import cn.meowrain.aioj.backend.auth.dto.resp.UserLoginResponseDTO;
|
||||
|
||||
public interface AuthService {
|
||||
/**
|
||||
* 用户登录
|
||||
* @param request {@link UserLoginRequestDTO}
|
||||
* @return {@link UserLoginResponseDTO}
|
||||
*/
|
||||
UserLoginResponseDTO userLogin(UserLoginRequestDTO request);
|
||||
|
||||
/**
|
||||
* 刷新token
|
||||
* @param refreshToken
|
||||
* @return
|
||||
*/
|
||||
UserLoginResponseDTO refreshToken(String refreshToken);
|
||||
/**
|
||||
* 用户登录
|
||||
* @param request {@link UserLoginRequestDTO}
|
||||
* @return {@link UserLoginResponseDTO}
|
||||
*/
|
||||
UserLoginResponseDTO userLogin(UserLoginRequestDTO request);
|
||||
|
||||
/**
|
||||
* 刷新token
|
||||
* @param refreshToken
|
||||
* @return
|
||||
*/
|
||||
UserLoginResponseDTO refreshToken(String refreshToken);
|
||||
|
||||
}
|
||||
|
||||
@@ -26,81 +26,84 @@ import java.util.concurrent.TimeUnit;
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
public class AuthServiceImpl implements AuthService {
|
||||
private final JwtUtil jwtUtil;
|
||||
private final UserLoginRequestParamVerifyContext userLoginRequestParamVerifyContext;
|
||||
private final UserClient userClient;
|
||||
private final StringRedisTemplate stringRedisTemplate;
|
||||
private final JwtPropertiesConfiguration jwtPropertiesConfiguration;
|
||||
|
||||
@Override
|
||||
public UserLoginResponseDTO userLogin(UserLoginRequestDTO requestParam) {
|
||||
// 1.校验
|
||||
userLoginRequestParamVerifyContext.handler(ChainMarkEnums.USER_LOGIN_REQ_PARAM_VERIFY.getMarkName(),
|
||||
requestParam);
|
||||
// 如果调用user-service失败,那么就说明是系统内部错误
|
||||
Result<UserAuthRespDTO> userResp = userClient.getUserByUserName(requestParam.getUserAccount());
|
||||
if (userResp.isFail()) {
|
||||
log.error("调用user-service返回失败:{}", userResp.getMessage());
|
||||
throw new ServiceException(ErrorCode.SYSTEM_ERROR);
|
||||
}
|
||||
UserAuthRespDTO user = userResp.getData();
|
||||
private final JwtUtil jwtUtil;
|
||||
|
||||
if (ObjectUtil.isNull(user)
|
||||
|| !BCrypt.checkpw(requestParam.getUserPassword(), user.getUserPassword())) {
|
||||
throw new ServiceException("用户不存在或者密码错误", ErrorCode.NOT_LOGIN_ERROR);
|
||||
}
|
||||
// 生成 JWT
|
||||
String accessToken = jwtUtil.generateAccessToken(user);
|
||||
String refreshToken = jwtUtil.generateRefreshToken(user.getId());
|
||||
UserLoginResponseDTO resp = new UserLoginResponseDTO();
|
||||
resp.setId(user.getId());
|
||||
resp.setUserAccount(user.getUserAccount());
|
||||
resp.setAccessToken(accessToken);
|
||||
resp.setRefreshToken(refreshToken);
|
||||
private final UserLoginRequestParamVerifyContext userLoginRequestParamVerifyContext;
|
||||
|
||||
// refresh token存入到REDIS里面
|
||||
stringRedisTemplate.opsForValue().set(
|
||||
String.format(RedisKeyConstants.REFRESH_TOKEN_KEY_PREFIX, user.getId()),
|
||||
refreshToken,
|
||||
jwtPropertiesConfiguration.getRefreshExpire(),
|
||||
TimeUnit.MILLISECONDS);
|
||||
return resp;
|
||||
}
|
||||
private final UserClient userClient;
|
||||
|
||||
/**
|
||||
* 更新access token,使用refresh token
|
||||
* @param refreshToken
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public UserLoginResponseDTO refreshToken(String refreshToken) {
|
||||
UserLoginResponseDTO userLoginResponseDTO = new UserLoginResponseDTO();
|
||||
if (!jwtUtil.isTokenValid(refreshToken)) {
|
||||
throw new RuntimeException("Refresh Token 已过期");
|
||||
}
|
||||
private final StringRedisTemplate stringRedisTemplate;
|
||||
|
||||
Long userId = Long.valueOf(jwtUtil.parseClaims(refreshToken).getSubject());
|
||||
private final JwtPropertiesConfiguration jwtPropertiesConfiguration;
|
||||
|
||||
String cacheKey = String.format(RedisKeyConstants.REFRESH_TOKEN_KEY_PREFIX, userId);
|
||||
String cacheValue = stringRedisTemplate.opsForValue().get(cacheKey);
|
||||
@Override
|
||||
public UserLoginResponseDTO userLogin(UserLoginRequestDTO requestParam) {
|
||||
// 1.校验
|
||||
userLoginRequestParamVerifyContext.handler(ChainMarkEnums.USER_LOGIN_REQ_PARAM_VERIFY.getMarkName(),
|
||||
requestParam);
|
||||
// 如果调用user-service失败,那么就说明是系统内部错误
|
||||
Result<UserAuthRespDTO> userResp = userClient.getUserByUserName(requestParam.getUserAccount());
|
||||
if (userResp.isFail()) {
|
||||
log.error("调用user-service返回失败:{}", userResp.getMessage());
|
||||
throw new ServiceException(ErrorCode.SYSTEM_ERROR);
|
||||
}
|
||||
UserAuthRespDTO user = userResp.getData();
|
||||
|
||||
if (cacheValue == null || !cacheValue.equals(refreshToken)) {
|
||||
throw new RuntimeException("Refresh Token 已失效");
|
||||
}
|
||||
if (ObjectUtil.isNull(user) || !BCrypt.checkpw(requestParam.getUserPassword(), user.getUserPassword())) {
|
||||
throw new ServiceException("用户不存在或者密码错误", ErrorCode.NOT_LOGIN_ERROR);
|
||||
}
|
||||
// 生成 JWT
|
||||
String accessToken = jwtUtil.generateAccessToken(user);
|
||||
String refreshToken = jwtUtil.generateRefreshToken(user.getId());
|
||||
UserLoginResponseDTO resp = new UserLoginResponseDTO();
|
||||
resp.setId(user.getId());
|
||||
resp.setUserAccount(user.getUserAccount());
|
||||
resp.setAccessToken(accessToken);
|
||||
resp.setRefreshToken(refreshToken);
|
||||
|
||||
// 再次签发新的 Access Token
|
||||
// 此处你需要查用户,拿 userName, role
|
||||
Result<UserAuthRespDTO> userResult = userClient.getUserById(String.valueOf(userId));
|
||||
if (userResult.isFail()) {
|
||||
log.error("通过id查找用户失败:{}", userResult.getMessage());
|
||||
throw new ServiceException(ErrorCode.SYSTEM_ERROR);
|
||||
}
|
||||
UserAuthRespDTO user = userResult.getData();
|
||||
String newAccessToken = jwtUtil.generateAccessToken(user);
|
||||
// refresh token存入到REDIS里面
|
||||
stringRedisTemplate.opsForValue()
|
||||
.set(String.format(RedisKeyConstants.REFRESH_TOKEN_KEY_PREFIX, user.getId()), refreshToken,
|
||||
jwtPropertiesConfiguration.getRefreshExpire(), TimeUnit.MILLISECONDS);
|
||||
return resp;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新access token,使用refresh token
|
||||
* @param refreshToken
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public UserLoginResponseDTO refreshToken(String refreshToken) {
|
||||
UserLoginResponseDTO userLoginResponseDTO = new UserLoginResponseDTO();
|
||||
if (!jwtUtil.isTokenValid(refreshToken)) {
|
||||
throw new RuntimeException("Refresh Token 已过期");
|
||||
}
|
||||
|
||||
Long userId = Long.valueOf(jwtUtil.parseClaims(refreshToken).getSubject());
|
||||
|
||||
String cacheKey = String.format(RedisKeyConstants.REFRESH_TOKEN_KEY_PREFIX, userId);
|
||||
String cacheValue = stringRedisTemplate.opsForValue().get(cacheKey);
|
||||
|
||||
if (cacheValue == null || !cacheValue.equals(refreshToken)) {
|
||||
throw new RuntimeException("Refresh Token 已失效");
|
||||
}
|
||||
|
||||
// 再次签发新的 Access Token
|
||||
// 此处你需要查用户,拿 userName, role
|
||||
Result<UserAuthRespDTO> userResult = userClient.getUserById(String.valueOf(userId));
|
||||
if (userResult.isFail()) {
|
||||
log.error("通过id查找用户失败:{}", userResult.getMessage());
|
||||
throw new ServiceException(ErrorCode.SYSTEM_ERROR);
|
||||
}
|
||||
UserAuthRespDTO user = userResult.getData();
|
||||
String newAccessToken = jwtUtil.generateAccessToken(user);
|
||||
|
||||
// 设置refresh token和access token
|
||||
userLoginResponseDTO.setRefreshToken(refreshToken);
|
||||
userLoginResponseDTO.setAccessToken(newAccessToken);
|
||||
return userLoginResponseDTO;
|
||||
}
|
||||
|
||||
//设置refresh token和access token
|
||||
userLoginResponseDTO.setRefreshToken(refreshToken);
|
||||
userLoginResponseDTO.setAccessToken(newAccessToken);
|
||||
return userLoginResponseDTO;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,58 +17,56 @@ import java.util.Map;
|
||||
@Component
|
||||
public class JwtUtil {
|
||||
|
||||
private final JwtPropertiesConfiguration jwtConfig;
|
||||
private final JwtPropertiesConfiguration jwtConfig;
|
||||
|
||||
private SecretKey getSigningKey() {
|
||||
return Keys.hmacShaKeyFor(jwtConfig.getSecret().getBytes());
|
||||
}
|
||||
private SecretKey getSigningKey() {
|
||||
return Keys.hmacShaKeyFor(jwtConfig.getSecret().getBytes());
|
||||
}
|
||||
|
||||
/** 生成 Access Token */
|
||||
public String generateAccessToken(UserAuthRespDTO user) {
|
||||
long now = System.currentTimeMillis();
|
||||
/** 生成 Access Token */
|
||||
public String generateAccessToken(UserAuthRespDTO user) {
|
||||
long now = System.currentTimeMillis();
|
||||
|
||||
Map<String, Object> claims = new HashMap<>();
|
||||
claims.put("userId", user.getId());
|
||||
claims.put("userName", user.getUserName());
|
||||
claims.put("role", user.getUserRole());
|
||||
Map<String, Object> claims = new HashMap<>();
|
||||
claims.put("userId", user.getId());
|
||||
claims.put("userName", user.getUserName());
|
||||
claims.put("role", user.getUserRole());
|
||||
|
||||
return Jwts.builder()
|
||||
.subject(user.getUserAccount())
|
||||
.issuedAt(new Date(now))
|
||||
.expiration(new Date(now + jwtConfig.getAccessExpire()))
|
||||
.claims(claims)
|
||||
.signWith(getSigningKey(), Jwts.SIG.HS256)
|
||||
.compact();
|
||||
}
|
||||
return Jwts.builder()
|
||||
.subject(user.getUserAccount())
|
||||
.issuedAt(new Date(now))
|
||||
.expiration(new Date(now + jwtConfig.getAccessExpire()))
|
||||
.claims(claims)
|
||||
.signWith(getSigningKey(), Jwts.SIG.HS256)
|
||||
.compact();
|
||||
}
|
||||
|
||||
/** 生成 Refresh Token(只含 userId) */
|
||||
public String generateRefreshToken(Long userId) {
|
||||
long now = System.currentTimeMillis();
|
||||
/** 生成 Refresh Token(只含 userId) */
|
||||
public String generateRefreshToken(Long userId) {
|
||||
long now = System.currentTimeMillis();
|
||||
|
||||
return Jwts.builder()
|
||||
.subject(String.valueOf(userId))
|
||||
.issuedAt(new Date(now))
|
||||
.expiration(new Date(now + jwtConfig.getRefreshExpire()))
|
||||
.signWith(getSigningKey(), Jwts.SIG.HS256)
|
||||
.compact();
|
||||
}
|
||||
return Jwts.builder()
|
||||
.subject(String.valueOf(userId))
|
||||
.issuedAt(new Date(now))
|
||||
.expiration(new Date(now + jwtConfig.getRefreshExpire()))
|
||||
.signWith(getSigningKey(), Jwts.SIG.HS256)
|
||||
.compact();
|
||||
}
|
||||
|
||||
/** 解析 Token */
|
||||
public Claims parseClaims(String token) {
|
||||
return Jwts.parser()
|
||||
.verifyWith(getSigningKey())
|
||||
.build()
|
||||
.parseSignedClaims(token)
|
||||
.getPayload();
|
||||
}
|
||||
/** 解析 Token */
|
||||
public Claims parseClaims(String token) {
|
||||
return Jwts.parser().verifyWith(getSigningKey()).build().parseSignedClaims(token).getPayload();
|
||||
}
|
||||
|
||||
/** 校验 Token 是否过期 */
|
||||
public boolean isTokenValid(String token) {
|
||||
try {
|
||||
Claims claims = parseClaims(token);
|
||||
return claims.getExpiration().after(new Date());
|
||||
}
|
||||
catch (Exception ignored) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/** 校验 Token 是否过期 */
|
||||
public boolean isTokenValid(String token) {
|
||||
try {
|
||||
Claims claims = parseClaims(token);
|
||||
return claims.getExpiration().after(new Date());
|
||||
} catch (Exception ignored) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,56 +15,47 @@ import java.time.format.DateTimeFormatter;
|
||||
@Component
|
||||
public class EnvironmentBanner implements ApplicationListener<ApplicationReadyEvent> {
|
||||
|
||||
@Value("${spring.application.name:unknown}")
|
||||
private String appName;
|
||||
@Value("${spring.application.name:unknown}")
|
||||
private String appName;
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(ApplicationReadyEvent event) {
|
||||
@Override
|
||||
public void onApplicationEvent(ApplicationReadyEvent event) {
|
||||
|
||||
Environment env = event.getApplicationContext().getEnvironment();
|
||||
Environment env = event.getApplicationContext().getEnvironment();
|
||||
|
||||
// Active profiles
|
||||
String profiles = String.join(",", env.getActiveProfiles());
|
||||
if (profiles.isEmpty()) {
|
||||
profiles = "default";
|
||||
}
|
||||
// Active profiles
|
||||
String profiles = String.join(",", env.getActiveProfiles());
|
||||
if (profiles.isEmpty()) {
|
||||
profiles = "default";
|
||||
}
|
||||
|
||||
// Port
|
||||
String port = env.getProperty("server.port", "unknown");
|
||||
// Port
|
||||
String port = env.getProperty("server.port", "unknown");
|
||||
|
||||
// JVM info
|
||||
String jvm = System.getProperty("java.version") + " (" + System.getProperty("java.vendor") + ")";
|
||||
// JVM info
|
||||
String jvm = System.getProperty("java.version") + " (" + System.getProperty("java.vendor") + ")";
|
||||
|
||||
// PID
|
||||
String pid = ManagementFactory.getRuntimeMXBean().getPid() + "";
|
||||
// PID
|
||||
String pid = ManagementFactory.getRuntimeMXBean().getPid() + "";
|
||||
|
||||
// Time
|
||||
String time = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
|
||||
// Time
|
||||
String time = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
|
||||
|
||||
// Git commit id (如果没有 git.properties,不会报错)
|
||||
String gitCommit = env.getProperty("git.commit.id.abbrev", "N/A");
|
||||
// Git commit id (如果没有 git.properties,不会报错)
|
||||
String gitCommit = env.getProperty("git.commit.id.abbrev", "N/A");
|
||||
|
||||
printBanner(appName, profiles, port, jvm, pid, time, gitCommit);
|
||||
}
|
||||
printBanner(appName, profiles, port, jvm, pid, time, gitCommit);
|
||||
}
|
||||
|
||||
private void printBanner(String appName,
|
||||
String profiles,
|
||||
String port,
|
||||
String jvm,
|
||||
String pid,
|
||||
String time,
|
||||
String gitCommit) {
|
||||
private void printBanner(String appName, String profiles, String port, String jvm, String pid, String time,
|
||||
String gitCommit) {
|
||||
|
||||
String banner = "\n" + "------------------------------------------------------------\n"
|
||||
+ " ✨AI Online Judge✨ - " + appName + "\n" + " Environment : " + profiles + "\n" + " Port : "
|
||||
+ port + "\n" + " Git Commit : " + gitCommit + "\n" + " JVM : " + jvm + "\n"
|
||||
+ " PID : " + pid + "\n" + " Started At : " + time + "\n"
|
||||
+ "------------------------------------------------------------\n";
|
||||
System.out.println(banner);
|
||||
}
|
||||
|
||||
String banner = "\n" +
|
||||
"------------------------------------------------------------\n" +
|
||||
" ✨AI Online Judge✨ - " + appName + "\n" +
|
||||
" Environment : " + profiles + "\n" +
|
||||
" Port : " + port + "\n" +
|
||||
" Git Commit : " + gitCommit + "\n" +
|
||||
" JVM : " + jvm + "\n" +
|
||||
" PID : " + pid + "\n" +
|
||||
" Started At : " + time + "\n" +
|
||||
"------------------------------------------------------------\n";
|
||||
System.out.println(banner);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package cn.meowrain.aioj.backend.framework.core.config;
|
||||
|
||||
|
||||
import cn.meowrain.aioj.backend.framework.core.exception.handler.GlobalExceptionHandler;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
||||
@@ -8,8 +7,10 @@ import org.springframework.context.annotation.Bean;
|
||||
* 注册为bean,全局异常拦截器
|
||||
*/
|
||||
public class WebAutoConfiguration {
|
||||
@Bean
|
||||
public GlobalExceptionHandler globalExceptionHandler() {
|
||||
return new GlobalExceptionHandler();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public GlobalExceptionHandler globalExceptionHandler() {
|
||||
return new GlobalExceptionHandler();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,17 +3,17 @@ package cn.meowrain.aioj.backend.framework.core.designpattern.chains;
|
||||
import org.springframework.core.Ordered;
|
||||
|
||||
public interface AbstractChianHandler<T> extends Ordered {
|
||||
/**
|
||||
* 执行责任链逻辑
|
||||
*
|
||||
* @param requestParam 责任链执行入参
|
||||
*/
|
||||
void handle(T requestParam);
|
||||
|
||||
/**
|
||||
* 责任链组件标识
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
String mark();
|
||||
/**
|
||||
* 执行责任链逻辑
|
||||
* @param requestParam 责任链执行入参
|
||||
*/
|
||||
void handle(T requestParam);
|
||||
|
||||
/**
|
||||
* 责任链组件标识
|
||||
* @return String
|
||||
*/
|
||||
String mark();
|
||||
|
||||
}
|
||||
|
||||
@@ -19,53 +19,50 @@ import java.util.stream.Collectors;
|
||||
@Component
|
||||
@Slf4j
|
||||
public class CommonChainContext<T> implements ApplicationContextAware, CommandLineRunner {
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
this.applicationContext = applicationContext;
|
||||
}
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
private final Map<String, List<AbstractChianHandler<T>>> abstractChainHandlerMap = new HashMap<>();
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
this.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
public void handler(String mark, T requestParam) {
|
||||
List<AbstractChianHandler<T>> merchantAdminAbstractChainHandlers = abstractChainHandlerMap.get(mark);
|
||||
if (merchantAdminAbstractChainHandlers == null || merchantAdminAbstractChainHandlers.isEmpty()) {
|
||||
throw new RuntimeException(String.format("[%s] Chain of Responsibility ID is undefined.", mark));
|
||||
}
|
||||
merchantAdminAbstractChainHandlers.forEach(h -> {
|
||||
h.handle(requestParam);
|
||||
});
|
||||
}
|
||||
private final Map<String, List<AbstractChianHandler<T>>> abstractChainHandlerMap = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public void run(String... args) throws Exception {
|
||||
log.info("【责任链路初始化】开始加载并分组所有处理器...");
|
||||
applicationContext.getBeansOfType(AbstractChianHandler.class)
|
||||
.values()
|
||||
.forEach(handler -> {
|
||||
// 打印当前处理器的类名和它所属的 ChainMark
|
||||
String handlerName = handler.getClass().getSimpleName();
|
||||
String mark = handler.mark();
|
||||
log.info(" -> 发现处理器:{},归属链路:{}", handlerName, mark);
|
||||
abstractChainHandlerMap
|
||||
.computeIfAbsent(handler.mark(), k -> new ArrayList<>())
|
||||
.add(handler);
|
||||
});
|
||||
public void handler(String mark, T requestParam) {
|
||||
List<AbstractChianHandler<T>> merchantAdminAbstractChainHandlers = abstractChainHandlerMap.get(mark);
|
||||
if (merchantAdminAbstractChainHandlers == null || merchantAdminAbstractChainHandlers.isEmpty()) {
|
||||
throw new RuntimeException(String.format("[%s] Chain of Responsibility ID is undefined.", mark));
|
||||
}
|
||||
merchantAdminAbstractChainHandlers.forEach(h -> {
|
||||
h.handle(requestParam);
|
||||
});
|
||||
}
|
||||
|
||||
// 步骤 2: 对每个链路中的处理器进行排序 (Sort 阶段)
|
||||
abstractChainHandlerMap.forEach((mark, handlers) -> {
|
||||
handlers.sort(Comparator.comparing(Ordered::getOrder));
|
||||
@Override
|
||||
public void run(String... args) throws Exception {
|
||||
log.info("【责任链路初始化】开始加载并分组所有处理器...");
|
||||
applicationContext.getBeansOfType(AbstractChianHandler.class).values().forEach(handler -> {
|
||||
// 打印当前处理器的类名和它所属的 ChainMark
|
||||
String handlerName = handler.getClass().getSimpleName();
|
||||
String mark = handler.mark();
|
||||
log.info(" -> 发现处理器:{},归属链路:{}", handlerName, mark);
|
||||
abstractChainHandlerMap.computeIfAbsent(handler.mark(), k -> new ArrayList<>()).add(handler);
|
||||
});
|
||||
|
||||
// 打印排序后的 Bean 列表
|
||||
String sortedList = handlers.stream()
|
||||
.map(h -> String.format("%s (Order:%d)", h.getClass().getSimpleName(), h.getOrder()))
|
||||
.collect(Collectors.joining(" -> "));
|
||||
// 步骤 2: 对每个链路中的处理器进行排序 (Sort 阶段)
|
||||
abstractChainHandlerMap.forEach((mark, handlers) -> {
|
||||
handlers.sort(Comparator.comparing(Ordered::getOrder));
|
||||
|
||||
log.info(" ✅ 链路 {} 排序完成:{}", mark, sortedList);
|
||||
});
|
||||
// 打印排序后的 Bean 列表
|
||||
String sortedList = handlers.stream()
|
||||
.map(h -> String.format("%s (Order:%d)", h.getClass().getSimpleName(), h.getOrder()))
|
||||
.collect(Collectors.joining(" -> "));
|
||||
|
||||
log.info("【责任链路初始化】所有处理器链已完全就绪。");
|
||||
}
|
||||
log.info(" ✅ 链路 {} 排序完成:{}", mark, sortedList);
|
||||
});
|
||||
|
||||
log.info("【责任链路初始化】所有处理器链已完全就绪。");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -4,14 +4,17 @@ package cn.meowrain.aioj.backend.framework.core.enums;
|
||||
* 删除枚举
|
||||
*/
|
||||
public enum DelStatusEnum {
|
||||
STATUS_NORMAL("0"),
|
||||
STATUS_DELETE("1");
|
||||
|
||||
private final String code;
|
||||
DelStatusEnum(String code) {
|
||||
this.code = code;
|
||||
}
|
||||
public String code() {
|
||||
return this.code;
|
||||
}
|
||||
STATUS_NORMAL("0"), STATUS_DELETE("1");
|
||||
|
||||
private final String code;
|
||||
|
||||
DelStatusEnum(String code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public String code() {
|
||||
return this.code;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,38 +1,35 @@
|
||||
package cn.meowrain.aioj.backend.framework.core.errorcode;
|
||||
|
||||
public enum ErrorCode implements IErrorCode {
|
||||
SUCCESS("0", "ok"),
|
||||
PARAMS_ERROR("40000", "请求参数错误"),
|
||||
NOT_LOGIN_ERROR("40100", "未登录"),
|
||||
NO_AUTH_ERROR("40101", "无权限"),
|
||||
NOT_FOUND_ERROR("40400", "请求数据不存在"),
|
||||
FORBIDDEN_ERROR("40300", "禁止访问"),
|
||||
SYSTEM_ERROR("50000", "系统内部异常"),
|
||||
OPERATION_ERROR("50001", "操作失败"),
|
||||
API_REQUEST_ERROR("50010", "接口调用失败");
|
||||
/**
|
||||
* 状态码
|
||||
*/
|
||||
|
||||
private final String code;
|
||||
SUCCESS("0", "ok"), PARAMS_ERROR("40000", "请求参数错误"), NOT_LOGIN_ERROR("40100", "未登录"), NO_AUTH_ERROR("40101", "无权限"),
|
||||
NOT_FOUND_ERROR("40400", "请求数据不存在"), FORBIDDEN_ERROR("40300", "禁止访问"), SYSTEM_ERROR("50000", "系统内部异常"),
|
||||
OPERATION_ERROR("50001", "操作失败"), API_REQUEST_ERROR("50010", "接口调用失败");
|
||||
|
||||
/**
|
||||
* 信息
|
||||
*/
|
||||
private final String message;
|
||||
/**
|
||||
* 状态码
|
||||
*/
|
||||
|
||||
ErrorCode(String code, String message) {
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
}
|
||||
private final String code;
|
||||
|
||||
@Override
|
||||
public String code() {
|
||||
return code;
|
||||
}
|
||||
/**
|
||||
* 信息
|
||||
*/
|
||||
private final String message;
|
||||
|
||||
ErrorCode(String code, String message) {
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String code() {
|
||||
return code;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String message() {
|
||||
return message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String message() {
|
||||
return message;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package cn.meowrain.aioj.backend.framework.core.errorcode;
|
||||
|
||||
public interface IErrorCode {
|
||||
String code();
|
||||
String message();
|
||||
|
||||
String code();
|
||||
|
||||
String message();
|
||||
|
||||
}
|
||||
|
||||
@@ -12,13 +12,16 @@ import java.util.Optional;
|
||||
@Getter
|
||||
|
||||
public class AbstractException extends RuntimeException {
|
||||
public final String errorCode;
|
||||
public final String errorMessage;
|
||||
|
||||
public AbstractException(String message, Throwable throwable, IErrorCode errorCode) {
|
||||
super(message);
|
||||
this.errorCode = errorCode.code();
|
||||
this.errorMessage = Optional.ofNullable(StringUtils.hasLength(message) ? message : null)
|
||||
.orElse(errorCode.message());
|
||||
}
|
||||
public final String errorCode;
|
||||
|
||||
public final String errorMessage;
|
||||
|
||||
public AbstractException(String message, Throwable throwable, IErrorCode errorCode) {
|
||||
super(message);
|
||||
this.errorCode = errorCode.code();
|
||||
this.errorMessage = Optional.ofNullable(StringUtils.hasLength(message) ? message : null)
|
||||
.orElse(errorCode.message());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -8,21 +8,22 @@ import lombok.ToString;
|
||||
* 客户端异常
|
||||
*/
|
||||
@ToString
|
||||
public class ClientException extends AbstractException{
|
||||
public ClientException(String message, Throwable throwable, IErrorCode errorCode) {
|
||||
super(message, throwable, errorCode);
|
||||
}
|
||||
public class ClientException extends AbstractException {
|
||||
|
||||
public ClientException(IErrorCode errorCode) {
|
||||
this(null, null, errorCode);
|
||||
}
|
||||
public ClientException(String message, Throwable throwable, IErrorCode errorCode) {
|
||||
super(message, throwable, errorCode);
|
||||
}
|
||||
|
||||
public ClientException(String message, IErrorCode errorCode) {
|
||||
this(message, null, errorCode);
|
||||
}
|
||||
public ClientException(IErrorCode errorCode) {
|
||||
this(null, null, errorCode);
|
||||
}
|
||||
|
||||
public ClientException(String message) {
|
||||
this(message, null, ErrorCode.PARAMS_ERROR);
|
||||
}
|
||||
public ClientException(String message, IErrorCode errorCode) {
|
||||
this(message, null, errorCode);
|
||||
}
|
||||
|
||||
public ClientException(String message) {
|
||||
this(message, null, ErrorCode.PARAMS_ERROR);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -8,20 +8,22 @@ import lombok.ToString;
|
||||
* 调用第三方服务异常
|
||||
*/
|
||||
@ToString
|
||||
public class RemoteException extends AbstractException{
|
||||
public RemoteException(IErrorCode errorCode) {
|
||||
this(null, null, errorCode);
|
||||
}
|
||||
public class RemoteException extends AbstractException {
|
||||
|
||||
public RemoteException(String message, IErrorCode errorCode) {
|
||||
this(message, null, errorCode);
|
||||
}
|
||||
public RemoteException(IErrorCode errorCode) {
|
||||
this(null, null, errorCode);
|
||||
}
|
||||
|
||||
public RemoteException(String message, Throwable throwable, IErrorCode errorCode) {
|
||||
super(message, throwable, errorCode);
|
||||
}
|
||||
public RemoteException(String message) {
|
||||
this(message, null, ErrorCode.API_REQUEST_ERROR);
|
||||
}
|
||||
public RemoteException(String message, IErrorCode errorCode) {
|
||||
this(message, null, errorCode);
|
||||
}
|
||||
|
||||
public RemoteException(String message, Throwable throwable, IErrorCode errorCode) {
|
||||
super(message, throwable, errorCode);
|
||||
}
|
||||
|
||||
public RemoteException(String message) {
|
||||
this(message, null, ErrorCode.API_REQUEST_ERROR);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -9,20 +9,21 @@ import lombok.ToString;
|
||||
*/
|
||||
@ToString
|
||||
public class ServiceException extends AbstractException {
|
||||
public ServiceException(String message, IErrorCode errorCode) {
|
||||
this(message, null, errorCode);
|
||||
}
|
||||
|
||||
public ServiceException(String message) {
|
||||
this(message, null, ErrorCode.SYSTEM_ERROR);
|
||||
}
|
||||
public ServiceException(String message, IErrorCode errorCode) {
|
||||
this(message, null, errorCode);
|
||||
}
|
||||
|
||||
public ServiceException(IErrorCode errorCode) {
|
||||
this(null, null, errorCode);
|
||||
}
|
||||
public ServiceException(String message) {
|
||||
this(message, null, ErrorCode.SYSTEM_ERROR);
|
||||
}
|
||||
|
||||
public ServiceException(String message, Throwable throwable, IErrorCode errorCode) {
|
||||
super(message, throwable, errorCode);
|
||||
}
|
||||
public ServiceException(IErrorCode errorCode) {
|
||||
this(null, null, errorCode);
|
||||
}
|
||||
|
||||
public ServiceException(String message, Throwable throwable, IErrorCode errorCode) {
|
||||
super(message, throwable, errorCode);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -20,64 +20,68 @@ import java.util.List;
|
||||
@Slf4j
|
||||
@RestControllerAdvice
|
||||
public class GlobalExceptionHandler {
|
||||
/**
|
||||
* 捕获所有参数错误,然后统一捕获并且抛出
|
||||
* @param request {@link HttpServletRequest}
|
||||
* @param ex {@link org.springframework.validation.method.MethodValidationException}
|
||||
* @return {@link Result<Void>}
|
||||
*/
|
||||
@ExceptionHandler(value = MethodArgumentNotValidException.class)
|
||||
public Result<Void> validExceptionHandler(HttpServletRequest request, MethodArgumentNotValidException ex) {
|
||||
BindingResult bindingResult = ex.getBindingResult();
|
||||
// 收集所有错误字段
|
||||
List<String> errorMessages = bindingResult.getFieldErrors().stream()
|
||||
.map(FieldError::getDefaultMessage).toList();
|
||||
String exceptionMessage = String.join(",", errorMessages);
|
||||
log.error("[{}] {} [ex] {}", request.getMethod(), getUrl(request), exceptionMessage);
|
||||
return Results.paramsValidFailure();
|
||||
}
|
||||
|
||||
/**
|
||||
* 抽象异常捕获其
|
||||
* @param request {@link HttpServletRequest}
|
||||
* @param ex {@link AbstractException}
|
||||
* @return {@link Result<Void>}
|
||||
*/
|
||||
@ExceptionHandler(value = {AbstractException.class})
|
||||
public Result<Void> abstractExceptionHandler(HttpServletRequest request,AbstractException ex ) {
|
||||
if (ex.getCause() != null) {
|
||||
log.error("[{}] {} [ex] {}", request.getMethod(), request.getRequestURL().toString(), ex, ex.getCause());
|
||||
return Results.failure(ex);
|
||||
}
|
||||
StringBuilder stackTraceBuilder = new StringBuilder();
|
||||
stackTraceBuilder.append(ex.getClass().getName()).append(": ").append(ex.getErrorMessage()).append("\n");
|
||||
StackTraceElement[] stackTrace = ex.getStackTrace();
|
||||
for (int i = 0; i < Math.min(5, stackTrace.length); i++) {
|
||||
stackTraceBuilder.append("\tat ").append(stackTrace[i]).append("\n");
|
||||
}
|
||||
log.error("[{}] {} [ex] {} \n\n{}", request.getMethod(), request.getRequestURL().toString(), ex,
|
||||
stackTraceBuilder);
|
||||
return Results.failure(ex);
|
||||
}
|
||||
/**
|
||||
* 捕获所有参数错误,然后统一捕获并且抛出
|
||||
* @param request {@link HttpServletRequest}
|
||||
* @param ex {@link org.springframework.validation.method.MethodValidationException}
|
||||
* @return {@link Result<Void>}
|
||||
*/
|
||||
@ExceptionHandler(value = MethodArgumentNotValidException.class)
|
||||
public Result<Void> validExceptionHandler(HttpServletRequest request, MethodArgumentNotValidException ex) {
|
||||
BindingResult bindingResult = ex.getBindingResult();
|
||||
// 收集所有错误字段
|
||||
List<String> errorMessages = bindingResult.getFieldErrors()
|
||||
.stream()
|
||||
.map(FieldError::getDefaultMessage)
|
||||
.toList();
|
||||
String exceptionMessage = String.join(",", errorMessages);
|
||||
log.error("[{}] {} [ex] {}", request.getMethod(), getUrl(request), exceptionMessage);
|
||||
return Results.paramsValidFailure();
|
||||
}
|
||||
|
||||
/**
|
||||
* 拦截未捕获异常
|
||||
*/
|
||||
@ExceptionHandler(value = Throwable.class)
|
||||
public Result<Void> defaultErrorHandler(HttpServletRequest request, Throwable throwable) {
|
||||
log.error("[{}] {} ", request.getMethod(), getUrl(request), throwable);
|
||||
return Results.failure();
|
||||
}
|
||||
/**
|
||||
* 抽象异常捕获其
|
||||
* @param request {@link HttpServletRequest}
|
||||
* @param ex {@link AbstractException}
|
||||
* @return {@link Result<Void>}
|
||||
*/
|
||||
@ExceptionHandler(value = { AbstractException.class })
|
||||
public Result<Void> abstractExceptionHandler(HttpServletRequest request, AbstractException ex) {
|
||||
if (ex.getCause() != null) {
|
||||
log.error("[{}] {} [ex] {}", request.getMethod(), request.getRequestURL().toString(), ex, ex.getCause());
|
||||
return Results.failure(ex);
|
||||
}
|
||||
StringBuilder stackTraceBuilder = new StringBuilder();
|
||||
stackTraceBuilder.append(ex.getClass().getName()).append(": ").append(ex.getErrorMessage()).append("\n");
|
||||
StackTraceElement[] stackTrace = ex.getStackTrace();
|
||||
for (int i = 0; i < Math.min(5, stackTrace.length); i++) {
|
||||
stackTraceBuilder.append("\tat ").append(stackTrace[i]).append("\n");
|
||||
}
|
||||
log.error("[{}] {} [ex] {} \n\n{}", request.getMethod(), request.getRequestURL().toString(), ex,
|
||||
stackTraceBuilder);
|
||||
return Results.failure(ex);
|
||||
}
|
||||
|
||||
/**
|
||||
* 拦截未捕获异常
|
||||
*/
|
||||
@ExceptionHandler(value = Throwable.class)
|
||||
public Result<Void> defaultErrorHandler(HttpServletRequest request, Throwable throwable) {
|
||||
log.error("[{}] {} ", request.getMethod(), getUrl(request), throwable);
|
||||
return Results.failure();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取请求URL
|
||||
* @param request {@link HttpServletRequest}
|
||||
* @return String
|
||||
*/
|
||||
private String getUrl(HttpServletRequest request) {
|
||||
if (!StringUtils.hasText(request.getQueryString())) {
|
||||
return request.getRequestURI();
|
||||
}
|
||||
return request.getRequestURL() + "?" + request.getQueryString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取请求URL
|
||||
* @param request {@link HttpServletRequest}
|
||||
* @return String
|
||||
*/
|
||||
private String getUrl(HttpServletRequest request) {
|
||||
if (!StringUtils.hasText(request.getQueryString())) {
|
||||
return request.getRequestURI();
|
||||
}
|
||||
return request.getRequestURL() + "?" + request.getQueryString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,39 +12,44 @@ import java.io.Serializable;
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class Result<T> implements Serializable {
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
/**
|
||||
* 正确返回码
|
||||
* */
|
||||
public static final String SUCCESS_CODE = "0";
|
||||
/**
|
||||
* 响应码
|
||||
*/
|
||||
private String code;
|
||||
/**
|
||||
* 响应数据
|
||||
*/
|
||||
private T data;
|
||||
/**
|
||||
* 响应信息
|
||||
*/
|
||||
private String message;
|
||||
|
||||
/**
|
||||
* 返回是否是正确响应
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public boolean isSuccess() {
|
||||
return SUCCESS_CODE.equals(code);
|
||||
}
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 正确返回码
|
||||
*/
|
||||
public static final String SUCCESS_CODE = "0";
|
||||
|
||||
/**
|
||||
* 响应码
|
||||
*/
|
||||
private String code;
|
||||
|
||||
/**
|
||||
* 响应数据
|
||||
*/
|
||||
private T data;
|
||||
|
||||
/**
|
||||
* 响应信息
|
||||
*/
|
||||
private String message;
|
||||
|
||||
/**
|
||||
* 返回是否是正确响应
|
||||
* @return boolean
|
||||
*/
|
||||
public boolean isSuccess() {
|
||||
return SUCCESS_CODE.equals(code);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回是否是错误响应
|
||||
* @return boolean
|
||||
*/
|
||||
public boolean isFail() {
|
||||
return !isSuccess();
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回是否是错误响应
|
||||
* @return boolean
|
||||
*/
|
||||
public boolean isFail() {
|
||||
return !isSuccess();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package cn.meowrain.aioj.backend.framework.core.web;
|
||||
|
||||
|
||||
import cn.meowrain.aioj.backend.framework.core.errorcode.ErrorCode;
|
||||
import cn.meowrain.aioj.backend.framework.core.exception.AbstractException;
|
||||
|
||||
@@ -10,70 +9,61 @@ import java.util.Optional;
|
||||
* 构建响应的工具类
|
||||
*/
|
||||
public final class Results {
|
||||
/**
|
||||
* 成功响应,不返回任何信息
|
||||
*
|
||||
* @return {@link Result<Void>}
|
||||
*/
|
||||
public static Result<Void> success() {
|
||||
return new Result<Void>().setCode(Result.SUCCESS_CODE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 成功响应 返回数据
|
||||
*
|
||||
* @param data 返回的响应体信息
|
||||
* @param <T> 泛型
|
||||
* @return {@link Result<T>}
|
||||
*/
|
||||
public static <T> Result<T> success(T data) {
|
||||
return new Result<T>().setCode(Result.SUCCESS_CODE)
|
||||
.setData(data);
|
||||
}
|
||||
/**
|
||||
* 成功响应,不返回任何信息
|
||||
* @return {@link Result<Void>}
|
||||
*/
|
||||
public static Result<Void> success() {
|
||||
return new Result<Void>().setCode(Result.SUCCESS_CODE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 客户端请求参数错误
|
||||
* @return {@link Result<Void>}
|
||||
*/
|
||||
public static Result<Void> paramsValidFailure() {
|
||||
return failure(ErrorCode.PARAMS_ERROR.code(), ErrorCode.PARAMS_ERROR.message());
|
||||
}
|
||||
/**
|
||||
* 成功响应 返回数据
|
||||
* @param data 返回的响应体信息
|
||||
* @param <T> 泛型
|
||||
* @return {@link Result<T>}
|
||||
*/
|
||||
public static <T> Result<T> success(T data) {
|
||||
return new Result<T>().setCode(Result.SUCCESS_CODE).setData(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 服务端错误默认响应 -- <b>内部错误</b>
|
||||
*
|
||||
* @return {@link Result<Void>}
|
||||
*/
|
||||
public static Result<Void> failure() {
|
||||
return new Result<Void>().setCode(ErrorCode.SYSTEM_ERROR.code())
|
||||
.setMessage(ErrorCode.SYSTEM_ERROR.message());
|
||||
}
|
||||
/**
|
||||
* 客户端请求参数错误
|
||||
* @return {@link Result<Void>}
|
||||
*/
|
||||
public static Result<Void> paramsValidFailure() {
|
||||
return failure(ErrorCode.PARAMS_ERROR.code(), ErrorCode.PARAMS_ERROR.message());
|
||||
}
|
||||
|
||||
/**
|
||||
* 服务端错误响应 - 接收一个AbstractException,里面定义了错误码和错误信息
|
||||
*
|
||||
* @param exception {@link AbstractException}
|
||||
* @return {@link Result<Void>}
|
||||
*/
|
||||
public static Result<Void> failure(AbstractException exception) {
|
||||
String errorCode = Optional.ofNullable(exception.getErrorCode()).orElse(ErrorCode.SYSTEM_ERROR.code());
|
||||
String errorMessage = Optional.ofNullable(exception.getMessage()).orElse(ErrorCode.SYSTEM_ERROR.message());
|
||||
/**
|
||||
* 服务端错误默认响应 -- <b>内部错误</b>
|
||||
* @return {@link Result<Void>}
|
||||
*/
|
||||
public static Result<Void> failure() {
|
||||
return new Result<Void>().setCode(ErrorCode.SYSTEM_ERROR.code()).setMessage(ErrorCode.SYSTEM_ERROR.message());
|
||||
}
|
||||
|
||||
return new Result<Void>()
|
||||
.setCode(errorCode)
|
||||
.setMessage(errorMessage);
|
||||
}
|
||||
/**
|
||||
* 服务端错误响应 - 接收一个AbstractException,里面定义了错误码和错误信息
|
||||
* @param exception {@link AbstractException}
|
||||
* @return {@link Result<Void>}
|
||||
*/
|
||||
public static Result<Void> failure(AbstractException exception) {
|
||||
String errorCode = Optional.ofNullable(exception.getErrorCode()).orElse(ErrorCode.SYSTEM_ERROR.code());
|
||||
String errorMessage = Optional.ofNullable(exception.getMessage()).orElse(ErrorCode.SYSTEM_ERROR.message());
|
||||
|
||||
return new Result<Void>().setCode(errorCode).setMessage(errorMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 服务端错误响应,自定义错误码和错误信息
|
||||
* @param errorCode {@link String}
|
||||
* @param errorMessage {@link String}
|
||||
* @return {@link Result<Void>}
|
||||
*/
|
||||
public static Result<Void> failure(String errorCode, String errorMessage) {
|
||||
return new Result<Void>().setCode(errorCode).setMessage(errorMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 服务端错误响应,自定义错误码和错误信息
|
||||
*
|
||||
* @param errorCode {@link String}
|
||||
* @param errorMessage {@link String}
|
||||
* @return {@link Result<Void>}
|
||||
*/
|
||||
public static Result<Void> failure(String errorCode, String errorMessage) {
|
||||
return new Result<Void>()
|
||||
.setCode(errorCode)
|
||||
.setMessage(errorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,19 +14,23 @@ import org.springframework.scheduling.annotation.EnableAsync;
|
||||
@EnableConfigurationProperties(AIOJLogPropertiesConfiguration.class)
|
||||
@ConditionalOnProperty(value = "aioj.log.enabled", matchIfMissing = true)
|
||||
public class LogAutoConfiguration {
|
||||
/**
|
||||
* 创建并返回SysLogListener的Bean实例
|
||||
*/
|
||||
@Bean
|
||||
public SysLogListener sysLogListener(AIOJLogPropertiesConfiguration logProperties, RemoteLogService remoteLogService) {
|
||||
return new SysLogListener(remoteLogService, logProperties);
|
||||
}
|
||||
/**
|
||||
* 返回切面类实例
|
||||
* @return {@link SysLogAspect}
|
||||
*/
|
||||
@Bean
|
||||
public SysLogAspect sysLogAspect() {
|
||||
return new SysLogAspect();
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建并返回SysLogListener的Bean实例
|
||||
*/
|
||||
@Bean
|
||||
public SysLogListener sysLogListener(AIOJLogPropertiesConfiguration logProperties,
|
||||
RemoteLogService remoteLogService) {
|
||||
return new SysLogListener(remoteLogService, logProperties);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回切面类实例
|
||||
* @return {@link SysLogAspect}
|
||||
*/
|
||||
@Bean
|
||||
public SysLogAspect sysLogAspect() {
|
||||
return new SysLogAspect();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -9,15 +9,17 @@ import java.lang.annotation.*;
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface SysLog {
|
||||
/**
|
||||
* 描述
|
||||
* @return {@link String}
|
||||
*/
|
||||
String value() default "";
|
||||
|
||||
/**
|
||||
* Spel表达式
|
||||
* @return 日志描述
|
||||
*/
|
||||
String expression() default "";
|
||||
/**
|
||||
* 描述
|
||||
* @return {@link String}
|
||||
*/
|
||||
String value() default "";
|
||||
|
||||
/**
|
||||
* Spel表达式
|
||||
* @return 日志描述
|
||||
*/
|
||||
String expression() default "";
|
||||
|
||||
}
|
||||
|
||||
@@ -15,17 +15,18 @@ import org.springframework.expression.EvaluationContext;
|
||||
@RequiredArgsConstructor
|
||||
public class SysLogAspect {
|
||||
|
||||
@Around("@annotation(sysLog)")
|
||||
public Object around(ProceedingJoinPoint joinPoint,SysLog sysLog) throws Throwable {
|
||||
String strClassName = joinPoint.getTarget().getClass().getName();
|
||||
String strMethodName = joinPoint.getSignature().getName();
|
||||
log.debug("[类名]:{},[方法]:{}", strClassName, strMethodName);
|
||||
String value = sysLog.value();
|
||||
String expression = sysLog.expression();
|
||||
if(StrUtil.isNotBlank(expression)) {
|
||||
// 解析SPEL
|
||||
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
|
||||
EvaluationContext context = SysLogUtils.getContext(point.getArgs(), signature.getMethod());
|
||||
}
|
||||
}
|
||||
@Around("@annotation(sysLog)")
|
||||
public Object around(ProceedingJoinPoint joinPoint, SysLog sysLog) throws Throwable {
|
||||
String strClassName = joinPoint.getTarget().getClass().getName();
|
||||
String strMethodName = joinPoint.getSignature().getName();
|
||||
log.debug("[类名]:{},[方法]:{}", strClassName, strMethodName);
|
||||
String value = sysLog.value();
|
||||
String expression = sysLog.expression();
|
||||
if (StrUtil.isNotBlank(expression)) {
|
||||
// 解析SPEL
|
||||
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
|
||||
EvaluationContext context = SysLogUtils.getContext(point.getArgs(), signature.getMethod());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -8,14 +8,17 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
@Setter
|
||||
@ConfigurationProperties(AIOJLogPropertiesConfiguration.PREFIX)
|
||||
public class AIOJLogPropertiesConfiguration {
|
||||
public static final String PREFIX = "aioj.log";
|
||||
/**
|
||||
* 开启日志记录
|
||||
*/
|
||||
private boolean enabled = true;
|
||||
|
||||
/**
|
||||
* 请求报文最大存储长度
|
||||
*/
|
||||
private Integer maxLength = 20000;
|
||||
public static final String PREFIX = "aioj.log";
|
||||
|
||||
/**
|
||||
* 开启日志记录
|
||||
*/
|
||||
private boolean enabled = true;
|
||||
|
||||
/**
|
||||
* 请求报文最大存储长度
|
||||
*/
|
||||
private Integer maxLength = 20000;
|
||||
|
||||
}
|
||||
|
||||
@@ -12,81 +12,82 @@ import java.time.LocalDateTime;
|
||||
@Data
|
||||
public class SysLog implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 编号
|
||||
*/
|
||||
private Long id;
|
||||
/**
|
||||
* 编号
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 日志类型
|
||||
*/
|
||||
private String logType;
|
||||
/**
|
||||
* 日志类型
|
||||
*/
|
||||
private String logType;
|
||||
|
||||
/**
|
||||
* 日志标题
|
||||
*/
|
||||
private String title;
|
||||
/**
|
||||
* 日志标题
|
||||
*/
|
||||
private String title;
|
||||
|
||||
/**
|
||||
* 创建者
|
||||
*/
|
||||
private String createBy;
|
||||
/**
|
||||
* 创建者
|
||||
*/
|
||||
private String createBy;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private LocalDateTime createTime;
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private LocalDateTime createTime;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
private LocalDateTime updateTime;
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
/**
|
||||
* 操作IP地址
|
||||
*/
|
||||
private String remoteAddr;
|
||||
/**
|
||||
* 操作IP地址
|
||||
*/
|
||||
private String remoteAddr;
|
||||
|
||||
/**
|
||||
* 用户代理
|
||||
*/
|
||||
private String userAgent;
|
||||
/**
|
||||
* 用户代理
|
||||
*/
|
||||
private String userAgent;
|
||||
|
||||
/**
|
||||
* 请求URI
|
||||
*/
|
||||
private String requestUri;
|
||||
/**
|
||||
* 请求URI
|
||||
*/
|
||||
private String requestUri;
|
||||
|
||||
/**
|
||||
* 操作方式
|
||||
*/
|
||||
private String method;
|
||||
/**
|
||||
* 操作方式
|
||||
*/
|
||||
private String method;
|
||||
|
||||
/**
|
||||
* 操作提交的数据
|
||||
*/
|
||||
private String params;
|
||||
/**
|
||||
* 操作提交的数据
|
||||
*/
|
||||
private String params;
|
||||
|
||||
/**
|
||||
* 执行时间
|
||||
*/
|
||||
private Long time;
|
||||
/**
|
||||
* 执行时间
|
||||
*/
|
||||
private Long time;
|
||||
|
||||
/**
|
||||
* 异常信息
|
||||
*/
|
||||
private String exception;
|
||||
/**
|
||||
* 异常信息
|
||||
*/
|
||||
private String exception;
|
||||
|
||||
/**
|
||||
* 服务ID
|
||||
*/
|
||||
private String serviceId;
|
||||
/**
|
||||
* 服务ID
|
||||
*/
|
||||
private String serviceId;
|
||||
|
||||
/**
|
||||
* 删除标记
|
||||
*/
|
||||
private String delFlag;
|
||||
|
||||
/**
|
||||
* 删除标记
|
||||
*/
|
||||
private String delFlag;
|
||||
}
|
||||
|
||||
@@ -9,12 +9,15 @@ import java.io.Serial;
|
||||
* 系统日志事件类
|
||||
*/
|
||||
public class SysLogEvent extends ApplicationEvent {
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
/**
|
||||
* 构造方法,根据源SysLog对象创建SysLogEvent
|
||||
*/
|
||||
public SysLogEvent(SysLog source) {
|
||||
super(source);
|
||||
}
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 构造方法,根据源SysLog对象创建SysLogEvent
|
||||
*/
|
||||
public SysLogEvent(SysLog source) {
|
||||
super(source);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -13,12 +13,12 @@ import java.io.Serializable;
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class SysLogEventSource extends SysLogEvent implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 参数重写成object
|
||||
*/
|
||||
private Object body;
|
||||
/**
|
||||
* 参数重写成object
|
||||
*/
|
||||
private Object body;
|
||||
|
||||
}
|
||||
|
||||
@@ -13,24 +13,27 @@ import org.springframework.scheduling.annotation.Async;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class SysLogListener implements InitializingBean {
|
||||
private final static ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
private final RemoteLogService remoteLogService;
|
||||
private final static ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
private final AIOJLogPropertiesConfiguration logProperties;
|
||||
private final RemoteLogService remoteLogService;
|
||||
|
||||
@SneakyThrows
|
||||
@Async
|
||||
@Order
|
||||
@EventListener(SysLogEvent.class)
|
||||
public void saveLog(SysLogEvent sysLogEvent){
|
||||
SysLogEventSource source = (SysLogEventSource) sysLogEvent.getSource();
|
||||
SysLog sysLog = new SysLog();
|
||||
BeanUtils.copyProperties(source, sysLog);
|
||||
private final AIOJLogPropertiesConfiguration logProperties;
|
||||
|
||||
}
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
@SneakyThrows
|
||||
@Async
|
||||
@Order
|
||||
@EventListener(SysLogEvent.class)
|
||||
public void saveLog(SysLogEvent sysLogEvent) {
|
||||
SysLogEventSource source = (SysLogEventSource) sysLogEvent.getSource();
|
||||
SysLog sysLog = new SysLog();
|
||||
BeanUtils.copyProperties(source, sysLog);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,13 +6,15 @@ import org.springframework.core.Ordered;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
|
||||
public class ApplicationLoggerInitializer implements EnvironmentPostProcessor, Ordered {
|
||||
@Override
|
||||
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
|
||||
|
||||
}
|
||||
@Override
|
||||
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return Ordered.LOWEST_PRECEDENCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return Ordered.LOWEST_PRECEDENCE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,9 @@ package cn.meowrain.aioj.backend.framework.log.utils;
|
||||
import cn.meowrain.aioj.backend.framework.log.event.SysLogEventSource;
|
||||
|
||||
public final class SysLogUtils {
|
||||
public static SysLogEventSource getSysLog() {
|
||||
|
||||
}
|
||||
public static SysLogEventSource getSysLog() {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -9,19 +9,19 @@ import org.springframework.context.annotation.Configuration;
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
public class MybatisPlusAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
public MybatisPlusInterceptor mybatisPlusInterceptor() {
|
||||
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
|
||||
interceptor.addInnerInterceptor(new PaginationInterceptor());
|
||||
return interceptor;
|
||||
}
|
||||
@Bean
|
||||
public MybatisPlusInterceptor mybatisPlusInterceptor() {
|
||||
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
|
||||
interceptor.addInnerInterceptor(new PaginationInterceptor());
|
||||
return interceptor;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建并返回MybatisPlusMetaObjectHandler实例,用于审计字段自动填充
|
||||
*/
|
||||
@Bean
|
||||
public MybatisPlusMetaObjectHandler mybatisPlusMetaObjectHandler() {
|
||||
return new MybatisPlusMetaObjectHandler();
|
||||
}
|
||||
/**
|
||||
* 创建并返回MybatisPlusMetaObjectHandler实例,用于审计字段自动填充
|
||||
*/
|
||||
@Bean
|
||||
public MybatisPlusMetaObjectHandler mybatisPlusMetaObjectHandler() {
|
||||
return new MybatisPlusMetaObjectHandler();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -11,38 +11,41 @@ import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 基础实体抽象类,包含通用实体字段
|
||||
* 基础实体抽象类,包含通用实体字段
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class BaseEntity implements Serializable {
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
/**
|
||||
* 创建者
|
||||
*/
|
||||
@Schema(description = "创建人")
|
||||
@TableField(fill = FieldFill.INSERT)
|
||||
private String createBy;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@Schema(description = "创建时间")
|
||||
@TableField(fill = FieldFill.INSERT)
|
||||
private LocalDateTime createTime;
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 更新者
|
||||
*/
|
||||
@Schema(description = "更新人")
|
||||
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||
private String updateBy;
|
||||
/**
|
||||
* 创建者
|
||||
*/
|
||||
@Schema(description = "创建人")
|
||||
@TableField(fill = FieldFill.INSERT)
|
||||
private String createBy;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@Schema(description = "创建时间")
|
||||
@TableField(fill = FieldFill.INSERT)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
/**
|
||||
* 更新者
|
||||
*/
|
||||
@Schema(description = "更新人")
|
||||
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||
private String updateBy;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
@Schema(description = "更新时间")
|
||||
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
@Schema(description = "更新时间")
|
||||
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||
private LocalDateTime updateTime;
|
||||
}
|
||||
|
||||
@@ -17,54 +17,56 @@ import java.util.Optional;
|
||||
*/
|
||||
@Slf4j
|
||||
public class MybatisPlusMetaObjectHandler implements MetaObjectHandler {
|
||||
@Override
|
||||
public void insertFill(MetaObject metaObject) {
|
||||
log.debug("mybatis plus start insert fill ....");
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
|
||||
fillValIfNullByName("createTime", now, metaObject, true);
|
||||
fillValIfNullByName("updateTime", now, metaObject, true);
|
||||
fillValIfNullByName("createBy", getUserName(), metaObject, true);
|
||||
fillValIfNullByName("updateBy", getUserName(), metaObject, true);
|
||||
@Override
|
||||
public void insertFill(MetaObject metaObject) {
|
||||
log.debug("mybatis plus start insert fill ....");
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
|
||||
// 删除标记自动填充
|
||||
fillValIfNullByName("delFlag", DelStatusEnum.STATUS_NORMAL.code(), metaObject, true);
|
||||
}
|
||||
fillValIfNullByName("createTime", now, metaObject, true);
|
||||
fillValIfNullByName("updateTime", now, metaObject, true);
|
||||
fillValIfNullByName("createBy", getUserName(), metaObject, true);
|
||||
fillValIfNullByName("updateBy", getUserName(), metaObject, true);
|
||||
|
||||
@Override
|
||||
public void updateFill(MetaObject metaObject) {
|
||||
log.debug("mybatis plus start update fill ....");
|
||||
fillValIfNullByName("updateTime", LocalDateTime.now(), metaObject, true);
|
||||
fillValIfNullByName("updateBy", getUserName(), metaObject, true);
|
||||
}
|
||||
// 删除标记自动填充
|
||||
fillValIfNullByName("delFlag", DelStatusEnum.STATUS_NORMAL.code(), metaObject, true);
|
||||
}
|
||||
|
||||
private void fillValIfNullByName(String fieldName, Object fieldVal, MetaObject metaObject, boolean isCover) {
|
||||
//如果填充值为空
|
||||
if (fieldVal == null) {
|
||||
return;
|
||||
}
|
||||
// 没有 set 方法
|
||||
if (!metaObject.hasSetter(fieldName)) {
|
||||
return;
|
||||
}
|
||||
// field 类型相同时设置
|
||||
Class<?> getterType = metaObject.getGetterType(fieldName);
|
||||
if (ClassUtils.isAssignableValue(getterType, fieldVal)) {
|
||||
metaObject.setValue(fieldName, fieldVal);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void updateFill(MetaObject metaObject) {
|
||||
log.debug("mybatis plus start update fill ....");
|
||||
fillValIfNullByName("updateTime", LocalDateTime.now(), metaObject, true);
|
||||
fillValIfNullByName("updateBy", getUserName(), metaObject, true);
|
||||
}
|
||||
|
||||
private Object getUserName() {
|
||||
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
||||
// 匿名接口直接返回
|
||||
if (authentication instanceof AnonymousAuthenticationToken) {
|
||||
return null;
|
||||
}
|
||||
private void fillValIfNullByName(String fieldName, Object fieldVal, MetaObject metaObject, boolean isCover) {
|
||||
// 如果填充值为空
|
||||
if (fieldVal == null) {
|
||||
return;
|
||||
}
|
||||
// 没有 set 方法
|
||||
if (!metaObject.hasSetter(fieldName)) {
|
||||
return;
|
||||
}
|
||||
// field 类型相同时设置
|
||||
Class<?> getterType = metaObject.getGetterType(fieldName);
|
||||
if (ClassUtils.isAssignableValue(getterType, fieldVal)) {
|
||||
metaObject.setValue(fieldName, fieldVal);
|
||||
}
|
||||
}
|
||||
|
||||
if (Optional.ofNullable(authentication).isPresent()) {
|
||||
return authentication.getName();
|
||||
}
|
||||
private Object getUserName() {
|
||||
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
||||
// 匿名接口直接返回
|
||||
if (authentication instanceof AnonymousAuthenticationToken) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (Optional.ofNullable(authentication).isPresent()) {
|
||||
return authentication.getName();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package cn.meowrain.backend.common.mybaits.plugins;
|
||||
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.DbType;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.core.toolkit.ParameterUtils;
|
||||
@@ -16,47 +15,49 @@ import org.apache.ibatis.session.ResultHandler;
|
||||
import org.apache.ibatis.session.RowBounds;
|
||||
|
||||
/**
|
||||
* * 分页拦截器实现类,用于处理分页查询逻辑
|
||||
* * <p>
|
||||
* * 分页拦截器实现类,用于处理分页查询逻辑 *
|
||||
* <p>
|
||||
* * 当分页大小小于0时自动设置为0,防止全表查询
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class PaginationInterceptor extends PaginationInnerInterceptor {
|
||||
/**
|
||||
* 数据库类型
|
||||
* <p>
|
||||
* 查看 {@link #findIDialect(Executor)} 逻辑
|
||||
*/
|
||||
private DbType dbType;
|
||||
|
||||
/**
|
||||
* 方言实现类
|
||||
* <p>
|
||||
* 查看 {@link #findIDialect(Executor)} 逻辑
|
||||
*/
|
||||
private IDialect dialect;
|
||||
/**
|
||||
* 数据库类型
|
||||
* <p>
|
||||
* 查看 {@link #findIDialect(Executor)} 逻辑
|
||||
*/
|
||||
private DbType dbType;
|
||||
|
||||
/**
|
||||
* 方言实现类
|
||||
* <p>
|
||||
* 查看 {@link #findIDialect(Executor)} 逻辑
|
||||
*/
|
||||
private IDialect dialect;
|
||||
|
||||
public PaginationInterceptor(DbType dbType) {
|
||||
this.dbType = dbType;
|
||||
}
|
||||
public PaginationInterceptor(DbType dbType) {
|
||||
this.dbType = dbType;
|
||||
}
|
||||
|
||||
public PaginationInterceptor(IDialect dialect) {
|
||||
this.dialect = dialect;
|
||||
}
|
||||
public PaginationInterceptor(IDialect dialect) {
|
||||
this.dialect = dialect;
|
||||
}
|
||||
|
||||
/**
|
||||
* 在执行查询前处理分页参数
|
||||
*/
|
||||
@Override
|
||||
public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds,
|
||||
ResultHandler resultHandler, BoundSql boundSql) {
|
||||
IPage<?> page = ParameterUtils.findPage(parameter).orElse(null);
|
||||
// size 小于 0 直接设置为 0 , 即不查询任何数据
|
||||
if (null != page && page.getSize() < 0) {
|
||||
page.setSize(0);
|
||||
}
|
||||
super.beforeQuery(executor, ms, page, rowBounds, resultHandler, boundSql);
|
||||
}
|
||||
|
||||
/**
|
||||
* 在执行查询前处理分页参数
|
||||
*/
|
||||
@Override
|
||||
public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
|
||||
IPage<?> page = ParameterUtils.findPage(parameter).orElse(null);
|
||||
// size 小于 0 直接设置为 0 , 即不查询任何数据
|
||||
if (null != page && page.getSize() < 0) {
|
||||
page.setSize(0);
|
||||
}
|
||||
super.beforeQuery(executor, ms, page, rowBounds, resultHandler, boundSql);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,10 +5,12 @@ import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
|
||||
@EnableConfigurationProperties(value = {GatewayPropertiesConfiguration.class})
|
||||
@EnableConfigurationProperties(value = { GatewayPropertiesConfiguration.class })
|
||||
@SpringBootApplication
|
||||
public class AIOJGatewayApplication {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(AIOJGatewayApplication.class, args);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(AIOJGatewayApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -12,57 +12,49 @@ import java.util.List;
|
||||
/**
|
||||
* 全局 CORS 配置(WebFlux 环境使用 CorsWebFilter)
|
||||
*
|
||||
* WebFlux 不使用 Spring MVC 的 CorsFilter,
|
||||
* 而是使用专门的 CorsWebFilter 处理跨域。
|
||||
* WebFlux 不使用 Spring MVC 的 CorsFilter, 而是使用专门的 CorsWebFilter 处理跨域。
|
||||
*
|
||||
* 此配置实现了:
|
||||
* - 允许任意域名访问(AllowedOriginPatterns = "*")
|
||||
* - 允许所有请求方法(GET、POST、PUT...)
|
||||
* - 允许所有请求头
|
||||
* - 允许跨域携带 Cookie(AllowCredentials)
|
||||
* - 对所有路径生效(/**)
|
||||
* 此配置实现了: - 允许任意域名访问(AllowedOriginPatterns = "*") - 允许所有请求方法(GET、POST、PUT...) - 允许所有请求头 -
|
||||
* 允许跨域携带 Cookie(AllowCredentials) - 对所有路径生效(/**)
|
||||
*/
|
||||
@Configuration
|
||||
public class CorsConfig {
|
||||
|
||||
/**
|
||||
* 注册全局 CORS 过滤器
|
||||
*
|
||||
* @return CorsWebFilter 跨域过滤器
|
||||
*/
|
||||
@Bean
|
||||
public CorsWebFilter corsWebFilter() {
|
||||
/**
|
||||
* 注册全局 CORS 过滤器
|
||||
* @return CorsWebFilter 跨域过滤器
|
||||
*/
|
||||
@Bean
|
||||
public CorsWebFilter corsWebFilter() {
|
||||
|
||||
// 创建跨域配置对象
|
||||
CorsConfiguration corsConfiguration = new CorsConfiguration();
|
||||
// 创建跨域配置对象
|
||||
CorsConfiguration corsConfiguration = new CorsConfiguration();
|
||||
|
||||
// 允许所有请求方式:GET、POST、PUT、DELETE、OPTIONS...
|
||||
corsConfiguration.addAllowedMethod("*");
|
||||
// 允许所有请求方式:GET、POST、PUT、DELETE、OPTIONS...
|
||||
corsConfiguration.addAllowedMethod("*");
|
||||
|
||||
// 是否允许携带 Cookie 信息。跨域默认不允许,需要显式开启
|
||||
corsConfiguration.setAllowCredentials(true);
|
||||
// 是否允许携带 Cookie 信息。跨域默认不允许,需要显式开启
|
||||
corsConfiguration.setAllowCredentials(true);
|
||||
|
||||
/**
|
||||
* 允许跨域的来源域名
|
||||
* 使用 setAllowedOriginPatterns("*") 是 WebFlux 推荐方式,
|
||||
* 因为 setAllowedOrigins("*") 在 allowCredentials=true 时会被拦截。
|
||||
*/
|
||||
corsConfiguration.setAllowedOriginPatterns(List.of("*"));
|
||||
/**
|
||||
* 允许跨域的来源域名 使用 setAllowedOriginPatterns("*") 是 WebFlux 推荐方式, 因为
|
||||
* setAllowedOrigins("*") 在 allowCredentials=true 时会被拦截。
|
||||
*/
|
||||
corsConfiguration.setAllowedOriginPatterns(List.of("*"));
|
||||
|
||||
// 允许所有请求头,例如 Authorization、Content-Type 等
|
||||
corsConfiguration.addAllowedHeader("*");
|
||||
// 允许所有请求头,例如 Authorization、Content-Type 等
|
||||
corsConfiguration.addAllowedHeader("*");
|
||||
|
||||
/**
|
||||
* 基于 URL 的跨域配置源,
|
||||
* PathPatternParser 用于解析路径模式(更高性能)
|
||||
*/
|
||||
UrlBasedCorsConfigurationSource source =
|
||||
new UrlBasedCorsConfigurationSource(new PathPatternParser());
|
||||
/**
|
||||
* 基于 URL 的跨域配置源, PathPatternParser 用于解析路径模式(更高性能)
|
||||
*/
|
||||
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(new PathPatternParser());
|
||||
|
||||
// 对所有路径应用跨域设置
|
||||
source.registerCorsConfiguration("/**", corsConfiguration);
|
||||
// 对所有路径应用跨域设置
|
||||
source.registerCorsConfiguration("/**", corsConfiguration);
|
||||
|
||||
// 创建并返回 WebFlux 专用的 CORS 过滤器
|
||||
return new CorsWebFilter(source);
|
||||
}
|
||||
|
||||
// 创建并返回 WebFlux 专用的 CORS 过滤器
|
||||
return new CorsWebFilter(source);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,9 +6,12 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
@ConfigurationProperties(prefix = GatewayPropertiesConfiguration.PREFIX)
|
||||
@Data
|
||||
public class GatewayPropertiesConfiguration {
|
||||
public static final String PREFIX = "aioj-backend-gateway";
|
||||
/*
|
||||
* 白名单放行
|
||||
* */
|
||||
private String[] whiteList;
|
||||
|
||||
public static final String PREFIX = "aioj-backend-gateway";
|
||||
|
||||
/*
|
||||
* 白名单放行
|
||||
*/
|
||||
private String[] whiteList;
|
||||
|
||||
}
|
||||
|
||||
@@ -13,15 +13,16 @@ import reactor.core.publisher.Mono;
|
||||
@RequiredArgsConstructor
|
||||
public class AuthGlobalFilter implements GlobalFilter, Ordered {
|
||||
|
||||
private final WebClient.Builder webClientBuilder;
|
||||
private final WebClient.Builder webClientBuilder;
|
||||
|
||||
@Override
|
||||
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,76 +8,76 @@ import java.time.LocalDateTime;
|
||||
@Schema(description = "日志查询对象")
|
||||
public class SysLogDTO {
|
||||
|
||||
/**
|
||||
* 编号
|
||||
*/
|
||||
private Long id;
|
||||
/**
|
||||
* 编号
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 日志类型
|
||||
*/
|
||||
@NotBlank(message = "日志类型不能为空")
|
||||
private String logType;
|
||||
/**
|
||||
* 日志类型
|
||||
*/
|
||||
@NotBlank(message = "日志类型不能为空")
|
||||
private String logType;
|
||||
|
||||
/**
|
||||
* 日志标题
|
||||
*/
|
||||
@NotBlank(message = "日志标题不能为空")
|
||||
private String title;
|
||||
/**
|
||||
* 日志标题
|
||||
*/
|
||||
@NotBlank(message = "日志标题不能为空")
|
||||
private String title;
|
||||
|
||||
/**
|
||||
* 创建者
|
||||
*/
|
||||
private String createBy;
|
||||
/**
|
||||
* 创建者
|
||||
*/
|
||||
private String createBy;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
private LocalDateTime updateTime;
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
/**
|
||||
* 操作IP地址
|
||||
*/
|
||||
private String remoteAddr;
|
||||
/**
|
||||
* 操作IP地址
|
||||
*/
|
||||
private String remoteAddr;
|
||||
|
||||
/**
|
||||
* 用户代理
|
||||
*/
|
||||
private String userAgent;
|
||||
/**
|
||||
* 用户代理
|
||||
*/
|
||||
private String userAgent;
|
||||
|
||||
/**
|
||||
* 请求URI
|
||||
*/
|
||||
private String requestUri;
|
||||
/**
|
||||
* 请求URI
|
||||
*/
|
||||
private String requestUri;
|
||||
|
||||
/**
|
||||
* 操作方式
|
||||
*/
|
||||
private String method;
|
||||
/**
|
||||
* 操作方式
|
||||
*/
|
||||
private String method;
|
||||
|
||||
/**
|
||||
* 操作提交的数据
|
||||
*/
|
||||
private String params;
|
||||
/**
|
||||
* 操作提交的数据
|
||||
*/
|
||||
private String params;
|
||||
|
||||
/**
|
||||
* 执行时间
|
||||
*/
|
||||
private Long time;
|
||||
/**
|
||||
* 执行时间
|
||||
*/
|
||||
private Long time;
|
||||
|
||||
/**
|
||||
* 异常信息
|
||||
*/
|
||||
private String exception;
|
||||
/**
|
||||
* 异常信息
|
||||
*/
|
||||
private String exception;
|
||||
|
||||
/**
|
||||
* 服务ID
|
||||
*/
|
||||
private String serviceId;
|
||||
/**
|
||||
* 服务ID
|
||||
*/
|
||||
private String serviceId;
|
||||
|
||||
/**
|
||||
* 创建时间区间 [开始时间,结束时间]
|
||||
*/
|
||||
private LocalDateTime[] createTime;
|
||||
/**
|
||||
* 创建时间区间 [开始时间,结束时间]
|
||||
*/
|
||||
private LocalDateTime[] createTime;
|
||||
|
||||
}
|
||||
|
||||
@@ -7,7 +7,9 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
@SpringBootApplication
|
||||
@MapperScan("cn.meowrain.aioj.backend.userservice.dao.mapper")
|
||||
public class UserServiceApplication {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(UserServiceApplication.class, args);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(UserServiceApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -5,20 +5,22 @@ import lombok.RequiredArgsConstructor;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public enum ChainMarkEnums {
|
||||
/**
|
||||
* 用户注册请求验证
|
||||
*/
|
||||
USER_REGISTER_REQ_PARAM_VERIFY("USER_REGISTER_REQ_PARAM_VERIFY"),
|
||||
/**
|
||||
* 用户登录请求验证
|
||||
*/
|
||||
USER_LOGIN_REQ_PARAM_VERIFY("USER_LOGIN_REQ_PARAM_VERIFY");
|
||||
|
||||
@Getter
|
||||
private final String markName;
|
||||
/**
|
||||
* 用户注册请求验证
|
||||
*/
|
||||
USER_REGISTER_REQ_PARAM_VERIFY("USER_REGISTER_REQ_PARAM_VERIFY"),
|
||||
/**
|
||||
* 用户登录请求验证
|
||||
*/
|
||||
USER_LOGIN_REQ_PARAM_VERIFY("USER_LOGIN_REQ_PARAM_VERIFY");
|
||||
|
||||
@Getter
|
||||
private final String markName;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return markName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return markName;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,10 +5,7 @@ import org.springframework.context.annotation.ComponentScans;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
@ComponentScans({
|
||||
@ComponentScan("cn.meowrain.aioj.backend.framework.core.banner")
|
||||
})
|
||||
@ComponentScans({ @ComponentScan("cn.meowrain.aioj.backend.framework.core.banner") })
|
||||
public class FrameworkConfiguration {
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -16,23 +16,25 @@ import org.springframework.context.annotation.Configuration;
|
||||
@Configuration
|
||||
@EnableKnife4j
|
||||
public class SwaggerConfiguration implements ApplicationRunner {
|
||||
@Value("${server.port:8080}")
|
||||
private String serverPort;
|
||||
@Value("${server.servlet.context-path:}")
|
||||
private String contextPath;
|
||||
|
||||
@Bean
|
||||
public OpenAPI customerOpenAPI() {
|
||||
return new OpenAPI()
|
||||
.info(new Info()
|
||||
.title("AIOJ-用户微服务✨")
|
||||
.description("用户注册,用户登录等功能")
|
||||
.version("v1.0.0")
|
||||
.contact(new Contact().name("meowrain").email("meowrain@126.com"))
|
||||
.license(new License().name("MeowRain").url("https://meowrain.cn")));
|
||||
}
|
||||
@Override
|
||||
public void run(ApplicationArguments args) throws Exception {
|
||||
log.info("✨API Document: http://127.0.0.1:{}{}/doc.html", serverPort, contextPath);
|
||||
}
|
||||
@Value("${server.port:8080}")
|
||||
private String serverPort;
|
||||
|
||||
@Value("${server.servlet.context-path:}")
|
||||
private String contextPath;
|
||||
|
||||
@Bean
|
||||
public OpenAPI customerOpenAPI() {
|
||||
return new OpenAPI().info(new Info().title("AIOJ-用户微服务✨")
|
||||
.description("用户注册,用户登录等功能")
|
||||
.version("v1.0.0")
|
||||
.contact(new Contact().name("meowrain").email("meowrain@126.com"))
|
||||
.license(new License().name("MeowRain").url("https://meowrain.cn")));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(ApplicationArguments args) throws Exception {
|
||||
log.info("✨API Document: http://127.0.0.1:{}{}/doc.html", serverPort, contextPath);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -13,25 +13,24 @@ import org.springframework.web.bind.annotation.*;
|
||||
@RequestMapping("/v1/user")
|
||||
public class UserController {
|
||||
|
||||
private final UserService userService;
|
||||
private final UserService userService;
|
||||
|
||||
@PostMapping("/register")
|
||||
public Result<Long> register(@RequestBody UserRegisterRequestDTO userRegisterRequest) {
|
||||
Long l = userService.userRegister(userRegisterRequest);
|
||||
return Results.success(l);
|
||||
}
|
||||
|
||||
@PostMapping("/register")
|
||||
public Result<Long> register(@RequestBody UserRegisterRequestDTO userRegisterRequest) {
|
||||
Long l = userService.userRegister(userRegisterRequest);
|
||||
return Results.success(l);
|
||||
}
|
||||
@GetMapping("/inner/get-by-username")
|
||||
public Result<UserAuthRespDTO> getUserByUserName(@RequestParam("userAccount") String userAccount) {
|
||||
UserAuthRespDTO userAuthDTO = userService.findAuthInfoByUserAccount(userAccount);
|
||||
return Results.success(userAuthDTO);
|
||||
}
|
||||
|
||||
@GetMapping("/inner/get-by-username")
|
||||
public Result<UserAuthRespDTO> getUserByUserName(@RequestParam("userAccount") String userAccount) {
|
||||
UserAuthRespDTO userAuthDTO = userService.findAuthInfoByUserAccount(userAccount);
|
||||
return Results.success(userAuthDTO);
|
||||
}
|
||||
|
||||
@GetMapping("/inner/get-by-userid")
|
||||
public Result<UserAuthRespDTO> getUserById(@RequestParam("userId") String userid) {
|
||||
UserAuthRespDTO userAuthRespDTO = userService.findAuthInfoByUserId(userid);
|
||||
return Results.success(userAuthRespDTO);
|
||||
}
|
||||
@GetMapping("/inner/get-by-userid")
|
||||
public Result<UserAuthRespDTO> getUserById(@RequestParam("userId") String userid) {
|
||||
UserAuthRespDTO userAuthRespDTO = userService.findAuthInfoByUserId(userid);
|
||||
return Results.success(userAuthRespDTO);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -12,69 +12,70 @@ import java.util.Date;
|
||||
@Accessors(chain = true)
|
||||
public class User implements Serializable {
|
||||
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
@TableId(type = IdType.ASSIGN_ID)
|
||||
private Long id;
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
@TableId(type = IdType.ASSIGN_ID)
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 用户账号
|
||||
*/
|
||||
private String userAccount;
|
||||
/**
|
||||
* 用户账号
|
||||
*/
|
||||
private String userAccount;
|
||||
|
||||
/**
|
||||
* 用户密码
|
||||
*/
|
||||
private String userPassword;
|
||||
/**
|
||||
* 用户密码
|
||||
*/
|
||||
private String userPassword;
|
||||
|
||||
/**
|
||||
* 开放平台id
|
||||
*/
|
||||
private String unionId;
|
||||
/**
|
||||
* 开放平台id
|
||||
*/
|
||||
private String unionId;
|
||||
|
||||
/**
|
||||
* 公众号openId
|
||||
*/
|
||||
private String mpOpenId;
|
||||
/**
|
||||
* 公众号openId
|
||||
*/
|
||||
private String mpOpenId;
|
||||
|
||||
/**
|
||||
* 用户昵称
|
||||
*/
|
||||
private String userName;
|
||||
/**
|
||||
* 用户昵称
|
||||
*/
|
||||
private String userName;
|
||||
|
||||
/**
|
||||
* 用户头像
|
||||
*/
|
||||
private String userAvatar;
|
||||
/**
|
||||
* 用户头像
|
||||
*/
|
||||
private String userAvatar;
|
||||
|
||||
/**
|
||||
* 用户简介
|
||||
*/
|
||||
private String userProfile;
|
||||
/**
|
||||
* 用户简介
|
||||
*/
|
||||
private String userProfile;
|
||||
|
||||
/**
|
||||
* 用户角色:user/admin/ban
|
||||
*/
|
||||
private String userRole;
|
||||
/**
|
||||
* 用户角色:user/admin/ban
|
||||
*/
|
||||
private String userRole;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@TableField(fill = FieldFill.INSERT)
|
||||
private Date createTime;
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@TableField(fill = FieldFill.INSERT)
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
private Date updateTime;
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
private Date updateTime;
|
||||
|
||||
/**
|
||||
* 是否删除
|
||||
*/
|
||||
@TableLogic
|
||||
private Integer isDelete;
|
||||
/**
|
||||
* 是否删除
|
||||
*/
|
||||
@TableLogic
|
||||
private Integer isDelete;
|
||||
|
||||
@TableField(exist = false)
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@TableField(exist = false)
|
||||
private static final long serialVersionUID = 1L;
|
||||
}
|
||||
|
||||
@@ -4,4 +4,5 @@ import cn.meowrain.aioj.backend.userservice.dao.entity.User;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
public interface UserMapper extends BaseMapper<User> {
|
||||
|
||||
}
|
||||
|
||||
@@ -12,32 +12,34 @@ import org.springframework.stereotype.Component;
|
||||
@Component
|
||||
@Slf4j
|
||||
public class UserRegisterRequestParamVerifyChain implements AbstractChianHandler<UserRegisterRequestDTO> {
|
||||
@Override
|
||||
public void handle(UserRegisterRequestDTO requestParam) {
|
||||
// 校验参数里面用户名和密码是不是空的
|
||||
if (StringUtils.isAnyBlank(requestParam.getUserAccount(), requestParam.getUserPassword())) {
|
||||
throw new ClientException("参数为空", ErrorCode.PARAMS_ERROR);
|
||||
}
|
||||
if (requestParam.getUserAccount().length() < 4) {
|
||||
throw new ClientException("账号长度不小于4位", ErrorCode.PARAMS_ERROR);
|
||||
}
|
||||
if (requestParam.getUserPassword().length() < 8) {
|
||||
throw new ClientException("密码长度不小于8位", ErrorCode.PARAMS_ERROR);
|
||||
}
|
||||
// 密码和校验密码相同
|
||||
if (!requestParam.getUserPassword().equals(requestParam.getCheckPassword())) {
|
||||
throw new ClientException("两次输入的密码不一致", ErrorCode.PARAMS_ERROR);
|
||||
}
|
||||
|
||||
}
|
||||
@Override
|
||||
public void handle(UserRegisterRequestDTO requestParam) {
|
||||
// 校验参数里面用户名和密码是不是空的
|
||||
if (StringUtils.isAnyBlank(requestParam.getUserAccount(), requestParam.getUserPassword())) {
|
||||
throw new ClientException("参数为空", ErrorCode.PARAMS_ERROR);
|
||||
}
|
||||
if (requestParam.getUserAccount().length() < 4) {
|
||||
throw new ClientException("账号长度不小于4位", ErrorCode.PARAMS_ERROR);
|
||||
}
|
||||
if (requestParam.getUserPassword().length() < 8) {
|
||||
throw new ClientException("密码长度不小于8位", ErrorCode.PARAMS_ERROR);
|
||||
}
|
||||
// 密码和校验密码相同
|
||||
if (!requestParam.getUserPassword().equals(requestParam.getCheckPassword())) {
|
||||
throw new ClientException("两次输入的密码不一致", ErrorCode.PARAMS_ERROR);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String mark() {
|
||||
return ChainMarkEnums.USER_REGISTER_REQ_PARAM_VERIFY.getMarkName();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String mark() {
|
||||
return ChainMarkEnums.USER_REGISTER_REQ_PARAM_VERIFY.getMarkName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return 10;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return 10;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,4 +6,5 @@ import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class UserRegisterRequestParamVerifyContext extends CommonChainContext<UserRegisterRequestDTO> {
|
||||
|
||||
}
|
||||
|
||||
@@ -5,6 +5,9 @@ import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class UserLoginRequestDTO {
|
||||
private String userAccount;
|
||||
private String userPassword;
|
||||
|
||||
private String userAccount;
|
||||
|
||||
private String userPassword;
|
||||
|
||||
}
|
||||
|
||||
@@ -5,7 +5,11 @@ import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
public class UserRegisterRequestDTO {
|
||||
private String userAccount;
|
||||
private String userPassword;
|
||||
private String checkPassword;
|
||||
|
||||
private String userAccount;
|
||||
|
||||
private String userPassword;
|
||||
|
||||
private String checkPassword;
|
||||
|
||||
}
|
||||
|
||||
@@ -10,60 +10,59 @@ import java.util.Date;
|
||||
@Data
|
||||
public class UserAuthRespDTO {
|
||||
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
private Long id;
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 用户账号
|
||||
*/
|
||||
private String userAccount;
|
||||
/**
|
||||
* 用户密码
|
||||
*/
|
||||
private String userPassword;
|
||||
/**
|
||||
* 用户账号
|
||||
*/
|
||||
private String userAccount;
|
||||
|
||||
/**
|
||||
* 开放平台id
|
||||
*/
|
||||
private String unionId;
|
||||
/**
|
||||
* 用户密码
|
||||
*/
|
||||
private String userPassword;
|
||||
|
||||
/**
|
||||
* 公众号openId
|
||||
*/
|
||||
private String mpOpenId;
|
||||
/**
|
||||
* 开放平台id
|
||||
*/
|
||||
private String unionId;
|
||||
|
||||
/**
|
||||
* 用户昵称
|
||||
*/
|
||||
private String userName;
|
||||
/**
|
||||
* 公众号openId
|
||||
*/
|
||||
private String mpOpenId;
|
||||
|
||||
/**
|
||||
* 用户头像
|
||||
*/
|
||||
private String userAvatar;
|
||||
/**
|
||||
* 用户昵称
|
||||
*/
|
||||
private String userName;
|
||||
|
||||
/**
|
||||
* 用户简介
|
||||
*/
|
||||
private String userProfile;
|
||||
/**
|
||||
* 用户头像
|
||||
*/
|
||||
private String userAvatar;
|
||||
|
||||
/**
|
||||
* 用户角色:user/admin/ban
|
||||
*/
|
||||
private String userRole;
|
||||
/**
|
||||
* 用户简介
|
||||
*/
|
||||
private String userProfile;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
private Date updateTime;
|
||||
/**
|
||||
* 用户角色:user/admin/ban
|
||||
*/
|
||||
private String userRole;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
private Date updateTime;
|
||||
|
||||
}
|
||||
|
||||
@@ -8,68 +8,69 @@ import java.util.Date;
|
||||
|
||||
@Data
|
||||
public class UserLoginResponseDTO implements Serializable {
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
@TableId(type = IdType.ASSIGN_ID)
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 用户账号
|
||||
*/
|
||||
private String userAccount;
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
@TableId(type = IdType.ASSIGN_ID)
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 开放平台id
|
||||
*/
|
||||
private String unionId;
|
||||
/**
|
||||
* 用户账号
|
||||
*/
|
||||
private String userAccount;
|
||||
|
||||
/**
|
||||
* 公众号openId
|
||||
*/
|
||||
private String mpOpenId;
|
||||
/**
|
||||
* 开放平台id
|
||||
*/
|
||||
private String unionId;
|
||||
|
||||
/**
|
||||
* 用户昵称
|
||||
*/
|
||||
private String userName;
|
||||
/**
|
||||
* 公众号openId
|
||||
*/
|
||||
private String mpOpenId;
|
||||
|
||||
/**
|
||||
* 用户头像
|
||||
*/
|
||||
private String userAvatar;
|
||||
/**
|
||||
* 用户昵称
|
||||
*/
|
||||
private String userName;
|
||||
|
||||
/**
|
||||
* 用户简介
|
||||
*/
|
||||
private String userProfile;
|
||||
/**
|
||||
* 用户头像
|
||||
*/
|
||||
private String userAvatar;
|
||||
|
||||
/**
|
||||
* 用户角色:user/admin/ban
|
||||
*/
|
||||
private String userRole;
|
||||
/**
|
||||
* 用户简介
|
||||
*/
|
||||
private String userProfile;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private Date createTime;
|
||||
/**
|
||||
* 用户角色:user/admin/ban
|
||||
*/
|
||||
private String userRole;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
private Date updateTime;
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 是否删除
|
||||
*/
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
private Date updateTime;
|
||||
|
||||
private Integer isDelete;
|
||||
/**
|
||||
* 是否删除
|
||||
*/
|
||||
|
||||
private Integer isDelete;
|
||||
|
||||
/**
|
||||
* JWT令牌(登录成功返回)
|
||||
*/
|
||||
private String token;
|
||||
/**
|
||||
* JWT令牌(登录成功返回)
|
||||
*/
|
||||
private String token;
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
}
|
||||
|
||||
@@ -9,5 +9,7 @@ import java.io.Serializable;
|
||||
*/
|
||||
@Data
|
||||
public class UserRegisterResponseDTO implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
}
|
||||
|
||||
@@ -7,24 +7,25 @@ import cn.meowrain.aioj.backend.userservice.dto.resp.UserAuthRespDTO;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
public interface UserService extends IService<User> {
|
||||
/**
|
||||
* 用户注册
|
||||
* @param request {@link cn.meowrain.aioj.backend.userservice.dto.req.UserRegisterRequestDTO}
|
||||
* @return {@link Long}
|
||||
*/
|
||||
Long userRegister(UserRegisterRequestDTO request);
|
||||
|
||||
/**
|
||||
* 用户注册
|
||||
* @param request
|
||||
* {@link cn.meowrain.aioj.backend.userservice.dto.req.UserRegisterRequestDTO}
|
||||
* @return {@link Long}
|
||||
*/
|
||||
Long userRegister(UserRegisterRequestDTO request);
|
||||
|
||||
/**
|
||||
* 根据用户账号查找用户认证信息
|
||||
* @param userAccount
|
||||
* @return
|
||||
*/
|
||||
UserAuthRespDTO findAuthInfoByUserAccount(String userAccount);
|
||||
|
||||
/**
|
||||
* 根据用户账号查找用户认证信息
|
||||
* @param userAccount
|
||||
* @return
|
||||
*/
|
||||
UserAuthRespDTO findAuthInfoByUserAccount(String userAccount);
|
||||
/**
|
||||
* 根据用户id查找用户认证信息
|
||||
*/
|
||||
UserAuthRespDTO findAuthInfoByUserId(String userId);
|
||||
|
||||
/**
|
||||
* 根据用户id查找用户认证信息
|
||||
*/
|
||||
UserAuthRespDTO findAuthInfoByUserId(String userId);
|
||||
}
|
||||
|
||||
@@ -25,56 +25,61 @@ import java.util.Date;
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
|
||||
private final UserRegisterRequestParamVerifyContext userRegisterRequestParamVerifyContext;
|
||||
|
||||
@Override
|
||||
public Long userRegister(UserRegisterRequestDTO request) {
|
||||
UserAuthRespDTO authInfoByUserAccount = findAuthInfoByUserAccount(request.getUserAccount());
|
||||
if (authInfoByUserAccount != null) {
|
||||
throw new ClientException("重复创建用户");
|
||||
}
|
||||
private final UserRegisterRequestParamVerifyContext userRegisterRequestParamVerifyContext;
|
||||
|
||||
log.info("进行用户注册");
|
||||
userRegisterRequestParamVerifyContext.handler(ChainMarkEnums.USER_REGISTER_REQ_PARAM_VERIFY.getMarkName(),
|
||||
request);
|
||||
// 使用 BCrypt 加密密码
|
||||
Date now = new Date();
|
||||
String salt = BCrypt.gensalt();
|
||||
String encryptPassword = BCrypt.hashpw(request.getUserPassword(), salt);
|
||||
User user = new User().setUserAccount(request.getUserAccount()).setUserPassword(encryptPassword)
|
||||
.setUserRole("user").setCreateTime(now).setUpdateTime(now);
|
||||
try {
|
||||
// 需要修改表,使得用户名是唯一的
|
||||
this.save(user);
|
||||
} catch (DuplicateKeyException e) {
|
||||
log.error("重复创建用户");
|
||||
throw new ServiceException("用户名已存在", ErrorCode.SYSTEM_ERROR);
|
||||
}
|
||||
@Override
|
||||
public Long userRegister(UserRegisterRequestDTO request) {
|
||||
UserAuthRespDTO authInfoByUserAccount = findAuthInfoByUserAccount(request.getUserAccount());
|
||||
if (authInfoByUserAccount != null) {
|
||||
throw new ClientException("重复创建用户");
|
||||
}
|
||||
|
||||
return user.getId();
|
||||
}
|
||||
log.info("进行用户注册");
|
||||
userRegisterRequestParamVerifyContext.handler(ChainMarkEnums.USER_REGISTER_REQ_PARAM_VERIFY.getMarkName(),
|
||||
request);
|
||||
// 使用 BCrypt 加密密码
|
||||
Date now = new Date();
|
||||
String salt = BCrypt.gensalt();
|
||||
String encryptPassword = BCrypt.hashpw(request.getUserPassword(), salt);
|
||||
User user = new User().setUserAccount(request.getUserAccount())
|
||||
.setUserPassword(encryptPassword)
|
||||
.setUserRole("user")
|
||||
.setCreateTime(now)
|
||||
.setUpdateTime(now);
|
||||
try {
|
||||
// 需要修改表,使得用户名是唯一的
|
||||
this.save(user);
|
||||
}
|
||||
catch (DuplicateKeyException e) {
|
||||
log.error("重复创建用户");
|
||||
throw new ServiceException("用户名已存在", ErrorCode.SYSTEM_ERROR);
|
||||
}
|
||||
|
||||
return user.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserAuthRespDTO findAuthInfoByUserAccount(String userAccount) {
|
||||
User one = this.lambdaQuery().eq(User::getUserAccount, userAccount).one();
|
||||
UserAuthRespDTO userAuthDTO = new UserAuthRespDTO();
|
||||
if (one != null) {
|
||||
BeanUtils.copyProperties(one, userAuthDTO);
|
||||
return userAuthDTO;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public UserAuthRespDTO findAuthInfoByUserAccount(String userAccount) {
|
||||
User one = this.lambdaQuery().eq(User::getUserAccount, userAccount).one();
|
||||
UserAuthRespDTO userAuthDTO = new UserAuthRespDTO();
|
||||
if (one != null) {
|
||||
BeanUtils.copyProperties(one, userAuthDTO);
|
||||
return userAuthDTO;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserAuthRespDTO findAuthInfoByUserId(String userId) {
|
||||
User one = this.lambdaQuery().eq(User::getId, userId).one();
|
||||
UserAuthRespDTO userAuthDTO = new UserAuthRespDTO();
|
||||
if (one != null) {
|
||||
BeanUtils.copyProperties(one, userAuthDTO);
|
||||
return userAuthDTO;
|
||||
}
|
||||
return null;
|
||||
@Override
|
||||
public UserAuthRespDTO findAuthInfoByUserId(String userId) {
|
||||
User one = this.lambdaQuery().eq(User::getId, userId).one();
|
||||
UserAuthRespDTO userAuthDTO = new UserAuthRespDTO();
|
||||
if (one != null) {
|
||||
BeanUtils.copyProperties(one, userAuthDTO);
|
||||
return userAuthDTO;
|
||||
}
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
20
pom.xml
20
pom.xml
@@ -31,6 +31,7 @@
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<spring-boot.version>3.5.7</spring-boot.version>
|
||||
<spring-cloud-alibaba.version>2025.0.0.0</spring-cloud-alibaba.version>
|
||||
<spring.checkstyle.plugin>0.0.47</spring.checkstyle.plugin>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
@@ -84,6 +85,10 @@
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<includes>
|
||||
<include>application*.yml</include>
|
||||
<include>application*.properties</include>
|
||||
</includes>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
@@ -103,6 +108,21 @@
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<version>${spring-boot.version}</version>
|
||||
</plugin>
|
||||
<!--
|
||||
代码格式插件,默认使用spring 规则,可运行命令进行项目格式化:./mvnw spring-javaformat:apply 或 mvn spring-javaformat:apply,可在IDEA中安装插件以下插件进行自动格式化:
|
||||
https://repo1.maven.org/maven2/io/spring/javaformat/spring-javaformat-intellij-idea-plugin
|
||||
-->
|
||||
<plugin>
|
||||
<groupId>io.spring.javaformat</groupId>
|
||||
<artifactId>spring-javaformat-maven-plugin</artifactId>
|
||||
<version>${spring.checkstyle.plugin}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>validate</phase>
|
||||
<inherited>true</inherited>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<profiles>
|
||||
|
||||
Reference in New Issue
Block a user