im:code review 代码风格方面

This commit is contained in:
YunaiV 2024-03-21 12:51:03 +08:00
parent 04123e5987
commit 9c1764e36e
17 changed files with 68 additions and 23 deletions

View File

@ -17,6 +17,7 @@
<name>${project.artifactId}</name> <name>${project.artifactId}</name>
<description> <description>
<!-- TODO 芋艿:这块后面再调整下 -->
im 模块,主要提供能力: im 模块,主要提供能力:
1. 通讯能力,例如:消息发送、消息接收、消息撤回、消息已读等。 1. 通讯能力,例如:消息发送、消息接收、消息撤回、消息已读等。
2. 通讯会话,例如:单聊、群聊、聊天室等。 2. 通讯会话,例如:单聊、群聊、聊天室等。

View File

@ -1,5 +1,5 @@
/** /**
* @author anhaohao * @author anhaohao
* @date 2024/3/9 下午8:59 * @date 2024/3/9 下午8:59 TODO @hao没有 @date 这个应该是 @since
*/ */
package cn.iocoder.yudao.module.im.api; package cn.iocoder.yudao.module.im.api;

View File

@ -23,4 +23,5 @@ public interface ErrorCodeConstants {
// ========== 群成员 (1-040-500-000) ========== // ========== 群成员 (1-040-500-000) ==========
ErrorCode GROUP_MEMBER_NOT_EXISTS = new ErrorCode(1_040_500_000, "群成员不存在"); ErrorCode GROUP_MEMBER_NOT_EXISTS = new ErrorCode(1_040_500_000, "群成员不存在");
} }

View File

@ -6,6 +6,7 @@ import lombok.Getter;
import java.util.Arrays; import java.util.Arrays;
// TODO @hao类型保持和 openim 一致
/** /**
* IM 消息的类型枚举 * IM 消息的类型枚举
* <p> * <p>
@ -42,4 +43,5 @@ public enum ImMessageTypeEnum implements IntArrayValuable {
public int[] array() { public int[] array() {
return ARRAYS; return ARRAYS;
} }
} }

View File

@ -1,5 +0,0 @@
/**
* @author anhaohao
* @date 2024/3/9 下午8:59
*/
package cn.iocoder.yudao.module.im.enums;

View File

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>yudao-module-im</artifactId> <artifactId>yudao-module-im</artifactId>
<groupId>cn.iocoder.boot</groupId> <groupId>cn.iocoder.boot</groupId>
<version>${revision}</version> <!-- 1. 修改 version 为 ${revision} --> <version>${revision}</version> <!-- 1. 修改 version 为 ${revision} TODO @hao这种都去掉哈 -->
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging> <!-- 2. 新增 packaging 为 jar --> <packaging>jar</packaging> <!-- 2. 新增 packaging 为 jar -->
@ -52,6 +52,9 @@
<groupId>cn.iocoder.boot</groupId> <groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-spring-boot-starter-test</artifactId> <artifactId>yudao-spring-boot-starter-test</artifactId>
</dependency> </dependency>
<!-- TODO @hao下面几个依赖的位置不太对。主要是它不属于 test可以参考别的模块顺序调整下哈 -->
<dependency> <dependency>
<groupId>cn.iocoder.boot</groupId> <groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-spring-boot-starter-excel</artifactId> <artifactId>yudao-spring-boot-starter-excel</artifactId>
@ -61,6 +64,7 @@
<artifactId>yudao-spring-boot-starter-websocket</artifactId> <artifactId>yudao-spring-boot-starter-websocket</artifactId>
</dependency> </dependency>
<!-- TODO @hao引入我们自己的 redis starter 哈 -->
<dependency> <dependency>
<groupId>org.redisson</groupId> <groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId> <artifactId>redisson-spring-boot-starter</artifactId>

View File

