前言:

本周我完成了关于博客模块的设计,包含数据库表的设计和创建,以及相关接口的设计与相关接口文档的编写。博客模块要求以下内容:发帖,回帖,回复评论,点赞,收藏,以及AI端推送内容。

一.数据库表的设计:

post表,用于存储帖子的元数据,包含标题,图片,内容,点赞数,收藏数等必要的帖子信息

关联用户,包含状态,以此确定帖子是否被封禁

post_collect表,用于关联哪些用户收藏了哪些博客:

post_label表,用于关联博客和标签的信息:

post_comment表,用于表示用户对帖子的评论信息,包含状态,以此确定评论是否被封禁

post_like表,用于存储用户对帖子的点赞信息,由于考虑到点赞的数量众多,一个表可能存储不来,所以采用分表存储模式,后端依照哈希函数将数据存储到对应的表中:

post_history表,用于存储用户对帖子的浏览信息,其与点赞表,评论表等,都可以作为AI分析用户喜好并推送帖子的凭据。浏览信息亦采用分表存储:

post_comment_reply表,用于存储用户对某一个评论的恢复信息,以及对回复评论的回复信息(使用is_sub_reply表明):

post_recommend表,用于存储对于用户的推荐的表,由AI端的定时任务分析结果,然后填充,再由业务端进行查询,形成分层解耦:

二.相关接口的设计

2.1 接口的设计

