import { SocketWithUser , Variables} from './router_io.ts'; import { MessageType, MessageStatus } from '../client/share/types.ts' import { APIClient } from "@d8d-appcontainer/api"; interface MessageSendData { title: string; content: string; type: MessageType; receiver_ids: number[]; } interface MessageListData { page?: number; pageSize?: number; type?: MessageType; status?: MessageStatus; } export function setupMessageEvents({ socket , apiClient }:Variables) { // 订阅频道 socket.on('message:subscribe', (channel: string) => { try { socket.join(channel); socket.emit('message:subscribed', { message: `成功订阅频道: ${channel}`, channel }); } catch (error) { console.error('订阅频道失败:', error); socket.emit('error', '订阅频道失败'); } }); // 取消订阅 socket.on('message:unsubscribe', (channel: string) => { try { socket.leave(channel); socket.emit('message:unsubscribed', { message: `已取消订阅频道: ${channel}`, channel }); } catch (error) { console.error('取消订阅失败:', error); socket.emit('error', '取消订阅失败'); } }); // 广播消息 socket.on('message:broadcast', async (data: { channel?: string; title: string; content: string; type: MessageType; }) => { try { const { channel, title, content, type } = data; const user = socket.user; if (!user) { socket.emit('error', '未授权访问'); return; } // 创建广播消息 const [messageId] = await apiClient.database.table('messages').insert({ title, content, type, sender_id: user.id, sender_name: user.username, is_broadcast: 1, created_at: apiClient.database.fn.now(), updated_at: apiClient.database.fn.now() }); // 广播到所有客户端或特定频道 const broadcastTarget = channel ? socket.to(channel) : socket.broadcast; broadcastTarget.emit('message:broadcasted', { id: messageId, title, content, type, sender_id: user.id, sender_name: user.username, created_at: new Date().toISOString() }); socket.emit('message:broadcasted', { message: '广播消息发送成功', data: { id: messageId } }); } catch (error) { console.error('广播消息失败:', error); socket.emit('error', '广播消息失败'); } }); // 发送消息 socket.on('message:send', async (data: MessageSendData) => { try { const { title, content, type, receiver_ids } = data; if (!title || !content || !type || !receiver_ids?.length) { socket.emit('error', '缺少必要参数'); return; } const user = socket.user; if (!user) { socket.emit('error', '未授权访问'); return; } // 创建消息 const [messageId] = await apiClient.database.table('messages').insert({ title, content, type, sender_id: user.id, sender_name: user.username, created_at: apiClient.database.fn.now(), updated_at: apiClient.database.fn.now() }); // 关联用户消息 const userMessages = receiver_ids.map((userId: number) => ({ user_id: userId, message_id: messageId, status: MessageStatus.UNREAD, created_at: apiClient.database.fn.now(), updated_at: apiClient.database.fn.now() })); await apiClient.database.table('user_messages').insert(userMessages); // 根据消息类型推送到不同频道 const messageData = { id: messageId, title, content, type, sender_id: user.id, sender_name: user.username, created_at: new Date().toISOString() }; if (type === MessageType.SYSTEM) { socket.to('system').emit('message:received', messageData); } else if (type === MessageType.ANNOUNCE) { socket.to('announce').emit('message:received', messageData); } else if (type === MessageType.PRIVATE) { receiver_ids.forEach(userId => { socket.to(`user_${userId}`).emit('message:received', messageData); }); } socket.emit('message:sent', { message: '消息发送成功', data: { id: messageId } }); } catch (error) { console.error('发送消息失败:', error); socket.emit('error', '发送消息失败'); } }); // 获取消息列表 socket.on('message:list', async (data: MessageListData) => { try { const { page = 1, pageSize = 20, type, status } = data; const user = socket.user; if (!user) { socket.emit('error', '未授权访问'); return; } const query = apiClient.database.table('user_messages as um') .select('m.*', 'um.status as user_status', 'um.read_at', 'um.id as user_message_id') .leftJoin('messages as m', 'um.message_id', 'm.id') .where('um.user_id', user.id) .where('um.is_deleted', 0) .orderBy('m.created_at', 'desc') .limit(pageSize) .offset((page - 1) * pageSize); if (type) query.where('m.type', type); if (status) query.where('um.status', status); const countQuery = query.clone(); const messages = await query; // 获取总数用于分页 const total = await countQuery.count(); const totalCount = Number(total); const totalPages = Math.ceil(totalCount / pageSize); socket.emit('message:list', { data: messages, pagination: { total: totalCount, current: page, pageSize, totalPages } }); } catch (error) { console.error('获取消息列表失败:', error); socket.emit('error', '获取消息列表失败'); } }); // 获取消息详情 socket.on('message:detail', async (messageId: number) => { try { const user = socket.user; if (!user) { socket.emit('error', '未授权访问'); return; } const message = await apiClient.database.table('user_messages as um') .select('m.*', 'um.status as user_status', 'um.read_at') .leftJoin('messages as m', 'um.message_id', 'm.id') .where('um.user_id', user.id) .where('um.message_id', messageId) .first(); if (!message) { socket.emit('error', '消息不存在或无权访问'); return; } // 标记为已读 if (message.user_status === MessageStatus.UNREAD) { await apiClient.database.table('user_messages') .where('user_id', user.id) .where('message_id', messageId) .update({ status: MessageStatus.READ, read_at: apiClient.database.fn.now(), updated_at: apiClient.database.fn.now() }); } socket.emit('message:detail', { message: '获取消息成功', data: message }); } catch (error) { console.error('获取消息详情失败:', error); socket.emit('error', '获取消息详情失败'); } }); // 删除消息 socket.on('message:delete', async (messageId: number) => { try { const user = socket.user; if (!user) { socket.emit('error', '未授权访问'); return; } await apiClient.database.table('user_messages') .where('user_id', user.id) .where('message_id', messageId) .update({ is_deleted: 1, updated_at: apiClient.database.fn.now() }); socket.emit('message:deleted', { message: '消息已删除' }); } catch (error) { console.error('删除消息失败:', error); socket.emit('error', '删除消息失败'); } }); // 获取未读消息数 socket.on('message:count', async () => { try { const user = socket.user; if (!user) { socket.emit('error', '未授权访问'); return; } const count = await apiClient.database.table('user_messages') .where('user_id', user.id) .where('status', MessageStatus.UNREAD) .where('is_deleted', 0) .count(); socket.emit('message:count', { count: Number(count) }); } catch (error) { console.error('获取未读消息数失败:', error); socket.emit('error', '获取未读消息数失败'); } }); // 标记消息为已读 socket.on('message:read', async (messageId: number) => { try { const user = socket.user; if (!user) { socket.emit('error', '未授权访问'); return; } await apiClient.database.table('user_messages') .where('user_id', user.id) .where('message_id', messageId) .update({ status: MessageStatus.READ, read_at: apiClient.database.fn.now(), updated_at: apiClient.database.fn.now() }); socket.emit('message:read', { message: '消息已标记为已读' }); } catch (error) { console.error('标记消息为已读失败:', error); socket.emit('error', '标记消息为已读失败'); } }); }