Update Search footer header index user
This commit is contained in:
@@ -88,7 +88,7 @@ public class WebSecurityConfig {
|
||||
auth.requestMatchers(
|
||||
"/css/**", "/js/**", "/images/**", "/static/**", "/favicon.ico",
|
||||
"/login/**", "/register", "/registerDo", "/initUserData",
|
||||
"/", "/main", "/index", "/getdiscussionsbyid",
|
||||
"/", "/main", "/index", "/getdiscussionsbyid", "/search", "/profile",
|
||||
// SpringDoc OpenAPI UI and spec endpoint (developer tools, no sensitive data)
|
||||
"/swagger-ui/**", "/swagger-ui.html", "/v3/api-docs/**"
|
||||
).permitAll();
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.yaoyuan.jiscuss.controller;
|
||||
|
||||
import com.yaoyuan.jiscuss.entity.UserInfo;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpSession;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.context.SecurityContext;
|
||||
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
|
||||
/**
|
||||
* Injects common model attributes (e.g. isAdmin) into every rendered view.
|
||||
*/
|
||||
@ControllerAdvice
|
||||
public class GlobalModelAdvice {
|
||||
|
||||
@ModelAttribute("isAdmin")
|
||||
public boolean isAdmin(HttpServletRequest request) {
|
||||
HttpSession session = request.getSession(false);
|
||||
if (session == null) return false;
|
||||
Object ctx = session.getAttribute("SPRING_SECURITY_CONTEXT");
|
||||
if (!(ctx instanceof SecurityContext sc)) return false;
|
||||
Authentication auth = sc.getAuthentication();
|
||||
if (auth == null || !(auth.getPrincipal() instanceof UserInfo)) return false;
|
||||
return auth.getAuthorities().stream()
|
||||
.map(GrantedAuthority::getAuthority)
|
||||
.anyMatch(a -> a.equals("ROLE_ADMIN"));
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,7 @@ import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
@@ -100,6 +101,54 @@ public class UserPageController extends BaseController {
|
||||
map.put("likedDiscussions", liked);
|
||||
}
|
||||
|
||||
map.put("isOwn", true);
|
||||
return "user";
|
||||
}
|
||||
|
||||
/**
|
||||
* 公开用户主页 /profile?uid=xxx (无需登录)
|
||||
*/
|
||||
@GetMapping("/profile")
|
||||
public String profile(@RequestParam Integer uid,
|
||||
@RequestParam(defaultValue = "discussion") String type,
|
||||
HttpServletRequest request, ModelMap map) {
|
||||
User userEntity = usersService.findOne(uid);
|
||||
if (userEntity == null) return "redirect:/";
|
||||
|
||||
long liveDiscCount = discussionsRepository.countByStartUserId(uid);
|
||||
long liveReplyCount = postsRepository.countByCreateId(uid);
|
||||
map.put("username", userEntity.getUsername());
|
||||
map.put("userEntity", userEntity);
|
||||
map.put("liveDiscCount", liveDiscCount);
|
||||
map.put("liveReplyCount", liveReplyCount);
|
||||
map.put("type", type);
|
||||
map.put("isOwn", false);
|
||||
|
||||
if ("discussion".equals(type)) {
|
||||
Page<Discussion> discussions = discussionsRepository.findByStartUserIdOrderByStartTimeDesc(
|
||||
uid, PageRequest.of(0, 20));
|
||||
map.put("discussions", discussions.getContent());
|
||||
} else if ("reply".equals(type)) {
|
||||
Page<Post> posts = postsRepository.findByCreateIdOrderByCreateTimeDesc(
|
||||
uid, PageRequest.of(0, 20));
|
||||
map.put("posts", posts.getContent());
|
||||
List<String> discTitles = new ArrayList<>();
|
||||
for (Post p : posts.getContent()) {
|
||||
Discussion d = p.getDiscussionId() != null
|
||||
? discussionsRepository.findById(p.getDiscussionId()).orElse(null) : null;
|
||||
discTitles.add(d != null ? d.getTitle() : "");
|
||||
}
|
||||
map.put("discTitles", discTitles);
|
||||
} else if ("like".equals(type)) {
|
||||
List<Integer> likedIds = likeCollectRepository.findLikedDiscussionIdsByUser(uid);
|
||||
List<Discussion> liked = new ArrayList<>();
|
||||
for (Integer id : likedIds) {
|
||||
Discussion d = discussionsRepository.findById(id).orElse(null);
|
||||
if (d != null) liked.add(d);
|
||||
}
|
||||
map.put("likedDiscussions", liked);
|
||||
}
|
||||
|
||||
return "user";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,8 @@ import com.yaoyuan.jiscuss.entity.Tag;
|
||||
import com.yaoyuan.jiscuss.entity.User;
|
||||
import com.yaoyuan.jiscuss.entity.UserInfo;
|
||||
import com.yaoyuan.jiscuss.entity.custom.DiscussionCustom;
|
||||
import com.yaoyuan.jiscuss.repository.DiscussionsRepository;
|
||||
import com.yaoyuan.jiscuss.repository.PostsRepository;
|
||||
import com.yaoyuan.jiscuss.service.IDiscussionsService;
|
||||
import com.yaoyuan.jiscuss.service.IDiscussionsTagsService;
|
||||
import com.yaoyuan.jiscuss.service.IPostsService;
|
||||
@@ -19,6 +21,7 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
@@ -59,6 +62,12 @@ public class UserPostController extends BaseController {
|
||||
@Autowired
|
||||
private IUsersService usersService;
|
||||
|
||||
@Autowired
|
||||
private DiscussionsRepository discussionsRepository;
|
||||
|
||||
@Autowired
|
||||
private PostsRepository postsRepository;
|
||||
|
||||
@Autowired
|
||||
private IpRegionService ipRegionService;
|
||||
|
||||
@@ -112,6 +121,19 @@ public class UserPostController extends BaseController {
|
||||
map.put("discussions", newdd);
|
||||
map.put("posts", postsObj);
|
||||
map.put("sort", sort);
|
||||
|
||||
// Sidebar: author stats and top discussions
|
||||
if (newdd.getStartUserId() != null) {
|
||||
Integer authorId = newdd.getStartUserId();
|
||||
long authorDiscCount = discussionsRepository.countByStartUserId(authorId);
|
||||
long authorReplyCount = postsRepository.countByCreateId(authorId);
|
||||
java.util.List<Discussion> authorTopDiscs = discussionsRepository
|
||||
.findTopByStartUserIdOrderByLikes(authorId, PageRequest.of(0, 5));
|
||||
map.put("authorDiscCount", authorDiscCount);
|
||||
map.put("authorReplyCount", authorReplyCount);
|
||||
map.put("authorTopDiscs", authorTopDiscs);
|
||||
}
|
||||
|
||||
UserInfo user = getUserInfo(request);
|
||||
if (user != null) {
|
||||
map.put("username", user.getUsername());
|
||||
|
||||
@@ -6,6 +6,7 @@ import com.yaoyuan.jiscuss.entity.User;
|
||||
import com.yaoyuan.jiscuss.entity.UserInfo;
|
||||
import com.yaoyuan.jiscuss.entity.custom.DiscussionCustom;
|
||||
import com.yaoyuan.jiscuss.entity.custom.TagCustom;
|
||||
import com.yaoyuan.jiscuss.repository.DiscussionsRepository;
|
||||
import com.yaoyuan.jiscuss.service.IDiscussionsService;
|
||||
import com.yaoyuan.jiscuss.service.ITagsService;
|
||||
import com.yaoyuan.jiscuss.service.IUsersService;
|
||||
@@ -54,6 +55,9 @@ public class UserSystemController extends BaseController {
|
||||
@Autowired
|
||||
private BCryptPasswordEncoder passwordEncoder;
|
||||
|
||||
@Autowired
|
||||
private DiscussionsRepository discussionsRepository;
|
||||
|
||||
/**
|
||||
* 首页index
|
||||
* @param tag
|
||||
@@ -276,6 +280,36 @@ public class UserSystemController extends BaseController {
|
||||
return "register";
|
||||
}
|
||||
|
||||
/**
|
||||
* 搜索页
|
||||
*/
|
||||
@GetMapping("/search")
|
||||
public String search(@RequestParam(defaultValue = "") String q,
|
||||
@RequestParam(defaultValue = "1") Integer pageNum,
|
||||
HttpServletRequest request, ModelMap map) {
|
||||
String keyword = q.trim();
|
||||
int pageSize = 10;
|
||||
int page = Math.max(pageNum - 1, 0);
|
||||
Page<Discussion> resultPage = keyword.isEmpty()
|
||||
? Page.empty()
|
||||
: discussionsRepository.searchByKeyword(keyword,
|
||||
org.springframework.data.domain.PageRequest.of(page, pageSize));
|
||||
|
||||
List<DiscussionCustom> results = new ArrayList<>();
|
||||
if (!keyword.isEmpty()) {
|
||||
setTagAndUserList(results, resultPage.getContent());
|
||||
}
|
||||
|
||||
map.put("q", keyword);
|
||||
map.put("results", results);
|
||||
map.put("totalPages", resultPage.getTotalPages());
|
||||
map.put("totalElements", resultPage.getTotalElements());
|
||||
map.put("pageNum", pageNum);
|
||||
UserInfo user = getUserInfo(request);
|
||||
if (user != null) map.put("username", user.getUsername());
|
||||
return "search";
|
||||
}
|
||||
|
||||
//获取设置信息
|
||||
|
||||
//获取首页统计
|
||||
|
||||
@@ -10,6 +10,7 @@ import org.springframework.stereotype.Repository;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
@Repository
|
||||
public interface DiscussionsRepository extends JpaRepository<Discussion, Integer> {
|
||||
@@ -49,4 +50,14 @@ public interface DiscussionsRepository extends JpaRepository<Discussion, Integer
|
||||
@org.springframework.data.repository.query.Param("userId") Integer userId,
|
||||
org.springframework.data.domain.Pageable pageable);
|
||||
long countByStartUserId(Integer startUserId);
|
||||
|
||||
/** Author's top discussions ordered by likeCount (for sidebar). */
|
||||
@Query("SELECT d FROM Discussion d WHERE d.startUserId = :userId ORDER BY COALESCE(d.likeCount, 0) DESC, d.startTime DESC")
|
||||
List<Discussion> findTopByStartUserIdOrderByLikes(
|
||||
@org.springframework.data.repository.query.Param("userId") Integer userId,
|
||||
Pageable pageable);
|
||||
|
||||
/** Full-text search by title or content. */
|
||||
@Query("SELECT d FROM Discussion d WHERE d.title LIKE %:q% OR d.content LIKE %:q% ORDER BY d.startTime DESC")
|
||||
Page<Discussion> searchByKeyword(@org.springframework.data.repository.query.Param("q") String q, Pageable pageable);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user