feat(note): 添加笔记更新功能
- 新增 /update 接口用于修改笔记内容 - 实现笔记类型校验,支持图文和视频笔记 - 校验图片数量不超过8张,视频链接不为空 - 更新笔记元数据并清除Redis和本地缓存 - 支持笔记内容的更新与K-V存储同步 - 新增笔记更新失败和话题不存在的异常码 - 添加 UpdateNoteReqVO 请求参数校验
This commit is contained in:
@@ -5,6 +5,7 @@ import com.hanserwei.framework.common.response.Response;
|
||||
import com.hanserwei.hannote.note.biz.model.vo.FindNoteDetailReqVO;
|
||||
import com.hanserwei.hannote.note.biz.model.vo.FindNoteDetailRspVO;
|
||||
import com.hanserwei.hannote.note.biz.model.vo.PublishNoteReqVO;
|
||||
import com.hanserwei.hannote.note.biz.model.vo.UpdateNoteReqVO;
|
||||
import com.hanserwei.hannote.note.biz.service.NoteService;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -34,4 +35,10 @@ public class NoteController {
|
||||
return noteService.findNoteDetail(findNoteDetailReqVO);
|
||||
}
|
||||
|
||||
@PostMapping(value = "/update")
|
||||
@ApiOperationLog(description = "笔记修改")
|
||||
public Response<?> updateNote(@Validated @RequestBody UpdateNoteReqVO updateNoteReqVO) {
|
||||
return noteService.updateNote(updateNoteReqVO);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -17,6 +17,8 @@ public enum ResponseCodeEnum implements BaseExceptionInterface {
|
||||
NOTE_PUBLISH_FAIL("NOTE-20001", "笔记发布失败"),
|
||||
NOTE_NOT_FOUND("NOTE-20002", "笔记不存在"),
|
||||
NOTE_PRIVATE("NOTE-20003", "作者已将该笔记设置为仅自己可见"),
|
||||
NOTE_UPDATE_FAIL("NOTE-20004", "笔记更新失败"),
|
||||
TOPIC_NOT_FOUND("NOTE-20005", "话题不存在")
|
||||
;
|
||||
|
||||
// 异常码
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.hanserwei.hannote.note.biz.model.vo;
|
||||
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
public class UpdateNoteReqVO {
|
||||
|
||||
@NotNull(message = "笔记 ID 不能为空")
|
||||
private Long id;
|
||||
|
||||
@NotNull(message = "笔记类型不能为空")
|
||||
private Integer type;
|
||||
|
||||
private List<String> imgUris;
|
||||
|
||||
private String videoUri;
|
||||
|
||||
private String title;
|
||||
|
||||
private String content;
|
||||
|
||||
private Long topicId;
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import com.hanserwei.hannote.note.biz.domain.dataobject.NoteDO;
|
||||
import com.hanserwei.hannote.note.biz.model.vo.FindNoteDetailReqVO;
|
||||
import com.hanserwei.hannote.note.biz.model.vo.FindNoteDetailRspVO;
|
||||
import com.hanserwei.hannote.note.biz.model.vo.PublishNoteReqVO;
|
||||
import com.hanserwei.hannote.note.biz.model.vo.UpdateNoteReqVO;
|
||||
|
||||
public interface NoteService extends IService<NoteDO> {
|
||||
|
||||
@@ -23,4 +24,11 @@ public interface NoteService extends IService<NoteDO> {
|
||||
*/
|
||||
Response<FindNoteDetailRspVO> findNoteDetail(FindNoteDetailReqVO findNoteDetailReqVO);
|
||||
|
||||
/**
|
||||
* 笔记更新
|
||||
* @param updateNoteReqVO 笔记更新请求
|
||||
* @return 笔记更新结果
|
||||
*/
|
||||
Response<?> updateNote(UpdateNoteReqVO updateNoteReqVO);
|
||||
|
||||
}
|
||||
@@ -13,6 +13,7 @@ import com.hanserwei.framework.common.response.Response;
|
||||
import com.hanserwei.framework.common.utils.JsonUtils;
|
||||
import com.hanserwei.hannote.note.biz.constant.RedisKeyConstants;
|
||||
import com.hanserwei.hannote.note.biz.domain.dataobject.NoteDO;
|
||||
import com.hanserwei.hannote.note.biz.domain.dataobject.TopicDO;
|
||||
import com.hanserwei.hannote.note.biz.domain.mapper.NoteDOMapper;
|
||||
import com.hanserwei.hannote.note.biz.enums.NoteStatusEnum;
|
||||
import com.hanserwei.hannote.note.biz.enums.NoteTypeEnum;
|
||||
@@ -21,6 +22,7 @@ import com.hanserwei.hannote.note.biz.enums.ResponseCodeEnum;
|
||||
import com.hanserwei.hannote.note.biz.model.vo.FindNoteDetailReqVO;
|
||||
import com.hanserwei.hannote.note.biz.model.vo.FindNoteDetailRspVO;
|
||||
import com.hanserwei.hannote.note.biz.model.vo.PublishNoteReqVO;
|
||||
import com.hanserwei.hannote.note.biz.model.vo.UpdateNoteReqVO;
|
||||
import com.hanserwei.hannote.note.biz.rpc.DistributedIdGeneratorRpcService;
|
||||
import com.hanserwei.hannote.note.biz.rpc.KeyValueRpcService;
|
||||
import com.hanserwei.hannote.note.biz.rpc.UserRpcService;
|
||||
@@ -34,6 +36,7 @@ import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
@@ -289,6 +292,104 @@ public class NoteServiceImpl extends ServiceImpl<NoteDOMapper, NoteDO> implement
|
||||
return Response.success(findNoteDetailRspVO);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Response<?> updateNote(UpdateNoteReqVO updateNoteReqVO) {
|
||||
// 笔记ID
|
||||
Long noteId = updateNoteReqVO.getId();
|
||||
// 笔记类型
|
||||
Integer type = updateNoteReqVO.getType();
|
||||
|
||||
// 获取对应枚举类
|
||||
NoteTypeEnum noteTypeEnum = NoteTypeEnum.valueOf(type);
|
||||
|
||||
// 判断笔记类型,如果非图文、视频笔记,则抛出异常
|
||||
if (Objects.isNull(noteTypeEnum)){
|
||||
throw new ApiException(ResponseCodeEnum.NOTE_TYPE_ERROR);
|
||||
}
|
||||
String imgUris = null;
|
||||
String videoUri = null;
|
||||
|
||||
switch (noteTypeEnum) {
|
||||
case IMAGE_TEXT -> {
|
||||
List<String> imgUriList = updateNoteReqVO.getImgUris();
|
||||
// 校验图片是否为空
|
||||
Preconditions.checkArgument(CollUtil.isNotEmpty(imgUriList), "笔记图片不能为空");
|
||||
// 校验图片数量
|
||||
Preconditions.checkArgument(imgUriList.size() <= 8, "笔记图片不能多于 8 张");
|
||||
imgUris = StringUtils.join(imgUriList, ",");
|
||||
}
|
||||
case VIDEO -> {
|
||||
videoUri = updateNoteReqVO.getVideoUri();
|
||||
// 校验视频链接是否为空
|
||||
Preconditions.checkArgument(StringUtils.isNotBlank(videoUri), "笔记视频不能为空");
|
||||
}
|
||||
default -> {
|
||||
// No operation needed, kept for clarity
|
||||
}
|
||||
}
|
||||
|
||||
// 话题
|
||||
Long topicId = updateNoteReqVO.getTopicId();
|
||||
String topicName = null;
|
||||
if (Objects.nonNull(topicId)){
|
||||
TopicDO topicDO = topicDOService.getById(topicId);
|
||||
if (Objects.isNull(topicDO)){
|
||||
throw new ApiException(ResponseCodeEnum.TOPIC_NOT_FOUND);
|
||||
}
|
||||
topicName = topicDO.getName();
|
||||
// 判断提交的话题是否真实存在
|
||||
if (StringUtils.isBlank(topicName)){
|
||||
throw new ApiException(ResponseCodeEnum.TOPIC_NOT_FOUND);
|
||||
}
|
||||
}
|
||||
|
||||
// 更新笔记元数据表
|
||||
String content = updateNoteReqVO.getContent();
|
||||
NoteDO noteDO = NoteDO.builder()
|
||||
.id(noteId)
|
||||
.isContentEmpty(StringUtils.isBlank(content))
|
||||
.imgUris(imgUris)
|
||||
.title(updateNoteReqVO.getTitle())
|
||||
.topicId(updateNoteReqVO.getTopicId())
|
||||
.topicName(topicName)
|
||||
.type(type)
|
||||
.updateTime(LocalDateTime.now())
|
||||
.videoUri(videoUri)
|
||||
.build();
|
||||
boolean updateResult = this.updateById(noteDO);
|
||||
if (!updateResult){
|
||||
throw new ApiException(ResponseCodeEnum.NOTE_UPDATE_FAIL);
|
||||
}
|
||||
// 删除Redis缓存
|
||||
String noteDetailRedisKey = RedisKeyConstants.buildNoteDetailKey(noteId);
|
||||
redisTemplate.delete(noteDetailRedisKey);
|
||||
|
||||
// 删除本地缓存
|
||||
LOCAL_CACHE.invalidate(noteId);
|
||||
|
||||
// 笔记内容更新
|
||||
// 查询笔记内容对应的UUID
|
||||
NoteDO noteDO1 = this.getById(noteId);
|
||||
String contentUuid = noteDO1.getContentUuid();
|
||||
|
||||
// 笔记内容是否更新成功
|
||||
boolean isUpdateContentSuccess = false;
|
||||
if (StringUtils.isNotBlank(contentUuid)){
|
||||
// 若笔记内容为空则删除kv存储
|
||||
isUpdateContentSuccess = keyValueRpcService.deleteNoteContent(contentUuid);
|
||||
}else {
|
||||
// 若将无内容的笔记,更新为了有内容的笔记,需要重新生成 UUID
|
||||
contentUuid = StringUtils.isBlank(contentUuid) ? UUID.randomUUID().toString() : contentUuid;
|
||||
// 调用 K-V 更新短文本
|
||||
isUpdateContentSuccess = keyValueRpcService.saveNoteContent(contentUuid, content);
|
||||
}
|
||||
if (!isUpdateContentSuccess){
|
||||
throw new ApiException(ResponseCodeEnum.NOTE_UPDATE_FAIL);
|
||||
}
|
||||
return Response.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验笔记的可见性
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user