feat: 新增论坛留言功能

This commit is contained in:
TIAN 2025-05-16 17:04:25 +08:00
parent d7f8a56a53
commit 5249bfe1f4
10 changed files with 321 additions and 26 deletions

View File

@ -9,32 +9,32 @@ use hebi;
-- 用户表
create table if not exists user
(
id bigint auto_increment comment 'id' primary key,
userAccount varchar(256) not null comment '账号',
userPassword varchar(512) not null comment '密码',
userName varchar(256) null comment '用户昵称',
userAvatar varchar(1024) null comment '用户头像',
userRole varchar(256) default 'user' not null comment '用户角色user/admin',
createTime datetime default CURRENT_TIMESTAMP not null comment '创建时间',
updateTime datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新时间',
isDelete tinyint default 0 not null comment '是否删除',
id bigint auto_increment Comment 'id' primary key,
userAccount varchar(256) not null Comment '账号',
userPassword varchar(512) not null Comment '密码',
userName varchar(256) null Comment '用户昵称',
userAvatar varchar(1024) null Comment '用户头像',
userRole varchar(256) default 'user' not null Comment '用户角色user/admin',
createTime datetime default CURRENT_TIMESTAMP not null Comment '创建时间',
updateTime datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP Comment '更新时间',
isDelete tinyint default 0 not null Comment '是否删除',
index idx_userAccount (userAccount)
) comment '用户' collate = utf8mb4_unicode_ci;
) Comment '用户' collate = utf8mb4_unicode_ci;
-- 图表信息表
create table if not exists chart
(
id bigint auto_increment comment 'id' primary key,
goal text null comment '分析目标',
`name` varchar(128) null comment '图标名称',
chartData text null comment '图表数据',
chartType varchar(128) null comment '图表类型',
genChart text null comment '生成的图表数据',
genResult text null comment '生成的分析结论',
status varchar(128) not null default 'wait' comment'wait,running,succeed,failed',
execMessage text null comment '执行信息',
userId bigint null comment '创建用户 id',
createTime datetime default CURRENT_TIMESTAMP not null comment '创建时间',
updateTime datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新时间',
isDelete tinyint default 0 not null comment '是否删除'
) comment '图表信息表' collate = utf8mb4_unicode_ci;
id bigint auto_increment Comment 'id' primary key,
goal text null Comment '分析目标',
`name` varchar(128) null Comment '图标名称',
chartData text null Comment '图表数据',
chartType varchar(128) null Comment '图表类型',
genChart text null Comment '生成的图表数据',
genResult text null Comment '生成的分析结论',
status varchar(128) not null default 'wait' Comment'wait,running,succeed,failed',
execMessage text null Comment '执行信息',
userId bigint null Comment '创建用户 id',
createTime datetime default CURRENT_TIMESTAMP not null Comment '创建时间',
updateTime datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP Comment '更新时间',
isDelete tinyint default 0 not null Comment '是否删除'
) Comment '图表信息表' collate = utf8mb4_unicode_ci;

View File

