import { View, ScrollView } from "@tarojs/components"; import NavBarNormal from "@/components/NavBarNormal/index"; import PageCustom from "@/components/page-custom/index"; import Taro, { useRouter, useUnload } from "@tarojs/taro"; import ChatMessage from "@/components/chat-message"; import style from "./index.module.less"; import InputBar from "./components/input-bar"; import { useEffect, useState, useRef } from "react"; import { useTextChat } from "@/store/textChat"; import { EAI_MODEL } from "@/consts/enum"; import type { TMessage, TRobotMessage } from "@/store/textChat"; import ChatWelcome from "./components/chat-welcome"; import IconArrowLeft from "@/components/icon/icon-arrow-left"; import PersonalCard from "./components/personal-card"; import { useAgentStore } from "@/store/agentStore"; import { useLoadMore } from "@/utils/loadMore"; import { getMessageHistories } from "@/service/bot"; import { useAppStore } from "@/store/appStore"; // 类型谓词函数 function isRobotMessage( message: TMessage | TRobotMessage ): message is TRobotMessage { return "robot" in message && "reasoningContent" in message; } export default function Index() { const router = useRouter(); const { agentId, isVisitor } = router.params; if (!agentId) { return 没有相应的智能体; } const headerHeight = useAppStore((state) => state.headerHeight); const { fetchAgent, fetchAgentProfile, } = useAgentStore(); const agent = useAgentStore((state) => { if(isVisitor === 'true'){ return state.agentProfile } return state.agent }); const [deepThink, setDeepThink] = useState(EAI_MODEL.DeepseekChat); const [histories, setHistories] = useState<(TMessage | TRobotMessage)[]>([]); const [keyboardHeight, setKeyboardHeight] = useState(0); const [contentHeight, setContentHeight] = useState(0); const [scrollViewHeight, setScrollViewHeight] = useState(0); const scrollViewRef = useRef(null); const messageList = useTextChat((state) => state.list); const { destroy, setScrollTop, genSessionId } = useTextChat(); const scrollTop = useTextChat((state) => state.scrollTop); const fetcher = async ([_url, nextId, page, pageSize]) => { if (!agent) { return null; } const _nextId = nextId ? decodeURIComponent(nextId) : nextId; const res = await getMessageHistories({ agentId, startId: _nextId, pageSize, }); return res.data; }; const { data, loadMore, page } = useLoadMore<(TMessage | TRobotMessage)[]>({ url: `messeagehistories${isVisitor}${agentId}`, fetcher, }); const [showWelcome, setShowWelcome] = useState(!histories.length); // 加载更多 const onScrollToUpper = () => { console.log("onscroll"); loadMore(); }; useEffect(() => { if(agentId){ if(isVisitor){ fetchAgentProfile(agentId) }else{ fetchAgent(agentId); } } }, [agentId, isVisitor]); useEffect(() => { setShowWelcome(!histories.length); }, [histories]); useEffect(() => { if (data?.data) { const combine = [...histories, ...data.data] setHistories(combine); if (page === 1) { setTimeout(() => { setScrollTop(); }, 300); } } }, [data, page,]); // 计算 marginTopOffset 偏移的距离 const marginTopOffset = (() => { if (keyboardHeight <= 0) return 0; // 如果内容超过滚动容器,取键盘弹起高度 if (contentHeight > scrollViewHeight) { return -keyboardHeight; } // 如果内容+键盘弹起高度超过滚动容器, 则取其差值 if (contentHeight + keyboardHeight > scrollViewHeight) { // 内容+键盘弹起高度 - 滚动容器高度 return -(contentHeight + keyboardHeight - scrollViewHeight); } })(); useEffect(() => { // 监听键盘高度变化 Taro.onKeyboardHeightChange((res) => { if (res.height <= 0) { return setKeyboardHeight(0); } setKeyboardHeight(res.height - 24); }); return () => { // 清理监听器 Taro.offKeyboardHeightChange(); }; }, []); // 监听内容高度和 ScrollView 高度变化 useEffect(() => { if (scrollViewRef.current) { const query = Taro.createSelectorQuery(); // 获取聊天内容高度 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(); } }, [messageList]); useEffect(() => { genSessionId(); }, []); useUnload(() => { destroy(); }); const switchDeepThink = () => { if (deepThink === EAI_MODEL.DeepseekChat) { setDeepThink(EAI_MODEL.DeepseekReasoner); return; } setDeepThink(EAI_MODEL.DeepseekChat); }; const renderNavLeft = () => { return ( Taro.navigateBack()} > ); }; // 自定义背景样式 const bgImageStyle = { backgroundImage: `url(${agent?.avatarUrl})`, }; return ( {(!!agent?.enabledChatBg) ? : <>} {showWelcome && } {/* 复制 histories 再 reverse 否则会影响 state */} {[...[...histories].reverse(), ...messageList].map((message) => { const robotMessage = isRobotMessage(message) ? message : null; return ( ); })} {/* 深度思考(R1) */} {agent && ( )} ); }