| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303 |
- 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);
- 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', '标记消息为已读失败');
- }
- });
- }
|