routes_io_messages.ts 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. import { SocketWithUser , Variables} from './router_io.ts';
  2. import { MessageType, MessageStatus } from '../client/share/types.ts'
  3. import { APIClient } from "@d8d-appcontainer/api";
  4. interface MessageSendData {
  5. title: string;
  6. content: string;
  7. type: MessageType;
  8. receiver_ids: number[];
  9. }
  10. interface MessageListData {
  11. page?: number;
  12. pageSize?: number;
  13. type?: MessageType;
  14. status?: MessageStatus;
  15. }
  16. export function setupMessageEvents({ socket , apiClient }:Variables) {
  17. // 发送消息
  18. socket.on('message:send', async (data: MessageSendData) => {
  19. try {
  20. const { title, content, type, receiver_ids } = data;
  21. if (!title || !content || !type || !receiver_ids?.length) {
  22. socket.emit('error', '缺少必要参数');
  23. return;
  24. }
  25. const user = socket.user;
  26. if (!user) {
  27. socket.emit('error', '未授权访问');
  28. return;
  29. }
  30. // 创建消息
  31. const [messageId] = await apiClient.database.table('messages').insert({
  32. title,
  33. content,
  34. type,
  35. sender_id: user.id,
  36. sender_name: user.username,
  37. created_at: apiClient.database.fn.now(),
  38. updated_at: apiClient.database.fn.now()
  39. });
  40. // 关联用户消息
  41. const userMessages = receiver_ids.map((userId: number) => ({
  42. user_id: userId,
  43. message_id: messageId,
  44. status: MessageStatus.UNREAD,
  45. created_at: apiClient.database.fn.now(),
  46. updated_at: apiClient.database.fn.now()
  47. }));
  48. await apiClient.database.table('user_messages').insert(userMessages);
  49. socket.emit('message:sent', {
  50. message: '消息发送成功',
  51. data: { id: messageId }
  52. });
  53. } catch (error) {
  54. console.error('发送消息失败:', error);
  55. socket.emit('error', '发送消息失败');
  56. }
  57. });
  58. // 获取消息列表
  59. socket.on('message:list', async (data: MessageListData) => {
  60. try {
  61. const { page = 1, pageSize = 20, type, status } = data;
  62. const user = socket.user;
  63. if (!user) {
  64. socket.emit('error', '未授权访问');
  65. return;
  66. }
  67. const query = apiClient.database.table('user_messages as um')
  68. .select('m.*', 'um.status as user_status', 'um.read_at', 'um.id as user_message_id')
  69. .leftJoin('messages as m', 'um.message_id', 'm.id')
  70. .where('um.user_id', user.id)
  71. .where('um.is_deleted', 0)
  72. .orderBy('m.created_at', 'desc')
  73. .limit(pageSize)
  74. .offset((page - 1) * pageSize);
  75. if (type) query.where('m.type', type);
  76. if (status) query.where('um.status', status);
  77. const countQuery = query.clone();
  78. const messages = await query;
  79. // 获取总数用于分页
  80. const total = await countQuery.count();
  81. const totalCount = Number(total);
  82. const totalPages = Math.ceil(totalCount / pageSize);
  83. socket.emit('message:list', {
  84. data: messages,
  85. pagination: {
  86. total: totalCount,
  87. current: page,
  88. pageSize,
  89. totalPages
  90. }
  91. });
  92. } catch (error) {
  93. console.error('获取消息列表失败:', error);
  94. socket.emit('error', '获取消息列表失败');
  95. }
  96. });
  97. // 获取消息详情
  98. socket.on('message:detail', async (messageId: number) => {
  99. try {
  100. const user = socket.user;
  101. if (!user) {
  102. socket.emit('error', '未授权访问');
  103. return;
  104. }
  105. const message = await apiClient.database.table('user_messages as um')
  106. .select('m.*', 'um.status as user_status', 'um.read_at')
  107. .leftJoin('messages as m', 'um.message_id', 'm.id')
  108. .where('um.user_id', user.id)
  109. .where('um.message_id', messageId)
  110. .first();
  111. if (!message) {
  112. socket.emit('error', '消息不存在或无权访问');
  113. return;
  114. }
  115. // 标记为已读
  116. if (message.user_status === MessageStatus.UNREAD) {
  117. await apiClient.database.table('user_messages')
  118. .where('user_id', user.id)
  119. .where('message_id', messageId)
  120. .update({
  121. status: MessageStatus.READ,
  122. read_at: apiClient.database.fn.now(),
  123. updated_at: apiClient.database.fn.now()
  124. });
  125. }
  126. socket.emit('message:detail', {
  127. message: '获取消息成功',
  128. data: message
  129. });
  130. } catch (error) {
  131. console.error('获取消息详情失败:', error);
  132. socket.emit('error', '获取消息详情失败');
  133. }
  134. });
  135. // 删除消息
  136. socket.on('message:delete', async (messageId: number) => {
  137. try {
  138. const user = socket.user;
  139. if (!user) {
  140. socket.emit('error', '未授权访问');
  141. return;
  142. }
  143. await apiClient.database.table('user_messages')
  144. .where('user_id', user.id)
  145. .where('message_id', messageId)
  146. .update({
  147. is_deleted: 1,
  148. updated_at: apiClient.database.fn.now()
  149. });
  150. socket.emit('message:deleted', { message: '消息已删除' });
  151. } catch (error) {
  152. console.error('删除消息失败:', error);
  153. socket.emit('error', '删除消息失败');
  154. }
  155. });
  156. // 获取未读消息数
  157. socket.on('message:count', async () => {
  158. try {
  159. const user = socket.user;
  160. if (!user) {
  161. socket.emit('error', '未授权访问');
  162. return;
  163. }
  164. const count = await apiClient.database.table('user_messages')
  165. .where('user_id', user.id)
  166. .where('status', MessageStatus.UNREAD)
  167. .where('is_deleted', 0)
  168. .count();
  169. socket.emit('message:count', { count: Number(count) });
  170. } catch (error) {
  171. console.error('获取未读消息数失败:', error);
  172. socket.emit('error', '获取未读消息数失败');
  173. }
  174. });
  175. // 标记消息为已读
  176. socket.on('message:read', async (messageId: number) => {
  177. try {
  178. const user = socket.user;
  179. if (!user) {
  180. socket.emit('error', '未授权访问');
  181. return;
  182. }
  183. await apiClient.database.table('user_messages')
  184. .where('user_id', user.id)
  185. .where('message_id', messageId)
  186. .update({
  187. status: MessageStatus.READ,
  188. read_at: apiClient.database.fn.now(),
  189. updated_at: apiClient.database.fn.now()
  190. });
  191. socket.emit('message:read', { message: '消息已标记为已读' });
  192. } catch (error) {
  193. console.error('标记消息为已读失败:', error);
  194. socket.emit('error', '标记消息为已读失败');
  195. }
  196. });
  197. }