package space.anyi.serve.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import space.anyi.serve.entity.order.OrderTip; import space.anyi.serve.entity.post.Post; import space.anyi.serve.entity.post.PostVo; import space.anyi.serve.entity.user.User; import space.anyi.serve.mapper.OrderTipMapper; import space.anyi.serve.mapper.PostMapper; import space.anyi.serve.mapper.PostViewRecordMapper; import space.anyi.serve.entity.post.PostViewRecord; import space.anyi.serve.service.PostService; import space.anyi.serve.service.UserService; import java.time.LocalDateTime; import java.util.List; import java.util.stream.Collectors; @Service public class PostServiceImpl extends ServiceImpl implements PostService { private final PostViewRecordMapper postViewRecordMapper; private final OrderTipMapper orderTipMapper; private final UserService userService; public PostServiceImpl(PostViewRecordMapper postViewRecordMapper, OrderTipMapper orderTipMapper, UserService userService) { this.postViewRecordMapper = postViewRecordMapper; this.orderTipMapper = orderTipMapper; this.userService = userService; } @Override public Page listPosts(String keyword, String status, int pageNum, int pageSize, Long currentUserId) { Page page = new Page<>(pageNum, pageSize); LambdaQueryWrapper wrapper = new LambdaQueryWrapper() .eq(Post::getDeleteFlag, 0); if (keyword != null && !keyword.isEmpty()) { wrapper.like(Post::getTitle, keyword); } LocalDateTime now = LocalDateTime.now(); if ("on_sale".equals(status)) { wrapper.gt(Post::getExpireTime, now); } else if ("public".equals(status)) { wrapper.le(Post::getExpireTime, now); } wrapper.orderByDesc(Post::getPublishTime); Page postPage = page(page, wrapper); List vos = postPage.getRecords().stream().map(post -> { PostVo vo = PostVo.from(post); User expert = userService.queryById(post.getExpertId()); if (expert != null) { vo.setExpertName(expert.getUsername()); vo.setExpertAvatar(expert.getAvatar()); } if (currentUserId != null) { vo.setIsPaid(hasUserPaid(post.getId(), currentUserId)); } return vo; }).collect(Collectors.toList()); Page result = new Page<>(postPage.getCurrent(), postPage.getSize(), postPage.getTotal()); result.setRecords(vos); if (currentUserId != null) { recordView(currentUserId, postPage.getRecords()); } return result; } @Override public PostVo getPostDetail(Long id, Long currentUserId) { Post post = getById(id); if (post == null || post.getDeleteFlag() == 1) return null; PostVo vo = PostVo.from(post); User expert = userService.queryById(post.getExpertId()); if (expert != null) { vo.setExpertName(expert.getUsername()); vo.setExpertAvatar(expert.getAvatar()); } boolean isExpired = LocalDateTime.now().isAfter(post.getExpireTime()); boolean isPaid = currentUserId != null && hasUserPaid(id, currentUserId); if (!isExpired && !isPaid) { vo.setContentPaid(null); } vo.setIsPaid(isPaid || isExpired); return vo; } @Override @Transactional public Long createPost(Post post) { post.setPublishTime(LocalDateTime.now()); post.setCreatedAt(LocalDateTime.now()); post.setUpdatedAt(LocalDateTime.now()); save(post); return post.getId(); } @Override @Transactional public void updateHitStatus(Long id, String hitStatus) { Post post = getById(id); if (post == null) throw new IllegalArgumentException("帖子不存在"); post.setHitStatus(hitStatus); post.setUpdatedAt(LocalDateTime.now()); updateById(post); } @Override @Transactional public void updateViewCount(Long id, Integer viewCount) { Post post = getById(id); if (post == null) throw new IllegalArgumentException("帖子不存在"); post.setViewCount(viewCount); post.setUpdatedAt(LocalDateTime.now()); updateById(post); } @Override public boolean hasUserPaid(Long postId, Long userId) { if (userId == null) return false; Long count = orderTipMapper.selectCount( new LambdaQueryWrapper() .eq(OrderTip::getPostId, postId) .eq(OrderTip::getUserId, userId) ); return count > 0; } @Override public Page listExpertPreviousPosts(Long expertId, int pageNum, int pageSize) { Page page = new Page<>(pageNum, pageSize); LambdaQueryWrapper wrapper = new LambdaQueryWrapper() .eq(Post::getExpertId, expertId) .le(Post::getExpireTime, LocalDateTime.now()) .eq(Post::getDeleteFlag, 0) .orderByDesc(Post::getPublishTime); return page(page, wrapper); } private void recordView(Long userId, List posts) { for (Post post : posts) { Long count = postViewRecordMapper.selectCount( new LambdaQueryWrapper() .eq(PostViewRecord::getPostId, post.getId()) .eq(PostViewRecord::getUserId, userId) ); if (count == 0) { PostViewRecord record = new PostViewRecord(); record.setPostId(post.getId()); record.setUserId(userId); record.setViewTime(LocalDateTime.now()); record.setCreatedAt(LocalDateTime.now()); record.setUpdatedAt(LocalDateTime.now()); postViewRecordMapper.insert(record); post.setViewCount(post.getViewCount() + 1); updateById(post); } } } }