• 优化好友状态的获取和验证逻辑,将 ImFriendStateEnum 的使用改为整型状态值,简化了好友关系的校验过程。新增 validateFriend 方法,统一处理好友和黑名单的校验,提升代码可读性和维护性。
    YunaiV authored
     
    Browse Dir »

  • ImProperties.message 新增 privateReadEnabled / groupReadEnabled,前端 config.ts 同步镜像。关闭后:
    - 后端:read 系列接口(read / getMaxReadMessageId / getGroupReadUserIds)抛业务异常;sendGroupMessage 强制 NO_RECEIPT 忽略 receipt=true;pull 群消息跳过 Redis 已读游标读取与 readCount 补齐
    - 前端:气泡已读标签 / 群回执 popover / 「发送回执消息」下拉入口 / admin 列表「状态」「回执」列与详情对应字段按开关隐藏;自动上报 / 冷启动同步对方已读位置 / WS READ & RECEIPT handler 全部按开关短路兜底,避免打到禁用接口
    - 单测:补 @Spy ImProperties 修复原本就在的 NPE,加 disabled 分支断言
    YunaiV authored
     
    Browse Dir »

  • 后端
    - createInviteRequestList N+1 → 3 SQL:批量 select IN + update IN + insertBatch;20 人邀请从 40 RTT 降到 3 RTT
    - service 不再出现 mybatis:复用记录的 update(null, wrapper) 下沉到 Im{Group,Friend}RequestMapper.update*Reset helper
    - inviteGroupMember 入参去重切 hutool:CollUtil.subtractToList(CollUtil.distinct(...), activeMemberUserIds)
    - 删除 dead 字段 inviterUserId(GroupRequestApprovedNotification / GroupRequestRejectedNotification):前端不再消费
    
    前端
    - 1505 / 1506 通知改静默:同意走群事件 1509 / 1510 渲染系统提示,拒绝不再打扰
    - 修竞态:addByRequestId 校验 handleResult === UNHANDLED,避免 1503 在途时被 1505 / 1506 抢先后又把已处理记录塞回未处理列表
    - 修复 dialog 复用记录刷新:watch key 含 inviterUserId / applyContent,同 id 不同内容也触发 refetch;actingId 期间跳过避免本端动作多余 RTT
    - 修复 willGoApproval 误报:group.ownerUserId 兜底群主;members 未到位时保守按非审批处理
    - unhandledCountMap memoized getter:O(N) 扫一次缓存到 Map,ConversationItem 直读 Map 消除 O(N×M) 重复 filter
    YunaiV authored
     
    Browse Dir »
  • - 邀请路径写 addSource=INVITE;群主 / 管理员邀请绕过审批;inviteGroupMember 入参去重
    - getGroupRequest 越权校验加成员有效状态判断;新增 list-by-group 接口
    - 申请列表按 update_time 倒序,update(null, wrapper) 路径手动刷 updateTime
    - addByRequestId 不再 skip 同 id,复用记录刷新并置顶
    - GroupRequestListDialog 单群模式订阅 store 增量同步;GroupMemberAddDialog 审批分支文案区分
    - ConversationItem 增加 [X 条进群申请] 红字前缀;MessagePanel 顶部胶囊横幅
    - 1505 / 1506 通知改静默:同意走群事件渲染系统提示,拒绝不再打扰;清掉 dead inviterUserId 字段
    YunaiV authored
     
    Browse Dir »







  • 私聊已读语义在 message.status 字段翻转,离线期间错过的 RECEIPT 推送没法
    重放(与群聊不同——群聊已读在 message.readCount / receiptStatus 字段自带)。
    新增此接口:客户端进入私聊会话或断线重连后,拿到对方已读到我发的最大消息
    id,按 id <= maxReadId 翻转本地自发消息状态。
    实现:
    - mapper 用 order by id desc + LIMIT 1 命中 (sender_id, receiver_id)
      索引,无 max() 聚合开销;
    - 对方一条都没读过时返回 null(不做 0 兜底,避免与真实 id 混淆);
    - 补齐 hit / miss 两个单测。
    YunaiV authored
     
    Browse Dir »
  • 原 readPrivateMessages 走 select-then-update 两步:先按 status=UNREAD
    查未读,再按 id in 翻转,maxReadId 取已 update 行的 max(id)。该实现
    有两个问题:
    1. select 与 update 之间到达的消息会被一并标 READ,但 maxReadId 取的
       是 select 时刻的最大值,对方端拿到的「已读到哪条」语义偏弱,前端按
       maxReadId 卡边界时也会与实际状态错位。
    2. 接口与群聊 readGroupMessages(userId, groupId, messageId) 不对称。
    
    改造:
    - 接口签名增加 messageId(已读位置,含),与群聊接口对齐;
    - mapper 替换为单条 update SQL:id <= messageId AND status=UNREAD 直接
      翻转,消除两步竞态窗口;
    - READ / RECEIPT 推送的已读位置直接采用前端上报的 messageId;
    - 落地 ImPrivateMessageServiceImpl 原 TODO;
    - 同步更新 testReadMessages_success / testReadMessages_noUnread。
    YunaiV authored
     
    Browse Dir »