Procházet zdrojové kódy

refactor: 知识库数据请求优化

王晓东 před 3 týdny
rodič
revize
3e00796d58

+ 18 - 5
src/app.less

@@ -164,6 +164,7 @@ page {
   display: flex;
   padding: 14px;
   align-items: center;
+  word-break: keep-all;
   justify-content: center;
   border-radius: 8px;
   background-color: white;
@@ -203,6 +204,14 @@ page {
 }
 
 
+// /* 竖屏且宽度<390px */
+// @media (orientation: portrait) and (max-width: 390px) {
+//   .button-rounded.button-primary {
+    
+//   }
+// }
+
+
 // 社交媒体icon 
 .social-media-icon{
   width: 24px;
@@ -438,13 +447,17 @@ page {
   }
 }
 
-
-.blurBg {
-  margin-top: 220px;
+// 智能体内容容器毛玻璃效果,距顶部距离 240 ,留出空间显示形象
+.blur-rounded-container{
+  margin-top: 240px;
   width: 100%;
   box-sizing: border-box;
   border-top-left-radius: 24px;
   border-top-right-radius: 24px;
-  background: rgba(#FFF, .45);
+  // background: rgba(#FFF, .45);
   backdrop-filter: blur(38px);
-}
+  background: linear-gradient( rgba(#fff, .45) 1%, rgba(#fff, 0) 100%);
+}
+
+
+

+ 1 - 1
src/components/AgentPage/index.tsx

@@ -47,7 +47,7 @@ export default function Index({ agentId }: IProps) {
   return (
     <PageCustom styleBg={bgImageStyle}>
       <NavBarNormal leftColumn={Logo}></NavBarNormal>
-      <View className={style.blurBg}>
+      <View className="blur-rounded-container">
         {(!!agent) ? <SummaryBar isVisitor={false} agent={agent}></SummaryBar> : <></>}
         <View className={`flex flex-col gap-12 w-full p-16`}>
           <ComponentList components={components}></ComponentList>

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

@@ -62,6 +62,7 @@ export default function Index() {
   return (
     <PageCustom>
       <NavBarNormal
+        scrollFadeIn
         backText="联系我们"
       ></NavBarNormal>
       <View className="flex flex-col items-center w-full gap-16 p-16 pb-140">

+ 0 - 0
src/pages/knowledge/components/asistant-message/index.tsx → src/pages/knowledge/components/AsistantMessage/index.tsx


+ 111 - 0
src/pages/knowledge/components/CompanyList/index.tsx

@@ -0,0 +1,111 @@
+import { View } from "@tarojs/components";
+
+import EmptyData from "@/components/empty-data";
+import { useEffect, useState } from "react";
+
+import PickerSingleColumn from "@/components/Picker/PickerSingleColumn";
+import IconArrowDownRounded from "@/components/icon/IconArrowDownRounded";
+import { useUserStore } from "@/store/userStore";
+import Taro, { useDidShow } from "@tarojs/taro";
+import { TEntItem } from "@/types/user";
+
+// extraEnt 可额外传递预测的企业比如 自已构造一个 “个人知识库” 伪装成企业请求
+// const extraEnt = [{
+//   entName: '个人知识库',
+//   entId: -1,
+//   expireTime: '0',
+//   isExpired: false,
+//   knowledgeCnt: 0
+// }]
+
+interface IProps {
+  extraEnt?: TEntItem[]
+  currentEnt: TEntItem | null
+  setCurrentEnt: (ent:TEntItem) => void
+}
+
+const Index = ({currentEnt, setCurrentEnt, extraEnt = []}: IProps) => {
+  const {entList, fetchMyEntList } = useUserStore();
+
+  
+  const allEnt = [...entList, ...extraEnt]
+  // 当前选中的值
+  const options = allEnt.map((item) => item.entName);
+  // 是否显示选择器
+  const [showPicker, setShowPicker] = useState(false);
+
+  // 当前选中的值
+  const [selected, setSelected] = useState(options[0]);
+
+  const handleChange = (value: string) => {
+    setSelected(value);
+    const ent = allEnt.find((item) => item.entName === value);
+    if (ent) {
+      setCurrentEnt(ent);
+    }
+  };
+
+  useEffect(() => {
+    // 如果没有设置过当前企业,且有企业列表,则设置一个默认的为当前企业
+    console.log(currentEnt, allEnt, entList)
+    if (!currentEnt &&  allEnt.length) {
+      setSelected(allEnt[0].entName);
+      setCurrentEnt(allEnt[0]);
+    }
+  }, [allEnt, entList, currentEnt]);
+
+  useDidShow(() => {
+    fetchMyEntList();
+  });
+
+  // 如果没有公司
+  if (!allEnt.length) {
+    return (
+      <View className="flex-center pt-40">
+        <EmptyData type={7}>
+          <View className="text-center text-14 leading-28 text-gray-45 mb-44 w-172">
+            <View className="text-center text-16 leading-24 font-medium text-black">
+              绑定企业,知识自动到位
+            </View>
+            <View>访问公司统一知识内容</View>
+            <View>一键同步到你的智能体</View>
+            <View>提升回复效率与专业度</View>
+            <View
+              className="button-rounded button-primary-light button-border-primary button-inline-flex mt-24"
+              onClick={() =>
+                Taro.navigateTo({ url: "/pages/contact-us/index" })
+              }
+            >
+              联系我们
+            </View>
+          </View>
+        </EmptyData>
+      </View>
+    );
+  }
+
+  // 渲染公司选择器
+  return (
+    <PickerSingleColumn
+      options={options}
+      selected={selected}
+      onChange={handleChange}
+      showPicker={showPicker}
+      setShowPicker={setShowPicker}
+    >
+      <View
+        className="flex items-center gap-2 bg-gray-3 rounded-12 p-12 mb-16"
+        onClick={() => setShowPicker(true)}
+      >
+        <View className="flex-1 text-14 leading-22 text-gray-45">
+          {selected}
+        </View>
+        <View className="flex-center">
+          <IconArrowDownRounded />
+        </View>
+      </View>
+    </PickerSingleColumn>
+  );
+};
+
+export default Index;

+ 35 - 11
src/pages/knowledge/components/view-style/ViewStyleListEnt.tsx → src/pages/knowledge/components/CompanyTab/components/ScrollList.tsx

@@ -3,30 +3,54 @@ import { ScrollView, View, Image } from "@tarojs/components";
 import FigureList from "@/components/list/FigureList";
 import FigureListItem from "@/components/list/FigureListItem";
 import { useDidShow } from "@tarojs/taro";
-import { useEffect } from "react";
+import { useEffect, useState } from "react";
 
 import RotateLoading from "@/components/rotate-loading";
 import Taro from "@tarojs/taro";
 
-import { useKnowledgeEntStore } from "@/store/knowledgeEnt";
-import type { TKnowledgeItem } from "@/types/knowledge";
 import KnowledgeIcon from "@/components/KnowledgeIcon";
+import {
+  getEntKnowledgeList,
+} from "@/service/knowledge";
+import type { TKnowledgeItem } from "@/types/knowledge";
+import { useLoadMore } from "@/utils/loadMore";
 export interface Iprops {
   entId: string|number
 }
 const Index = ({entId}:Iprops) => {
-  const { listItems, listScrollTop, loadMoreList, initLoadList } = useKnowledgeEntStore();
+  
+
+  const [scrollTop, setScrollTop] = useState(9999)
+  const [list, setList] = useState<TKnowledgeItem[]>([]);
+
+  const fetcher = async ([_url, nextId, page, pageSize, entId]) => {
+    const res = await getEntKnowledgeList({ startId: nextId, pageSize, entId });
+    return res.data;
+  };
+  const { data, loadMore, refetch } = useLoadMore<TKnowledgeItem[]>({
+    url: `getEntKnowledgeList ${entId}`,
+    fetcher,
+    params: [entId]
+  });
 
   const onScrollToUpper = async () => {
     console.log('toUpper')
-    loadMoreList()
+    loadMore()
   }
   useDidShow(()=> {
-    loadMoreList(true)
+    loadMore()
   })
-  useEffect(()=> {
-    initLoadList()
-  }, [])
+  useEffect(() => {
+    if (data?.data) {
+      setList([...list, ...data.data]);
+      setScrollTop(prev => prev + 1)
+    }
+  }, [data]);
+
+  useEffect(() => {
+    loadMore();
+  }, [entId]);
+  
 
   const handleEdit = (item: TKnowledgeItem)=> {
     if(item.parseStatus !== 'parsed'){
@@ -52,14 +76,14 @@ const Index = ({entId}:Iprops) => {
     <ScrollView
       scrollY
       onScrollToUpper={onScrollToUpper}
-      scrollTop={listScrollTop}
+      scrollTop={scrollTop}
       style={{
         flex: 1,
         height: "100%", // 高度自适应
       }}
     >
       <FigureList>
-      {listItems.map(item => {
+      {list.map(item => {
         return <FigureListItem
             figure={()=> <KnowledgeIcon data={item}/>}
             underline

Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 26 - 6
src/pages/knowledge/components/CompanyTab/components/ScrollListChat.tsx


+ 23 - 182
src/pages/knowledge/components/CompanyTab/index.tsx

@@ -1,204 +1,45 @@
 import { View } from "@tarojs/components";
-import RoundedLabel from "../RoundedLabel";
-import IconFilterFeeds from "@/components/icon/IconFilterFeeds";
-import IconFilterBatch from "@/components/icon/IconFilterBatch";
-import IconFilterList from "@/components/icon/IconFilterList";
-
-import EmptyData from "@/components/empty-data";
-import Popup from "@/components/popup/popup";
-import WemetaSwitch from "@/components/WemetaSwitch";
 import { useState } from "react";
 
-import ViewStyleChatEnt from "../view-style/ViewStyleChatEnt";
-import ViewStyleListEnt from "../view-style/ViewStyleListEnt";
+import ScrollListChat from "./components/ScrollListChat";
+import ScrollList from "./components/ScrollList";
+
 
-import PickerSingleColumn from "@/components/Picker/PickerSingleColumn";
-import IconArrowDownRounded from "@/components/icon/IconArrowDownRounded";
-import { useKnowledgeEntStore } from "@/store/knowledgeEnt";
-import { useUserStore } from "@/store/userStore";
-import { useAgentStore } from "@/store/agentStore";
+import CompanyList from '../CompanyList'
+import { TEntItem } from "@/types/user";
+import StyleFilter, {TListStyle} from '../StyleFilter'
 
-type TListStyle = "chat" | "list";
 
 const Index = () => {
-  const ents = useUserStore((state) => state.entList);
-  const [checked, setChecked] = useState(false);
-  const [showPopup, setShowPopup] = useState(false);
   const [listStyle, setListStyle] = useState<TListStyle>("chat");
-  const { ent, setEnt, total, listTotalCount } = useKnowledgeEntStore();
-  // const agents = useAgentStore((state) => state.agents);
-
-  const handleListStyleChange = (listStyle: TListStyle) => {
-    setListStyle(listStyle);
-  };
-
-  // 如果没有当前企业,则默认第一个
-  if (!ent) {
-    setEnt(ents[0]);
-  }
-
-  const renderTabContent = () => {
-    if (!ents.length) {
-      return (
-        <View className="flex-center pt-40">
-          <EmptyData type={7}>
-            <View className="text-center text-14 leading-28 text-gray-45 mb-44 w-172">
-              <View className="text-center text-16 leading-24 font-medium text-black">
-                绑定企业,知识自动到位
-              </View>
-              <View>访问公司统一知识内容</View>
-              <View>一键同步到你的智能体</View>
-              <View>提升回复效率与专业度</View>
-              <View
-                className="button-rounded button-primary-light button-border-primary button-inline-flex mt-24"
-                onClick={() =>
-                  Taro.navigateTo({ url: "/pages/contact-us/index" })
-                }
-              >
-                联系我们
-              </View>
-            </View>
-          </EmptyData>
-        </View>
-      );
-    }
-
-    return (
-      <>
-        <View className="px-16 pb-20">
-          <View className="pb-8">
-            <PickerSingleColumn
-              options={options}
-              selected={selected}
-              onChange={handleChange}
-              showPicker={showPicker}
-              setShowPicker={setShowPicker}
-            >
-              <View
-                className="flex items-center gap-2 bg-gray-3 rounded-12 p-12 mb-16"
-                onClick={() => setShowPicker(true)}
-              >
-                <View className="flex-1 text-14 leading-22 text-gray-45">
-                  {selected}
-                </View>
-                <View className="flex-center">
-                  <IconArrowDownRounded />
-                </View>
-              </View>
-            </PickerSingleColumn>
-          </View>
-          <View className="flex items-center">
-            <View className="flex-1 text-12 leading-20 text-gray-45">
-              共 {listStyle === "chat" ? total : listTotalCount} 个文件
-            </View>
-            <View className="flex items-center">
-              {listStyle === "chat" ? (
-                <RoundedLabel
-                  onClick={() => setShowPopup(true)}
-                  text="信息流"
-                  icon={IconFilterFeeds}
-                ></RoundedLabel>
-              ) : (
-                <>
-                  <RoundedLabel
-                    onClick={() => {
-                      console.log("batch");
-                    }}
-                    text="批量"
-                    icon={IconFilterBatch}
-                  ></RoundedLabel>
-                  <RoundedLabel
-                    text="列表"
-                    onClick={() => {
-                      setShowPopup(true);
-                    }}
-                    icon={IconFilterList}
-                  ></RoundedLabel>
-                </>
-              )}
-            </View>
-          </View>
-        </View>
-        <View className="px-16 h-full">{renderContent()}</View>
-      </>
-    );
-  };
-
-  // 当前选中的值
-  const options = ents.map((item) => item.entName);
-  // 是否显示选择器
-  const [showPicker, setShowPicker] = useState(false);
+  const [ent, setEnt] = useState<TEntItem|null>(null)
+  
 
-  // 当前选中的值
-  const [selected, setSelected] = useState(options[0]);
-
-  const handleChange = (value: string) => {
-    setSelected(value);
-    const ent = ents.find((item) => item.entName === value);
-    if (ent) {
-      setEnt(ent);
-    }
-  };
-
-  const renderContent = () => {
+  const renderScrollList = () => {
     if (!ent?.entId) {
       return <></>;
     }
     if (listStyle === "chat") {
-      return <ViewStyleChatEnt entId={ent.entId} />;
+      return <ScrollListChat entId={ent.entId} />;
     }
-    return <ViewStyleListEnt entId={ent.entId} />;
+    return <ScrollList entId={ent.entId} />;
   };
 
   return (
-    <>
-      <View className="pt-12 h-full">
-        <View className="rounded-container-header"></View>
-        {renderTabContent()}
-      </View>
+    <View className="px-16 h-full">
+      <CompanyList setCurrentEnt={setEnt} currentEnt={ent}></CompanyList>
 
-      <Popup setShow={setShowPopup} show={showPopup} title="展示样式">
-        <View
-          className={`rounded-card ${
-            listStyle === "chat" ? "rounded-card-actived" : ""
-          }`}
-          onClick={() => {
-            handleListStyleChange("chat");
-          }}
-        >
-          <View className="border-bottom1-gray mb-12">
-            <View className="mb-8 text-14 font-medium leading-22">
-              对话信息流
-            </View>
-            <View className="mb-12 text-12 leading-20 text-gray-45">
-              以对话形式展示,模拟自然的对话流程。
-            </View>
-          </View>
-          <View className="flex items-center">
-            <View className="flex-1 text-14 font-medium leading-22">
-              仅显示 AI 助手信息
-            </View>
-            <WemetaSwitch
-              checked={checked}
-              onChange={(checked) => setChecked(checked)}
-            ></WemetaSwitch>
-          </View>
-        </View>
-        <View
-          className={`rounded-card ${
-            listStyle === "list" ? "rounded-card-actived" : ""
-          }`}
-          onClick={() => {
-            handleListStyleChange("list");
-          }}
-        >
-          <View className="mb-8 text-14 font-medium leading-22">列表形式</View>
-          <View className="mb-12 text-12 leading-20 text-gray-45">
-            将知识点以简洁列表呈现,清晰快速地提供信息。
+      <StyleFilter listStyle={listStyle} setListStyle={setListStyle}>
+        <View className="flex-1 text-12 leading-20 text-gray-45">
+            共 0 个文件
           </View>
-        </View>
-      </Popup>
-    </>
+      </StyleFilter>
+      
+      {/* 知识库内容 */}
+      {renderScrollList()}
+        
+      
+    </View>
   );
 };
 

+ 20 - 93
src/pages/knowledge/components/CorrectionList/index.tsx

@@ -11,52 +11,30 @@ import { useState } from "react";
 
 import ViewStyleListCorrection from "../view-style/ViewStyleListCorrection";
 
-import PickerSingleColumn from "@/components/Picker/PickerSingleColumn";
-import IconArrowDownRounded from "@/components/icon/IconArrowDownRounded";
-import { useUserStore } from "@/store/userStore";
 import { TEntItem } from "@/types/user";
 
+import CompanyList from '../CompanyList'
+import { TCorrectionItem } from "@/types/correction";
+
 type TListStyle = "card" | "list";
 
 const Index = () => {
-  const ents = useUserStore((state) => state.entList);
   const [checked, setChecked] = useState(false);
   const [showPopup, setShowPopup] = useState(false);
   const [listStyle, setListStyle] = useState<TListStyle>("card");
   const [current, setCurrent] = useState<TEntItem | string>("");
+  const [list, setList] = useState<TCorrectionItem[]>([]);
 
-  // 默认设一个值,先去加载
-  const [list, setList] = useState<any[]>([1]);
-
-  const handleListStyleChange = (listStyle: TListStyle) => {
-    setListStyle(listStyle);
-  };
-
-  // 当前选中的值
-  const options = ["个人知识库", ...ents.map((item) => item.entName)];
-
-  // 如果没有当前企业,则默认第一个
-  if (!current) {
-    setCurrent(options[0]);
-  }
-  // 是否显示选择器
-  const [showPicker, setShowPicker] = useState(false);
-
-  // 当前选中的值
-  const [selected, setSelected] = useState(options[0]);
-
-  const handleChange = (value: string) => {
-    setSelected(value);
-    const ent = ents.find((item) => item.entName === value);
-    if (ent) {
-      setCurrent(ent);
-    } else {
-      setCurrent(value);
-    }
-  };
+  const extraEnt: TEntItem[] = [{
+    entName: '个人知识库',
+    entId: -1,
+    expireTime: '0',
+    isExpired: false,
+    knowledgeCnt: 0
+  }]
 
   // 渲染数据内容
-  const renderContent = () => {
+  const renderScrollContent = () => {
     const entId = typeof current === "string" ? undefined : current.entId;
     if (listStyle === "card") {
       return (
@@ -77,7 +55,7 @@ const Index = () => {
   };
 
   // 渲染主体
-  const renderTabContent = () => {
+  const renderEmpty = () => {
     // 空数据
     if (!list.length) {
       return (
@@ -94,69 +72,18 @@ const Index = () => {
         </View>
       );
     }
-    // 
-    return (
-      <>
-        <View className="px-16 pb-20">
-          <View className="pb-8">
-            <PickerSingleColumn
-              options={options}
-              selected={selected}
-              onChange={handleChange}
-              showPicker={showPicker}
-              setShowPicker={setShowPicker}
-            >
-              <View
-                className="flex items-center gap-2 bg-gray-3 rounded-12 p-12 mb-16"
-                onClick={() => setShowPicker(true)}
-              >
-                <View className="flex-1 text-14 leading-22 text-gray-45">
-                  {selected}
-                </View>
-                <View className="flex-center">
-                  <IconArrowDownRounded />
-                </View>
-              </View>
-            </PickerSingleColumn>
-          </View>
-          <View className="flex items-center">
-            <View className="flex-1 text-12 leading-20 text-gray-45">
-              {/* 共 {listStyle === 'chat' ? total : listTotalCount} 个文件 */}
-            </View>
-            <View className="flex items-center">
-              {listStyle === "card" ? (
-                <RoundedLabel
-                  onClick={() => setShowPopup(true)}
-                  text="信息流"
-                  icon={IconFilterFeeds}
-                ></RoundedLabel>
-              ) : (
-                <>
-                  <RoundedLabel
-                    text="列表"
-                    onClick={() => {
-                      setShowPopup(true);
-                    }}
-                    icon={IconFilterList}
-                  ></RoundedLabel>
-                </>
-              )}
-            </View>
-          </View>
-        </View>
-        <View className="px-16 h-full">{renderContent()}</View>
-      </>
-    );
+    return <></>
   };
 
   return (
     <>
-      <View className="pt-12 h-full">
-        <View className="rounded-container-header"></View>
-        {renderTabContent()}
+      <View className="px-16 h-full">
+        <CompanyList extraEnt={extraEnt}></CompanyList>
+        {renderEmpty()}
+        {renderScrollContent()}
       </View>
 
-      <Popup setShow={setShowPopup} show={showPopup} title="展示样式">
+      {/* <Popup setShow={setShowPopup} show={showPopup} title="展示样式">
         <View
           className={`rounded-card ${
             listStyle === "card" ? "rounded-card-actived" : ""
@@ -190,7 +117,7 @@ const Index = () => {
             将知识点以简洁列表呈现,清晰快速地提供信息。
           </View>
         </View>
-      </Popup>
+      </Popup> */}
     </>
   );
 };

+ 38 - 18
src/pages/knowledge/components/view-style/ViewStyleList.tsx → src/pages/knowledge/components/PersonalTab/components/ScrollList.tsx

@@ -3,40 +3,60 @@ import { ScrollView, View, Image } from "@tarojs/components";
 import FigureList from "@/components/list/FigureList";
 import FigureListItem from "@/components/list/FigureListItem";
 import { useDidShow } from "@tarojs/taro";
-import { useEffect } from "react";
+import { useEffect, useState } from "react";
 
 import RotateLoading from "@/components/rotate-loading";
 import Taro from "@tarojs/taro";
 
-import { useKnowledgeStore } from "@/store/knowledge";
-import type { TKnowledgeItem } from "@/types/knowledge";
+
 import { EKnowlegeTypes } from "@/consts/enum";
 import KnowledgeIcon from "@/components/KnowledgeIcon";
 import EmptyData from "@/components/empty-data";
+
+
+import type { TKnowledgeItem } from "@/types/knowledge";
+
+import {
+  getKnowledgeList,
+} from "@/service/knowledge";
+
+import { useLoadMore } from "@/utils/loadMore";
+
 export interface IProps {
   types?: EKnowlegeTypes[]
 }
 const Index = ({types}: IProps) => {
   
-  const { listItems, listScrollTop, loadMoreList, initLoadList, setListTypes } = useKnowledgeStore();
+  const [scrollTop, setScrollTop] = useState(9999)
+  const [list, setList] = useState<TKnowledgeItem[]>([]);
 
-  
+  const fetcher = async ([_url, nextId, page, pageSize, types]) => {
+    const res = await getKnowledgeList({ startId: nextId, pageSize, types });
+    return res.data;
+  };
+  const { data, loadMore } = useLoadMore<TKnowledgeItem[]>({
+    url: `getKnowledgeList${types}`,
+    fetcher,
+    params: [types]
+  });
 
   const onScrollToUpper = async () => {
     console.log('toUpper')
-    loadMoreList()
+    loadMore()
   }
 
-  useDidShow(()=> {
-    loadMoreList(true)
-  })
-
-  useEffect(()=> {
-    if(types){
-      setListTypes(types)
+  useEffect(() => {
+    if (data?.data) {
+      setList([...list, ...data.data]);
+      setScrollTop(prev => prev + 1)
     }
-    initLoadList()
-  }, [])
+  }, [data]);
+
+  useEffect(() => {
+    loadMore();
+  }, []);
+
+  
 
   const handleEdit = (item: TKnowledgeItem)=> {
     if(item.parseStatus !== 'parsed'){
@@ -62,15 +82,15 @@ const Index = ({types}: IProps) => {
     <ScrollView
       scrollY
       onScrollToUpper={onScrollToUpper}
-      scrollTop={listScrollTop}
+      scrollTop={scrollTop}
       style={{
         flex: 1,
         height: "100%", // 高度自适应
       }}
     >
-      {listItems.length<=0 ? <EmptyData type={2}/> : <></>}
+      {list.length<=0 ? <EmptyData type={2}/> : <></>}
       <FigureList>
-      {listItems.map(item => {
+      {list.map(item => {
         return <FigureListItem
             figure={()=> <KnowledgeIcon data={item}/>}
             underline

Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 24 - 3
src/pages/knowledge/components/PersonalTab/components/ScrollListChat.tsx


+ 14 - 125
src/pages/knowledge/components/PersonalTab/index.tsx

@@ -1,104 +1,35 @@
-import { Text, View, Image } from "@tarojs/components";
-import RoundedLabel from "../RoundedLabel";
-import IconFilterFeeds from "@/components/icon/IconFilterFeeds";
-import IconFilterBatch from "@/components/icon/IconFilterBatch";
-import IconFilterList from "@/components/icon/IconFilterList";
+import { Text, View } from "@tarojs/components";
 
 import IconPlusBig from "@/components/icon/icon-plus-big";
-import IconFIlePDF from "@/components/icon/IconFilePDF";
-import IconFIleXLSX from "@/components/icon/IconFileXLSX";
-
-import FigureList from "@/components/list/FigureList";
-import FigureListItem from "@/components/list/FigureListItem";
 
 import Popup from "@/components/popup/popup";
-import WemetaSwitch from "@/components/WemetaSwitch";
-import { useEffect, useState } from "react";
+import { useState } from "react";
 
-import ViewStyleChat from "../view-style/ViewStyleChat";
-import ViewStyleList from "../view-style/ViewStyleList";
-import Taro from "@tarojs/taro";
+import ScrollListChat from "./components/ScrollListChat";
+import ScrollList from "./components/ScrollList";
 import WeComQRcode from '@/components/WeComQRcode'
 
-import { useKnowledgeStore } from "@/store/knowledge";
-type TListStyle = "chat" | "list";
+import StyleFilter, {TListStyle} from '../StyleFilter'
 
 const Index = () => {
-  const [checked, setChecked] = useState(false);
-  const [showPopup, setShowPopup] = useState(false);
   const [showAiAsistant, setShowAiAsistant] = useState(false);
   const [listStyle, setListStyle] = useState<TListStyle>("chat");
 
-  const { total } = useKnowledgeStore()
-
-  const handleListStyleChange = (listStyle: TListStyle) => {
-    setListStyle(listStyle);
-  };
 
   const handleShowAsistantTip = () => {
     setShowAiAsistant(true)
-    // Taro.chooseMessageFile({
-    //   count: 1,
-    //   type: "all",
-    //   async success(res) {
-        
-    //     const tempFilePaths = res.tempFiles;
-    //     Taro.showLoading()
-    //     const result = await uploadKnowledgeFile({
-    //       tmpPath: tempFilePaths[0].path,
-    //       fileName: "field",
-    //     });
-    //     Taro.hideLoading()
-    //     if(result){
-    //       loadMore(true)
-    //     }
-
-    //   },
-    // });
   };
 
   return (
-    <>
-      <View className="pt-12 h-full">
-        <View className="rounded-container-header"></View>
-        <View className="px-16 pb-20">
-          <View className="flex items-center">
-            <View className="flex-1 text-12 leading-20 text-gray-45">
-              共{total}个文件
-            </View>
-            <View className="flex items-center">
-              {listStyle === "chat" ? (
-                <RoundedLabel
-                  onClick={() => setShowPopup(true)}
-                  text="信息流"
-                  icon={IconFilterFeeds}
-                ></RoundedLabel>
-              ) : (
-                <>
-                  <RoundedLabel
-                    onClick={() => {
-                      console.log("batch");
-                    }}
-                    text="批量"
-                    icon={IconFilterBatch}
-                  ></RoundedLabel>
-                  <RoundedLabel
-                    text="列表"
-                    onClick={() => {
-                      setShowPopup(true)
-                    }}
-                    icon={IconFilterList}
-                  ></RoundedLabel>
-                </>
-              )}
-            </View>
+    <View className="h-full">
+      <StyleFilter listStyle={listStyle} setListStyle={setListStyle}>
+        <View className="flex-1 text-12 leading-20 text-gray-45">
+            共 0 个文件
           </View>
-        </View>
-        <View className="px-16  h-full">
-          
-            {listStyle === "chat" ? <ViewStyleChat /> : <ViewStyleList />}
-          
-        </View>
+      </StyleFilter>
+
+      <View className="px-16  h-full">
+        {listStyle === "chat" ? <ScrollListChat /> : <ScrollList />}
       </View>
 
       <View
@@ -119,49 +50,7 @@ const Index = () => {
           <WeComQRcode />
         </View>
       </Popup>
-
-      <Popup setShow={setShowPopup} show={showPopup} title="展示样式">
-        <View
-          className={`rounded-card ${
-            listStyle === "chat" ? "rounded-card-actived" : ""
-          }`}
-          onClick={() => {
-            handleListStyleChange("chat");
-          }}
-        >
-          <View className="border-bottom1-gray mb-12">
-            <View className="mb-8 text-14 font-medium leading-22">
-              对话信息流
-            </View>
-            <View className="mb-12 text-12 leading-20 text-gray-45">
-              以对话形式展示,模拟自然的对话流程。
-            </View>
-          </View>
-          <View className="flex items-center">
-            <View className="flex-1 text-14 font-medium leading-22">
-              仅显示 AI 助手信息
-            </View>
-            <WemetaSwitch
-              checked={checked}
-              onChange={(checked) => setChecked(checked)}
-            ></WemetaSwitch>
-          </View>
-        </View>
-        <View
-          className={`rounded-card ${
-            listStyle === "list" ? "rounded-card-actived" : ""
-          }`}
-          onClick={() => {
-            handleListStyleChange("list");
-          }}
-        >
-          <View className="mb-8 text-14 font-medium leading-22">列表形式</View>
-          <View className="mb-12 text-12 leading-20 text-gray-45">
-            将知识点以简洁列表呈现,清晰快速地提供信息。
-          </View>
-        </View>
-      </Popup>
-    </>
+    </View>
   );
 };
 

+ 107 - 0
src/pages/knowledge/components/StyleFilter/index.tsx

@@ -0,0 +1,107 @@
+import { View } from "@tarojs/components";
+import RoundedLabel from "../RoundedLabel";
+import IconFilterFeeds from "@/components/icon/IconFilterFeeds";
+import IconFilterBatch from "@/components/icon/IconFilterBatch";
+import IconFilterList from "@/components/icon/IconFilterList";
+
+import Popup from "@/components/popup/popup";
+import WemetaSwitch from "@/components/WemetaSwitch";
+import { useState } from "react";
+export type TListStyle = "chat" | "list";
+interface IProps {
+  listStyle?: TListStyle
+  setListStyle: (style: TListStyle)=>void
+  children: JSX.Element
+}
+
+const Index = ({listStyle = "chat", setListStyle, children}: IProps) => {
+  const [checked, setChecked] = useState(false);
+  const [showPopup, setShowPopup] = useState(false);
+
+
+  const handleListStyleChange = (listStyle: TListStyle) => {
+    setListStyle(listStyle);
+  };
+
+  return (
+    <>
+      <View className="px-16 pb-20">
+        <View className="flex items-center">
+          <View className="flex-1 text-12 leading-20 text-gray-45">
+            {children}
+          </View>
+          <View className="flex items-center">
+            {listStyle === "chat" ? (
+              <RoundedLabel
+                onClick={() => setShowPopup(true)}
+                text="信息流"
+                icon={IconFilterFeeds}
+              ></RoundedLabel>
+            ) : (
+              <>
+                {/* <RoundedLabel
+                  onClick={() => {
+                    console.log("batch");
+                  }}
+                  text="批量"
+                  icon={IconFilterBatch}
+                ></RoundedLabel> */}
+                <RoundedLabel
+                  text="列表"
+                  onClick={() => {
+                    setShowPopup(true)
+                  }}
+                  icon={IconFilterList}
+                ></RoundedLabel>
+              </>
+            )}
+          </View>
+        </View>
+      </View>
+      <Popup setShow={setShowPopup} show={showPopup} title="展示样式">
+        <View
+          className={`rounded-card ${
+            listStyle === "chat" ? "rounded-card-actived" : ""
+          }`}
+          onClick={() => {
+            handleListStyleChange("chat");
+          }}
+        >
+          <View className="border-bottom1-gray mb-12">
+            <View className="mb-8 text-14 font-medium leading-22">
+              对话信息流
+            </View>
+            <View className="mb-12 text-12 leading-20 text-gray-45">
+              以对话形式展示,模拟自然的对话流程。
+            </View>
+          </View>
+          <View className="flex items-center">
+            <View className="flex-1 text-14 font-medium leading-22">
+              仅显示 AI 助手信息
+            </View>
+            <WemetaSwitch
+              checked={checked}
+              onChange={(checked) => setChecked(checked)}
+            ></WemetaSwitch>
+          </View>
+        </View>
+        <View
+          className={`rounded-card ${
+            listStyle === "list" ? "rounded-card-actived" : ""
+          }`}
+          onClick={() => {
+            handleListStyleChange("list");
+          }}
+        >
+          <View className="mb-8 text-14 font-medium leading-22">列表形式</View>
+          <View className="mb-12 text-12 leading-20 text-gray-45">
+            将知识点以简洁列表呈现,清晰快速地提供信息。
+          </View>
+        </View>
+      </Popup>
+    </>
+  );
+
+};
+
+export default Index;

+ 0 - 9
src/pages/knowledge/components/container-header/index.module.less

@@ -1,9 +0,0 @@
-.container{
-  width: 100%;
-  border-top-left-radius: 24px;
-  border-top-right-radius: 24px;
-  padding-top: 20px;
-  border-top-width: 1px;
-  border-top: 1px solid #FFFFFF;
-  backdrop-filter: blur(38px);
-}

+ 0 - 13
src/pages/knowledge/components/container-header/index.tsx

@@ -1,13 +0,0 @@
-import { View } from '@tarojs/components';
-import style from './index.module.less'
-
-const Index = () => {
-  
-  return (
-    <View className={style.container}>
-      
-    </View>
-  )
-}
-
-export default Index;

+ 26 - 18
src/pages/knowledge/index.tsx

@@ -3,42 +3,50 @@
  */
 
 import { View, Text } from "@tarojs/components";
-import { useState } from "react";
 import PageCustom from "@/components/page-custom/index";
 import NavBarNormal from "@/components/NavBarNormal/index";
 import WemetaTabs from "@/components/wemeta-tabs/index";
-import PersonalTab from './components/PersonalTab'
-import CompanyTab from './components/CompanyTab'
-import CorrectionList from './components/CorrectionList'
+import PersonalTab from "./components/PersonalTab";
+import CompanyTab from "./components/CompanyTab";
+import CorrectionList from "./components/CorrectionList";
 import style from "./index.module.less";
 
+// 渲染统一容器带高光圆角的头部
+const renderTabContainer = (children: JSX.Element) => {
+  return (
+    <View className={style.tabContent}>
+      <View className="pt-12 h-full">
+        <View className="rounded-container-header"></View>
+        {children}
+      </View>
+    </View>
+  );
+};
+
 export default function Index() {
   const tabList = [
     {
       key: "1",
       label: "个人知识",
-      children: <View className={style.tabContent}>
-        <PersonalTab />
-      </View> ,
+      children: renderTabContainer(<PersonalTab />),
     },
     {
       key: "2",
       label: "企业知识",
-      children: <View className={style.tabContent}>
-          <CompanyTab/>
-      </View>,
-    },
-    {
-      key: "3",
-      label: "纠错记录",
-      children: <View className={style.tabContent}>
-          <CorrectionList /> 
-      </View>,
+      children: renderTabContainer(<CompanyTab />),
     },
+    // {
+    //   key: "3",
+    //   label: "纠错记录",
+    //   children: renderTabContainer(<CorrectionList />),
+    // },
   ];
   return (
     <PageCustom>
-      <NavBarNormal scrollFadeIn leftColumn={() => <Text className="text-16 font-medium">知识库</Text>}></NavBarNormal>
+      <NavBarNormal
+        scrollFadeIn
+        leftColumn={() => <Text className="text-16 font-medium">知识库</Text>}
+      ></NavBarNormal>
       <View className="w-full">
         <View className={style.container}>
           <WemetaTabs current="1" list={tabList} className="px-16"></WemetaTabs>

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

@@ -102,7 +102,7 @@ export default function Profile() {
         <NavBarNormal
           leftColumn={renderNavBarLeft}
         ></NavBarNormal>
-        <View className="blurBg">
+        <View className="blur-rounded-container">
           {agentProfile && (
             <>
               <SummaryBar isVisitor agent={agentProfile}></SummaryBar>

+ 0 - 128
src/store/knowledge.ts

@@ -1,128 +0,0 @@
-import { create } from "zustand";
-
-import { isSuccess } from "@/utils";
-import type { TKnowledgeStreamResponseData, TKnowledgeItem } from "@/types/knowledge";
-
-import {
-  getMyKnowledgeStream as _getMyKnowledgeStream,
-  getKnowledgeList as _getKnowledgeList,
-} from "@/service/knowledge";
-import { EKnowlegeTypes } from "@/consts/enum";
-
-export interface KnowledgeStoreState {
-  scrollTop: number;
-  total: number;
-  list: TKnowledgeStreamResponseData[];
-  isLoading: boolean;
-  startId?: string;
-  // List view specific state
-  listTypes?: EKnowlegeTypes[]
-  listScrollTop: number;
-  listTotalCount: number;
-  listItems: TKnowledgeItem[];
-  listStartId?: string;
-  listLoading: boolean;
-  loadMore: (force?: boolean) => Promise<void>;
-  initLoad: () => Promise<void>;
-  // List view specific functions
-  loadMoreList: (force?: boolean) => Promise<void>;
-  initLoadList: () => Promise<void>;
-  setListTypes: (types: EKnowlegeTypes[])=> void
-}
-
-export const useKnowledgeStore = create<KnowledgeStoreState>((set, get) => ({
-  scrollTop: 9999,
-  total: 10000,
-  list: [],
-  isLoading: false,
-  startId: undefined,
-  // List view specific state
-  listTypes: [],
-  listScrollTop: 9999,
-  listTotalCount: 9999,
-  listItems: [],
-  listStartId: undefined,
-  listLoading: false,
-  loadMore: async (force) => {
-    const { list, total, isLoading, startId } = get();
-    
-    if (!force && (list.length >= total || isLoading)) {
-      return;
-    }
-
-    set({ isLoading: true });
-    
-    try {
-      const response = await _getMyKnowledgeStream({
-        startId,
-        pageSize: 10,
-      });
-
-      const result = isSuccess(response.status);
-      if (result) {
-        // 请求到的数组倒序后排在数组前面
-        const newData = [...response.data.data.reverse(), ...list];
-        set({
-          list: newData,
-          startId: response.data.nextId,
-          total: response.data.totalCount ?? 0,
-        });
-      }
-    } finally {
-      set({ isLoading: false, scrollTop: get().scrollTop + 1 });
-    }
-  },
-  // 重新初始化加载
-  initLoad: async() => {
-    set({
-      list: [],
-      startId: undefined,
-      total: 9999,
-      isLoading: false,
-    })
-    console.log('initLoad')
-    await get().loadMore()
-  },
-  // 列表视图-加载
-  loadMoreList: async (force) => {
-    const { listItems, listTotalCount, listLoading, listStartId, listTypes } = get();
-    
-    if (!force && (listItems.length >= listTotalCount || listLoading)) {
-      return;
-    }
-
-    set({ listLoading: true });
-    
-    try {
-      const response = await _getKnowledgeList({
-        startId: listStartId,
-        pageSize: 10,
-        types: listTypes,
-      });
-
-      const result = isSuccess(response.status);
-      if (result) {
-        const newData = [...response.data.data, ...listItems];
-        set({
-          listItems: newData,
-          listStartId: response.data.nextId,
-          listTotalCount: response.data.totalCount,
-        });
-      }
-    } finally {
-      set({ listLoading: false, listScrollTop: get().listScrollTop + 1 });
-    }
-  },
-  setListTypes: (types)=> {
-    set({listTypes: types})
-  },
-  initLoadList: async() => {
-    set({
-      listItems: [],
-      listStartId: undefined,
-      listTotalCount: 9999,
-      listLoading: false,
-    })
-    await get().loadMoreList()
-  }
-}));

+ 0 - 145
src/store/knowledgeEnt.ts

@@ -1,145 +0,0 @@
-/**
- * 企业知识库
- */
-import { create } from "zustand";
-
-import { isSuccess } from "@/utils";
-import type { TKnowledgeStreamResponseData, TKnowledgeItem } from "@/types/knowledge";
-
-import {
-  getEntKnowledgeStream as _getMyKnowledgeStream,
-  getEntKnowledgeList as _getKnowledgeList,
-} from "@/service/knowledge";
-
-type TEnt = {entId: string|number, entName: string}
-
-export interface KnowledgeEntStoreState {
-  scrollTop: number;
-  total: number;
-  list: TKnowledgeStreamResponseData[];
-  isLoading: boolean;
-  startId?: string;
-  ent?: TEnt|null;
-  // List view specific state
-  listScrollTop: number;
-  listTotalCount: number;
-  listItems: TKnowledgeItem[];
-  listStartId?: string;
-  listLoading: boolean;
-  loadMore: (force?: boolean) => Promise<void>;
-  initLoad: () => Promise<void>;
-  // List view specific functions
-  loadMoreList: (force?: boolean) => Promise<void>;
-  initLoadList: () => Promise<void>;
-  
-  setEnt: (ent: TEnt) => void
-}
-
-// todo: 可用工厂函数方式与 useKnowledgeStore 合并成一个 store
-export const useKnowledgeEntStore = create<KnowledgeEntStoreState>((set, get) => ({
-  scrollTop: 9999,
-  total: 10000,
-  list: [],
-  isLoading: false,
-  startId: undefined,
-  ent: null,
-  // List view specific state
-  listScrollTop: 9999,
-  listTotalCount: 9999,
-  listItems: [],
-  listStartId: undefined,
-  listLoading: false,
-  loadMore: async (force) => {
-    const { list, total, isLoading, startId, ent } = get();
-    
-    if (!force && (list.length >= total || isLoading)) {
-      return;
-    }
-    if(!ent?.entId){
-      return
-    }
-    set({ isLoading: true });
-    
-    try {
-      const response = await _getMyKnowledgeStream({
-        startId,
-        entId: ent?.entId,
-        pageSize: 10,
-      });
-
-      const result = isSuccess(response.status);
-      if (result) {
-        // 请求到的数组倒序后排在数组前面
-        const newData = [...response.data.data.reverse(), ...list];
-        set({
-          list: newData,
-          startId: response.data.nextId,
-          total: response.data.totalCount ?? 0,
-        });
-      }
-    } finally {
-      set({ isLoading: false, scrollTop: get().scrollTop + 1 });
-    }
-  },
-  // 重新初始化加载
-  initLoad: async() => {
-    set({
-      list: [],
-      startId: undefined,
-      total: 9999,
-      isLoading: false,
-    })
-    console.log('initLoad')
-    await get().loadMore()
-  },
-  // 列表视图-加载
-  loadMoreList: async (force) => {
-    const { listItems, listTotalCount, listLoading, listStartId, ent } = get();
-    
-    if (!force && (listItems.length >= listTotalCount || listLoading)) {
-      return;
-    }
-
-    if(!ent?.entId){
-      return
-    }
-
-    set({ listLoading: true });
-    
-    try {
-      const response = await _getKnowledgeList({
-        startId: listStartId,
-        entId: ent?.entId,
-        pageSize: 10,
-      });
-
-      const result = isSuccess(response.status);
-      if (result) {
-        const newData = [...response.data.data, ...listItems];
-        set({
-          listItems: newData,
-          listStartId: response.data.nextId,
-          listTotalCount: response.data.totalCount,
-        });
-      }
-    } finally {
-      set({ listLoading: false, listScrollTop: get().listScrollTop + 1 });
-    }
-  },
-  initLoadList: async() => {
-    set({
-      listItems: [],
-      listStartId: undefined,
-      listTotalCount: 9999,
-      listLoading: false,
-    })
-    await get().loadMoreList()
-  },
-  setEnt: (ent)=> {
-    set(
-      {
-        ent: ent
-      }
-    )
-  }
-}));

+ 9 - 3
src/types/user.ts

@@ -6,12 +6,18 @@ export type TUserInfo = {
   userName?: string;
 };
 
+
+// entId (integer, optional): 企业 ID ,
+// entName (string, optional): 企业名称 ,
+// expireTime (string, optional): 到期时间 ,
+// isExpired (boolean, optional): 是否已到期 ,
+// knowledgeCnt (integer, optional): 企业知识库统计数
 export type TEntItem = {
   entId: number | string;
   entName: string;
-  expireTime: string;
-  isExpired: boolean;
-  knowledgeCnt: number;
+  expireTime?: string;
+  isExpired?: boolean;
+  knowledgeCnt?: number;
 };
 
 export type TMyContact = {

+ 7 - 0
src/utils/loadMore.ts

@@ -26,6 +26,13 @@ export const useLoadMore = <T>({url, fetcher, startId, pageIndex=1,  pageSize =
     // key 数组,当这些值变化时会重新请求
     [url, nextId, page, pageSize, ...params],
     fetcher,
+    {
+      onErrorRetry(err, key, config, revalidate, revalidateOpts) {
+        if(err.status === 404) return 
+        if(err.status === 401) return
+        if(revalidateOpts.retryCount >=3 )return
+      },
+    }
   )
 
   

Některé soubory nejsou zobrazeny, neboť je v těchto rozdílových datech změněno mnoho souborů