diff --git a/han-note-note/han-note-note-biz/src/main/java/com/hanserwei/hannote/note/biz/controller/NoteController.java b/han-note-note/han-note-note-biz/src/main/java/com/hanserwei/hannote/note/biz/controller/NoteController.java index a07e86f..09c99d2 100644 --- a/han-note-note/han-note-note-biz/src/main/java/com/hanserwei/hannote/note/biz/controller/NoteController.java +++ b/han-note-note/han-note-note-biz/src/main/java/com/hanserwei/hannote/note/biz/controller/NoteController.java @@ -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); + } + } diff --git a/han-note-note/han-note-note-biz/src/main/java/com/hanserwei/hannote/note/biz/enums/ResponseCodeEnum.java b/han-note-note/han-note-note-biz/src/main/java/com/hanserwei/hannote/note/biz/enums/ResponseCodeEnum.java index e83de05..c9b0544 100644 --- a/han-note-note/han-note-note-biz/src/main/java/com/hanserwei/hannote/note/biz/enums/ResponseCodeEnum.java +++ b/han-note-note/han-note-note-biz/src/main/java/com/hanserwei/hannote/note/biz/enums/ResponseCodeEnum.java @@ -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", "话题不存在") ; // 异常码 diff --git a/han-note-note/han-note-note-biz/src/main/java/com/hanserwei/hannote/note/biz/model/vo/UpdateNoteReqVO.java b/han-note-note/han-note-note-biz/src/main/java/com/hanserwei/hannote/note/biz/model/vo/UpdateNoteReqVO.java new file mode 100644 index 0000000..bb26878 --- /dev/null +++ b/han-note-note/han-note-note-biz/src/main/java/com/hanserwei/hannote/note/biz/model/vo/UpdateNoteReqVO.java @@ -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 imgUris; + + private String videoUri; + + private String title; + + private String content; + + private Long topicId; +} \ No newline at end of file diff --git a/han-note-note/han-note-note-biz/src/main/java/com/hanserwei/hannote/note/biz/service/NoteService.java b/han-note-note/han-note-note-biz/src/main/java/com/hanserwei/hannote/note/biz/service/NoteService.java index 83c59d4..ca546bd 100644 --- a/han-note-note/han-note-note-biz/src/main/java/com/hanserwei/hannote/note/biz/service/NoteService.java +++ b/han-note-note/han-note-note-biz/src/main/java/com/hanserwei/hannote/note/biz/service/NoteService.java @@ -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 { @@ -23,4 +24,11 @@ public interface NoteService extends IService { */ Response findNoteDetail(FindNoteDetailReqVO findNoteDetailReqVO); + /** + * 笔记更新 + * @param updateNoteReqVO 笔记更新请求 + * @return 笔记更新结果 + */ + Response updateNote(UpdateNoteReqVO updateNoteReqVO); + } \ No newline at end of file diff --git a/han-note-note/han-note-note-biz/src/main/java/com/hanserwei/hannote/note/biz/service/impl/NoteServiceImpl.java b/han-note-note/han-note-note-biz/src/main/java/com/hanserwei/hannote/note/biz/service/impl/NoteServiceImpl.java index 512e874..cc6e3d5 100644 --- a/han-note-note/han-note-note-biz/src/main/java/com/hanserwei/hannote/note/biz/service/impl/NoteServiceImpl.java +++ b/han-note-note/han-note-note-biz/src/main/java/com/hanserwei/hannote/note/biz/service/impl/NoteServiceImpl.java @@ -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 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 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(); + } + /** * 校验笔记的可见性 *