|
|
@@ -0,0 +1,226 @@
|
|
|
+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: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);
|
|
|
+
|
|
|
+ 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', '标记消息为已读失败');
|
|
|
+ }
|
|
|
+ });
|
|
|
+}
|