比较提交

..

没有共同的提交。fefd8d191b1b2826da9e4c6c47c1837e28b966de 和 ebf6a389cf6b518c4d55cd1c73232b11591751d3 的历史完全不同。

共有 5 个文件被更改,包括 2 次插入337 次删除

查看文件

@ -49,14 +49,7 @@ export class ImClient {
try { try {
const frame = JSON.parse(event.data as string) const frame = JSON.parse(event.data as string)
if (frame.type === 'MESSAGE') { if (frame.type === 'MESSAGE') {
const message = this.normalizeMessage(frame.payload as ImMessage) this.emit('message', this.normalizeMessage(frame.payload as ImMessage))
if (message.status === 'READ') {
this.emit('read', message)
}
if (message.revoked || message.status === 'REVOKED' || message.msgType === 'REVOKED') {
this.emit('revoke', { msgId: message.id, operatorId: message.fromId ?? message.fromUserId })
}
this.emit('message', message)
} else if (frame.type === 'REVOKE') { } else if (frame.type === 'REVOKE') {
this.emit('revoke', frame.payload as { msgId: string; operatorId: string }) this.emit('revoke', frame.payload as { msgId: string; operatorId: string })
} }

查看文件

@ -3,10 +3,7 @@ import { http } from '../core/http'
import type { import type {
ChatType, ChatType,
ConversationView, ConversationView,
FriendRequest,
HistoryQuery, HistoryQuery,
GroupJoinRequest,
ImGroup,
ImMessage, ImMessage,
PageResult, PageResult,
UserProfile, UserProfile,
@ -48,54 +45,6 @@ export function fetchGroupHistory(groupId: string, query: HistoryQuery = {}): Pr
) )
} }
export async function locateHistoryPage(
toId: string,
messageId: string,
pageSize = 20,
maxPages = 20,
): Promise<ImMessage[] | null> {
for (let page = 0; page < Math.max(maxPages, 1); page += 1) {
const result = await fetchHistory(toId, { page, size: pageSize })
if (result.content.some((item) => item.id === messageId)) {
return result.content
}
if (result.content.length < pageSize) return null
}
return null
}
export async function locateGroupHistoryPage(
groupId: string,
messageId: string,
pageSize = 20,
maxPages = 20,
): Promise<ImMessage[] | null> {
for (let page = 0; page < Math.max(maxPages, 1); page += 1) {
const result = await fetchGroupHistory(groupId, { page, size: pageSize })
if (result.content.some((item) => item.id === messageId)) {
return result.content
}
if (result.content.length < pageSize) return null
}
return null
}
export function editMessage(messageId: string, content: string): Promise<ImMessage> {
return http.put<ImMessage>(
`/api/im/messages/${encodeURIComponent(messageId)}`,
{ content },
appQuery(),
)
}
export function revokeMessage(messageId: string): Promise<ImMessage> {
return http.post<ImMessage>(
`/api/im/messages/${encodeURIComponent(messageId)}/revoke`,
undefined,
appQuery(),
)
}
export function markRead(targetId: string, chatType: ChatType = 'SINGLE'): Promise<void> { export function markRead(targetId: string, chatType: ChatType = 'SINGLE'): Promise<void> {
return http.put<void>( return http.put<void>(
`/api/im/conversations/${encodeURIComponent(targetId)}/read`, `/api/im/conversations/${encodeURIComponent(targetId)}/read`,
@ -151,99 +100,3 @@ export function updateProfile(
appQuery({ nickname, avatar, gender }), appQuery({ nickname, avatar, gender }),
) )
} }
export function listFriends(): Promise<string[]> {
return http.get<string[]>('/api/im/friends', appQuery())
}
export function listGroups(): Promise<ImGroup[]> {
return http.get<ImGroup[]>('/api/im/groups', appQuery())
}
export function searchUsers(keyword: string, size = 20): Promise<UserProfile[]> {
return http.get<UserProfile[]>('/api/im/admin/users/search', appQuery({ keyword, size }))
}
export function searchGroups(keyword: string, size = 20): Promise<ImGroup[]> {
return http.get<ImGroup[]>('/api/im/admin/groups/search', appQuery({ keyword, size }))
}
export function searchMessages(
keyword: string | null = null,
chatType: ChatType | null = null,
msgType: string | null = null,
startTime: string | number | Date | null = null,
endTime: string | number | Date | null = null,
page = 0,
size = 20,
): Promise<PageResult<ImMessage>> {
return http.get<PageResult<ImMessage>>(
'/api/im/admin/messages/search',
appQuery({ keyword, chatType, msgType, startTime, endTime, page, size }),
)
}
export function getGroupInfo(groupId: string): Promise<ImGroup> {
return http.get<ImGroup>(`/api/im/groups/${encodeURIComponent(groupId)}`, appQuery())
}
export function listGroupMembers(groupId: string): Promise<UserProfile[]> {
return http.get<UserProfile[]>(`/api/im/groups/${encodeURIComponent(groupId)}/members`, appQuery())
}
export function searchGroupMembers(groupId: string, keyword: string, size = 20): Promise<UserProfile[]> {
return http.get<UserProfile[]>(`/api/im/groups/${encodeURIComponent(groupId)}/members/search`, appQuery({ keyword, size }))
}
export function sendFriendRequest(toUserId: string, remark?: string): Promise<FriendRequest> {
return http.post<FriendRequest>(
'/api/im/friend-requests',
undefined,
appQuery({
toUserId,
...(remark ? { remark } : {}),
}),
)
}
export function listFriendRequests(direction: 'incoming' | 'outgoing' = 'incoming'): Promise<FriendRequest[]> {
return http.get<FriendRequest[]>('/api/im/friend-requests', appQuery({ direction }))
}
export function acceptFriendRequest(requestId: string): Promise<FriendRequest> {
return http.post<FriendRequest>(`/api/im/friend-requests/${encodeURIComponent(requestId)}/accept`, undefined, appQuery())
}
export function rejectFriendRequest(requestId: string): Promise<FriendRequest> {
return http.post<FriendRequest>(`/api/im/friend-requests/${encodeURIComponent(requestId)}/reject`, undefined, appQuery())
}
export function sendGroupJoinRequest(groupId: string, remark?: string): Promise<GroupJoinRequest> {
return http.post<GroupJoinRequest>(
`/api/im/groups/${encodeURIComponent(groupId)}/join-requests`,
undefined,
appQuery({
...(remark ? { remark } : {}),
}),
)
}
export function listGroupJoinRequests(groupId: string): Promise<GroupJoinRequest[]> {
return http.get<GroupJoinRequest[]>(`/api/im/groups/${encodeURIComponent(groupId)}/join-requests`, appQuery())
}
export function acceptGroupJoinRequest(groupId: string, requestId: string): Promise<GroupJoinRequest> {
return http.post<GroupJoinRequest>(
`/api/im/groups/${encodeURIComponent(groupId)}/join-requests/${encodeURIComponent(requestId)}/accept`,
undefined,
appQuery(),
)
}
export function rejectGroupJoinRequest(groupId: string, requestId: string): Promise<GroupJoinRequest> {
return http.post<GroupJoinRequest>(
`/api/im/groups/${encodeURIComponent(groupId)}/join-requests/${encodeURIComponent(requestId)}/reject`,
undefined,
appQuery(),
)
}

查看文件

@ -2,25 +2,10 @@ import { ref, shallowRef, onUnmounted } from 'vue'
import { ImClient } from './ImClient' import { ImClient } from './ImClient'
import { import {
deleteConversation, deleteConversation,
acceptFriendRequest,
acceptGroupJoinRequest,
getGroupInfo,
fetchGroupHistory, fetchGroupHistory,
fetchHistory, fetchHistory,
editMessage,
locateGroupHistoryPage,
locateHistoryPage,
revokeMessage,
listFriendRequests,
listFriends,
listGroupJoinRequests,
listGroups,
listConversations, listConversations,
markRead, markRead,
rejectFriendRequest,
rejectGroupJoinRequest,
sendFriendRequest,
sendGroupJoinRequest,
setConversationMuted, setConversationMuted,
setConversationPinned, setConversationPinned,
setDraft, setDraft,
@ -52,20 +37,6 @@ export function useIm() {
messages.value = [...messages.value, message] messages.value = [...messages.value, message]
} }
function markMessageRevoked(msgId: string) {
const index = messages.value.findIndex((item) => item.id === msgId)
if (index < 0) return
const next = [...messages.value]
next[index] = {
...next[index],
status: 'REVOKED',
msgType: 'REVOKED',
revoked: true,
content: '',
}
messages.value = next
}
async function refreshConversations() { async function refreshConversations() {
const items = await listConversations() const items = await listConversations()
conversations.value = [...items].sort((a, b) => { conversations.value = [...items].sort((a, b) => {
@ -74,14 +45,6 @@ export function useIm() {
}) })
} }
function markConversationRead(targetId: string, chatType: ChatType = 'SINGLE') {
conversations.value = conversations.value.map((item) =>
item.targetId === targetId && item.chatType === chatType
? { ...item, unreadCount: 0 }
: item,
)
}
async function loadHistory(toId: string, query: HistoryQuery = {}): Promise<PageResult<ImMessage>> { async function loadHistory(toId: string, query: HistoryQuery = {}): Promise<PageResult<ImMessage>> {
return fetchHistory(toId, query) return fetchHistory(toId, query)
} }
@ -90,14 +53,6 @@ export function useIm() {
return fetchGroupHistory(groupId, query) return fetchGroupHistory(groupId, query)
} }
function jumpToMessagePage(toId: string, messageId: string, pageSize = 20, maxPages = 20) {
return locateHistoryPage(toId, messageId, pageSize, maxPages)
}
function jumpToGroupMessagePage(groupId: string, messageId: string, pageSize = 20, maxPages = 20) {
return locateGroupHistoryPage(groupId, messageId, pageSize, maxPages)
}
function connect() { function connect() {
const im = new ImClient() const im = new ImClient()
im.on('connected', () => { im.on('connected', () => {
@ -109,14 +64,6 @@ export function useIm() {
upsertMessage(msg) upsertMessage(msg)
void refreshConversations().catch(() => {}) void refreshConversations().catch(() => {})
}) })
im.on('read', (msg) => {
upsertMessage(msg)
void refreshConversations().catch(() => {})
})
im.on('revoke', ({ msgId }) => {
markMessageRevoked(msgId)
void refreshConversations().catch(() => {})
})
im.on('error', (e) => { error.value = e }) im.on('error', (e) => { error.value = e })
im.connect() im.connect()
client.value = im client.value = im
@ -131,19 +78,7 @@ export function useIm() {
} }
function revoke(msgId: string) { function revoke(msgId: string) {
return revokeMessage(msgId).then((message) => { client.value?.revoke(msgId)
upsertMessage(message)
void refreshConversations().catch(() => {})
return message
})
}
function edit(msgId: string, content: string) {
return editMessage(msgId, content).then((message) => {
upsertMessage(message)
void refreshConversations().catch(() => {})
return message
})
} }
function disconnect() { function disconnect() {
@ -153,8 +88,6 @@ export function useIm() {
} }
function setConversationRead(targetId: string, chatType: ChatType = 'SINGLE') { function setConversationRead(targetId: string, chatType: ChatType = 'SINGLE') {
markConversationRead(targetId, chatType)
void refreshConversations().catch(() => {})
return markRead(targetId, chatType) return markRead(targetId, chatType)
} }
@ -174,57 +107,12 @@ export function useIm() {
return deleteConversation(targetId, chatType) return deleteConversation(targetId, chatType)
} }
function getFriends() {
return listFriends()
}
function getGroups() {
return listGroups()
}
function getGroup(groupId: string) {
return getGroupInfo(groupId)
}
function sendFriend(toUserId: string, remark?: string) {
return sendFriendRequest(toUserId, remark)
}
function loadFriendRequests(direction: 'incoming' | 'outgoing' = 'incoming') {
return listFriendRequests(direction)
}
function approveFriendRequest(requestId: string) {
return acceptFriendRequest(requestId)
}
function declineFriendRequest(requestId: string) {
return rejectFriendRequest(requestId)
}
function sendGroupJoin(groupId: string, remark?: string) {
return sendGroupJoinRequest(groupId, remark)
}
function loadGroupJoinRequests(groupId: string) {
return listGroupJoinRequests(groupId)
}
function approveGroupJoinRequest(groupId: string, requestId: string) {
return acceptGroupJoinRequest(groupId, requestId)
}
function declineGroupJoinRequest(groupId: string, requestId: string) {
return rejectGroupJoinRequest(groupId, requestId)
}
onUnmounted(disconnect) onUnmounted(disconnect)
return { return {
connect, connect,
send, send,
revoke, revoke,
edit,
disconnect, disconnect,
messages, messages,
conversations, conversations,
@ -233,23 +121,10 @@ export function useIm() {
refreshConversations, refreshConversations,
loadHistory, loadHistory,
loadGroupHistory, loadGroupHistory,
jumpToMessagePage,
jumpToGroupMessagePage,
setConversationRead, setConversationRead,
setConversationPinnedState, setConversationPinnedState,
setConversationMutedState, setConversationMutedState,
setConversationDraft, setConversationDraft,
removeConversation, removeConversation,
getFriends,
getGroups,
getGroup,
sendFriend,
loadFriendRequests,
approveFriendRequest,
declineFriendRequest,
sendGroupJoin,
loadGroupJoinRequests,
approveGroupJoinRequest,
declineGroupJoinRequest,
} }
} }

查看文件

@ -2,30 +2,12 @@ export { init, setToken, setUserId, getToken, getUserId, getConfig } from './cor
export { http } from './core/http' export { http } from './core/http'
export { ImClient } from './im/ImClient' export { ImClient } from './im/ImClient'
export { export {
acceptFriendRequest,
acceptGroupJoinRequest,
deleteConversation, deleteConversation,
getGroupInfo,
fetchGroupHistory, fetchGroupHistory,
fetchHistory, fetchHistory,
editMessage,
locateGroupHistoryPage,
locateHistoryPage,
revokeMessage,
listFriendRequests,
listFriends,
listGroupJoinRequests,
listGroups,
listConversations, listConversations,
markRead, markRead,
getProfile, getProfile,
searchGroups,
searchMessages,
searchUsers,
rejectFriendRequest,
rejectGroupJoinRequest,
sendFriendRequest,
sendGroupJoinRequest,
setConversationMuted, setConversationMuted,
setConversationPinned, setConversationPinned,
setDraft, setDraft,
@ -40,9 +22,6 @@ export type {
ImMessage, ImMessage,
ConversationView, ConversationView,
HistoryQuery, HistoryQuery,
ImGroup,
FriendRequest,
GroupJoinRequest,
PageResult, PageResult,
UserProfile, UserProfile,
SendMessageParams, SendMessageParams,

查看文件

@ -84,40 +84,6 @@ export interface UserProfile {
createdAt?: string | number | null createdAt?: string | number | null
} }
export interface ImGroup {
id: string
appId?: string
name: string
groupType?: string
creatorId: string
memberIds: string
adminIds: string
announcement?: string | null
createdAt?: string | number | null
}
export interface FriendRequest {
id: string
appId?: string
fromUserId: string
toUserId: string
remark?: string | null
status: 'PENDING' | 'ACCEPTED' | 'REJECTED'
createdAt: string | number
reviewedAt?: string | number | null
}
export interface GroupJoinRequest {
id: string
appId?: string
groupId: string
requesterId: string
remark?: string | null
status: 'PENDING' | 'ACCEPTED' | 'REJECTED'
createdAt: string | number
reviewedAt?: string | number | null
}
export interface SendMessageParams { export interface SendMessageParams {
messageId?: string messageId?: string
toId: string toId: string
@ -130,7 +96,6 @@ export interface SendMessageParams {
export interface ImEventMap { export interface ImEventMap {
message: (msg: ImMessage) => void message: (msg: ImMessage) => void
read: (msg: ImMessage) => void
revoke: (data: { msgId: string; operatorId: string }) => void revoke: (data: { msgId: string; operatorId: string }) => void
connected: () => void connected: () => void
disconnected: (code: number, reason: string) => void disconnected: (code: number, reason: string) => void