Commit 14090be672d2302f9d76b2a01034d3dfc1a134c5

Authored by YunaiV
1 parent 6e1a8dc3

feat(im):将"免打扰"字段从 muted 全量重命名为 silent(DO/VO/Service/Mapper/测试/SQL + 前端 types/st…

…ore/组件/管理后台),为后续 mute 禁言功能腾出词族
Showing 20 changed files with 86 additions and 54 deletions
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/friend/vo/ImFriendRespVO.java
@@ -21,7 +21,7 @@ public class ImFriendRespVO { @@ -21,7 +21,7 @@ public class ImFriendRespVO {
21 private Long friendUserId; 21 private Long friendUserId;
22 22
23 @Schema(description = "是否免打扰", example = "false") 23 @Schema(description = "是否免打扰", example = "false")
24 - private Boolean muted; 24 + private Boolean silent;
25 25
26 @Schema(description = "好友展示备注(仅自己可见)", example = "老张") 26 @Schema(description = "好友展示备注(仅自己可见)", example = "老张")
27 private String displayName; 27 private String displayName;
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/friend/vo/ImFriendUpdateReqVO.java
@@ -14,7 +14,7 @@ public class ImFriendUpdateReqVO { @@ -14,7 +14,7 @@ public class ImFriendUpdateReqVO {
14 private Long friendUserId; 14 private Long friendUserId;
15 15
16 @Schema(description = "是否免打扰;不传表示不修改", example = "true") 16 @Schema(description = "是否免打扰;不传表示不修改", example = "true")
17 - private Boolean muted; 17 + private Boolean silent;
18 18
19 @Schema(description = "好友展示备注(仅自己可见);不传表示不修改,传空串表示清空", example = "老张") 19 @Schema(description = "好友展示备注(仅自己可见);不传表示不修改,传空串表示清空", example = "老张")
20 @Size(max = 16, message = "好友备注最多 16 个字符") 20 @Size(max = 16, message = "好友备注最多 16 个字符")
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/group/vo/member/ImGroupMemberRespVO.java
@@ -25,7 +25,7 @@ public class ImGroupMemberRespVO { @@ -25,7 +25,7 @@ public class ImGroupMemberRespVO {
25 private String groupRemark; 25 private String groupRemark;
26 26
27 @Schema(description = "是否免打扰") 27 @Schema(description = "是否免打扰")
28 - private Boolean muted; 28 + private Boolean silent;
29 29
30 @Schema(description = "成员状态", example = "0") 30 @Schema(description = "成员状态", example = "0")
31 private Integer status; 31 private Integer status;
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/group/vo/member/ImGroupMemberUpdateReqVO.java
@@ -21,6 +21,6 @@ public class ImGroupMemberUpdateReqVO { @@ -21,6 +21,6 @@ public class ImGroupMemberUpdateReqVO {
21 private String groupRemark; 21 private String groupRemark;
22 22
23 @Schema(description = "是否免打扰") 23 @Schema(description = "是否免打扰")
24 - private Boolean muted; 24 + private Boolean silent;
25 25
26 } 26 }
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/manager/friend/vo/ImFriendManagerPageReqVO.java
@@ -25,7 +25,7 @@ public class ImFriendManagerPageReqVO extends PageParam { @@ -25,7 +25,7 @@ public class ImFriendManagerPageReqVO extends PageParam {
25 private Integer status; // 参见 CommonStatusEnum 枚举类 25 private Integer status; // 参见 CommonStatusEnum 枚举类
26 26
27 @Schema(description = "是否免打扰", example = "false") 27 @Schema(description = "是否免打扰", example = "false")
28 - private Boolean muted; 28 + private Boolean silent;
29 29
30 @Schema(description = "添加好友时间", example = "[2026-04-01 00:00:00, 2026-04-30 23:59:59]") 30 @Schema(description = "添加好友时间", example = "[2026-04-01 00:00:00, 2026-04-30 23:59:59]")
31 @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) 31 @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/manager/friend/vo/ImFriendManagerRespVO.java
@@ -28,7 +28,7 @@ public class ImFriendManagerRespVO { @@ -28,7 +28,7 @@ public class ImFriendManagerRespVO {
28 private String displayName; 28 private String displayName;
29 29
30 @Schema(description = "是否免打扰", requiredMode = Schema.RequiredMode.REQUIRED, example = "false") 30 @Schema(description = "是否免打扰", requiredMode = Schema.RequiredMode.REQUIRED, example = "false")
31 - private Boolean muted; 31 + private Boolean silent;
32 32
33 @Schema(description = "好友状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0") 33 @Schema(description = "好友状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
34 private Integer status; // 参见 CommonStatusEnum 枚举类 34 private Integer status; // 参见 CommonStatusEnum 枚举类
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/manager/group/vo/member/ImGroupMemberManagerRespVO.java
@@ -25,7 +25,7 @@ public class ImGroupMemberManagerRespVO { @@ -25,7 +25,7 @@ public class ImGroupMemberManagerRespVO {
25 private String groupRemark; 25 private String groupRemark;
26 26
27 @Schema(description = "是否免打扰", example = "false") 27 @Schema(description = "是否免打扰", example = "false")
28 - private Boolean muted; 28 + private Boolean silent;
29 29
30 @Schema(description = "成员状态", example = "0") 30 @Schema(description = "成员状态", example = "0")
31 private Integer status; // 参见 CommonStatusEnum 枚举类 31 private Integer status; // 参见 CommonStatusEnum 枚举类
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/friend/ImFriendDO.java
@@ -15,7 +15,7 @@ import java.time.LocalDateTime; @@ -15,7 +15,7 @@ import java.time.LocalDateTime;
15 * 业务语义: 15 * 业务语义:
16 * - 双向关系:A-B 互为好友会存 2 条记录(userId=A, friendUserId=B 和 userId=B, friendUserId=A) 16 * - 双向关系:A-B 互为好友会存 2 条记录(userId=A, friendUserId=B 和 userId=B, friendUserId=A)
17 * - 状态管理:{@link #status} 使用 {@link CommonStatusEnum},ENABLE=正常,DISABLE=已删除 17 * - 状态管理:{@link #status} 使用 {@link CommonStatusEnum},ENABLE=正常,DISABLE=已删除
18 - * - 免打扰:{@link #muted} 控制是否屏蔽来自该好友的通知 18 + * - 免打扰:{@link #silent} 控制是否屏蔽来自该好友的通知
19 * - 联系人置顶:{@link #pinned} 单边,影响联系人 / 会话排序 19 * - 联系人置顶:{@link #pinned} 单边,影响联系人 / 会话排序
20 * - 黑名单:{@link #blocked} 弱关联 friend,单边屏蔽对方消息(必须先是好友) 20 * - 黑名单:{@link #blocked} 弱关联 friend,单边屏蔽对方消息(必须先是好友)
21 * 21 *
@@ -51,7 +51,7 @@ public class ImFriendDO extends BaseDO { @@ -51,7 +51,7 @@ public class ImFriendDO extends BaseDO {
51 /** 51 /**
52 * 是否免打扰 52 * 是否免打扰
53 */ 53 */
54 - private Boolean muted; 54 + private Boolean silent;
55 /** 55 /**
56 * 好友展示备注 56 * 好友展示备注
57 */ 57 */
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/group/ImGroupMemberDO.java
@@ -53,7 +53,7 @@ public class ImGroupMemberDO extends BaseDO { @@ -53,7 +53,7 @@ public class ImGroupMemberDO extends BaseDO {
53 /** 53 /**
54 * 是否免打扰 54 * 是否免打扰
55 */ 55 */
56 - private Boolean muted; 56 + private Boolean silent;
57 /** 57 /**
58 * 成员状态 58 * 成员状态
59 * <p> 59 * <p>
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/friend/ImFriendMapper.java
@@ -50,7 +50,7 @@ public interface ImFriendMapper extends BaseMapperX&lt;ImFriendDO&gt; { @@ -50,7 +50,7 @@ public interface ImFriendMapper extends BaseMapperX&lt;ImFriendDO&gt; {
50 .eqIfPresent(ImFriendDO::getUserId, reqVO.getUserId()) 50 .eqIfPresent(ImFriendDO::getUserId, reqVO.getUserId())
51 .eqIfPresent(ImFriendDO::getFriendUserId, reqVO.getFriendUserId()) 51 .eqIfPresent(ImFriendDO::getFriendUserId, reqVO.getFriendUserId())
52 .eqIfPresent(ImFriendDO::getStatus, reqVO.getStatus()) 52 .eqIfPresent(ImFriendDO::getStatus, reqVO.getStatus())
53 - .eqIfPresent(ImFriendDO::getMuted, reqVO.getMuted()) 53 + .eqIfPresent(ImFriendDO::getSilent, reqVO.getSilent())
54 .betweenIfPresent(ImFriendDO::getAddTime, reqVO.getAddTime()) 54 .betweenIfPresent(ImFriendDO::getAddTime, reqVO.getAddTime())
55 .orderByDesc(ImFriendDO::getId)); 55 .orderByDesc(ImFriendDO::getId));
56 } 56 }
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/enums/message/ImMessageTypeEnum.java
@@ -84,9 +84,9 @@ public enum ImMessageTypeEnum implements ArrayValuable&lt;Integer&gt; { @@ -84,9 +84,9 @@ public enum ImMessageTypeEnum implements ArrayValuable&lt;Integer&gt; {
84 */ 84 */
85 FRIEND_INFO_UPDATED(1209, "好友资料变更", false, false), 85 FRIEND_INFO_UPDATED(1209, "好友资料变更", false, false),
86 /** 86 /**
87 - * 对应 OpenIM:FriendsInfoUpdateNotification 1210(窄化到 muted / pinned 单边属性) 87 + * 对应 OpenIM:FriendsInfoUpdateNotification 1210(窄化到 silent / pinned 单边属性)
88 * 对应自己的类:FriendUpdateNotification 88 * 对应自己的类:FriendUpdateNotification
89 - * 场景:A 改了 muted / pinned 等单边属性,推 A 多端 89 + * 场景:A 改了 silent / pinned 等单边属性,推 A 多端
90 */ 90 */
91 FRIEND_UPDATE(1210, "好友信息批量更新", false, false), 91 FRIEND_UPDATE(1210, "好友信息批量更新", false, false),
92 92
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/framework/config/ImProperties.java 0 → 100644
  1 +package cn.iocoder.yudao.module.im.framework.config;
  2 +
  3 +import lombok.Data;
  4 +import org.springframework.boot.context.properties.ConfigurationProperties;
  5 +import org.springframework.stereotype.Component;
  6 +
  7 +/**
  8 + * IM 模块全局配置
  9 + * <p>
  10 + * 各子模块用嵌套 inner class 区分(friend / 后续 group / sensitive 等),
  11 + * yaml 路径保持 yudao.im.{module}.{key} 与原有部署保持兼容
  12 + *
  13 + * @author 芋道源码
  14 + */
  15 +@Component
  16 +@ConfigurationProperties(prefix = "yudao.im")
  17 +@Data
  18 +public class ImProperties {
  19 +
  20 + private Friend friend = new Friend();
  21 +
  22 + /**
  23 + * 好友模块配置
  24 + */
  25 + @Data
  26 + public static class Friend {
  27 +
  28 + /**
  29 + * 是否自动通过所有好友申请(全局开关)
  30 + * <p>
  31 + * 默认 false,普通用户必须走申请-审批流程;开启后所有用户的好友申请会立即同意,主要用于全员开放型 IM 部署。
  32 + * 如需细化到「仅特定用户自动通过」(如机器人 / AI 账号),请在 system 用户表加字段,并在 applyFriend 内按用户级开关短路
  33 + */
  34 + private boolean autoAccept = false;
  35 +
  36 + }
  37 +
  38 +}
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/friend/ImFriendServiceImpl.java
@@ -95,7 +95,7 @@ public class ImFriendServiceImpl implements ImFriendService { @@ -95,7 +95,7 @@ public class ImFriendServiceImpl implements ImFriendService {
95 @Override 95 @Override
96 public void updateFriend(Long userId, ImFriendUpdateReqVO reqVO) { 96 public void updateFriend(Long userId, ImFriendUpdateReqVO reqVO) {
97 // 1.1 校验:至少改一个字段(无字段变更,直接结束) 97 // 1.1 校验:至少改一个字段(无字段变更,直接结束)
98 - if (reqVO.getDisplayName() == null && reqVO.getMuted() == null && reqVO.getPinned() == null) { 98 + if (reqVO.getDisplayName() == null && reqVO.getSilent() == null && reqVO.getPinned() == null) {
99 return; 99 return;
100 } 100 }
101 // 1.2 校验好友关系存在 101 // 1.2 校验好友关系存在
@@ -106,13 +106,11 @@ public class ImFriendServiceImpl implements ImFriendService { @@ -106,13 +106,11 @@ public class ImFriendServiceImpl implements ImFriendService {
106 106
107 // 2. 更新好友属性(备注 / 免打扰 / 联系人置顶) 107 // 2. 更新好友属性(备注 / 免打扰 / 联系人置顶)
108 friendMapper.updateById(new ImFriendDO().setId(friend.getId()) 108 friendMapper.updateById(new ImFriendDO().setId(friend.getId())
109 - .setMuted(reqVO.getMuted())  
110 - .setDisplayName(reqVO.getDisplayName())  
111 - .setPinned(reqVO.getPinned())); 109 + .setSilent(reqVO.getSilent()).setDisplayName(reqVO.getDisplayName()).setPinned(reqVO.getPinned()));
112 110
113 // 3. 推 FRIEND_UPDATE 给 A 多端:所有单边属性变更合并为单条通知,避免多通知顺序竞争 111 // 3. 推 FRIEND_UPDATE 给 A 多端:所有单边属性变更合并为单条通知,避免多通知顺序竞争
114 FriendUpdateNotification payload = (FriendUpdateNotification) new FriendUpdateNotification() 112 FriendUpdateNotification payload = (FriendUpdateNotification) new FriendUpdateNotification()
115 - .setDisplayName(reqVO.getDisplayName()).setMuted(reqVO.getMuted()).setPinned(reqVO.getPinned()) 113 + .setDisplayName(reqVO.getDisplayName()).setSilent(reqVO.getSilent()).setPinned(reqVO.getPinned())
116 .setOperatorUserId(userId).setFriendUserId(reqVO.getFriendUserId()); 114 .setOperatorUserId(userId).setFriendUserId(reqVO.getFriendUserId());
117 websocketService.sendPrivateMessageAsync(userId, ImPrivateMessageDTO.ofFriendNotification( 115 websocketService.sendPrivateMessageAsync(userId, ImPrivateMessageDTO.ofFriendNotification(
118 ImMessageTypeEnum.FRIEND_UPDATE.getType(), userId, userId, payload)); 116 ImMessageTypeEnum.FRIEND_UPDATE.getType(), userId, userId, payload));
@@ -245,7 +243,7 @@ public class ImFriendServiceImpl implements ImFriendService { @@ -245,7 +243,7 @@ public class ImFriendServiceImpl implements ImFriendService {
245 243
246 /** 244 /**
247 * 单向绑定好友关系(内部方法,被 {@link #becomeFriends} / {@link #silentReAddFriend} 调用): 245 * 单向绑定好友关系(内部方法,被 {@link #becomeFriends} / {@link #silentReAddFriend} 调用):
248 - * - 情况一:已存在记录(含 ENABLE / DISABLE)→ 复用并恢复 ENABLE,muted / pinned / blocked 一并重置为 false 246 + * - 情况一:已存在记录(含 ENABLE / DISABLE)→ 复用并恢复 ENABLE,silent / pinned / blocked 一并重置为 false
249 * - 情况二:不存在记录 → 直接插入新记录 247 * - 情况二:不存在记录 → 直接插入新记录
250 * <p> 248 * <p>
251 * 并发安全:agree 路径由 {@code friend_request.handle_result} 的乐观锁单边推进; 249 * 并发安全:agree 路径由 {@code friend_request.handle_result} 的乐观锁单边推进;
@@ -255,11 +253,11 @@ public class ImFriendServiceImpl implements ImFriendService { @@ -255,11 +253,11 @@ public class ImFriendServiceImpl implements ImFriendService {
255 */ 253 */
256 public void addFriend0(Long userId, Long friendUserId, String displayName, Integer addSource) { 254 public void addFriend0(Long userId, Long friendUserId, String displayName, Integer addSource) {
257 ImFriendDO exists = friendMapper.selectByUserIdAndFriendUserId(userId, friendUserId); 255 ImFriendDO exists = friendMapper.selectByUserIdAndFriendUserId(userId, friendUserId);
258 - // 情况一:复用旧记录 → 恢复 ENABLE + 重置 muted / pinned / blocked 与首次新增对齐 256 + // 情况一:复用旧记录 → 恢复 ENABLE + 重置 silent / pinned / blocked 与首次新增对齐
259 if (exists != null) { 257 if (exists != null) {
260 ImFriendDO update = new ImFriendDO().setId(exists.getId()) 258 ImFriendDO update = new ImFriendDO().setId(exists.getId())
261 .setStatus(CommonStatusEnum.ENABLE.getStatus()).setAddTime(LocalDateTime.now()) 259 .setStatus(CommonStatusEnum.ENABLE.getStatus()).setAddTime(LocalDateTime.now())
262 - .setMuted(false).setPinned(false).setBlocked(false); 260 + .setSilent(false).setPinned(false).setBlocked(false);
263 if (displayName != null) { 261 if (displayName != null) {
264 update.setDisplayName(displayName); 262 update.setDisplayName(displayName);
265 } 263 }
@@ -271,7 +269,7 @@ public class ImFriendServiceImpl implements ImFriendService { @@ -271,7 +269,7 @@ public class ImFriendServiceImpl implements ImFriendService {
271 } 269 }
272 // 情况二:不存在记录 → 直接插入新记录 270 // 情况二:不存在记录 → 直接插入新记录
273 ImFriendDO friend = ImFriendDO.builder().userId(userId).friendUserId(friendUserId) 271 ImFriendDO friend = ImFriendDO.builder().userId(userId).friendUserId(friendUserId)
274 - .muted(false).pinned(false).blocked(false) 272 + .silent(false).pinned(false).blocked(false)
275 .displayName(displayName).addSource(addSource) 273 .displayName(displayName).addSource(addSource)
276 .status(CommonStatusEnum.ENABLE.getStatus()).addTime(LocalDateTime.now()).build(); 274 .status(CommonStatusEnum.ENABLE.getStatus()).addTime(LocalDateTime.now()).build();
277 friendMapper.insert(friend); 275 friendMapper.insert(friend);
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/group/ImGroupMemberServiceImpl.java
@@ -222,14 +222,14 @@ public class ImGroupMemberServiceImpl implements ImGroupMemberService { @@ -222,14 +222,14 @@ public class ImGroupMemberServiceImpl implements ImGroupMemberService {
222 groupMessageService.sendGroupMessage(userId, ImGroupMessageSendDTO.ofGroupMemberNicknameUpdate( 222 groupMessageService.sendGroupMessage(userId, ImGroupMessageSendDTO.ofGroupMemberNicknameUpdate(
223 groupId, userId, updateReqVO.getDisplayUserName())); 223 groupId, userId, updateReqVO.getDisplayUserName()));
224 } 224 }
225 - // 3.2 muted / groupRemark 是个人字段,仅推自己做多端同步;与旧值都相同跳过  
226 - boolean mutedChanged = updateReqVO.getMuted() != null  
227 - && ObjUtil.notEqual(updateReqVO.getMuted(), member.getMuted()); 225 + // 3.2 silent / groupRemark 是个人字段,仅推自己做多端同步;与旧值都相同跳过
  226 + boolean silentChanged = updateReqVO.getSilent() != null
  227 + && ObjUtil.notEqual(updateReqVO.getSilent(), member.getSilent());
228 boolean groupRemarkChanged = updateReqVO.getGroupRemark() != null 228 boolean groupRemarkChanged = updateReqVO.getGroupRemark() != null
229 && ObjUtil.notEqual(updateReqVO.getGroupRemark(), member.getGroupRemark()); 229 && ObjUtil.notEqual(updateReqVO.getGroupRemark(), member.getGroupRemark());
230 - if (mutedChanged || groupRemarkChanged) { 230 + if (silentChanged || groupRemarkChanged) {
231 groupMessageService.sendGroupMessage(userId, List.of(userId), ImGroupMessageSendDTO.ofGroupMemberSettingUpdate( 231 groupMessageService.sendGroupMessage(userId, List.of(userId), ImGroupMessageSendDTO.ofGroupMemberSettingUpdate(
232 - groupId, userId, updateReqVO.getMuted(), updateReqVO.getGroupRemark())); 232 + groupId, userId, updateReqVO.getSilent(), updateReqVO.getGroupRemark()));
233 } 233 }
234 } 234 }
235 235
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/message/dto/ImGroupMessageSendDTO.java
@@ -136,8 +136,7 @@ public class ImGroupMessageSendDTO { @@ -136,8 +136,7 @@ public class ImGroupMessageSendDTO {
136 public static ImGroupMessageSendDTO ofGroupNoticeUpdate(Long groupId, Long operatorUserId, String oldNotice, String newNotice) { 136 public static ImGroupMessageSendDTO ofGroupNoticeUpdate(Long groupId, Long operatorUserId, String oldNotice, String newNotice) {
137 GroupNoticeUpdateNotification notification = new GroupNoticeUpdateNotification(); 137 GroupNoticeUpdateNotification notification = new GroupNoticeUpdateNotification();
138 notification.setOperatorUserId(operatorUserId); 138 notification.setOperatorUserId(operatorUserId);
139 - notification.setOldNotice(oldNotice);  
140 - notification.setNewNotice(newNotice); 139 + notification.setOldNotice(oldNotice).setNewNotice(newNotice);
141 return new ImGroupMessageSendDTO().setGroupId(groupId) 140 return new ImGroupMessageSendDTO().setGroupId(groupId)
142 .setType(ImMessageTypeEnum.GROUP_NOTICE_UPDATE.getType()).setContent(notification); 141 .setType(ImMessageTypeEnum.GROUP_NOTICE_UPDATE.getType()).setContent(notification);
143 } 142 }
@@ -145,17 +144,15 @@ public class ImGroupMessageSendDTO { @@ -145,17 +144,15 @@ public class ImGroupMessageSendDTO {
145 public static ImGroupMessageSendDTO ofGroupNameUpdate(Long groupId, Long operatorUserId, String oldName, String newName) { 144 public static ImGroupMessageSendDTO ofGroupNameUpdate(Long groupId, Long operatorUserId, String oldName, String newName) {
146 GroupNameUpdateNotification notification = new GroupNameUpdateNotification(); 145 GroupNameUpdateNotification notification = new GroupNameUpdateNotification();
147 notification.setOperatorUserId(operatorUserId); 146 notification.setOperatorUserId(operatorUserId);
148 - notification.setOldName(oldName);  
149 - notification.setNewName(newName); 147 + notification.setOldName(oldName).setNewName(newName);
150 return new ImGroupMessageSendDTO().setGroupId(groupId) 148 return new ImGroupMessageSendDTO().setGroupId(groupId)
151 .setType(ImMessageTypeEnum.GROUP_NAME_UPDATE.getType()).setContent(notification); 149 .setType(ImMessageTypeEnum.GROUP_NAME_UPDATE.getType()).setContent(notification);
152 } 150 }
153 151
154 - public static ImGroupMessageSendDTO ofGroupMemberSettingUpdate(Long groupId, Long operatorUserId, Boolean muted, String groupRemark) { 152 + public static ImGroupMessageSendDTO ofGroupMemberSettingUpdate(Long groupId, Long operatorUserId, Boolean silent, String groupRemark) {
155 GroupMemberSettingUpdateNotification notification = new GroupMemberSettingUpdateNotification(); 153 GroupMemberSettingUpdateNotification notification = new GroupMemberSettingUpdateNotification();
156 notification.setOperatorUserId(operatorUserId); 154 notification.setOperatorUserId(operatorUserId);
157 - notification.setMuted(muted);  
158 - notification.setGroupRemark(groupRemark); 155 + notification.setSilent(silent).setGroupRemark(groupRemark);
159 return new ImGroupMessageSendDTO().setGroupId(groupId) 156 return new ImGroupMessageSendDTO().setGroupId(groupId)
160 .setType(ImMessageTypeEnum.GROUP_MEMBER_SETTING_UPDATE.getType()).setContent(notification); 157 .setType(ImMessageTypeEnum.GROUP_MEMBER_SETTING_UPDATE.getType()).setContent(notification);
161 } 158 }
@@ -164,8 +161,7 @@ public class ImGroupMessageSendDTO { @@ -164,8 +161,7 @@ public class ImGroupMessageSendDTO {
164 cn.iocoder.yudao.module.im.dal.dataobject.message.ImGroupMessageDO message) { 161 cn.iocoder.yudao.module.im.dal.dataobject.message.ImGroupMessageDO message) {
165 GroupMessagePinNotification notification = new GroupMessagePinNotification(); 162 GroupMessagePinNotification notification = new GroupMessagePinNotification();
166 notification.setOperatorUserId(operatorUserId); 163 notification.setOperatorUserId(operatorUserId);
167 - notification.setMessageId(message.getId());  
168 - notification.setMessage(message); 164 + notification.setMessageId(message.getId()).setMessage(message);
169 return new ImGroupMessageSendDTO().setGroupId(groupId) 165 return new ImGroupMessageSendDTO().setGroupId(groupId)
170 .setType(ImMessageTypeEnum.GROUP_MESSAGE_PIN.getType()).setContent(notification); 166 .setType(ImMessageTypeEnum.GROUP_MESSAGE_PIN.getType()).setContent(notification);
171 } 167 }
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/dto/notification/friend/FriendUpdateNotification.java
@@ -18,7 +18,7 @@ public class FriendUpdateNotification extends BaseFriendNotification { @@ -18,7 +18,7 @@ public class FriendUpdateNotification extends BaseFriendNotification {
18 /** 18 /**
19 * 免打扰;不为空则更新 19 * 免打扰;不为空则更新
20 */ 20 */
21 - private Boolean muted; 21 + private Boolean silent;
22 /** 22 /**
23 * 联系人置顶;不为空则更新 23 * 联系人置顶;不为空则更新
24 */ 24 */
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/dto/notification/group/GroupMemberSettingUpdateNotification.java
@@ -5,7 +5,7 @@ import lombok.Data; @@ -5,7 +5,7 @@ import lombok.Data;
5 /** 5 /**
6 * 群成员个人设置变更事件通知(个人多端同步) 6 * 群成员个人设置变更事件通知(个人多端同步)
7 * <p> 7 * <p>
8 - * muted / groupRemark 字段 null 表示本次未变更,前端按非 null 局部更新 8 + * silent / groupRemark 字段 null 表示本次未变更,前端按非 null 局部更新
9 */ 9 */
10 @Data 10 @Data
11 public class GroupMemberSettingUpdateNotification extends BaseGroupNotification { 11 public class GroupMemberSettingUpdateNotification extends BaseGroupNotification {
@@ -13,7 +13,7 @@ public class GroupMemberSettingUpdateNotification extends BaseGroupNotification @@ -13,7 +13,7 @@ public class GroupMemberSettingUpdateNotification extends BaseGroupNotification
13 /** 13 /**
14 * 群免打扰 14 * 群免打扰
15 */ 15 */
16 - private Boolean muted; 16 + private Boolean silent;
17 /** 17 /**
18 * 群备注 18 * 群备注
19 */ 19 */
yudao-module-im/src/test/java/cn/iocoder/yudao/module/im/service/friend/ImFriendServiceImplTest.java
@@ -81,19 +81,19 @@ public class ImFriendServiceImplTest extends BaseMockitoUnitTest { @@ -81,19 +81,19 @@ public class ImFriendServiceImplTest extends BaseMockitoUnitTest {
81 // 准备 81 // 准备
82 ImFriendUpdateReqVO reqVO = new ImFriendUpdateReqVO(); 82 ImFriendUpdateReqVO reqVO = new ImFriendUpdateReqVO();
83 reqVO.setFriendUserId(2L); 83 reqVO.setFriendUserId(2L);
84 - reqVO.setMuted(true); 84 + reqVO.setSilent(true);
85 ImFriendDO friend = ImFriendDO.builder().id(100L).userId(1L).friendUserId(2L) 85 ImFriendDO friend = ImFriendDO.builder().id(100L).userId(1L).friendUserId(2L)
86 - .muted(false).status(CommonStatusEnum.ENABLE.getStatus()).build(); 86 + .silent(false).status(CommonStatusEnum.ENABLE.getStatus()).build();
87 when(imFriendMapper.selectByUserIdAndFriendUserId(1L, 2L)).thenReturn(friend); 87 when(imFriendMapper.selectByUserIdAndFriendUserId(1L, 2L)).thenReturn(friend);
88 88
89 // 调用 89 // 调用
90 friendService.updateFriend(1L, reqVO); 90 friendService.updateFriend(1L, reqVO);
91 91
92 - // 断言:更新了 muted 字段 92 + // 断言:更新了 silent 字段
93 ArgumentCaptor<ImFriendDO> captor = ArgumentCaptor.forClass(ImFriendDO.class); 93 ArgumentCaptor<ImFriendDO> captor = ArgumentCaptor.forClass(ImFriendDO.class);
94 verify(imFriendMapper).updateById(captor.capture()); 94 verify(imFriendMapper).updateById(captor.capture());
95 assertEquals(100L, captor.getValue().getId()); 95 assertEquals(100L, captor.getValue().getId());
96 - assertTrue(captor.getValue().getMuted()); 96 + assertTrue(captor.getValue().getSilent());
97 // 断言:推送了好友更新通知 97 // 断言:推送了好友更新通知
98 verify(imWebSocketService).sendPrivateMessageAsync(eq(1L), any(ImPrivateMessageDTO.class)); 98 verify(imWebSocketService).sendPrivateMessageAsync(eq(1L), any(ImPrivateMessageDTO.class));
99 } 99 }
@@ -103,7 +103,7 @@ public class ImFriendServiceImplTest extends BaseMockitoUnitTest { @@ -103,7 +103,7 @@ public class ImFriendServiceImplTest extends BaseMockitoUnitTest {
103 // 准备 103 // 准备
104 ImFriendUpdateReqVO reqVO = new ImFriendUpdateReqVO(); 104 ImFriendUpdateReqVO reqVO = new ImFriendUpdateReqVO();
105 reqVO.setFriendUserId(2L); 105 reqVO.setFriendUserId(2L);
106 - reqVO.setMuted(true); 106 + reqVO.setSilent(true);
107 when(imFriendMapper.selectByUserIdAndFriendUserId(1L, 2L)).thenReturn(null); 107 when(imFriendMapper.selectByUserIdAndFriendUserId(1L, 2L)).thenReturn(null);
108 108
109 // 调用并断言 109 // 调用并断言
@@ -114,34 +114,34 @@ public class ImFriendServiceImplTest extends BaseMockitoUnitTest { @@ -114,34 +114,34 @@ public class ImFriendServiceImplTest extends BaseMockitoUnitTest {
114 114
115 @Test 115 @Test
116 public void testUpdateFriend_displayNameOnly() { 116 public void testUpdateFriend_displayNameOnly() {
117 - // 准备:只传备注、不传 muted —— 走差量更新 117 + // 准备:只传备注、不传 silent —— 走差量更新
118 ImFriendUpdateReqVO reqVO = new ImFriendUpdateReqVO(); 118 ImFriendUpdateReqVO reqVO = new ImFriendUpdateReqVO();
119 reqVO.setFriendUserId(2L); 119 reqVO.setFriendUserId(2L);
120 reqVO.setDisplayName("老张"); 120 reqVO.setDisplayName("老张");
121 ImFriendDO friend = ImFriendDO.builder().id(100L).userId(1L).friendUserId(2L) 121 ImFriendDO friend = ImFriendDO.builder().id(100L).userId(1L).friendUserId(2L)
122 - .muted(false).status(CommonStatusEnum.ENABLE.getStatus()).build(); 122 + .silent(false).status(CommonStatusEnum.ENABLE.getStatus()).build();
123 when(imFriendMapper.selectByUserIdAndFriendUserId(1L, 2L)).thenReturn(friend); 123 when(imFriendMapper.selectByUserIdAndFriendUserId(1L, 2L)).thenReturn(friend);
124 124
125 // 调用 125 // 调用
126 friendService.updateFriend(1L, reqVO); 126 friendService.updateFriend(1L, reqVO);
127 127
128 - // 断言:updateById 收到 displayName 但没有 muted(MyBatis-Plus 靠 NOT_NULL 跳过) 128 + // 断言:updateById 收到 displayName 但没有 silent(MyBatis-Plus 靠 NOT_NULL 跳过)
129 ArgumentCaptor<ImFriendDO> captor = ArgumentCaptor.forClass(ImFriendDO.class); 129 ArgumentCaptor<ImFriendDO> captor = ArgumentCaptor.forClass(ImFriendDO.class);
130 verify(imFriendMapper).updateById(captor.capture()); 130 verify(imFriendMapper).updateById(captor.capture());
131 assertEquals(100L, captor.getValue().getId()); 131 assertEquals(100L, captor.getValue().getId());
132 assertEquals("老张", captor.getValue().getDisplayName()); 132 assertEquals("老张", captor.getValue().getDisplayName());
133 - assertNull(captor.getValue().getMuted()); 133 + assertNull(captor.getValue().getSilent());
134 // 断言:推送好友更新通知 134 // 断言:推送好友更新通知
135 verify(imWebSocketService).sendPrivateMessageAsync(eq(1L), any(ImPrivateMessageDTO.class)); 135 verify(imWebSocketService).sendPrivateMessageAsync(eq(1L), any(ImPrivateMessageDTO.class));
136 } 136 }
137 137
138 @Test 138 @Test
139 public void testUpdateFriend_emptyRequest() { 139 public void testUpdateFriend_emptyRequest() {
140 - // 准备:muted 和 displayName 都不传 —— 直接返回,不打 SQL 也不发推送 140 + // 准备:silent 和 displayName 都不传 —— 直接返回,不打 SQL 也不发推送
141 ImFriendUpdateReqVO reqVO = new ImFriendUpdateReqVO(); 141 ImFriendUpdateReqVO reqVO = new ImFriendUpdateReqVO();
142 reqVO.setFriendUserId(2L); 142 reqVO.setFriendUserId(2L);
143 ImFriendDO friend = ImFriendDO.builder().id(100L).userId(1L).friendUserId(2L) 143 ImFriendDO friend = ImFriendDO.builder().id(100L).userId(1L).friendUserId(2L)
144 - .muted(false).status(CommonStatusEnum.ENABLE.getStatus()).build(); 144 + .silent(false).status(CommonStatusEnum.ENABLE.getStatus()).build();
145 when(imFriendMapper.selectByUserIdAndFriendUserId(1L, 2L)).thenReturn(friend); 145 when(imFriendMapper.selectByUserIdAndFriendUserId(1L, 2L)).thenReturn(friend);
146 146
147 // 调用 147 // 调用
yudao-module-im/src/test/java/cn/iocoder/yudao/module/im/service/group/ImGroupMemberServiceImplTest.java
@@ -233,14 +233,14 @@ public class ImGroupMemberServiceImplTest extends BaseMockitoUnitTest { @@ -233,14 +233,14 @@ public class ImGroupMemberServiceImplTest extends BaseMockitoUnitTest {
233 when(groupMemberMapper.selectByGroupIdAndUserId(10L, 1L)).thenReturn(member); 233 when(groupMemberMapper.selectByGroupIdAndUserId(10L, 1L)).thenReturn(member);
234 234
235 ImGroupMemberUpdateReqVO reqVO = new ImGroupMemberUpdateReqVO() 235 ImGroupMemberUpdateReqVO reqVO = new ImGroupMemberUpdateReqVO()
236 - .setGroupId(10L).setMuted(true).setDisplayUserName("昵称"); 236 + .setGroupId(10L).setSilent(true).setDisplayUserName("昵称");
237 237
238 groupMemberService.updateGroupMember(1L, reqVO); 238 groupMemberService.updateGroupMember(1L, reqVO);
239 239
240 ArgumentCaptor<ImGroupMemberDO> captor = ArgumentCaptor.forClass(ImGroupMemberDO.class); 240 ArgumentCaptor<ImGroupMemberDO> captor = ArgumentCaptor.forClass(ImGroupMemberDO.class);
241 verify(groupMemberMapper).updateById(captor.capture()); 241 verify(groupMemberMapper).updateById(captor.capture());
242 assertEquals(50L, captor.getValue().getId()); 242 assertEquals(50L, captor.getValue().getId());
243 - assertTrue(captor.getValue().getMuted()); 243 + assertTrue(captor.getValue().getSilent());
244 verify(webSocketService).sendGroupMessageAsync(eq(1L), any(ImGroupMessageDTO.class)); 244 verify(webSocketService).sendGroupMessageAsync(eq(1L), any(ImGroupMessageDTO.class));
245 } 245 }
246 246
yudao-module-im/src/test/resources/sql/create_tables.sql
@@ -64,7 +64,7 @@ CREATE TABLE IF NOT EXISTS &quot;im_group_member&quot; ( @@ -64,7 +64,7 @@ CREATE TABLE IF NOT EXISTS &quot;im_group_member&quot; (
64 "user_id" bigint NOT NULL COMMENT '用户编号', 64 "user_id" bigint NOT NULL COMMENT '用户编号',
65 "display_user_name" varchar(64) DEFAULT NULL COMMENT '组内显示名', 65 "display_user_name" varchar(64) DEFAULT NULL COMMENT '组内显示名',
66 "group_remark" varchar(64) DEFAULT NULL COMMENT '群备注', 66 "group_remark" varchar(64) DEFAULT NULL COMMENT '群备注',
67 - "muted" bit DEFAULT FALSE COMMENT '是否免打扰', 67 + "silent" bit DEFAULT FALSE COMMENT '是否免打扰',
68 "status" tinyint NOT NULL COMMENT '成员状态', 68 "status" tinyint NOT NULL COMMENT '成员状态',
69 "role" tinyint NOT NULL DEFAULT 3 COMMENT '成员角色:1=群主 2=管理员 3=普通成员', 69 "role" tinyint NOT NULL DEFAULT 3 COMMENT '成员角色:1=群主 2=管理员 3=普通成员',
70 "join_time" timestamp DEFAULT NULL COMMENT '入群时间', 70 "join_time" timestamp DEFAULT NULL COMMENT '入群时间',
@@ -82,7 +82,7 @@ CREATE TABLE IF NOT EXISTS &quot;im_friend&quot; ( @@ -82,7 +82,7 @@ CREATE TABLE IF NOT EXISTS &quot;im_friend&quot; (
82 "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY COMMENT '编号', 82 "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY COMMENT '编号',
83 "user_id" bigint NOT NULL COMMENT '用户编号', 83 "user_id" bigint NOT NULL COMMENT '用户编号',
84 "friend_user_id" bigint NOT NULL COMMENT '好友用户编号', 84 "friend_user_id" bigint NOT NULL COMMENT '好友用户编号',
85 - "muted" bit DEFAULT FALSE COMMENT '是否免打扰', 85 + "silent" bit DEFAULT FALSE COMMENT '是否免打扰',
86 "display_name" varchar(64) NOT NULL DEFAULT '' COMMENT '好友展示备注(仅自己可见)', 86 "display_name" varchar(64) NOT NULL DEFAULT '' COMMENT '好友展示备注(仅自己可见)',
87 "add_source" tinyint DEFAULT NULL COMMENT '添加来源', 87 "add_source" tinyint DEFAULT NULL COMMENT '添加来源',
88 "pinned" bit DEFAULT FALSE COMMENT '是否置顶联系人', 88 "pinned" bit DEFAULT FALSE COMMENT '是否置顶联系人',