messageApi.ts 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. import { API_BASE_URL } from "@/lib/config";
  2. import { MessageItem } from "../types";
  3. interface SendMessagePayload {
  4. conversationId: number;
  5. content: string;
  6. senderId?: number;
  7. senderIsAgent?: boolean;
  8. // 文件相关字段(可选)
  9. fileUrl?: string;
  10. fileType?: "image" | "document";
  11. fileName?: string;
  12. fileSize?: number;
  13. mimeType?: string;
  14. }
  15. // 文件上传结果
  16. export interface UploadFileResult {
  17. file_url: string;
  18. file_type: "image" | "document";
  19. file_name: string;
  20. file_size: number;
  21. mime_type: string;
  22. }
  23. export async function fetchMessages(
  24. conversationId: number,
  25. includeAIMessages: boolean = false
  26. ): Promise<MessageItem[]> {
  27. const res = await fetch(
  28. `${API_BASE_URL}/messages?conversation_id=${conversationId}&include_ai_messages=${includeAIMessages}`,
  29. {
  30. cache: "no-store",
  31. }
  32. );
  33. if (!res.ok) {
  34. throw new Error("获取消息失败");
  35. }
  36. const data = await res.json();
  37. if (!Array.isArray(data)) {
  38. return [];
  39. }
  40. return data;
  41. }
  42. // 上传文件
  43. export async function uploadFile(
  44. file: File,
  45. conversationId?: number
  46. ): Promise<UploadFileResult> {
  47. const formData = new FormData();
  48. formData.append("file", file);
  49. if (conversationId) {
  50. formData.append("conversation_id", conversationId.toString());
  51. }
  52. const res = await fetch(`${API_BASE_URL}/messages/upload`, {
  53. method: "POST",
  54. body: formData,
  55. });
  56. if (!res.ok) {
  57. const error = await res.json().catch(() => ({}));
  58. throw new Error(error.error || "文件上传失败");
  59. }
  60. const data = await res.json();
  61. if (!data.success) {
  62. throw new Error(data.error || "文件上传失败");
  63. }
  64. return data.data;
  65. }
  66. export async function sendMessage({
  67. conversationId,
  68. content,
  69. senderId,
  70. senderIsAgent = true,
  71. fileUrl,
  72. fileType,
  73. fileName,
  74. fileSize,
  75. mimeType,
  76. }: SendMessagePayload): Promise<void> {
  77. const payload: any = {
  78. conversation_id: conversationId,
  79. content,
  80. sender_is_agent: senderIsAgent,
  81. sender_id: typeof senderId === "number" ? senderId : 0,
  82. };
  83. // 如果有文件,添加文件字段
  84. if (fileUrl) {
  85. payload.file_url = fileUrl;
  86. if (fileType) payload.file_type = fileType;
  87. if (fileName) payload.file_name = fileName;
  88. if (fileSize) payload.file_size = fileSize;
  89. if (mimeType) payload.mime_type = mimeType;
  90. }
  91. const res = await fetch(`${API_BASE_URL}/messages`, {
  92. method: "POST",
  93. headers: { "Content-Type": "application/json" },
  94. body: JSON.stringify(payload),
  95. });
  96. if (!res.ok) {
  97. const error = await res.json().catch(() => ({}));
  98. console.error(
  99. `❌ 发送消息失败: 对话ID=${conversationId}, 状态=${res.status}, 错误=${JSON.stringify(error)}`
  100. );
  101. throw new Error(error.error || "发送消息失败");
  102. }
  103. }
  104. export interface MarkMessagesReadResult {
  105. message_ids: number[];
  106. unread_count: number;
  107. read_at?: string;
  108. }
  109. export async function markMessagesRead(
  110. conversationId: number,
  111. readerIsAgent: boolean
  112. ): Promise<MarkMessagesReadResult | null> {
  113. const res = await fetch(`${API_BASE_URL}/messages/read`, {
  114. method: "PUT",
  115. headers: { "Content-Type": "application/json" },
  116. body: JSON.stringify({
  117. conversation_id: conversationId,
  118. reader_is_agent: readerIsAgent,
  119. }),
  120. });
  121. if (!res.ok) {
  122. return null;
  123. }
  124. const data = await res.json();
  125. return {
  126. message_ids: Array.isArray(data.message_ids) ? data.message_ids : [],
  127. unread_count:
  128. typeof data.unread_count === "number" ? data.unread_count : 0,
  129. read_at: typeof data.read_at === "string" ? data.read_at : undefined,
  130. };
  131. }