// 群聊管理器 - 微信小程序专用 // 处理群聊创建、管理、成员管理、权限控制等功能 const apiClient = require('./api-client.js'); /** * 群聊管理器 * 功能: * 1. 群聊创建和解散 * 2. 群成员管理 * 3. 群信息设置 * 4. 群权限管理 * 5. @提醒功能 * 6. 群公告管理 */ class GroupChatManager { constructor() { this.isInitialized = false; // 群聊配置 this.groupConfig = { // 群聊基本配置 maxMembers: 500, // 最大成员数 maxGroupNameLength: 20, // 群名称最大长度 maxDescriptionLength: 200, // 群描述最大长度 maxAnnouncementLength: 500, // 群公告最大长度 // 权限配置 permissions: { owner: { name: '群主', level: 3, canInvite: true, canRemove: true, canSetAdmin: true, canEditInfo: true, canDissolve: true, canMute: true, canSetAnnouncement: true }, admin: { name: '管理员', level: 2, canInvite: true, canRemove: true, canSetAdmin: false, canEditInfo: true, canDissolve: false, canMute: true, canSetAnnouncement: true }, member: { name: '普通成员', level: 1, canInvite: false, canRemove: false, canSetAdmin: false, canEditInfo: false, canDissolve: false, canMute: false, canSetAnnouncement: false } }, // @提醒配置 mention: { enabled: true, maxMentions: 10, // 单条消息最多@10个人 allMemberKeyword: '所有人' // @全体成员关键词 }, // 群设置默认值 defaultSettings: { allowMemberInvite: true, // 允许成员邀请 allowMemberModifyInfo: false, // 允许成员修改群信息 muteAll: false, // 全员禁言 showMemberNickname: true, // 显示成员昵称 saveToContacts: true, // 保存到通讯录 showQRCode: true // 显示群二维码 } }; // 群聊缓存 this.groupCache = new Map(); this.memberCache = new Map(); // 当前用户信息 this.currentUserId = null; this.init(); } // 初始化群聊管理器 async init() { if (this.isInitialized) return; try { // 获取当前用户ID this.currentUserId = wx.getStorageSync('userId'); // 加载群聊缓存 await this.loadGroupCache(); this.isInitialized = true; } catch (error) { console.error('❌ 群聊管理器初始化失败:', error); } } // 👥 ===== 群聊创建和管理 ===== // 创建群聊 async createGroup(groupInfo) { try { // 验证群聊信息 const validation = this.validateGroupInfo(groupInfo); if (!validation.valid) { return { success: false, error: validation.error }; } // 调用API创建群聊 const response = await apiClient.request({ url: '/api/v1/groups', method: 'POST', data: { name: groupInfo.name, description: groupInfo.description || '', avatar: groupInfo.avatar || '', memberIds: groupInfo.memberIds || [], settings: { ...this.groupConfig.defaultSettings, ...groupInfo.settings } } }); if (response.success) { const group = response.data; // 更新本地缓存 this.updateGroupCache(group); return { success: true, data: group }; } else { throw new Error(response.error || '创建群聊失败'); } } catch (error) { console.error('❌ 创建群聊失败:', error); return { success: false, error: error.message }; } } // 解散群聊 async dissolveGroup(groupId) { try { // 检查权限 const hasPermission = await this.checkPermission(groupId, 'canDissolve'); if (!hasPermission) { return { success: false, error: '没有解散群聊的权限' }; } // 调用API解散群聊 const response = await apiClient.request({ url: `/api/v1/groups/${groupId}/dissolve`, method: 'POST' }); if (response.success) { // 清除本地缓存 this.groupCache.delete(groupId); this.memberCache.delete(groupId); return { success: true }; } else { throw new Error(response.error || '解散群聊失败'); } } catch (error) { console.error('❌ 解散群聊失败:', error); return { success: false, error: error.message }; } } // 退出群聊 async leaveGroup(groupId) { try { // 调用API退出群聊 const response = await apiClient.request({ url: `/api/v1/groups/${groupId}/leave`, method: 'POST' }); if (response.success) { // 清除本地缓存 this.groupCache.delete(groupId); this.memberCache.delete(groupId); return { success: true }; } else { throw new Error(response.error || '退出群聊失败'); } } catch (error) { console.error('❌ 退出群聊失败:', error); return { success: false, error: error.message }; } } // 👤 ===== 群成员管理 ===== // 邀请成员 async inviteMembers(groupId, memberIds) { try { // 检查权限 const hasPermission = await this.checkPermission(groupId, 'canInvite'); if (!hasPermission) { return { success: false, error: '没有邀请成员的权限' }; } // 检查成员数量限制 const currentMembers = await this.getGroupMembers(groupId); if (currentMembers.data && currentMembers.data.length + memberIds.length > this.groupConfig.maxMembers) { return { success: false, error: `群成员数量不能超过${this.groupConfig.maxMembers}人` }; } // 调用API邀请成员 const response = await apiClient.request({ url: `/api/v1/groups/${groupId}/members`, method: 'POST', data: { memberIds: memberIds } }); if (response.success) { // 更新成员缓存 this.updateMemberCache(groupId, response.data.members); return { success: true, data: response.data }; } else { throw new Error(response.error || '邀请成员失败'); } } catch (error) { console.error('❌ 邀请成员失败:', error); return { success: false, error: error.message }; } } // 移除成员 async removeMember(groupId, memberId) { try { // 检查权限 const hasPermission = await this.checkPermission(groupId, 'canRemove'); if (!hasPermission) { return { success: false, error: '没有移除成员的权限' }; } // 不能移除自己 if (memberId === this.currentUserId) { return { success: false, error: '不能移除自己,请使用退出群聊功能' }; } // 调用API移除成员 const response = await apiClient.request({ url: `/api/v1/groups/${groupId}/members/${memberId}`, method: 'DELETE' }); if (response.success) { // 更新成员缓存 this.removeMemberFromCache(groupId, memberId); return { success: true }; } else { throw new Error(response.error || '移除成员失败'); } } catch (error) { console.error('❌ 移除成员失败:', error); return { success: false, error: error.message }; } } // 设置管理员 async setAdmin(groupId, memberId, isAdmin) { try { // 检查权限 const hasPermission = await this.checkPermission(groupId, 'canSetAdmin'); if (!hasPermission) { return { success: false, error: '没有设置管理员的权限' }; } // 调用API设置管理员 const response = await apiClient.request({ url: `/api/v1/groups/${groupId}/members/${memberId}/admin`, method: 'PUT', data: { isAdmin: isAdmin } }); if (response.success) { // 更新成员缓存 this.updateMemberRole(groupId, memberId, isAdmin ? 'admin' : 'member'); return { success: true }; } else { throw new Error(response.error || '设置管理员失败'); } } catch (error) { console.error('❌ 设置管理员失败:', error); return { success: false, error: error.message }; } } // 获取群成员列表 async getGroupMembers(groupId, useCache = true) { try { // 先从缓存获取 if (useCache && this.memberCache.has(groupId)) { const cached = this.memberCache.get(groupId); if (Date.now() - cached.timestamp < 300000) { // 5分钟缓存 return { success: true, data: cached.members }; } } // 从服务器获取 const response = await apiClient.request({ url: `/api/v1/groups/${groupId}/members`, method: 'GET' }); if (response.success) { const members = response.data || []; // 更新缓存 this.memberCache.set(groupId, { members: members, timestamp: Date.now() }); return { success: true, data: members }; } else { throw new Error(response.error || '获取群成员失败'); } } catch (error) { console.error('❌ 获取群成员失败:', error); return { success: false, error: error.message }; } } // ⚙️ ===== 群信息设置 ===== // 更新群信息 async updateGroupInfo(groupId, updates) { try { // 检查权限 const hasPermission = await this.checkPermission(groupId, 'canEditInfo'); if (!hasPermission) { return { success: false, error: '没有修改群信息的权限' }; } // 验证更新信息 const validation = this.validateGroupUpdates(updates); if (!validation.valid) { return { success: false, error: validation.error }; } // 调用API更新群信息 const response = await apiClient.request({ url: `/api/v1/groups/${groupId}`, method: 'PUT', data: updates }); if (response.success) { // 更新群聊缓存 this.updateGroupCache(response.data); return { success: true, data: response.data }; } else { throw new Error(response.error || '更新群信息失败'); } } catch (error) { console.error('❌ 更新群信息失败:', error); return { success: false, error: error.message }; } } // 设置群公告 async setGroupAnnouncement(groupId, announcement) { try { // 检查权限 const hasPermission = await this.checkPermission(groupId, 'canSetAnnouncement'); if (!hasPermission) { return { success: false, error: '没有设置群公告的权限' }; } // 验证公告长度 if (announcement.length > this.groupConfig.maxAnnouncementLength) { return { success: false, error: `群公告不能超过${this.groupConfig.maxAnnouncementLength}字符` }; } // 调用API设置群公告 const response = await apiClient.request({ url: `/api/v1/groups/${groupId}/announcement`, method: 'PUT', data: { announcement: announcement } }); if (response.success) { return { success: true }; } else { throw new Error(response.error || '设置群公告失败'); } } catch (error) { console.error('❌ 设置群公告失败:', error); return { success: false, error: error.message }; } } // 📢 ===== @提醒功能 ===== // 解析@提醒 parseMentions(content) { const mentions = []; const mentionRegex = /@([^\s@]+)/g; let match; while ((match = mentionRegex.exec(content)) !== null) { const mentionText = match[1]; if (mentionText === this.groupConfig.mention.allMemberKeyword) { // @全体成员 mentions.push({ type: 'all', text: mentionText, start: match.index, end: match.index + match[0].length }); } else { // @特定成员 mentions.push({ type: 'user', text: mentionText, start: match.index, end: match.index + match[0].length }); } } return mentions; } // 验证@提醒 async validateMentions(groupId, mentions) { try { if (mentions.length > this.groupConfig.mention.maxMentions) { return { valid: false, error: `单条消息最多只能@${this.groupConfig.mention.maxMentions}个人` }; } // 获取群成员列表 const membersResult = await this.getGroupMembers(groupId); if (!membersResult.success) { return { valid: false, error: '获取群成员列表失败' }; } const members = membersResult.data; const validMentions = []; for (const mention of mentions) { if (mention.type === 'all') { // 检查@全体成员权限 const hasPermission = await this.checkPermission(groupId, 'canMentionAll'); if (hasPermission) { validMentions.push({ ...mention, userIds: members.map(m => m.userId) }); } } else { // 查找对应的成员 const member = members.find(m => m.nickname === mention.text || m.username === mention.text || m.userId === mention.text ); if (member) { validMentions.push({ ...mention, userId: member.userId, userIds: [member.userId] }); } } } return { valid: true, mentions: validMentions }; } catch (error) { console.error('❌ 验证@提醒失败:', error); return { valid: false, error: '验证@提醒失败' }; } } // 🔧 ===== 工具方法 ===== // 验证群聊信息 validateGroupInfo(groupInfo) { if (!groupInfo.name || groupInfo.name.trim().length === 0) { return { valid: false, error: '群名称不能为空' }; } if (groupInfo.name.length > this.groupConfig.maxGroupNameLength) { return { valid: false, error: `群名称不能超过${this.groupConfig.maxGroupNameLength}字符` }; } if (groupInfo.description && groupInfo.description.length > this.groupConfig.maxDescriptionLength) { return { valid: false, error: `群描述不能超过${this.groupConfig.maxDescriptionLength}字符` }; } if (groupInfo.memberIds && groupInfo.memberIds.length > this.groupConfig.maxMembers) { return { valid: false, error: `群成员数量不能超过${this.groupConfig.maxMembers}人` }; } return { valid: true }; } // 验证群信息更新 validateGroupUpdates(updates) { if (updates.name !== undefined) { if (!updates.name || updates.name.trim().length === 0) { return { valid: false, error: '群名称不能为空' }; } if (updates.name.length > this.groupConfig.maxGroupNameLength) { return { valid: false, error: `群名称不能超过${this.groupConfig.maxGroupNameLength}字符` }; } } if (updates.description !== undefined && updates.description.length > this.groupConfig.maxDescriptionLength) { return { valid: false, error: `群描述不能超过${this.groupConfig.maxDescriptionLength}字符` }; } return { valid: true }; } // 检查权限 async checkPermission(groupId, permission) { try { const userRole = await this.getUserRole(groupId, this.currentUserId); if (!userRole) return false; const roleConfig = this.groupConfig.permissions[userRole]; return roleConfig && roleConfig[permission]; } catch (error) { console.error('❌ 检查权限失败:', error); return false; } } // 获取用户在群中的角色 async getUserRole(groupId, userId) { try { const membersResult = await this.getGroupMembers(groupId); if (!membersResult.success) return null; const member = membersResult.data.find(m => m.userId === userId); return member ? member.role : null; } catch (error) { console.error('❌ 获取用户角色失败:', error); return null; } } // 更新群聊缓存 updateGroupCache(group) { this.groupCache.set(group.groupId, { ...group, timestamp: Date.now() }); } // 更新成员缓存 updateMemberCache(groupId, members) { this.memberCache.set(groupId, { members: members, timestamp: Date.now() }); } // 从缓存中移除成员 removeMemberFromCache(groupId, memberId) { const cached = this.memberCache.get(groupId); if (cached) { cached.members = cached.members.filter(m => m.userId !== memberId); this.memberCache.set(groupId, cached); } } // 更新成员角色 updateMemberRole(groupId, memberId, role) { const cached = this.memberCache.get(groupId); if (cached) { const member = cached.members.find(m => m.userId === memberId); if (member) { member.role = role; this.memberCache.set(groupId, cached); } } } // 加载群聊缓存 async loadGroupCache() { try { const cached = wx.getStorageSync('groupCache') || {}; this.groupCache = new Map(Object.entries(cached)); } catch (error) { console.error('❌ 加载群聊缓存失败:', error); } } // 保存群聊缓存 saveGroupCache() { try { const cacheObj = Object.fromEntries(this.groupCache); wx.setStorageSync('groupCache', cacheObj); } catch (error) { console.error('❌ 保存群聊缓存失败:', error); } } // 获取群聊管理器状态 getStatus() { return { isInitialized: this.isInitialized, groupCount: this.groupCache.size, memberCacheCount: this.memberCache.size, currentUserId: this.currentUserId, config: this.groupConfig }; } // 清除所有缓存 clearAllCache() { this.groupCache.clear(); this.memberCache.clear(); wx.removeStorageSync('groupCache'); } // 重置管理器 reset() { this.clearAllCache(); this.currentUserId = null; this.isInitialized = false; } } // 创建全局实例 const groupChatManager = new GroupChatManager(); module.exports = groupChatManager;