|
@@ -42,8 +42,6 @@ type ChatProps = {
|
|
app_name: string;
|
|
app_name: string;
|
|
// 会话id 后续会话带入
|
|
// 会话id 后续会话带入
|
|
conversation_id?: string;
|
|
conversation_id?: string;
|
|
- // 开始流式传输内容
|
|
|
|
- onStart?: (data?: ResponseMessageItem) => void;
|
|
|
|
// 成功获取会话内容
|
|
// 成功获取会话内容
|
|
onSuccess?: (data: ResponseMessageItem) => void;
|
|
onSuccess?: (data: ResponseMessageItem) => void;
|
|
// 更新流式消息内容
|
|
// 更新流式消息内容
|
|
@@ -52,13 +50,45 @@ type ChatProps = {
|
|
onError?: (error: Error) => void;
|
|
onError?: (error: Error) => void;
|
|
};
|
|
};
|
|
|
|
|
|
|
|
+/**
|
|
|
|
+ * 获取日期格式化分组
|
|
|
|
+ * @param dateVal 日期
|
|
|
|
+ * @returns
|
|
|
|
+ */
|
|
|
|
+export function getDateGroupString(dateVal: Date | string): string {
|
|
|
|
+ const normalizeDate = (date: Date | string): Date => {
|
|
|
|
+ const d = new Date(date);
|
|
|
|
+ d.setHours(0, 0, 0, 0);
|
|
|
|
+ return d;
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ const now = normalizeDate(new Date()); // 当前日期归一化
|
|
|
|
+
|
|
|
|
+ const itemDate = normalizeDate(new Date(dateVal));
|
|
|
|
+ const diffTime = now.getTime() - itemDate.getTime();
|
|
|
|
+ const diffDays = Math.floor(diffTime / (1000 * 3600 * 24));
|
|
|
|
+
|
|
|
|
+ if (diffDays === 0) {
|
|
|
|
+ return "今日";
|
|
|
|
+ } else if (diffDays === 1) {
|
|
|
|
+ return "昨日";
|
|
|
|
+ } else if (diffDays <= 6) {
|
|
|
|
+ return "7日内";
|
|
|
|
+ } else if (diffDays <= 29) {
|
|
|
|
+ return "30日内";
|
|
|
|
+ } else {
|
|
|
|
+ return "更久~";
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
const defaultConversation = {
|
|
const defaultConversation = {
|
|
// 会话id
|
|
// 会话id
|
|
key: "1",
|
|
key: "1",
|
|
label: "新的对话",
|
|
label: "新的对话",
|
|
|
|
+ group: '今日'
|
|
};
|
|
};
|
|
|
|
|
|
-export function useChat({ app_name, onStart, onSuccess, onUpdate, onError }: ChatProps) {
|
|
|
|
|
|
+export function useChat({ app_name, onSuccess, onUpdate, onError }: ChatProps) {
|
|
/**
|
|
/**
|
|
* 发送消息加载状态
|
|
* 发送消息加载状态
|
|
*/
|
|
*/
|
|
@@ -93,39 +123,73 @@ export function useChat({ app_name, onStart, onSuccess, onUpdate, onError }: Cha
|
|
// 当前智能体对象
|
|
// 当前智能体对象
|
|
const [currentAgent, setCurrentAgent] = useSessionStorageState("agent-map");
|
|
const [currentAgent, setCurrentAgent] = useSessionStorageState("agent-map");
|
|
|
|
|
|
- useEffect(() => {
|
|
|
|
|
|
+ // 有更多对话
|
|
|
|
+ const [hasMoreConversation, setHasMoreConversation] = useState(false);
|
|
|
|
+
|
|
|
|
+ // 会话分页
|
|
|
|
+ const [pageIndex, setPageIndex] = useState(1);
|
|
|
|
+
|
|
|
|
+ const getSession = (page: number) => {
|
|
setLoadingSession(true);
|
|
setLoadingSession(true);
|
|
GetSessionList({
|
|
GetSessionList({
|
|
app_name,
|
|
app_name,
|
|
- page_index: 1,
|
|
|
|
|
|
+ page_index: page,
|
|
})
|
|
})
|
|
.then((res) => {
|
|
.then((res) => {
|
|
- setConversationList([
|
|
|
|
- { ...defaultConversation },
|
|
|
|
- ...(res?.result?.model || []).map((item: any) => ({
|
|
|
|
- ...item,
|
|
|
|
- key: item.sessionId,
|
|
|
|
- label: item.name,
|
|
|
|
- })),
|
|
|
|
- ]);
|
|
|
|
|
|
+ if(page === 1) {
|
|
|
|
+ setConversationList([
|
|
|
|
+ { ...defaultConversation },
|
|
|
|
+ ...(res?.result?.model || []).map((item: any) => ({
|
|
|
|
+ ...item,
|
|
|
|
+ key: item.sessionId,
|
|
|
|
+ label: item.name,
|
|
|
|
+ group: getDateGroupString(item.updateTime)
|
|
|
|
+ })),
|
|
|
|
+ ]);
|
|
|
|
+ } else {
|
|
|
|
+ setConversationList([
|
|
|
|
+ ...(conversationList || []),
|
|
|
|
+ ...(res?.result?.model || []).map((item: any) => ({
|
|
|
|
+ ...item,
|
|
|
|
+ key: item.sessionId,
|
|
|
|
+ label: item.name,
|
|
|
|
+ group: getDateGroupString(item.updateTime)
|
|
|
|
+ })),
|
|
|
|
+ ]);
|
|
|
|
+ }
|
|
|
|
+ setHasMoreConversation(res?.result.totalPages > page);
|
|
})
|
|
})
|
|
.finally(() => {
|
|
.finally(() => {
|
|
setLoadingSession(false);
|
|
setLoadingSession(false);
|
|
});
|
|
});
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 切换app时获取会话记录
|
|
|
|
+ useEffect(() => {
|
|
|
|
+ setPageIndex(1);
|
|
|
|
+ getSession(1);
|
|
}, [app_name]);
|
|
}, [app_name]);
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ * 加载更多会话
|
|
|
|
+ */
|
|
|
|
+ const loadMoreConversation = () => {
|
|
|
|
+ getSession(pageIndex + 1);
|
|
|
|
+ setPageIndex(pageIndex + 1);
|
|
|
|
+ };
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* 切换会话
|
|
* 切换会话
|
|
* @param key 会话id
|
|
* @param key 会话id
|
|
* @returns
|
|
* @returns
|
|
*/
|
|
*/
|
|
const changeConversation = async (key: string) => {
|
|
const changeConversation = async (key: string) => {
|
|
- cancel();
|
|
|
|
setActiveConversation(key);
|
|
setActiveConversation(key);
|
|
if (key === "1") {
|
|
if (key === "1") {
|
|
setMessages([]);
|
|
setMessages([]);
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
+ cancel();
|
|
setLoadingMessages(true);
|
|
setLoadingMessages(true);
|
|
// 获取会话内容
|
|
// 获取会话内容
|
|
try {
|
|
try {
|
|
@@ -158,27 +222,22 @@ export function useChat({ app_name, onStart, onSuccess, onUpdate, onError }: Cha
|
|
}
|
|
}
|
|
};
|
|
};
|
|
|
|
|
|
- const baseUrl = process.env.NODE_ENV === "production" ? "" : "/api";
|
|
|
|
-
|
|
|
|
/**
|
|
/**
|
|
* 封装智能体
|
|
* 封装智能体
|
|
*/
|
|
*/
|
|
const [agent] = useXAgent<ResponseMessageItem>({
|
|
const [agent] = useXAgent<ResponseMessageItem>({
|
|
request: async (message, { onError, onSuccess, onUpdate }) => {
|
|
request: async (message, { onError, onSuccess, onUpdate }) => {
|
|
- const enterpriseCode = sessionStorage.getItem("enterpriseCode");
|
|
|
|
- const token = localStorage.getItem("token_" + enterpriseCode) || '';
|
|
|
|
-
|
|
|
|
abortController.current = new AbortController();
|
|
abortController.current = new AbortController();
|
|
const signal = abortController.current.signal;
|
|
const signal = abortController.current.signal;
|
|
try {
|
|
try {
|
|
setLoading(true);
|
|
setLoading(true);
|
|
const response = await fetch(
|
|
const response = await fetch(
|
|
- baseUrl + "/api/ai/chat-message",
|
|
|
|
|
|
+ "https://design.shalu.com/api/ai/chat-message",
|
|
{
|
|
{
|
|
method: "POST",
|
|
method: "POST",
|
|
body: JSON.stringify(message),
|
|
body: JSON.stringify(message),
|
|
headers: {
|
|
headers: {
|
|
- Authorization: token,
|
|
|
|
|
|
+ Authorization: localStorage.getItem("token_a") || "",
|
|
"Content-Type": "application/json",
|
|
"Content-Type": "application/json",
|
|
},
|
|
},
|
|
signal,
|
|
signal,
|
|
@@ -196,13 +255,13 @@ export function useChat({ app_name, onStart, onSuccess, onUpdate, onError }: Cha
|
|
onUpdate(data);
|
|
onUpdate(data);
|
|
} else if (data?.event === "message_end") {
|
|
} else if (data?.event === "message_end") {
|
|
onSuccess(data);
|
|
onSuccess(data);
|
|
|
|
+ } else if (data?.event === "message_error") {
|
|
|
|
+ onError(data);
|
|
} else if (data?.event === "ping") {
|
|
} else if (data?.event === "ping") {
|
|
console.log(">>>> stream start <<<<");
|
|
console.log(">>>> stream start <<<<");
|
|
- onStart?.(data);
|
|
|
|
} else {
|
|
} else {
|
|
console.log(">>>> stream error <<<<");
|
|
console.log(">>>> stream error <<<<");
|
|
- console.log(data);
|
|
|
|
- onError(data?.message || "请求失败");
|
|
|
|
|
|
+ onError(Error(data?.message || '请求失败'));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -231,12 +290,8 @@ export function useChat({ app_name, onStart, onSuccess, onUpdate, onError }: Cha
|
|
* 发起请求
|
|
* 发起请求
|
|
* @param chat_query 对话内容
|
|
* @param chat_query 对话内容
|
|
*/
|
|
*/
|
|
- const onRequest = (chat_query: string, callbacks?: {
|
|
|
|
- onUpdate: (message: ResponseMessageItem) => void;
|
|
|
|
- onSuccess: (message: ResponseMessageItem) => void;
|
|
|
|
- onError: (error: Error) => void;
|
|
|
|
- }, name?: string) => {
|
|
|
|
- setConversationList((list) => {
|
|
|
|
|
|
+ const onRequest = (chat_query: string) => {
|
|
|
|
+ activeConversation === '1' && setConversationList((list) => {
|
|
return list?.map((item) => {
|
|
return list?.map((item) => {
|
|
return {
|
|
return {
|
|
...item,
|
|
...item,
|
|
@@ -248,11 +303,11 @@ export function useChat({ app_name, onStart, onSuccess, onUpdate, onError }: Cha
|
|
{
|
|
{
|
|
app_name,
|
|
app_name,
|
|
chat_query,
|
|
chat_query,
|
|
- chat_name: activeConversation === "1" ? name || chat_query : undefined,
|
|
|
|
|
|
+ chat_name: activeConversation === "1" ? chat_query : undefined,
|
|
conversation_id:
|
|
conversation_id:
|
|
activeConversation === "1" ? undefined : activeConversation,
|
|
activeConversation === "1" ? undefined : activeConversation,
|
|
},
|
|
},
|
|
- callbacks ?? {
|
|
|
|
|
|
+ {
|
|
onSuccess: (data) => {
|
|
onSuccess: (data) => {
|
|
onSuccess?.(data);
|
|
onSuccess?.(data);
|
|
},
|
|
},
|
|
@@ -285,6 +340,7 @@ export function useChat({ app_name, onStart, onSuccess, onUpdate, onError }: Cha
|
|
*/
|
|
*/
|
|
const cancel = () => {
|
|
const cancel = () => {
|
|
abortController.current?.abort();
|
|
abortController.current?.abort();
|
|
|
|
+ setLoading(false);
|
|
};
|
|
};
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -305,6 +361,14 @@ export function useChat({ app_name, onStart, onSuccess, onUpdate, onError }: Cha
|
|
}
|
|
}
|
|
};
|
|
};
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ * 更新会话列表
|
|
|
|
+ */
|
|
|
|
+ const refreshConversationList = () => {
|
|
|
|
+ setPageIndex(1);
|
|
|
|
+ getSession(1);
|
|
|
|
+ };
|
|
|
|
+
|
|
return {
|
|
return {
|
|
agent,
|
|
agent,
|
|
loading,
|
|
loading,
|
|
@@ -320,5 +384,8 @@ export function useChat({ app_name, onStart, onSuccess, onUpdate, onError }: Cha
|
|
onRequest,
|
|
onRequest,
|
|
addConversation,
|
|
addConversation,
|
|
changeConversation,
|
|
changeConversation,
|
|
|
|
+ loadMoreConversation,
|
|
|
|
+ hasMoreConversation,
|
|
|
|
+ refreshConversationList
|
|
};
|
|
};
|
|
}
|
|
}
|