customerService.ts
2.39 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
import { service as http } from "@/utils/request";
import { askQuestion, streamAnswer, createChat } from "@/api/chat";
import type { AxiosPromise } from "axios";
const CS_CHAT_KEY = "cs_chat_id";
function getToken(): string {
return localStorage.getItem("auth_token") || "";
}
function authHeaders(): { Authorization?: string } {
const t = getToken();
return t ? { Authorization: `Bearer ${t}` } : {};
}
/** 获取或创建客服专用会话 ID */
export async function getOrCreateCsChatId(): Promise<number> {
const cached = localStorage.getItem(CS_CHAT_KEY);
if (cached) return parseInt(cached, 10);
const res = await createChat({ title: "智能客服" });
const chatId = (res.data as any)?.data?.id ?? (res.data as any)?.id;
if (!chatId) throw new Error("创建客服会话失败");
localStorage.setItem(CS_CHAT_KEY, String(chatId));
return chatId;
}
/** 重置客服会话(清除缓存,下次会新建) */
export function resetCsChat(): void {
localStorage.removeItem(CS_CHAT_KEY);
}
interface CsAskResult {
chatId: number;
questionId: string;
}
/** 发送客服问题,返回 chatId + questionId 用于后续流式订阅 */
export async function csAsk(
content: string,
chatId?: number,
): Promise<CsAskResult> {
const resolvedChatId = chatId ?? (await getOrCreateCsChatId());
const res = await askQuestion({
chatId: resolvedChatId,
questionContent: content,
});
const data = (res.data as any)?.data ?? res.data;
const questionId: string = data?.questionId ?? data?.externalQuestionId ?? "";
return { chatId: resolvedChatId, questionId };
}
interface CsStreamOptions {
chatId: number;
questionId: string;
onChunk: (text: string) => void;
onDone: () => void;
onError: (err: any) => void;
signal?: AbortSignal;
}
/** 订阅客服流式回答 */
export function csStream({
chatId,
questionId,
onChunk,
onDone,
onError,
signal,
}: CsStreamOptions): { close: () => void } {
return streamAnswer({
chatId,
questionId,
onMessage: (payload) => {
if (typeof payload === "string") {
onChunk(payload);
} else if (payload && typeof payload === "object") {
const p = payload as any;
const text =
p?.choices?.[0]?.delta?.content ??
p?.delta?.content ??
p?.content ??
"";
if (text) onChunk(text);
}
},
onEnd: onDone,
onError,
signal,
});
}