refactor(utils): 重构工具类并添加新功能
- 重命名ApiResponseUtil为ApiResponseUtils,MarkdownAST保持不变,PaginationUtil为PaginationUtils,SecurityUtil为SecurityUtils- 添加MarkdownUtils类,分离Markdown相关功能 - 新增SearchUtils类,用于搜索相关功能 - 添加TraceIdFilter过滤器,用于追踪ID - 新增NeedLoginAspect切面,用于登录验证- 更新相关类的引用和使用
This commit is contained in:
parent
439e7e1633
commit
ae5b7cbd1a
@ -28,6 +28,8 @@ repositories {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
implementation 'org.springframework.boot:spring-boot-starter'
|
||||||
|
implementation 'org.springframework.boot:spring-boot-starter-web'
|
||||||
implementation 'org.springframework.boot:spring-boot-starter-data-jdbc'
|
implementation 'org.springframework.boot:spring-boot-starter-data-jdbc'
|
||||||
implementation 'org.springframework.boot:spring-boot-starter-security'
|
implementation 'org.springframework.boot:spring-boot-starter-security'
|
||||||
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
|
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
|
||||||
@ -49,6 +51,10 @@ dependencies {
|
|||||||
testImplementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter-test:3.0.4'
|
testImplementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter-test:3.0.4'
|
||||||
testImplementation 'org.springframework.security:spring-security-test'
|
testImplementation 'org.springframework.security:spring-security-test'
|
||||||
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
|
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
|
||||||
|
implementation 'com.huaban:jieba-analysis:1.0.2'
|
||||||
|
implementation 'org.aspectj:aspectjweaver:1.9.19'
|
||||||
|
implementation 'org.springframework:spring-aop:6.1.0'
|
||||||
|
implementation 'javax.servlet:javax.servlet-api:4.0.1'
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.named('test') {
|
tasks.named('test') {
|
||||||
|
|||||||
@ -2,8 +2,10 @@ package com.example.copykamanotes;
|
|||||||
|
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||||
|
|
||||||
@SpringBootApplication(scanBasePackages = "com.example.copykamanotes")
|
@SpringBootApplication(scanBasePackages = "com.example.copykamanotes")
|
||||||
|
@EnableScheduling
|
||||||
public class NotesApplication {
|
public class NotesApplication {
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
|||||||
@ -0,0 +1,31 @@
|
|||||||
|
package com.example.copykamanotes.aspect;
|
||||||
|
|
||||||
|
import com.example.copykamanotes.annotation.NeedLogin;
|
||||||
|
import com.example.copykamanotes.scope.RequestScopeData;
|
||||||
|
import com.example.copykamanotes.utils.ApiResponseUtils;
|
||||||
|
import org.aspectj.lang.ProceedingJoinPoint;
|
||||||
|
import org.aspectj.lang.annotation.Around;
|
||||||
|
import org.aspectj.lang.annotation.Aspect;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Aspect
|
||||||
|
@Component
|
||||||
|
public class NeedLoginAspect {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RequestScopeData requestScopeData;
|
||||||
|
|
||||||
|
@Around("@annotation(needLogin)")
|
||||||
|
public Object around(ProceedingJoinPoint joinPoint, NeedLogin needLogin) throws Throwable {
|
||||||
|
|
||||||
|
if (!requestScopeData.isLogin()) {
|
||||||
|
return ApiResponseUtils.error("请先登录");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (requestScopeData.getUserId() == null ) {
|
||||||
|
return ApiResponseUtils.error("用户不存在");
|
||||||
|
}
|
||||||
|
return joinPoint.proceed();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -5,6 +5,7 @@ import org.springframework.context.annotation.Configuration;
|
|||||||
import org.springframework.http.HttpMethod;
|
import org.springframework.http.HttpMethod;
|
||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||||
|
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
|
||||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
import org.springframework.security.web.SecurityFilterChain;
|
import org.springframework.security.web.SecurityFilterChain;
|
||||||
@ -23,7 +24,7 @@ public class SecurityConfig {
|
|||||||
.requestMatchers("/api/**").permitAll() // 允许 /api/** 路径下的所有请求
|
.requestMatchers("/api/**").permitAll() // 允许 /api/** 路径下的所有请求
|
||||||
.anyRequest().authenticated() // 其他请求需要认证
|
.anyRequest().authenticated() // 其他请求需要认证
|
||||||
)
|
)
|
||||||
.csrf(csrf -> csrf.disable()); // 根据需要禁用 CSRF
|
.csrf(AbstractHttpConfigurer::disable); // 根据需要禁用 CSRF
|
||||||
|
|
||||||
return http.build();
|
return http.build();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,9 +1,14 @@
|
|||||||
package com.example.copykamanotes.config;
|
package com.example.copykamanotes.config;
|
||||||
|
|
||||||
|
import com.example.copykamanotes.filter.TraceIdFilter;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.web.servlet.config.annotation.CorsRegistry;
|
import org.springframework.web.servlet.config.annotation.CorsRegistry;
|
||||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||||
|
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
||||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||||
|
|
||||||
import com.example.copykamanotes.interceptor.TokenInterceptor;
|
import com.example.copykamanotes.interceptor.TokenInterceptor;
|
||||||
@ -13,6 +18,14 @@ public class WebConfig implements WebMvcConfigurer {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private TokenInterceptor tokenInterceptor;
|
private TokenInterceptor tokenInterceptor;
|
||||||
|
|
||||||
|
@Value("${upload.path:D:/kamaNotes/upload")
|
||||||
|
private String uploadPath;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addResourceHandlers(ResourceHandlerRegistry registry) {
|
||||||
|
registry.addResourceHandler("/images/**")
|
||||||
|
.addResourceLocations("file:" + uploadPath + "/");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 添加拦截器, 拦截所有请求,除了登录和注册
|
* 添加拦截器, 拦截所有请求,除了登录和注册
|
||||||
@ -35,4 +48,11 @@ public class WebConfig implements WebMvcConfigurer {
|
|||||||
.maxAge(3600);
|
.maxAge(3600);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public FilterRegistrationBean<TraceIdFilter> traceIdFilter() {
|
||||||
|
FilterRegistrationBean<TraceIdFilter> registrationBean = new FilterRegistrationBean<>();
|
||||||
|
registrationBean.setFilter(new TraceIdFilter());
|
||||||
|
registrationBean.addUrlPatterns("/*");
|
||||||
|
return registrationBean;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,34 @@
|
|||||||
|
package com.example.copykamanotes.filter;
|
||||||
|
|
||||||
|
import org.slf4j.MDC;
|
||||||
|
|
||||||
|
import jakarta.servlet.Filter;
|
||||||
|
import jakarta.servlet.FilterChain;
|
||||||
|
import jakarta.servlet.FilterConfig;
|
||||||
|
import jakarta.servlet.ServletException;
|
||||||
|
import jakarta.servlet.ServletRequest;
|
||||||
|
import jakarta.servlet.ServletResponse;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class TraceIdFilter implements Filter {
|
||||||
|
private static final String TRACE_ID_KEY = "trace_id";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
|
||||||
|
try {
|
||||||
|
chain.doFilter(request, response);
|
||||||
|
} finally {
|
||||||
|
MDC.remove(TRACE_ID_KEY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(FilterConfig filterConfig) throws ServletException {
|
||||||
|
Filter.super.init(filterConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void destroy() {
|
||||||
|
Filter.super.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -16,9 +16,9 @@ import com.example.copykamanotes.service.NoteLikeService;
|
|||||||
import com.example.copykamanotes.service.NoteService;
|
import com.example.copykamanotes.service.NoteService;
|
||||||
import com.example.copykamanotes.service.QuestionService;
|
import com.example.copykamanotes.service.QuestionService;
|
||||||
import com.example.copykamanotes.service.UserService;
|
import com.example.copykamanotes.service.UserService;
|
||||||
import com.example.copykamanotes.utils.ApiResponseUtil;
|
import com.example.copykamanotes.utils.ApiResponseUtils;
|
||||||
import com.example.copykamanotes.utils.MarkdownUtil;
|
import com.example.copykamanotes.utils.MarkdownUtils;
|
||||||
import com.example.copykamanotes.utils.PaginationUtil;
|
import com.example.copykamanotes.utils.PaginationUtils;
|
||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
@ -48,7 +48,7 @@ public class NoteServiceImpl implements NoteService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ApiResponse<List<NoteVO>> getNotes(NoteQueryParams noteQueryParams) {
|
public ApiResponse<List<NoteVO>> getNotes(NoteQueryParams noteQueryParams) {
|
||||||
int offset = PaginationUtil.calculateOffset(noteQueryParams.getPage(), noteQueryParams.getPageSize());
|
int offset = PaginationUtils.calculateOffset(noteQueryParams.getPage(), noteQueryParams.getPageSize());
|
||||||
|
|
||||||
int total = noteMapper.countNotes(noteQueryParams);
|
int total = noteMapper.countNotes(noteQueryParams);
|
||||||
|
|
||||||
@ -105,9 +105,9 @@ public class NoteServiceImpl implements NoteService {
|
|||||||
userActionsVO.setIsCollected(true);
|
userActionsVO.setIsCollected(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MarkdownUtil.needCollapsed(note.getContent())) {
|
if (MarkdownUtils.needCollapsed(note.getContent())) {
|
||||||
noteVO.setNeedCollapsed(true);
|
noteVO.setNeedCollapsed(true);
|
||||||
noteVO.setDisplayContent(MarkdownUtil.extractIntroduction(note.getContent()));
|
noteVO.setDisplayContent(MarkdownUtils.extractIntroduction(note.getContent()));
|
||||||
} else {
|
} else {
|
||||||
noteVO.setNeedCollapsed(false);
|
noteVO.setNeedCollapsed(false);
|
||||||
}
|
}
|
||||||
@ -116,9 +116,9 @@ public class NoteServiceImpl implements NoteService {
|
|||||||
return noteVO;
|
return noteVO;
|
||||||
}).toList();
|
}).toList();
|
||||||
|
|
||||||
return ApiResponseUtil.success("获取笔记列表成功", noteVOs, pagination);
|
return ApiResponseUtils.success("获取笔记列表成功", noteVOs, pagination);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return ApiResponseUtil.error("获取笔记列表失败");
|
return ApiResponseUtils.error("获取笔记列表失败");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import com.example.copykamanotes.model.base.ApiResponse;
|
|||||||
import com.example.copykamanotes.model.vo.upload.ImageVO;
|
import com.example.copykamanotes.model.vo.upload.ImageVO;
|
||||||
import com.example.copykamanotes.service.FileService;
|
import com.example.copykamanotes.service.FileService;
|
||||||
import com.example.copykamanotes.service.UploadService;
|
import com.example.copykamanotes.service.UploadService;
|
||||||
import com.example.copykamanotes.utils.ApiResponseUtil;
|
import com.example.copykamanotes.utils.ApiResponseUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
@ -20,6 +20,6 @@ public class UploadServiceImpl implements UploadService {
|
|||||||
String url = fileService.uploadImage(file);
|
String url = fileService.uploadImage(file);
|
||||||
ImageVO imageVO = new ImageVO();
|
ImageVO imageVO = new ImageVO();
|
||||||
imageVO.setUrl(url);
|
imageVO.setUrl(url);
|
||||||
return ApiResponseUtil.success("上传成功", imageVO);
|
return ApiResponseUtils.success("上传成功", imageVO);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,10 +17,9 @@ import com.example.copykamanotes.scope.RequestScopeData;
|
|||||||
import com.example.copykamanotes.service.EmailService;
|
import com.example.copykamanotes.service.EmailService;
|
||||||
import com.example.copykamanotes.service.FileService;
|
import com.example.copykamanotes.service.FileService;
|
||||||
import com.example.copykamanotes.service.UserService;
|
import com.example.copykamanotes.service.UserService;
|
||||||
import com.example.copykamanotes.utils.ApiResponseUtil;
|
import com.example.copykamanotes.utils.ApiResponseUtils;
|
||||||
import com.example.copykamanotes.utils.JwtUtil;
|
import com.example.copykamanotes.utils.JwtUtil;
|
||||||
import com.example.copykamanotes.utils.PaginationUtil;
|
import com.example.copykamanotes.utils.PaginationUtils;
|
||||||
import com.google.protobuf.Api;
|
|
||||||
import lombok.extern.log4j.Log4j2;
|
import lombok.extern.log4j.Log4j2;
|
||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@ -62,14 +61,14 @@ public class UserServiceImpl implements UserService {
|
|||||||
public ApiResponse<RegisterVO> register(RegisterRequest registerRequest) {
|
public ApiResponse<RegisterVO> register(RegisterRequest registerRequest) {
|
||||||
User existingUser = userMapper.findByAccount(registerRequest.getAccount());
|
User existingUser = userMapper.findByAccount(registerRequest.getAccount());
|
||||||
if (existingUser != null) {
|
if (existingUser != null) {
|
||||||
return ApiResponseUtil.error("账号重复");
|
return ApiResponseUtils.error("账号重复");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (registerRequest.getEmail() != null && !registerRequest.getEmail().isEmpty()) {
|
if (registerRequest.getEmail() != null && !registerRequest.getEmail().isEmpty()) {
|
||||||
// 验证邮箱是否重复
|
// 验证邮箱是否重复
|
||||||
existingUser = userMapper.findByEmail(registerRequest.getEmail());
|
existingUser = userMapper.findByEmail(registerRequest.getEmail());
|
||||||
if (existingUser != null) {
|
if (existingUser != null) {
|
||||||
return ApiResponseUtil.error("邮箱重复");
|
return ApiResponseUtils.error("邮箱重复");
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (registerRequest.getVerifyCode() == null || registerRequest.getVerifyCode().isEmpty()) {
|
// if (registerRequest.getVerifyCode() == null || registerRequest.getVerifyCode().isEmpty()) {
|
||||||
@ -95,10 +94,10 @@ public class UserServiceImpl implements UserService {
|
|||||||
BeanUtils.copyProperties(user, registerVO);
|
BeanUtils.copyProperties(user, registerVO);
|
||||||
|
|
||||||
userMapper.updateLastLoginAt(user.getUserId());
|
userMapper.updateLastLoginAt(user.getUserId());
|
||||||
return ApiResponseUtil.success("注册成功", registerVO, token);
|
return ApiResponseUtils.success("注册成功", registerVO, token);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("注册失败", e);
|
log.error("注册失败", e);
|
||||||
return ApiResponseUtil.error("注册失败,请稍后再试");
|
return ApiResponseUtils.error("注册失败,请稍后再试");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,15 +110,15 @@ public class UserServiceImpl implements UserService {
|
|||||||
} else if (loginRequest.getEmail() != null && !loginRequest.getEmail().isEmpty()) {
|
} else if (loginRequest.getEmail() != null && !loginRequest.getEmail().isEmpty()) {
|
||||||
user = userMapper.findByEmail(loginRequest.getEmail());
|
user = userMapper.findByEmail(loginRequest.getEmail());
|
||||||
} else {
|
} else {
|
||||||
return ApiResponseUtil.error("账号或邮箱不能为空");
|
return ApiResponseUtils.error("账号或邮箱不能为空");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
return ApiResponseUtil.error("账号或邮箱不存在");
|
return ApiResponseUtils.error("账号或邮箱不存在");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!passwordEncoder.matches(loginRequest.getPassword(), user.getPassword())) {
|
if (!passwordEncoder.matches(loginRequest.getPassword(), user.getPassword())) {
|
||||||
return ApiResponseUtil.error("密码错误");
|
return ApiResponseUtils.error("密码错误");
|
||||||
}
|
}
|
||||||
|
|
||||||
String token = jwtUtil.generateToken(user.getUserId());
|
String token = jwtUtil.generateToken(user.getUserId());
|
||||||
@ -129,7 +128,7 @@ public class UserServiceImpl implements UserService {
|
|||||||
|
|
||||||
userMapper.updateLastLoginAt(user.getUserId());
|
userMapper.updateLastLoginAt(user.getUserId());
|
||||||
|
|
||||||
return ApiResponseUtil.success("登录成功", loginUserVO, token);
|
return ApiResponseUtils.success("登录成功", loginUserVO, token);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -137,26 +136,26 @@ public class UserServiceImpl implements UserService {
|
|||||||
Long userId = requestScopeData.getUserId();
|
Long userId = requestScopeData.getUserId();
|
||||||
|
|
||||||
if (userId == null) {
|
if (userId == null) {
|
||||||
return ApiResponseUtil.error("未登录");
|
return ApiResponseUtils.error("未登录");
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
User user = userMapper.findById(userId);
|
User user = userMapper.findById(userId);
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
return ApiResponseUtil.error("用户不存在");
|
return ApiResponseUtils.error("用户不存在");
|
||||||
}
|
}
|
||||||
|
|
||||||
String newToken = jwtUtil.generateToken(userId);
|
String newToken = jwtUtil.generateToken(userId);
|
||||||
if (newToken == null) {
|
if (newToken == null) {
|
||||||
return ApiResponseUtil.error("token生成失败");
|
return ApiResponseUtils.error("token生成失败");
|
||||||
}
|
}
|
||||||
|
|
||||||
LoginUserVO loginUserVO = new LoginUserVO();
|
LoginUserVO loginUserVO = new LoginUserVO();
|
||||||
BeanUtils.copyProperties(user, loginUserVO);
|
BeanUtils.copyProperties(user, loginUserVO);
|
||||||
return ApiResponseUtil.success("获取用户信息成功", loginUserVO, newToken);
|
return ApiResponseUtils.success("获取用户信息成功", loginUserVO, newToken);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("获取用户信息失败", e);
|
log.error("获取用户信息失败", e);
|
||||||
return ApiResponseUtil.error("获取用户信息失败");
|
return ApiResponseUtils.error("获取用户信息失败");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,12 +164,12 @@ public class UserServiceImpl implements UserService {
|
|||||||
User user = userMapper.findById(userId);
|
User user = userMapper.findById(userId);
|
||||||
|
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
return ApiResponseUtil.error("用户不存在");
|
return ApiResponseUtils.error("用户不存在");
|
||||||
}
|
}
|
||||||
|
|
||||||
UserVO userVO = new UserVO();
|
UserVO userVO = new UserVO();
|
||||||
BeanUtils.copyProperties(user, userVO);
|
BeanUtils.copyProperties(user, userVO);
|
||||||
return ApiResponseUtil.success("获取用户信息成功", userVO);
|
return ApiResponseUtils.success("获取用户信息成功", userVO);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -180,7 +179,7 @@ public class UserServiceImpl implements UserService {
|
|||||||
Long userId = requestScopeData.getUserId();
|
Long userId = requestScopeData.getUserId();
|
||||||
|
|
||||||
if (userId == null) {
|
if (userId == null) {
|
||||||
return ApiResponseUtil.error("未登录");
|
return ApiResponseUtils.error("未登录");
|
||||||
}
|
}
|
||||||
|
|
||||||
User user = new User();
|
User user = new User();
|
||||||
@ -189,10 +188,10 @@ public class UserServiceImpl implements UserService {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
userMapper.update(user);
|
userMapper.update(user);
|
||||||
return ApiResponseUtil.success("更新用户信息成功");
|
return ApiResponseUtils.success("更新用户信息成功");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("更新用户信息失败", e);
|
log.error("更新用户信息失败", e);
|
||||||
return ApiResponseUtil.error("更新用户信息失败");
|
return ApiResponseUtils.error("更新用户信息失败");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -210,15 +209,15 @@ public class UserServiceImpl implements UserService {
|
|||||||
|
|
||||||
// 分页数据
|
// 分页数据
|
||||||
int total = userMapper.countByQueryParam(userQueryParam);
|
int total = userMapper.countByQueryParam(userQueryParam);
|
||||||
int offset = PaginationUtil.calculateOffset(userQueryParam.getPage(), userQueryParam.getPageSize());
|
int offset = PaginationUtils.calculateOffset(userQueryParam.getPage(), userQueryParam.getPageSize());
|
||||||
Pagination pagination = new Pagination(userQueryParam.getPage(), userQueryParam.getPageSize(), total);
|
Pagination pagination = new Pagination(userQueryParam.getPage(), userQueryParam.getPageSize(), total);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
List<User> users = userMapper.findByQueryParam(userQueryParam, userQueryParam.getPageSize(), offset);
|
List<User> users = userMapper.findByQueryParam(userQueryParam, userQueryParam.getPageSize(), offset);
|
||||||
|
|
||||||
return ApiResponseUtil.success("获取用户列表成功", users, pagination);
|
return ApiResponseUtils.success("获取用户列表成功", users, pagination);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return ApiResponseUtil.error(e.getMessage());
|
return ApiResponseUtils.error(e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -228,10 +227,10 @@ public class UserServiceImpl implements UserService {
|
|||||||
String url = fileService.uploadImage(file);
|
String url = fileService.uploadImage(file);
|
||||||
AvatarVO avatarVO = new AvatarVO();
|
AvatarVO avatarVO = new AvatarVO();
|
||||||
avatarVO.setAvatarUrl(url);
|
avatarVO.setAvatarUrl(url);
|
||||||
return ApiResponseUtil.success("上传成功", avatarVO);
|
return ApiResponseUtils.success("上传成功", avatarVO);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("上传失败", e);
|
log.error("上传失败", e);
|
||||||
return ApiResponseUtil.error("上传失败");
|
return ApiResponseUtils.error("上传失败");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -240,27 +239,27 @@ public class UserServiceImpl implements UserService {
|
|||||||
Long userId = requestScopeData.getUserId();
|
Long userId = requestScopeData.getUserId();
|
||||||
|
|
||||||
if (userId == null) {
|
if (userId == null) {
|
||||||
return ApiResponseUtil.error("未登录");
|
return ApiResponseUtils.error("未登录");
|
||||||
}
|
}
|
||||||
|
|
||||||
User user = null;
|
User user = null;
|
||||||
user = userMapper.findById(userId);
|
user = userMapper.findById(userId);
|
||||||
if (user == null || !passwordEncoder.matches(oldPassword, user.getPassword())) {
|
if (user == null || !passwordEncoder.matches(oldPassword, user.getPassword())) {
|
||||||
return ApiResponseUtil.error("旧密码错误");
|
return ApiResponseUtils.error("旧密码错误");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Objects.equals(oldPassword, newPassword)) {
|
if (Objects.equals(oldPassword, newPassword)) {
|
||||||
return ApiResponseUtil.error("新密码不能与旧密码相同");
|
return ApiResponseUtils.error("新密码不能与旧密码相同");
|
||||||
}
|
}
|
||||||
|
|
||||||
user.setPassword(passwordEncoder.encode(newPassword));
|
user.setPassword(passwordEncoder.encode(newPassword));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
userMapper.updatePassword(user.getUserId(), user.getPassword());
|
userMapper.updatePassword(user.getUserId(), user.getPassword());
|
||||||
return ApiResponseUtil.success("更新密码成功");
|
return ApiResponseUtils.success("更新密码成功");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("更新密码失败", e);
|
log.error("更新密码失败", e);
|
||||||
return ApiResponseUtil.error("更新密码失败");
|
return ApiResponseUtils.error("更新密码失败");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,7 +7,7 @@ import com.example.copykamanotes.model.base.PaginationApiResponse;
|
|||||||
import com.example.copykamanotes.model.base.TokenApiResponse;
|
import com.example.copykamanotes.model.base.TokenApiResponse;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
|
|
||||||
public class ApiResponseUtil {
|
public class ApiResponseUtils {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构建成功的响应
|
* 构建成功的响应
|
||||||
@ -44,8 +44,9 @@ public class JwtUtil {
|
|||||||
*/
|
*/
|
||||||
public Long getUserIdFromToken(String token) {
|
public Long getUserIdFromToken(String token) {
|
||||||
try {
|
try {
|
||||||
Claims claims = Jwts.parser()
|
Claims claims = Jwts
|
||||||
.setSigningKey(SECRET_KEY)
|
.parserBuilder()
|
||||||
|
.setSigningKey(SECRET_KEY).build()
|
||||||
.parseClaimsJws(token)
|
.parseClaimsJws(token)
|
||||||
.getBody();
|
.getBody();
|
||||||
return Long.valueOf(claims.get("userId").toString());
|
return Long.valueOf(claims.get("userId").toString());
|
||||||
@ -60,7 +61,8 @@ public class JwtUtil {
|
|||||||
*/
|
*/
|
||||||
public boolean validateToken(String token) {
|
public boolean validateToken(String token) {
|
||||||
try {
|
try {
|
||||||
Jwts.parser().setSigningKey(secret).parseClaimsJws(token);
|
Jwts.parserBuilder().setSigningKey(SECRET_KEY).build().parseClaimsJws(token);
|
||||||
|
// Jwts.parser().setSigningKey(secret).parseClaimsJws(token);
|
||||||
return true;
|
return true;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@ -15,20 +15,24 @@ public class MarkdownAST {
|
|||||||
private final Document markdownAST;
|
private final Document markdownAST;
|
||||||
private final String markdownText;
|
private final String markdownText;
|
||||||
|
|
||||||
public MarkdownAST( String markdownText) {
|
// 构造函数:初始化并解析 Markdown文本
|
||||||
|
public MarkdownAST(String markdownText) {
|
||||||
this.markdownText = markdownText;
|
this.markdownText = markdownText;
|
||||||
|
|
||||||
Parser parser = Parser.builder().build();
|
Parser parser = Parser.builder().build();
|
||||||
|
// 解析 Markdown 文本
|
||||||
this.markdownAST = parser.parse(markdownText);
|
this.markdownAST = parser.parse(markdownText);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String extractIntroduction(int maxChars) {
|
public String extractIntroduction(int maxChars) {
|
||||||
StringBuilder introText = new StringBuilder();
|
StringBuilder introText = new StringBuilder();
|
||||||
|
// 遍历 AST 节点,提取文本内容
|
||||||
for (Node node : markdownAST.getChildren()) {
|
for (Node node : markdownAST.getChildren()) {
|
||||||
if (node instanceof Heading || node instanceof Paragraph) {
|
if (node instanceof Heading || node instanceof Paragraph) {
|
||||||
|
// 获取节点的文本内容
|
||||||
String renderedText = getNoteText(node);
|
String renderedText = getNoteText(node);
|
||||||
|
|
||||||
|
// 计算剩余字符数,并截取文本
|
||||||
int remainingChars = maxChars - introText.length();
|
int remainingChars = maxChars - introText.length();
|
||||||
introText.append(renderedText, 0, Math.min(remainingChars, renderedText.length()));
|
introText.append(renderedText, 0, Math.min(remainingChars, renderedText.length()));
|
||||||
|
|
||||||
@ -41,26 +45,30 @@ public class MarkdownAST {
|
|||||||
return introText.toString().trim() + "...";
|
return introText.toString().trim() + "...";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 检查Markdown文本中是否包含图片
|
||||||
public List<String> extractImages() {
|
public List<String> extractImages() {
|
||||||
List<String> images = new ArrayList<>();
|
List<String> imageUrls = new ArrayList<>();
|
||||||
|
|
||||||
for (Node node : markdownAST.getChildren()) {
|
for (Node node : markdownAST.getChildren()) {
|
||||||
if (node instanceof Image imageNode) {
|
if (node instanceof Image imageNode) {
|
||||||
images.add(((Image) node).getUrl().toString());
|
imageUrls.add(imageNode.getUrl().toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return images;
|
return imageUrls;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 检查Markdown文本是否需要折叠
|
||||||
public boolean shouldCollapse(int maxChars) {
|
public boolean shouldCollapse(int maxChars) {
|
||||||
return hasImages() || markdownText.length() > maxChars;
|
return hasImages() || markdownText.length() > maxChars;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取折叠后的Markdown文本
|
||||||
public String getCollapseMarkdown() {
|
public String getCollapseMarkdown() {
|
||||||
String introText = extractIntroduction(150);
|
String introText = extractIntroduction(150);
|
||||||
return introText + "...";
|
return introText + "...";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取节点的文本内容
|
||||||
private String getNoteText(Node node) {
|
private String getNoteText(Node node) {
|
||||||
StringBuilder text = new StringBuilder();
|
StringBuilder text = new StringBuilder();
|
||||||
|
|
||||||
@ -74,6 +82,7 @@ public class MarkdownAST {
|
|||||||
return text.toString();
|
return text.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 检查Markdown文本中是否包含图片
|
||||||
private boolean hasImages() {
|
private boolean hasImages() {
|
||||||
return !extractImages().isEmpty();
|
return !extractImages().isEmpty();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
package com.example.copykamanotes.utils;
|
package com.example.copykamanotes.utils;
|
||||||
|
|
||||||
public class MarkdownUtil {
|
public class MarkdownUtil {
|
||||||
|
|
||||||
public static boolean needCollapsed(String markdown) {
|
public static boolean needCollapsed(String markdown) {
|
||||||
MarkdownAST ast = new MarkdownAST(markdown);
|
MarkdownAST ast = new MarkdownAST(markdown);
|
||||||
return ast.shouldCollapse(250);
|
return ast.shouldCollapse(250);
|
||||||
|
|||||||
@ -0,0 +1,13 @@
|
|||||||
|
package com.example.copykamanotes.utils;
|
||||||
|
|
||||||
|
public class MarkdownUtils {
|
||||||
|
public static boolean needCollapsed(String markdown) {
|
||||||
|
MarkdownAST ast = new MarkdownAST(markdown);
|
||||||
|
return ast.shouldCollapse(250);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String extractIntroduction(String markdown) {
|
||||||
|
MarkdownAST ast = new MarkdownAST(markdown);
|
||||||
|
return ast.extractIntroduction(250);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,6 +1,6 @@
|
|||||||
package com.example.copykamanotes.utils;
|
package com.example.copykamanotes.utils;
|
||||||
|
|
||||||
public class PaginationUtil {
|
public class PaginationUtils {
|
||||||
/**
|
/**
|
||||||
* 计算分页参数
|
* 计算分页参数
|
||||||
*
|
*
|
||||||
@ -0,0 +1,37 @@
|
|||||||
|
package com.example.copykamanotes.utils;
|
||||||
|
|
||||||
|
import com.huaban.analysis.jieba.JiebaSegmenter;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class SearchUtils {
|
||||||
|
private static final JiebaSegmenter segmenter = new JiebaSegmenter();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 预处理搜索关键词
|
||||||
|
* @param keyword
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static String preprocessKeyword(String keyword) {
|
||||||
|
if (!StringUtils.hasText(keyword)) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
keyword = keyword.replaceAll("[\\p{P}\\p{S}]", " ");
|
||||||
|
|
||||||
|
List<String> words = segmenter.sentenceProcess(keyword);
|
||||||
|
|
||||||
|
return String.join(" ", words);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算分页的偏移量
|
||||||
|
* @param page
|
||||||
|
* @param pageSize
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static int calculateOffset(int page, int pageSize) {
|
||||||
|
return Math.max(0, (page - 1) * pageSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -4,7 +4,7 @@ import com.example.copykamanotes.model.entity.User;
|
|||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
|
|
||||||
public class SecurityUtil {
|
public class SecurityUtils {
|
||||||
/**
|
/**
|
||||||
* 获取当前登录用户的ID
|
* 获取当前登录用户的ID
|
||||||
*
|
*
|
||||||
Reference in New Issue
Block a user