Explorar o código

fix: 聊天界面进入时重新拉取数据

王晓东 hai 2 meses
pai
achega
a8a42f2adb

+ 2 - 1
src/components/AvatarMedia/index.tsx

@@ -2,6 +2,7 @@ import { Image, Video, VideoProps, ImageProps, View } from "@tarojs/components";
 import { useEffect, useRef } from "react";
 import Taro from "@tarojs/taro";
 import { DEFAULT_AVATAR } from '@/config'
+import { addOssProcessLowQualityParam } from '@/utils'
 
 interface Props {
   source?: string;
@@ -57,7 +58,7 @@ export const AvatarMedia = ({ source, className, roundedFull = true, mode = 'wid
     );  
   }
 
-  const _source = source?.length ? `${source}?x-oss-process=image/quality,Q_60/format,jpg` : DEFAULT_AVATAR
+  const _source = source?.length ? `${addOssProcessLowQualityParam(source)}` : DEFAULT_AVATAR
   return (
     <View className={`overflow-hidden shrink-0 ${roundedFull ? 'rounded-full': ''} ${className}`}>
       <Image

+ 1 - 1
src/pages/chat/components/InputBar/useChatInput.ts

@@ -47,7 +47,7 @@ export const useChatInput = ({
     setScrollTop,
     setAutoScroll,
   } = useTextChat();
-  const list = useTextChat(state => state.list)
+  
   
 
   // 聊天框内消息定时上报

+ 3 - 1
src/pages/chat/hooks/useChatMessages.ts

@@ -18,6 +18,7 @@ export const useChatMessages = (agentId: string, isVisitor?: string): {
   loadMore: () => void;
   pageIndex: number;
   mutate: (data: any, params: any) => void;
+  resetAndLoadFirstPage: () => void;
 } => {
   const messageList = useTextChat((state) => state.list);
 
@@ -33,7 +34,7 @@ export const useChatMessages = (agentId: string, isVisitor?: string): {
   };
 
   // 使用无限滚动加载历史消息
-  const { list, loadMore, pageIndex, mutate } = useLoadMoreInfinite<
+  const { list, loadMore, pageIndex, mutate, resetAndLoadFirstPage } = useLoadMoreInfinite<
     TMessage[] | TRobotMessage[]
   >(createKey(`messeagehistories${isVisitor}${agentId}`), fetcher, {
     revalidateOnMount: false
@@ -93,5 +94,6 @@ export const useChatMessages = (agentId: string, isVisitor?: string): {
     loadMore,
     pageIndex,
     mutate,
+    resetAndLoadFirstPage,
   };
 };

+ 1 - 0
src/pages/chat/hooks/useChatScrollManager.ts

@@ -33,6 +33,7 @@ export const useChatScrollManager = (messagesLength: number, pageIndex: number,
 
   // 首次进入界面滚动到底部
   useEffect(() => {
+    console.log('useEffect 首次进入界面滚动到底部: ', pageIndex, messagesLength, initialScrolledRef.current)
     // 仅首次 pageIndex === 1 且已经有消息时滚动一次
     if (pageIndex === 1 && messagesLength > 0 && !initialScrolledRef.current) {
       initialScrolledRef.current = true;

+ 3 - 2
src/pages/chat/index.tsx

@@ -44,6 +44,7 @@ export default function Index() {
     loadMore,
     pageIndex,
     mutate,
+    resetAndLoadFirstPage,
   } = useChatMessages(agentId, isVisitor);
 
   // 获取原始历史消息列表长度(用于UI状态判断)
@@ -95,7 +96,7 @@ export default function Index() {
 
   // 页面显示时刷新数据
   useDidShow(() => {
-    mutate(undefined, {revalidate: true})
+    resetAndLoadFirstPage()
   });
 
   // 首次进入聊天生成 session id
@@ -113,7 +114,7 @@ export default function Index() {
 
   // 使用工厂函数创建导航栏左侧渲染器
   const renderNavLeft = createNavLeftRenderer(PersonalCard, IconArrowLeftWhite24, IconArrowLeft);
-  console.log('----scrollTop: ', scrollTop, '----')
+  // console.log('----scrollTop: ', scrollTop, '----')
   return (
     <PageCustom
       fullPage

+ 1 - 1
src/pages/component-library/index.tsx

@@ -62,7 +62,7 @@ export default () => {
       type: EComponentType.bluebook,
       typeStyle: CompType.bluebook,
       num: 0,
-      text: "小蓝本",
+      text: "智能体",
     },
   ]);
 

+ 3 - 1
src/store/textChatStore.ts

@@ -75,6 +75,7 @@ export const useTextChat = create<TextChat>((set, get) => ({
     set({isReacting})
   },
   setAutoScroll: (b)=> {
+    // console.log('setAutoScroll:', b)
     set({autoScroll: b})
   },
   setQuestions: (q:string[])=> {
@@ -137,13 +138,14 @@ export const useTextChat = create<TextChat>((set, get) => ({
     return {msgUk, sessionId}
   },
   setScrollTop: (num?: number)=> {
-    console.log('setScrollTop')
+    // console.log('setScrollTop')
     set((state) => {
       if(num!== undefined){
         return {
           scrollTop: num,
         }
       }
+      // console.log('autoScroll: ', state.autoScroll)
       if(state.autoScroll){
         return {
           scrollTop: state.scrollTop + 1,

+ 47 - 0
src/utils/index.ts

@@ -479,3 +479,50 @@ export const pxToRpx = (px: number) => {
   const systemInfo = Taro.getSystemInfoSync()
   return (750 / systemInfo.windowWidth) * px
 }
+
+
+
+/**
+ * 为图片URL添加阿里云OSS处理参数
+ * 如果URL中不包含?x-oss-process=,则添加?x-oss-process=image/quality,Q_60/format,jpg
+ * 如果URL中已包含其他查询参数,则追加&x-oss-process=image/quality,Q_60/format,jpg
+ * @param url 原始图片URL
+ * @returns 处理后的图片URL
+ */
+export function addOssProcessLowQualityParam(url: string): string {
+  // 检查URL是否有效
+  if (!url || typeof url !== 'string') {
+    return url;
+  }
+
+  // 检查是否已经包含OSS处理参数
+  if (url.includes('x-oss-process=')) {
+    return url;
+  }
+
+  // 分离URL和查询参数
+  const [baseUrl, existingQuery] = url.split('?');
+  
+  // 构建新的查询参数
+  const ossParam = 'x-oss-process=image/quality,Q_60/format,jpg';
+  const newQuery = existingQuery 
+    ? `${existingQuery}&${ossParam}`  // 已有查询参数,追加OSS参数
+    : ossParam;                       // 没有查询参数,直接使用OSS参数
+
+  // 返回处理后的URL
+  return `${baseUrl}?${newQuery}`;
+}
+
+// 使用示例
+// const exampleUrl1 = "https://example.com/image.jpg";
+// const exampleUrl2 = "https://example.com/image.png?width=200&height=200";
+// const exampleUrl3 = "https://example.com/image.webp?x-oss-process=image/resize,w_300";
+
+// console.log(addOssProcessParam(exampleUrl1)); 
+// // 输出: https://example.com/image.jpg?x-oss-process=image/quality,Q_60/format,jpg
+
+// console.log(addOssProcessParam(exampleUrl2)); 
+// // 输出: https://example.com/image.png?width=200&height=200&x-oss-process=image/quality,Q_60/format,jpg
+
+// console.log(addOssProcessParam(exampleUrl3)); 
+// // 输出: https://example.com/image.webp?x-oss-process=image/resize,w_300 (保持不变,因为已包含OSS参数)

+ 9 - 0
src/utils/loadMoreInfinite.ts

@@ -75,6 +75,14 @@ export const useLoadMoreInfinite = <T>(getKey, fetcher, params = {}) => {
   const loadMore = () => {
     setSize((size) => size + 1);
   }
+  // 重置并重新加载第一页
+  const resetAndLoadFirstPage = async () => {
+    // 使用mutate重置数据
+    await mutate([], false)
+    // 重新设置size为1,加载第一页
+    setSize(1)
+    await mutate();
+  }
   return {
     data,
     list,
@@ -82,6 +90,7 @@ export const useLoadMoreInfinite = <T>(getKey, fetcher, params = {}) => {
     isLoading,
     pages,
     mutate,
+    resetAndLoadFirstPage,
     setSize,
     size,
     loadMore,