Bläddra i källkod

fix: 聊天框内好评差评修复点击状态

sheldon 2 veckor sedan
förälder
incheckning
e217daeaf2

+ 31 - 8
src/components/chat-message/MessageRobot.tsx

@@ -44,33 +44,56 @@ export default ({agent, text, message, textReasoning=''}:Props) => {
     }
   }
   const loginId = getLoginId();
-  const handleDislike = async (disLike: boolean) => {
+  const handleDislike = async () => {
     if(!agent?.agentId){
       return;  
     }
+    const isDislike = !message.isDislike
     const response = await dislikeMessage({
       agentId: agent?.agentId,
       dislikeReason: '',
-      isDislike: !disLike,
+      isDislike: isDislike,
       loginId,
       msgUk: message.msgUk
     })
     if(isSuccess(response.status)){
-      setIsDislike(!disLike)
+      Taro.showToast({
+        title: isDislike ? '已差评' : '已取消差评',
+        icon: 'none'
+      })
+      message.isDislike = isDislike; // 更新本地状态
+      setIsDislike(isDislike)
+      if(isDislike && isLike) {
+        message.isLike = false; // 取消 like
+        setIsLike(false) // 取消 like
+      }
     }
   }
-  const handleLike = async (like: boolean) => {
+  const handleLike = async () => {
     if(!agent?.agentId){
       return;  
     }
+    const isLike = !message.isLike
     const response = await likeMessage({
       agentId: agent?.agentId,
-      isLike: !like,
+      isLike: isLike,
       loginId,
       msgUk: message.msgUk
     })
+    
     if(isSuccess(response.status)){
-      setIsLike(!like)
+      Taro.showToast({
+        title: isLike ? '已喜欢' : '已取消喜欢',
+        icon: 'none'
+      })
+      message.isLike = isLike; // 更新本地状态
+      // 触发 mutate 更新列表
+      setIsLike(isLike)
+      if(isDislike && isLike) {
+        message.isDislike = false; // 取消 dislike
+        setIsDislike(false) // 取消 dislike
+      }
+      
     }
   }
 
@@ -103,10 +126,10 @@ export default ({agent, text, message, textReasoning=''}:Props) => {
         <View className="flex gap-8">
           <View onClick={handleCopy}><IconCopy /></View>
           {/* <IconSpeaker></IconSpeaker> */}
-          <View onClick={()=> handleDislike(message.isDislike)}>
+          <View onClick={()=> handleDislike()}>
             {isDislike ? <IconDislikeBlue/> : <IconDislike/>}
           </View>
-          <View onClick={()=> handleLike(message.isLike)}>
+          <View onClick={()=> handleLike()}>
             {isLike ? <IconLikeBlue/> : <IconLike/>}
           </View>
         </View>

+ 3 - 2
src/components/chat-message/index.tsx

@@ -9,12 +9,13 @@ interface Props {
   text: string
   textReasoning?: string
   message: TMessage
+  mutate: (data?: any, options?: { revalidate?: boolean } ) => void
 }
-export default ({agent, text, role, message, textReasoning=''}:Props) => {
+export default ({agent, text, role, message, mutate, textReasoning=''}:Props) => {
   if(role === EChatRole.User ){
     return <Message text={text}/>
   }
-  return <MessageRobot message={message} textReasoning={textReasoning} text={text} agent={agent}/>
+  return <MessageRobot mutate={mutate} message={message} textReasoning={textReasoning} text={text} agent={agent}/>
 }
 
 

+ 1 - 15
src/pages/agent/components/AgentSetting/components/AgentKnowledgeLib/index.tsx

@@ -24,19 +24,7 @@ export default function Index() {
     fetchAgent(agent.agentId);
   };
 
-  const IconArrowRight = () => {
-    return (
-      <View className="flex items-center">
-        <IconArrow />
-      </View>
-    );
-  };
-
-  const handleClick = () => {
-    Taro.switchTab({
-      url: "/pages/knowledge/index",
-    });
-  };
+  
 
   if (!agent || !agent.isEnt) {
     return <></>;
@@ -47,8 +35,6 @@ export default function Index() {
       <CardListItem
         className="pl-16 pr-8"
         leftRenderer={IconPageColor}
-        rightRenderer={IconArrowRight}
-        onClick={handleClick}
       >
         <View className="text-14 py-18 font-medium leading-22">知识库</View>
       </CardListItem>

+ 25 - 30
src/pages/chat/index.tsx

@@ -1,30 +1,26 @@
 import { View, ScrollView, Video } from "@tarojs/components";
 import NavBarNormal from "@/components/NavBarNormal/index";
 import PageCustom from "@/components/page-custom/index";
-import Taro, { useRouter, useUnload } from "@tarojs/taro";
+import Taro, { useDidShow, 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 type { TRobotMessage } from "@/store/textChat";
+import { EChatRole, TChatRole, TMessage } from "@/types/bot";
 
 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 { useLoadMoreInfinite, createKey } from "@/utils/loadMoreInfinite";
 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();
@@ -43,7 +39,7 @@ export default function Index() {
 
   const [deepThink, setDeepThink] = useState(EAI_MODEL.DeepseekChat);
 
-  const [histories, setHistories] = useState<(TMessage | TRobotMessage)[]>([]);
+  
 
   const [keyboardHeight, setKeyboardHeight] = useState(0);
   const [contentHeight, setContentHeight] = useState(0);
@@ -55,7 +51,7 @@ export default function Index() {
   const { destroy, setScrollTop, genSessionId } = useTextChat();
   const scrollTop = useTextChat((state) => state.scrollTop);
 
-  const fetcher = async ([_url, nextId, page, pageSize]) => {
+  const fetcher = async ([_url,{ nextId, pageSize}]) => {
     if (!agent) {
       return null;
     }
@@ -67,18 +63,21 @@ export default function Index() {
     });
     return res.data;
   };
-  const { data, loadMore, page } = useLoadMore<(TMessage | TRobotMessage)[]>({
-    url: `messeagehistories${isVisitor}${agentId}`,
+  const { list, loadMore, pageIndex, mutate } = useLoadMoreInfinite<(TMessage | TRobotMessage)[]>(
+    createKey(`messeagehistories${isVisitor}${agentId}`),
     fetcher,
-  });
+  );
 
-  const [showWelcome, setShowWelcome] = useState(!histories.length);
+  const [showWelcome, setShowWelcome] = useState(!list.length);
 
   //  加载更多
   const onScrollToUpper = () => {
     console.log("onscroll");
     loadMore();
   };
+  useDidShow(()=> {
+    mutate(undefined,{revalidate: true})
+  })
 
   useEffect(() => {
     if(agentId){
@@ -91,20 +90,16 @@ export default function Index() {
   }, [agentId, isVisitor]);
 
   useEffect(() => {
-    setShowWelcome(!histories.length);
-  }, [histories]);
+    setShowWelcome(!list.length);
+  }, [list]);
 
   useEffect(() => {
-    if (data?.data) {
-      const combine = [...histories, ...data.data]
-      setHistories(combine);
-      if (page === 1) {
-        setTimeout(() => {
-          setScrollTop();
-        }, 300);
-      }
+    if (pageIndex === 1) {
+      setTimeout(() => {
+        setScrollTop();
+      }, 300);
     }
-  }, [data, page,]);
+  }, [pageIndex]);
 
   // 计算 marginTopOffset 偏移的距离
   const marginTopOffset = (() => {
@@ -239,16 +234,16 @@ export default function Index() {
           {showWelcome && <ChatWelcome agent={agent} />}
           <View id="messageList" className="flex flex-col gap-8 px-18 pb-140">
             {/* 复制 histories 再 reverse 否则会影响 state */}
-            {[...[...histories].reverse(), ...messageList].map((message) => {
-              const robotMessage = isRobotMessage(message) ? message : null;
+            {[...[...list].reverse(), ...messageList].map((message) => {
               return (
                 <ChatMessage
                   key={message.msgUk}
-                  textReasoning={robotMessage?.reasoningContent}
+                  textReasoning={message?.reasoningContent}
                   agent={agent}
                   role={message.role}
                   text={message.content}
                   message={message}
+                  mutate={mutate}
                 ></ChatMessage>
               );
             })}
@@ -275,7 +270,7 @@ export default function Index() {
             <InputBar
               aiModel={deepThink}
               agent={agent}
-              histories={histories}
+              histories={list}
               setShowWelcome={setShowWelcome}
             ></InputBar>
           )}

+ 0 - 1
src/pages/editor-pages/editor-link-contact/components/MyContactsScrollList/index.tsx

@@ -3,7 +3,6 @@ import { View, ScrollView } from "@tarojs/components";
 import style from "./index.module.less";
 import { useEffect, useState } from "react";
 import { getContactList } from "@/service/contact";
-import { useLoadMore } from "@/utils/loadMore";
 import { TContactItem } from "@/types/contact";
 import ContactCard from "@/components/contact-card/index";
 import WemetaRadio from "@/components/WemetaRadio/index";

+ 23 - 11
src/pages/editor-pages/editor-link-contact/components/MyEntAgentsScrollList/index.tsx

@@ -1,15 +1,11 @@
 import Taro, { useReachBottom,} from "@tarojs/taro";
 import { View, ScrollView } from "@tarojs/components";
-import style from "./index.module.less";
-import { useEffect, useState } from "react";
-import { getContactList } from "@/service/contact";
-import { useLoadMore } from "@/utils/loadMore";
-import { TContactItem } from "@/types/contact";
+import { getEntAgentPartners } from "@/service/agent";
 import ContactCard from "@/components/contact-card/index";
 import WemetaRadio from "@/components/WemetaRadio/index";
 import { useAgentStore } from "@/store/agentStore";
 import { TAgent } from "@/types/agent";
-
+import { createKey, useLoadMoreInfinite } from "@/utils/loadMoreInfinite";
 export interface IProps {
   selected: any[]
   setSelected: (values) => void
@@ -18,10 +14,20 @@ export interface IProps {
 
 export default function Index({selected, setSelected}: IProps) {
 
-  const { agents } = useAgentStore()
-
-  const entAgents = agents.filter(item => item.isEnt)
+  const  agent = useAgentStore((state) => state.agent);
   
+  const fetcher = async ([_url, {nextId, pageSize}, [entId]]) => {
+    const res = await getEntAgentPartners({ startId: nextId, pageSize, entId });
+    return res.data;
+  };
+
+  const entId = agent?.entId ?? 0;
+
+
+  const { list, loadMore } = useLoadMoreInfinite<TAgent[]>(
+    createKey(`/blue-aiagent/api/v1/my/ent/${entId}/agent/partners`, 10, [entId]),
+    fetcher,
+  );
 
   const handleClick = (item: TAgent) => {
     console.log(item)
@@ -35,9 +41,14 @@ export default function Index({selected, setSelected}: IProps) {
     }
   };
 
+  const onScrollToLower = () => {
+    // 加载更多数据
+    loadMore();
+  };
+
   const renderContent = () => {
-    if (entAgents.length) {
-      return entAgents.map((item) => (
+    if (list.length) {
+      return list.map((item) => (
         <View className='bg-white'>
           <ContactCard
               className="border-bottom1-gray py-16"
@@ -71,6 +82,7 @@ export default function Index({selected, setSelected}: IProps) {
   return (
     <ScrollView
       scrollY
+      onScrollToLower={onScrollToLower}
       style={{
         flex: 1,
         height: "100%", // 高度自适应

+ 1 - 1
src/pages/editor-pages/editor-link-contact/index.tsx

@@ -186,7 +186,7 @@ export default function Index() {
           </View>
         </View>
       </View>
-      <Popup setShow={setShow} show={show} title="知识库-链接">
+      <Popup setShow={setShow} show={show} title="智能体">
         <WemetaTabs current="1" list={tabList}></WemetaTabs>
         <BottomBar>
           <View

+ 7 - 4
src/pages/index/components/WelcomeTips/index.tsx

@@ -2,9 +2,6 @@ import { View, Image } from "@tarojs/components";
 import style from "./index.module.less";
 import Taro from "@tarojs/taro";
 
-import { getAgents, getAgent, createAgent, } from "@/service/agent";
-
-import { isSuccess } from "@/utils";
 import { useAgentStore } from "@/store/agentStore";
 interface IProps {
   // children: JSX.Element|JSX.Element[]
@@ -12,7 +9,13 @@ interface IProps {
 export default function Index({}: IProps) {  
   const { createAgent } = useAgentStore()
   const handleCreate = async ()=> {
-    createAgent()
+    const agentDetail = await createAgent()
+    if(agentDetail){
+      Taro.navigateTo({
+        url: `/pages/agent/index?agentId=${agentDetail.agentId}`
+      })
+    }
+    
   }
   return (
     <View className={style.container}>

+ 0 - 1
src/pages/index/index.tsx

@@ -16,7 +16,6 @@ export default function Index() {
       fetchAgents();
     }
   });
-
   if (!defaultAgent) {
     return <InitView></InitView>;
   }

+ 42 - 45
src/pages/voice/components/VoiceList/index.tsx

@@ -2,8 +2,9 @@ import WemetaRadio from "@/components/WemetaRadio/index";
 import { Image, View } from "@tarojs/components";
 import { useEffect, useState } from "react";
 import CardListItem from "@/components/list/card-list-item";
-import { TVoiceItem } from '@/types/voice'
+import { TVoiceItem } from "@/types/voice";
 import { TAgentDetail } from "@/types/agent";
+import EmptyData from "@/components/empty-data";
 
 export default function Index({
   onPlay,
@@ -11,18 +12,12 @@ export default function Index({
   agent,
 }: {
   onPlay: (voice: any) => void;
-  list: TVoiceItem[]
-  agent: TAgentDetail|null
+  list: TVoiceItem[];
+  agent: TAgentDetail | null;
 }) {
-  
-  
-  
-  
-
   const initPage = async () => {
     // console.log("profileId: ", profileId);
     // const res = await getSysVoiceList();
-
     // if (res.code === 0 && res.data) {
     //   const r = res.data.map((item) => {
     //     item.checked = character?.defaultSystemVoice === item.voice;
@@ -49,43 +44,45 @@ export default function Index({
   return (
     <View className="w-full">
       <View className="flex flex-col w-full gap-28">
-      <View>
+        <View>
           <View className="flex flex-col gap-12">
-        {list.map((item: TVoiceItem, index) => {
-          // 与克隆语音是否相同
-          const isEqualToClonedVoice = item.voiceId === agent?.voiceId;
-          return (
-            <CardListItem
-            underline
-            rightRenderer={()=> {
-              return <View className="flex items-center">
-                <WemetaRadio
-                  checked={isEqualToClonedVoice}
-                ></WemetaRadio>
-              </View>
-            }}
-          >
-            <View
-              className="flex gap-16 w-full py-16"
-              key={item.voiceId}
-              onClick={() => {
-                handleSelect(item);
-              }}
-            >
-              
-              <View className="flex flex-1 flex-col gap-4 overflow-hidden">
-                <View className="text-14 leading-22 font-medium text-black">
-                  {item.voiceName}
-                </View>
-                <View className="flex-1 text-12 leading-20 font-medium text-gray-45 truncate">
-                  {item.gender === 'male' ? "男" : "女"}
-                </View>
-              </View>
-            </View>
-          </CardListItem>
-          );
-        })}
-        </View>
+            {!list.length && <EmptyData type={'search'}></EmptyData>}
+            {list.map((item: TVoiceItem, index) => {
+              // 与克隆语音是否相同
+              const isEqualToClonedVoice = item.voiceId === agent?.voiceId;
+              return (
+                <CardListItem
+                  underline
+                  rightRenderer={() => {
+                    return (
+                      <View className="flex items-center">
+                        <WemetaRadio
+                          checked={isEqualToClonedVoice}
+                        ></WemetaRadio>
+                      </View>
+                    );
+                  }}
+                >
+                  <View
+                    className="flex gap-16 w-full py-16"
+                    key={item.voiceId}
+                    onClick={() => {
+                      handleSelect(item);
+                    }}
+                  >
+                    <View className="flex flex-1 flex-col gap-4 overflow-hidden">
+                      <View className="text-14 leading-22 font-medium text-black">
+                        {item.voiceName}
+                      </View>
+                      <View className="flex-1 text-12 leading-20 font-medium text-gray-45 truncate">
+                        {item.gender === "male" ? "男" : "女"}
+                      </View>
+                    </View>
+                  </View>
+                </CardListItem>
+              );
+            })}
+          </View>
         </View>
       </View>
     </View>

+ 13 - 14
src/store/agentStore.ts

@@ -138,17 +138,20 @@ export const useAgentStore = create<AgentStoreState>((set, get) => ({
     }
     return null
   },
+  // 创建并设置其为默认智能体
   createAgent: async () => {
     const response = await _createAgent();
-    if (response.data) {
+    const agentDetail = response.data
+    if (agentDetail) {
       const a: TAgent = {
-        agentId: response.data.agentId ?? "",
-        isDefault: response.data.isDefault ?? false,
-        isEnt: response.data.isEnt ?? false,
-        isNewEnt: response.data.isNewEnt ?? false,
-        name: response.data.name ?? "",
+        agentId: agentDetail.agentId ?? "",
+        isDefault: agentDetail.isDefault ?? false,
+        isEnt: agentDetail.isEnt ?? false,
+        isNewEnt: agentDetail.isNewEnt ?? false,
+        name: agentDetail.name ?? "",
         enabledChatBg: false,
       }
+
       set((state) => {
         return {
           agents: [
@@ -158,7 +161,7 @@ export const useAgentStore = create<AgentStoreState>((set, get) => ({
           defaultAgent: a,
         };
       });
-      return response.data;
+      return agentDetail;
     }
     return null;
   },
@@ -197,13 +200,9 @@ export const useAgentStore = create<AgentStoreState>((set, get) => ({
   deleteAgent: async (agentId: string)=> {
     const response = await _deleteAgent(agentId)
     if(isSuccess(response.status)){
-      set((state) => {
-        const agents = state.agents.filter((item: TAgent) => item.agentId !== agentId)
-        return {
-          agents: [...agents]
-        }
-      })
-      const agents =await get().fetchAgents()
+      const agents = get().agents.filter((item: TAgent) => item.agentId !== agentId)
+      set({agents: [...agents]})
+      get().fetchAgents()
       if(agents.length <= 0){
         Taro.reLaunch({url: '/pages/index/index'})
         return;

+ 2 - 2
src/types/bot.ts

@@ -3,8 +3,8 @@
 export type TMessage = {
   content: string,
   dislikeReason: string,
-  isDislike: boolean,
-  isLike: boolean,
+  isDislike?: boolean,
+  isLike?: boolean,
   isStreaming: boolean,
   msgId: number,
   msgTime: string,