目錄
一、項目簡介
二、技術選型
?三、數據庫設計
四、接口設計及思考
回復帖子部分
4.1?回復帖子
4.1.1.1 實現邏輯
4.1.1.2創建Service接?
4.1.1.3?實現Service接?
4.1.1.4?實現Controller
4.1.1.5?測試接口
4.1.1.6?實現前端頁面
4.2 點贊帖子
4.2.1.1 參數要求
4.2.1.2 創建Service接?
4.2.1.3 實現Service接?
4.3 刪除帖子
4.3.1.1 參數要求
?4.3.1.2 創建Service接口
4.3.1.3?實現Service接?
4.3.1.4?實現Controller
一、項目簡介
本系統實現了基于 Spring 的前后端分離版本的社群系統, 后端主要采用了SSM架構,前端采用ajax和后端進行交互,采用MySQL 數據庫,實現了用戶登錄注冊、個人信息和帖子的查看、發布帖子、帖子回復、站內信等功能。
應用技術有:SpringBoot、SpringMVC、Mybaits、MySQL、CSS等。
二、技術選型
?三、數據庫設計
數據庫名: forum_db
公共字段:?特殊要求的情況下,每張表必須有?整型的?增主鍵,刪除狀態、創建時間、更新時 間,如下所?:
共建五張表?
?SQL腳本
-- ----------------------------
-- 創建數據庫,并指定字符集
-- ----------------------------
drop database if exists forum_db;
create database forum_db character set utf8mb4 collate utf8mb4_general_ci;
-- 選擇數據庫
use forum_db;SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;-- ----------------------------
-- 創建帖子表 t_article
-- ----------------------------
DROP TABLE IF EXISTS `t_article`;
CREATE TABLE `t_article` (`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '帖子編號,主鍵,自增',`boardId` bigint(20) NOT NULL COMMENT '關聯板塊編號,非空',`userId` bigint(20) NOT NULL COMMENT '發帖人,非空,關聯用戶編號',`title` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '標題,非空,最大長度100個字符',`content` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '帖子正文,非空',`visitCount` int(11) NOT NULL DEFAULT 0 COMMENT '訪問量,默認0',`replyCount` int(11) NOT NULL DEFAULT 0 COMMENT '回復數據,默認0',`likeCount` int(11) NOT NULL DEFAULT 0 COMMENT '點贊數,默認0',`state` tinyint(4) NOT NULL DEFAULT 0 COMMENT '狀態 0正常 1 禁用,默認0',`deleteState` tinyint(4) NOT NULL DEFAULT 0 COMMENT '是否刪除 0 否 1 是,默認0',`createTime` datetime NOT NULL COMMENT '創建時間,精確到秒,非空',`updateTime` datetime NOT NULL COMMENT '修改時間,精確到秒,非空',PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '帖子表' ROW_FORMAT = Dynamic;-- ----------------------------
-- 創建帖子回復表 t_article_reply
-- ----------------------------
DROP TABLE IF EXISTS `t_article_reply`;
CREATE TABLE `t_article_reply` (`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '編號,主鍵,自增',`articleId` bigint(20) NOT NULL COMMENT '關聯帖子編號,非空',`postUserId` bigint(20) NOT NULL COMMENT '樓主用戶,關聯用戶編號,非空',`replyId` bigint(20) NULL DEFAULT NULL COMMENT '關聯回復編號,支持樓中樓',`replyUserId` bigint(20) NULL DEFAULT NULL COMMENT '樓主下的回復用戶編號,支持樓中樓',`content` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '回貼內容,長度500個字符,非空',`likeCount` int(11) NOT NULL DEFAULT 0 COMMENT '點贊數,默認0',`state` tinyint(4) NOT NULL DEFAULT 0 COMMENT '狀態 0 正常,1禁用,默認0',`deleteState` tinyint(4) NOT NULL DEFAULT 0 COMMENT '是否刪除 0否 1是,默認0',`createTime` datetime NOT NULL COMMENT '創建時間,精確到秒,非空',`updateTime` datetime NOT NULL COMMENT '更新時間,精確到秒,非空',PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '帖子回復表' ROW_FORMAT = Dynamic;-- ----------------------------
-- 創建版塊表 t_board
-- ----------------------------
DROP TABLE IF EXISTS `t_board`;
CREATE TABLE `t_board` (`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '版塊編號,主鍵,自增',`name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '版塊名,非空',`articleCount` int(11) NOT NULL DEFAULT 0 COMMENT '帖子數量,默認0',`sort` int(11) NOT NULL DEFAULT 0 COMMENT '排序優先級,升序,默認0,',`state` tinyint(4) NOT NULL DEFAULT 0 COMMENT '狀態,0 正常,1禁用,默認0',`deleteState` tinyint(4) NOT NULL DEFAULT 0 COMMENT '是否刪除 0否,1是,默認0',`createTime` datetime NOT NULL COMMENT '創建時間,精確到秒,非空',`updateTime` datetime NOT NULL COMMENT '更新時間,精確到秒,非空',PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '版塊表' ROW_FORMAT = Dynamic;-- ----------------------------
-- 創建站內信表 for t_message
-- ----------------------------
DROP TABLE IF EXISTS `t_message`;
CREATE TABLE `t_message` (`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '站內信編號,主鍵,自增',`postUserId` bigint(20) NOT NULL COMMENT '發送者,并聯用戶編號',`receiveUserId` bigint(20) NOT NULL COMMENT '接收者,并聯用戶編號',`content` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '內容,非空,長度255個字符',`state` tinyint(4) NOT NULL DEFAULT 0 COMMENT '狀態 0未讀 1已讀,默認0',`deleteState` tinyint(4) NOT NULL DEFAULT 0 COMMENT '是否刪除 0否,1是,默認0',`createTime` datetime NOT NULL COMMENT '創建時間,精確到秒,非空',`updateTime` datetime NOT NULL COMMENT '更新時間,精確到秒,非空',PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '站內信表' ROW_FORMAT = Dynamic;-- ----------------------------
-- 創建用戶表 for t_user
-- ----------------------------
DROP TABLE IF EXISTS `t_user`;
CREATE TABLE `t_user` (`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '用戶編號,主鍵,自增',`username` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '用戶名,非空,唯一',`password` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '加密后的密碼',`nickname` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '昵稱,非空',`phoneNum` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '手機號',`email` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '郵箱地址',`gender` tinyint(4) NOT NULL DEFAULT 2 COMMENT '0女 1男 2保密,非空,默認2',`salt` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '為密碼加鹽,非空',`avatarUrl` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '用戶頭像URL,默認系統圖片',`articleCount` int(11) NOT NULL DEFAULT 0 COMMENT '發帖數量,非空,默認0',`isAdmin` tinyint(4) NOT NULL DEFAULT 0 COMMENT '是否管理員,0否 1是,默認0',`remark` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '備注,自我介紹',`state` tinyint(4) NOT NULL DEFAULT 0 COMMENT '狀態 0 正常,1 禁言,默認0',`deleteState` tinyint(4) NOT NULL DEFAULT 0 COMMENT '是否刪除 0否 1是,默認0',`createTime` datetime NOT NULL COMMENT '創建時間,精確到秒',`updateTime` datetime NOT NULL COMMENT '更新時間,精確到秒',PRIMARY KEY (`id`) USING BTREE,UNIQUE INDEX `user_username_uindex`(`username`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '用戶表' ROW_FORMAT = Dynamic;SET FOREIGN_KEY_CHECKS = 1;-- 寫入版塊信息數據INSERT INTO `t_board` (`id`, `name`, `articleCount`, `sort`, `state`, `deleteState`, `createTime`, `updateTime`) VALUES (1, 'Java', 0, 1, 0, 0, '2023-01-14 19:02:18', '2023-01-14 19:02:18');INSERT INTO `t_board` (`id`, `name`, `articleCount`, `sort`, `state`, `deleteState`, `createTime`, `updateTime`) VALUES (2, 'C++', 0, 2, 0, 0, '2023-01-14 19:02:41', '2023-01-14 19:02:41');INSERT INTO `t_board` (`id`, `name`, `articleCount`, `sort`, `state`, `deleteState`, `createTime`, `updateTime`) VALUES (3, '前端技術', 0, 3, 0, 0, '2023-01-14 19:02:52', '2023-01-14 19:02:52');INSERT INTO `t_board` (`id`, `name`, `articleCount`, `sort`, `state`, `deleteState`, `createTime`, `updateTime`) VALUES (4, 'MySQL', 0, 4, 0, 0, '2023-01-14 19:03:02', '2023-01-14 19:03:02');INSERT INTO `t_board` (`id`, `name`, `articleCount`, `sort`, `state`, `deleteState`, `createTime`, `updateTime`) VALUES (5, '面試寶典', 0, 5, 0, 0, '2023-01-14 19:03:24', '2023-01-14 19:03:24');INSERT INTO `t_board` (`id`, `name`, `articleCount`, `sort`, `state`, `deleteState`, `createTime`, `updateTime`) VALUES (6, '經驗分享', 0, 6, 0, 0, '2023-01-14 19:03:48', '2023-01-14 19:03:48');INSERT INTO `t_board` (`id`, `name`, `articleCount`, `sort`, `state`, `deleteState`, `createTime`, `updateTime`) VALUES (7, '招聘信息', 0, 7, 0, 0, '2023-01-25 21:25:33', '2023-01-25 21:25:33');INSERT INTO `t_board` (`id`, `name`, `articleCount`, `sort`, `state`, `deleteState`, `createTime`, `updateTime`) VALUES (8, '福利待遇', 0, 8, 0, 0, '2023-01-25 21:25:58', '2023-01-25 21:25:58');INSERT INTO `t_board` (`id`, `name`, `articleCount`, `sort`, `state`, `deleteState`, `createTime`, `updateTime`) VALUES (9, '灌水區', 0, 9, 0, 0, '2023-01-25 21:26:12', '2023-01-25 21:26:12');-- 寫入帖子表數據
insert into t_article values (null, 1, 1, '測試數據-標題1', '測試數據-內容1', 0,0,0,0,0, '2023-08-11 16:52:00','2023-08-11 16:52:00');
insert into t_article values (null, 1, 1, '測試數據-標題2', '測試數據-內容2', 0,0,0,0,0, '2023-08-11 16:53:00','2023-08-11 16:53:00');
insert into t_article values (null, 1, 1, '測試數據-標題3', '測試數據-內容3', 0,0,0,0,0, '2023-08-11 16:54:00','2023-08-11 16:54:00');
insert into t_article values (null, 2, 2, '測試數據-標題4', '測試數據-內容4', 0,0,0,0,0, '2023-08-11 16:55:00','2023-08-11 16:55:00');
insert into t_article values (null, 2, 2, '測試數據-標題5', '測試數據-內容5', 0,0,0,0,0, '2023-08-11 16:56:00','2023-08-11 16:56:00');-- 寫入回復表數據
insert into t_article_reply values (NULL, 1, 1, NULL, NULL, '回復內容111', 0, 0, 0, '2023-08-14 16:52:00', '2023-08-14 16:52:00');
insert into t_article_reply values (NULL, 1, 1, NULL, NULL, '回復內容222', 0, 0, 0, '2023-08-14 16:53:00', '2023-08-14 16:53:00');
insert into t_article_reply values (NULL, 1, 1, NULL, NULL, '回復內容333', 0, 0, 0, '2023-08-14 16:54:00', '2023-08-14 16:54:00');
insert into t_article_reply values (NULL, 1, 2, NULL, NULL, '回復內容444', 0, 0, 0, '2023-08-14 16:55:00', '2023-08-14 16:55:00');
insert into t_article_reply values (NULL, 1, 2, NULL, NULL, '回復內容555', 0, 0, 0, '2023-08-14 16:56:00', '2023-08-14 16:56:00');
四、接口設計及思考
回復帖子部分
4.1?回復帖子
4.1.1 提交回復內容
? 在帖?詳情????可以發表回復
4.1.1.1 實現邏輯
1. 帖?在正常狀態下允許??回復? ?(校驗1)
2. 填寫回復內容,點擊提交按鈕后發送請求到服務器
3. 服務器校驗回復內容、帖?與??狀態(校驗二),通過后寫?數據庫 (回復表中新增一條數據)
4. 帖?回復數量加1 (帖子表的更新)
5. 返回結果
思考:根據3. 4.,發表回復時,需要對兩張表進行更新操作,那么就需要用事務管理起來
使用事務的原則:當一個執行流程中,要進行多個更新操作(增刪改),不論涉及幾張表都需要用事務管理起來。
4.1.1.2創建Service接?
? 在IArticleReplyService定義?法
/*** 新增一個回復記錄* @param articleReply*/@Transactionalvoid create (ArticleReply articleReply);
}
4.1.1.3?實現Service接?
? 在ArticleReplyServiceImpl中實現?法
4.1.1.4?實現Controller
? 新建ArticleReplyController并提供對外的API接?
4.1.1.5?測試接口
測試?例:
1. ??在沒有登錄的情況下回復帖?,不成功
2. 回復已刪除或已禁?的帖?,不成功 3. 回復不存在的帖?,不成功
4. 禁???回復帖?,不成功
5. ??和帖?狀態正常的情況下,回復帖?,成功
6. 回復成功,帖?回復數量加1
7. 在測試?具中編輯并在數據庫中查看驗證是否成功
4.1.1.6?實現前端頁面
// ====================== 回復帖? ======================$('#details_btn_article_reply').click(function () {let articleIdEl = $('#details_article_id');let replyContentEl = $('#details_article_reply_content');// ?空校驗if (!replyContentEl.val()) {// 提?$.toast({heading: '提?',text: '請輸?回復內容',icon: 'warning'});return;}// 構造帖?對象let articleReplyObj = {articleId: articleIdEl.val(),content: replyContentEl.val()}// 發送請求$.ajax({type: 'post',url: '/article/reply',// 發送的數據data: articleReplyObj,success: function (respData) {// ?狀態碼判斷是否成功if (respData.code == 0) {// 清空輸?區editor.setValue('');// 更新回貼數currentArticle.replyCount = currentArticle.replyCount + 1;$('#details_article_replyCount').html(currentArticle.replyCount);// 構建回貼??loadArticleDetailsReply();$.toast({heading: '提?',text: respData.message,icon: 'success'});} else {// 提?$.toast({heading: '提?',text: respData.message,icon: 'info'});}},error: function () {$.toast({heading: '錯誤',text: '出錯了,請聯系管理員',icon: 'error'});}});
});
4.2 點贊帖子
? ??在帖?詳情?進?點贊操作
4.2.1.1 參數要求

?
4.2.1.2 創建Service接?
? 在IArticleService定義?法
/*** 點贊* @param id 帖子Id*/void thumbsUpById(Long id);
}
4.2.1.3 實現Service接?
? 在ArticleServiceImpl中實現?法
@Overridepublic void thumbsUpById(Long id) {//非空校驗if (id == null || id <= 0) {// 打印日志log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());// 拋出異常throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));}//查詢帖子信息Article article = selectById(id);if (article == null || article.getState() == 1 || article.getDeleteState() == 1) {//打印日志log.info(ResultCode.FAILED_ARTICLE_NOT_EXISTS.toString());//拋出異常throw new ApplicationException(AppResult.failed(ResultCode.FAILED_NOT_EXISTS));}//構造更新對象Article update = new Article();update.setId(article.getId());update.setLikeCount(article.getLikeCount() + 1);//更新數據庫int row = articleMapper.updateByPrimaryKeySelective(update);if (row != 1) {log.info(ResultCode.FAILED_CREATE.toString() + "userId = " + article.getUserId());throw new ApplicationException(AppResult.failed(ResultCode.FAILED_CREATE));}}
}
4.2.1.4?? 實現Controller
? 在ArticleController中提供對外的API接?
@ApiOperation("點贊")@PostMapping("/thumbsUp")public AppResult thumbsUp(HttpServletRequest request,@ApiParam(value = "帖子Id") @RequestParam(value = "id") @NonNull Long id){// 獲取??信息HttpSession session = request.getSession(false);User user = (User) session.getAttribute(AppConfig.SESSION_USER_KEY);// 判斷是否被禁?if (user.getState() != 0) {// ?志log.warn(ResultCode.FAILED_USER_BANNED.toString() + ", userId = " +user.getId());// 返回錯誤信息return AppResult.failed(ResultCode.FAILED_USER_BANNED);}// 更新點贊數articleService.thumbsUpById(id);// 返回結果return AppResult.success();}
4.3 刪除帖子
4.3.1.1 參數要求
?4.3.1.2 創建Service接口
? 在IBoardService定義?法
/*** 版塊中的帖子數量 -1* @param id 版塊Id*/void subOneArticleCountById(Long id);
}
? 在IUserService定義?法
/*** 用戶發帖數 -1* @param id*/void subOneArticleCountById(Long id);
}
? 在IArticleService定義?法,并加?事務管理
/*** 根據Id刪除帖子* @param id 帖子Id*/
@Transactionalvoid deleteById(Long id);
}
4.3.1.3?實現Service接?
? 在BoardServiceImpl中實現?法
@Overridepublic void subOneArticleCountById(Long id) {//非空校驗if (id == null || id < 0) {//打印日志log.warn(ResultCode.FAILED_ARTICLE_NOT_EXISTS.toString());// 拋出異常throw new ApplicationException(AppResult.failed(ResultCode.FAILED_ARTICLE_NOT_EXISTS));}//查詢板塊信息Board board = selectById(id);// 校驗版塊是否存在if (board == null) {// 打印日志log.warn(ResultCode.FAILED_BOARD_NOT_EXISTS.toString());// 拋出異常throw new ApplicationException(AppResult.failed(ResultCode.FAILED_BOARD_NOT_EXISTS));}// 構造要更新的對象Board updateBoard = new Board();updateBoard.setId(board.getId()); // 版塊IDupdateBoard.setArticleCount(board.getArticleCount() - 1); // 帖子數量if (updateBoard.getArticleCount() < 0) {//如果小于0那么設置為0updateBoard.setArticleCount(0);}// 調用DAOint row = boardMapper.updateByPrimaryKeySelective(updateBoard);if (row != 1) {// 打印日志log.warn(ResultCode.FAILED.toString() + ",受影響的行數不等于1.");// 拋出異常throw new ApplicationException(AppResult.failed(ResultCode.FAILED));}}
}
? 在UserServiceImpl中實現?法
@Overridepublic void subOneArticleCountById(Long id) {//非空校驗if (id == null || id < 0) {//打印日志log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());// 拋出異常throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));}//根據用戶名查詢用戶信息User user = userMapper.selectById(id);//校驗用戶是否存在if(user == null){// 打印日志log.warn(ResultCode.FAILED_ARTICLE_NOT_EXISTS.toString() + ", user id = " + id);// 拋出異常throw new ApplicationException(AppResult.failed(ResultCode.FAILED_ARTICLE_NOT_EXISTS));}//構造要更新的對象User updateUser = new User();updateUser.setId(user.getId());//用戶IdupdateUser.setArticleCount(user.getArticleCount() - 1);//帖子數量-1//判斷-1之后,用戶的發帖數是否小于0if(updateUser.getArticleCount() < 0){//如果小于0,則設置為0updateUser.setArticleCount(0);}//調用DAOint row = userMapper.updateByPrimaryKeySelective(updateUser);if (row != 1) {// 打印日志log.warn(ResultCode.FAILED.toString() + ",受影響的行數不等于1.");// 拋出異常throw new ApplicationException(AppResult.failed(ResultCode.FAILED));}
? 在ArticleServiceImpl中實現?法
@Overridepublic void deleteById(Long id) {//非空校驗if (id == null || id <= 0) {// 打印日志log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());// 拋出異常throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));}//根據Id查詢帖子信息Article article = articleMapper.selectByPrimaryKey(id);if (article == null || article.getDeleteState() == 1) {//打印日志log.info(ResultCode.FAILED_ARTICLE_NOT_EXISTS.toString() + ",article id = " + id);//拋出異常throw new ApplicationException(AppResult.failed(ResultCode.FAILED_NOT_EXISTS));}//構造更新對象Article updateArticle = new Article();updateArticle.setId(article.getId());updateArticle.setDeleteState((byte) 1);//更新數據庫int row = articleMapper.updateByPrimaryKeySelective(updateArticle);if (row != 1) {log.info(ResultCode.ERROR_SERVICES.toString());throw new ApplicationException(AppResult.failed(ResultCode.ERROR_SERVICES));}//更新版塊中的帖子數量boardService.subOneArticleCountById(article.getUserId());//更新用戶發帖數userService.subOneArticleCountById(article.getUserId());log.info("刪除帖子成功,article id = " + article.getId() + ",user id = " + article.getUserId() + ".");}
4.3.1.4?實現Controller
? 在ArticleController中提供對外的API接?
/*** 根據Id刪除帖?** @param id 帖?Id* @return*/
@ApiOperation("刪除帖?")
@PostMapping("/delete")
public AppResult deleteById (HttpServletRequest request,@ApiParam("帖?Id") @RequestParam("id") @NonNull Longid) {// 1. ??是否禁?HttpSession session = request.getSession(false);User user = (User) session.getAttribute(AppConfig.SESSION_USER_KEY);if (user.getState() == 1) {// 返回錯誤描述return AppResult.failed(ResultCode.FAILED_USER_BANNED);}//查詢帖子信息Article article = articleService.selectById(id);//2.帖子是否存在或已刪除if (article == null || article.getDeleteState() == 1) {// 返回錯誤描述return AppResult.failed(ResultCode.FAILED_ARTICLE_NOT_EXISTS);}// 3. ??是否是作者if (article.getUserId() != user.getId()) {// 返回錯誤描述return AppResult.failed(ResultCode.FAILED_FORBIDDEN);}// 調?Service執?刪除articleService.deleteById(id);// 返回成功return AppResult.success();}