|
@@ -17,9 +17,8 @@ import PersonalCard from "./components/personal-card";
|
|
|
import { useAgentStore } from "@/store/agentStore";
|
|
|
|
|
|
import { useLoadMore } from "@/utils/loadMore";
|
|
|
-import {
|
|
|
- getMessageHistories,
|
|
|
-} from "@/service/bot";
|
|
|
+import { getMessageHistories } from "@/service/bot";
|
|
|
+import { useAppStore } from "@/store/appStore";
|
|
|
|
|
|
// 类型谓词函数
|
|
|
function isRobotMessage(
|
|
@@ -29,103 +28,99 @@ function isRobotMessage(
|
|
|
}
|
|
|
|
|
|
export default function Index() {
|
|
|
- const router = useRouter()
|
|
|
- const {agentId} = router.params
|
|
|
-
|
|
|
- if(!agentId){
|
|
|
- return <View>没有相应的智能体</View>
|
|
|
- }
|
|
|
- const {fetchAgent} = useAgentStore()
|
|
|
- const agent = useAgentStore((state) => state.agent)
|
|
|
+ const router = useRouter();
|
|
|
+ const { agentId } = router.params;
|
|
|
|
|
|
+ if (!agentId) {
|
|
|
+ return <View>没有相应的智能体</View>;
|
|
|
+ }
|
|
|
+ const headerHeight = useAppStore((state) => state.headerHeight);
|
|
|
+ const { fetchAgent } = useAgentStore();
|
|
|
+ const agent = useAgentStore((state) => state.agent);
|
|
|
|
|
|
const [deepThink, setDeepThink] = useState(EAI_MODEL.DeepseekChat);
|
|
|
|
|
|
- const [histories, setHistories] = useState<(TMessage|TRobotMessage)[]>([]);
|
|
|
-
|
|
|
+ const [histories, setHistories] = useState<(TMessage | TRobotMessage)[]>([]);
|
|
|
+
|
|
|
const [keyboardHeight, setKeyboardHeight] = useState(0);
|
|
|
const [contentHeight, setContentHeight] = useState(0);
|
|
|
const [scrollViewHeight, setScrollViewHeight] = useState(0);
|
|
|
|
|
|
const scrollViewRef = useRef<any>(null);
|
|
|
- // const headerHeight = useAppStore((state) => state.headerHeight);
|
|
|
-
|
|
|
+
|
|
|
const messageList = useTextChat((state) => state.list);
|
|
|
- const { destroy, setScrollTop } = useTextChat();
|
|
|
+ const { destroy, setScrollTop, genSessionId } = useTextChat();
|
|
|
const scrollTop = useTextChat((state) => state.scrollTop);
|
|
|
|
|
|
const fetcher = async ([_url, nextId, page, pageSize]) => {
|
|
|
- if(!agent){
|
|
|
- return null
|
|
|
+ if (!agent) {
|
|
|
+ return null;
|
|
|
}
|
|
|
- const _nextId = nextId ? decodeURIComponent(nextId) : nextId
|
|
|
+ const _nextId = nextId ? decodeURIComponent(nextId) : nextId;
|
|
|
const res = await getMessageHistories({
|
|
|
agentId,
|
|
|
- startId: _nextId,
|
|
|
+ startId: _nextId,
|
|
|
pageSize,
|
|
|
});
|
|
|
return res.data;
|
|
|
};
|
|
|
const { data, loadMore, page } = useLoadMore<{
|
|
|
- data?: (TMessage|TRobotMessage)[]
|
|
|
- nextId?: string,
|
|
|
- totalCount?: number
|
|
|
+ data?: (TMessage | TRobotMessage)[];
|
|
|
+ nextId?: string;
|
|
|
+ totalCount?: number;
|
|
|
}>({
|
|
|
- url: '/blue-aiagent/api/v1/my/messeagehistories',
|
|
|
+ url: "/blue-aiagent/api/v1/my/messeagehistories",
|
|
|
fetcher,
|
|
|
});
|
|
|
-
|
|
|
+
|
|
|
const [showWelcome, setShowWelcome] = useState(!histories.length);
|
|
|
-
|
|
|
-
|
|
|
+
|
|
|
// 加载更多
|
|
|
const onScrollToUpper = () => {
|
|
|
- console.log('onscroll')
|
|
|
- loadMore()
|
|
|
+ console.log("onscroll");
|
|
|
+ loadMore();
|
|
|
};
|
|
|
|
|
|
-
|
|
|
- useEffect(()=> {
|
|
|
- agentId && fetchAgent(agentId)
|
|
|
- }, [agentId])
|
|
|
+ useEffect(() => {
|
|
|
+ agentId && fetchAgent(agentId);
|
|
|
+ }, [agentId]);
|
|
|
|
|
|
- useEffect(()=> {
|
|
|
- setShowWelcome(!histories.length)
|
|
|
- }, [histories])
|
|
|
+ useEffect(() => {
|
|
|
+ setShowWelcome(!histories.length);
|
|
|
+ }, [histories]);
|
|
|
|
|
|
useEffect(() => {
|
|
|
if (data?.data) {
|
|
|
setHistories([...data.data.reverse(), ...histories]);
|
|
|
- if(page === 1){
|
|
|
- setTimeout(()=> {
|
|
|
- setScrollTop()
|
|
|
- }, 300)
|
|
|
+ if (page === 1) {
|
|
|
+ setTimeout(() => {
|
|
|
+ setScrollTop();
|
|
|
+ }, 300);
|
|
|
}
|
|
|
}
|
|
|
}, [data, page]);
|
|
|
-
|
|
|
-
|
|
|
+
|
|
|
// 计算 marginTopOffset 偏移的距离
|
|
|
const marginTopOffset = (() => {
|
|
|
if (keyboardHeight <= 0) return 0;
|
|
|
// 如果内容超过滚动容器,取键盘弹起高度
|
|
|
- if(contentHeight > scrollViewHeight){
|
|
|
- return -(keyboardHeight)
|
|
|
+ if (contentHeight > scrollViewHeight) {
|
|
|
+ return -keyboardHeight;
|
|
|
}
|
|
|
// 如果内容+键盘弹起高度超过滚动容器, 则取其差值
|
|
|
- if( contentHeight + keyboardHeight > scrollViewHeight){
|
|
|
+ if (contentHeight + keyboardHeight > scrollViewHeight) {
|
|
|
// 内容+键盘弹起高度 - 滚动容器高度
|
|
|
- return -(contentHeight + keyboardHeight - scrollViewHeight)
|
|
|
+ return -(contentHeight + keyboardHeight - scrollViewHeight);
|
|
|
}
|
|
|
})();
|
|
|
-
|
|
|
+
|
|
|
useEffect(() => {
|
|
|
// 监听键盘高度变化
|
|
|
Taro.onKeyboardHeightChange((res) => {
|
|
|
- if(res.height <= 0){
|
|
|
+ if (res.height <= 0) {
|
|
|
return setKeyboardHeight(0);
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
setKeyboardHeight(res.height - 24);
|
|
|
});
|
|
|
|
|
@@ -140,22 +135,29 @@ export default function Index() {
|
|
|
if (scrollViewRef.current) {
|
|
|
const query = Taro.createSelectorQuery();
|
|
|
// 获取聊天内容高度
|
|
|
- query.select('#message-list').boundingClientRect((rect: any) => {
|
|
|
- if (rect) {
|
|
|
- setContentHeight(rect.height);
|
|
|
- }
|
|
|
- }).exec();
|
|
|
+ query
|
|
|
+ .select("#message-list")
|
|
|
+ .boundingClientRect((rect: any) => {
|
|
|
+ if (rect) {
|
|
|
+ setContentHeight(rect.height);
|
|
|
+ }
|
|
|
+ })
|
|
|
+ .exec();
|
|
|
// 获取滚动容器高度
|
|
|
- query.select('#scroll-view').boundingClientRect((rect: any) => {
|
|
|
- if (rect) {
|
|
|
- setScrollViewHeight(rect.height);
|
|
|
- }
|
|
|
- }).exec();
|
|
|
+ query
|
|
|
+ .select("#scroll-view")
|
|
|
+ .boundingClientRect((rect: any) => {
|
|
|
+ if (rect) {
|
|
|
+ setScrollViewHeight(rect.height);
|
|
|
+ }
|
|
|
+ })
|
|
|
+ .exec();
|
|
|
}
|
|
|
}, [messageList]);
|
|
|
|
|
|
-
|
|
|
-
|
|
|
+ useEffect(() => {
|
|
|
+ genSessionId();
|
|
|
+ }, []);
|
|
|
|
|
|
useUnload(() => {
|
|
|
destroy();
|
|
@@ -171,7 +173,10 @@ export default function Index() {
|
|
|
|
|
|
const renderNavLeft = () => {
|
|
|
return (
|
|
|
- <View className="flex items-center gap-8" onClick={()=>Taro.navigateBack()}>
|
|
|
+ <View
|
|
|
+ className="flex items-center gap-8"
|
|
|
+ onClick={() => Taro.navigateBack()}
|
|
|
+ >
|
|
|
<IconArrowLeft />
|
|
|
<View className={showWelcome ? "hidden" : "block"}>
|
|
|
<PersonalCard size="mini" />
|
|
@@ -180,10 +185,19 @@ export default function Index() {
|
|
|
);
|
|
|
};
|
|
|
|
|
|
+ // 自定义背景样式
|
|
|
+ const bgImageStyle = {
|
|
|
+ backgroundImage: `url(${agent?.avatarUrl})`,
|
|
|
+ };
|
|
|
+
|
|
|
return (
|
|
|
- <PageCustom>
|
|
|
- <NavBarNormal scrollFadeIn leftColumn={renderNavLeft}></NavBarNormal>
|
|
|
- <View className="flex flex-col w-full h-screen" style={{marginTop: `${marginTopOffset}px`}}>
|
|
|
+ <PageCustom fullPage style={{ overflow: "hidden" }}>
|
|
|
+ <NavBarNormal leftColumn={renderNavLeft}></NavBarNormal>
|
|
|
+ {(!!agent?.enabledChatBg) ? <View className={style.topBg} style={bgImageStyle}></View> : <></>}
|
|
|
+ <View
|
|
|
+ className="flex flex-col w-full h-screen relative z-10"
|
|
|
+ style={{ marginTop: `${marginTopOffset}px` }}
|
|
|
+ >
|
|
|
<ScrollView
|
|
|
ref={scrollViewRef}
|
|
|
scrollY
|
|
@@ -198,7 +212,6 @@ export default function Index() {
|
|
|
>
|
|
|
{showWelcome && <ChatWelcome />}
|
|
|
<View id="messageList" className="flex flex-col gap-8 px-18 pb-140">
|
|
|
-
|
|
|
{[...histories, ...messageList].map((message) => {
|
|
|
const robotMessage = isRobotMessage(message) ? message : null;
|
|
|
return (
|
|
@@ -208,6 +221,7 @@ export default function Index() {
|
|
|
agent={agent}
|
|
|
role={message.role}
|
|
|
text={message.content}
|
|
|
+ message={message}
|
|
|
></ChatMessage>
|
|
|
);
|
|
|
})}
|
|
@@ -230,12 +244,14 @@ export default function Index() {
|
|
|
>
|
|
|
深度思考(R1)
|
|
|
</View>
|
|
|
- {agent && <InputBar
|
|
|
- aiModel={deepThink}
|
|
|
- agent={agent}
|
|
|
- histories={histories}
|
|
|
- setShowWelcome={setShowWelcome}
|
|
|
- ></InputBar>}
|
|
|
+ {agent && (
|
|
|
+ <InputBar
|
|
|
+ aiModel={deepThink}
|
|
|
+ agent={agent}
|
|
|
+ histories={histories}
|
|
|
+ setShowWelcome={setShowWelcome}
|
|
|
+ ></InputBar>
|
|
|
+ )}
|
|
|
</View>
|
|
|
</View>
|
|
|
</PageCustom>
|