关于帖子的相关接口的设计放在PostController中,,其中包含添加帖子,删除帖子,点赞帖子等基本功能,并且设置自动审批功能,若开启,则要计划将帖子和评论及时发给AI端进行审核。自动审批功能预计由管理员端开启

 /**
     *
     * TODO 创建帖子,需要初始化status为待审核,以及需要绑定帖子和标签
     *TODO 如果AI_AUDIT设置为自动审批,同时要通过消息队列传送帖子id,让AI
     *      * TODO 审批帖子,并修改status
     *      TODO 之后AI通过消息队列回传审批情况,业务端接收到之后,以系统消息的方式发送给号主
     *          //AI审核结果
     *    TODO public static final String AI_AUDIT_RESULT_QUEUE = "ai-audit-result-routing-key";
     * **/
    @PostMapping("/add")
    @Operation(summary = "添加帖子")
    public Result<Void> add(@RequestBody PostDTO postDTO) {
        log.info("添加帖子:{}", postDTO);
        postService.add(postDTO);
        return Result.success();
    }


    /**
     *
     * TODO 逻辑删除帖子
     *
     * **/
    @PostMapping("/delete")
    @Operation(summary = "删除帖子")
    public Result<Void> delete(@RequestBody BaseRequest request) {
        log.info("删除帖子:{}", request);
        postService.delete(request);
        return Result.success();
    }


    /***
     *
     * TODO 查询获得自己发布的帖子,keyword关键词可以先匹配标题,再匹配内容,最后匹配标签,按顺序排列
     *
     * */
    @PostMapping("/listMyPost")
    @Operation(summary = "查看我的帖子列表")
    public Result<List<PostListVO>> listMyPost(@RequestBody PostQueryDTO postQueryDTO) {
        log.info("查看我的帖子列表:{}", postQueryDTO);

        return Result.success();
    }


    /**
     *
     * TODO 点赞帖子,记得点赞的时候,首先检查用户是否已经点赞,
     * TODO 然后要修改帖子的点赞数以及post_like表,其中post_like表是分片的,使用用户的userId
     * TODO 对4取模选择进入对应的表
     *
     * **/
    @PostMapping("/like")
    @Operation(summary = "点赞帖子")
    public Result<Void> like(@RequestBody BaseRequest request) {
        log.info("点赞帖子:{}", request);
        postService.like(request);
        return Result.success();
    }

    /**
     *
     * TODO 取消点赞,接的同时修改贴子的点赞数和post_like表
     *
     * **/
    @PostMapping("/undoLike")
    @Operation(summary = "取消点赞")
    public Result<Void> undoLike(@RequestBody BaseRequest request) {
        log.info("取消点赞:{}", request);
        postService.undoLike(request);
        return Result.success();
    }

    /**
     *
     * TODO 收藏帖子,要求同点赞要求一致
     *
     * **/
    @PostMapping("/collect")
    @Operation(summary = "收藏帖子")
    public Result<Void> collect(@RequestBody BaseRequest request) {
        log.info("收藏帖子:{}", request);
        postService.collect(request);
        return Result.success();
    }


    /**
     *
     * TODO 取消收藏,要求与同点赞要求一致
     *
     *
     * **/
    @PostMapping("/undoCollect")
    @Operation(summary = "取消收藏")
    public Result<Void> undoCollect(@RequestBody BaseRequest request) {
        log.info("取消收藏:{}", request);
        postService.undoCollect(request);
        return Result.success();
    }

    /**
     *
     * TODO 显示出我的所有收藏的帖子,要求仍然是先标题,然后内容,最后标签
     *
     * **/
    @PostMapping("/listMyCollect")
    @Operation(summary = "查看我的收藏列表")
    public Result<List<PostListVO>> listMyCollect(@RequestBody PostQueryDTO postQueryDTO) {
        log.info("查看我的收藏列表:{}", postQueryDTO);
        List<PostListVO> p = postService.listMyCollectList(postQueryDTO);
        return Result.success(p);
    }




    /**
     * TODO 查看帖子详情,并且加入历史记录,传过来的是帖子的id,要求分页查询评论
     */
    @PostMapping("/detail")
    @Operation(summary = "帖子详情")
    public Result<PostVO> detail(@RequestBody PostDetailDTO request) {
        log.info("帖子详情:{}", request);
        PostVO  p = postService.detail(request);
        return Result.success(p);
    }


    /**
     *
     *
     * TODO 要涉及到AI的推荐功能,先从post_recommend中查询,当recommend表中的数据查完了,就查post表
     * TODO 每次将帖子推送之后,要把这些帖子的id放在redis中
     * TODO 在查帖子前,要先检查redis中是否有该帖子,如果有,就不再查这些帖子,没有就可以查
     * TODO 帖子推送,每次推送10个
     * **/
    @PostMapping("/freshPost")
    @Operation(summary = "刷新帖子")
    public Result<List<PostListVO>> freshPost() {
        log.info("刷新帖子");
       return null;
    }

    @PostMapping("/listPost")
    @Operation(summary = "搜索帖子列表")
    public Result<List<PostListVO>> listPost(@RequestBody PostQueryDTO postQueryDTO) {
        log.info("查看帖子列表:{}", postQueryDTO);
         List<PostListVO> p = postService.listPostList(postQueryDTO);
        return Result.success(p);
    }


    /**
     *
     * TODO 显示我的历史记录,要求先标题,然后内容,最后标签
     *
     * **/
    @PostMapping("/listMyHistory")
    @Operation(summary = "查看我的历史记录")
    public Result<List<PostListVO>> listMyHistory(@RequestBody PostQueryDTO postQueryDTO) {
        log.info("查看我的历史记录:{}", postQueryDTO);
        List<PostListVO> p = postService.listMyHistoryList(postQueryDTO);
        return Result.success(p);
    }

    /**
     * TODO 直接物理删除,前端传过来的是帖子的id
     *
     * **/
    @PostMapping("/deleteMyHistory")
    @Operation(summary = "删除我的历史记录")
    public Result<Void> deleteMyHistory(@RequestBody BaseRequest request) {
        log.info("删除我的历史记录:{}", request);
        postService.deleteMyHistory(request);
        return Result.success();
    }


    /**
     *
     * TODO 评论帖子,要同时修改帖子的评论数和post_comment表
     * TODO 如果AI_AUDIT设置为自动审批,同时要通过消息队列传送评论id,让AI
     * TODO 审批评论,并修改status
     *    //AI审核
     *     public static final String AI_AUDIT_QUEUE = "ai-audit-routing-key";
     *
     * **/
    @PostMapping("/comment")
    @Operation(summary = "评论帖子")
    public Result<Void> comment(@RequestBody CommentDTO commentDTO) {
        log.info("评论帖子:{}", commentDTO);

        return Result.success();
    }

    /**
     *
     * TODO 删除评论,要同时修改帖子的评论数和post_comment表,前端传过来的是评论的id
     *
     * **/
    @PostMapping("/undoComment")
    @Operation(summary = "取消评论")
    public Result<Void> undoComment(@RequestBody BaseRequest request) {
        log.info("取消评论:{}", request);

        return Result.success();
    }

    /**
     *
     * TODO 回复评论,要同时修改帖子的评论数和post_comment_reply表
     *TODO 如果AI_AUDIT设置为自动审批,同时要通过消息队列传送评论id,让AI
     *      *      * TODO 审批评论,并修改status
     * **/
    @PostMapping("/replyComment")
    @Operation(summary = "回复评论")
    public Result<Void> replyComment(@RequestBody CommentDTO commentDTO) {
        log.info("回复评论:{}", commentDTO);

        return Result.success();
    }

    /**
     *
     * TODO 删除回复评论,要同时修改帖子的评论数和post_comment_reply表,前端传过来是回复的id
     *
     * **/
    @PostMapping("/undoReplyComment")
    @Operation(summary = "取消回复评论")
    public Result<Void> undoReplyComment(@RequestBody BaseRequest request) {
        log.info("取消回复评论:{}", request);

        return Result.success();
    }

2.2 DTO的设计

其中主要的DTO如下,包含查询帖子,保存帖子,查看帖子详情的信息,以及发布评论的DTO封装

public class PostDTO {

    @Schema(description = "图片列表")
    private List<String> images;

    @Schema(description = "帖子内容")
    private String text;

    @Schema(description = "标题")
    private String title;

    @Schema(description = "标签列表")
    private List<Label> labels;


}


