✨ feat(im):fetchFriends 加 pending 去重 + FRIEND_APPLICATION 重命名 RECEIVED + inflight 命名调整为 pending
parent
cfd152addf
commit
b242b017c0
|
|
@ -25,14 +25,16 @@ import { getCurrentUserId, imStorage, setQuietly, StorageKeys } from '../../util
|
||||||
import { getFriendDisplayName } from '../../utils/user'
|
import { getFriendDisplayName } from '../../utils/user'
|
||||||
import type { Friend, FriendRequest } from '../types'
|
import type { Friend, FriendRequest } from '../types'
|
||||||
|
|
||||||
|
/** 当前正在进行的好友列表拉取;多 dispatcher 同时触发时复用同一 Promise,避免雪崩重拉 */
|
||||||
|
let pendingFetchFriends: Promise<void> | null = null
|
||||||
/** 当前正在进行的好友申请列表拉取;多端连续多条申请到达时复用同一 Promise,避免雪崩重拉 */
|
/** 当前正在进行的好友申请列表拉取;多端连续多条申请到达时复用同一 Promise,避免雪崩重拉 */
|
||||||
let inflightFetchRequests: Promise<void> | null = null
|
let pendingFetchRequests: Promise<void> | null = null
|
||||||
|
|
||||||
/** 好友通知 payload(对齐后端 BaseFriendNotification + 子类裁减后的字段) */
|
/** 好友通知 payload(对齐后端 BaseFriendNotification + 子类裁减后的字段) */
|
||||||
export interface FriendNotificationPayload {
|
export interface FriendNotificationPayload {
|
||||||
operatorUserId: number
|
operatorUserId: number
|
||||||
friendUserId: number
|
friendUserId: number
|
||||||
// FRIEND_APPLICATION 系列:申请记录的核心字段(避免 payload 携带完整 DO)
|
// FRIEND_REQUEST_* 系列:申请记录的核心字段(避免 payload 携带完整 DO)
|
||||||
requestId?: number
|
requestId?: number
|
||||||
applyContent?: string
|
applyContent?: string
|
||||||
handleContent?: string
|
handleContent?: string
|
||||||
|
|
@ -128,24 +130,34 @@ export const useFriendStore = defineStore('imFriendStore', {
|
||||||
|
|
||||||
// ==================== 远端拉取 ====================
|
// ==================== 远端拉取 ====================
|
||||||
|
|
||||||
/** 从后端拉取并覆盖本地列表;同步刷新对应私聊会话的展示名 / 头像 + 落 IDB */
|
/** 从后端拉取并覆盖本地列表;同步刷新对应私聊会话的展示名 / 头像 + 落 IDB;pending 期间复用同一 Promise */
|
||||||
async fetchFriends(force = false) {
|
async fetchFriends(force = false) {
|
||||||
if (this.loaded && !force) {
|
if (this.loaded && !force) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const list = await apiGetMyFriendList()
|
if (pendingFetchFriends) {
|
||||||
this.friends = (list || []).map(convertFriend)
|
return pendingFetchFriends
|
||||||
this.loaded = true
|
|
||||||
// 同步 conversationStore 私聊会话的展示名 / 头像 / 免打扰
|
|
||||||
const conversationStore = useConversationStore()
|
|
||||||
for (const friend of this.friends) {
|
|
||||||
conversationStore.updateConversation(ImConversationType.PRIVATE, friend.friendUserId, {
|
|
||||||
name: getFriendDisplayName(friend),
|
|
||||||
avatar: friend.avatar,
|
|
||||||
muted: friend.muted
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
this.saveFriends()
|
pendingFetchFriends = apiGetMyFriendList()
|
||||||
|
.then((list) => {
|
||||||
|
this.friends = (list || []).map(convertFriend)
|
||||||
|
this.loaded = true
|
||||||
|
// 同步 conversationStore 私聊会话的展示名 / 头像 / 免打扰
|
||||||
|
const conversationStore = useConversationStore()
|
||||||
|
for (const friend of this.friends) {
|
||||||
|
conversationStore.updateConversation(ImConversationType.PRIVATE, friend.friendUserId, {
|
||||||
|
name: getFriendDisplayName(friend),
|
||||||
|
avatar: friend.avatar,
|
||||||
|
muted: friend.muted
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 落本地缓存
|
||||||
|
this.saveFriends()
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
pendingFetchFriends = null
|
||||||
|
})
|
||||||
|
return pendingFetchFriends
|
||||||
},
|
},
|
||||||
|
|
||||||
/** 按 friendUserId 获取详情并合并到本地(保证 nickname / avatar 最新) */
|
/** 按 friendUserId 获取详情并合并到本地(保证 nickname / avatar 最新) */
|
||||||
|
|
@ -195,19 +207,19 @@ export const useFriendStore = defineStore('imFriendStore', {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/** 拉取「我相关」的好友申请列表(页面打开时 / 收到 FRIEND_APPLICATION 时刷新);in-flight 期间复用同一 Promise */
|
/** 拉取「我相关」的好友申请列表(页面打开时 / 收到 FRIEND_REQUEST_RECEIVED 时刷新);pending 期间复用同一 Promise */
|
||||||
async fetchFriendRequests() {
|
async fetchFriendRequests() {
|
||||||
if (inflightFetchRequests) {
|
if (pendingFetchRequests) {
|
||||||
return inflightFetchRequests
|
return pendingFetchRequests
|
||||||
}
|
}
|
||||||
inflightFetchRequests = apiGetMyFriendRequestList()
|
pendingFetchRequests = apiGetMyFriendRequestList()
|
||||||
.then((list) => {
|
.then((list) => {
|
||||||
this.friendRequests = (list || []).map(convertFriendRequest)
|
this.friendRequests = (list || []).map(convertFriendRequest)
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
inflightFetchRequests = null
|
pendingFetchRequests = null
|
||||||
})
|
})
|
||||||
return inflightFetchRequests
|
return pendingFetchRequests
|
||||||
},
|
},
|
||||||
|
|
||||||
/** 按 id 查申请记录;列表是按 id 倒序的小列表,O(n) find 即可,不再维护 Map 索引 */
|
/** 按 id 查申请记录;列表是按 id 倒序的小列表,O(n) find 即可,不再维护 Map 索引 */
|
||||||
|
|
@ -320,8 +332,8 @@ export const useFriendStore = defineStore('imFriendStore', {
|
||||||
|
|
||||||
// ==================== WebSocket 事件 dispatcher(1201-1210 段) ====================
|
// ==================== WebSocket 事件 dispatcher(1201-1210 段) ====================
|
||||||
|
|
||||||
/** FRIEND_APPLICATION(1203):收到新申请;payload 已裁减为核心字段,本地拉一次列表补齐 fromUser 等聚合字段 */
|
/** FRIEND_REQUEST_RECEIVED(1203):收到新申请;payload 已裁减为核心字段,本地拉一次列表补齐 fromUser 等聚合字段 */
|
||||||
applyFriendRequestNotification(_payload: FriendNotificationPayload) {
|
applyFriendRequestReceivedNotification(_payload: FriendNotificationPayload) {
|
||||||
this.fetchFriendRequests().catch(() => undefined)
|
this.fetchFriendRequests().catch(() => undefined)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -486,8 +486,8 @@ export const useImWebSocketStore = defineStore('imWebSocketStore', {
|
||||||
const payload = JSON.parse(websocketMessage.content || '{}') as FriendNotificationPayload
|
const payload = JSON.parse(websocketMessage.content || '{}') as FriendNotificationPayload
|
||||||
const friendStore = useFriendStore()
|
const friendStore = useFriendStore()
|
||||||
switch (websocketMessage.type) {
|
switch (websocketMessage.type) {
|
||||||
case ImMessageType.FRIEND_APPLICATION:
|
case ImMessageType.FRIEND_REQUEST_RECEIVED:
|
||||||
friendStore.applyFriendRequestNotification(payload)
|
friendStore.applyFriendRequestReceivedNotification(payload)
|
||||||
break
|
break
|
||||||
case ImMessageType.FRIEND_REQUEST_APPROVED:
|
case ImMessageType.FRIEND_REQUEST_APPROVED:
|
||||||
friendStore.applyFriendRequestApprovedNotification(payload)
|
friendStore.applyFriendRequestApprovedNotification(payload)
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ export const ImMessageType = {
|
||||||
// ========== 好友通知(1201-1210 直接复用 OpenIM 段位编号) ==========
|
// ========== 好友通知(1201-1210 直接复用 OpenIM 段位编号) ==========
|
||||||
FRIEND_REQUEST_APPROVED: 1201, // 好友申请被同意
|
FRIEND_REQUEST_APPROVED: 1201, // 好友申请被同意
|
||||||
FRIEND_REQUEST_REJECTED: 1202, // 好友申请被拒绝
|
FRIEND_REQUEST_REJECTED: 1202, // 好友申请被拒绝
|
||||||
FRIEND_APPLICATION: 1203, // 收到新的好友申请
|
FRIEND_REQUEST_RECEIVED: 1203, // 收到新的好友申请
|
||||||
FRIEND_ADD: 1204, // 新增好友(双方建立关系)
|
FRIEND_ADD: 1204, // 新增好友(双方建立关系)
|
||||||
FRIEND_DELETE: 1205, // 好友被删除
|
FRIEND_DELETE: 1205, // 好友被删除
|
||||||
// 1206 对应 OpenIM FriendRemarkSetNotification;本系统并入 FRIEND_UPDATE(1210) 统一推送,单一字段变更不再独立通道
|
// 1206 对应 OpenIM FriendRemarkSetNotification;本系统并入 FRIEND_UPDATE(1210) 统一推送,单一字段变更不再独立通道
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue