conversationApi.ts 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. import { API_BASE_URL } from "@/lib/config";
  2. import {
  3. ConversationDetail,
  4. ConversationSummary,
  5. } from "../types";
  6. export type ConversationListType = "visitor" | "internal";
  7. export async function fetchConversations(
  8. userId?: number,
  9. opts?: { type?: ConversationListType }
  10. ): Promise<ConversationSummary[]> {
  11. const params = new URLSearchParams();
  12. if (userId) params.set("user_id", String(userId));
  13. if (opts?.type) params.set("type", opts.type);
  14. const url = `${API_BASE_URL}/conversations?${params.toString()}`;
  15. const res = await fetch(url, { cache: "no-store" });
  16. if (!res.ok) {
  17. throw new Error("获取对话列表失败");
  18. }
  19. const data = await res.json();
  20. if (!Array.isArray(data)) {
  21. return [];
  22. }
  23. return data.map((item) => ({
  24. ...item,
  25. unread_count: item.unread_count ?? 0,
  26. has_participated: item.has_participated ?? false,
  27. }));
  28. }
  29. /** 创建一条内部对话(知识库测试),返回新对话 ID */
  30. export async function initInternalConversation(userId: number): Promise<{ conversation_id: number }> {
  31. const res = await fetch(`${API_BASE_URL}/conversations/internal?user_id=${userId}`, {
  32. method: "POST",
  33. headers: { "Content-Type": "application/json" },
  34. });
  35. if (!res.ok) {
  36. const err = await res.json().catch(() => ({}));
  37. throw new Error((err as { error?: string }).error || "创建内部对话失败");
  38. }
  39. const data = await res.json();
  40. return { conversation_id: data.conversation_id };
  41. }
  42. export async function searchConversations(
  43. query: string,
  44. userId?: number
  45. ): Promise<ConversationSummary[]> {
  46. const url = userId
  47. ? `${API_BASE_URL}/conversations/search?q=${encodeURIComponent(query)}&user_id=${userId}`
  48. : `${API_BASE_URL}/conversations/search?q=${encodeURIComponent(query)}`;
  49. const res = await fetch(url, {
  50. cache: "no-store",
  51. });
  52. if (!res.ok) {
  53. throw new Error("搜索对话失败");
  54. }
  55. const data = await res.json();
  56. if (!Array.isArray(data)) {
  57. return [];
  58. }
  59. return data.map((item) => ({
  60. ...item,
  61. unread_count: item.unread_count ?? 0,
  62. has_participated: item.has_participated ?? false,
  63. }));
  64. }
  65. export async function fetchConversationDetail(
  66. conversationId: number,
  67. userId?: number
  68. ): Promise<ConversationDetail | null> {
  69. const url = userId
  70. ? `${API_BASE_URL}/conversations/${conversationId}?user_id=${userId}`
  71. : `${API_BASE_URL}/conversations/${conversationId}`;
  72. const res = await fetch(url, { cache: "no-store" });
  73. if (!res.ok) {
  74. return null;
  75. }
  76. const data = await res.json();
  77. return {
  78. ...data,
  79. unread_count: data.unread_count ?? 0,
  80. };
  81. }
  82. export interface UpdateConversationContactPayload {
  83. email?: string;
  84. phone?: string;
  85. notes?: string;
  86. }
  87. export interface UpdateConversationContactResult {
  88. email: string;
  89. phone: string;
  90. notes: string;
  91. }
  92. export async function updateConversationContact(
  93. conversationId: number,
  94. payload: UpdateConversationContactPayload
  95. ): Promise<UpdateConversationContactResult> {
  96. const res = await fetch(
  97. `${API_BASE_URL}/conversations/${conversationId}/contact`,
  98. {
  99. method: "PUT",
  100. headers: { "Content-Type": "application/json" },
  101. body: JSON.stringify(payload),
  102. }
  103. );
  104. if (!res.ok) {
  105. throw new Error("更新访客联系信息失败");
  106. }
  107. const data = await res.json();
  108. return {
  109. email: data.email ?? "",
  110. phone: data.phone ?? "",
  111. notes: data.notes ?? "",
  112. };
  113. }