@@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-parent</artifactId>
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
<version>3.3.5</version>
|
<version>3.5.13</version>
|
||||||
<relativePath/>
|
<relativePath/>
|
||||||
</parent>
|
</parent>
|
||||||
<groupId>com.yaoyuan</groupId>
|
<groupId>com.yaoyuan</groupId>
|
||||||
@@ -73,7 +73,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springdoc</groupId>
|
<groupId>org.springdoc</groupId>
|
||||||
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
|
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
|
||||||
<version>2.6.0</version>
|
<version>2.8.9</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- Lombok -->
|
<!-- Lombok -->
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import org.springframework.security.authentication.dao.DaoAuthenticationProvider
|
|||||||
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
|
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
|
||||||
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.configuration.WebSecurityCustomizer;
|
|
||||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||||
import org.springframework.security.web.SecurityFilterChain;
|
import org.springframework.security.web.SecurityFilterChain;
|
||||||
@@ -52,17 +51,6 @@ public class WebSecurityConfig {
|
|||||||
this.applicationContext = applicationContext;
|
this.applicationContext = applicationContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Exclude truly static assets from the security filter chain entirely.
|
|
||||||
* H2 console and Druid monitoring are NOT excluded here — they are secured via filterChain.
|
|
||||||
*/
|
|
||||||
@Bean
|
|
||||||
public WebSecurityCustomizer webSecurityCustomizer() {
|
|
||||||
return web -> web.ignoring().requestMatchers(
|
|
||||||
"/css/**", "/js/**", "/images/**", "/static/**", "/favicon.ico"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Main security filter chain.
|
* Main security filter chain.
|
||||||
*
|
*
|
||||||
@@ -98,6 +86,7 @@ public class WebSecurityConfig {
|
|||||||
http.authorizeHttpRequests(auth -> {
|
http.authorizeHttpRequests(auth -> {
|
||||||
// Publicly accessible
|
// Publicly accessible
|
||||||
auth.requestMatchers(
|
auth.requestMatchers(
|
||||||
|
"/css/**", "/js/**", "/images/**", "/static/**", "/favicon.ico",
|
||||||
"/login/**", "/register", "/registerDo", "/initUserData",
|
"/login/**", "/register", "/registerDo", "/initUserData",
|
||||||
"/", "/main", "/index", "/getdiscussionsbyid",
|
"/", "/main", "/index", "/getdiscussionsbyid",
|
||||||
// SpringDoc OpenAPI UI and spec endpoint (developer tools, no sensitive data)
|
// SpringDoc OpenAPI UI and spec endpoint (developer tools, no sensitive data)
|
||||||
|
|||||||
@@ -21,13 +21,17 @@ import org.springframework.web.bind.annotation.GetMapping;
|
|||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.servlet.view.RedirectView;
|
||||||
|
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author yaoyuan2.chu
|
* @author yaoyuan2.chu
|
||||||
@@ -142,6 +146,19 @@ public class UserSystemController extends BaseController {
|
|||||||
tagMap.put(tc.getDiscussionId(), tagCustomListTemp);
|
tagMap.put(tc.getDiscussionId(), tagCustomListTemp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Set<Integer> userIds = new HashSet<>();
|
||||||
|
for (Discussion dd : allDiscussions) {
|
||||||
|
if (dd.getStartUserId() != null) {
|
||||||
|
userIds.add(dd.getStartUserId());
|
||||||
|
}
|
||||||
|
if (dd.getLastUserId() != null) {
|
||||||
|
userIds.add(dd.getLastUserId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Map<Integer, User> userMap = usersService.findAllById(userIds).stream()
|
||||||
|
.collect(Collectors.toMap(User::getId, u -> u));
|
||||||
|
|
||||||
for (Discussion dd : allDiscussions) {
|
for (Discussion dd : allDiscussions) {
|
||||||
DiscussionCustom newdd = new DiscussionCustom();
|
DiscussionCustom newdd = new DiscussionCustom();
|
||||||
BeanUtils.copyProperties(dd, newdd);
|
BeanUtils.copyProperties(dd, newdd);
|
||||||
@@ -154,13 +171,13 @@ public class UserSystemController extends BaseController {
|
|||||||
}
|
}
|
||||||
newdd.setContent(newCon);
|
newdd.setContent(newCon);
|
||||||
if (null != newdd.getStartUserId()) {
|
if (null != newdd.getStartUserId()) {
|
||||||
User startUser = usersService.findOne(newdd.getStartUserId());
|
User startUser = userMap.get(newdd.getStartUserId());
|
||||||
newdd.setAvatar(startUser != null && startUser.getAvatar() != null ? startUser.getAvatar() : "");
|
newdd.setAvatar(startUser != null && startUser.getAvatar() != null ? startUser.getAvatar() : "");
|
||||||
newdd.setRealname(startUser != null && startUser.getRealname() != null ? startUser.getRealname() : "");
|
newdd.setRealname(startUser != null && startUser.getRealname() != null ? startUser.getRealname() : "");
|
||||||
newdd.setUsername(startUser != null && startUser.getUsername() != null ? startUser.getUsername() : "");
|
newdd.setUsername(startUser != null && startUser.getUsername() != null ? startUser.getUsername() : "");
|
||||||
}
|
}
|
||||||
if (null != newdd.getLastUserId()) {
|
if (null != newdd.getLastUserId()) {
|
||||||
User lastUser = usersService.findOne(newdd.getLastUserId());
|
User lastUser = userMap.get(newdd.getLastUserId());
|
||||||
newdd.setAvatarLast(lastUser != null && lastUser.getAvatar() != null ? lastUser.getAvatar() : "");
|
newdd.setAvatarLast(lastUser != null && lastUser.getAvatar() != null ? lastUser.getAvatar() : "");
|
||||||
newdd.setRealnameLast(lastUser != null && lastUser.getRealname() != null ? lastUser.getRealname() : "");
|
newdd.setRealnameLast(lastUser != null && lastUser.getRealname() != null ? lastUser.getRealname() : "");
|
||||||
newdd.setUsernameLast(lastUser != null && lastUser.getUsername() != null ? lastUser.getUsername() : "");
|
newdd.setUsernameLast(lastUser != null && lastUser.getUsername() != null ? lastUser.getUsername() : "");
|
||||||
@@ -209,6 +226,11 @@ public class UserSystemController extends BaseController {
|
|||||||
return "login";
|
return "login";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/favicon.ico")
|
||||||
|
public RedirectView favicon() {
|
||||||
|
return new RedirectView("/static/assets/images/logo.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 注册提交
|
* 注册提交
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ import org.springframework.security.access.AccessDeniedException;
|
|||||||
import org.springframework.web.bind.MethodArgumentNotValidException;
|
import org.springframework.web.bind.MethodArgumentNotValidException;
|
||||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||||
|
import org.springframework.web.servlet.NoHandlerFoundException;
|
||||||
|
import org.springframework.web.servlet.resource.NoResourceFoundException;
|
||||||
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@@ -69,6 +71,15 @@ public class GlobalExceptionHandler {
|
|||||||
.body(ApiResponse.error("没有权限访问该资源"));
|
.body(ApiResponse.error("没有权限访问该资源"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 404 mappings/resources should not be logged as system errors. */
|
||||||
|
@ExceptionHandler({NoHandlerFoundException.class, NoResourceFoundException.class})
|
||||||
|
public ResponseEntity<ApiResponse<Void>> handleNotFound(Exception ex) {
|
||||||
|
log.warn("Not found: {}", ex.getMessage());
|
||||||
|
return ResponseEntity
|
||||||
|
.status(HttpStatus.NOT_FOUND)
|
||||||
|
.body(ApiResponse.error("资源不存在"));
|
||||||
|
}
|
||||||
|
|
||||||
/** Catch-all for any unhandled exception — never expose stack traces to clients. */
|
/** Catch-all for any unhandled exception — never expose stack traces to clients. */
|
||||||
@ExceptionHandler(Exception.class)
|
@ExceptionHandler(Exception.class)
|
||||||
public ResponseEntity<ApiResponse<Void>> handleGeneral(Exception ex) {
|
public ResponseEntity<ApiResponse<Void>> handleGeneral(Exception ex) {
|
||||||
|
|||||||
@@ -24,5 +24,7 @@ public interface IUsersService {
|
|||||||
|
|
||||||
User getByUsername(String username);
|
User getByUsername(String username);
|
||||||
|
|
||||||
|
List<User> findAllById(Iterable<Integer> ids);
|
||||||
|
|
||||||
User update(User user, Integer id);
|
User update(User user, Integer id);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ public class UsersServiceImpl implements IUsersService {
|
|||||||
@Cacheable(value = "user", key = "#id")
|
@Cacheable(value = "user", key = "#id")
|
||||||
@Override
|
@Override
|
||||||
public User findOne(Integer id) {
|
public User findOne(Integer id) {
|
||||||
return usersRepository.getById(id);
|
return usersRepository.findById(id).orElse(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -140,6 +140,12 @@ public class UsersServiceImpl implements IUsersService {
|
|||||||
return usersRepository.getByUsername(username);
|
return usersRepository.getByUsername(username);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Transactional(readOnly = true)
|
||||||
|
@Override
|
||||||
|
public List<User> findAllById(Iterable<Integer> ids) {
|
||||||
|
return usersRepository.findAllById(ids);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<#--jquery-->
|
<#--jquery-->
|
||||||
|
<link rel="icon" type="image/png" href="/static/assets/images/logo.png">
|
||||||
<script crossorigin="anonymous" integrity="sha384-vk5WoKIaW/vJyUAd9n/wmopsmNhiy+L2Z+SBxGYnUkunIxVxAv/UtMOhba/xskxh"
|
<script crossorigin="anonymous" integrity="sha384-vk5WoKIaW/vJyUAd9n/wmopsmNhiy+L2Z+SBxGYnUkunIxVxAv/UtMOhba/xskxh"
|
||||||
src="https://lib.baomitu.com/jquery/3.4.1/jquery.min.js"></script>
|
src="https://lib.baomitu.com/jquery/3.4.1/jquery.min.js"></script>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user