feat(Talk): 系统消息居中展示,订阅 talk:conversation 实时同步
talkSocket 新增 talk:conversation 事件;Talk.vue 收到该事件后:解散或本人被移出则直接移除该会话(在会话中同时清空聊天区并提示),其余变更(改名/公告/角色/移出他人)重新拉取会话列表。 消息区区分 MsgType=3 系统消息,居中灰字展示(不带头像与名字);api/talk 补齐 MsgType.System。
This commit is contained in:
1 parent
04535d2dc0
commit
dd1ece0a7f
3 files changed
+43
-4
No files matched your search
+3
-3
@@ -18,8 +18,8 @@ export const ASSET_DOWNLOAD_BASE = 'https://api.gvsds.com/API/Asset/Download'
|
||||
/** 会话类型:0=单聊 1=群聊 */
|
||||
export const TalkConversationType = { Single: 0, Group: 1 } as const
|
||||
|
||||
/** 消息类型:0=文本 1=图片 2=文件(后端契约未显式约定,按此实现,见汇总说明) */
|
||||
export const TalkMsgType = { Text: 0, Image: 1, File: 2 } as const
|
||||
/** 消息类型:0=文本 1=图片 2=文件 3=系统(后端 MsgType 对齐 manager.py) */
|
||||
export const TalkMsgType = { Text: 0, Image: 1, File: 2, System: 3 } as const
|
||||
|
||||
/** 群成员角色:0=成员 1=群主 2=管理员(上限由 Entry.GroupAdminLimit 下发) */
|
||||
export const TalkMemberRole = { Member: 0, Owner: 1, Admin: 2 } as const
|
||||
@@ -118,7 +118,7 @@ export interface TalkMessage {
|
||||
ConversationUUID: string
|
||||
SenderUUID: string
|
||||
SenderName: string
|
||||
/** 0=文本 1=图片 2=文件 */
|
||||
/** 0=文本 1=图片 2=文件 3=系统 */
|
||||
MsgType: number
|
||||
Content: string
|
||||
Attachment: TalkAttachment | null
|
||||
|
||||
@@ -19,6 +19,7 @@ export type TalkServerEvent =
|
||||
| 'talk:message'
|
||||
| 'talk:read'
|
||||
| 'talk:typing'
|
||||
| 'talk:conversation'
|
||||
| 'talk:pong'
|
||||
| 'talk:error'
|
||||
|
||||
@@ -31,6 +32,7 @@ const SERVER_EVENTS: TalkServerEvent[] = [
|
||||
'talk:message',
|
||||
'talk:read',
|
||||
'talk:typing',
|
||||
'talk:conversation',
|
||||
'talk:pong',
|
||||
'talk:error',
|
||||
]
|
||||
|
||||
+38
-1
@@ -848,6 +848,7 @@ function SetupSocketHandlers(): void {
|
||||
subscribeTalkEvent('talk:ready', OnSocketReady),
|
||||
subscribeTalkEvent('talk:message', OnSocketMessage),
|
||||
subscribeTalkEvent('talk:typing', OnSocketTyping),
|
||||
subscribeTalkEvent('talk:conversation', OnSocketConversation),
|
||||
subscribeTalkEvent('talk:error', OnSocketError),
|
||||
]
|
||||
}
|
||||
@@ -870,6 +871,28 @@ function OnSocketMessage(payload: unknown): void {
|
||||
PatchConversationOnMessage(message)
|
||||
}
|
||||
|
||||
/** talk:conversation:群主/管理员操作后的会话级同步(改名 / 公告 / 角色 / 移出 / 转让 / 解散) */
|
||||
function OnSocketConversation(payload: unknown): void {
|
||||
const data = payload as
|
||||
| { ConversationUUID?: string; Action?: string; Removed?: string[] }
|
||||
| undefined
|
||||
if (!data?.ConversationUUID) return
|
||||
const conversationUUID = data.ConversationUUID
|
||||
const removedMe = (data.Removed || []).includes(MyUUID.value)
|
||||
// 解散或本人被移出:直接从列表移除(在会话中则同时清空聊天区)
|
||||
if (data.Action === 'dissolved' || removedMe) {
|
||||
if (ActiveUUID.value === conversationUUID) {
|
||||
ActiveUUID.value = ''
|
||||
Messages.value = []
|
||||
}
|
||||
Conversations.value = Conversations.value.filter((c) => c.ConversationUUID !== conversationUUID)
|
||||
ElMessage.warning(removedMe ? '你已被移出该群聊' : '该群聊已解散')
|
||||
return
|
||||
}
|
||||
// 其余变更(改名 / 公告 / 角色 / 追加成员等):重新拉取会话,保持成员与权限最新
|
||||
void LoadConversations()
|
||||
}
|
||||
|
||||
/** talk:typing:仅当前会话且非自己时展示 */
|
||||
function OnSocketTyping(payload: unknown): void {
|
||||
const data = payload as { ConversationUUID?: string; UserUUID?: string } | undefined
|
||||
@@ -1067,7 +1090,11 @@ onBeforeUnmount(() => {
|
||||
<div v-if="NeedTimeDivider(index)" class="talk-time-divider">
|
||||
{{ FormatMessageTime(message.CreateTime) }}
|
||||
</div>
|
||||
<div class="talk-msg-row" :class="{ self: IsSelf(message) }">
|
||||
<!-- 系统消息(群主/管理员操作留痕):居中灰字,不带头像 -->
|
||||
<div v-if="message.MsgType === TalkMsgType.System" class="talk-sysmsg">
|
||||
{{ message.Content }}
|
||||
</div>
|
||||
<div v-else class="talk-msg-row" :class="{ self: IsSelf(message) }">
|
||||
<TalkAvatar :user-uuid="message.SenderUUID" :name="message.SenderName" size="small" />
|
||||
<div class="talk-msg-body">
|
||||
<div v-if="IsGroupChat && !IsSelf(message)" class="talk-msg-sender">
|
||||
@@ -1512,6 +1539,16 @@ onBeforeUnmount(() => {
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
/* ---------- 系统消息(群主/管理员操作留痕) ---------- */
|
||||
.talk-sysmsg {
|
||||
margin: 8px 0;
|
||||
text-align: center;
|
||||
font-size: 12px;
|
||||
line-height: 1.6;
|
||||
color: var(--el-text-color-secondary);
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.talk-msg-row {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
|
||||
Reference in new issue
Block a user