仿牛客网项目---帖子详情功能的实现

news2024/11/15 1:56:36

这篇文章主要讲讲帖子详情功能。其实帖子详情功能简单来说就是你点进去可以看到文章,这就叫帖子详情功能。那接下来我讲讲我的这个项目是如何实现这个功能的。

首先写DAO层。

@Mapper
public interface DiscussPostMapper {

    List<DiscussPost> selectDiscussPosts(int userId, int offset, int limit, int orderMode);
    //查询讨论帖子列表的方法,根据给定的用户ID、偏移量、限制数量和排序方式来查询讨论帖子

    int selectDiscussPostRows(@Param("userId") int userId);
    //查询讨论帖子的总行数的方法,根据给定的用户ID来查询该用户发表的讨论帖子总数

    int insertDiscussPost(DiscussPost discussPost);
    //插入一条讨论帖子记录的方法,将给定的讨论帖子对象插入到数据库中

    DiscussPost selectDiscussPostById(int id);
    //根据给定的帖子ID查询讨论帖子的方法,返回对应ID的讨论帖子对象

    int updateCommentCount(int id, int commentCount);
    //更新讨论帖子的评论数量的方法,根据给定的帖子ID更新评论数量

    int updateType(int id, int type);
    //更新讨论帖子的类型的方法,根据给定的帖子ID更新类型

    int updateStatus(int id, int status);
    //更新讨论帖子的状态的方法,根据给定的帖子ID更新状态

    int updateScore(int id, double score);
    //更新讨论帖子的评分的方法,根据给定的帖子ID更新评分

}

再来写Service层。

    @PostConstruct
    public List<DiscussPost> findDiscussPosts(int userId, int offset, int limit, int orderMode) {
        if (userId == 0 && orderMode == 1) {
            return postListCache.get(offset + ":" + limit);
        }

        logger.debug("load post list from DB.");
        return discussPostMapper.selectDiscussPosts(userId, offset, limit, orderMode);
    }

    public int findDiscussPostRows(int userId) {
        if (userId == 0) {
            return postRowsCache.get(userId);
        }

        logger.debug("load post rows from DB.");
        return discussPostMapper.selectDiscussPostRows(userId);
    }

    public int addDiscussPost(DiscussPost post) {
        if (post == null) {
            throw new IllegalArgumentException("参数不能为空!");
        }

        // 转义HTML标记
        post.setTitle(HtmlUtils.htmlEscape(post.getTitle()));
        post.setContent(HtmlUtils.htmlEscape(post.getContent()));
        // 过滤敏感词
        post.setTitle(sensitiveFilter.filter(post.getTitle()));
        post.setContent(sensitiveFilter.filter(post.getContent()));

        return discussPostMapper.insertDiscussPost(post);
    }

    public DiscussPost findDiscussPostById(int id) {
        return discussPostMapper.selectDiscussPostById(id);
    }

    public int updateCommentCount(int id, int commentCount) {
        return discussPostMapper.updateCommentCount(id, commentCount);
    }

    public int updateType(int id, int type) {
        return discussPostMapper.updateType(id, type);
    }

    public int updateStatus(int id, int status) {
        return discussPostMapper.updateStatus(id, status);
    }

    public int updateScore(int id, double score) {
        return discussPostMapper.updateScore(id, score);
    }

service层的代码是一个帖子(DiscussPost)的服务类,提供了一些操作帖子的方法,并使用了缓存来提高性能。这段代码有点长,所以读起来有点费力,我讲一下我对这些代码的理解吧。

  • findDiscussPosts() 方法用于查询帖子列表。如果传入的用户ID为0且排序方式为1(orderMode == 1),则直接从缓存中获取对应的结果;否则,调用数据库查询方法从数据库中获取结果。
  • findDiscussPostRows() 方法用于查询帖子总数。如果传入的用户ID为0,则直接从缓存中获取对应的结果;否则,调用数据库查询方法从数据库中获取结果。
  • addDiscussPost() 方法用于添加帖子。在添加之前,会对帖子的标题和内容进行转义HTML标记和敏感词过滤的处理,然后调用数据库操作方法将帖子插入到数据库中,并返回插入的结果。
  • 其他方法如 findDiscussPostById()updateCommentCount()updateType()updateStatus()updateScore() 都是调用数据库操作方法来更新或查询帖子的相关信息。

