uniapp+node.js前后端做帖子模块:帖子的点赞/取消点赞(社区管理平台的小程序)

@TOC


👍 点赞,你的认可是我创作的动力!

⭐️ 收藏,你的青睐是我努力的方向!

✏️ 评论,你的意见是我进步的财富!


0前提

温馨提示:我做的思路可能是复杂化了或者说代码写的不规范,如果你觉得可以更加简便的话欢迎分享到评论区或者自己改写一下我的代码,我的后端是写的很简单的没有什么路由分发是直接写的,你可以自由优化 小程序的其他部分你可以看看我往期的文章

1.一些准备

1.1表

帖子表 post

字段名称 类型(长度) 允许空 主键 外键 自增 唯一 说明
id int 帖子id
title varchar(20) 标题
content varchar(20) 内容
images varchar(200) 详情表
classification varchar(20) 帖子分类
likes int 点赞数
comments int 评论数
shares int 分享数
userId int 用户id
communityId int 小区id
creatTime timestamp 创建时间
updateTime timestamp 数据改变时的时间

帖子点赞表 postLike

字段名称 类型(长度) 允许空 主键 外键 自增 唯一 说明
id int 帖子点赞id
postId int 帖子id
userId int 用户id
creatTime timestamp 创建时间
updateTime timestamp 数据改变时的时间

1.2总体思路

当用户点击帖子上的点赞按钮之后,调用点赞/取消点赞的方法,向后端传入用户id和帖子id,在后端进行判断是点赞还是取消点赞执行不同的操作,执行成功之后更新帖子按钮的颜色和点赞数

2.点赞前端

当用户想要进行点赞操作时还需要去阻拦一下用户,查看一下用户有没有登陆,如果登录之后才可以进入到这个发帖页(我这里是没有写的是直接默认根据用户登陆了,写的话思路就是查询本地存储是否有token和用户信息)。当用户进行点赞操作之后,向后端传入这个用户的id和被点赞/取消点赞的帖子id,然后执行成功之后更新帖子按钮的颜色和点赞数

ini 复制代码
            <view class="icons">
              <view>
                <uni-icons :type="post.isLiked ? 'hand-up-filled' : 'hand-up'" @click="handleLike(post)"></uni-icons> {{ post.likes }}
              </view>
    // 处理用户点赞/取消点赞操作
    async handleLike(post) {
          const userId = this.$store.state.user.id;
          const res = await this.$myRequest({
            method: 'post',
            url: '/like',
            data: {
              postId: post.id,
              userId: userId
            }
          });
          if (res.data.error) {
            uni.showToast({
              title: '点赞失败',
              icon: 'none'
            });
          } else {
            post.isLiked = !post.isLiked;
            post.likes = res.data.likesCount;
          }
        },

3.后端

后端:当接受到前端传来的信息之后到数据库里面去新增这一条帖子信息,这里也是需要验证用户信息的就是验证前端传来的token解析之后是否和传来的用户id是一致的(不过我没加😊,这个验证可以自己搞搞加) 当接受到前端传来的信息时去查看一下这个帖子是否被当前用户点赞,如果被当前用户点赞过则执行的是取消点赞的操作,如果用户没有被用户点赞过则执行的是点赞操作 取消点赞:删除帖子点赞表中对应帖子id和用户id的数据,更新帖子表的点赞数减一并且返回点赞数 点赞操作:增加一条帖子点赞表的数据,更新帖子表的点赞数加一并且返回点赞数(这样子前端就不用再去重新查询一遍帖子列表来获取数据了)

javascript 复制代码
// 点赞/取消点赞接口
app.post('/like', (req, res) => {
  const postId = req.body.postId;
  const userId = req.body.userId;
  connection.query(
    'SELECT COUNT(*) as likesCount FROM postLike WHERE postId = ? AND userId = ?',
    [postId, userId],
    (error, results) => {
      if (error) {
        return res.status(500).json({
          error: 'false'
        });
      }
      if (results[0].likesCount > 0) {
        connection.query( // 用户已经点赞,取消点赞
          'DELETE FROM postLike WHERE postId = ? AND userId = ?',
          [postId, userId],
          (deleteError) => {
            if (deleteError) {
              console.error(deleteError);
              return res.status(500).json({
                error: 'false'
              });
            }
            connection.query( // 更新帖子表点赞数减1
              'UPDATE post SET likes = likes - 1 WHERE id = ?',
              [postId],
              (updateError) => {
                if (updateError) {
                  console.error(updateError);
                  return res.status(500).json({
                    error: 'false'
                  });
                }
                res.json({
                  likesCount: results[0].likesCount - 1 // 返回更新后的点赞数
                });
              }
            );
          }
        );
      } else { // 用户未点赞,进行点赞
        connection.query(
          'INSERT INTO postLike (postId, userId) VALUES (?, ?)',
          [postId, userId],
          (insertError) => {
            if (insertError) {
              console.error(insertError);
              return res.status(500).json({
                error: 'false'
              });
            }
            // 更新帖子表点赞数加1
            connection.query(
              'UPDATE post SET likes = likes + 1 WHERE id = ?',
              [postId],
              (updateError) => {
                if (updateError) {
                  console.error(updateError);
                  return res.status(500).json({
                    error: 'false'
                  });
                }
                res.json({
                  likesCount: results[0].likesCount + 1 // 返回更新后的点赞数
                });
              }
            );
          }
        );
      }
    }
  );
});
相关推荐
爱写bug的野原新之助几秒前
爬虫之补环境:加载原型链
前端·javascript·爬虫
陈广亮8 分钟前
工具指南7-Unix时间戳转换工具
前端
NGBQ1213814 分钟前
Adobe-Premiere-Pro-2026-26.0.2.2-m0nkrus 全解析:专业视频编辑软件深度指南
前端·adobe·音视频
北城笑笑16 分钟前
Chrome:Paused in debugger 的踩坑实录:问题排查全过程与终极解决方案( 在调试器中暂停 )
前端·chrome
haorooms18 分钟前
Promise.try () 完全指南
前端·javascript
kyriewen19 分钟前
闭包:那个“赖着不走”的家伙,到底有什么用?
前端·javascript·ecmascript 6
小杨同学4919 分钟前
STM32 进阶封神之路(二十二):DMA 实战全攻略 ——ADC 采集 + 串口收发 + 内存复制(库函数 + 代码落地)
后端·单片机·嵌入式
斌味代码22 分钟前
el-popover跳转页面不隐藏,el-popover销毁
前端·javascript·vue.js
该怎么办呢22 分钟前
cesium核心代码学习-01项目目录及其基本作用
前端·3d·源码·webgl·cesium·webgis
踩着两条虫30 分钟前
AI 驱动的 Vue3 应用开发平台 深入探究(十九):CLI与工具链之Create VTJ CLI 参考
前端·ai编程·vite