比较提交
没有共同的提交。fefd8d191b1b2826da9e4c6c47c1837e28b966de 和 ebf6a389cf6b518c4d55cd1c73232b11591751d3 的历史完全不同。
fefd8d191b
...
ebf6a389cf
@ -49,14 +49,7 @@ export class ImClient {
|
||||
try {
|
||||
const frame = JSON.parse(event.data as string)
|
||||
if (frame.type === 'MESSAGE') {
|
||||
const 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)
|
||||
this.emit('message', this.normalizeMessage(frame.payload as ImMessage))
|
||||
} else if (frame.type === 'REVOKE') {
|
||||
this.emit('revoke', frame.payload as { msgId: string; operatorId: string })
|
||||
}
|
||||
|
||||
147
src/im/api.ts
147
src/im/api.ts
@ -3,10 +3,7 @@ import { http } from '../core/http'
|
||||
import type {
|
||||
ChatType,
|
||||
ConversationView,
|
||||
FriendRequest,
|
||||
HistoryQuery,
|
||||
GroupJoinRequest,
|
||||
ImGroup,
|
||||
ImMessage,
|
||||
PageResult,
|
||||
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> {
|
||||
return http.put<void>(
|
||||
`/api/im/conversations/${encodeURIComponent(targetId)}/read`,
|
||||
@ -151,99 +100,3 @@ export function updateProfile(
|
||||
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(),
|
||||
)
|
||||
}
|
||||
|
||||
127
src/im/useIm.ts
127
src/im/useIm.ts
@ -2,25 +2,10 @@ import { ref, shallowRef, onUnmounted } from 'vue'
|
||||
import { ImClient } from './ImClient'
|
||||
import {
|
||||
deleteConversation,
|
||||
acceptFriendRequest,
|
||||
acceptGroupJoinRequest,
|
||||
getGroupInfo,
|
||||
fetchGroupHistory,
|
||||
fetchHistory,
|
||||
editMessage,
|
||||
locateGroupHistoryPage,
|
||||
locateHistoryPage,
|
||||
revokeMessage,
|
||||
listFriendRequests,
|
||||
listFriends,
|
||||
listGroupJoinRequests,
|
||||
listGroups,
|
||||
listConversations,
|
||||
markRead,
|
||||
rejectFriendRequest,
|
||||
rejectGroupJoinRequest,
|
||||
sendFriendRequest,
|
||||
sendGroupJoinRequest,
|
||||
setConversationMuted,
|
||||
setConversationPinned,
|
||||
setDraft,
|
||||
@ -52,20 +37,6 @@ export function useIm() {
|
||||
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() {
|
||||
const items = await listConversations()
|
||||
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>> {
|
||||
return fetchHistory(toId, query)
|
||||
}
|
||||
@ -90,14 +53,6 @@ export function useIm() {
|
||||
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() {
|
||||
const im = new ImClient()
|
||||
im.on('connected', () => {
|
||||
@ -109,14 +64,6 @@ export function useIm() {
|
||||
upsertMessage(msg)
|
||||
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.connect()
|
||||
client.value = im
|
||||
@ -131,19 +78,7 @@ export function useIm() {
|
||||
}
|
||||
|
||||
function revoke(msgId: string) {
|
||||
return revokeMessage(msgId).then((message) => {
|
||||
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
|
||||
})
|
||||
client.value?.revoke(msgId)
|
||||
}
|
||||
|
||||
function disconnect() {
|
||||
@ -153,8 +88,6 @@ export function useIm() {
|
||||
}
|
||||
|
||||
function setConversationRead(targetId: string, chatType: ChatType = 'SINGLE') {
|
||||
markConversationRead(targetId, chatType)
|
||||
void refreshConversations().catch(() => {})
|
||||
return markRead(targetId, chatType)
|
||||
}
|
||||
|
||||
@ -174,57 +107,12 @@ export function useIm() {
|
||||
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)
|
||||
|
||||
return {
|
||||
connect,
|
||||
send,
|
||||
revoke,
|
||||
edit,
|
||||
disconnect,
|
||||
messages,
|
||||
conversations,
|
||||
@ -233,23 +121,10 @@ export function useIm() {
|
||||
refreshConversations,
|
||||
loadHistory,
|
||||
loadGroupHistory,
|
||||
jumpToMessagePage,
|
||||
jumpToGroupMessagePage,
|
||||
setConversationRead,
|
||||
setConversationPinnedState,
|
||||
setConversationMutedState,
|
||||
setConversationDraft,
|
||||
removeConversation,
|
||||
getFriends,
|
||||
getGroups,
|
||||
getGroup,
|
||||
sendFriend,
|
||||
loadFriendRequests,
|
||||
approveFriendRequest,
|
||||
declineFriendRequest,
|
||||
sendGroupJoin,
|
||||
loadGroupJoinRequests,
|
||||
approveGroupJoinRequest,
|
||||
declineGroupJoinRequest,
|
||||
}
|
||||
}
|
||||
|
||||
21
src/index.ts
21
src/index.ts
@ -2,30 +2,12 @@ export { init, setToken, setUserId, getToken, getUserId, getConfig } from './cor
|
||||
export { http } from './core/http'
|
||||
export { ImClient } from './im/ImClient'
|
||||
export {
|
||||
acceptFriendRequest,
|
||||
acceptGroupJoinRequest,
|
||||
deleteConversation,
|
||||
getGroupInfo,
|
||||
fetchGroupHistory,
|
||||
fetchHistory,
|
||||
editMessage,
|
||||
locateGroupHistoryPage,
|
||||
locateHistoryPage,
|
||||
revokeMessage,
|
||||
listFriendRequests,
|
||||
listFriends,
|
||||
listGroupJoinRequests,
|
||||
listGroups,
|
||||
listConversations,
|
||||
markRead,
|
||||
getProfile,
|
||||
searchGroups,
|
||||
searchMessages,
|
||||
searchUsers,
|
||||
rejectFriendRequest,
|
||||
rejectGroupJoinRequest,
|
||||
sendFriendRequest,
|
||||
sendGroupJoinRequest,
|
||||
setConversationMuted,
|
||||
setConversationPinned,
|
||||
setDraft,
|
||||
@ -40,9 +22,6 @@ export type {
|
||||
ImMessage,
|
||||
ConversationView,
|
||||
HistoryQuery,
|
||||
ImGroup,
|
||||
FriendRequest,
|
||||
GroupJoinRequest,
|
||||
PageResult,
|
||||
UserProfile,
|
||||
SendMessageParams,
|
||||
|
||||
@ -84,40 +84,6 @@ export interface UserProfile {
|
||||
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 {
|
||||
messageId?: string
|
||||
toId: string
|
||||
@ -130,7 +96,6 @@ export interface SendMessageParams {
|
||||
|
||||
export interface ImEventMap {
|
||||
message: (msg: ImMessage) => void
|
||||
read: (msg: ImMessage) => void
|
||||
revoke: (data: { msgId: string; operatorId: string }) => void
|
||||
connected: () => void
|
||||
disconnected: (code: number, reason: string) => void
|
||||
|
||||
正在加载...
在新工单中引用
屏蔽一个用户