service层大概就是这些,虽然说比较长,但是还是很容易懂的,controller层更加长。

最后写controller层。

@Controller
@RequestMapping("/discuss")
public class DiscussPostController implements CommunityConstant {

    @RequestMapping(path = "/add", method = RequestMethod.POST)
    @ResponseBody
    public String addDiscussPost(String title, String content) {
        User user = hostHolder.getUser();
        if (user == null) {
            return CommunityUtil.getJSONString(403, "你还没有登录哦!");
        }

        DiscussPost post = new DiscussPost();
        post.setUserId(user.getId());
        post.setTitle(title);
        post.setContent(content);
        post.setCreateTime(new Date());
        discussPostService.addDiscussPost(post);

        // 触发发帖事件
        Event event = new Event()
                .setTopic(TOPIC_PUBLISH)
                .setUserId(user.getId())
                .setEntityType(ENTITY_TYPE_POST)
                .setEntityId(post.getId());
        eventProducer.fireEvent(event);

        // 计算帖子分数
        String redisKey = RedisKeyUtil.getPostScoreKey();
        redisTemplate.opsForSet().add(redisKey, post.getId());

        // 报错的情况,将来统一处理.
        return CommunityUtil.getJSONString(0, "发布成功!");
    }

    @RequestMapping(path = "/detail/{discussPostId}", method = RequestMethod.GET)
    public String getDiscussPost(@PathVariable("discussPostId") int discussPostId, Model model, Page page) {
        // 帖子
        DiscussPost post = discussPostService.findDiscussPostById(discussPostId);
        model.addAttribute("post", post);
        // 作者
        User user = userService.findUserById(post.getUserId());
        model.addAttribute("user", user);
        // 点赞数量
        long likeCount = likeService.findEntityLikeCount(ENTITY_TYPE_POST, discussPostId);
        model.addAttribute("likeCount", likeCount);
        // 点赞状态
        int likeStatus = hostHolder.getUser() == null ? 0 :
                likeService.findEntityLikeStatus(hostHolder.getUser().getId(), ENTITY_TYPE_POST, discussPostId);
        model.addAttribute("likeStatus", likeStatus);

        // 评论分页信息
        page.setLimit(5);
        page.setPath("/discuss/detail/" + discussPostId);
        page.setRows(post.getCommentCount());

        // 评论: 给帖子的评论
        // 回复: 给评论的评论
        // 评论列表
        List<Comment> commentList = commentService.findCommentsByEntity(
                ENTITY_TYPE_POST, post.getId(), page.getOffset(), page.getLimit());
        // 评论VO列表
        List<Map<String, Object>> commentVoList = new ArrayList<>();
        if (commentList != null) {
            for (Comment comment : commentList) {
                // 评论VO
                Map<String, Object> commentVo = new HashMap<>();
                // 评论
                commentVo.put("comment", comment);
                // 作者
                commentVo.put("user", userService.findUserById(comment.getUserId()));
                // 点赞数量
                likeCount = likeService.findEntityLikeCount(ENTITY_TYPE_COMMENT, comment.getId());
                commentVo.put("likeCount", likeCount);
                // 点赞状态
                likeStatus = hostHolder.getUser() == null ? 0 :
                        likeService.findEntityLikeStatus(hostHolder.getUser().getId(), ENTITY_TYPE_COMMENT, comment.getId());
                commentVo.put("likeStatus", likeStatus);

                // 回复列表
                List<Comment> replyList = commentService.findCommentsByEntity(
                        ENTITY_TYPE_COMMENT, comment.getId(), 0, Integer.MAX_VALUE);
                // 回复VO列表
                List<Map<String, Object>> replyVoList = new ArrayList<>();
                if (replyList != null) {
                    for (Comment reply : replyList) {
                        Map<String, Object> replyVo = new HashMap<>();
                        // 回复
                        replyVo.put("reply", reply);
                        // 作者
                        replyVo.put("user", userService.findUserById(reply.getUserId()));
                        // 回复目标
                        User target = reply.getTargetId() == 0 ? null : userService.findUserById(reply.getTargetId());
                        replyVo.put("target", target);
                        // 点赞数量
                        likeCount = likeService.findEntityLikeCount(ENTITY_TYPE_COMMENT, reply.getId());
                        replyVo.put("likeCount", likeCount);
                        // 点赞状态
                        likeStatus = hostHolder.getUser() == null ? 0 :
                                likeService.findEntityLikeStatus(hostHolder.getUser().getId(), ENTITY_TYPE_COMMENT, reply.getId());
                        replyVo.put("likeStatus", likeStatus);

                        replyVoList.add(replyVo);
                    }
                }
                commentVo.put("replys", replyVoList);

                // 回复数量
                int replyCount = commentService.findCommentCount(ENTITY_TYPE_COMMENT, comment.getId());
                commentVo.put("replyCount", replyCount);

                commentVoList.add(commentVo);
            }
        }

        model.addAttribute("comments", commentVoList);

        return "/site/discuss-detail";
    }

