add
This commit is contained in:
parent
4fcf2042b2
commit
d20e9ba3e2
60
src/main/java/com/lk/paopao/controller/PostController.java
Normal file
60
src/main/java/com/lk/paopao/controller/PostController.java
Normal file
@ -0,0 +1,60 @@
|
||||
package com.lk.paopao.controller;
|
||||
|
||||
|
||||
import com.lk.paopao.dto.CommentDto;
|
||||
import com.lk.paopao.dto.PostDto;
|
||||
import com.lk.paopao.dto.rest.request.PostRequest;
|
||||
import com.lk.paopao.dto.rest.response.DataResult;
|
||||
import com.lk.paopao.dto.rest.response.Paged;
|
||||
import com.lk.paopao.dto.rest.response.ResultUtil;
|
||||
import com.lk.paopao.service.PostService;
|
||||
import jakarta.websocket.server.PathParam;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("${app.version}")
|
||||
public class PostController {
|
||||
|
||||
@Autowired
|
||||
PostService postService;
|
||||
|
||||
// https://iibiubiu.com/v1/posts?style=newest&page=1&page_size=20
|
||||
@GetMapping("/posts")
|
||||
public DataResult<Paged<PostDto>> getPosts(@PathParam("type") Long type, @PathParam("style") String style, @PathParam("page") Integer page, @PathParam("page_size") Integer pageSize) {
|
||||
return ResultUtil.ok(postService.getPosts(type, style, page, pageSize));
|
||||
|
||||
}
|
||||
@GetMapping("/post")
|
||||
public DataResult<PostDto> getPost(@PathParam("id") Long id) {
|
||||
return ResultUtil.ok(postService.getPost(id));
|
||||
}
|
||||
@PostMapping("/post")
|
||||
public DataResult<PostDto> createPost(@RequestBody PostRequest postRequest) {
|
||||
return ResultUtil.ok(postService.createPost(postRequest));
|
||||
}
|
||||
|
||||
@GetMapping("/post/comments")
|
||||
public DataResult<Paged<CommentDto>> getPostComments(@PathParam("id") Long id, @PathParam("style") String style, @PathParam("page") Integer page, @PathParam("page_size") Integer pageSize) {
|
||||
Paged<CommentDto> paged = new Paged<>(new ArrayList<>(),0L,1,10);
|
||||
return ResultUtil.ok(paged);
|
||||
}
|
||||
|
||||
@GetMapping("/post/star")
|
||||
public DataResult<Map<String, Boolean>> currentHasStarred(@PathParam("id") Long postId) {
|
||||
Map<String, Boolean> result = new HashMap<>();
|
||||
result.put("status", postService.currentUserHasStarred(postId));
|
||||
return ResultUtil.ok(result);
|
||||
}
|
||||
|
||||
@GetMapping("/post/collection")
|
||||
public DataResult<Map<String, Boolean>> currentHasCollected(@PathParam("id") Long postId) {
|
||||
Map<String, Boolean> result = new HashMap<>();
|
||||
result.put("status", postService.currentUserHasCollected(postId));
|
||||
return ResultUtil.ok(result);
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
package com.lk.paopao.controller;
|
||||
|
||||
|
||||
import com.lk.paopao.dto.rest.response.DataResult;
|
||||
import com.lk.paopao.dto.rest.response.ResultUtil;
|
||||
import com.lk.paopao.service.PostService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("${app.version}/suggest")
|
||||
public class SuggestController {
|
||||
@Autowired
|
||||
private PostService postService;
|
||||
|
||||
@GetMapping("/users")
|
||||
public DataResult<Map<String,List<String>>> suggestUsers(@RequestParam("k") String keyword){
|
||||
List<String> names = postService.getSuggestUsers(keyword);
|
||||
Map<String,List<String>> res = new HashMap<>();
|
||||
res.put("suggest", names);
|
||||
return ResultUtil.ok(res);
|
||||
}
|
||||
|
||||
@GetMapping("/tags")
|
||||
public DataResult<Map<String,List<String>>> suggestTags(@RequestParam("k") String keyword){
|
||||
List<String> tags = postService.getSuggestTags(keyword);
|
||||
Map<String,List<String>> res = new HashMap<>();
|
||||
res.put("suggest", tags);
|
||||
return ResultUtil.ok(res);
|
||||
}
|
||||
|
||||
}
|
@ -3,5 +3,8 @@ package com.lk.paopao.repository;
|
||||
import com.lk.paopao.entity.PostCollection;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public interface PostCollectionRepository extends JpaRepository<PostCollection, Long> {
|
||||
Optional<PostCollection> findByUserIdAndPostId(Long userId, Long postId);
|
||||
}
|
@ -3,5 +3,8 @@ package com.lk.paopao.repository;
|
||||
import com.lk.paopao.entity.PostStar;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public interface PostStarRepository extends JpaRepository<PostStar, Long> {
|
||||
Optional<PostStar> findByUserIdAndPostId(Long postId, Long userId);
|
||||
}
|
@ -10,8 +10,8 @@ import java.util.Optional;
|
||||
|
||||
public interface TagRepository extends JpaRepository<Tag, Long> {
|
||||
|
||||
@Query("SELECT t.tag FROM Tag t WHERE t.tag LIKE CONCAT('%', :key, '%') ORDER BY t.tag ASC limit 20")
|
||||
List<String> findByTagContainingOrderByTagAsc(@Param("key") String key);
|
||||
@Query("SELECT t.tag FROM Tag t WHERE t.tag LIKE CONCAT('%', :key, '%') ORDER BY t.quoteNum DESC limit 20")
|
||||
List<String> findByTagContainingOrderByQuoteNumDesc(@Param("key") String key);
|
||||
|
||||
Optional<Tag> findByTag(String tag);
|
||||
|
||||
|
208
src/main/java/com/lk/paopao/service/PostService.java
Normal file
208
src/main/java/com/lk/paopao/service/PostService.java
Normal file
@ -0,0 +1,208 @@
|
||||
package com.lk.paopao.service;
|
||||
|
||||
import com.lk.paopao.dto.PostDto;
|
||||
import com.lk.paopao.dto.rest.request.PostRequest;
|
||||
import com.lk.paopao.dto.rest.response.Paged;
|
||||
import com.lk.paopao.entity.Post;
|
||||
import com.lk.paopao.entity.PostContent;
|
||||
import com.lk.paopao.entity.Tag;
|
||||
import com.lk.paopao.entity.User;
|
||||
import com.lk.paopao.exception.ResourceNotFoundException;
|
||||
import com.lk.paopao.mapper.PostMapper;
|
||||
import com.lk.paopao.mapper.TagMapper;
|
||||
import com.lk.paopao.repository.*;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.dao.OptimisticLockingFailureException;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 文章服务类,提供文章相关的业务逻辑处理
|
||||
*/
|
||||
@Service
|
||||
@Transactional
|
||||
public class PostService {
|
||||
// 注入所需的仓库和Mapper类以及其他服务
|
||||
@Autowired
|
||||
UserRepository userRepository;
|
||||
@Autowired
|
||||
PostRepository postRepository;
|
||||
|
||||
@Autowired
|
||||
TagRepository tagRepository;
|
||||
|
||||
@Autowired
|
||||
PostMapper postMapper;
|
||||
@Autowired
|
||||
TagMapper tagMapper;
|
||||
|
||||
@Autowired
|
||||
AuthService authService;
|
||||
@Autowired
|
||||
PostStarRepository postStarRepository;
|
||||
@Autowired
|
||||
PostCollectionRepository postCollectionRepository;
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(PostService.class);
|
||||
/**
|
||||
* 根据文章ID获取文章详情
|
||||
* @param id 文章ID
|
||||
* @return 文章DTO
|
||||
*/
|
||||
public PostDto getPost(Long id){
|
||||
Post post = postRepository.findById(id).orElseThrow(()->new ResourceNotFoundException("Post","id="+id));
|
||||
return postMapper.toDto(post);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文章列表
|
||||
* @param type 文章类型
|
||||
* @param style 文章样式
|
||||
* @param page 页码
|
||||
* @param size 每页大小
|
||||
* @return 文章DTO的分页数据
|
||||
*/
|
||||
public Paged<PostDto> getPosts(Long type, String style, Integer page, Integer size){
|
||||
size = size==null?10:size; // 如果未指定每页大小,默认为10
|
||||
|
||||
Sort sort = Sort.by(Sort.Direction.DESC, "createdOn"); // 按创建时间倒序排序
|
||||
Pageable pageable = PageRequest.of(page-1, size, sort); // 创建分页请求
|
||||
Page<Post> posts = postRepository.findAll(pageable); // 执行分页查询
|
||||
List<PostDto> dtos = new ArrayList<>(); // 用于存储转换后的DTO对象的列表
|
||||
posts.getContent().forEach((post)->{
|
||||
dtos.add(postMapper.toDto(post)); // 将查询结果转换为DTO
|
||||
});
|
||||
return new Paged<>(dtos,posts.getTotalElements(),page,posts.getSize()); // 构建并返回分页数据
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建文章
|
||||
* @param postRequest 创建文章的请求参数
|
||||
* @return 创建成功后的文章DTO
|
||||
*/
|
||||
public PostDto createPost(PostRequest postRequest){
|
||||
// 获取当前用户
|
||||
User user = authService.getCurrentUser();
|
||||
Post post = new Post();
|
||||
post.setUser(user);
|
||||
// 设置附件价格,默认为0
|
||||
post.setAttachmentPrice(postRequest.getAttachmentPrice()!=null?postRequest.getAttachmentPrice():0);
|
||||
// 设置文章可见性
|
||||
post.setVisibility(postRequest.getVisibility());
|
||||
// 文章内容
|
||||
List<PostContent> contents = new ArrayList<>();
|
||||
postRequest.getContents().forEach(contentReq -> {
|
||||
PostContent content = new PostContent();
|
||||
content.setContent(contentReq.getContent()); // 设置内容
|
||||
content.setSort(contentReq.getSort()); // 设置排序
|
||||
content.setType(contentReq.getType()); // 设置类型
|
||||
content.setPost(post); // 关联文章
|
||||
content.setUser(user); // 关联用户
|
||||
contents.add(content); // 添加到列表
|
||||
});
|
||||
post.setContents(contents);
|
||||
// 保存文章
|
||||
Post savedPost = postRepository.save(post);
|
||||
|
||||
// 处理post中的标签
|
||||
handleTags(postRequest, user);
|
||||
// 发送消息通知post中@的用户
|
||||
handleAtUser(postRequest, user);
|
||||
|
||||
return postMapper.toDto(savedPost);
|
||||
}
|
||||
|
||||
private void handleTags(PostRequest postRequest, User currentUser){
|
||||
// 处理post中的标签
|
||||
postRequest.getTags().forEach((tag)->{
|
||||
Tag tagEntity = tagRepository.findByTag(tag).orElse(null);
|
||||
if(tagEntity==null){
|
||||
// 如果标签不存在,则创建新标签并关联文章
|
||||
tagEntity = new Tag();
|
||||
tagEntity.setTag(tag);
|
||||
tagEntity.setUser(currentUser);
|
||||
tagEntity.setQuoteNum(1L);
|
||||
tagRepository.save(tagEntity);
|
||||
}else{
|
||||
// 如果标签已存在,则更新引用次数
|
||||
try {
|
||||
tagEntity.setQuoteNum(tagEntity.getQuoteNum() + 1L);
|
||||
tagRepository.save(tagEntity); // Spring Data JPA 自动处理乐观锁
|
||||
} catch (OptimisticLockingFailureException e) {
|
||||
// 处理乐观锁失败的情况,如重新获取实体并重试或记录日志等
|
||||
log.error("Optimistic locking failed for tag: {}", tagEntity.getTag(), e);
|
||||
// TODO: 可添加重试逻辑
|
||||
// 简单处理为继续抛出异常,让此次发帖失败
|
||||
throw e;
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void handleAtUser(PostRequest postRequest, User currentUser){
|
||||
postRequest.getUsers().forEach((username)->{
|
||||
User toUser = userRepository.findByUsername(username).orElseThrow(()->new ResourceNotFoundException("User","username="+username));
|
||||
// TODO: 发送消息通知toUser
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户推荐列表
|
||||
* @param keyword 关键字,用于筛选推荐用户
|
||||
* @return 符合条件的用户列表
|
||||
*/
|
||||
public List<String> getSuggestUsers(String keyword){
|
||||
// 如果关键字为空,则默认为空字符串
|
||||
keyword = keyword==null?"":keyword;
|
||||
// 根据关键字查询并按用户名升序返回用户列表
|
||||
return userRepository.findByUsernameContainingOrderByUsernameAsc(keyword);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取标签推荐列表
|
||||
* @param keyword 关键字,用于筛选推荐标签
|
||||
* @return 符合条件的标签列表
|
||||
*/
|
||||
public List<String> getSuggestTags(String keyword){
|
||||
keyword = keyword==null?"":keyword;
|
||||
// 根据关键字查询并按标签名升序返回标签列表
|
||||
return tagRepository.findByTagContainingOrderByQuoteNumDesc(keyword);
|
||||
}
|
||||
|
||||
/**
|
||||
* 封装帖子的分页数据。
|
||||
*
|
||||
* @param posts 分页的帖子数据。
|
||||
* @return 返回封装好的帖子分页数据。
|
||||
*/
|
||||
private Paged<PostDto> pageDataWrapper(Page<Post> posts){
|
||||
// 将帖子实体转换为DTO
|
||||
List<PostDto> dtos = new ArrayList<>();
|
||||
posts.getContent().forEach((post)->{
|
||||
dtos.add(postMapper.toDto(post));
|
||||
});
|
||||
// 返回封装好的分页数据
|
||||
return new Paged<>(dtos,posts.getTotalElements(),posts.getNumber()+1,posts.getSize());
|
||||
}
|
||||
|
||||
public boolean currentUserHasStarred(Long postId){
|
||||
User user = authService.getCurrentUser();
|
||||
return postStarRepository.findByUserIdAndPostId(user.getId(), postId).isPresent();
|
||||
}
|
||||
|
||||
public boolean currentUserHasCollected(Long postId){
|
||||
User user = authService.getCurrentUser();
|
||||
return postCollectionRepository.findByUserIdAndPostId(user.getId(), postId).isPresent();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user