/** * 好友关系数据存储(内存存储,生产环境应使用数据库) */ // 好友关系表: { odId: [friendId1, friendId2, ...] } const friendships = new Map(); // 好友请求表: { requestId: { id, fromUserId, toUserId, message, status, createTime } } const friendRequests = new Map(); // 用户表(模拟): { odId: { id, nickname, phone, avatarUrl, isOnline } } const users = new Map(); let requestIdCounter = 1; let userIdCounter = 100; // 初始化一些测试用户 function initTestUsers() { const testUsers = [ { id: 1, nickname: '测试用户1', phone: '13800000001', avatarUrl: '', isOnline: 1 }, { id: 2, nickname: '测试用户2', phone: '13800000002', avatarUrl: '', isOnline: 0 }, { id: 3, nickname: '小明', phone: '13800000003', avatarUrl: '', isOnline: 1 }, { id: 4, nickname: '小红', phone: '13800000004', avatarUrl: '', isOnline: 0 }, { id: 5, nickname: '张三', phone: '13800000005', avatarUrl: '', isOnline: 1 }, ]; testUsers.forEach(user => { users.set(user.id, user); }); userIdCounter = 100; } initTestUsers(); /** * 获取或创建用户 */ function getOrCreateUser(userId) { if (!users.has(userId)) { users.set(userId, { id: userId, nickname: `用户${userId}`, phone: '', avatarUrl: '', isOnline: 0 }); } return users.get(userId); } /** * 搜索用户 */ function searchUsers(keyword, currentUserId, page = 1, pageSize = 20) { const results = []; const lowerKeyword = keyword.toLowerCase(); for (const [id, user] of users) { if (id === currentUserId) continue; // 排除自己 const matchNickname = user.nickname && user.nickname.toLowerCase().includes(lowerKeyword); const matchPhone = user.phone && user.phone.includes(keyword); if (matchNickname || matchPhone) { // 判断好友状态 let friendStatus = 0; // 0: 非好友, 1: 已是好友, 2: 已发送请求, 3: 收到请求 const myFriends = friendships.get(currentUserId) || []; if (myFriends.includes(id)) { friendStatus = 1; } else { // 检查是否有待处理的请求 for (const [reqId, req] of friendRequests) { if (req.status !== 'pending') continue; if (req.fromUserId === currentUserId && req.toUserId === id) { friendStatus = 2; break; } if (req.fromUserId === id && req.toUserId === currentUserId) { friendStatus = 3; break; } } } results.push({ id: user.id, nickname: user.nickname, phone: user.phone ? user.phone.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2') : '', avatarUrl: user.avatarUrl, friendStatus }); } } const start = (page - 1) * pageSize; const end = start + pageSize; return { list: results.slice(start, end), total: results.length, page, pageSize }; } /** * 获取好友列表 */ function getFriendList(userId, page = 1, pageSize = 100) { const friendIds = friendships.get(userId) || []; const list = []; for (const friendId of friendIds) { const user = users.get(friendId); if (user) { list.push({ id: user.id, name: user.nickname, avatarUrl: user.avatarUrl, isOnline: user.isOnline }); } } const start = (page - 1) * pageSize; const end = start + pageSize; return { list: list.slice(start, end), total: list.length, page, pageSize }; } /** * 发送好友请求 */ function sendFriendRequest(fromUserId, toUserId, message = '') { // 检查是否已经是好友 const myFriends = friendships.get(fromUserId) || []; if (myFriends.includes(toUserId)) { return { success: false, message: '已经是好友了' }; } // 检查是否已有待处理的请求 for (const [reqId, req] of friendRequests) { if (req.status !== 'pending') continue; if (req.fromUserId === fromUserId && req.toUserId === toUserId) { return { success: false, message: '已发送过好友请求,请等待对方处理' }; } if (req.fromUserId === toUserId && req.toUserId === fromUserId) { return { success: false, message: '对方已向你发送好友请求,请在好友请求中处理' }; } } // 确保目标用户存在 getOrCreateUser(toUserId); const requestId = requestIdCounter++; const request = { id: requestId, fromUserId, toUserId, message, status: 'pending', createTime: new Date().toISOString() }; friendRequests.set(requestId, request); return { success: true, requestId }; } /** * 获取收到的好友请求 */ function getFriendRequests(userId, page = 1, pageSize = 100) { const list = []; for (const [reqId, req] of friendRequests) { if (req.toUserId === userId && req.status === 'pending') { const fromUser = users.get(req.fromUserId); list.push({ id: req.id, from_user_id: req.fromUserId, nickname: fromUser ? fromUser.nickname : `用户${req.fromUserId}`, avatarUrl: fromUser ? fromUser.avatarUrl : '', message: req.message, create_time: req.createTime }); } } // 按时间倒序 list.sort((a, b) => new Date(b.create_time) - new Date(a.create_time)); const start = (page - 1) * pageSize; const end = start + pageSize; return { list: list.slice(start, end), total: list.length, page, pageSize }; } /** * 处理好友请求 */ function handleFriendRequest(requestId, userId, accept) { const request = friendRequests.get(requestId); if (!request) { return { success: false, message: '好友请求不存在' }; } if (request.toUserId !== userId) { return { success: false, message: '无权处理此请求' }; } if (request.status !== 'pending') { return { success: false, message: '请求已被处理' }; } if (accept) { // 接受请求,建立双向好友关系 const fromFriends = friendships.get(request.fromUserId) || []; const toFriends = friendships.get(request.toUserId) || []; if (!fromFriends.includes(request.toUserId)) { fromFriends.push(request.toUserId); friendships.set(request.fromUserId, fromFriends); } if (!toFriends.includes(request.fromUserId)) { toFriends.push(request.fromUserId); friendships.set(request.toUserId, toFriends); } request.status = 'accepted'; } else { request.status = 'rejected'; } friendRequests.set(requestId, request); return { success: true }; } /** * 删除好友 */ function removeFriend(userId, friendId) { const myFriends = friendships.get(userId) || []; const theirFriends = friendships.get(friendId) || []; const myIndex = myFriends.indexOf(friendId); if (myIndex > -1) { myFriends.splice(myIndex, 1); friendships.set(userId, myFriends); } const theirIndex = theirFriends.indexOf(userId); if (theirIndex > -1) { theirFriends.splice(theirIndex, 1); friendships.set(friendId, theirFriends); } return { success: true }; } /** * 检查是否是好友 */ function isFriend(userId1, userId2) { const friends = friendships.get(userId1) || []; return friends.includes(userId2); } module.exports = { searchUsers, getFriendList, sendFriendRequest, getFriendRequests, handleFriendRequest, removeFriend, isFriend, getOrCreateUser };