2
0

routes_messages.ts 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. import { Hono } from 'hono'
  2. import type { Variables } from './app.tsx'
  3. import type { WithAuth } from './app.tsx'
  4. import { MessageType, MessageStatus } from '../client/share/types.ts'
  5. export function createMessagesRoutes(withAuth: WithAuth) {
  6. const messagesRoutes = new Hono<{ Variables: Variables }>()
  7. // 发送消息
  8. messagesRoutes.post('/', withAuth, async (c) => {
  9. try {
  10. const auth = c.get('auth')
  11. const apiClient = c.get('apiClient')
  12. const { title, content, type, receiver_ids } = await c.req.json()
  13. if (!title || !content || !type || !receiver_ids?.length) {
  14. return c.json({ error: '缺少必要参数' }, 400)
  15. }
  16. // 创建消息
  17. const user = c.get('user')
  18. if (!user) return c.json({ error: '未授权访问' }, 401)
  19. const [messageId] = await apiClient.database.table('messages').insert({
  20. title,
  21. content,
  22. type,
  23. sender_id: user.id,
  24. sender_name: user.username,
  25. created_at: apiClient.database.fn.now(),
  26. updated_at: apiClient.database.fn.now()
  27. })
  28. // 关联用户消息
  29. const userMessages = receiver_ids.map((userId: number) => ({
  30. user_id: userId,
  31. message_id: messageId,
  32. status: MessageStatus.UNREAD,
  33. created_at: apiClient.database.fn.now(),
  34. updated_at: apiClient.database.fn.now()
  35. }))
  36. await apiClient.database.table('user_messages').insert(userMessages)
  37. return c.json({ message: '消息发送成功', id: messageId }, 201)
  38. } catch (error) {
  39. console.error('发送消息失败:', error)
  40. return c.json({ error: '发送消息失败' }, 500)
  41. }
  42. })
  43. // 获取用户消息列表
  44. messagesRoutes.get('/', withAuth, async (c) => {
  45. try {
  46. const apiClient = c.get('apiClient')
  47. const page = Number(c.req.query('page')) || 1
  48. const pageSize = Number(c.req.query('pageSize')) || 20
  49. const type = c.req.query('type')
  50. const status = c.req.query('status')
  51. const user = c.get('user')
  52. if (!user) return c.json({ error: '未授权访问' }, 401)
  53. const query = apiClient.database.table('user_messages')
  54. .select('m.*', 'um.status as user_status', 'um.read_at', 'um.id as user_message_id')
  55. .from('user_messages as um')
  56. .leftJoin('messages as m', 'um.message_id', 'm.id')
  57. .where('um.user_id', user.id)
  58. .where('um.is_deleted', 0)
  59. .orderBy('m.created_at', 'desc')
  60. .limit(pageSize)
  61. .offset((page - 1) * pageSize)
  62. if (type) query.where('m.type', type)
  63. if (status) query.where('um.status', status)
  64. const messages = await query
  65. return c.json(messages)
  66. } catch (error) {
  67. console.error('获取消息列表失败:', error)
  68. return c.json({ error: '获取消息列表失败' }, 500)
  69. }
  70. })
  71. // 获取消息详情
  72. messagesRoutes.get('/:id', withAuth, async (c) => {
  73. try {
  74. const apiClient = c.get('apiClient')
  75. const messageId = c.req.param('id')
  76. const user = c.get('user')
  77. if (!user) return c.json({ error: '未授权访问' }, 401)
  78. const message = await apiClient.database.table('user_messages')
  79. .select('m.*', 'um.status as user_status', 'um.read_at')
  80. .from('user_messages as um')
  81. .leftJoin('messages as m', 'um.message_id', 'm.id')
  82. .where('um.user_id', user.id)
  83. .where('um.message_id', messageId)
  84. .first()
  85. if (!message) {
  86. return c.json({ error: '消息不存在或无权访问' }, 404)
  87. }
  88. // 标记为已读
  89. if (message.user_status === MessageStatus.UNREAD) {
  90. const user = c.get('user')
  91. if (!user) return c.json({ error: '未授权访问' }, 401)
  92. await apiClient.database.table('user_messages')
  93. .where('user_id', user.id)
  94. .where('message_id', messageId)
  95. .update({
  96. status: MessageStatus.READ,
  97. read_at: apiClient.database.fn.now(),
  98. updated_at: apiClient.database.fn.now()
  99. })
  100. }
  101. return c.json(message)
  102. } catch (error) {
  103. console.error('获取消息详情失败:', error)
  104. return c.json({ error: '获取消息详情失败' }, 500)
  105. }
  106. })
  107. // 删除消息(软删除)
  108. messagesRoutes.delete('/:id', withAuth, async (c) => {
  109. try {
  110. const apiClient = c.get('apiClient')
  111. const user = c.get('user')
  112. if (!user) return c.json({ error: '未授权访问' }, 401)
  113. const messageId = c.req.param('id')
  114. await apiClient.database.table('user_messages')
  115. .where('user_id', user.id)
  116. .where('message_id', messageId)
  117. .update({
  118. is_deleted: 1,
  119. updated_at: apiClient.database.fn.now()
  120. })
  121. return c.json({ message: '消息已删除' })
  122. } catch (error) {
  123. console.error('删除消息失败:', error)
  124. return c.json({ error: '删除消息失败' }, 500)
  125. }
  126. })
  127. // 获取未读消息数量
  128. messagesRoutes.get('/unread-count', withAuth, async (c) => {
  129. try {
  130. const apiClient = c.get('apiClient')
  131. const user = c.get('user')
  132. if (!user) return c.json({ error: '未授权访问' }, 401)
  133. const count = await apiClient.database.table('user_messages')
  134. .where('user_id', user.id)
  135. .where('status', MessageStatus.UNREAD)
  136. .where('is_deleted', 0)
  137. .clone()
  138. .count()
  139. return c.json({ count: Number(count) })
  140. } catch (error) {
  141. console.error('获取未读消息数失败:', error)
  142. return c.json({ error: '获取未读消息数失败' }, 500)
  143. }
  144. })
  145. return messagesRoutes
  146. }