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 // 返回更新后的点赞数
                });
              }
            );
          }
        );
      }
    }
  );
});
相关推荐
大家的林语冰10 分钟前
CSS 已死?DOM 性能黑洞!Pretext 排版革命让你在文本间跳舞,没有 DOM 也能纵享丝滑~
前端·javascript·css
vipbic20 分钟前
我也该升级了,陪伴了我7年的博客
前端
程序猿追37 分钟前
我搭了个网页工具:输入关键词,SERP API 自动吐出比价 Excel
后端
Lee川39 分钟前
RAG 实战:从一篇掘金文章出发,拆解检索增强生成的全链路
前端·人工智能·后端
Lee川1 小时前
MCP 高德地图实战:当 AI 学会使用工具,一个协议如何重塑大模型的行动边界
前端·人工智能·后端
楼田莉子1 小时前
C++17新特性:__had_include/属性/求值顺序规则
开发语言·c++·后端
ZC跨境爬虫1 小时前
跟着 MDN 学CSS day_14:(尺寸调整技能测试与实战解析)
前端·css·ui·html·tensorflow
kyriewen1 小时前
用魔法打败魔法:我让AI替我去面试前端岗,AI面试官给我打了92分,还发了offer
前端·javascript·面试
程序员cxuan1 小时前
Codex 把我家烂网给优化后,我 TM 直接原地起飞了。
人工智能·后端·程序员
IT_陈寒1 小时前
Redis批量删除踩了坑,原来DEL命令不是万能的
前端·人工智能·后端