Spring Boot项目学习14之帖子收藏模块

1.收藏表的设计

收藏表最主要包含有以下几个字段:

  • 主键id
  • 收藏帖子的主键
  • 收藏者的id
  • 收藏时间
DROP TABLE IF EXISTS `tb_post_collect_record`;

CREATE TABLE `tb_post_collect_record` (
      `record_id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键id',
      `post_id` bigint NOT NULL DEFAULT '0' COMMENT '收藏帖子主键',
      `user_id` bigint NOT NULL DEFAULT '0' COMMENT '收藏者id',
      `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '收藏时间',
       PRIMARY KEY (`record_id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC;

2. 实现收藏模块

2.1 收藏实体类

BBSPostCollect

public class BBSPostCollect {
    private Long recordId;

    private Long postId;

    private Long userId;

    private Date createTime;

    public Long getRecordId() {
        return recordId;
    }

    public void setRecordId(Long recordId) {
        this.recordId = recordId;
    }

    public Long getPostId() {
        return postId;
    }

    public void setPostId(Long postId) {
        this.postId = postId;
    }

    public Long getUserId() {
        return userId;
    }

    public void setUserId(Long userId) {
        this.userId = userId;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append(getClass().getSimpleName());
        sb.append(" [");
        sb.append("Hash = ").append(hashCode());
        sb.append(", recordId=").append(recordId);
        sb.append(", postId=").append(postId);
        sb.append(", userId=").append(userId);
        sb.append(", createTime=").append(createTime);
        sb.append("]");
        return sb.toString();
    }
}

2.2 收藏模块展示

在BBSPostController控制类的postDetail()方法中添加收藏帖子功能。

        // todo 是否收藏了本贴
        BBSUser currentUser = (BBSUser) request.getSession().getAttribute(Constants.USER_SESSION_KEY);
        request.setAttribute("currentUserCollectFlag", bbsPostCollectService.validUserCollect(currentUser.getUserId(), postId));

BBSPostCollectService

public interface BBSPostCollectService {
    /**
     * 验证用户是否收藏了帖子
     *
     * @param userId
     * @param postId
     * @return
     */
    Boolean validUserCollect(Long userId, Long postId);
}
@Service
public class BBSPostCollectServiceImpl implements BBSPostCollectService {

    @Autowired
    private BBSPostCollectMapper bbsPostCollectMapper;

    @Autowired
    private BBSPostMapper bbsPostMapper;

    @Autowired
    private BBSUserMapper bbsUserMapper;

        @Override
    public Boolean validUserCollect(Long userId, Long postId) {
        BBSPostCollect bbsPostCollect = bbsPostCollectMapper.selectByUserIdAndPostId(userId, postId);
        if (bbsPostCollect == null) {
            return false;
        }
        return true;
    }
}

BBSPostCollectMapper

public interface BBSPostCollectMapper {
    BBSPostCollect selectByUserIdAndPostId(@Param("userId") Long userId, @Param("postId") Long postId);
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="top.picacho.bbs.dao.BBSPostCollectMapper">
    <resultMap id="BaseResultMap" type="top.picacho.bbs.entity.BBSPostCollect">
        <id column="record_id" jdbcType="BIGINT" property="recordId" />
        <result column="post_id" jdbcType="BIGINT" property="postId" />
        <result column="user_id" jdbcType="BIGINT" property="userId" />
        <result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
    </resultMap>
    <sql id="Base_Column_List">
        record_id, post_id, user_id, create_time
    </sql>

    <select id="selectByUserIdAndPostId" resultMap="BaseResultMap">
        select
        <include refid="Base_Column_List" />
        from tb_post_collect_record
        where post_id = #{postId,jdbcType=BIGINT} and user_id = #{userId,jdbcType=BIGINT} limit 1
    </select>
</mapper>

2.3 前端页面

         <div style="text-align: center;">
                    <th:block th:unless="${currentUserCollectFlag}">
                        <a href="##" th:onclick="'collect('+${bbsPost.postId}+')'">
                        <span style="color: red;">
                            <i class="iconfont icon-zan"></i>
                            收藏&nbsp;&nbsp;(<th:block th:text="${bbsPost.postCollects}"></th:block>)
                        </span>
                        </a>
                    </th:block>
                    <th:block th:if="${currentUserCollectFlag}">
                        <a href="##" th:onclick="'delCollect('+${bbsPost.postId}+')'">
                        <span style="color: grey;">
                            <i class="iconfont icon-zan"></i>
                            取消收藏&nbsp;&nbsp;(<th:block th:text="${bbsPost.postCollects}"></th:block>)
                        </span>
                        </a>
                    </th:block>
                </div>

2.4 测试效果

在这里插入图片描述

2.5 添加收藏的接口

BBSPostCollectController

@Controller
public class BBSPostCollectController {

    @Resource
    private BBSPostCollectService bbsPostCollectService;

    @PostMapping("/addCollect/{postId}")
    @ResponseBody
    public Result addCollect(@PathVariable("postId") Long postId,
                             HttpSession httpSession) {
        if (null == postId || postId < 0) {
            return ResultGenerator.genFailResult("postId参数错误");
        }
        BBSUser bbsUser = (BBSUser) httpSession.getAttribute(Constants.USER_SESSION_KEY);
        if (bbsPostCollectService.addCollectRecord(bbsUser.getUserId(), postId)) {
            return ResultGenerator.genSuccessResult();
        } else {
            return ResultGenerator.genFailResult("请求失败,请检查参数及账号是否有操作权限");
        }
    }
}

BBSPostCollectService

public interface BBSPostCollectService {

    /**
     * 收藏帖子
     *
     * @param userId
     * @param postId
     * @return
     */
    Boolean addCollectRecord(Long userId, Long postId);
}
@Service
public class BBSPostCollectServiceImpl implements BBSPostCollectService {

    @Autowired
    private BBSPostCollectMapper bbsPostCollectMapper;

    @Autowired
    private BBSPostMapper bbsPostMapper;

    @Autowired
    private BBSUserMapper bbsUserMapper;

    @Override
    @Transactional
    public Boolean addCollectRecord(Long userId, Long postId) {

        BBSPostCollect bbsPostCollect = bbsPostCollectMapper.selectByUserIdAndPostId(userId, postId);

        BBSUser bbsUser = bbsUserMapper.selectByPrimaryKey(userId);

        if (bbsUser == null || bbsUser.getUserStatus().intValue() == 1) {
            //账号已被封禁
            return false;
        }

        if (bbsPostCollect != null) {
            return true;
        } else {
            bbsPostCollect = new BBSPostCollect();
            bbsPostCollect.setPostId(postId);
            bbsPostCollect.setUserId(userId);

            //收藏数量加1
            BBSPost bbsPost = bbsPostMapper.selectByPrimaryKey(postId);

            bbsPost.setPostCollects(bbsPost.getPostCollects() + 1);

            if (bbsPostCollectMapper.insertSelective(bbsPostCollect) > 0 && bbsPostMapper.updateByPrimaryKey(bbsPost) > 0) {
                return true;
            }
        }
        return false;
    }
}

这里首先通过帖子id和用户id查询出收藏实体,如果存在说明已经已经收藏了直接返回;如果不存在说明没有收藏过,那么按正常的添加收藏实体,并且更新帖子的收藏数。

BBSPostCollectMapper

public interface BBSPostCollectMapper {
    BBSPostCollect selectByUserIdAndPostId(@Param("userId") Long userId, @Param("postId") Long postId);

	int insertSelective(BBSPostCollect record);
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="top.picacho.bbs.dao.BBSPostCollectMapper">
    <resultMap id="BaseResultMap" type="top.picacho.bbs.entity.BBSPostCollect">
        <id column="record_id" jdbcType="BIGINT" property="recordId" />
        <result column="post_id" jdbcType="BIGINT" property="postId" />
        <result column="user_id" jdbcType="BIGINT" property="userId" />
        <result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
    </resultMap>
    <sql id="Base_Column_List">
        record_id, post_id, user_id, create_time
    </sql>

    <select id="selectByUserIdAndPostId" resultMap="BaseResultMap">
        select
        <include refid="Base_Column_List" />
        from tb_post_collect_record
        where post_id = #{postId,jdbcType=BIGINT} and user_id = #{userId,jdbcType=BIGINT} limit 1
    </select>

    <insert id="insertSelective" parameterType="top.picacho.bbs.entity.BBSPostCollect">
        insert into tb_post_collect_record
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="recordId != null">
                record_id,
            </if>
            <if test="postId != null">
                post_id,
            </if>
            <if test="userId != null">
                user_id,
            </if>
            <if test="createTime != null">
                create_time,
            </if>
        </trim>
        <trim prefix="values (" suffix=")" suffixOverrides=",">
            <if test="recordId != null">
                #{recordId,jdbcType=BIGINT},
            </if>
            <if test="postId != null">
                #{postId,jdbcType=BIGINT},
            </if>
            <if test="userId != null">
                #{userId,jdbcType=BIGINT},
            </if>
            <if test="createTime != null">
                #{createTime,jdbcType=TIMESTAMP},
            </if>
        </trim>
    </insert>
</mapper>

BBSPostMapper

int updateByPrimaryKey(BBSPost record);
    <update id="updateByPrimaryKey" parameterType="top.picacho.bbs.entity.BBSPost">
        update tb_bbs_post
        set publish_user_id    = #{publishUserId,jdbcType=BIGINT},
            post_title         = #{postTitle,jdbcType=VARCHAR},
            post_category_id   = #{postCategoryId,jdbcType=INTEGER},
            post_category_name = #{postCategoryName,jdbcType=VARCHAR},
            post_status        = #{postStatus,jdbcType=TINYINT},
            post_views         = #{postViews,jdbcType=BIGINT},
            post_comments      = #{postComments,jdbcType=BIGINT},
            post_collects      = #{postCollects,jdbcType=BIGINT},
            last_update_time   = #{lastUpdateTime,jdbcType=TIMESTAMP},
            create_time        = #{createTime,jdbcType=TIMESTAMP}
        where post_id = #{postId,jdbcType=BIGINT}
    </update>

2.6 前端逻辑

在detail.html页面添加收藏板块。
在这里插入图片描述

        //收藏
        window.collect = function (postId) {
            var $ = layui.$;
            $.ajax({
                type: 'POST',//方法类型
                url: '/addCollect/' + postId,
                success: function (result) {
                    if (result.resultCode == 200) {
                        layer.confirm('收藏成功!将刷新本页面...', {
                            icon: 3,
                            skin: 'layui-layer-molv',
                            title: '提示'
                        }, function (index) {
                            layer.close(index);
                            window.location.reload();
                        });
                    } else {
                        layer.msg(result.message);
                    }
                    ;
                },
                error: function () {
                    layer.alert('操作失败!', {title: '提醒', skin: 'layui-layer-molv', icon: 2});
                }
            });
        }

2.7 测试效果

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.8 取消收藏的接口

BBSPostCollectController

    @PostMapping("/delCollect/{postId}")
    @ResponseBody
    public Result delCollect(@PathVariable("postId") Long postId,
                             HttpSession httpSession) {
        if (null == postId || postId < 0) {
            return ResultGenerator.genFailResult("postId参数错误");
        }
        BBSUser bbsUser = (BBSUser) httpSession.getAttribute(Constants.USER_SESSION_KEY);
        if (bbsPostCollectService.deleteCollectRecord(bbsUser.getUserId(), postId)) {
            return ResultGenerator.genSuccessResult();
        } else {
            return ResultGenerator.genFailResult("请求失败,请检查参数及账号是否有操作权限");
        }
    }

BBSPostCollectService

    /**
     * 取消收藏帖子
     *
     * @param userId
     * @param postId
     * @return
     */
    Boolean deleteCollectRecord(Long userId, Long postId);
    @Override
    @Transactional
    public Boolean deleteCollectRecord(Long userId, Long postId) {

        BBSPostCollect bbsPostCollect = bbsPostCollectMapper.selectByUserIdAndPostId(userId, postId);

        BBSUser bbsUser = bbsUserMapper.selectByPrimaryKey(userId);

        if (bbsUser == null || bbsUser.getUserStatus().intValue() == 1) {
            //账号已被封禁
            return false;
        }

        if (bbsPostCollect == null) {
            return true;
        } else {
            //收藏数量减1
            BBSPost bbsPost = bbsPostMapper.selectByPrimaryKey(postId);

            Long collectCount = bbsPost.getPostCollects() - 1;
            if (collectCount >= 0) {
                bbsPost.setPostCollects(collectCount);
            }

            if (bbsPostCollectMapper.deleteByPrimaryKey(bbsPostCollect.getRecordId()) > 0 && bbsPostMapper.updateByPrimaryKey(bbsPost) > 0) {
                return true;
            }
        }
        return false;
    }

BBSPostCollectMapper

int deleteByPrimaryKey(Long recordId);
    <delete id="deleteByPrimaryKey" parameterType="java.lang.Long">
        delete from tb_post_collect_record
        where record_id = #{recordId,jdbcType=BIGINT}
    </delete>

2.9 前端逻辑

在这里插入图片描述

                    <th:block th:if="${currentUserCollectFlag}">
                        <a href="##" th:onclick="'delCollect('+${bbsPost.postId}+')'">
                        <span style="color: grey;">
                            <i class="iconfont icon-zan"></i>
                            取消收藏&nbsp;&nbsp;(<th:block th:text="${bbsPost.postCollects}"></th:block>)
                        </span>
                        </a>
                    </th:block>
        //取消收藏
        window.delCollect = function (postId) {
            var $ = layui.$;
            $.ajax({
                type: 'POST',//方法类型
                url: '/delCollect/' + postId,
                success: function (result) {
                    if (result.resultCode == 200) {
                        layer.confirm('取消收藏成功!将刷新本页面...', {
                            icon: 3,
                            skin: 'layui-layer-molv',
                            title: '提示'
                        }, function (index) {
                            layer.close(index);
                            window.location.reload();
                        });
                    } else {
                        layer.msg(result.message);
                    }
                    ;
                },
                error: function () {
                    layer.alert('操作失败!', {title: '提醒', skin: 'layui-layer-molv', icon: 2});
                }
            });
        }

2.10 测试效果

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

项目源码地址下载:源码下载

  • 3
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
课程简介这是一门使用Java语言,SpringBoot框架,从0开发一个RESTful API应用,接近企业级的项目(我的云音乐),课程包含了基础内容,高级内容,项目封装,项目重构等知识,99%代码为手写;因为这是项目课程;所以不会深入到源码讲解某个知识点,以及原理,但会粗略的讲解下基础原理;主要是讲解如何使用系统功能,流行的第三方框架,第三方服务,完成接近企业级项目,目的是让大家,学到真正的企业级项目开发技术。适用人群刚刚毕业的学生想提高职场竞争力想学从零开发SpringBoot项目想提升SpringBoot项目开发技术想学习SpringBoot项目架构技术想学习企业级项目开发技术就是想学习SpringBoot开发能学到什么从0开发一个类似企业级项目学会能做出市面上90%通用API快速增加1到2年实际开发经验刚毕业学完后能找到满意的工作已经工作学完后最高涨薪30%课程信息全课程目前是82章,155小时,每节视频都经过精心剪辑。在线学习分辨率最高1080P课程知识点1~11章:学习方法,项目架构,编码规范,Postman使用方法,Git和Github版本控制12~16章:搭建开发环境,快速入门SpringBoot框架17~20章:快速入门MySQL数据库21~30章:MyBatis,登录注册,找回密码,发送短信,发送邮件,企业级接口配置31~41章:实现歌单,歌单标签,音乐,列表分页,视频,评论,好友功能42~48章:阿里云OSS,话题,MyBatis-plus,应用监控49~53章:Redis使用,集成Redis,SpringCache,HTTP缓存54~58章:Elasticsearch使用,集成Elasticsearch,使用ES搜索59~61章:商城,集成支付宝SDK,支付宝支付62~64章:常用哈希和加密算法,接口加密和签名65~67章:实时挤掉用户,企业级项目测试环境,企业级接口文档68~69章:SpringBoot全站HTTPS,自签证书,申请免费证书70~73章:云MySQL数据库,云Redis数据库使用,轻量级应用部署环境,域名解析74~80章:Docker使用,生产级Kubernetes集群,域名解析,集群全站HTTPS81~82章:增强和重构项目,课程总结,后续学习计划
对于学习 Spring Boot项目学习路线,可以按照以下步骤进行: 1. 第一阶段:了解基础知识和概念。在此阶段,你可以开始学习 Spring Boot 的基础知识和核心概念,包括 Spring Framework、Spring Boot 的特点和优势等。可以参考中提供的学习路线,掌握基础知识和概念是深入学习 Spring Boot 的基础。 2. 第二阶段:学习 Spring Boot Starter。Spring Boot Starter 是 Spring Boot 的一个重要特性,它提供了一种快速集成常用框架和库的方式。在此阶段,你可以学习如何使用已有的 Starter,例如 Spring Data JPA、Thymeleaf 等,来快速集成这些常用框架和库。这将有助于你在实际项目中更快地构建应用程序。可以参考中提供的学习内容,深入理解 Spring Boot Starter 的概念和作用。 3. 第三阶段:深入学习 Spring Boot 特性和功能。在这个阶段,你可以进一步深入学习 Spring Boot 的各种特性和功能,例如自动配置、Actuator、Spring Boot DevTools、Spring Security 等。通过学习和实践,你将能够更好地理解和应用这些功能,进一步提升你的开发能力。可以参考中提供的学习路线,逐步掌握 Spring Boot 的核心概念和功能。 通过以上学习路线,你可以系统地学习和掌握 Spring Boot 的核心概念和功能。随着实践项目的进行和不断学习,你将能够应对更复杂的需求和场景,深入理解和运用 Spring Boot 的各种特性和功能。希望这个学习路线对你的学习有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

picacho_pkq

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值