|
|
@@ -108,12 +108,10 @@ import { prettyObject } from "../utils/format";
|
|
|
import { ExportMessageModal } from "./exporter";
|
|
|
import { getClientConfig } from "../config/client";
|
|
|
import { useAllModels } from "../utils/hooks";
|
|
|
-import { MultimodalContent } from "../client/api";
|
|
|
import { Select } from 'antd';
|
|
|
+import { RightOutlined } from '@ant-design/icons';
|
|
|
import api from "@/app/api/api";
|
|
|
|
|
|
-const { Option } = Select;
|
|
|
-
|
|
|
const Markdown = dynamic(async () => (await import("./markdown")).Markdown, {
|
|
|
loading: () => <LoadingIcon />,
|
|
|
});
|
|
|
@@ -912,8 +910,15 @@ function _Chat() {
|
|
|
const [appList, setAppList] = useState<AppList>([]);
|
|
|
const [appValue, setAppValue] = useState<string>();
|
|
|
const globalStore = useGlobalStore();
|
|
|
+ type QuestionList = any[];
|
|
|
+ const [questionList, setQuestionList] = useState<QuestionList>([]);
|
|
|
|
|
|
- const init = async () => {
|
|
|
+ useEffect(() => {
|
|
|
+ console.log(questionList, 'questionList');
|
|
|
+ }, [questionList]);
|
|
|
+
|
|
|
+ // 获取应用列表
|
|
|
+ const fetchApplicationList = async () => {
|
|
|
setLoading(true);
|
|
|
try {
|
|
|
const res = await api.get('/bigmodel/api/application/list');
|
|
|
@@ -936,6 +941,22 @@ function _Chat() {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ const fetchDefaultQuestion = async () => {
|
|
|
+ try {
|
|
|
+ const res = await api.get('/bigmodel/api/presets');
|
|
|
+ setQuestionList(res.data);
|
|
|
+ } catch (error) {
|
|
|
+ console.error(error);
|
|
|
+ } finally {
|
|
|
+ setLoading(false);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const init = async () => {
|
|
|
+ await fetchApplicationList();
|
|
|
+ await fetchDefaultQuestion();
|
|
|
+ }
|
|
|
+
|
|
|
useEffect(() => {
|
|
|
init();
|
|
|
}, [])
|
|
|
@@ -1432,6 +1453,14 @@ function _Chat() {
|
|
|
setAttachImages(images);
|
|
|
}
|
|
|
|
|
|
+ const getAppName = () => {
|
|
|
+ const item = appList.find(item => item.value === appValue);
|
|
|
+ if (!item) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ return item.label;
|
|
|
+ }
|
|
|
+
|
|
|
return (
|
|
|
<div className={styles.chat} key={session.id}>
|
|
|
<div className="window-header" data-tauri-drag-region>
|
|
|
@@ -1537,7 +1566,6 @@ function _Chat() {
|
|
|
setShowModal={setShowPromptModal}
|
|
|
/> */}
|
|
|
</div>
|
|
|
-
|
|
|
<div
|
|
|
className={styles["chat-body"]}
|
|
|
ref={scrollRef}
|
|
|
@@ -1548,28 +1576,31 @@ function _Chat() {
|
|
|
setAutoScroll(false);
|
|
|
}}
|
|
|
>
|
|
|
- {messages.map((message, i) => {
|
|
|
- const isUser = message.role === "user";
|
|
|
- const isContext = i < context.length;
|
|
|
- const showActions =
|
|
|
- i > 0 &&
|
|
|
- !(message.preview || message.content.length === 0) &&
|
|
|
- !isContext;
|
|
|
- const showTyping = message.preview || message.streaming;
|
|
|
-
|
|
|
- const shouldShowClearContextDivider = i === clearContextIndex - 1;
|
|
|
-
|
|
|
- return (
|
|
|
- <Fragment key={message.id}>
|
|
|
- <div
|
|
|
- className={
|
|
|
- isUser ? styles["chat-message-user"] : styles["chat-message"]
|
|
|
- }
|
|
|
- >
|
|
|
- <div className={styles["chat-message-container"]}>
|
|
|
- <div className={styles["chat-message-header"]}>
|
|
|
- <div className={styles["chat-message-avatar"]}>
|
|
|
- {/* <div className={styles["chat-message-edit"]}>
|
|
|
+ {
|
|
|
+ messages.length > 1 ?
|
|
|
+ <>
|
|
|
+ {messages.map((message, i) => {
|
|
|
+ const isUser = message.role === "user";
|
|
|
+ const isContext = i < context.length;
|
|
|
+ const showActions =
|
|
|
+ i > 0 &&
|
|
|
+ !(message.preview || message.content.length === 0) &&
|
|
|
+ !isContext;
|
|
|
+ const showTyping = message.preview || message.streaming;
|
|
|
+
|
|
|
+ const shouldShowClearContextDivider = i === clearContextIndex - 1;
|
|
|
+
|
|
|
+ return (
|
|
|
+ <Fragment key={message.id}>
|
|
|
+ <div
|
|
|
+ className={
|
|
|
+ isUser ? styles["chat-message-user"] : styles["chat-message"]
|
|
|
+ }
|
|
|
+ >
|
|
|
+ <div className={styles["chat-message-container"]}>
|
|
|
+ <div className={styles["chat-message-header"]}>
|
|
|
+ <div className={styles["chat-message-avatar"]}>
|
|
|
+ {/* <div className={styles["chat-message-edit"]}>
|
|
|
<IconButton
|
|
|
icon={<EditIcon />}
|
|
|
aria={Locale.Chat.Actions.Edit}
|
|
|
@@ -1604,51 +1635,51 @@ function _Chat() {
|
|
|
}}
|
|
|
></IconButton>
|
|
|
</div> */}
|
|
|
- {isUser ? (
|
|
|
- // 在这里换头像
|
|
|
- <div style={{ position: 'relative' }}>
|
|
|
- {/* <MaskAvatar */}
|
|
|
- {/* avatar={session.mask.avatar} */}
|
|
|
- {/* /> */}
|
|
|
- {/* <div */}
|
|
|
- {/* style={{ */}
|
|
|
- {/* position: 'absolute', */}
|
|
|
- {/* zIndex: 2, */}
|
|
|
- {/* top: '50%', */}
|
|
|
- {/* left: '50%', */}
|
|
|
- {/* transform: ' translate(-50%, -50%)', */}
|
|
|
- {/* fontSize: 14, */}
|
|
|
- {/* }}> */}
|
|
|
- {/* 我 */}
|
|
|
- {/* </div> */}
|
|
|
- <div
|
|
|
- style={{
|
|
|
- position: 'absolute',
|
|
|
- zIndex: 2,
|
|
|
- top: '50%',
|
|
|
- left: '50%',
|
|
|
- transform: ' translate(-110%, -100%)',
|
|
|
- fontSize: 14,
|
|
|
- }}>
|
|
|
- 我
|
|
|
+ {isUser ? (
|
|
|
+ // 在这里换头像
|
|
|
+ <div style={{ position: 'relative' }}>
|
|
|
+ {/* <MaskAvatar */}
|
|
|
+ {/* avatar={session.mask.avatar} */}
|
|
|
+ {/* /> */}
|
|
|
+ {/* <div */}
|
|
|
+ {/* style={{ */}
|
|
|
+ {/* position: 'absolute', */}
|
|
|
+ {/* zIndex: 2, */}
|
|
|
+ {/* top: '50%', */}
|
|
|
+ {/* left: '50%', */}
|
|
|
+ {/* transform: ' translate(-50%, -50%)', */}
|
|
|
+ {/* fontSize: 14, */}
|
|
|
+ {/* }}> */}
|
|
|
+ {/* 我 */}
|
|
|
+ {/* </div> */}
|
|
|
+ <div
|
|
|
+ style={{
|
|
|
+ position: 'absolute',
|
|
|
+ zIndex: 2,
|
|
|
+ top: '50%',
|
|
|
+ left: '50%',
|
|
|
+ transform: ' translate(-110%, -100%)',
|
|
|
+ fontSize: 14,
|
|
|
+ }}>
|
|
|
+ 我
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ ) : (
|
|
|
+ <>
|
|
|
+ {["system"].includes(message.role) ? (
|
|
|
+ <Avatar avatar="2699-fe0f" />
|
|
|
+ ) : (
|
|
|
+ <MaskAvatar
|
|
|
+ avatar={session.mask.avatar}
|
|
|
+ model={
|
|
|
+ message.model || session.mask.modelConfig.model
|
|
|
+ }
|
|
|
+ />
|
|
|
+ )}
|
|
|
+ </>
|
|
|
+ )}
|
|
|
</div>
|
|
|
- </div>
|
|
|
- ) : (
|
|
|
- <>
|
|
|
- {["system"].includes(message.role) ? (
|
|
|
- <Avatar avatar="2699-fe0f" />
|
|
|
- ) : (
|
|
|
- <MaskAvatar
|
|
|
- avatar={session.mask.avatar}
|
|
|
- model={
|
|
|
- message.model || session.mask.modelConfig.model
|
|
|
- }
|
|
|
- />
|
|
|
- )}
|
|
|
- </>
|
|
|
- )}
|
|
|
- </div>
|
|
|
- {/* {showActions && (
|
|
|
+ {/* {showActions && (
|
|
|
<div className={styles["chat-message-actions"]}>
|
|
|
<div className={styles["chat-input-actions"]}>
|
|
|
{message.streaming ? (
|
|
|
@@ -1690,73 +1721,116 @@ function _Chat() {
|
|
|
</div>
|
|
|
</div>
|
|
|
)} */}
|
|
|
- </div>
|
|
|
- {showTyping && (
|
|
|
- <div className={styles["chat-message-status"]}>
|
|
|
- {Locale.Chat.Typing}
|
|
|
- </div>
|
|
|
- )}
|
|
|
- <div className={styles["chat-message-item"]}>
|
|
|
- <Markdown
|
|
|
- key={message.streaming ? "loading" : "done"}
|
|
|
- content={getMessageTextContent(message)}
|
|
|
- loading={
|
|
|
- (message.preview || message.streaming) &&
|
|
|
- message.content.length === 0 &&
|
|
|
- !isUser
|
|
|
- }
|
|
|
- // onContextMenu={(e) => onRightClick(e, message)}
|
|
|
- onDoubleClickCapture={() => {
|
|
|
- if (!isMobileScreen) return;
|
|
|
- setUserInput(getMessageTextContent(message));
|
|
|
- }}
|
|
|
- fontSize={fontSize}
|
|
|
- fontFamily={fontFamily}
|
|
|
- parentRef={scrollRef}
|
|
|
- defaultShow={i >= messages.length - 6}
|
|
|
- />
|
|
|
- {getMessageImages(message).length == 1 && (
|
|
|
- <img
|
|
|
- className={styles["chat-message-item-image"]}
|
|
|
- src={getMessageImages(message)[0]}
|
|
|
- alt=""
|
|
|
- />
|
|
|
- )}
|
|
|
- {getMessageImages(message).length > 1 && (
|
|
|
- <div
|
|
|
- className={styles["chat-message-item-images"]}
|
|
|
- style={
|
|
|
- {
|
|
|
- "--image-count": getMessageImages(message).length,
|
|
|
- } as React.CSSProperties
|
|
|
- }
|
|
|
- >
|
|
|
- {getMessageImages(message).map((image, index) => {
|
|
|
- return (
|
|
|
+ </div>
|
|
|
+ {showTyping && (
|
|
|
+ <div className={styles["chat-message-status"]}>
|
|
|
+ {Locale.Chat.Typing}
|
|
|
+ </div>
|
|
|
+ )}
|
|
|
+ <div className={styles["chat-message-item"]}>
|
|
|
+ <Markdown
|
|
|
+ key={message.streaming ? "loading" : "done"}
|
|
|
+ content={getMessageTextContent(message)}
|
|
|
+ loading={
|
|
|
+ (message.preview || message.streaming) &&
|
|
|
+ message.content.length === 0 &&
|
|
|
+ !isUser
|
|
|
+ }
|
|
|
+ // onContextMenu={(e) => onRightClick(e, message)}
|
|
|
+ onDoubleClickCapture={() => {
|
|
|
+ if (!isMobileScreen) return;
|
|
|
+ setUserInput(getMessageTextContent(message));
|
|
|
+ }}
|
|
|
+ fontSize={fontSize}
|
|
|
+ fontFamily={fontFamily}
|
|
|
+ parentRef={scrollRef}
|
|
|
+ defaultShow={i >= messages.length - 6}
|
|
|
+ />
|
|
|
+ {getMessageImages(message).length == 1 && (
|
|
|
<img
|
|
|
- className={
|
|
|
- styles["chat-message-item-image-multi"]
|
|
|
- }
|
|
|
- key={index}
|
|
|
- src={image}
|
|
|
+ className={styles["chat-message-item-image"]}
|
|
|
+ src={getMessageImages(message)[0]}
|
|
|
alt=""
|
|
|
/>
|
|
|
- );
|
|
|
- })}
|
|
|
- </div>
|
|
|
- )}
|
|
|
- </div>
|
|
|
- {/* <div className={styles["chat-message-action-date"]}>
|
|
|
+ )}
|
|
|
+ {getMessageImages(message).length > 1 && (
|
|
|
+ <div
|
|
|
+ className={styles["chat-message-item-images"]}
|
|
|
+ style={
|
|
|
+ {
|
|
|
+ "--image-count": getMessageImages(message).length,
|
|
|
+ } as React.CSSProperties
|
|
|
+ }
|
|
|
+ >
|
|
|
+ {getMessageImages(message).map((image, index) => {
|
|
|
+ return (
|
|
|
+ <img
|
|
|
+ className={
|
|
|
+ styles["chat-message-item-image-multi"]
|
|
|
+ }
|
|
|
+ key={index}
|
|
|
+ src={image}
|
|
|
+ alt=""
|
|
|
+ />
|
|
|
+ );
|
|
|
+ })}
|
|
|
+ </div>
|
|
|
+ )}
|
|
|
+ </div>
|
|
|
+ {/* <div className={styles["chat-message-action-date"]}>
|
|
|
{isContext
|
|
|
? Locale.Chat.IsContext
|
|
|
: message.date.toLocaleString()}
|
|
|
</div> */}
|
|
|
- </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ {shouldShowClearContextDivider && <ClearContextDivider />}
|
|
|
+ </Fragment>
|
|
|
+ );
|
|
|
+ })}
|
|
|
+ </>
|
|
|
+ :
|
|
|
+ <>
|
|
|
+ <div style={{ position: 'absolute', width: '800px', height: '550px', top: '0', left: '0', right: '0', bottom: '0', margin: 'auto' }}>
|
|
|
+ <h1 style={{ display: 'flex', justifyContent: 'center', alignItems: 'center' }}>
|
|
|
+ {getAppName()}
|
|
|
+ </h1>
|
|
|
+ <p style={{ display: 'flex', justifyContent: 'center', alignItems: 'center' }}>创建人: admin</p>
|
|
|
+ <p style={{ display: 'flex', justifyContent: 'center', alignItems: 'center' }}>
|
|
|
+ 您好,欢迎使用建科·小智使用知识库创建的
|
|
|
+ <span>
|
|
|
+ {getAppName()}
|
|
|
+ </span>
|
|
|
+ </p>
|
|
|
+ <p style={{ display: 'flex', justifyContent: 'center', alignItems: 'center' }}>如果需要问本企业相关的其他问题请点击左上角,选中切换的知识库问答应用使用</p>
|
|
|
+ <p>我猜您可能想问:</p>
|
|
|
+ {
|
|
|
+ questionList.map((item) => {
|
|
|
+ return (
|
|
|
+ <div style={{
|
|
|
+ padding: '10px',
|
|
|
+ marginBottom: '10px',
|
|
|
+ border: '1px solid #e6e8f1',
|
|
|
+ borderRadius: '10px',
|
|
|
+ fontSize: '16px',
|
|
|
+ display: 'flex',
|
|
|
+ justifyContent: 'space-between',
|
|
|
+ alignItems: 'center',
|
|
|
+ cursor: 'pointer'
|
|
|
+ }} onClick={() => {
|
|
|
+ setUserInput(item)
|
|
|
+ }}>
|
|
|
+ <div>
|
|
|
+ {item}
|
|
|
+ </div>
|
|
|
+ <RightOutlined />
|
|
|
+ </div>
|
|
|
+ )
|
|
|
+ })
|
|
|
+ }
|
|
|
</div>
|
|
|
- {shouldShowClearContextDivider && <ClearContextDivider />}
|
|
|
- </Fragment>
|
|
|
- );
|
|
|
- })}
|
|
|
+ </>
|
|
|
+ }
|
|
|
</div>
|
|
|
|
|
|
<div className={styles["chat-input-panel"]}>
|