YunaiV
|
89a49cf19c
|
refactor(frontend): 统一当前登录用户 ID 获取入口
- 新增 getCurrentUserId 到 utils/auth
- 替换 IM、CRM、BPM、MES、Mall 等模块中直接读取 userStore.getUser.id 的写法
- 移除 IM 内部 currentUser 工具依赖,统一从全局 auth 工具获取当前用户编号
- 保留 userStore 对昵称、头像、部门等非 ID 字段的读取
|
2026-05-28 23:38:46 +08:00 |
YunaiV
|
763e11eb78
|
refactor(im): 统一本地存储入口和 store 命名
- 删除 utils/storage.ts,getCurrentUserId 移到 utils/user.ts
- StorageKeys 移到 utils/db.ts,按 localStorage / settings 分组
- db 客户端新增 clearStore;整桶 store 改为 clearStore + 循环 put 单事务
- 业务 store action / getter 统一改为 verbXxxList / verbXxx 风格
- draft API 加 Conversation 前缀;FriendStore loadFriends 改名 loadFriendData
- 卸载 localforage 依赖
|
2026-05-28 19:49:54 +08:00 |
YunaiV
|
664904bd06
|
refactor(im): 拆分会话消息存储并合并草稿
- 新增 IM IndexedDB DB client,按当前用户初始化本地库
- 将会话与消息拆成 conversations / messages 逐条存储
- 将草稿合并进 Conversation.draft,删除 draftStore
- 优化 pull 批量写入,消息、会话摘要和游标同事务落库
- 统一 store action 命名,清理旧 localStorage key 和 TODO
- 保留 maxId settings 游标,避免本地消息回收后游标回退
|
2026-05-28 08:39:49 +08:00 |
YunaiV
|
811b93d9f1
|
refactor(im): 拆分会话和消息本地存储
- 新增 IM IndexedDB DB 封装、schema、key helper 和 session guard
- 新增 messageStore,支持消息逐条持久化、分页加载、ack 合并、撤回和回执更新
- 调整 conversationStore 只持久化会话摘要,不再内嵌 messages 数组
- 切换发送、拉取、WebSocket、媒体上传和消息组件到 messageStore
- 增加离开 IM 时的 store 清理和本地存储序列化保护
|
2026-05-27 23:46:18 +08:00 |
YunaiV
|
8b06efe5ee
|
fix: 加强 IM 上传 URL 与 RTC 来电载荷校验
|
2026-05-24 23:41:46 +08:00 |
YunaiV
|
9893aedbb2
|
✨ feat(im): 修一批 WS 健壮性与跨账号防御
- WS 重连改指数退避(1→2→4→8→16→30s + jitter),频率封顶不再固定 3s 形成惊群
- onerror 不再调 reconnect,主动 close 让 onclose 成为唯一重连入口,避免双触计数 +2
- 私聊 / 群消息入口加防御层,senderId / receiverId / 定向 receiverUserIds 不含当前用户的帧直接丢弃
- useMessagePuller 引入 epoch + userId 双重快照,离开 IM / 切账号时旧 pull 写入前自检跳出
- cancelPull 同步清 WS messageBuffer,防止下次进 IM 把旧 session 缓冲帧回放进新 store
|
2026-05-21 20:02:44 +08:00 |
YunaiV
|
7a236b4378
|
✨ feat(im): 修 L-13/L-16:PagedScroller 加 itemKey 防索引乱位、私聊 Message.targetId 改对端 userId、抽 getPrivateMessagePeerId 收敛 4 处 peer 计算
|
2026-05-21 14:50:42 +08:00 |
YunaiV
|
29b257b8cd
|
✨ feat(im): 修一批状态串扰:群申请列表防同群 WS 推送乱序覆盖、群免打扰同步会话、跨端群已读清 @、联系人 selection 跟随 store、好友申请按钮并发锁
|
2026-05-21 11:11:36 +08:00 |
YunaiV
|
8468d9bf4d
|
✨ feat(im): 修 WebSocket 重复连接:connect 入口检测旧 socket 状态复用 / 重建,disconnect 解绑全部 handler
|
2026-05-21 08:41:44 +08:00 |
YunaiV
|
f7cda1fc4e
|
✨ feat(im): 修一组细节:会话 silent 跟随新消息同步、合并末尾刷摘要 + 群 @ 标记、录音 1s 下限、邀请 reload 透 friendIds、pull 游标取最大 id
|
2026-05-21 01:13:29 +08:00 |
YunaiV
|
fc812aef26
|
✨ feat(im): 增加频道消息的已读状态
|
2026-05-20 01:00:46 +08:00 |
YunaiV
|
bfd407d75b
|
✨ feat(im): 继续优化频道的各种代码,
|
2026-05-19 17:18:48 +08:00 |
YunaiV
|
5ebbbf7499
|
✨ feat(im): 新增频道消息的前端实现
|
2026-05-19 13:26:32 +08:00 |
YunaiV
|
b52ad0c34b
|
refactor: 前端 IM API 移除 src/api/im/home 中间目录,face / friend / group / message / rtc 直接放在 src/api/im 下
|
2026-05-18 13:20:43 +08:00 |
YunaiV
|
f58d1d88c8
|
✨ feat(im): 振铃超时 Job 单人粒度标 NO_ANSWER + 独立 NO_ANSWER 信令推送
✨ feat(im): 处理 RTC_CALL(NO_ANSWER) 信令;私聊气泡显示「未接听」
|
2026-05-18 08:03:52 +08:00 |
YunaiV
|
b9b085f1ee
|
✨ feat(im): 群通话本端拒绝 / 挂断后立即从胶囊条移除自己,无需等后端推回
|
2026-05-18 00:00:53 +08:00 |
YunaiV
|
b455ce4949
|
✨ feat(im): 优化 rtcStore 的命名
|
2026-05-14 22:15:35 +08:00 |
YunaiV
|
e579a4de13
|
✨ feat(im): 优化 rtc 整体弹窗界面
|
2026-05-14 09:44:39 +08:00 |
YunaiV
|
e12596ad7c
|
♻️ refactor(im): 移动 IM 相关 API 引用至新路径
|
2026-05-09 01:25:03 +08:00 |
YunaiV
|
2935d7d112
|
✨ feat(im): 拆出私聊 / 群聊已读两个全局开关,关闭后禁用接口与所有 UI 入口(含群回执)
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 分支断言
|
2026-05-09 01:07:18 +08:00 |
YunaiV
|
cb26df3ca1
|
✨ feat(im): 初始化群申请 v0.4:第五把 review(多轮 finding 修复 + 通知静默化)
- 邀请路径写 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 字段
|
2026-05-07 00:51:48 +08:00 |
YunaiV
|
8fc5273a88
|
✨ feat(im): 初始化群申请 v0.1:第二把 review
|
2026-05-06 18:52:30 +08:00 |
YunaiV
|
5bd99c53c2
|
🐛 fix(im):codex 评审修复 FRIEND_ADD / FRIEND_DELETE 接收方 peer 与 clear 气泡
- FRIEND_ADD 接收方 peer 改按帧 sender / receiver 反推:becomeFriends 单条入库后双方收到同一份 payload,payload.friendUserId 固定是 toUserId,本端真正的对端要看自己是 sender 还是 receiver;新增 websocketStore.computeFriendPeerId 算好后传给 friendStore.applyFriendAdd/DeleteNotification
- FRIEND_DELETE clear=true 跳过气泡插入:clear 语义是清会话本身,气泡分支按 isFriendDeleteWithClear 校验,避免在已清会话里写虚拟消息
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
2026-05-05 22:32:04 +08:00 |
YunaiV
|
a9f54fdee1
|
feat(im): 重构普通消息类型,和 openim 的消息编号对齐
|
2026-05-05 21:56:05 +08:00 |
YunaiV
|
4d006f8e73
|
feat(im):将"免打扰"字段从 muted 全量重命名为 silent(DO/VO/Service/Mapper/测试/SQL + 前端 types/store/组件/管理后台),为后续 mute 禁言功能腾出词族
|
2026-05-05 13:51:53 +08:00 |
YunaiV
|
b242b017c0
|
✨ feat(im):fetchFriends 加 pending 去重 + FRIEND_APPLICATION 重命名 RECEIVED + inflight 命名调整为 pending
|
2026-05-04 19:14:51 +08:00 |
YunaiV
|
7618d58a66
|
feat(im):好友模块 code review 多项修复(补 block/unblock 全链路 + UserInfo 菜单入口、silent 后主动入库、防 currentUserId 切账号失活、雪崩去重与命名/枚举清理)
|
2026-05-04 17:31:21 +08:00 |
YunaiV
|
ce2cdc112f
|
fix(im):仅普通消息进行声音通知
|
2026-05-04 10:29:41 +08:00 |
YunaiV
|
f86cd30af4
|
✨ feat(im): 增加好友申请的逻辑(v1)
|
2026-05-04 09:18:35 +08:00 |
YunaiV
|
ffb69063b9
|
✨ feat(im): 重构群通知相关,对齐 openim 的消息编号(继续优化代码)
|
2026-05-03 09:22:53 +08:00 |
YunaiV
|
43372c05ad
|
✨ feat(im): 重构群通知相关,对齐 openim 的消息编号
|
2026-05-03 02:00:43 +08:00 |
YunaiV
|
1dfab43b8a
|
✨ feat(im): 增加【消息引用】的功能
|
2026-05-01 18:03:05 +08:00 |
YunaiV
|
4b64153044
|
✨ feat(im): 完善 friend、group 相关的本地存储(疯狂优化)
|
2026-04-29 22:03:54 +08:00 |
YunaiV
|
e90f9e5237
|
✨ feat(im): 增加 friend、group 相关的本地存储
|
2026-04-29 15:50:49 +08:00 |
YunaiV
|
de39bc7fc1
|
✨ feat(im): 优化代码,移除 message 里的 name 存储,避免更新困难。(为 friend、group 独立存储做准备)
|
2026-04-28 23:32:40 +08:00 |
YunaiV
|
3ea04663f2
|
✨ feat(im): IM 5 个 store 补 HMR + 抽 atAll 常量 + 全面补齐 JSDoc
- 全部 5 个 store(conversation / friend / group / ui / websocket)加
acceptHMRUpdate;Pinia 单例的 actions 是 wrapper 闭包,Vite 推新模块时
不会自动替换闭包内的旧函数体,导致改 store 后看着热重载、跑的还是旧逻辑
- 抽 IM_AT_ALL_USER_ID(-1)+ IM_AT_ALL_NICKNAME('所有人')到
utils/constants.ts;conversationStore 删本地 AT_ALL_FLAG 改用共享常量;
MentionPicker 渲染虚拟项 / ChatGroupMember 类型注释也都引这两个常量
- groupStore.loadGroups 改成合并而非全量替换:用 groupMap 按 id 找已有项,
保留 loadGroupMembers 写过的 members / memberCount / muted(这三个字段
不在 ImGroupRespVO 里,全量替换会被冲掉)
- groupStore.loadGroupMembers 重写为分步注释(1. 缓存 / 2. 拉取 /
3. 回填 muted / 4.1 占位 / 4.2 直写);await 之后必须重新 getGroup
防 race(loadGroupMembers 与 loadGroups 并发时用入口快照会把真实 name
覆盖成 String(groupId))
- types/GroupMember 补 muted 字段,convertGroupMember 透传,
解决 vue-tsc TS2339 / TS2353
- 5 个 store 缺 JSDoc 的方法全部补齐:removePrivateConversation /
removeGroupConversation / getFriend / getActiveFriends / isFriend /
loadGroupInfo / upsertGroup / stopHeartbeat
- 全局"墓碑"措辞统一为"软删保留记录",types / friendStore / groupStore 三处
- groupStore 删冗余注释(与代码自描述重复的)若干处;变量 g/old 改 group/existing
|
2026-04-27 13:10:15 +08:00 |
YunaiV
|
8a7991261f
|
🐛 fix(im): 主动断开 WS 后不再自动重连,同步复位 isConnected
disconnect() 之前调用 socket.close() 是异步触发 onclose,回调里会
无条件走 reconnect,导致离开 IM 主壳后 3 秒又会在后台重新打开 WebSocket。
修复:
- close 前先解绑 onclose / onerror handler,主动关闭路径不再走自动重连
- onclose 已被解绑后没人帮我们设 isConnected=false,disconnect 内手动复位,
避免 socket=null 但 isConnected=true 的状态不一致
|
2026-04-26 23:08:23 +08:00 |
YunaiV
|
f929ebc184
|
✨ feat(im): 增加 conversationStore.ts 未来的优化 todo;
|
2026-04-26 16:13:58 +08:00 |
YunaiV
|
8c1f17f5a6
|
🐛 fix(im): 私聊已读消费端卡 maxReadId + 上报 messageId 与后端对齐
handlePrivateReceipt 收到对方 RECEIPT 时丢弃了后端编码在 DTO id 字段
的 maxReadId,applyReadReceipt 把会话里所有 selfSend 未撤回消息一刀切
标 READ;回执在路上时刚发的消息会被误标已读。
- applyReadReceipt 的 markPrivateRead 改为 privateReadMaxId,按
id <= maxReadId 卡边界,超过 maxReadId 的自发消息保留原状态;
- handlePrivateReceipt 透传 websocketMessage.id 作为 privateReadMaxId;
- apiReadPrivateMessages 增加 messageId 形参,与后端新接口对齐;
- websocketStore 私聊自动已读用刚到的消息 id;useMessageSender.readActive
把私聊 / 群聊的 maxMessageId 计算合并到调用前。
|
2026-04-26 09:46:09 +08:00 |
YunaiV
|
a35698fc07
|
🐛 fix(im): 群聊离线拉取看不到撤回提示,pull 路径接入 recallMessage
pullByType 之前对 RECALL 信号一律 skip、只靠原消息 status=RECALL 走 OR 兜底渲染。
当 pull 的 minId 卡在原消息处、回拉只返回信号时,本地缓存里的老消息没人翻成
RECALL,会一直停在原态——配合后端群聊 mapper 过滤掉 status=RECALL 的原消息,群聊
离线撤回完全不可见。
改成 pull / WS 走同一套 dispatch:
- pullByType 信号转 conversationStore.recallMessage(),跟 WS 路径一致
- recallMessage 把 parseRecallMessageId 收敛进内部,第 3 个参数从
messageId: number 改成 recallSignalContent: string,4 个调用点都缩成一行
- MessageItem.isRecall 只判 type=RECALL,去掉 status=RECALL OR 分支
(conversationStore 里跳未读 / 跳已读那两处对 status 的判断是业务逻辑保留)
|
2026-04-26 00:28:43 +08:00 |
YunaiV
|
66514fc597
|
♻️ refactor(im): conversationStore 存储改为 IndexedDB 按会话分桶 + 命名统一
- 持久化迁到 localforage(IndexedDB),meta 索引与单会话 messages 分 key 存,消除写放大
- saveConversations 支持 不传 / 单个 / 数组 三种粒度;签名改为 sync void(fire-and-forget)
- 修复 sortConversations 仅刷 meta 不刷 messages 导致离线消息重启丢失的 bug
- 方法重命名:saveToStorage→saveConversations、updateMessageState→ackMessage、applyRecall→recallMessage、refreshConversations→sortConversations、removeLocalMessage→removeMessage、_removeMessagesStorage→removeConversationMessages
- 删除 dead field Conversation.lastReadCount;TIP_TIME clientMessageId 改用 uuid
|
2026-04-25 22:52:00 +08:00 |
YunaiV
|
e30e30ea51
|
🐛 fix(im): 撤回信号错用 TIP_TEXT,应为 RECALL
|
2026-04-25 11:42:34 +08:00 |