YunaiV
8d06f87e0f
feat(wms):减法,去掉批次号等字段
2026-05-13 22:06:37 +08:00
YunaiV
fdbb98fe65
feat(wms):减法,去掉 area 表
2026-05-13 20:29:25 +08:00
YunaiV
c5948d405e
feat(wms):减法,去掉 detail 表,和 mes 更对齐
2026-05-13 18:42:51 +08:00
YunaiV
70aff05ef5
feat(wms):新增移库、盘库管理
2026-05-13 09:47:45 +08:00
YunaiV
b3b35e147b
feat(wms):新增出库管理
2026-05-13 08:57:41 +08:00
YunaiV
765c8ea94f
feat(wms):修复只能删除作废的入库单的问题
2026-05-13 00:42:29 +08:00
YunaiV
ac49ba5c6d
feat(wms):增加供应商 select 组件
2026-05-12 23:34:45 +08:00
YunaiV
3ef4e8424f
feat(wms):增加入库列表的评审
2026-05-12 23:30:06 +08:00
YunaiV
c865dfe488
feat(wms):进一步优化入库单的后端实现(对齐 mes)
2026-05-12 23:02:46 +08:00
YunaiV
18e5c97bf3
✨ feat(im): 将后端的 roomName 和 callId 融合,简化字段和逻辑(一致性更好、概念更简洁)
2026-05-12 20:29:08 +08:00
HmEJ
680c0e0e8b
feat: 使流程图居中显示
2026-05-12 16:50:13 +08:00
YunaiV
0be2674277
feat(wms):增加 inv 库存的新增、修改方法,并提供相关单测
2026-05-12 11:14:21 +08:00
YunaiV
f0cd639137
feat(wms):优化 inventory history
2026-05-11 15:11:39 +08:00
YunaiV
314293ced3
feat(wms):优化 inventory 的实现
2026-05-11 14:10:16 +08:00
YunaiV
32bbd912a2
feat(wms):增加 inventory history
2026-05-11 13:07:35 +08:00
YunaiV
32442830b0
feat(wms):增加 inventory
2026-05-11 09:45:24 +08:00
YunaiV
711d5abc0a
feat(wms):完善往来企业
2026-05-10 23:56:28 +08:00
YunaiV
4da16e95f5
feat(wms):完善商品信息、SKU 信息
2026-05-10 22:46:23 +08:00
YunaiV
d890781149
feat(wms):增加商品信息、SKU 信息
2026-05-10 21:33:42 +08:00
YunaiV
30e4fef7bb
feat(wms):增加商品分类、商品品牌。
2026-05-10 16:38:25 +08:00
YunaiV
1aad2f1648
feat(wms):迁移到 md 更整体
2026-05-10 09:02:51 +08:00
YunaiV
c3737d3b7a
feat(wms):增加 warehouse 功能
2026-05-10 01:22:38 +08:00
YunaiV
750f25410c
✨ feat(im): 基于 livekit 构建 im 通话(语音聊天、视频聊天、共享桌面)v0.1:推进中
2026-05-09 15:23:07 +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
46b06b0444
【新增】IM:群头像支持成员头像九宫格兜底
...
群头像为空时,取前 9 个成员头像在 Canvas 上拼九宫格 dataURL;空头像 / 加载失败的格子画跟 UserAvatar 同款色卡(首字 + charCode 哈希调色板)。
- 新增 GroupAvatar 组件包一层 UserAvatar;按容器 size × DPR 自适应画布像素,避免 retina 屏糊
- utils/group.ts 加 buildGroupAvatar 与 LRU 缓存 facade(上限 200);utils/image.ts 抽公共 loadImage;utils/user.ts 抽 getAvatarText / getAvatarBgColor 供 UserAvatar 与拼图共用
- GroupItem / GroupInfo / ConversationItem / ConversationPickerPanel 按会话类型分支换用 GroupAvatar
2026-05-08 18:28:02 +08:00
YunaiV
70e7a1c900
【新增】IM:群头像支持成员头像九宫格兜底
...
群头像为空时,取前 9 个成员头像在 Canvas 上拼九宫格 dataURL;空头像 / 加载失败的格子画跟 UserAvatar 同款色卡(首字 + charCode 哈希调色板)。
- 新增 GroupAvatar 组件包一层 UserAvatar;按容器 size × DPR 自适应画布像素,避免 retina 屏糊
- utils/group.ts 加 buildGroupAvatar 与 LRU 缓存 facade(上限 200);utils/image.ts 抽公共 loadImage;utils/user.ts 抽 getAvatarText / getAvatarBgColor 供 UserAvatar 与拼图共用
- GroupItem / GroupInfo / ConversationItem / ConversationPickerPanel 按会话类型分支换用 GroupAvatar
2026-05-08 18:27:53 +08:00
YunaiV
c5b082ca80
♻️ refactor(im): 业务策略数值从 ImCommonConstants 上移到 ImProperties(按 group / message 子模块分组),常量类仅保留 AT_USER_ID_ALL 协议契约值
...
♻️ refactor(im): 抽出 utils/config.ts 集中数值常量,按业务域统一前缀(GROUP_ / MESSAGE_ / FRIEND_ / CONVERSATION_ / FORWARD_),constants.ts 只留协议枚举与契约值
2026-05-08 17:42:13 +08:00
YunaiV
dfd5b39a17
feat(im): MessageForwardDialog 接入「创建聊天」分支 + 收尾打磨
...
- MessageForwardDialog 加 view: 'conversation' | 'contact' 切换:
- 模板按 view 切 ConversationPickerPanel / FriendPickerPanel;dialog header 用 slot 渲染「← 返回」
- handleSwitchToContact 切 view + 清留言(避免不可见输入框留言被静默发出)
- handleCreateGroupAndSend 复用 forwardToTarget(newConversation),merge / single 都按 mode 自动跑
- 成功 / 失败统一末尾退多选 + 关弹窗,避免源会话遗留多选态
- 顺手清掉 GroupMemberAddDialog / MessageForwardDialog 末尾多余空行
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 16:16:01 +08:00
YunaiV
312df4c73d
refactor(im): 抽象 IM 选择类弹窗为 PickerPanel 体系,对齐微信 PC
...
- 拆「业务壳 + 纯 PickerPanel」两层;13 个 dialog 统一 ref + open(opts) 接口
- 新增 FriendPickerPanel / ConversationPickerPanel / GroupMemberPickerPanel
- 抽 useFriendBuckets / useSelectedItems composable + buildDefaultGroupName / picker-dialog.scss mixin
- conversationStore 加 recentForwardConversationKeys 系列 action(持久化到 IDB)
- 三态语义固化:hide > locked > disabled
- 圆形勾选用微信绿;主按钮跟随项目主题色;最近转发横向头像 + 移除模式
- 删 GroupMemberSelector(由 GroupMemberPickerPanel 替代)/ FriendLite.deleted 死字段
- 配套:project_duibiao/im/dialog-picker-{contract,wechat-compare}.md
2026-05-08 14:06:48 +08:00
YunaiV
40ac2daca8
✨ feat(im):文本气泡 @ 高亮支持点击 + URL 自动识别成可点击链接
...
- @ 段:群消息按 atUserIds 反查群成员,候选 name 兼容历史字面量(真实昵称 / 好友备注 / 群自定义昵称),displayName 统一收敛到 nickname,让历史消息也能渲染成 @真实昵称;@ 段点击弹 UserInfoCard
- @所有人:注入 IM_AT_ALL_USER_ID 虚拟候选,对齐微信 PC 仅高亮配色不挂点击
- 同名歧义:同字面量对应多个 userId 时标记 ambiguous,parser 整段消费成普通文本,避免错绑用户
- URL:识别 http(s) / www. 起头链接,<a target="_blank"> 新标签打开;默认补 https://
- TipSegment 加 link 变体作为统一文本片段类型,TEXT 气泡与灰条 tip 共用 TipSegments 组件渲染
- MessageInput @ token 文本统一用真实昵称,不再掺好友备注 / 群自定义昵称
2026-05-08 01:23:09 +08:00
YunaiV
094ab44094
🎨 refactor(im): joinMentionSegments 用 flatMap 替代命令式 push
...
少一个可变 out + 命令式 forEach,意图更直观
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-07 23:59:00 +08:00
YunaiV
9eb221e8d2
✨ feat(im): 灰条 tip 文案的 mention 段支持点击弹 UserInfoCard
...
群广播 / 撤回 / 好友事件 tip 文案从纯字符串拆成 TipSegment[],mention
段携带 userId,渲染层挂点击 → uiStore.openUserInfoCardAtEvent。
- utils/message.ts:加 TipSegment 协议 + 零依赖 helper
- utils/user.ts、utils/conversation.ts:加 segments builder,string 版
改写为 segmentsToText 包装,避免 case 表分叉
- TipSegments.vue:按 activeConversation 推断 addSource,群里走
GROUP+群名、私聊走 SEARCH;nickname 不传备注避免 UserInfo 首屏闪
- MessageItem.vue / MessageHistory.vue:tip 块切 <TipSegments>
顺手补:utils/constants.ts 新增 SystemUserSexEnum,替换 IM 模块 sex
硬编码 1 / 2
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-07 23:46:50 +08:00
YunaiV
5b85a4c469
✨ feat(im): 浏览器标签 title 拼上未读数前缀
2026-05-07 22:17:03 +08:00
YunaiV
7fa1dbc55c
🐛 fix(im): 当前打开的会话在列表里不再展示 [草稿] 前缀
2026-05-07 21:55:45 +08:00
YunaiV
cc93b8a742
✨ feat(im): 初始化消息转发 v0.4:第四次评审(语音播放器资源释放打磨)
...
agent 三轮复审后的质量打磨,无功能变更。
- useVoicePlayer.stop:audio.removeAttribute('src') + audio.load() 替代 audio.src = '';不会触发空 src 加载的 error 事件,也能让浏览器立即释放底层 decoder buffer
- useVoicePlayer.play:同 key 再点的 stop() 改 stop(key),意图自解释(我想停的就是我自己)
- useVoicePlayer 移除未消费的 currentKey 暴露;调用方都走 isPlaying(key) 派生
- home/index.vue onUnmounted 追加 voicePlayer.stop():模块级单例 audio 不会随视图卸载自动停,补主壳兜底
2026-05-07 21:46:33 +08:00
YunaiV
0b07091e79
🐛 fix(im): 修复切会话 watch 仅监听 targetId 导致私聊与群聊 id 同号时不触发
...
home/index.vue 已读 watch、MessagePanel 滚动 / 侧栏 / 群资料预拉 watch 都只看 targetId,
私聊 1 切群 1 时不会触发,会把侧栏 / 新消息浮窗 / 滚动状态 / 已读上报漏掉,且不跑 ensureGroupData。
对齐多选 + 语音那两条 watch,统一改成监听 [type, targetId]。
2026-05-07 21:26:40 +08:00
YunaiV
0323566878
✨ feat(im): 初始化消息转发 v0.3:第三次评审(语音播放全局互斥)
...
新点的语音停掉旧的,对齐微信 PC 语义;一次只播一条,主面板 / 历史抽屉 / 合并详情共享同一播放态,避免多窗口同时出声。
- 新增 useVoicePlayer composable:模块级单例 currentTask + play / stop;ended / error / play().catch 全部 once: true 收尾,避免 listener 泄漏;play(key, url) / stop(key?) / isPlaying(key) 以 Symbol 当播放身份
- MessageBubble setup 里 Symbol('im-message-bubble-voice') 生成实例级 voiceKey;voicePlaying 改成派生 computed,移除本地 currentAudio
- MessageBubble 卸载兜底:调 voicePlayer.stop(voiceKey) 仅停自己;防止删除消息 / 历史抽屉切筛选导致气泡消失但 audio 仍在响;不会误伤别处仍可见的同 url 气泡
- MessagePanel 切会话 watch 追加 voicePlayer.stop()
- MessageHistory 关闭抽屉 watch 追加 voicePlayer.stop()
- MessageMergeDetailDialog handleClose 追加 voicePlayer.stop()
2026-05-07 21:26:12 +08:00
YunaiV
82d065c270
✨ feat(im): 初始化消息转发 v0.2:第二次优化部分代码(一些工具类等)
2026-05-07 20:34:09 +08:00
YunaiV
cf01143632
✨ feat(im): 初始化消息转发 v0.1:第一次评审
2026-05-07 19:47:27 +08:00
YunaiV
9bcdc92806
✨ feat(im): 初始化群名片 v0.2:第二次评审(需求各种进群的小问题)
2026-05-07 19:07:37 +08:00
YunaiV
f5936a6e7f
✨ feat(im): 初始化群名片 v0.2:第二次评审(需求各种进群的小问题)
2026-05-07 18:01:43 +08:00
YunaiV
d175fe86be
✨ feat(im): 初始化群名片 v0.2:第二次评审(需求各种进群的小问题)
2026-05-07 17:28:16 +08:00
YunaiV
ce66a507ef
✨ feat(im): 初始化群名片 v0.2:第二次评审(需求各种进群的小问题)
2026-05-07 17:25:03 +08:00
YunaiV
65d5aacac9
✨ feat(im): 初始化群名片 v0.1:第一次评审
2026-05-07 13:07:56 +08:00
YunaiV
808ad575fc
✨ feat(im): 初始化群申请 v0.5:第六把 review(性能 / 健壮性 / 简洁度收口)
...
后端
- 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
2026-05-07 08:13:27 +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
b2ba42049b
✨ feat(im): 初始化群申请 v0.3:第四把 review(优化界面,进一步对齐微信界面)【之前提交错了】
2026-05-06 23:57:54 +08:00
YunaiV
f746aebe08
✨ feat(im): 初始化群申请 v0.3:第四把 review(优化界面,进一步对齐微信界面)
2026-05-06 23:57:03 +08:00
YunaiV
0eca952c6a
✨ feat(im): 初始化表情包 v0.3:第四把 review(增加表情管理的界面)
2026-05-06 23:00:08 +08:00
YunaiV
a98e32554c
✨ feat(im): 初始化表情包 v0.2:第三把 review
2026-05-06 21:08:46 +08:00
YunaiV
2f513f7b8f
✨ feat(im): 初始化群申请 v0.2:第三把 review
2026-05-06 20:51:45 +08:00
YunaiV
8eebfd4744
✨ feat(im): 初始化表情包 v0.1:第二把 review
2026-05-06 20:50:55 +08:00
YunaiV
1ed5dc7e6a
✨ feat(im): 初始化表情包 v0.0:第一把 review
2026-05-06 19:42:19 +08:00
YunaiV
8fc5273a88
✨ feat(im): 初始化群申请 v0.1:第二把 review
2026-05-06 18:52:30 +08:00
DevDengChao
ee5ed1f97b
merge: upstream master into upgrade
...
Co-authored-by: OpenAI <support@openai.com>
2026-05-06 16:00:18 +08:00
YunaiV
3be0daf115
✨ feat(im): 初始化群申请 v0.0:第一把 review
2026-05-06 14:53:47 +08:00
YunaiV
4868d69ed8
✨ feat(im): 优化名片消息类型 v0.4:增加转发成功失败的提示
2026-05-06 12:18:31 +08:00
YunaiV
1ac0650984
♻️ refactor(im):注释对齐 + patchMessage 复用 applyServerMessageUpdate
...
- recomputeConversationLast / videoCoverUrl / showSendingLoading 三处 JSDoc 跟实现对齐:
原描述还停留在旧设计(lastSendTime 不重算 / 占位 coverUrl 用 blob / 「外层 loading 多余」),
这轮一并改成当前事实,避免后续维护被误导
- patchMessage 删手写 revoke + Object.assign,改调 applyServerMessageUpdate,
与 ackMessage / insertMessage(existingIndex) 共用一份服务端字段合并语义;
「值未变早返回」保留在 patchMessage 顶部
- 抽 BLOB_URL_PREFIX 常量替代散落在 utils/message.ts 与 useMediaUploader.ts 的 3 处 'blob:' 字面量
2026-05-06 10:38:43 +08:00
YunaiV
30d695d702
🐛 fix(im):codex 评审修复发送中状态边角
...
- recomputeConversationLast 空 messages 时一并清 lastSendTime,
避免刷新后被 drop 的媒体占位让空会话仍按旧时间排在列表前面
- 视频占位 coverUrl 不再赋 blob URL:<video poster> 期待图片资源,
传 video blob 在部分浏览器会退化成黑底,cover 等 probe 出真实 URL 后由 commit 阶段一起 patch
- useMediaUploader 暴露 requireMediaHandler typed accessor,
消除 video 链路 mediaTypeHandlers[VIDEO]! 非空断言
- MessageItem 把外层 loading 的 (!isUploading || isVoice) 抽成 showSendingLoading computed
2026-05-06 10:18:49 +08:00
YunaiV
459eaa5428
♻️ refactor(im): 优化消息存储逻辑,减少不必要的处理
...
改进消息存储时的处理逻辑,通过提前检查是否存在 _localFile 来优化性能,避免不必要的全量映射操作。
2026-05-06 08:50:13 +08:00
YunaiV
59aab8ecdc
✨ feat(im): 优化名片消息类型 v0.3:增加表情选择
2026-05-06 08:47:18 +08:00
YunaiV
b17f7a57e5
✨ feat(im): 优化发送中的能力 v0.2:简化各种 kind、复用各种逻辑
2026-05-06 08:46:33 +08:00
YunaiV
957a63f8f4
✨ feat(im): 优化名片消息类型 v0.2:优化转发弹窗的界面样式
2026-05-06 08:33:03 +08:00
YunaiV
c15d75ba91
✨ feat(im): 优化发送中的能力 v0.1:各种清理时的边界
2026-05-06 08:22:41 +08:00
YunaiV
3836467481
✨ feat(im): 优化名片消息类型 v0.1:补充缺失的名片展示
2026-05-06 08:21:52 +08:00
YunaiV
f3de29f95f
✨ feat(im): 增加名片消息类型
2026-05-06 08:00:36 +08:00
YunaiV
8f2eddea4a
✨ feat(im): 增加发送中的能力,针对图片、文件、视频等
2026-05-06 08:00:23 +08:00
YunaiV
f8cc9d14d9
✨ feat(im): 优化下禁言弹窗的样式
2026-05-05 22:51:26 +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
c653c2fa2b
✨ feat(im): 增强消息处理逻辑,支持好友通知与撤回消息
2026-05-05 22:15:48 +08:00
YunaiV
4e181564b8
feat(im): 清理一些 TODO 的修复
2026-05-05 22:04:45 +08:00
YunaiV
a9f54fdee1
feat(im): 重构普通消息类型,和 openim 的消息编号对齐
2026-05-05 21:56:05 +08:00
YunaiV
055d4bab27
✨ feat(im): 联动好友 / 群通知重构,抽 useMuteOverlay 统一禁言拦截与媒体上传公共骨架
2026-05-05 21:33:27 +08:00
YunaiV
e48316231c
feat(im): 增加好友申请的管理界面
2026-05-05 19:36:29 +08:00
YunaiV
390b66aee8
feat(im): 群禁言/封禁 UI 交互 + 群主解散群聊
...
一、群禁言交互
- MessageItem 右键菜单新增「禁言/解除禁言/移除」(权限校验)
- 新增 GroupMuteMemberDialog 禁言时长选择弹窗
- ConversationGroupSide 新增「全群禁言」开关
- MessageInput 新增禁言/封禁覆盖层,拦截所有发送入口
- canManageSender 目标角色未知时不展示管理菜单
- 全群禁言群主按 ownerUserId 直接豁免,不依赖成员列表
二、群封禁(GROUP_BANNED 1533)
- constants 激活 GROUP_BANNED 常量,扩展 isGroupNotification 范围
- groupStore 处理 1533 事件,实时更新 banned 字段
- MessageInput 覆盖层最高优先级判断 banned(红底)
- Group 类型、convertGroup 映射 banned 字段
三、禁言事件(1512-1515)
- constants 激活 GROUP_MEMBER_MUTED / CANCEL_MUTED / MUTED / CANCEL_MUTED
- groupStore 处理 1512-1515 事件,更新 muteEndTime / mutedAll
- user.ts 新增 4 条禁言 + 2 条封禁通知文案
- GroupNotificationPayload 扩展 mutedUserId / muteEndTime / banned
四、群主解散群聊
- ConversationGroupSide 底部按钮:群主显示「解散群聊」,非群主显示「退出群聊」
- 新增 handleDissolve 实现(二次确认 → dissolveGroup API → 清本地数据)
2026-05-05 18:41:28 +08:00
YunaiV
7b4c7028a0
feat(im):群禁言功能(阶段三管理后台 UI)
...
1. group API 新增 mutedAll 字段 + 3 个禁言接口(muteAll、muteMember、cancelMuteMember)
2. group member API 新增 muteEndTime 字段
3. 管理后台群列表新增「全群禁言」列(已禁言/未禁言标签)
4. 群详情抽屉新增「全群禁言」状态行 + 成员表新增「禁言状态」列(禁言中 + 到期时间)
2026-05-05 16:58:51 +08:00
YunaiV
4d006f8e73
feat(im):将"免打扰"字段从 muted 全量重命名为 silent(DO/VO/Service/Mapper/测试/SQL + 前端 types/store/组件/管理后台),为后续 mute 禁言功能腾出词族
2026-05-05 13:51:53 +08:00
preschooler
536e54062e
✨ feat(system): 优化用户选择 UserSelectV2 布局,多选支持、默认选中当前用户支持、禁选支持、默认部门支持,可替代项目所有位置,可移除原 UserSelectForm、UserSelect,避免一次性查询所有用户
2026-05-05 12:35:31 +08:00
YunaiV
dd75c702db
✨ feat(im):删好友「同时清空聊天记录」弹窗 + 顶部「对方还不是你的朋友」胶囊(点击弹 UserInfoCard)+ fetchFriends 不动 DISABLE 尊重用户选择
2026-05-05 00:57:58 +08:00
YunaiV
2a55748296
✨ feat(im):增加好友删除时,增加是否删除本地聊天的选项
2026-05-05 00:33:06 +08:00
YunaiV
1400bd80dd
🐛 fix(im):loadFriendRequest 按 id 大小决定插入位置,老 id 不入避免破坏倒序 + loadMore 重复 push
2026-05-04 23:06:12 +08:00
YunaiV
14e3f85cb0
♻️ refactor(im):用户申请列表,增加流式查询,避免一次性加载过多,或者历史无法被加载到。
2026-05-04 22:46:20 +08:00
YunaiV
9fc25b7109
♻️ refactor(im):friendStore 修 setMuted/removeFriend 一致性 + 新申请直推列表 + 清 dispatcher 防御兜底
2026-05-04 21:13:36 +08:00
YunaiV
45bac49ec0
♻️ refactor(im):friendStore 回调参数 f 改全名 friend / existing
2026-05-04 19:52:44 +08:00
YunaiV
b242b017c0
✨ feat(im):fetchFriends 加 pending 去重 + FRIEND_APPLICATION 重命名 RECEIVED + inflight 命名调整为 pending
2026-05-04 19:14:51 +08:00
YunaiV
cfd152addf
✨ feat(im):实现 1209 FRIEND_INFO_UPDATED 推送(system 发 AdminUserProfileUpdateMessage,IM Consumer 监听后批量推好友多端)
2026-05-04 18:24:08 +08:00
YunaiV
7618d58a66
feat(im):好友模块 code review 多项修复(补 block/unblock 全链路 + UserInfo 菜单入口、silent 后主动入库、防 currentUserId 切账号失活、雪崩去重与命名/枚举清理)
2026-05-04 17:31:21 +08:00
YunaiV
5c2a185ff9
【IM 优化】通讯录顶部搜索栏改为 h-14,与消息 Tab 顶部对齐,避免切换抖动
2026-05-04 16:47:33 +08:00
YunaiV
42566d1e86
✨ feat(im): 优化好友申请逻辑,增加自我添加校验与异常处理
...
更新好友申请功能,使用 computed 包裹当前用户 ID,避免在 keep-alive 实例中持有旧 ID。增加自我添加好友的校验逻辑,防止用户添加自己为好友。同时,增强自动通过好友申请的异常处理,确保在事务提交后能正确处理失败情况。
2026-05-04 16:41:55 +08:00
YunaiV
7141e431e2
✨ feat(im): 前端增加「黑名单」的操作
2026-05-04 16:24:12 +08:00
YunaiV
1b51926b19
refactor(im): 移除 TIP_TIME 消息类型,时间分隔条改为渲染时按 prevMessage.sendTime 计算
...
顺带修复 Bug-Y(删除最后一条消息后孤立时间分隔条)
2026-05-04 16:05:23 +08:00
YunaiV
63c4dd1096
fix(im):修复对话置顶被关闭时,默认还选择了第一个置顶对话,导致又被打开。
2026-05-04 12:00:03 +08:00
YunaiV
b6ca1187b1
✨ feat(im): 增加好友申请的逻辑(v1.3:修复各种边界情况,包括静默添加好友)
2026-05-04 11:08:03 +08:00
YunaiV
89ee5d51ea
✨ feat(im): 增加好友申请的逻辑(v1.2:增加相关枚举、字典,减少硬编码)
2026-05-04 10:44:09 +08:00
YunaiV
5b9acb4813
fix(im):从群聊,点击好友聊天时,关闭之前的群聊面板
2026-05-04 10:31:02 +08:00
YunaiV
0e979a9f67
fix(im):私聊头像,也可以点击,方便好友管理。
2026-05-04 10:30:30 +08:00
YunaiV
ce2cdc112f
fix(im):仅普通消息进行声音通知
2026-05-04 10:29:41 +08:00
YunaiV
1469d8bb3d
✨ feat(im): 增加好友申请的逻辑(v1.1:增加各种 code review 注释)
2026-05-04 09:47:25 +08:00
YunaiV
f86cd30af4
✨ feat(im): 增加好友申请的逻辑(v1)
2026-05-04 09:18:35 +08:00
芋道源码
5e937d797d
!851 feat:增加说明文案
...
Merge pull request !851 from steven/feat-自定义海报代码补充开发
2026-05-03 10:59:47 +00:00
芋道源码
5e6b6bdd8e
回退 'Pull Request !870 : fix: 菜单名称过长时没有正确显示省略号'
2026-05-03 10:55:35 +00:00
YunaiV
b7a13a0000
♻️ refactor(service): 优化请求拦截器中的 token 设置逻辑,简化白名单判断
2026-05-03 18:48:12 +08:00
YunaiV
6d5705b655
fix(bpm):修正流程实例审批弹窗网关分支重算的并发与提交问题
...
- 提交时不再用节点表单值覆盖 data.variables;与预览阶段使用同一份合并变量
- onChange 加 useDebounceFn(300ms) + 请求序号去重,handleAudit 提交前 await 最新一轮重算
- 切换任务时重置请求序号与 pending 重算
- 改用 form-create 官方 formData() 取节点表单当前值
- 双 nextTick 改为 until 等 fApi 就绪,1s 兜底超时
2026-05-03 18:48:12 +08:00
YunaiV
8571a27a15
fix: 【framework】关闭 TagsView 标签后 keep-alive 缓存未收缩,导致 DOM/JS heap 不回收
...
delView/delAllViews 误用 delCachedView,关闭非当前标签时会去删 currentRoute
对应的缓存,把要关的 name 留在 cachedViews 里,keep-alive include 不收缩,
旧组件实例无法 unmount。
回退到基于剩余 visitedViews 重建 cachedViews 的实现(对应 5718c7881 之前的写法);
delCachedView 自身保留 issue #180 的修复,仍供 refreshPage 使用。
2026-05-03 18:48:12 +08:00
YunaiV
cdcd200c7d
【修复】form-create 单图上传规则 disabled 字段标题与默认值错配
2026-05-03 18:48:12 +08:00
YunaiV
6232330c81
【修复】IoT 场景联动:事件触发器比较值改普通文本输入,允许留空(事件发生即匹配)
2026-05-03 18:48:12 +08:00
YunaiV
418f0c4f52
🐛 fix(system):修复租户 get-by-website 接口不支持端口的问题
...
🐛 fix(mes):修复常见缺陷的「检测项类型」错用独立字典的问题
「常见缺陷」与「检测项设置」的「检测项类型」语义一致,应共用同一份字典;DefectForm 与列表页统一改为 MES_INDICATOR_TYPE,并清理未使用的 MES_DEFECT_TYPE 常量。
2026-05-03 18:48:12 +08:00
芋道源码
2e65691737
!870 fix: 菜单名称过长时没有正确显示省略号
...
Merge pull request !870 from 李家辉/fix-text-overflow
2026-05-03 10:38:57 +00:00
芋道源码
aafe5f12bc
!866 fix: 修复请求拦截器bug
...
Merge pull request !866 from funcong/fc-fix-bug
2026-05-03 10:37:47 +00:00
YunaiV
bf79e07d5c
♻️ refactor(im): 清理代码中的 TODO 注释并优化逻辑
2026-05-03 13:27:31 +08:00
YunaiV
7c129c18c4
✨ feat(im): 增加群消息的置顶
2026-05-03 12:53:24 +08:00
YunaiV
01e0e8e37b
✨ feat(im): 增加群消息的置顶
2026-05-03 12:15:39 +08:00
芋道源码
583b409fad
!864 条件节点添加包含和不包含操作符
...
Merge pull request !864 from Lesan/bugfix/bpm-202602
2026-05-03 03:01:48 +00:00
YunaiV
ffb69063b9
✨ feat(im): 重构群通知相关,对齐 openim 的消息编号(继续优化代码)
2026-05-03 09:22:53 +08:00
芋道源码
a698cb1635
!867 feat(iot): 前端新增 Database 数据目的配置表单
...
Merge pull request !867 from puhui999/master
2026-05-03 01:19:11 +00:00
YunaiV
43372c05ad
✨ feat(im): 重构群通知相关,对齐 openim 的消息编号
2026-05-03 02:00:43 +08:00
芋道源码
7fd0a24ca5
!875 fix(bpm):修复流程网关分支问题
...
Merge pull request !875 from 郭某人/master
2026-05-02 16:01:00 +00:00
YunaiV
fa27c27831
✨ feat(im): 增加群角色(管理员)
2026-05-02 14:31:42 +08:00
芋道源码
f9c0cace70
!871 fix: 修复响应拦截器 code=0 的逻辑错误
...
Merge pull request !871 from zhulh/fix/code-0-bug
2026-05-02 03:21:51 +00:00
YunaiV
3146f64edc
✨ feat(im): 未读计数改用 isNormalMessage,对齐后端 normal 语义
2026-05-02 09:06:01 +08:00
YunaiV
fbd8615398
✨ feat(im): 消息右键菜单优化 + 修复图片场景滚不到底
...
- MessageItem:「回复」→「引用」并加图标;撤回 / 删除互斥(自己消息 2 分钟内显示撤回,超出 / 对方消息显示删除),均加分割线 + 红色样式对齐微信;MENU_KEYS 抽 const 防 typo;引用块从气泡上方移到下方,selfSend 时竖线镜像到右侧
- MessagePanel:scrollToBottom 改 async + waitMediaSettled 等图片 / 视频元数据加载;用 expectedScrollTop drift 替代 distanceFromBottom,修复「图片加载完底部上移、误判用户已滚走」导致到不了底
- ReplyPreview:删等价的 filePayload / voicePayload alias,直接复用 parsedPayload
- uiStore:ContextMenuItem 加 icon? 字段,支持菜单项前置图标
2026-05-01 23:06:14 +08:00
YunaiV
52fdf0bcab
✨ feat(im): 消息右键菜单优化 + 修复图片场景滚不到底
...
- MessageItem:「回复」→「引用」并加图标;撤回 / 删除互斥(自己消息 2 分钟内显示撤回,超出 / 对方消息显示删除),均加分割线 + 红色样式对齐微信;MENU_KEYS 抽 const 防 typo;引用块从气泡上方移到下方,selfSend 时竖线镜像到右侧
- MessagePanel:scrollToBottom 改 async + waitMediaSettled 等图片 / 视频元数据加载;用 expectedScrollTop drift 替代 distanceFromBottom,修复「图片加载完底部上移、误判用户已滚走」导致到不了底
- ReplyPreview:删等价的 filePayload / voicePayload alias,直接复用 parsedPayload
- uiStore:ContextMenuItem 加 icon? 字段,支持菜单项前置图标
2026-05-01 23:04:56 +08:00
YunaiV
43666dc56c
✨ feat(im): 优化【消息引用】的功能,增加文件、图片的展示调整
2026-05-01 19:05:57 +08:00
YunaiV
ef901b5381
✨ feat(im): 优化【消息引用】的功能,来自第二波 code review,解决安全性问题
2026-05-01 18:20:04 +08:00
YunaiV
cfeee7bbb7
✨ feat(im): 优化【消息引用】的功能,来自第一波 code review
2026-05-01 18:09:02 +08:00
YunaiV
1dfab43b8a
✨ feat(im): 增加【消息引用】的功能
2026-05-01 18:03:05 +08:00
YunaiV
744229a02e
✨ feat(im): 优化语音输入的交互。
2026-05-01 09:59:27 +08:00
YunaiV
63c711f9e2
✨ feat(im): 增加视频消息
2026-05-01 09:47:01 +08:00
YunaiV
82022b86de
✨ feat(im): 实现 im 的首页统计
2026-05-01 09:25:39 +08:00
YunaiV
f5656c8a2f
✨ feat(im): 同步输入框状态以支持粘贴功能
2026-05-01 08:50:51 +08:00
YunaiV
31dc1b1198
✨ feat(im): 用户的输入,改成 userselectv2,增强体验。
2026-05-01 08:49:14 +08:00
YunaiV
3cc7ac7f8b
Merge branch 'master' of https://gitee.com/yudaocode/yudao-ui-admin-vue3 into im
...
# Conflicts:
# pnpm-lock.yaml
# src/router/modules/remaining.ts
# src/utils/dict.ts
2026-05-01 08:22:54 +08:00
YunaiV
7ed6fa5579
✨ feat(im): 增加群管理的完善
2026-05-01 08:19:13 +08:00
YunaiV
8564788b11
✨ feat(im): 对齐微信的图标展示
2026-05-01 08:17:24 +08:00
YunaiV
92b1466597
✨ feat(im): 增加群管理的 code review
2026-05-01 07:52:31 +08:00
YunaiV
238862b572
✨ feat(im): 增加发送草稿,切换对话的时候,不丢失。对齐微信
2026-05-01 07:52:18 +08:00
YunaiV
be654bce50
✨ feat(im): 增加私聊消息的管理
2026-05-01 07:46:19 +08:00
YunaiV
d64a695673
✨ feat(im): 增加群聊消息的管理
2026-05-01 07:08:05 +08:00
YunaiV
dfbae06afa
✨ feat(im): 优化输入框的样式
2026-05-01 06:59:14 +08:00
YunaiV
384a0c134a
✨ feat(im): 完成敏感词的管理
2026-04-30 22:25:25 +08:00
YunaiV
9f1fc9ef78
reviewed
2026-04-30 21:38:17 +08:00
YunaiV
fd1ba30bdb
✨ feat(im): 优化好友列表的管理
2026-04-30 21:09:03 +08:00
YunaiV
01fff53aaf
✨ feat(im): 增加 im 的管理界面
2026-04-30 19:04:31 +08:00
YunaiV
4b4c4fab11
✨ feat(im): 优化群聊的功能界面
2026-04-30 16:59:56 +08:00
YunaiV
368b385267
✨ feat(im): 增加群邀请的功能
2026-04-30 15:47:32 +08:00
YunaiV
0ab8b292f2
✨ feat(im): 增加 pinyin 功能
2026-04-30 15:22:35 +08:00
YunaiV
d19bdd42d5
✨ feat(im): 优化添加好友界面
2026-04-30 14:53:41 +08:00
YunaiV
0c7d1f0df6
✨ feat(im): 新增通讯录界面
2026-04-30 14:07:03 +08:00
YunaiV
a762dfff84
✨ feat(im): 优化整体包结构,将 friend、group 通用组件抽过去。
2026-04-30 10:11:20 +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
f0fc144e8a
✨ feat(im): 调整代码结构,优化 side 样式
2026-04-28 20:14:24 +08:00
YunaiV
431a0bfb93
✨ feat(im): 调整代码结构,优化 side 样式
2026-04-28 20:13:01 +08:00
YunaiV
ba34e4adc0
✨ feat(im): 优化整体 message 包结构
2026-04-28 09:30:12 +08:00
YunaiV
29a03ef03d
✨ feat(im): 优化整体 message 包结构
2026-04-28 09:29:40 +08:00
YunaiV
122b1ba748
✨ feat(im): 优化 message 的导入
2026-04-28 08:48:38 +08:00
YunaiV
56b0630847
✨ feat(im): 优化 icon 的导入
2026-04-28 08:15:29 +08:00
YunaiV
6ead932813
✨ feat(im): 优化 icon 的导入
2026-04-28 08:15:10 +08:00
YunaiV
9fc10b304c
✨ feat(im): 增加 ChatPanel.vue 组件
2026-04-28 01:15:04 +08:00
YunaiV
4c8898b6f5
🐛 fix(im): 上传 URL 取错字段,粘贴图片 / 文件 / 语音消息加载失败
...
axios 配置里 request.upload 直接返回完整 axios response(不是 res.data,
跟 get/post/put 不一致),原代码 (await updateFile(form)) as unknown as string
把整个 {data, status, headers, ...} 对象当成 URL 塞进消息 JSON,接收端
<el-image src> 拿到的是序列化串自然加载失败。
uploadAndSendImage / uploadAndSendFile / onVoiceSend 三处统一改成 .data 取值:
((await updateFile(form)) as { data?: string })?.data
跟 mall PictureSelectUpload / bpm SignDialog 等其它业务代码取 URL 的方式一致。
2026-04-28 01:14:24 +08:00
YunaiV
9c5b11e551
✨ feat(im): 支持历史消息的加载
2026-04-28 01:08:45 +08:00
YunaiV
e9be6ef8b3
✨ feat(im): 增加群消息的回执开关,通过向下箭头
2026-04-27 23:56:50 +08:00
YunaiV
29695b649a
✨ feat(im): 增加群消息的回执开关,通过向下箭头
2026-04-27 23:54:41 +08:00
YunaiV
8847cdb79f
✨ feat(im): 新增 MessageReadStatus.vue
2026-04-27 22:36:47 +08:00
YunaiV
bfa267120a
♻️ refactor(im): MessageItem 头像顶右 + MentionPicker/MessageInput 命名清理
...
【MessageItem.vue】
- 头像合一:双 v-if 头像(左/右)收成单一 <UserAvatar>,DOM 顺序固定为
[头像, 气泡],selfSend 靠外层 flex-row-reverse 翻视觉 → 头像顶右、气泡在
头像左侧。早先双 v-if + row-reverse 让自己消息时气泡顶右、头像反而被
挤在 bubble 左边,跟微信观感不对齐
- 5 处脚本 TODO 注释补齐:groupMembersForReadStatus / handleContextMenu /
handleRecall / handleDelete,解释 WHY 而不是 WHAT
- formatTipTime 局部变量按"不缩写"展开:d → messageDate / n → value /
hm → hourMinute / (a,b) → (left,right) / weeks → weekNames
- senderAvatar / groupMembersForReadStatus 回调参数 m → member、g → group
【MessageInput.vue】
- groupMembers producer 局部变量 g → group、(m) => → (member) =>
【MentionPicker.vue】
- memberItems 过滤回调 (m) => → (member) =>
2026-04-27 21:48:34 +08:00
YunaiV
8fd21da555
🐛 fix(im): TIP_TEXT 系统提示不再显示空白
...
群解散 / 退群 / 踢人 等系统提示后端发的是裸字符串,之前按 TextMessage JSON
解析 → 主聊天窗显示空行、会话列表摘要变空。
- message.ts:新增 resolveTipText helper,兼容裸字符串 + {"content":"..."}
- MessageItem / conversationStore.resolveLastContent 把 TIP_TEXT 从 TEXT
分支拆出来,统一走 resolveTipText(TEXT 仍按 JSON 解析,没有裸字符串可能)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 19:59:56 +08:00
YunaiV
9e8d04249c
🐛 fix(im): TIP_TEXT 系统提示不再显示空白
...
群解散 / 退群 / 踢人 等系统提示后端发的是裸字符串,之前按 TextMessage JSON
解析 → 主聊天窗显示空行、会话列表摘要变空。
- message.ts:新增 resolveTipText helper,兼容裸字符串 + {"content":"..."}
- MessageItem / conversationStore.resolveLastContent 把 TIP_TEXT 从 TEXT
分支拆出来,统一走 resolveTipText(TEXT 仍按 JSON 解析,没有裸字符串可能)
2026-04-27 19:56:54 +08:00
YunaiV
cb5d30e327
✨ feat(im): 新增 MessageItem.vue
2026-04-27 19:11:31 +08:00
YunaiV
ccc9aca21c
✨ feat(im): MessageInput 工具栏挪到底部 + 4 图标统一 Iconify + 聊天历史挪到右上角
...
对齐微信 PC:输入区在上、操作图标在下;会话级操作(如聊天历史)统一放 header 右上角
【MessageInput.vue】
- 模板顺序对调:editor 在上 / 工具栏在下(justify-between:左 4 图标 gap-1 / 右"发 送"按钮)
- editor min-height 80 → 100、padding 8/12 → 10/14,输入区视觉权重接近微信
- 4 个图标统一走 Iconify ant-design outlined 同源,避免 ep / antd 混用视觉割裂:
- 表情:Sunny → ant-design:smile-outlined(Element Plus 没有 smile,必须走 Iconify)
- 图片:Picture → ant-design:picture-outlined
- 文件夹:Paperclip → ant-design:folder-outlined(附件 → 文件夹更贴近微信观感)
- 语音:Microphone → ant-design:audio-outlined
- 整条 @element-plus/icons-vue import 删除,全部改 <span class="message-input__tool inline-flex …">
+ <Icon icon="…" :size="18" /> 的统一外壳;scoped CSS 的 :deep(svg) 继续命中,padding / hover
样式不动;DOM 实测 4 图标全部 30×30、top:761、间距 34px 完全对齐
- EmojiPicker class:bottom-9 left-3 → bottom-full left-3 mb-2,picker 从工具栏顶部向上弹出
(旧值在新布局下会浮在工具栏内部,盖住图标)
- 删 defineEmits<{ openHistory }>():聊天历史挪到 ChatPanel header 后已没有调用方
【ChatPanel.vue】
- header 右上角新增"聊天历史"图标(Tickets),点击直接 historyVisible = true 弹"历史消息"抽屉
(对齐微信 PC:右上角集中放会话级操作;并列在原"聊天信息 / 群聊信息"图标左侧)
- <MessageInput :key="…" @open-history="…"> 上的 listener 摘掉,emit 链路完整解耦
2026-04-27 15:46:13 +08:00
YunaiV
fc82ed3d7e
♻️ refactor(input): 优化粘贴文件处理逻辑,简化代码结构
2026-04-27 14:30:38 +08:00
YunaiV
cba5c15604
✨ feat(im): MessageInput / MentionPicker / ChatPanel 三连修——粘贴文件、切群清空、命名规范
...
【ChatPanel.vue】
- 加 messageInputKey computed(type-targetId)+ MessageInput :key 绑它,
切会话强制 unmount + remount editor / mention range / 草稿全归零,
避免 A 群打了一半的字 / @ token 漏到 B 群被发出去
(早先用 inline template literal 做 :key,Vue SFC 编译没把表达式接到
vnode.key 上,hmr / 完整 reload 都看到 key=null;改 computed 后正常)
【MessageInput.vue】
- onPaste 加 clipboardData.items 扫一轮:image/* → uploadAndSendImage,
其它 file → uploadAndSendFile,纯文本兜底走 nativeExec('insertText');
截图 / 拖入图片 / 拖入文件不再被默默吞掉
- 抽 uploadAndSendImage / uploadAndSendFile 两个共用函数,
onImagePicked / onFilePicked 改成薄包装走它们,避免上传逻辑双份
- 删 nativeExec 里的 // eslint-disable-next-line @typescript-eslint/no-deprecated:
项目当前 @typescript-eslint v7 没有这条规则,加了会让 lint 报"规则不存在",
反而把 lint 拖红;改用单纯 JSDoc 解释为什么留着 execCommand
- 重命名 mentionPos → mentionPosition(prop / ref 一致),按"变量不缩写"
- 7 个方法补 JSDoc:onSelectionChange / insertText / onPaste / onInput /
onKeydown / onImagePicked / onFilePicked / onVoiceSend;复杂的
collectFromEditor 和 handleSend 加分步 1./2./3. 内联注释
- data-empty 改用属性"存在 / 缺失"模拟(template 里 data-empty="",JS 里
raw 为空就 set ''、否则 delete),CSS 选择器同步改 [data-empty],
比 [data-empty='true'] 直观
【MentionPicker.vue】
- prop pos → position(不缩写);ref / 内部解构 / 默认值都跟着改
- <el-icon><UserFilled /></el-icon> → <Icon icon="ep:user-filled">:
用全局 Icon 组件走 Iconify,少一个 EP 图标 import
- scrollToTop / scrollToActive 局部变量 wrap → scrollWrap、
itemH → itemHeight、activeTop → activeOffsetTop;
v-for 与 handleSelect 的 (m) → (member)
2026-04-27 13:57:18 +08:00
YunaiV
678c2d6834
✨ feat(im): MessageInput 切 contenteditable + MentionPicker 对齐微信,修一堆 @ 浮层 bug
...
【MessageInput.vue】
- textarea → contenteditable div:拿真·光标 rect 给浮层定位(textarea 拿不到),@ 成员
以 <span data-id contenteditable=false> token 节点存在,删 token 即删 atUserIds
- collectFromEditor:DOM walk 还原 plain text + atUserIds(text / br / span[data-id] /
div / 其他元素 五种节点分支),过滤零宽空格
- handleSend:从 DOM 收集而非 ref<string>,atUserIds 走 Set 去重;分步注释
- placeholder 用 [data-empty]::before + JS 维护属性"存在 / 缺失"模拟,避开浏览器删空
后留 <br> 让 :empty 不命中
- @ 浮层位置:bottom 锚定(picker 下沿贴 @ 上方 8px),无论候选多寡下沿固定,不再
随 picker 高度变化漂移;上方放不下才翻成 top 锚定到 @ 下方
- @ 浮层规则:regex 改成 `(?:^|\s)@([^\s@]*)$`,避免 email-like "test@example.com"
误触发;锚定在 @ 字符位置而非 caret,否则用户每多敲一字浮层右移
- click outside 关浮层:document mousedown 监听,target 不在 editor / picker 内即关
- Enter 兜底:mention 浮层无候选时 fall through 到正常发送,避免按 Enter 没反应
- token 首位 ZWSP:token 是 editor 第一个节点时 contenteditable=false 边缘会让光标
无法挪到 token 前,补一个零宽空格当锚点;DOM walk 滤掉
- Shift+Enter 强制 br(execCommand insertLineBreak),DOM walk 不必处理多换行容器
- onPaste 用 execCommand('insertText') 剥光所有 HTML,不留外部样式 / 脚本
- onEditorScroll 同步浮层位置,多行 + 滚动条场景下 picker 跟随 caret
- selection 保存:document selectionchange 监听 + 仅 editor 内时记录,emoji 面板偷
焦点后能回到原位
【MentionPicker.vue】
- 视觉对齐微信 PC:顶部"所有人"虚拟项(蓝方块 + UserFilled 图标)+ "群成员"分组
header + 底部三角指针;rounded-md + soft shadow
- "全体成员" → "所有人";userId=-1 / 文案常量化到 utils/constants.ts
(IM_AT_ALL_USER_ID / IM_AT_ALL_NICKNAME),三个文件共用,不再散落
- !fixed + !h-75 / max-height:用 UnoCSS important 变体压过 Element Plus 的
.el-scrollbar { position:relative; height:100% } 默认 CSS——之前 picker 落到父
容器坐标系导致 y=1326 飞出视口外,肉眼看不到的根因
- pos prop 从 {x, y} → {x, top?, bottom?},配合 MessageInput 的 bottom 锚定
- allItem / memberItems 拆成两个 computed,showMembers 做扁平合并供键盘导航;
群成员上限 100 去掉,浮层本就支持滚动
- 5 个内部函数 / watch 全部补 JSDoc(showMembers / visible 两个 watch、scrollToTop /
scrollToActive / handleSelect)
2026-04-27 13:21:27 +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
a0ed0d800c
✨ feat(im): 群聊免打扰接入后端,完善免打扰失败回滚 + ContextMenu 微调
...
- groupStore.setMuted 改 async,调 /im/group-member/update 推后端
- GroupMember.muted 在类型层补齐;convertGroupMember 保留 muted;
loadGroupMembers 拉完成员后用当前用户那条 member.muted 回填 group.muted
与 conversation.muted,避免冷启动后服务端已免打扰的群在会话列表里仍显示为
未免打扰
- ConversationItem.handleMuted 失败回滚:catch 后 ElMessage.error 并反向
setMuted 把 conversationStore(已 saveConversations 落盘)拽回正确状态
- ContextMenu 分割线改用 h-[1px] + bg(UnoCSS 不带 border-style preflight,
border-t 在空内容 div 上不显形),文案 text-center → text-left 贴近微信
- groupStore.setMuted 改 async 后,ConversationItem 里两路 setMuted 调用
都用 void 显式 fire-and-forget,风格统一
2026-04-27 09:29:49 +08:00
YunaiV
45a530e8c7
✨ feat(im): 新增 MentionPicker.vue、MessageInput.vue、VoiceRecorder.vue 三个组件,vibe~
2026-04-27 09:20:10 +08:00
YunaiV
6add0b0600
✨ feat(im): 群聊免打扰接入后端,完善免打扰失败回滚 + ContextMenu 微调
...
- groupStore.setMuted 改 async,调 /im/group-member/update 推后端
- GroupMember.muted 在类型层补齐;convertGroupMember 保留 muted;
loadGroupMembers 拉完成员后用当前用户那条 member.muted 回填 group.muted
与 conversation.muted,避免冷启动后服务端已免打扰的群在会话列表里仍显示为
未免打扰
- ConversationItem.handleMuted 失败回滚:catch 后 ElMessage.error 并反向
setMuted 把 conversationStore(已 saveConversations 落盘)拽回正确状态
- ContextMenu 分割线改用 h-[1px] + bg(UnoCSS 不带 border-style preflight,
border-t 在空内容 div 上不显形),文案 text-center → text-left 贴近微信
- groupStore.setMuted 改 async 后,ConversationItem 里两路 setMuted 调用
都用 void 显式 fire-and-forget,风格统一
2026-04-27 09:03:18 +08:00
YunaiV
7f84c428a5
✨ feat(im): 优化 ConversationItem.vue,对齐微信的时间展示。
2026-04-27 08:51:35 +08:00
YunaiV
e85f8edcaa
✨ feat(im): 优化 ConversationItem.vue,对齐微信交互
2026-04-27 08:42:39 +08:00
YunaiV
115e0482db
✨ feat(im): 优化 ConversationItem.vue 增加相关评审
2026-04-27 08:22:14 +08:00
YunaiV
a1a9053aaa
✨ feat(im): 优化 MessagePage.vue 页面,对齐微信交互
2026-04-27 00:51:31 +08:00
YunaiV
1a0c11f685
✨ feat(im): 优化 MessagePage.vue 页面,对齐微信交互
2026-04-27 00:51:15 +08:00
YunaiV
e1b52be8ea
✨ feat(im): 新增 MessagePage.vue 页面 + 部分 review
2026-04-27 00:01:43 +08:00
YunaiV
8790d6b128
✨ feat(im): 优化 ToolBar.vue 组件
...
- tabs / goTab / goProfile 从 path 切到路由 name:path 后期容易随前缀调整变动,name 更稳定
- isActive 由 path 前缀比对简化为 route.name 全等比对(IM 三 Tab 无嵌套子路由,足够)
- 群聊图标 svg-icon:peoples → ant-design:team:三人组合跟 ep:user(单人)视觉区分更明显
- 给 goTab / goProfile 补 JSDoc;清理 5 个 TODO @AI
2026-04-26 23:45:27 +08:00
YunaiV
3a77001b42
🐛 fix(im): 修复主壳初始化期间消息漏拉 / 缓冲回放失效
...
三处时序竞态修复:
- loading=true 提前到 connect 前,避免 WS 早于 pullOnce 推进 maxId 漏拉断线积压
- loading=false 提到 flushBuffer 前,让回放走正常 insertMessage 而非被 push 回 buffer
- 加 bootstrapped 守卫,避免 isConnected watcher 在 friend/group 加载完前抢跑
附带:主壳文件名 Index.vue → index.vue 对齐其他模块小写惯例;清理 5 个 TODO @AI。
2026-04-26 23:32:55 +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
1e02a40ec4
✨ feat(im): 添加 IM 聊天模块的全屏容器组件,并添加相关 review 注释
2026-04-26 22:02:02 +08:00
YunaiV
9570f25cdc
✨ feat(im): 优化 ToolBar.vue 组件
2026-04-26 21:51:09 +08:00
YunaiV
d37af6d959
✨ feat(im): 优化 PagedScroller.vue 组件
2026-04-26 21:46:13 +08:00
YunaiV
802a10cf85
✨ feat(im): 优化 ResizableAside.vue 组件
2026-04-26 21:35:27 +08:00
YunaiV
a973406b2a
✨ feat(im): 优化 ContextMenu.vue 组件
2026-04-26 20:19:19 +08:00
YunaiV
43771b0f47
✨ feat(im): 优化 EmojiPicker.vue 组件
2026-04-26 19:49:44 +08:00
YunaiV
20c6631e7a
✨ feat(im): 新增 UserInfoCard.vue
2026-04-26 19:08:02 +08:00
YunaiV
9a4e79e4ef
🐛 fix(im): conversation.messages 入 IDB 前用 toRaw 解 Proxy,否则 structuredClone 抛 DataCloneError 静默丢消息
2026-04-26 17:57:50 +08:00
YunaiV
f1d44c8267
✨ feat(im): 优化 UserAvatar.vue 通用用户头像组件
2026-04-26 17:52:32 +08:00
YunaiV
969d8237ce
✨ feat(im): 增加 UserAvatar.vue 通用用户头像组件
2026-04-26 17:32:47 +08:00
YunaiV
f929ebc184
✨ feat(im): 增加 conversationStore.ts 未来的优化 todo;
2026-04-26 16:13:58 +08:00
YunaiV
2c1ff59286
✨ feat(im): 初始化 useMessageSender.ts
2026-04-26 15:56:24 +08:00
YunaiV
e573462cb7
✨ feat(im): 增加 useMessagePuller 用于首次消息的拉取
2026-04-26 10:38:14 +08:00