如何通过Sequelize判断用户是否已点赞子商品
解决方案
首先确保你已经从请求的token中解析出当前用户ID(示例命名为currentUserId,具体获取方式根据你的鉴权逻辑调整)。接下来通过修改查询代码,新增isLiked字段,通过条件聚合判断当前用户是否点赞过对应子商品:
基础实现(带SQL注入防护)
// 从token解析当前用户ID,示例代码 const currentUserId = req.user.id; const Products = await db.SubProduct.findAll({ attributes: { include: [ [Sequelize.fn("COUNT", Sequelize.col("likes.id")), "LikeCount"], // 新增isLiked字段:通过条件聚合判断用户是否点赞 [ Sequelize.fn('MAX', Sequelize.case( [[Sequelize.where(Sequelize.col('likes.userId'), '=', currentUserId), 1]], 0 ) ), 'isLiked' ] ] }, include: [ { model: db.Like, as: "likes", attributes: [] } ], group: ['SubProduct.id'], // 绑定参数避免SQL注入 bind: { currentUserId } }); // 可选:将数据库返回的0/1转为布尔值,方便前端使用 const formattedProducts = Products.map(product => ({ ...product.toJSON(), isLiked: Boolean(product.isLiked) }));
兼容未登录场景
如果需要处理用户未登录的情况(此时isLiked默认返回false),可以调整代码如下:
const currentUserId = req.user?.id; // 未登录时为undefined // 根据用户登录状态生成isLiked字段配置 const isLikedAttribute = currentUserId ? [ Sequelize.fn('MAX', Sequelize.case( [[Sequelize.where(Sequelize.col('likes.userId'), '=', currentUserId), 1]], 0 ) ), 'isLiked' ] : [Sequelize.literal('FALSE'), 'isLiked']; const Products = await db.SubProduct.findAll({ attributes: { include: [ [Sequelize.fn("COUNT", Sequelize.col("likes.id")), "LikeCount"], isLikedAttribute ] }, // 未登录时无需关联Like表 include: currentUserId ? [{ model: db.Like, as: "likes", attributes: [] }] : [], group: ['SubProduct.id'], ...(currentUserId ? { bind: { currentUserId } } : {}) });
逻辑说明
- 使用
MAX(CASE...)聚合函数:分组后只要当前用户有一条点赞记录,MAX就会返回1,否则返回0 - 通过
bind参数传递用户ID,避免直接拼接SQL导致注入风险 - 可选的布尔值转换:将数据库返回的数值型结果转为前端更易处理的布尔值
内容的提问来源于stack exchange,提问作者meetmoradiya
相关产品推荐
相关产品推荐