@ -0,0 +1,183 @@
package com.yupi.springbootinit.controller;
import com.alibaba.excel.util.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.yupi.springbootinit.common.BaseResponse;
import com.yupi.springbootinit.common.ErrorCode;
import com.yupi.springbootinit.common.ResultUtils;
import com.yupi.springbootinit.exception.BusinessException;
import com.yupi.springbootinit.mapper.commentMapper;
import com.yupi.springbootinit.model.dto.Comment.CommentAddRequest;
import com.yupi.springbootinit.model.entity.Comment;
import com.yupi.springbootinit.model.entity.Post;
import com.yupi.springbootinit.model.entity.User;
import com.yupi.springbootinit.model.vo.CommentVO;
import com.yupi.springbootinit.service.PostService;
import com.yupi.springbootinit.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import com.yupi.springbootinit.service.commentService;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
/**
* 帖子评论
*
*/
@RestController
@RequestMapping("/comment")
@Slf4j
public class commentController {
/**
* 获取指定帖子的评论详情
*/
@Resource
private commentService commentService;
@Resource
private UserService userService;
@Resource
private commentMapper commentMapper;
@Resource
private PostService postService;
// @GetMapping("/comment")
// public void pingController(HttpServletRequest request){
// /**
// * 返回评论详情
// * 1.返回评论人信息头像名称
// * 2.返回评论内容
// */
// User loginUser = userService.getLoginUser(request);
//
//
// }
/**
* 根据帖子ID获取评论列表
*/
@GetMapping("/comments")
public BaseResponse<List<CommentVO>> getCommentListByPostId(@RequestParam("postId") Long postId) {
if (postId == null || postId <= 0) {
throw new BusinessException(ErrorCode.PARAMS_ERROR, "帖子ID无效");
}
// 1. 查询该帖子下的未删除评论
QueryWrapper<Comment> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("postId", postId);
queryWrapper.eq("isDelete", false);
queryWrapper.orderByDesc("createTime");
List<Comment> commentList = commentService.list(queryWrapper);
// 2. 取所有非空的 userId避免 N+1 查询
Set<Long> userIdSet = commentList.stream()
.map(Comment::getUserId)
.filter(userId -> userId != null) // 过滤掉空的userId
.collect(Collectors.toSet());
// 创建用户ID到用户对象的映射
Map<Long, User> userMap;
if (!userIdSet.isEmpty()) { // 只有在有用户ID时才查询
userMap = userService.listByIds(userIdSet).stream()
.collect(Collectors.toMap(User::getId, user -> user, (existing, replacement) -> existing));
} else {
userMap = new HashMap<>();
}
// 3. 组装返回 VO
List<CommentVO> commentVOList = commentList.stream().map(comment -> {
CommentVO vo = new CommentVO();
vo.setContent(comment.getContent());
vo.setCreateTime(comment.getCreateTime());
// 处理用户信息包括空userId的情况
Long userId = comment.getUserId();
if (userId != null) {
User user = userMap.get(userId);
if (user != null) {
vo.setUserName(user.getUserName());
vo.setUserAvatar(user.getUserAvatar());
} else {
// 用户ID存在但未找到用户
vo.setUserName("未知用户");
vo.setUserAvatar(""); // 设置默认头像或留空
}
} else {
// userId为空的情况
vo.setUserName("匿名用户");
vo.setUserAvatar(""); // 设置默认头像或留空
}
return vo;
}).collect(Collectors.toList());
return ResultUtils.success(commentVOList);
}
/**
* 发布评论
*/
@PostMapping("/sendcomment")
public BaseResponse<Long> addComment(@RequestBody CommentAddRequest commentAddRequest, HttpServletRequest request) {
// BaseResponse baseResponse = new BaseResponse();
// baseResponse.setCode();
// baseResponse.setData();
// baseResponse.setMessage();
// return baseResponse;
// 1. 参数校验
if (commentAddRequest == null) {
throw new BusinessException(ErrorCode.PARAMS_ERROR, "请求参数为空");
}
Long postId = commentAddRequest.getPostId();
String content = commentAddRequest.getContent();
// 校验帖子ID
if (postId == null || postId <= 0) {
throw new BusinessException(ErrorCode.PARAMS_ERROR, "帖子ID无效");
}
// 校验评论内容
if (StringUtils.isBlank(content)) {
throw new BusinessException(ErrorCode.PARAMS_ERROR, "评论内容不能为空");
}
if (content.length() > 1000) {
throw new BusinessException(ErrorCode.PARAMS_ERROR, "评论内容过长");
}
// 2. 获取当前登录用户
User loginUser = userService.getLoginUser(request);
if (loginUser == null) {
throw new BusinessException(ErrorCode.NOT_LOGIN_ERROR);
}
// 3. 校验帖子是否存在
Post post = postService.getById(postId);
if (post == null || Boolean.TRUE.equals(post.getIsDelete())) {
throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "帖子不存在");
}
// 4. 创建评论对象
Comment comment = new Comment();
comment.setPostId(postId);
comment.setContent(content);
comment.setUserId(loginUser.getId());
// 6. 保存评论
boolean result = commentService.save(comment);
if (!result) {
throw new BusinessException(ErrorCode.SYSTEM_ERROR, "评论发布失败");
}
// 8. 返回评论ID
return ResultUtils.success(comment.getId());
}
}

View File

@ -0,0 +1,11 @@
package com.yupi.springbootinit.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yupi.springbootinit.model.entity.Comment;
/**
* @Entity com.yupi.springbootinit.model.entity.comment
*/
public interface commentMapper extends BaseMapper<Comment> {
}

View File

@ -0,0 +1,21 @@
package com.yupi.springbootinit.model.dto.Comment;
import lombok.Data;
import java.io.Serializable;
@Data
public class CommentAddRequest implements Serializable {
/**
* 帖子ID
*/
private Long postId;
/**
* 评论内容
*/
private String content;
private static final long serialVersionUID = 1L;
}

View File

@ -0,0 +1,21 @@
package com.yupi.springbootinit.model.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.util.Date;
/**
* 评论详情
*/
@TableName(value = "comment")
@Data
public class Comment {
private Long id;
private Long postId;
private Long userId;
private String content;
private Date createTime;
private Integer isDelete;
}

View File

@ -68,8 +68,8 @@ public class Post implements Serializable {
/**
* 是否删除
*/
// @TableLogic
// private Integer isDelete;
@TableLogic
private Integer isDelete;
@TableField(exist = false)
private static final long serialVersionUID = 1L;

View File

@ -0,0 +1,13 @@
package com.yupi.springbootinit.model.vo;
import lombok.Data;
import java.util.Date;
@Data
public class CommentVO {
private String userName;
private String userAvatar;
private String content;
private Date createTime;
}

View File

@ -0,0 +1,12 @@
package com.yupi.springbootinit.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.yupi.springbootinit.model.entity.Comment;
/**
* @author lxl
* @description 针对表comment(评论表)的数据库操作Service
* @createDate 2023-09-05 16:01:07
*/
public interface commentService extends IService<Comment> {
}

View File

@ -0,0 +1,16 @@
package com.yupi.springbootinit.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yupi.springbootinit.mapper.commentMapper;
import com.yupi.springbootinit.model.entity.Comment;
import com.yupi.springbootinit.service.commentService;
import org.springframework.stereotype.Service;
/**
* @author lxl
* @description 针对表comment(评论表)的数据库操作Service实现
* @createDate 2023-09-05 15:05:05
*/
@Service
public class commentServicelmpl extends ServiceImpl<commentMapper, Comment> implements commentService {
}

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.yupi.springbootinit.mapper.commentMapper" >
<resultMap id="BaseResultMap" type="com.yupi.springbootinit.model.entity.Comment">
<id property="id" column="id" />
<result property="userId" column="userId" />
<result property="postId" column="postId" />
<result property="content" column="content" />
<result property="createTime" column="createTime" />
<result property="isDelete" column="isDelete" />
</resultMap>
<!-- <sql id="Base_Column_List">-->
<!-- id,`name`,goal,chartData,chartType,genChart,genResult,-->
<!-- userId,createTime,updateTime,isDelete-->
<!-- </sql>-->
</mapper>