findme-miniprogram-frontend/utils/nim-user-manager.js
2025-12-27 17:16:03 +08:00

221 lines
5.8 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* NIM 用户信息管理器
* 负责同步用户头像和昵称到 NIM SDK
*/
const app = getApp();
class NIMUserManager {
constructor() {
this.initialized = false;
this.userInfoCache = new Map(); // 用户信息缓存
this.cacheExpiry = 30 * 60 * 1000; // 缓存30分钟
}
/**
* 初始化用户管理器
*/
init() {
if (this.initialized) {
console.log('NIM 用户管理器已初始化');
return;
}
console.log('📋 初始化 NIM 用户管理器');
this.initialized = true;
}
/**
* 更新自己的用户信息到 NIM
* @param {Object} userInfo - 用户信息对象
* @param {string} userInfo.avatar - 头像 URL
* @param {string} userInfo.nickname - 昵称
* @returns {Promise<boolean>} 是否更新成功
*/
async updateSelfUserInfo(userInfo = {}) {
try {
const nim = app.globalData?.nim;
if (!nim) {
console.warn('⚠️ NIM 实例未初始化,跳过用户信息同步');
return false;
}
// 🔥 正确的访问方式nim.V2NIMUserService (小程序/Web平台)
const userService = nim.V2NIMUserService;
if (!userService) {
console.warn('⚠️ NIM V2NIMUserService 未注册');
return false;
}
// 构建更新参数
const updateParams = {};
if (userInfo.avatar) {
updateParams.avatar = userInfo.avatar;
}
if (userInfo.nickname) {
updateParams.name = userInfo.nickname;
}
// 如果没有需要更新的字段,直接返回
if (Object.keys(updateParams).length === 0) {
console.log('没有需要更新的用户信息');
return true;
}
console.log('🔄 同步用户信息到 NIM:', updateParams);
// 🔥 调用 NIM SDK 更新用户资料
// 参考文档https://doc.yunxin.163.com/messaging2/client-apis/jc0MTUyODY?platform=client#updateSelfUserProfile
await userService.updateSelfUserProfile(updateParams);
console.log('✅ NIM 用户信息同步成功');
return true;
} catch (error) {
console.error('❌ NIM 用户信息同步失败:', error);
// 不抛出错误,避免影响主流程
return false;
}
}
/**
* 批量获取用户信息(从 NIM 或 API
* @param {Array<string>} accountIds - 用户账号 ID 列表
* @returns {Promise<Map<string, Object>>} 用户信息 Map
*/
async getUserInfoBatch(accountIds = []) {
if (!Array.isArray(accountIds) || accountIds.length === 0) {
return new Map();
}
try {
const nim = app.globalData?.nim;
if (!nim) {
console.warn('⚠️ NIM 实例未初始化');
return new Map();
}
// 🔥 正确的访问方式nim.V2NIMUserService
const userService = nim.V2NIMUserService;
if (!userService) {
console.warn('⚠️ NIM V2NIMUserService 未注册');
return new Map();
}
// 过滤掉已缓存且未过期的用户
const now = Date.now();
const needFetch = accountIds.filter(id => {
const cached = this.userInfoCache.get(id);
return !cached || (now - cached.timestamp > this.cacheExpiry);
});
if (needFetch.length === 0) {
// 全部从缓存返回
const result = new Map();
accountIds.forEach(id => {
const cached = this.userInfoCache.get(id);
if (cached) {
result.set(id, cached.data);
}
});
return result;
}
console.log(`📡 从 NIM 获取 ${needFetch.length} 个用户信息`);
// 从 NIM 获取用户信息
const users = await userService.getUserList(needFetch);
const result = new Map();
if (Array.isArray(users)) {
users.forEach(user => {
const userInfo = {
accountId: user.accountId,
avatar: user.avatar || '',
nickname: user.name || '',
createTime: user.createTime,
updateTime: user.updateTime
};
result.set(user.accountId, userInfo);
// 更新缓存
this.userInfoCache.set(user.accountId, {
data: userInfo,
timestamp: now
});
});
}
// 补充缓存中的数据
accountIds.forEach(id => {
if (!result.has(id)) {
const cached = this.userInfoCache.get(id);
if (cached) {
result.set(id, cached.data);
}
}
});
return result;
} catch (error) {
console.error('❌ 批量获取用户信息失败:', error);
return new Map();
}
}
/**
* 获取单个用户信息
* @param {string} accountId - 用户账号 ID
* @returns {Promise<Object|null>} 用户信息对象
*/
async getUserInfo(accountId) {
if (!accountId) {
return null;
}
const userMap = await this.getUserInfoBatch([accountId]);
return userMap.get(accountId) || null;
}
/**
* 清除用户信息缓存
* @param {string} accountId - 可选,指定用户 ID不传则清除全部
*/
clearCache(accountId = null) {
if (accountId) {
this.userInfoCache.delete(accountId);
console.log(`🗑️ 清除用户 ${accountId} 的缓存`);
} else {
this.userInfoCache.clear();
console.log('🗑️ 清除所有用户信息缓存');
}
}
/**
* 获取缓存统计信息
* @returns {Object} 缓存统计
*/
getCacheStats() {
const now = Date.now();
let expired = 0;
this.userInfoCache.forEach(item => {
if (now - item.timestamp > this.cacheExpiry) {
expired++;
}
});
return {
total: this.userInfoCache.size,
expired: expired,
valid: this.userInfoCache.size - expired
};
}
}
// 导出单例
const nimUserManager = new NIMUserManager();
module.exports = nimUserManager;