云上社群学习系统部分接口设计详解

news2024/11/26 15:29:35

目录

一、项目简介

二、技术选型

 三、数据库设计

四、接口设计及思考

回复帖子部分

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
     */
    @Transactional
    void 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中实现⽅法
    @Override
    public 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
     */
@Transactional
    void deleteById(Long id);
}

4.3.1.3 实现Service接⼝

在BoardServiceImpl中实现⽅法
    @Override
    public 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()); // 版块ID
        updateBoard.setArticleCount(board.getArticleCount() - 1); // 帖子数量
        if (updateBoard.getArticleCount() < 0) {
            //如果小于0那么设置为0
            updateBoard.setArticleCount(0);
        }
        // 调用DAO
        int row = boardMapper.updateByPrimaryKeySelective(updateBoard);
        if (row != 1) {
            // 打印日志
            log.warn(ResultCode.FAILED.toString() + ",受影响的行数不等于1.");
            // 抛出异常
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED));
        }
    }
}
在UserServiceImpl中实现⽅法
    @Override
    public 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());//用户Id
        updateUser.setArticleCount(user.getArticleCount() - 1);//帖子数量-1
        //判断-1之后,用户的发帖数是否小于0
        if(updateUser.getArticleCount() < 0){
            //如果小于0,则设置为0
            updateUser.setArticleCount(0);
        }
        //调用DAO
        int row = userMapper.updateByPrimaryKeySelective(updateUser);
        if (row != 1) {
            // 打印日志
            log.warn(ResultCode.FAILED.toString() + ",受影响的行数不等于1.");
            // 抛出异常
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED));
        }
在ArticleServiceImpl中实现⽅法
    @Override
    public 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 Long
                                     id) {
        // 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();
         }
         

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/881267.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL 根据多字段查询重复数据

MySQL 根据多字段查询重复数据 在实际的数据库应用中&#xff0c;我们经常需要根据多个字段来查询重复的数据。MySQL 提供了一些方法来实现这个功能&#xff0c;让我们能够快速准确地找到和处理重复数据。本文将介绍如何使用 MySQL 来根据多字段查询重复数据&#xff0c;并提供…

LeetCode 38题:外观数列

题目 给定一个正整数 n &#xff0c;输出外观数列的第 n 项。 「外观数列」是一个整数序列&#xff0c;从数字 1 开始&#xff0c;序列中的每一项都是对前一项的描述。 你可以将其视作是由递归公式定义的数字字符串序列&#xff1a; countAndSay(1) "1"countAnd…

【【verilog典型电路设计之复数乘法器】】

verilog典型电路设计之复数乘法器 典型电路设计之复数乘法器 复数乘法的算法是&#xff1a; 设复数xabi ; ycdi; 则复数乘法结果 x.y(abi)(cdi)(ac-bd) i(adbc) 复数乘法器 我们可以将复数x y 的实部与虚部相乘&#xff0c;减去 x与y的虚部相乘 得到输出结果的实部 就是ac-bd…

DC电源模块减小输入电源与输出负载之间的能量损失

BOSHIDA DC电源模块减小输入电源与输出负载之间的能量损失 随着电子产品的普及&#xff0c;DC电源模块已成为现代电子设备中不可或缺的组成部分。DC电源模块可以将交流电转化为直流电&#xff0c;并根据需要&#xff0c;以适当的电压和电流提供给输出负载。然而&#xff0c;在输…

css3-flex布局:基础使用 / Flexbox布局

一、理解flex 二、理解Flex布局&#xff08;又称Flexbox布局&#xff09; Flex布局&#xff08;又称Flexbox布局&#xff09;是一种基于Web的CSS3布局模式&#xff0c;其目的是为了更加灵活和自适应地布置各种各样的网页元素。Flex布局通过将一个父容器分割为一个或多个弹性项…

gitlab修改远程仓库地址

目录 背景&#xff1a; 解决&#xff1a; 1.删除本地仓库关联的远程地址&#xff0c;添加新的远程仓库地址 2.直接修改本地仓库关联的远程仓库地址 3.打开.git隐藏文件修改远程仓库地址 4.拉取代码报错(git host key verification failed) 背景&#xff1a; 公司搬家&#…

item_review-获得TB商品评论

一、接口参数说明&#xff1a; item_review-获得TB商品评论&#xff0c;点击更多API调试&#xff0c;请移步注册API账号点击获取测试key和secret 公共参数 请求地址: https://api-gw.onebound.cn/taobao/item_review 名称类型必须描述keyString是调用key&#xff08;点击获取…

el-table实现懒加载(el-table-infinite-scroll)

2023.8.15今天我学习了用el-table对大量的数据进行懒加载。 效果如下&#xff1a; 1.首先安装&#xff1a; npm install --save el-table-infinite-scroll2 2.全局引入&#xff1a; import ElTableInfiniteScroll from "el-table-infinite-scroll";// 懒加载 V…

神经网络基础-神经网络补充概念-03-逻辑回归损失函数

概念 逻辑回归使用的损失函数通常是"对数损失"&#xff08;也称为"交叉熵损失"&#xff09;或"逻辑损失"。这些损失函数在训练过程中用于衡量模型预测与实际标签之间的差异&#xff0c;从而帮助模型逐步调整权重参数&#xff0c;以更好地拟合数…

线程池中的常见面试题

目录 1. 线程池相比于线程有什么优点 2. 线程池的参数有哪些 3. 线程工厂有什么用 4. 说一下线程的优先级 5. 说一下线程池的执行流程 6. 线程池的拒绝策略有哪些 7. 如何实现自定义拒绝策略 8. 如何判断线程池中的任务是否执行完成 1. 线程池相比于线程有什么优点 有…

【【verilog典型电路设计之Wallace 树乘法器】】

verilog典型电路设计之Wallace 树乘法器 Wallace 树乘法器 是一种我们在集成电路学习中应用非常广泛的设计 其中由两部分组成 一个是FA和HA FA是full add 全加器 HA 是half 半加器 加法从数据最密集的地方开始&#xff0c;不断地反复使用全加器半加器来覆盖“树” 。 这一级全…

TIOBE2023年8月榜单发布,Python超越老将C/C++蝉联冠军

TIOBE 编程社区指数是一个衡量编程语言受欢迎程度的指标&#xff0c;评判的依据来自世界范围内的工程师、课程、供应商及搜索引擎&#xff0c;TIOBE 官网近日公布了 2023 年 8 月的编程语言排行榜。 此次的榜单中&#xff0c;Python依旧稳居第一&#xff0c;占比达到了13.33%。…

企业门禁如何应对安全问题?这个方法稳赢!

随着科技的不断进步&#xff0c;门禁监控正逐渐演化为一个智能化、高效能的管理工具&#xff0c;为工业安全管理带来了全新的可能性。 因此&#xff0c;门禁监控不仅是安全管理的一部分&#xff0c;更是企业保护财产和保障生产流程的关键策略之一。 客户案例 湖南某制造公司是…

【Spring】统一事件的处理(拦截器、统一异常处理、统一数据格式返回)

文章目录 前言一、Spring 拦截器1.1 用户登录权限校验案例1.1.1 最初的用户登录验证1.1.2 使用 Spring AOP 实现登录验证的问题 1.2 Spring 拦截器的使用1.2.1 Spring 拦截器概念与使用步骤1.2.2 使用拦截器实现对用户登录权限的校验 1.3 拦截器实现原理1.4 Spring 拦截器和 Sp…

AI绘画 | 一文学会Midjourney绘画,创作自己的AI作品(快速入门+参数介绍)

一、生成第一个AI图片 首先&#xff0c;生成将中文描述词翻译成英文 然后在输入端输入&#xff1a;/imagine prompt:Bravely running boy in Q version, cute head portrait 最后&#xff0c;稍等一会即可输出效果 说明&#xff1a; 下面的U1、U2、U3、U4代表的第一张、第二张…

Revit SDK: FindColumns 找到和墙相交的柱子 MeasureHeight 计算天窗到最近楼板的位置

前言 本文的主要内容是基于 ReferenceIntersector 的两个个应用。ReferenceIntersector 的主要作用是找到一条与给定射线相交的各个元素。 FindColumns 内容 ReferenceIntersector namespace Autodesk.Revit.DB {public class ReferenceIntersector : IDisposable{public R…

trollcave靶场

配置 第一步&#xff1a;启动靶机时按下 shift 键&#xff0c; 进入以下界面 第二步&#xff1a;选择第二个选项&#xff0c;然后按下 e 键&#xff0c;进入编辑界面 将这里的ro修改为rw single init/bin/bash&#xff0c;然后按ctrlx&#xff0c;进入一个相当于控制台的界面…

用于构建生成式 AI 应用程序备忘单的最佳 Python 工具

推荐&#xff1a;使用 NSDT场景编辑器 助你快速搭建可二次编辑器的3D应用场景 新一代的声音 KDnuggets发布了一份富有洞察力的新备忘单&#xff0c;重点介绍了用于构建生成AI应用程序的顶级Python库。 毫无疑问&#xff0c;读者都知道&#xff0c;生成式人工智能是目前数据科…

小红书运营 变现方法总结(精)

大家好&#xff0c;我是网媒智星&#xff0c;今天跟大家分享一下小红书运营方面的知识&#xff0c;怎样利用小红书变现&#xff1f;全篇倾情干货输出&#xff0c;认真学习&#xff0c;保证您收获多多。 首先&#xff0c;让我们来分析一下小红书平台的优势。关于卖东西&#xff…

政务中心站至政务中心东站右线盾构本月始发

本报记者 赵鹏 实习记者 池阳 通讯员 董浩程 立秋已过&#xff0c;平谷线“瓜熟蒂落”的日子指日可待。在左线隧道刚刚顺利贯通后&#xff0c;平谷线政务中心站至政务中心东站区间右线隧道已展开盾构组装施工&#xff0c;右线盾构即将于本月内始发&#xff0c;被誉为“地下蛟龙…