    // 置顶
    @RequestMapping(path = "/top", method = RequestMethod.POST)
    @ResponseBody
    public String setTop(int id) {
        discussPostService.updateType(id, 1);

        // 触发发帖事件
        Event event = new Event()
                .setTopic(TOPIC_PUBLISH)
                .setUserId(hostHolder.getUser().getId())
                .setEntityType(ENTITY_TYPE_POST)
                .setEntityId(id);
        eventProducer.fireEvent(event);

        return CommunityUtil.getJSONString(0);
    }

    // 加精
    @RequestMapping(path = "/wonderful", method = RequestMethod.POST)
    @ResponseBody
    public String setWonderful(int id) {
        discussPostService.updateStatus(id, 1);

        // 触发发帖事件
        Event event = new Event()
                .setTopic(TOPIC_PUBLISH)
                .setUserId(hostHolder.getUser().getId())
                .setEntityType(ENTITY_TYPE_POST)
                .setEntityId(id);
        eventProducer.fireEvent(event);

        // 计算帖子分数
        String redisKey = RedisKeyUtil.getPostScoreKey();
        redisTemplate.opsForSet().add(redisKey, id);

        return CommunityUtil.getJSONString(0);
    }

    // 删除
    @RequestMapping(path = "/delete", method = RequestMethod.POST)
    @ResponseBody
    public String setDelete(int id) {
        discussPostService.updateStatus(id, 2);

        // 触发删帖事件
        Event event = new Event()
                .setTopic(TOPIC_DELETE)
                .setUserId(hostHolder.getUser().getId())
                .setEntityType(ENTITY_TYPE_POST)
                .setEntityId(id);
        eventProducer.fireEvent(event);

        return CommunityUtil.getJSONString(0);
    }

}

这段代码是一个控制器类,处理与帖子相关的请求。 

首先是 addDiscussPost() 方法,用于处理发布帖子的请求。在方法中首先判断用户是否登录,如果未登录则返回相应的提示信息。然后根据传入的参数创建一个 DiscussPost 对象,并设置相应的属性。接下来调用 discussPostService.addDiscussPost(post) 方法将帖子插入到数据库中。之后触发一个发帖事件,并计算帖子的分数。最后返回一个 JSON 格式的发布成功信息。

接下来是 getDiscussPost() 方法,用于获取帖子详情的请求。首先根据传入的帖子ID调用 discussPostService.findDiscussPostById(discussPostId) 方法获取帖子对象,并将帖子对象添加到 Model 中。然后获取帖子的作者、点赞数量和点赞状态,并将它们添加到 Model 中。接着设置评论的分页信息,并调用 commentService.findCommentsByEntity() 方法获取帖子的评论列表。通过遍历评论列表,将每个评论及其相关信息封装成一个评论VO(Map<String, Object>),并将评论VO添加到评论VO列表中。对于每个评论,还会获取其回复列表,并将每个回复及其相关信息封装成一个回复VO(Map<String, Object>),再将回复VO添加到回复VO列表中。最后将评论VO列表添加到 Model 中,并返回一个指向帖子详情页面的视图。

接下来是 setTop() 方法,用于置顶帖子的请求。在方法中调用 discussPostService.updateType(id, 1) 方法将帖子的类型设置为置顶。然后触发一个发帖事件,并返回一个 JSON 格式的成功信息。

最后是 setDelete() 方法,用于删除帖子的请求。在方法中调用 discussPostService.updateStatus(id, 2) 方法将帖子的状态设置为删除。然后触发一个删帖事件,并返回一个 JSON 格式的成功信息。

