feat(comment): 实现评论异步消费与内容存储

- 新增评论内容批量存储接口与实现
- 实现MQ消息消费端处理评论发布逻辑
- 支持一级与二级评论的层级关系构建
- 添加评论内容与元数据分离存储机制
- 集成分布式ID生成服务用于评论ID生成
- 完善评论相关DTO、DO、BO模型类
- 添加Cassandra数据库操作支持
- 实现Feign接口调用与事务控制
This commit is contained in:
2025-11-05 19:19:19 +08:00
parent c37b16ff42
commit a37e76c87c
22 changed files with 575 additions and 4 deletions

View File

@@ -0,0 +1,29 @@
package com.hanserwei.hannote.kv.biz.controller;
import com.hanserwei.framework.biz.operationlog.aspect.ApiOperationLog;
import com.hanserwei.framework.common.response.Response;
import com.hanserwei.hannote.kv.biz.service.CommentContentService;
import com.hanserwei.hannote.kv.dto.req.BatchAddCommentContentReqDTO;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/kv")
@Slf4j
public class CommentContentController {
@Resource
private CommentContentService commentContentService;
@PostMapping("/comment/content/batchAdd")
@ApiOperationLog(description = "批量添加评论内容")
public Response<?> batchAddCommentContent(@Validated @RequestBody BatchAddCommentContentReqDTO batchAddCommentContentReqDTO) {
return commentContentService.batchAddCommentContent(batchAddCommentContentReqDTO);
}
}

View File

@@ -0,0 +1,21 @@
package com.hanserwei.hannote.kv.biz.domain.dataobject;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.cassandra.core.mapping.PrimaryKey;
import org.springframework.data.cassandra.core.mapping.Table;
@Table("comment_content")
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class CommentContentDO {
@PrimaryKey
private CommentContentPrimaryKey primaryKey;
private String content;
}

View File

@@ -0,0 +1,37 @@
package com.hanserwei.hannote.kv.biz.domain.dataobject;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.cassandra.core.cql.PrimaryKeyType;
import org.springframework.data.cassandra.core.mapping.PrimaryKeyClass;
import org.springframework.data.cassandra.core.mapping.PrimaryKeyColumn;
import java.util.UUID;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@PrimaryKeyClass
public class CommentContentPrimaryKey {
/**
* 分区键1
*/
@PrimaryKeyColumn(name = "note_id", type = PrimaryKeyType.PARTITIONED)
private Long noteId;
/**
* 分区键2
*/
@PrimaryKeyColumn(name = "year_month", type = PrimaryKeyType.PARTITIONED)
private String yearMonth;
/**
* 聚簇键
*/
@PrimaryKeyColumn(name = "content_id", type = PrimaryKeyType.PARTITIONED)
private UUID contentId;
}

View File

@@ -0,0 +1,9 @@
package com.hanserwei.hannote.kv.biz.service;
import com.hanserwei.framework.common.response.Response;
import com.hanserwei.hannote.kv.dto.req.BatchAddCommentContentReqDTO;
public interface CommentContentService {
Response<?> batchAddCommentContent(BatchAddCommentContentReqDTO batchAddCommentContentReqDTO);
}

View File

@@ -0,0 +1,50 @@
package com.hanserwei.hannote.kv.biz.service.impl;
import com.hanserwei.framework.common.response.Response;
import com.hanserwei.hannote.kv.biz.domain.dataobject.CommentContentDO;
import com.hanserwei.hannote.kv.biz.domain.dataobject.CommentContentPrimaryKey;
import com.hanserwei.hannote.kv.biz.service.CommentContentService;
import com.hanserwei.hannote.kv.dto.req.BatchAddCommentContentReqDTO;
import com.hanserwei.hannote.kv.dto.req.CommentContentReqDTO;
import jakarta.annotation.Resource;
import org.springframework.data.cassandra.core.CassandraTemplate;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.UUID;
@Service
public class CommentContentServiceImpl implements CommentContentService {
@Resource
private CassandraTemplate cassandraTemplate;
@Override
public Response<?> batchAddCommentContent(BatchAddCommentContentReqDTO batchAddCommentContentReqDTO) {
List<CommentContentReqDTO> comments = batchAddCommentContentReqDTO.getComments();
//DTO转DO
List<CommentContentDO> contentDOS = comments.stream()
.map(comment -> {
// 构建主键类
CommentContentPrimaryKey commentContentPrimaryKey = CommentContentPrimaryKey.builder()
.noteId(comment.getNoteId())
.yearMonth(comment.getYearMonth())
.contentId(UUID.fromString(comment.getContentId()))
.build();
// 构建DO
return CommentContentDO.builder()
.primaryKey(commentContentPrimaryKey)
.content(comment.getContent())
.build();
}).toList();
// 批量插入数据
cassandraTemplate.batchOps()
.insert(contentDOS)
.execute();
return Response.success();
}
}