Skip to content

Commit

Permalink
Feature/zhouj/web UI chat trial (#1217)
Browse files Browse the repository at this point in the history
  • Loading branch information
zhoujie16 authored Jan 11, 2025
1 parent 9ec3c14 commit 81bd77b
Show file tree
Hide file tree
Showing 26 changed files with 1,541 additions and 14 deletions.
7 changes: 7 additions & 0 deletions ui/config/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,13 @@ export default [
icon: 'DashboardOutlined',
component: './ClusterCpods',
},
{
path: '/chat-trial',
name: 'ChatTrial',
component: './ChatTrial',
layout: false,
},

{
path: '*',
layout: false,
Expand Down
11 changes: 10 additions & 1 deletion ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,9 @@
"classnames": "^2.5.1",
"dayjs": "^1.11.10",
"jsencrypt": "^3.3.2",
"localforage": "^1.10.0",
"lodash": "^4.17.21",
"mermaid": "^11.4.1",
"moment": "^2.30.1",
"omit.js": "^2.0.2",
"querystring": "^0.2.1",
Expand All @@ -63,8 +65,15 @@
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-helmet-async": "^1.3.0",
"react-markdown": "^9.0.3",
"react-syntax-highlighter": "^15.6.1",
"swr": "^2.2.5"
"rehype-highlight": "^7.0.1",
"rehype-katex": "^7.0.1",
"remark-breaks": "^4.0.0",
"remark-gfm": "^4.0.0",
"remark-math": "^6.0.0",
"swr": "^2.2.5",
"use-debounce": "^10.0.4"
},
"devDependencies": {
"@ant-design/pro-cli": "^3.3.0",
Expand Down
172 changes: 172 additions & 0 deletions ui/src/models/chat-h5-model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
import {
cahtActionH5_ModalType,
generateUUID,
scrollH5ChatBodyToBottom,
} from '@/pages/ChatTrial/utils';
import storage from '@/pages/ChatTrial/utils/store';
import { useEffect, useState } from 'react';

export const chat_store_key = 'Chat_Store_H5_Model';

export interface IChatItemMsg {
content: string;
role: 'user' | 'assistant';
id: string;
date: string;
source_documents?: any[];
show_images?: any[];
raw?: any;
}
export interface IChatItem {
id: string;
state: 'success' | 'loading';
messages: IChatItemMsg[];
}

export interface IChatStore {
[key: string]: IChatItem;
}

export interface IKnowledgeListItem {
kb_id: string;
kb_name: string;
}

const testChatStore: IChatStore = {
demo: {
id: 'demo',
state: 'success',
messages: [],
},
};

export default () => {
// 管理 chat 数据
const [chatModel, setChatModel] = useState<any>('');
const [chatStore, setChatStore] = useState<IChatStore>(testChatStore);
const [activeChat, setActiveChat] = useState('demo');
// console.log('chatStore', chatStore);
useEffect(() => {
const init = async () => {
const _chatStoreJson: any = await storage.getItem(chat_store_key);
if (_chatStoreJson) {
setChatStore(_chatStoreJson);
setActiveChat(Object.keys(_chatStoreJson)[0]);
}
};
init();
}, []);

useEffect(() => {
// storage.setItem(chat_store_key, chatStore);
}, [chatStore]);

// 新增聊天数据
const addChatMsg = (id: string, msg: IChatItemMsg) => {
setChatStore((chatStore: any) => {
const _chatStore = JSON.parse(JSON.stringify(chatStore));
_chatStore[id].messages.push(msg);
setTimeout(() => {
scrollH5ChatBodyToBottom(id, true);
}, 100);
return _chatStore;
});
};

/**
* 更新聊天数据
* @param id chatid
* @param chatMsgItem
*/
const updateChatMsg = (id: string, chatMsgItem: IChatItemMsg) => {
setChatStore((chatStore: any) => {
const _chatStore = JSON.parse(JSON.stringify(chatStore));
const chatItem = _chatStore[id];
const index = chatItem.messages.findIndex((x: any) => x.id === chatMsgItem.id);
chatItem.messages[index] = chatMsgItem;
return _chatStore;
});
setTimeout(() => {
scrollH5ChatBodyToBottom(id, true);
}, 100);
};

/**
* 设置聊天状态
* @param id
* @param state
*/
const setChatItemState = (id: string, state: string) => {
setChatStore((chatStore: any) => {
const _chatStore = JSON.parse(JSON.stringify(chatStore));
_chatStore[id].state = state;
return _chatStore;
});
};

/**
* 清空聊天
*/
const deleteChatStore = (id: string) => {
setChatStore((chatStore: any) => {
const _chatStore = JSON.parse(JSON.stringify(chatStore));
_chatStore[id].messages = [];
return _chatStore;
});
};

const questionAction = ({ chatid, userMsgValue }: { chatid: string; userMsgValue: string }) => {
const chatMsgItemUser: IChatItemMsg = {
content: userMsgValue,
role: 'user',
date: '',
id: generateUUID(),
};
addChatMsg(chatid, chatMsgItemUser);
setChatItemState(chatid, 'loading');
const msgId = generateUUID();
const chatMsgItem: IChatItemMsg = {
content: '正在搜索...',
role: 'assistant',
id: msgId,
date: '',
};
addChatMsg(chatid, chatMsgItem);
cahtActionH5_ModalType({
id: msgId,
question: userMsgValue,
onMessage: (chatMsgItem: IChatItemMsg) => {
updateChatMsg(chatid, chatMsgItem);
},
onSuccess: (chatMsgItem: IChatItemMsg) => {
updateChatMsg(chatid, chatMsgItem);
setChatItemState(chatid, 'success');
},
});
};

const reQuestionAction = (chatMsgItem: IChatItemMsg) => {
console.log('reQuestionAction', chatMsgItem);
for (const key in chatStore) {
for (let index = 0; index < chatStore[key].messages.length; index++) {
const _chatMsgItem = chatStore[key].messages[index];
if (_chatMsgItem.id === chatMsgItem.id) {
questionAction({ chatid: key, userMsgValue: chatStore[key].messages[index - 1].content });
return;
}
}
}
};

return {
chatStore,
addChatMsg,
updateChatMsg,
deleteChatStore,
setChatItemState,
questionAction,
reQuestionAction,
activeChat,
setChatModel,
};
};
10 changes: 10 additions & 0 deletions ui/src/pages/ChatTrial/ChatContainer/index.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
.messageContainer {
max-width: 760px;
height: calc(100vh - 90px);
padding: 20px 16px 0 16px;
overflow-y: auto;
margin: auto;
&::-webkit-scrollbar {
display: none;
}
}
35 changes: 35 additions & 0 deletions ui/src/pages/ChatTrial/ChatContainer/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { IChatItemMsg } from '@/models/chat-h5-model';
import { useModel } from '@umijs/max';
import React from 'react';
import styles from './index.less';
import MessageItem from '../MessageItem';

const Index: React.FC = () => {
const { chatStore, activeChat } = useModel('chat-h5-model');
const chatListItem = chatStore[activeChat];
return (
<>
<div>
<div className={styles.messageContainer} id="chat-container-h5">
<div style={{ textAlign: 'center', marginBottom: 20 }}>
{/* <img style={{ width: 200 }} src={coverImg}></img> */}
</div>
<MessageItem
messageItem={{
content: '您好,您有相关的问题都可以在这里向我提问。',
role: 'assistant',
id: 'demo-welcome',
}}
/>
{chatListItem.messages?.map((x: IChatItemMsg) => (
<>
<MessageItem messageItem={x} />
</>
))}
</div>
</div>
</>
);
};

export default Index;
Loading

0 comments on commit 81bd77b

Please sign in to comment.