创建点赞模块 like 目录下 like.controller.ts、like.middleware.ts、like.router.ts、like.service.ts like.controller.ts:
1 import { Request, Response, NextFunction } from "express";
like.middleware.ts:
1 import { Request, Response, NextFunction } from "express";
like.router.ts:
1 2 3 4 5 6 7 8 9 import express from "express"; import * as likeController from "./like.controller"; const router = express.Router(); /** * 导出路由 */ export default router;
like.service.ts:
1 import { connection } from "../app/database/mysql";
创建点赞内容数据表 1 2 3 4 5 6 7 8 9 10 11 12 CREATE TABLE `user_like_post`( `userId` INT(11) NOT NULL, `postId` INT(11) NOT NULL, PRIMARY KEY (`userId`,`postId`), FOREIGN KEY (`userId`) REFERENCES `user`(`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, FOREIGN KEY (`postId`) REFERENCES `post`(`id`) ON DELETE NO ACTION ON UPDATE NO ACTION ) DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
定义保存点赞内容的功能 like.service.ts:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 import { connection } from "../app/database/mysql"; /** * 保存用户点赞内容 */ export const createUserLikePost = async (userId: number, postId: number) => { // 准备查询 const statement = ` INSERT INTO user_like_post (userId,postId) VALUES (?, ?) `; // 执行查询 const [data] = await connection.promise().query(statement, [userId, postId]); // 提供数据 return data; };
定义点赞内容接口 like.controller.ts:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 import { Request, Response, NextFunction } from "express"; import { createUserLikePost } from "./like.service"; /** * 点赞内容 */ export const storeUserLikePost = async ( request: Request, response: Response, next: NextFunction ) => { // 准备数据 const { postId } = request.params; const { id: userId } = request.user; // 点赞内容 try { const data = await createUserLikePost(userId, parseInt(postId, 10)); // 做出响应 response.status(201).send(data); } catch (error) { next(error); } };
like.router.ts:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 import express from "express"; import * as likeController from "./like.controller"; import { authGuard } from "../auth/auth.middleware"; const router = express.Router(); /** * 点赞内容 */ router.post("/posts/:postId/like", authGuard, likeController.storeUserLikePost); /** * 导出路由 */ export default router;
定义取消点赞内容功能 like.service.ts:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 /** * 取消点赞内容 */ export const deleteUserLikePost = async (userId: number, postId: number) => { // 准备查询 const statement = ` DELETE FROM user_like_post WHERE userId=? AND postId=? `; // 执行查询 const [data] = await connection.promise().query(statement, [userId, postId]); // 提供数据 return data; };
定义取消点赞内容接口 like.controller.ts:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 /** * 取消点赞内容接口 */ export const distroyUserLikePost = async ( request: Request, response: Response, next: NextFunction ) => { // 准备数据 const { postId } = request.params; const { id: userId } = request.user; // 取消点赞内容 try { const data = await deleteUserLikePost(userId, parseInt(postId, 10)); // 做出响应 response.send(data); } catch (error) { next(error); } };
like.router.ts:
1 2 3 4 5 6 7 8 /** * 取消点赞内容 */ router.delete( "/posts/:postId/like", authGuard, likeController.distroyUserLikePost );
在内容项目中包含点赞数量 定义查询片段 post.provider.ts:
1 2 3 4 5 6 7 totalLikes: ` ( SELECT COUNT(user_like_post.postId) FROM user_like_post WHERE user_like_post.postId = post.id ) AS totalLikes `
在 post.service.ts 中使用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 export const getPosts = async (options: GetPostOptions) => { const { sort, filter, pagination: { limit, offset }, } = options; // sql参数 let params: Array<any> = [limit, offset]; // 设置sql参数 if (filter.param) { params = [filter.param, ...params]; } const statement = ` SELECT post.id, post.title, post.content, ${sqlFragment.user}, ${sqlFragment.totalComments}, ${sqlFragment.file}, ${sqlFragment.tags}, ${sqlFragment.totalLikes} FROM post ${sqlFragment.leftJoinUser} ${sqlFragment.leftJoinOneFile} ${sqlFragment.leftJoinTag} WHERE ${filter.sql} GROUP BY post.id ORDER BY ${sort} LIMIT ? OFFSET ? `; const [data] = await connection.promise().query(statement, params); return data; };
用户赞过的内容列表 添加查询片段 post.provider.ts:
1 2 3 4 innerJoinUserLikePost: ` INNER JOIN user_like_post ON user_like_post.postId = post.id `,
post.middleware.ts:
1 2 3 4 5 6 7 8 // 过滤出用户赞过的内容 if (user && action == "liked" && !tag) { request.filter = { name: "userLiked", sql: "user_like_post.userId=?", param: user, }; }
post.service.ts:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 getPosts函数中: const statement = ` SELECT post.id, post.title, post.content, ${sqlFragment.user}, ${sqlFragment.totalComments}, ${sqlFragment.file}, ${sqlFragment.tags}, ${sqlFragment.totalLikes} FROM post ${sqlFragment.leftJoinUser} ${sqlFragment.leftJoinOneFile} ${sqlFragment.leftJoinTag} ${filter.name == "userLiked" ? sqlFragment.innerJoinUserLikePost : ""} //这里判断一下 WHERE ${filter.sql} GROUP BY post.id ORDER BY ${sort} LIMIT ? OFFSET ? `; getPostsTotalCount函数中 // 准备查询 const statement = ` SELECT COUNT(DISTINCT post.id) AS total FROM post ${sqlFragment.leftJoinUser} ${sqlFragment.leftJoinOneFile} ${sqlFragment.leftJoinTag} ${filter.name == "userLiked" ? sqlFragment.innerJoinUserLikePost : ""} //这里判断一下 WHERE ${filter.sql} `;