其实对于帖子详情这里并不算太重要,我觉得好好看看,知道有这么一回事儿就行,不需要刻意的去背,背的话其实也用不到,但是你确实需要知道这么一回事儿。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1481298.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Unity】在Unity中导出WebGL并读取Excel数据的实现方法

在游戏开发中&#xff0c;数据的处理和导出是至关重要的环节之一。Unity作为一款强大的游戏开发引擎&#xff0c;提供了丰富的工具和功能来处理和导出数据&#xff0c;包括将游戏导出为WebGL应用&#xff0c;并读取外部数据文件&#xff0c;比如Excel表格。本文将介绍如何在Uni…

Navicat Premium 16:打破数据库界限,实现高效管理mac/win版

Navicat Premium 16是一款功能强大的数据库管理工具&#xff0c;旨在帮助用户更轻松地连接、管理和保护各种数据库。该软件支持多种数据库系统&#xff0c;如MySQL、Oracle、SQL Server、PostgreSQL等&#xff0c;并提供了直观的图形界面&#xff0c;使用户能够轻松地完成各种数…

计算机网络_2.2物理层下面的传输媒体

2.2物理层下面的传输媒体 一、传输媒体的分类二、导向型传输媒体1、同轴电缆2、双绞线3、光纤&#xff08;1&#xff09;光纤通信原理&#xff08;2&#xff09;光纤组成&#xff08;4&#xff09;多模光纤与单模光纤对比&#xff08;5&#xff09;光纤的波长与规格&#xff08…

WSL2部署RV1126 SDK编译环境

1 下载RV1126 SDK 在 Firefly | 让科技更简单&#xff0c;让生活更智能 下载REPO_SDK 这里将SDK下载到了F:\SDK 2 解压SDK到WSL2 tar -xvf /mnt/f/SDK/rv1126_rv1109_linux_release_20211022.tgz 3 编译依赖安装 gcc、g版本依赖安装 sudo apt-get install lib32gcc-7-dev g-7 l…

【center-loss 中心损失函数】 原理及程序解释(更新中)

文章目录 前言问题引出open-set问题抛出 解决方法softmax函数、softmax-loss函数解决代码&#xff08;center_loss.py&#xff09;原理程序解释 代码运用 如何梯度更新首先了解一下基本的梯度下降算法然后 补充&#xff1a;外围知识模型 前言 学习一下&#xff1a; 中心损失函…

你真的了解C语言中的【柔性数组】吗~

柔性数组 1. 什么是柔性数组2. 柔性数组的特点3. 柔性数组的使用4. 柔性数组的优势 1. 什么是柔性数组 也许你从来没有听说过柔性数组这个概念&#xff0c;但是它确实是存在的。 C99中&#xff0c;结构体中的最后⼀个元素允许是未知大小的数组&#xff0c;这就叫做柔性数组成员…

2024年腾讯云优惠券领取入口、查看使用和常见问题解答FAQ

腾讯云代金券领取渠道有哪些&#xff1f;腾讯云官网可以领取、官方媒体账号可以领取代金券、完成任务可以领取代金券&#xff0c;大家也可以在腾讯云百科蹲守代金券&#xff0c;因为腾讯云代金券领取渠道比较分散&#xff0c;腾讯云百科txybk.com专注汇总优惠代金券领取页面&am…

力扣hot100题解(python版36-40题)

36、二叉树的中序遍历 给定一个二叉树的根节点 root &#xff0c;返回 它的 *中序 遍历* 。 示例 1&#xff1a; 输入&#xff1a;root [1,null,2,3] 输出&#xff1a;[1,3,2]示例 2&#xff1a; 输入&#xff1a;root [] 输出&#xff1a;[]示例 3&#xff1a; 输入&am…

Mysql主从备份

主从复制概述 将主服务器的binlog日志复制到从服务器上执行一遍&#xff0c;达到主从数据的一致状态&#xff0c;称之为主从复制。一句话表示就是&#xff0c;主数据库做什么&#xff0c;从数据库就跟着做什么。 为什么要使用主从复制 为实现服务器负载均衡/读写分离做铺垫&…

队列的结构概念和实现

文章目录 一、队列的结构和概念二、队列的实现三、队列的实现函数四、队列的思维导图 一、队列的结构和概念 什么是队列&#xff1f; 队列就是只允许在一端进行插入数据操作&#xff0c;在另一端进行删除数据操作的特殊线性表&#xff0c;队列具有先进先出 如上图所示&#x…

