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 && (
)}
);
}