@Data
@Tag(name = "查询帖子的信息")
public class PostQueryDTO {

    @Schema(description = "关键词")
    private String keyword;

    @Schema
    private LocalDateTime createTime;
    

}



@Data
@Tag(name = "帖子详情查询")
public class PostDetailDTO {

    private Integer pageNum = 1;    // 页码,默认第1页
    private Integer pageSize = 10;  // 每页大小,默认10条

    private Long postId;
}

//负责传递评论的相关信息

@Data
public class CommentDTO {

    private Long postCommentId;

    private Long postCommentReplyId;

    private Integer isSubReply;


    private String text;

}

2.3 VO的设计

主要的VO如下,主要就是帖子列表的显示,帖子详情的显示以及评论的显示:

首先是帖子列表的显示,需要体现用户昵称和用户头像,基本的点赞数,评论数等信息,以及创建时间

然后是帖子详情,要求显示更加具体的信息

其中涉及到CommentVO的设计,评论不仅要显示本评论的相关信息,还要包含子评论,以下是详细的代码定义:

@Data
@Tag(name = "帖子列表")
public class PostListVO {

    @Schema(description = "帖子id")
    private Long id;

    @Schema(description = "用户id")
    private Long userId;

    @Schema(description = "用户昵称")
    private String userName;

    @Schema(description = "用户头像")
    private String userAvatar;

    @Schema(description = "帖子标题")
    private String title;

    @Schema(description = "帖子内容,在PostListVO中只截取前两句")
    private String text;

    @Schema(description = "第一张图片作为封面")
    private String cover;

    @Schema(description = "点赞数")
    private Long likeCount;

    @Schema(description = "收藏数")
    private Long collectCount;

    @Schema(description = "评论数")
    private Long commentCount;

    @Schema(description = "创建时间")
    private LocalDateTime createTime;
}


@Data
@Tag(name = "帖子详情")
public class PostVO {

    @Schema(description = "帖子id")
    private Long id;

    @Schema(description = "帖主用户id")
    private Long userId;

    @Schema(description = "帖主用户昵称")
    private String userName;

    @Schema(description = "帖主用户头像")
    private String userAvatar;

    @Schema(description = "帖子标题")
    private String title;

    @Schema(description = "帖子内容")
    private String text;

    @Schema(description = "帖子图片")

    private List<String> images;

    @Schema(description = "点赞数")
    private Long likeCount;

    @Schema(description = "收藏数")
    private Long collectCount;

    @Schema(description = "评论数")
    private Long commentCount;

    @Schema(description = "创建时间")
    private LocalDateTime createTime;

    @Schema(description = "标签")
    private List<Label> labels;

    @Schema(description = "是否点赞")
    private Boolean isLike;

    @Schema(description = "是否收藏")
    private Boolean isCollect;

    @Schema(description = "评论具体数量")
    List<CommentVO> commentVOS;


}

@Data
@Tag(name = "评论详情")
public class CommentVO {

    @Schema(description = "评论id")
    private Long id;

    @Schema(description = "用户id")
    private Long userId;

    @Schema(description = "用户昵称")
    private String userName;

    @Schema(description = "用户头像")
    private String userAvatar;

    @Schema(description = "评论内容")
    private String text;

    @Schema(description = "发送时间")
    private LocalDateTime sendTime;

    @Schema(description = "状态")
    private Integer status;

    @Schema(description = "子评论")
    private List<CommentReplyVO> children;

}


@Data
@Schema(description = "评论回复详情")
public class CommentReplyVO {

    @Schema(description = "评论id")
    private Long id;

    @Schema(description = "用户id")
    private Long userId;

    @Schema(description = "用户昵称")
    private String userName;

    @Schema(description = "用户头像")
    private String userAvatar;

    @Schema(description = "评论内容")
    private String text;

    @Schema(description = "回复的评论id")
    private Long commentId;

    @Schema(description = "是否是回复‘回复评论’的评论")
    private Boolean isSubReply;

    @Schema(description = "回复的评论的用户id")
    private Long subUserId;

    @Schema(description = "回复的评论的用户昵称")
    private String subUserName;

    @Schema(description = "状态")
    private Integer status;

    @Schema(description = "发送时间")
    private LocalDateTime sendTime;



}


三.撰写接口文档:

3.1 撰写接口文档

撰写接口文档,并将接口文档发给后端成员进行具体的开发,图为接口文档的局部内容:

3.2 UI架构的设计

绘制UI架构图

四.总结

本周完成博客模块全套设计,完成八张核心数据表设计,对点赞、浏览记录表采用分表方案,依托用户行为数据支撑AI个性化推送;完成PostController全套业务接口及配套DTO、VO结构开发,落地AI自动审核消息队列与分层推荐、Redis去重逻辑,实现发帖、互动、个人帖子/收藏/历史管理等能力;编写接口文档同步开发人员,并绘制UI架构图,将我的帖子、收藏、浏览历史整合至个人中心页面,为前后端开发提供完整设计支撑。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