Ansible的playbook的编写和解析

目录 什么是playbook Ansible 的脚本 --- playbook 剧本 实例部署&#xff08;使用playbook安装启动httpd服务&#xff09; 1.编写一个.yaml文件 在主机下载安装http&#xff0c;将配置文件复制到opt目录下 运行playbook 在192.168.17.77主机上查看httpd服务是否成功开启…

BY组态功能清单

演示地址 &#xff1a;http://www.byzt.net:60/sm/ 官网地址&#xff1a;http://www.hcy-soft.com BY组态是一款非常优秀的纯前端的【web组态插件工具】&#xff0c;可无缝嵌入到vue项目&#xff0c;react项目等&#xff0c;由于是原生js开发&#xff0c;对于前端的集成没有框架…

vue2 引入阿里图标库iconfont

有时候我们使用的 ui 里面图标是不够丰富的&#xff0c;不一定可以满足我们的需求。 这时我们可以引入阿里图标库来丰富自己的项目图标。 上步骤&#xff1a; 1、点击文字地址连接&#xff1a; iconfont-阿里巴巴矢量图标库 2、登录&#xff0c;没有账号需要先使用手机号注册…

【Java题】调整奇数位于偶数之前(超简单版)

题目&#xff1a; 调整数组顺序使得奇数位于偶数之前。调整之后&#xff0c;不关心大小顺序。 如数组&#xff1a;[1,2,3,4,5,6,7,8,9] 调整后可能是&#xff1a;[1, 9,3,7,5, 6, 4, 8, 2] 代码&#xff1a; import java.util.Arrays;public class Main {public static voi…

MySQL存储引擎及索引机制

MySQL技术——存储引擎和索引机制 一、存储引擎概述二、常见存储引擎的区别三、索引机制四、索引的底层实现原理五、InnoDB主键和二级索引六、聚集索引和非聚集索引七、哈希索引八、InnoDB的自适应哈希索引九、索引常见问题十、慢查询日志总结 一、存储引擎概述 插件式存储引擎…

b站小土堆pytorch学习记录——P7-P8 Tensorboard的使用

文章目录 一、前置知识1.Tensorboard是什么2.SummaryWriter3.add_scalar()4.add_image() 二、代码1.一次函数2.蚂蚁和蜜蜂图片 一、前置知识 1.Tensorboard是什么 TensorBoard 是 TensorFlow 的可视化工具&#xff0c;它允许开发者可视化模型的图&#xff08;graph&#xff0…

一线互联网大厂中高级Android面试真题收录,记一次字节跳动Android社招面试

在开始回答前&#xff0c;先简单概括性地说说Linux现有的所有进程间IPC方式&#xff1a; 1. **管道&#xff1a;**在创建时分配一个page大小的内存&#xff0c;缓存区大小比较有限&#xff1b; 2. 消息队列&#xff1a;信息复制两次&#xff0c;额外的CPU消耗&#xff1b;不合…

驱动高级--mknod

一、起源 仅devfs&#xff0c;导致开发不方便以及一些功能难以支持&#xff1a; 热插拔 不支持一些针对所有设备的统一操作&#xff08;如电源管理&#xff09; 不能自动mknod 用户查看不了设备信息 设备信息硬编码&#xff0c;导致驱动代码通用性差&#xff0c;即没有分离…

【Python】成功解决ValueError: not enough values to unpack (expected 2, got 1)

【Python】成功解决ValueError: not enough values to unpack (expected 2, got 1) &#x1f308; 个人主页&#xff1a;高斯小哥 &#x1f525; 高质量专栏&#xff1a;Matplotlib之旅&#xff1a;零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程&am…

本科毕业设计:计及并网依赖性的分布式能源系统优化研究。(C语言实现)(内包含NSGA II优化算法)(二)

目录 前言 1、sofc函数 2、光伏板函数 3、集热场函数 4、sofc电跟随策略函数 5、二分法找sofc运行点函数 6、目标函数&#xff1a;成本 7、目标函数&#xff1a;二氧化碳排放量 8、目标函数&#xff1a;并网依赖性 前言 本篇文章介绍的是我的毕业设计&#xff0c;我将C…