9.4 KiB
9.4 KiB
title, url, publishedTime
| title | url | publishedTime |
|---|---|---|
| 笔记仅对自己可见接口开发 - 犬小哈专栏 | https://www.quanxiaoha.com/column/10356.html | null |
本小节中,我们将把笔记仅对自己可见接口开发完成,对应的原型图如下:
接口定义
接口地址
POST /visible/onlyme
入参
{
"id": "1829410872473157676" // 笔记 ID
}
出参
{
"success": true, // true 表示更新成功
"message": null,
"errorCode": null,
"data": null
}
创建接口入参 VO
编辑 xiaohashu-note-biz 模块,在 /model/vo 包下,创建接口入参实体类 UpdateNoteVisibleOnlyMeReqVO ,代码如下:
package com.quanxiaoha.xiaohashu.note.biz.model.vo;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author: 犬小哈
* @date: 2024/4/7 15:17
* @version: v1.0.0
* @description: 笔记仅对自己可见
**/
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class UpdateNoteVisibleOnlyMeReqVO {
@NotNull(message = "笔记 ID 不能为空")
private Long id;
}
新增 mapper 接口
为了能够将数据库中,指定的笔记权限修改为仅自己可见,还需要编辑 NoteDOMapper 接口,添加如下方法:
package com.quanxiaoha.xiaohashu.note.biz.domain.mapper;
import com.quanxiaoha.xiaohashu.note.biz.domain.dataobject.NoteDO;
public interface NoteDOMapper {
// 省略...
int updateVisibleOnlyMe(NoteDO noteDO);
}
接着,在对应的 xml映射文件中,添加上述方法对应的 SQL, 代码如下:
<update id="updateVisibleOnlyMe" parameterType="com.quanxiaoha.xiaohashu.note.biz.domain.dataobject.NoteDO">
update t_note
set visible = #{visible,jdbcType=TINYINT},
update_time = #{updateTime,jdbcType=TIMESTAMP}
where id = #{id,jdbcType=BIGINT} and `status` = 1
</update>
更新条件中,
status = 1表示仅更新笔记状态为正常展示的记录。
添加异常枚举值
编辑 ResponseCodeEnum 全局枚举类,添加如下异常码枚举值,等会业务层判断需要用到:
package com.quanxiaoha.xiaohashu.note.biz.enums;
import com.quanxiaoha.framework.common.exception.BaseExceptionInterface;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* @author: 犬小哈
* @url: www.quanxiaoha.com
* @date: 2023-08-15 10:33
* @description: 响应异常码
**/
@Getter
@AllArgsConstructor
public enum ResponseCodeEnum implements BaseExceptionInterface {
// 省略...
// ----------- 业务异常状态码 -----------
// 省略...
NOTE_CANT_VISIBLE_ONLY_ME("NOTE-20006", "此笔记无法修改为仅自己可见"),
;
// 省略...
}
编辑 service 业务层
修改 NoteService 业务接口,添加一个笔记仅对自己可见方法:
package com.quanxiaoha.xiaohashu.note.biz.service;
import com.quanxiaoha.framework.common.response.Response;
import com.quanxiaoha.xiaohashu.note.biz.model.vo.*;
/**
* @author: 犬小哈
* @date: 2024/4/7 15:41
* @version: v1.0.0
* @description: 笔记业务
**/
public interface NoteService {
// 省略...
/**
* 笔记仅对自己可见
* @param updateNoteVisibleOnlyMeReqVO
* @return
*/
Response<?> visibleOnlyMe(UpdateNoteVisibleOnlyMeReqVO updateNoteVisibleOnlyMeReqVO);
}
在其实现类中,实现上述方法,代码如下:
package com.quanxiaoha.xiaohashu.note.biz.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.RandomUtil;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.google.common.base.Preconditions;
import com.quanxiaoha.framework.biz.context.holder.LoginUserContextHolder;
import com.quanxiaoha.framework.common.exception.BizException;
import com.quanxiaoha.framework.common.response.Response;
import com.quanxiaoha.framework.common.util.JsonUtils;
import com.quanxiaoha.xiaohashu.note.biz.constant.MQConstants;
import com.quanxiaoha.xiaohashu.note.biz.constant.RedisKeyConstants;
import com.quanxiaoha.xiaohashu.note.biz.domain.dataobject.NoteDO;
import com.quanxiaoha.xiaohashu.note.biz.domain.mapper.NoteDOMapper;
import com.quanxiaoha.xiaohashu.note.biz.domain.mapper.TopicDOMapper;
import com.quanxiaoha.xiaohashu.note.biz.enums.NoteStatusEnum;
import com.quanxiaoha.xiaohashu.note.biz.enums.NoteTypeEnum;
import com.quanxiaoha.xiaohashu.note.biz.enums.NoteVisibleEnum;
import com.quanxiaoha.xiaohashu.note.biz.enums.ResponseCodeEnum;
import com.quanxiaoha.xiaohashu.note.biz.model.vo.*;
import com.quanxiaoha.xiaohashu.note.biz.rpc.DistributedIdGeneratorRpcService;
import com.quanxiaoha.xiaohashu.note.biz.rpc.KeyValueRpcService;
import com.quanxiaoha.xiaohashu.note.biz.rpc.UserRpcService;
import com.quanxiaoha.xiaohashu.note.biz.service.NoteService;
import com.quanxiaoha.xiaohashu.user.dto.resp.FindUserByIdRspDTO;
import jakarta.annotation.Resource;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
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;
import java.util.Objects;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
/**
* @author: 犬小哈
* @date: 2024/4/7 15:41
* @version: v1.0.0
* @description: 笔记业务
**/
@Service
@Slf4j
public class NoteServiceImpl implements NoteService {
// 省略...
/**
* 笔记仅对自己可见
*
* @param updateNoteVisibleOnlyMeReqVO
* @return
*/
@Override
public Response<?> visibleOnlyMe(UpdateNoteVisibleOnlyMeReqVO updateNoteVisibleOnlyMeReqVO) {
// 笔记 ID
Long noteId = updateNoteVisibleOnlyMeReqVO.getId();
// 构建更新 DO 实体类
NoteDO noteDO = NoteDO.builder()
.id(noteId)
.visible(NoteVisibleEnum.PRIVATE.getCode()) // 可见性设置为仅对自己可见
.updateTime(LocalDateTime.now())
.build();
// 执行更新 SQL
int count = noteDOMapper.updateVisibleOnlyMe(noteDO);
// 若影响的行数为 0,则表示该笔记无法修改为仅自己可见
if (count == 0) {
throw new BizException(ResponseCodeEnum.NOTE_CANT_VISIBLE_ONLY_ME);
}
// 删除 Redis 缓存
String noteDetailRedisKey = RedisKeyConstants.buildNoteDetailKey(noteId);
redisTemplate.delete(noteDetailRedisKey);
// 同步发送广播模式 MQ,将所有实例中的本地缓存都删除掉
rocketMQTemplate.syncSend(MQConstants.TOPIC_DELETE_NOTE_LOCAL_CACHE, noteId);
log.info("====> MQ:删除笔记本地缓存发送成功...");
return Response.success();
}
// 省略...
}
解释一下业务逻辑:
- 从入参中拿到需要修改的笔记 ID 后,构建 DO 实体类;
- 调用
updateVisibleOnlyMe()方法,传入入参 DO实体类,执行更新 SQL, 将指定笔记的权限更新为仅自己可见;- 判断更新语句影响的行数,若为 0,则表示该笔记无法修改为仅自己可见;
- 删除 Redis 缓存;
- 发送广播 MQ, 将所有实例中的本地缓存都删除掉;
新增 controller 接口
为 NoteController 控制器,添加 /visible/onlyme 接口,代码如下:
package com.quanxiaoha.xiaohashu.note.biz.controller;
import com.quanxiaoha.framework.biz.operationlog.aspect.ApiOperationLog;
import com.quanxiaoha.framework.common.response.Response;
import com.quanxiaoha.xiaohashu.note.biz.model.vo.*;
import com.quanxiaoha.xiaohashu.note.biz.service.NoteService;
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;
/**
* @author: 犬小哈
* @date: 2024/4/4 13:22
* @version: v1.0.0
* @description: 笔记
**/
@RestController
@RequestMapping("/note")
@Slf4j
public class NoteController {
// 省略...
@PostMapping(value = "/visible/onlyme")
@ApiOperationLog(description = "笔记仅对自己可见")
public Response<?> visibleOnlyMe(@Validated @RequestBody UpdateNoteVisibleOnlyMeReqVO updateNoteVisibleOnlyMeReqVO) {
return noteService.visibleOnlyMe(updateNoteVisibleOnlyMeReqVO);
}
}
自测一波
最后,重启笔记服务,自测一波接口功能是否好使,如下图所示:
可以看到,服务端响应成功,再确认一下数据库中对应的笔记,其权限字段是否已经被修改为了仅自己可见,以及二级缓存是否被删除。