@ -18,36 +18,41 @@ import java.util.List;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
// TODO @hao: 管理后台 - IM 会话
@Tag(name = "管理后台 - 会话") @Tag(name = "管理后台 - 会话")
@RestController @RestController
@RequestMapping("/im/conversation") @RequestMapping("/im/conversation")
@Validated @Validated
public class ImConversationController { public class ImConversationController {
// TODO @hao: conversationService 即可
@Resource @Resource
private ImConversationService imConversationService; private ImConversationService imConversationService;
// TODO @hao/list 会话列表一般 get 是给单个对象或者 get-count 这种然后 conversation 已经是模块名了所以可以简化
@GetMapping("/get-conversation") @GetMapping("/get-conversation")
@Operation(summary = "获得用户的会话列表") @Operation(summary = "获得用户的会话列表")
@PreAuthorize("hasAuthority('im:conversation:query')") @PreAuthorize("hasAuthority('im:conversation:query')") // TODO @hao不用权限哈
public CommonResult<List<ImConversationRespVO>> getConversationList() { public CommonResult<List<ImConversationRespVO>> getConversationList() {
List<ImConversationDO> conversationList = imConversationService.getConversationList(); List<ImConversationDO> conversationList = imConversationService.getConversationList();
return success(BeanUtils.toBean(conversationList, ImConversationRespVO.class)); return success(BeanUtils.toBean(conversationList, ImConversationRespVO.class));
} }
// TODO @hao/update-pinned 保持和 db 字段一致哈
// TODO @hao这个接口需要单独的 VO
@PostMapping("/update-top") @PostMapping("/update-top")
@Operation(summary = "置顶会话") @Operation(summary = "置顶会话")
@PreAuthorize("hasAuthority('im:conversation:update')") @PreAuthorize("hasAuthority('im:conversation:update')") // TODO @hao不用权限哈因为肯定会判断是不是自己的
public CommonResult<Boolean> updateTop(@Valid @RequestBody ImConversationSaveReqVO updateReqVO) { public CommonResult<Boolean> updateTop(@Valid @RequestBody ImConversationSaveReqVO updateReqVO) {
imConversationService.updateTop(updateReqVO); imConversationService.updateTop(updateReqVO);
return success(true); return success(true);
} }
// TODO @hao这个接口需要单独的 VO
@PostMapping("/update-last-read-time") @PostMapping("/update-last-read-time")
@Operation(summary = "更新最后已读时间") @Operation(summary = "更新最后已读时间")
@PreAuthorize("hasAuthority('im:conversation:update')") @PreAuthorize("hasAuthority('im:conversation:update')") // TODO @hao不用权限哈因为肯定会判断是不是自己的
public CommonResult<Boolean> updateLastReadTime(@Valid @RequestBody ImConversationSaveReqVO updateReqVO) { public CommonResult<Boolean> updateLastReadTime(@Valid @RequestBody ImConversationSaveReqVO updateReqVO) {
imConversationService.updateLastReadTime(updateReqVO); imConversationService.updateLastReadTime(updateReqVO);
return success(true); return success(true);

View File

@ -11,7 +11,8 @@ import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 会话分页 Request VO") // TODO @hao这个貌似业务上暂时用不到可以考虑删除哈
@Schema(description = "管理后台 - IM 会话分页 Request VO")
@Data @Data
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true) @ToString(callSuper = true)

View File

@ -9,9 +9,11 @@ import java.time.LocalDateTime;
@Schema(description = "管理后台 - 会话 Response VO") @Schema(description = "管理后台 - 会话 Response VO")
@Data @Data
@ExcelIgnoreUnannotated @ExcelIgnoreUnannotated // TODO @haoexcel 的注解可以先删除
public class ImConversationRespVO { public class ImConversationRespVO {
// TODO @haoexample 都写下
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "13905") @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "13905")
@ExcelProperty("编号") @ExcelProperty("编号")
private Long id; private Long id;
@ -20,18 +22,22 @@ public class ImConversationRespVO {
@ExcelProperty("所属用户") @ExcelProperty("所属用户")
private Long userId; private Long userId;
// TODO @hao@Schema 可以改成会话类型不用把具体的数字写在上面哈这样后续改动会比较难改
@Schema(description = "类型1 单聊2 群聊4 通知会话(预留)", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") @Schema(description = "类型1 单聊2 群聊4 通知会话(预留)", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@ExcelProperty("类型1 单聊2 群聊4 通知会话(预留)") @ExcelProperty("类型1 单聊2 群聊4 通知会话(预留)")
private Integer conversationType; private Integer conversationType;
// TODO @hao只写聊天对象编号
@Schema(description = "单聊时,用户编号;群聊时,群编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "21454") @Schema(description = "单聊时,用户编号;群聊时,群编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "21454")
@ExcelProperty("单聊时,用户编号;群聊时,群编号") @ExcelProperty("单聊时,用户编号;群聊时,群编号")
private Long targetId; private Long targetId;
// TODO @hao只写 no 即可
@Schema(description = "会话标志 单聊s_{userId}_{targetId},需要排序 userId 和 targetId 群聊g_groupId", requiredMode = Schema.RequiredMode.REQUIRED) @Schema(description = "会话标志 单聊s_{userId}_{targetId},需要排序 userId 和 targetId 群聊g_groupId", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("会话标志 单聊s_{userId}_{targetId},需要排序 userId 和 targetId 群聊g_groupId") @ExcelProperty("会话标志 单聊s_{userId}_{targetId},需要排序 userId 和 targetId 群聊g_groupId")
private String no; private String no;
// TODO @hao只写 是否置顶0 1 是数据库的结果哈
@Schema(description = "是否置顶 0否 1是", requiredMode = Schema.RequiredMode.REQUIRED) @Schema(description = "是否置顶 0否 1是", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("是否置顶 0否 1是") @ExcelProperty("是否置顶 0否 1是")
private Boolean pinned; private Boolean pinned;

View File

@ -7,6 +7,7 @@ import lombok.Data;
import java.time.LocalDateTime; import java.time.LocalDateTime;
// TODO @hao这个貌似业务上暂时用不到可以考虑删除哈
@Schema(description = "管理后台 - 会话新增/修改 Request VO") @Schema(description = "管理后台 - 会话新增/修改 Request VO")
@Data @Data
public class ImConversationSaveReqVO { public class ImConversationSaveReqVO {

View File

@ -9,7 +9,7 @@ import lombok.*;
import java.time.LocalDateTime; import java.time.LocalDateTime;
/** /**
* 会话 DO * IM 会话 DO
* *
* @author 芋道源码 * @author 芋道源码
*/ */
@ -32,12 +32,21 @@ public class ImConversationDO extends BaseDO {
* 所属用户 * 所属用户
*/ */
private Long userId; private Long userId;
// TODO @hao注释可以改成如下
/**
* 会话类型
*
* 枚举 {@link cn.iocoder.yudao.module.im.enums.conversation.ImConversationTypeEnum}
*/
/** /**
* 类型1 单聊2 群聊4 通知会话预留 * 类型1 单聊2 群聊4 通知会话预留
*/ */
// TODO @haoconversationType 改成 type
private Integer conversationType; private Integer conversationType;
/** /**
* 单聊时用户编号群聊时群编号 * 聊天对象编号
*
* 1. 单聊时用户编号群聊时群编号
*/ */
private Long targetId; private Long targetId;
/** /**

View File

@ -5,7 +5,7 @@ import com.baomidou.mybatisplus.annotation.*;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
/** /**
* DO * IM 信息 DO
* *
* @author 芋道源码 * @author 芋道源码
*/ */
@ -24,14 +24,17 @@ public class ImGroupDO extends BaseDO {
*/ */
@TableId @TableId
private Long id; private Long id;
// TODO @haoname如果这个表已经是 group 不用在带额外的
/** /**
* 群名字 * 群名字
*/ */
private String groupName; private String groupName;
// TODO @hao关联字段
/** /**
* 群主id * 群主编号
*/ */
private Long ownerId; private Long ownerId;
// TODO @hao头像使用 avatar 好了整个项目统一然后 Thumb 是不是不用存这个更多是文件服务做裁剪
/** /**
* 群头像 * 群头像
*/ */

View File

@ -7,8 +7,9 @@ import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.*; import com.baomidou.mybatisplus.annotation.*;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
// TODO @hao这个挪到 group 包下
/** /**
* 群成员 DO * IM 群成员 DO
* *
* @author 芋道源码 * @author 芋道源码
*/ */
@ -27,14 +28,16 @@ public class GroupMemberDO extends BaseDO {
*/ */
@TableId @TableId
private Long id; private Long id;
// TODO @haogroupId userId 都写下关联字段哈
/** /**
* id * 编号
*/ */
private Long groupId; private Long groupId;
/** /**
* 用户id * 用户编号
*/ */
private Long userId; private Long userId;
// TODO @haonickname avatar 是不是不用存储哈
/** /**
* 昵称 * 昵称
*/ */

View File

@ -6,8 +6,9 @@ import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*; import lombok.*;
// TODO 我们要不要改成 ImMessageQueue 队列从理解上概念上可能都更清晰一点哈每个用户一个消息队列
/** /**
* 收件箱 DO * IM 收件箱 DO
* *
* @author 芋道源码 * @author 芋道源码
*/ */
@ -28,6 +29,8 @@ public class ImInboxDO extends BaseDO {
private Long id; private Long id;
/** /**
* 用户编号 * 用户编号
*
* TODO @hao写下 userId messageId 的关联字段
*/ */
private Long userId; private Long userId;
/** /**

View File

@ -9,7 +9,7 @@ import lombok.*;
import java.time.LocalDateTime; import java.time.LocalDateTime;
/** /**
* 消息 DO * IM 消息 DO
* *
* @author 芋道源码 * @author 芋道源码
*/ */
@ -32,6 +32,7 @@ public class ImMessageDO extends BaseDO {
* 客户端消息编号 uuid用于排重 * 客户端消息编号 uuid用于排重
*/ */
private String clientMessageId; private String clientMessageId;
// TODO @haosenderIdreceiverId 存储的具体值写下对应的群之类的
/** /**
* 发送人编号 * 发送人编号
*/ */
@ -40,18 +41,23 @@ public class ImMessageDO extends BaseDO {
* 接收人编号 * 接收人编号
*/ */
private Long receiverId; private Long receiverId;
// TODO @hao冗余字段要说明下的例如说
/** /**
* 发送人昵称 * 发送人昵称
*
* 冗余 AdminUserDO nickname 字段
*/ */
private String senderNickname; private String senderNickname;
/** /**
* 发送人头像 * 发送人头像
*/ */
private String senderAvatar; private String senderAvatar;
// TODO @hao关联枚举
/** /**
* 会话类型 * 会话类型
*/ */
private Integer conversationType; private Integer conversationType;
// TODO @hao关联字段
/** /**
* 会话标志 * 会话标志
*/ */
@ -60,6 +66,7 @@ public class ImMessageDO extends BaseDO {
* 消息类型 * 消息类型
*/ */
private Integer contentType; private Integer contentType;
// TODO @hao说明下是 json 格式在哪个包看具体的格式
/** /**
* 消息内容 * 消息内容
*/ */
@ -68,11 +75,12 @@ public class ImMessageDO extends BaseDO {
* 发送时间 * 发送时间
*/ */
private LocalDateTime sendTime; private LocalDateTime sendTime;
// TODO @hao搞个枚举然后代码里注释说明下
/** /**
* 消息来源 100-用户发送200-系统发送一般是通知 * 消息来源 100-用户发送200-系统发送一般是通知
*/ */
private Integer sendFrom; private Integer sendFrom;
// TODO @hao搞个枚举然后代码里注释说明下
/** /**
* 消息状态 1 发送中2 发送成功3 发送失败4 已删除5 已撤回 * 消息状态 1 发送中2 发送成功3 发送失败4 已删除5 已撤回
*/ */

View File

@ -8,6 +8,7 @@ import com.fasterxml.jackson.databind.JsonNode;
import java.io.IOException; import java.io.IOException;
// TODO @hao可以讨论下是不是前端传递 type + content后端根据 type 判断后直接 jsonutil 解析到对应的 body ok
public class ImMessageBodyDeserializer extends JsonDeserializer<ImMessageBody> { public class ImMessageBodyDeserializer extends JsonDeserializer<ImMessageBody> {
@Override @Override
@ -33,4 +34,5 @@ public class ImMessageBodyDeserializer extends JsonDeserializer<ImMessageBody> {
// 如果没有匹配的属性抛出异常 // 如果没有匹配的属性抛出异常
throw ctxt.mappingException("Cannot deserialize to an instance of ImMessageBody"); throw ctxt.mappingException("Cannot deserialize to an instance of ImMessageBody");
} }
} }

View File

@ -21,6 +21,7 @@ import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.*;
import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.*; import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.*;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
// TODO @hao单测可以先都删除等后面搞了在弄
/** /**
* {@link ImConversationServiceImpl} 的单元测试类 * {@link ImConversationServiceImpl} 的单元测试类
* *