Commit 96f2d1a12fb191fff8627923f94e4c9ef686b2d2
1 parent
b0b707dd
✨ feat(friend): 添加好友展示备注功能
Showing
7 changed files
with
58 additions
and
5 deletions
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/friend/ImFriendController.java
| ... | ... | @@ -75,7 +75,7 @@ public class ImFriendController { |
| 75 | 75 | } |
| 76 | 76 | |
| 77 | 77 | @PutMapping("/update") |
| 78 | - @Operation(summary = "更新好友信息(当前仅免打扰)") | |
| 78 | + @Operation(summary = "更新好友信息") | |
| 79 | 79 | public CommonResult<Boolean> updateFriend(@Valid @RequestBody ImFriendUpdateReqVO reqVO) { |
| 80 | 80 | friendService.updateFriend(getLoginUserId(), reqVO); |
| 81 | 81 | return success(true); | ... | ... |
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/friend/vo/ImFriendRespVO.java
| ... | ... | @@ -23,6 +23,9 @@ public class ImFriendRespVO { |
| 23 | 23 | @Schema(description = "是否免打扰", example = "false") |
| 24 | 24 | private Boolean muted; |
| 25 | 25 | |
| 26 | + @Schema(description = "好友展示备注(仅自己可见)", example = "老张") | |
| 27 | + private String displayName; | |
| 28 | + | |
| 26 | 29 | @Schema(description = "好友状态(0=正常,1=已删除)", example = "0") |
| 27 | 30 | private Integer status; |
| 28 | 31 | ... | ... |
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/friend/vo/ImFriendUpdateReqVO.java
| ... | ... | @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.im.controller.admin.friend.vo; |
| 2 | 2 | |
| 3 | 3 | import io.swagger.v3.oas.annotations.media.Schema; |
| 4 | 4 | import jakarta.validation.constraints.NotNull; |
| 5 | +import jakarta.validation.constraints.Size; | |
| 5 | 6 | import lombok.Data; |
| 6 | 7 | |
| 7 | 8 | @Schema(description = "管理后台 - IM 好友更新 Request VO") |
| ... | ... | @@ -12,8 +13,11 @@ public class ImFriendUpdateReqVO { |
| 12 | 13 | @NotNull(message = "好友用户编号不能为空") |
| 13 | 14 | private Long friendUserId; |
| 14 | 15 | |
| 15 | - @Schema(description = "是否免打扰", requiredMode = Schema.RequiredMode.REQUIRED, example = "true") | |
| 16 | - @NotNull(message = "免打扰状态不能为空") | |
| 16 | + @Schema(description = "是否免打扰;不传表示不修改", example = "true") | |
| 17 | 17 | private Boolean muted; |
| 18 | 18 | |
| 19 | + @Schema(description = "好友展示备注(仅自己可见);不传表示不修改,传空串表示清空", example = "老张") | |
| 20 | + @Size(max = 16, message = "好友备注最多 16 个字符") | |
| 21 | + private String displayName; | |
| 22 | + | |
| 19 | 23 | } | ... | ... |
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/friend/ImFriendDO.java
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/friend/ImFriendServiceImpl.java
| ... | ... | @@ -84,8 +84,9 @@ public class ImFriendServiceImpl implements ImFriendService { |
| 84 | 84 | throw exception(FRIEND_NOT_FRIEND); |
| 85 | 85 | } |
| 86 | 86 | |
| 87 | - // 2. 更新好友属性(目前仅免打扰) | |
| 88 | - imFriendMapper.updateById(new ImFriendDO().setId(friend.getId()).setMuted(reqVO.getMuted())); | |
| 87 | + // 2. 更新好友属性 | |
| 88 | + imFriendMapper.updateById(new ImFriendDO().setId(friend.getId()) | |
| 89 | + .setMuted(reqVO.getMuted()).setDisplayName(reqVO.getDisplayName())); | |
| 89 | 90 | |
| 90 | 91 | // 3. 推送好友更新通知(多端同步) |
| 91 | 92 | imWebSocketService.sendPrivateMessageAsync(userId, | ... | ... |
yudao-module-im/src/test/java/cn/iocoder/yudao/module/im/service/friend/ImFriendServiceImplTest.java
| ... | ... | @@ -112,6 +112,46 @@ public class ImFriendServiceImplTest extends BaseMockitoUnitTest { |
| 112 | 112 | assertEquals(FRIEND_NOT_FRIEND.getCode(), exception.getCode()); |
| 113 | 113 | } |
| 114 | 114 | |
| 115 | + @Test | |
| 116 | + public void testUpdateFriend_displayNameOnly() { | |
| 117 | + // 准备:只传备注、不传 muted —— 走差量更新 | |
| 118 | + ImFriendUpdateReqVO reqVO = new ImFriendUpdateReqVO(); | |
| 119 | + reqVO.setFriendUserId(2L); | |
| 120 | + reqVO.setDisplayName("老张"); | |
| 121 | + ImFriendDO friend = ImFriendDO.builder().id(100L).userId(1L).friendUserId(2L) | |
| 122 | + .muted(false).status(CommonStatusEnum.ENABLE.getStatus()).build(); | |
| 123 | + when(imFriendMapper.selectByUserIdAndFriendUserId(1L, 2L)).thenReturn(friend); | |
| 124 | + | |
| 125 | + // 调用 | |
| 126 | + friendService.updateFriend(1L, reqVO); | |
| 127 | + | |
| 128 | + // 断言:updateById 收到 displayName 但没有 muted(MyBatis-Plus 靠 NOT_NULL 跳过) | |
| 129 | + ArgumentCaptor<ImFriendDO> captor = ArgumentCaptor.forClass(ImFriendDO.class); | |
| 130 | + verify(imFriendMapper).updateById(captor.capture()); | |
| 131 | + assertEquals(100L, captor.getValue().getId()); | |
| 132 | + assertEquals("老张", captor.getValue().getDisplayName()); | |
| 133 | + assertNull(captor.getValue().getMuted()); | |
| 134 | + // 断言:推送好友更新通知 | |
| 135 | + verify(imWebSocketService).sendPrivateMessageAsync(eq(1L), any(ImPrivateMessageDTO.class)); | |
| 136 | + } | |
| 137 | + | |
| 138 | + @Test | |
| 139 | + public void testUpdateFriend_emptyRequest() { | |
| 140 | + // 准备:muted 和 displayName 都不传 —— 短路返回,不打 SQL 也不发推送 | |
| 141 | + ImFriendUpdateReqVO reqVO = new ImFriendUpdateReqVO(); | |
| 142 | + reqVO.setFriendUserId(2L); | |
| 143 | + ImFriendDO friend = ImFriendDO.builder().id(100L).userId(1L).friendUserId(2L) | |
| 144 | + .muted(false).status(CommonStatusEnum.ENABLE.getStatus()).build(); | |
| 145 | + when(imFriendMapper.selectByUserIdAndFriendUserId(1L, 2L)).thenReturn(friend); | |
| 146 | + | |
| 147 | + // 调用 | |
| 148 | + friendService.updateFriend(1L, reqVO); | |
| 149 | + | |
| 150 | + // 断言:没触发 SQL 更新 / 没发 WebSocket 推送 | |
| 151 | + verify(imFriendMapper, never()).updateById(any(ImFriendDO.class)); | |
| 152 | + verify(imWebSocketService, never()).sendPrivateMessageAsync(any(Long.class), any(ImPrivateMessageDTO.class)); | |
| 153 | + } | |
| 154 | + | |
| 115 | 155 | // ========== addFriend ========== |
| 116 | 156 | |
| 117 | 157 | @Test | ... | ... |
yudao-module-im/src/test/resources/sql/create_tables.sql
| ... | ... | @@ -81,6 +81,7 @@ CREATE TABLE IF NOT EXISTS "im_friend" ( |
| 81 | 81 | "user_id" bigint NOT NULL COMMENT '用户编号', |
| 82 | 82 | "friend_user_id" bigint NOT NULL COMMENT '好友用户编号', |
| 83 | 83 | "muted" bit DEFAULT FALSE COMMENT '是否免打扰', |
| 84 | + "display_name" varchar(64) NOT NULL DEFAULT '' COMMENT '好友展示备注(仅自己可见)', | |
| 84 | 85 | "status" tinyint NOT NULL COMMENT '好友状态', |
| 85 | 86 | "add_time" timestamp DEFAULT NULL COMMENT '添加好友时间', |
| 86 | 87 | "delete_time" timestamp DEFAULT NULL COMMENT '删除好友时间', | ... | ... |