Browse Source

feat: 新编辑接口

王晓东 1 month ago
parent
commit
84e945f987
40 changed files with 676 additions and 417 deletions
  1. 4 1
      package.json
  2. 1 1
      project.private.config.json
  3. 4 1
      src/app.less
  4. 3 3
      src/components/AgentPage/components/AgentActionBar/index.tsx
  5. 6 9
      src/components/AgentPage/components/AgentSwap/index.tsx
  6. 4 4
      src/components/AgentPage/index.tsx
  7. 4 3
      src/components/GlobalModal/index.tsx
  8. 9 6
      src/components/NavBarNormal/index.tsx
  9. 7 4
      src/components/TextPolish/index.tsx
  10. 3 3
      src/components/WemetaModal/index.module.less
  11. 9 7
      src/components/WemetaModal/index.tsx
  12. 59 3
      src/components/WemetaTextareaAI/index.module.less
  13. 48 34
      src/components/WemetaTextareaAI/index.tsx
  14. 14 11
      src/pages/agent-avatars/index.tsx
  15. 4 3
      src/pages/agent-gen/components/step/StepConfirm.tsx
  16. 3 2
      src/pages/agent/components/AgentSetting/components/AgentCard/index.tsx
  17. 3 3
      src/pages/agent/components/AgentSetting/components/AgentContactCard/index.tsx
  18. 3 2
      src/pages/agent/components/AgentSetting/components/AgentKnowledgeLib/index.tsx
  19. 19 4
      src/pages/agent/components/AgentSetting/components/AgentSettingList/index.tsx
  20. 10 9
      src/pages/agent/components/AgentSetting/index.tsx
  21. 53 8
      src/pages/agent/index.tsx
  22. 3 3
      src/pages/chat/hooks/useChatAgent.ts
  23. 3 2
      src/pages/component-library/index.tsx
  24. 6 5
      src/pages/dashboard/components/AgentList/index.tsx
  25. 3 2
      src/pages/dashboard/index.tsx
  26. 1 1
      src/pages/dislike-messages/index.tsx
  27. 4 3
      src/pages/editor-pages/editor-greeting-questions/index.tsx
  28. 2 2
      src/pages/editor-pages/editor-link-contact/components/MyAgentsScrollList/index.tsx
  29. 4 4
      src/pages/index/components/InitView/index.tsx
  30. 9 13
      src/pages/index/components/WelcomeTips/index.tsx
  31. 5 4
      src/pages/index/index.tsx
  32. 1 1
      src/pages/knowledge-item/index.tsx
  33. 1 1
      src/pages/knowledge/components/CorrectionTab/components/CorrectionList.tsx
  34. 1 1
      src/pages/knowledge/components/CorrectionTab/components/CorrectionListChat.tsx
  35. 1 1
      src/pages/voice/components/MyVoiceList/index.tsx
  36. 5 3
      src/pages/voice/index.tsx
  37. 70 36
      src/service/agent.ts
  38. 256 196
      src/store/agentStore.ts
  39. 27 15
      src/store/modalStore.ts
  40. 4 3
      src/types/agent.ts

+ 4 - 1
package.json

@@ -9,6 +9,9 @@
     "css": "Less",
     "framework": "React"
   },
+  "engines": {
+    "node": "^v18.17.0"
+  },
   "scripts": {
     "devbuild:weapp": "taro build --type weapp --watch --env production",
     "dev:weapp": "npm run build:weapp -- --watch",
@@ -40,7 +43,7 @@
     "Android >= 4.1",
     "ios >= 8"
   ],
-  "author": "",
+  "author": "sheldon1930@gmail.com",
   "dependencies": {
     "@babel/runtime": "^7.21.5",
     "@taro-hooks/plugin-react": "^2.2.0",

+ 1 - 1
project.private.config.json

@@ -11,7 +11,7 @@
         {
           "name": "pages/agent/index",
           "pathName": "pages/agent/index",
-          "query": "agentId=p_2e73c9d7efaYfDo2-agent_2685",
+          "query": "",
           "scene": null,
           "launchMode": "default"
         }

+ 4 - 1
src/app.less

@@ -6,7 +6,7 @@
 
 /* 确保变量定义在全局作用域 */
 /* 为 RootPortal 容器单独定义变量 */
-:root, .taro-portal-container, page  {
+:root, .taro-portal-container, page, view  {
   font-family: PingFangSC-Regular;
   --color-primary: #327BF9;
   --color-primary-rgb: 49, 124, 250;
@@ -22,7 +22,10 @@
   --color-gray-5: rgba(17, 17, 17, 0.65); // 副标题,描述文本
   --color-gray-6: rgba(17, 17, 17, 0.85); // 正文
   --color-gray-7: rgba(17, 17, 17, 1); // 特殊标题,主标题,正文
+  --gutter-size: 16px;
 }
+
+
 .taro-portal-container-ztop{
   z-index: 10000;
 }

+ 3 - 3
src/components/AgentPage/components/AgentActionBar/index.tsx

@@ -19,7 +19,7 @@ import PopupSheets from "@/components/popup/popup-sheets";
 
 import { useModalStore } from "@/store/modalStore";
 import { TAgentDetail } from "@/types/agent";
-import { useAgentStore } from "@/store/agentStore";
+import { useAgentStore, useAgentStoreActions } from "@/store/agentStore";
 import LoginPopup from "@/components/LoginPopup";
 
 interface IProps {
@@ -33,10 +33,10 @@ export default ({agent, isVisitor}: IProps) => {
   const [showPopup, setShowPopup] = useState(false);
   const [showShare, setShowShare] = useState(false);
   const [showLogin, setShowLogin] = useState(false);
-  const { deleteAgent } = useAgentStore()
+  const { deleteAgent } = useAgentStoreActions();
 
 
-  const {showModal,} = useModalStore()
+  const {showModal} = useModalStore((state) => state.actions);
   const isLogin = useIsLogin();
   const handleClick = ()=> {
     // 如果是未登录状态下想要去聊天, 则弹窗登录

+ 6 - 9
src/components/AgentPage/components/AgentSwap/index.tsx

@@ -5,7 +5,7 @@ import TagCertificated from "@/components/tag-certificated";
 import IconPlusBlue from "@/components/icon/icon-plus-blue";
 import Popup from "@/components/popup/popup";
 import WemetaTabs from "@/components/wemeta-tabs/index";
-import { useAgentStore } from "@/store/agentStore";
+import { useAgentStore, useAgentStoreActions } from "@/store/agentStore";
 import { TAgent } from "@/types/agent";
 import Taro from "@tarojs/taro";
 import ContactIcon from "@/components/ContactIcon";
@@ -16,7 +16,8 @@ interface IProps {
   setShow: (show: boolean) => void;
 }
 export default ({ show, setShow }: IProps) => {
-  const { agents, setDefaultAgent, fetchAgents, createAgent } = useAgentStore();
+  const agents = useAgentStore((state) => state.agents);
+  const { setDefaultAgent, fetchAgents, clearMyAgent } = useAgentStoreActions();
   let loading = false;
   const personalAgents = agents.filter((item) => !item.isEnt);
   const entAgents = agents.filter((item) => item.isEnt);
@@ -49,13 +50,9 @@ export default ({ show, setShow }: IProps) => {
     }
     loading = true;
     try{
-      const response = await createAgent()
-      Taro.hideLoading()
+      Taro.navigateTo({ url: `/pages/agent/index` });
       loading = false;
       setShow(false)
-      if(response?.agentId){
-        Taro.navigateTo({ url: `/pages/agent/index?agentId=${response.agentId}` });
-      }
     }catch(e:any){
       Taro.hideLoading()
       loading = false;
@@ -142,8 +139,8 @@ export default ({ show, setShow }: IProps) => {
                 {renderPersonalAgents()}
               </View>
             </View>
-            <View className="absolute left-0 right-0 bottom-0 z-10 bg-white pt-14">
-              <View className="button-rounded button-primary-light gap-8 mb-15" onClick={handleCreate}>
+            <View className="absolute left-0 right-0 bottom-0 z-10 bg-white pt-14" onClick={handleCreate}>
+              <View className="button-rounded button-primary-light gap-8 mb-15">
                 <IconPlusBlue />
                 <View>创建新的智能体</View>
               </View>

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

@@ -4,7 +4,7 @@ import NavBarNormal from "@/components/NavBarNormal";
 import { View } from "@tarojs/components";
 import Logo from "@/components/logo";
 import AgentActionBar from "./components/AgentActionBar";
-import { useAgentStore } from "@/store/agentStore";
+import { useAgentStore, useAgentStoreActions } from "@/store/agentStore";
 import { useEffect, useState } from "react";
 import { useComponentStore } from "@/store/componentStore";
 import ComponentList from "@/components/component-list";
@@ -18,12 +18,12 @@ interface IProps {
   agentId: string;
 }
 export default function Index({ agentId }: IProps) {
-  const { fetchAgent } = useAgentStore();
   const agent = useAgentStore((state)=> state.agent);
+  const { fetchAgent } = useAgentStoreActions();
   const { fetchMyEntList } = useUserStore();
   const [bg, setBg] = useState('')
   const [isDefaultBg, setIsDefaultBg] = useState(false)
-  
+
   const { setComponentList } = useComponentStore()
   const components = useComponentStore((state) => state.components);
 
@@ -53,7 +53,7 @@ export default function Index({ agentId }: IProps) {
   useEffect(()=> {
     fetchMyEntList()
   }, [])
-  
+
   // 如果是默认形象,设置占位空间,点击后跳转至编辑页
   const renderDefaultPlaceholder = ()=> {
     if(!isDefaultBg){

+ 4 - 3
src/components/GlobalModal/index.tsx

@@ -3,7 +3,8 @@ import { useModalStore } from '@/store/modalStore';
 import WemetaModal from '@/components/WemetaModal'
 import { RootPortal } from '@tarojs/components';
 export function GlobalModal() {
-  const { isVisible, config, onConfirm, onCancel } = useModalStore();
+  const { isVisible, config } = useModalStore((state) => ({ isVisible: state.isVisible, config: state.config }));
+  const { onConfirm, onCancel } = useModalStore((state) => state.actions);
 
 
   if(!config?.content){
@@ -12,9 +13,9 @@ export function GlobalModal() {
 
   return (
     <RootPortal className={`taro-portal-container taro-portal-container-ztop`}>
-      <WemetaModal show={isVisible} showCancelButton={config.showCancelButton} onConfirm={()=> onConfirm() } onCancel={()=> onCancel()} >
+      <WemetaModal show={isVisible} cancelText={config.cancelText} confirmText={config.confirmText}  showCancelButton={config.showCancelButton} onConfirm={()=> onConfirm() } onCancel={()=> onCancel()} >
         <>{config.content}</>
       </WemetaModal>
       </RootPortal>
   );
-}
+}

+ 9 - 6
src/components/NavBarNormal/index.tsx

@@ -56,10 +56,13 @@ const Index: React.FC<Props> = ({
 
     if (onNavBack) {
       console.log("nav");
-      await onNavBack();
-      Taro.navigateBack({
-        delta: navDelta
-      });
+      const result = await onNavBack();
+      if(result !== false){
+        Taro.navigateBack({
+          delta: navDelta,
+        });
+      }
+
     } else {
       Taro.navigateBack();
     }
@@ -89,7 +92,7 @@ const Index: React.FC<Props> = ({
       );
     }
   };
-  
+
   const renderNavBar = () => {
     return (
       <View
@@ -98,7 +101,7 @@ const Index: React.FC<Props> = ({
         style={{
           paddingTop: `${statusBarHeight * ratio}rpx`,
         }}
-      > 
+      >
         {/* 背景毛玻璃与 渐变背景互斥 */}
         <View className={`${style.navBarBgContainer} ${blur ? style.backdropFilter : style.navBarBg}`} style={{opacity: opacity}}></View>
         <View className={`${style.navBar}`}>

+ 7 - 4
src/components/TextPolish/index.tsx

@@ -3,7 +3,7 @@ import IconStarColor from "@/components/icon/IconStarColor";
 import { textPolishing } from '@/service/agent'
 import { isSuccess } from "@/utils";
 import { useState } from "react";
-
+import Taro from '@tarojs/taro';
 interface Props {
   text: string;
   type: "personality" | "greeting"
@@ -17,32 +17,35 @@ const Index = ({
   onStateChange,
 }: Props) => {
   const [isLoading, setIsLoading] = useState(false)
-
+  const disabled =  text.length < 2
   const handleClick = async () => {
     // console.log('请求服务端润色')
-    if(isLoading){
+    if(isLoading || disabled){
       return
     }
     setIsLoading(true)
     onStateChange(true)
     try{
+      Taro.showLoading()
       const response = await textPolishing({
         content: text,
         type: type
       })
+      Taro.hideLoading()
       setIsLoading(false)
       onStateChange(false)
       if(isSuccess(response.status)){
         onPolished(response.data?.content)
       }
     }catch(e){
+      Taro.hideLoading()
       setIsLoading(false)
       onStateChange(false)
     }
   }
 
   return (
-    <View className="flex items-center gap-4" onClick={handleClick}>
+    <View className={`flex items-center gap-4 ${disabled ? 'opacity-20' : ''}`} onClick={handleClick}>
       {!isLoading ? <View className="text-primary flex flex-center"><IconStarColor color="blue"></IconStarColor><View>润色</View></View> : <View className="flex flex-center"><IconStarColor color="colorful"></IconStarColor><View className="gradient-text">润色中...</View></View>}
     </View>
   );

+ 3 - 3
src/components/WemetaModal/index.module.less

@@ -21,7 +21,7 @@
   padding: 32px;
   flex-direction: column;
   align-items: center;
-  
+
 }
 .footer{
   display: flex;
@@ -34,7 +34,7 @@
   align-items: center;
   justify-content: center;
   padding: 12px 30px;
-  color: rgba(0, 0, 0, 0.45);
+  color: var(--color-gray-6);
   text-align: center;
   font-size: 14px;
   line-height: 24px;
@@ -45,5 +45,5 @@
 }
 .footerButtonPrimary{
   .footerButton();
-  color: var(--color-primary-dark);
+  color: var(--color-primary);
 }

+ 9 - 7
src/components/WemetaModal/index.tsx

@@ -5,11 +5,13 @@ interface Props {
   children: React.ReactChild | React.ReactChild[]
   footer?: boolean
   showCancelButton?: boolean
+  confirmText?: string
+  cancelText?: string
   onCancel?: () => void
   onConfirm?: () => void
 }
-const index = ({show = false, children, onConfirm, onCancel, showCancelButton=true, footer = true}: Props) => {
-  
+const index = ({show = false, children, confirmText, cancelText, onConfirm, onCancel, showCancelButton=true, footer = true}: Props) => {
+
   const handleConfirm = () => {
     onConfirm && onConfirm()
   }
@@ -19,8 +21,8 @@ const index = ({show = false, children, onConfirm, onCancel, showCancelButton=tr
   const renderFooter = () => {
     return <>
       <View className={style.footer}>
-        {showCancelButton && <View className={style.footerButton} onClick={handleCancel}>取消</View>}
-        <View className={`${style.footerButtonPrimary}`} onClick={handleConfirm}>确定</View>
+        {showCancelButton && <View className={style.footerButton} onClick={handleCancel}>{cancelText || '取消'}</View>}
+        <View className={`${style.footerButtonPrimary}`} onClick={handleConfirm}>{confirmText || '确定'}</View>
       </View>
     </>
   }
@@ -34,12 +36,12 @@ const index = ({show = false, children, onConfirm, onCancel, showCancelButton=tr
           </View>
           {footer && renderFooter()}
         </View>
-      </View> 
-      ) 
+      </View>
+      )
     }
   }
   return <>
     {renderModal()}
   </>
 }
-export default index
+export default index

+ 59 - 3
src/components/WemetaTextareaAI/index.module.less

@@ -1,7 +1,7 @@
 .inputContainer{
   display: flex;
   flex-direction: column;
-  padding: 10px;
+  padding: var(--gutter-size);
   border-radius: 12px;
   background-color: white;
   border: 2px solid transparent;
@@ -14,8 +14,8 @@
   font-weight: 400;
   line-height: 22px;
   width: 100%;
-  min-height: 132px;
-  max-height: 200px;
+  min-height: 66px;
+  max-height: 134px;
   text-align: justify;
   color: var(--color-gray-7);
   caret-color: var(--color-primary);
@@ -38,6 +38,7 @@
 }
 .textareaContainer{
   flex: 1;
+  position: relative;
 }
 .textarea{
   .textInput();
@@ -54,3 +55,58 @@
   align-items: center;
   gap: 8px;
 }
+.skelonton{
+  position: absolute;
+  z-index: 2;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  width: 100%;
+  height: 100%;
+  background-color: white;
+  display: flex;
+  flex-direction: column;
+  gap: 8px;
+}
+.skelontonHide{
+  display: none;
+}
+.skelontonItem{
+  width: 100%;
+  height: 24px;
+  background: var(--color-gray-2);
+  position: relative;
+  overflow: hidden;
+  border-radius: 4px;
+
+  &::after {
+    content: '';
+    position: absolute;
+    top: 0;
+    left: -100%;
+    width: 100%;
+    height: 100%;
+    background: linear-gradient(
+      90deg,
+      transparent,
+      rgba(255, 255, 255, 0.4),
+      transparent
+    );
+    animation: shimmer 1.5s infinite;
+  }
+}
+
+@keyframes shimmer {
+  0% {
+    left: -100%;
+  }
+  100% {
+    left: 100%;
+  }
+}
+
+.skelontonItemShort{
+  .skelontonItem();
+  width: 50%;
+}

+ 48 - 34
src/components/WemetaTextareaAI/index.tsx

@@ -1,8 +1,7 @@
 import { View, Textarea, InputProps } from "@tarojs/components";
-import IconStarColor from "@/components/icon/IconStarColor";
 import TextPolish from '@/components/TextPolish'
 import style from "./index.module.less";
-import { useState, useRef, useEffect } from "react";
+import { useState, useRef, useCallback, useMemo } from "react";
 import { countCharacters, getStrByMaxLength } from "@/utils/index";
 interface Props {
   aiType: "personality" | "greeting"
@@ -23,7 +22,7 @@ interface Props {
   extraClass?: string;
   onConfirm?: (value: string) => void;
 }
-let isInbox = false;
+const DEFAULT_TEXTAREA_MAXLENGTH = 10000;
 const index = ({
   value,
   aiType,
@@ -44,88 +43,103 @@ const index = ({
   onConfirm,
 }: Props) => {
   const [focus, setFocus] = useState(false);
-  const [isLoading, setIsLoading] = useState(false);
+  const [isPolishing, setIsPolishing] = useState(false);
   const inputRef = useRef<HTMLInputElement>(null); // 创建一个 ref
 
+  // Memoize character count to avoid recalculation
+  const currentLength = useMemo(() => countCharacters(value), [value]);
+
   const handleFocus = () => {
-    isInbox = false;
     setFocus(true);
   };
+
   const handleBlur = () => {
-    // console.log("textarea blur");
-    if (!isInbox) {
-      setFocus(false);
-      if (onBlur && inputRef.current) {
-        onBlur(inputRef.current.value);
-      }
+    console.log("textarea blur");
+    setFocus(false);
+    if (onBlur && inputRef.current) {
+      onBlur(inputRef.current.value);
     }
   };
-  const handleInput = (value: string) => {
-    const len = countCharacters(value);
+
+  const handleInput = useCallback((inputValue: string) => {
+    if (!onInput) return;
+
+    const len = countCharacters(inputValue);
     if (maxlength && len > maxlength) {
-      const r = getStrByMaxLength(value, maxlength);
-      onInput && onInput(r);
+      const r = getStrByMaxLength(inputValue, maxlength);
+      onInput(r);
       return;
     }
-    onInput && onInput(value);
-  };
 
-  const onPolished = (text:string|null)=> {
-  if(text){
-    onInput && onInput(text);
-  }
+    onInput(inputValue);
+  }, [onInput, maxlength]);
+
+  const onPolished = (text: string | null) => {
+    if (text && onInput) {
+      onInput(text);
+    }
+  };
 
+  const handleTextareaInput = (e: any) => {
+    handleInput(e.target.value);
+  };
 
+  const handleConfirm = (e: any) => {
+    onConfirm && onConfirm(e.detail.value);
+  };
 
-}
+  // Memoize container style
+  const containerStyle = useMemo(() => {
+    return bgColor ? { backgroundColor: bgColor } : {};
+  }, [bgColor]);
 
   return (
     <View
       className={`${
         focus ? style.inputContainerFocused : style.inputContainer
       }  p-12`}
-      style={bgColor ? { backgroundColor: bgColor } : {}}
+      style={containerStyle}
     >
       <View className="flex w-full pb-12">
         <View className={style.label}>
           {prefix && prefix()}
         </View>
       <View className="flex items-center gap-4 text-14 font-pingfangSCMedium">
-        <TextPolish text={value} type={aiType} onPolished={onPolished} onStateChange={setIsLoading} />
+        <TextPolish text={value} type={aiType} onPolished={onPolished} onStateChange={setIsPolishing} />
       </View>
       </View>
 
       <View className={style.textareaContainer}>
-        {isLoading ? 'loading': 'noonon'}
         <Textarea
           ref={inputRef}
           value={value}
-          disabled={disabled}
+          disabled={disabled || isPolishing}
           confirmType={confirmType}
           style={extraStyle}
-          onInput={(e: any) => handleInput(e.target.value)}
+          onInput={handleTextareaInput}
           placeholder={placeholder}
           placeholderStyle="rgba(17,17,17,.25)"
-          className={`${style.textInput} ${extraClass}`}
+          className={`${style.textInput} ${extraClass || ''}`}
           onFocus={handleFocus}
           onBlur={handleBlur}
           autoHeight={autoHeight}
           autoFocus={autoFocus}
           cursorSpacing={cursorSpacing}
-          maxlength={10000}
-          onConfirm={(e: any) => {
-            onConfirm && onConfirm(e.detail.value);
-          }}
+          maxlength={DEFAULT_TEXTAREA_MAXLENGTH}
+          onConfirm={handleConfirm}
         />
         <View className={`${style.textareaButtons} justify-end gap-8`}>
           {extra && extra()}
-          {/* <View className={`button-rounded-mini ${!value.length ? 'disabled' :''}`} onClick={handleClear}>清除</View> */}
           {maxlength && (
             <View className="text-gray-4">
-              {maxlength}/{countCharacters(value)}
+              {currentLength}/{maxlength}
             </View>
           )}
         </View>
+        <View className={`${ isPolishing ? style.skelonton : style.skelontonHide}`}>
+          <View className={style.skelontonItem}></View>
+          <View className={style.skelontonItemShort}></View>
+        </View>
       </View>
     </View>
   );

+ 14 - 11
src/pages/agent-avatars/index.tsx

@@ -7,12 +7,11 @@ import NavBarNormal from "@/components/NavBarNormal/index";
 import { uploadAndNavToGenNewAvatar } from "@/utils/avatar";
 import IconPlusBig from "@/components/icon/icon-plus-big";
 
-import { editAgentAvatar } from "@/service/agent";
 import { deleteAvatar, fetchMyAvatars } from "@/service/storage";
 
 import style from "./index.module.less";
 import { TAvatarItem } from "@/service/storage";
-import { useAgentStore } from "@/store/agentStore";
+import { useAgentStore, useAgentStoreActions } from "@/store/agentStore";
 
 import Taro, { useDidShow } from "@tarojs/taro";
 import { isSuccess } from "@/utils";
@@ -21,11 +20,13 @@ import { useModalStore } from "@/store/modalStore";
 import { useLoadMoreInfinite, createKey } from "@/utils/loadMoreInfinite";
 
 export default function Index() {
-  const { agent, fetchAgent } = useAgentStore();
+  const agent = useAgentStore((state) => state.agent);
+
+  const { fetchAgent, saveAgent } = useAgentStoreActions();
   const [scrollTop, setScrollTop] = useState(0);
   const scrollPositionRef = useRef(0);
 
-  const { showModal } = useModalStore();
+  const { showModal } = useModalStore((state) => state.actions);
 
   const fetcher = async ([_url, { pageIndex, pageSize }]) => {
     const res = await fetchMyAvatars({ pageIndex: pageIndex, pageSize });
@@ -39,6 +40,7 @@ export default function Index() {
 
   const [current, setCurrent] = useState<TAvatarItem | null>(null);
 
+  // 选择形象
   const handleClick = async (item: TAvatarItem) => {
     console.log(item);
     if (!agent?.agentId) {
@@ -46,13 +48,14 @@ export default function Index() {
     }
 
     Taro.showLoading();
-    const result = await editAgentAvatar(agent.agentId, item.avatarId, true);
-    await fetchAgent(agent.agentId);
-    Taro.hideLoading();
-    setCurrent(item);
-    if (isSuccess(result.status)) {
-      Taro.navigateBack();
-    }
+    console.log(agent, 111111)
+    // const result = await saveAgent(agent.agentId, item.avatarId, true);
+    // await fetchAgent(agent.agentId);
+    // Taro.hideLoading();
+    // setCurrent(item);
+    // if (isSuccess(result.status)) {
+    //   Taro.navigateBack();
+    // }
   };
   const onScrollToLower = () => {
     loadMore();

+ 4 - 3
src/pages/agent-gen/components/step/StepConfirm.tsx

@@ -7,13 +7,14 @@ import ButtonMain from '@/components/buttons/ButtonMain'
 import Taro from "@tarojs/taro";
 import { TAvatarItem } from "@/service/storage";
 import { editAgentAvatar } from "@/service/agent";
-import { useAgentStore } from "@/store/agentStore";
+import { useAgentStore, useAgentStoreActions } from "@/store/agentStore";
 interface IProps {
   prev: ()=>void
   pickedAvatar: TAvatarItem
 }
 export default React.memo(function Index({prev, pickedAvatar}:IProps) {
-  const {agent, fetchAgent} = useAgentStore()
+  const agent = useAgentStore((state) => state.agent);
+  const {fetchAgent} = useAgentStoreActions();
   const [enabledChatBg, setEnabledChatBg] = useState(true)
 
   const handleConfirm = async () => {
@@ -26,7 +27,7 @@ export default React.memo(function Index({prev, pickedAvatar}:IProps) {
       enabledChatBg,
     );
     await fetchAgent(agent.agentId)
-    
+
     Taro.redirectTo({url: '/pages/agent/index'})
   }
   return (

+ 3 - 2
src/pages/agent/components/AgentSetting/components/AgentCard/index.tsx

@@ -4,14 +4,15 @@ import IconPlusBig from "@/components/icon/icon-plus-big";
 import Taro from "@tarojs/taro";
 import { uploadAndNavToGenNewAvatar } from "@/utils/avatar";
 import WemetaRadio from "@/components/WemetaRadio";
-import { useAgentStore } from "@/store/agentStore";
+import { useAgentStore, useAgentStoreActions } from "@/store/agentStore";
 import { editAgentChatBg } from "@/service/agent";
 import { isSuccess } from "@/utils";
 import { fetchMyAvatars } from "@/service/storage";
 import { AvatarMedia } from "@/components/AvatarMedia";
 
 export default () => {
-  const { agent, fetchAgent } = useAgentStore();
+  const agent = useAgentStore((state) => state.agent);
+  const { fetchAgent } = useAgentStoreActions();
 
   const handleChange = async (isChecked: boolean) => {
     if (!agent?.agentId || !agent.avatarUrl) {

+ 3 - 3
src/pages/agent/components/AgentSetting/components/AgentContactCard/index.tsx

@@ -1,11 +1,11 @@
 import { View, Text, Input} from "@tarojs/components"
 import style from './index.module.less'
 import IconPlusBlue from "@/components/icon/icon-plus-blue"
-import { useAgentStore } from "@/store/agentStore";
+import { useAgentStore, useAgentStoreActions } from "@/store/agentStore";
 // import ContactIcon from '@/components/ContactIcon'
 export default () => {
-  const agentTemp = useAgentStore((state)=> state.agentTemp)
-  const updateAgentTemp = useAgentStore((state)=> state.updateAgentTemp)
+  const agentTemp = useAgentStore((state)=> state.agentTemp);
+  const { updateAgentTemp } = useAgentStoreActions();
 
   // 处理表单字段更新
   const handleFieldChange = (field: string, value: string) => {

+ 3 - 2
src/pages/agent/components/AgentSetting/components/AgentKnowledgeLib/index.tsx

@@ -7,11 +7,12 @@ import IconArrow from "@/components/icon/icon-arrow";
 
 import IconPageColor from "@/components/icon/icon-page-color";
 import Taro from "@tarojs/taro";
-import { useAgentStore } from "@/store/agentStore";
+import { useAgentStore, useAgentStoreActions } from "@/store/agentStore";
 
 export default function Index() {
-  const { agent, editAgentCharacter, fetchAgent } = useAgentStore();
+  const agent = useAgentStore((state) => state.agent);
   const agentCharacter = useAgentStore((state) => state.agentCharacter);
+  const { editAgentCharacter, fetchAgent } = useAgentStoreActions();
   const handleSwitchChange = async (checked: boolean) => {
     if (!agent?.agentId || !agentCharacter) {
       return;

+ 19 - 4
src/pages/agent/components/AgentSetting/components/AgentSettingList/index.tsx

@@ -16,14 +16,29 @@ import { useAgentStore } from "@/store/agentStore";
 export default function Index() {
 
   const agent = useAgentStore((state) => state.agent)
+  const agentTemp = useAgentStore((state)=> state.agentTemp)
+
+  // 判断是编辑模式还是新建模式
+  const isEditMode = !!agent?.agentId
+
+  // 根据模式获取显示值
+  const getDisplayValue = (field: string) => {
+    if (isEditMode) {
+      // 编辑模式:优先显示agentTemp中的值,如果没有则显示agent中的值
+      return agentTemp[field] !== undefined ? agentTemp[field] : agent?.[field] ?? ''
+    } else {
+      // 新建模式:只显示agentTemp中的值
+      return agentTemp?.[field] ?? ''
+    }
+  }
   const { setEntId } = useVoiceStore()
   const handleEditVoice = () => {
     // 提前设置当前智能体 entId
     setEntId(agent?.entId ?? 0);
     Taro.navigateTo({ url: '/pages/voice/index' })
   }
-  const agentTemp = useAgentStore((state)=> state.agentTemp)
-  const updateAgentTemp = useAgentStore((state)=> state.updateAgentTemp)
+
+  const updateAgentTemp = useAgentStore((state)=> state.actions.updateAgentTemp)
 
   // 处理表单字段更新
   const handleFieldChange = (field: string, value: string) => {
@@ -45,7 +60,7 @@ export default function Index() {
         aiType="personality"
         prefix={() => <View>人设</View>}
         placeholder="示例:你是一名汽车销售人员,拥有专业的汽车相关知识,善于耐心的解答客户提出的每一个问题,并会主动邀请客户上门试驾。"
-        value={agentTemp?.personality ?? ''}
+        value={getDisplayValue('personality')}
         autoHeight
         onInput={(value) => {
           handleFieldChange('personality', value)
@@ -56,7 +71,7 @@ export default function Index() {
         aiType="greeting"
         prefix={() => <View>开场白</View>}
         placeholder="开场白是你的智能体和用户说的第一句话,简单做个自我介绍吧"
-        value={agentTemp?.greeting ?? ''}
+        value={getDisplayValue('greeting')}
         autoHeight
         onInput={(value) => {
           handleFieldChange('greeting', value)

+ 10 - 9
src/pages/agent/components/AgentSetting/index.tsx

@@ -6,17 +6,20 @@ import AgentContactCard from './components/AgentContactCard'
 import BottomBar from "@/components/BottomBar";
 
 import React, { useEffect, useState } from "react";
-import { useAgentStore } from "@/store/agentStore";
+
 import ButtonMain from "@/components/buttons/ButtonMain";
+import { useAgentStore } from "@/store/agentStore";
 
 
-export default React.memo(function Index() {
+export default React.memo(function Index({save}: {save: ()=> void}) {
   console.log('agent setting')
-  const {fetchAgents} = useAgentStore()
+  const agent = useAgentStore((state) => state.agent)
+  const agentTemp = useAgentStore((state)=> state.agentTemp)
 
-  useEffect(()=> {
-    fetchAgents()
-  }, [])
+  // 控制按钮状态和文本
+  const isNameValid = (agentTemp?.name?.length || 0) >= 2 || (agent?.name?.length || 0) >= 2
+  const isDisabled = !isNameValid
+  const buttonText = agent?.agentId ? '保存' : '创建'
 
   return (
     <View className="pb-64">
@@ -29,9 +32,7 @@ export default React.memo(function Index() {
         <AgentKnowledgeLib></AgentKnowledgeLib>
       </View>
       <BottomBar>
-        <ButtonMain className="flex-1" onClick={()=>{
-          console.log('create')
-        }}>创建</ButtonMain>
+        <ButtonMain disabled={isDisabled} className="flex-1" onClick={save}>{buttonText}</ButtonMain>
       </BottomBar>
     </View>
   );

+ 53 - 8
src/pages/agent/index.tsx

@@ -5,9 +5,10 @@ import PageCustom from "@/components/page-custom/index";
 import TabBarButtons from "@/components/wemeta-tabs/TabBarButtons";
 import AgentSetting from "./components/AgentSetting/";
 import AgentWebsite from "./components/AgentWebsite/";
-import { useAgentStore } from "@/store/agentStore";
+import { useModalStore } from "@/store/modalStore";
+import { useAgentStore, useAgentStoreActions } from "@/store/agentStore";
 import { useEffect, useState } from "react";
-import { useDidShow, useRouter } from "@tarojs/taro";
+import Taro, { useDidShow, useRouter } from "@tarojs/taro";
 import { useComponentStore } from "@/store/componentStore";
 import { useUserStore } from "@/store/userStore";
 import { useAppStore } from "@/store/appStore";
@@ -16,18 +17,21 @@ import {restrictedPage} from '@/utils'
 
 export default function Index() {
   restrictedPage()
-  const [tabIndex, setTabIndex] = useState('1');
+  const { showModal } = useModalStore((state) => state.actions);
   const router = useRouter();
   const headerHeight = useAppStore((state) => state.headerHeight);
   const agentId = router.params.agentId;
-  const { fetchAgent } = useAgentStore();
+  const agent = useAgentStore((state) => state.agent);
+  const { clearMyAgent, fetchAgent, saveAgent } = useAgentStoreActions();
   const { fetchMyEntList } = useUserStore();
   const { setComponentList } = useComponentStore();
+  const [tabIndex, setTabIndex] = useState('1');
+
   const handleTabIndexChange = (index: string) => {
     setTabIndex(index);
   };
 
-  const fetchAgentDetail = async (agentId: string) => {
+  const fetchData = async (agentId: string) => {
     const result = await fetchAgent(agentId);
     if (result) {
       const components = result.components ?? []
@@ -48,13 +52,54 @@ export default function Index() {
     },
   ];
 
+  const agentTemp = useAgentStore(state=> state.agentTemp);
+  const { fetchAgents } = useAgentStoreActions();
+
+  useEffect(()=> {
+    fetchAgents()
+  }, [])
+
+  const handleSave  = async () =>{
+    await saveAgent()
+  }
+
+  const handleNavBack = async () => {
+    if(!agentTemp){
+      return true
+    }
+    console.log(agentTemp, agent, 3333)
+    if(!agentTemp.name){
+      const r = await new Promise((resolve)=> {
+        showModal({
+          content: <View className="text-black font-pingfangSCMedium font-medium text-14 leading-22">确定放弃创建智能体?</View>,
+          confirmText: "我再想想",
+          onConfirm() {
+            Taro.showTabBar().catch(()=> {});
+            resolve(true)
+          },
+          onCancel() {
+            Taro.showTabBar().catch(()=> {});
+            resolve(false)
+          },
+        })
+      })
+
+      return r
+    }
+  }
+
   useDidShow(()=> {
-    agentId && fetchAgentDetail(agentId);
+    if(agentId){
+      fetchData(agentId);
+    }else{
+      clearMyAgent();
+    }
+
   })
 
   return (
     <PageCustom>
-      <NavBarNormal>编辑智能体</NavBarNormal>
+      <NavBarNormal  onNavBack={handleNavBack}>编辑智能体</NavBarNormal>
       <View className="px-16 w-full flex flex-col gap-20">
         <View className={style.tabContainer}
         style={{
@@ -71,7 +116,7 @@ export default function Index() {
         </View>
         <View className="pt-52">
           <View className={`${tabIndex === "1" ? "block" : "hidden"}`}>
-            <AgentSetting></AgentSetting>
+            <AgentSetting save={handleSave}></AgentSetting>
           </View>
           <View className={`${tabIndex === "2" ? "block" : "hidden"}`}>
             <View className="pt-36 pb-80">

+ 3 - 3
src/pages/chat/hooks/useChatAgent.ts

@@ -1,6 +1,6 @@
 import { useEffect } from 'react';
 import { useDidShow } from '@tarojs/taro';
-import { useAgentStore } from '@/store/agentStore';
+import { useAgentStore, useAgentStoreActions } from '@/store/agentStore';
 
 /**
  * 聊天智能体数据管理 Hook
@@ -10,8 +10,8 @@ export const useChatAgent = (agentId: string, isVisitor?: string): {
   agent: any;
   isVisitor: boolean;
 } => {
-  const { fetchAgent, fetchAgentProfile } = useAgentStore();
-  
+  const { fetchAgent, fetchAgentProfile } = useAgentStoreActions();
+
   // 获取智能体数据
   const agent = useAgentStore((state) => {
     if (isVisitor === "true") {

+ 3 - 2
src/pages/component-library/index.tsx

@@ -14,7 +14,7 @@ import { useState } from "react";
 import { EComponentType } from "@/consts/enum";
 import { TComponentItem } from "@/types/agent";
 import { createComponentData } from "./components/createComponentData";
-import { useAgentStore } from "@/store/agentStore";
+import { useAgentStore, useAgentStoreActions } from "@/store/agentStore";
 
 type TWidget = {
   type: EComponentType;
@@ -24,7 +24,8 @@ type TWidget = {
 };
 export default () => {
   const { loading, insertComponent, setLoading } = useComponentStore();
-  const { agent, editAgentWebsite, fetchAgent } = useAgentStore();
+  const agent = useAgentStore((state) => state.agent);
+  const { editAgentWebsite, fetchAgent } = useAgentStoreActions();
 
   const [commonWidget, setCommonWidget] = useState<TWidget[]>([
     {

+ 6 - 5
src/pages/dashboard/components/AgentList/index.tsx

@@ -3,7 +3,7 @@ import Taro, { useDidShow } from "@tarojs/taro";
 import Popup from "@/components/popup/popup";
 
 import { useEffect, useState } from "react";
-import { useAgentStore } from "@/store/agentStore";
+import { useAgentStore, useAgentStoreActions } from "@/store/agentStore";
 import WemetaRadio from "@/components/WemetaRadio/index";
 import { TAgent } from "@/types/agent";
 import AgentCard from "./components/AgentCard";
@@ -17,7 +17,8 @@ interface IProps {
 }
 
 export default ({currentAgent,  setCurrentAgent, show, setShow }: IProps) => {
-  const { agents, fetchAgents } = useAgentStore();
+  const agents = useAgentStore((state) => state.agents);
+  const { fetchAgents } = useAgentStoreActions();
 
   const fetchInitData = async () => {
     await fetchAgents();
@@ -39,11 +40,11 @@ export default ({currentAgent,  setCurrentAgent, show, setShow }: IProps) => {
   return (
     <Popup title="选择智能体" show={show} setShow={setShow}>
       <View className="flex flex-col gap-12 w-full overflow-y-auto max-h-[440px]">
-        {!agents.length && 
+        {!agents.length &&
           <View className="mb-88">
             <EmptyData type='search'></EmptyData>
           </View>
-          
+
         }
         {agents.map((item, index, array) => {
           return (
@@ -64,7 +65,7 @@ export default ({currentAgent,  setCurrentAgent, show, setShow }: IProps) => {
               }}>
 
             </AgentCard>
-            
+
           );
         })}
       </View>

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

@@ -8,7 +8,7 @@ import DataCard from './components/DataCard'
 import VisitorList from "./components/VisitorList";
 import  AgentList from "./components/AgentList";
 import { useEffect, useState } from "react";
-import { useAgentStore } from "@/store/agentStore";
+import { useAgentStore, useAgentStoreActions } from "@/store/agentStore";
 import { getVisitorSummary, type TVisitorSummary } from '@/service/visitor'
 import { isSuccess } from "@/utils";
 import { TAgent } from "@/types/agent";
@@ -21,7 +21,8 @@ import BlurContainer from '@/components/BlurContainer'
 
 export default () => {
 
-  const {agents, fetchAgents} = useAgentStore()
+  const agents = useAgentStore((state) => state.agents);
+  const { fetchAgents } = useAgentStoreActions();
 
   const [show, setShow] = useState(false);
 

+ 1 - 1
src/pages/dislike-messages/index.tsx

@@ -25,7 +25,7 @@ import { EContentType } from "@/types/bot";
 
 export default function Index() {
   const router = useRouter();
-  const { showModal } = useModalStore();
+  const { showModal } = useModalStore((state) => state.actions);
   const { agentId } = router.params as { agentId: string };
   const [scrollTop, setScrollTop] = useState(0);
 

+ 4 - 3
src/pages/editor-pages/editor-greeting-questions/index.tsx

@@ -5,7 +5,7 @@ import PageCustom from "@/components/page-custom/index";
 import NavBarNormal from "@/components/NavBarNormal/index";
 import WemetaInput from "@/components/wemeta-input/index";
 import Taro, { useUnload } from "@tarojs/taro";
-import { useAgentStore } from "@/store/agentStore";
+import { useAgentStore, useAgentStoreActions } from "@/store/agentStore";
 
 type InputField = {
   id: string; // 唯一标识(用于 key)
@@ -14,8 +14,9 @@ type InputField = {
 };
 
 export default function Index() {
-  const { agent, agentCharacter, editAgentCharacter, fetchAgent } =
-    useAgentStore();
+  const agent = useAgentStore((state) => state.agent);
+  const agentCharacter = useAgentStore((state) => state.agentCharacter);
+  const { editAgentCharacter, fetchAgent } = useAgentStoreActions();
   const questionGuides = agentCharacter?.questionGuides ?? [];
   const initialInputs: InputField[] = [
     { id: "1", value: "", title: "问题一" },

+ 2 - 2
src/pages/editor-pages/editor-link-contact/components/MyAgentsScrollList/index.tsx

@@ -19,9 +19,9 @@ export interface IProps {
 
 export default function Index({selected, setSelected}: IProps) {
 
-  const {agents} = useAgentStore()
+  const agents = useAgentStore((state) => state.agents);
   const myAgents = agents.filter(item => !item.isEnt)
-  
+
 
   const handleClick = (item: TAgent) => {
     console.log(item)

+ 4 - 4
src/pages/index/components/InitView/index.tsx

@@ -9,7 +9,7 @@ import { onLogout, useIsLogin } from '@/xiaolanbenlib/hooks/data/useAuth'
 import refreshUserId, { clearUserInfo, getOpenIdAsync } from '@/xiaolanbenlib/utils/auth'
 
 import WelcomeTips from '../WelcomeTips/index'
-import { useAgentStore } from '@/store/agentStore'
+import { useAgentStore, useAgentStoreActions } from '@/store/agentStore'
 import { useSystemStore } from '@/store/systemStore'
 import { TAgent } from "@/types/agent";
 import { useUserStore } from "@/store/userStore";
@@ -21,7 +21,7 @@ export default function Index({}: IProps) {
   const [userInfo, setUserInfo] = useState<UserInfoResponse>()
   const isLogin = useIsLogin()
 
-  const {fetchAgents} =  useAgentStore()
+  const { fetchAgents } = useAgentStoreActions();
   const { fetchSysCoreCnf } =  useSystemStore()
   const { fetchtMyInfo } = useUserStore()
 
@@ -44,7 +44,7 @@ export default function Index({}: IProps) {
       })
     await fetchSysCoreCnf()
     await fetchtMyInfo()
-    
+
     // 获取智能体
     await fetchAgents()
   }
@@ -54,7 +54,7 @@ export default function Index({}: IProps) {
       initUserInfo()
     }
   }, [isLogin])
-  
+
 
   const renderLogo = ()=> {
     return <View><Image className="w-68 h-24" src={LogoImage}></Image></View>

+ 9 - 13
src/pages/index/components/WelcomeTips/index.tsx

@@ -2,7 +2,7 @@ import { View, Image } from "@tarojs/components";
 import style from "./index.module.less";
 import Taro from "@tarojs/taro";
 import LoginPopup from '@/components/LoginPopup'
-import { useAgentStore } from "@/store/agentStore";
+import { getNewAgentInfo } from "@/service/agent";
 import { useState } from "react";
 import IconIndexProfile from '@/images/svgs/index/IconIndexProfile.svg'
 import IconIndexChat from '@/images/svgs/index/IconIndexChat.svg'
@@ -10,27 +10,23 @@ import IconIndexContent from '@/images/svgs/index/IconIndexContent.svg'
 interface IProps {
   // children: JSX.Element|JSX.Element[]
 }
-export default function Index({}: IProps) {  
-  const { createAgent } = useAgentStore()
+export default function Index({}: IProps) {
+
   const [showLogin, setShowLogin] = useState(false);
   const handleCreate = async ()=> {
     try{
-      const agentDetail = await createAgent()
+      const agentDetail = await getNewAgentInfo();
       if(agentDetail){
-        if(agentDetail){
-          Taro.navigateTo({ url: `/pages/agent/index?agentId=${agentDetail.agentId}` });
-        }
-        // Taro.navigateTo({
-        //   url: `/pages/agent/index?agentId=${agentDetail.agentId}`
-        // })
+        console.log(agentDetail)
+        Taro.navigateTo({ url: `/pages/agent/index`});
       }
     }catch(e){
       if(e.code === 401){
         setShowLogin(true)
       }
-      
+
     }
-    
+
   }
   const handleOnEnd = ()=> {
     setShowLogin(false)
@@ -42,7 +38,7 @@ export default function Index({}: IProps) {
       </View>
       <View className={style.content}>
         <View className={style.welcomBar}>
-          <View className={style.hello}>你好!</View>      
+          <View className={style.hello}>你好!</View>
           <View className={style.welcome}>欢迎你,体验「小蓝本智能体」</View>
         </View>
         <View className={style.box}>

+ 5 - 4
src/pages/index/index.tsx

@@ -1,14 +1,15 @@
 import DefaultAgent from "@/components/AgentPage";
 import InitView from "./components/InitView";
 import { useDidShow } from "@tarojs/taro";
-import { useAgentStore } from "@/store/agentStore";
+import { useAgentStore, useAgentStoreActions } from "@/store/agentStore";
 import { useIsLogin } from "@/xiaolanbenlib/hooks/data/useAuth";
 import { useEffect } from "react";
 
 export default function Index() {
   const isLogin = useIsLogin();
-  
-  const { fetchAgents, defaultAgent, resetData } = useAgentStore();
+
+  const defaultAgent = useAgentStore((state) => state.defaultAgent);
+  const { fetchAgents, resetData } = useAgentStoreActions();
 
   useDidShow(() => {
     // 如果没有登录过,则显示默认欢迎页
@@ -17,7 +18,7 @@ export default function Index() {
       fetchAgents();
     }
   });
-  
+
   // 如果登出,则重置当前 agent store
   useEffect(()=> {
     if(!isLogin){

+ 1 - 1
src/pages/knowledge-item/index.tsx

@@ -36,7 +36,7 @@ export default function Index() {
   const [detail, setDetail] = useState<TKnowledgeDetail | null>(null);
 
   const isEnt = (entId !== undefined)
-  const { showModal } = useModalStore();
+  const { showModal } = useModalStore((state) => state.actions);
   const [showPopup, setShowPopup] = useState(false);
 
 

+ 1 - 1
src/pages/knowledge/components/CorrectionTab/components/CorrectionList.tsx

@@ -17,7 +17,7 @@ export interface Iprops {
 }
 const Index = ({entId, setTotalCount}:Iprops) => {
   
-  const { showModal } = useModalStore();
+  const { showModal } = useModalStore((state) => state.actions);
 
   const fetcher = async ([_url, {nextId, pageSize}, [_entId]]) => {
     const res = await getCorrectionList({ startId: nextId, pageSize, entId: _entId});

+ 1 - 1
src/pages/knowledge/components/CorrectionTab/components/CorrectionListChat.tsx

@@ -21,7 +21,7 @@ export interface Iprops {
 }
 const Index = ({entId, setTotalCount}: Iprops) => {
 
-  const { showModal } = useModalStore();
+  const { showModal } = useModalStore((state) => state.actions);
 
   const fetcher = async ([_url, {nextId, pageSize}, [_entId]]) => {
     const res = await getCorrectionList({ startId: nextId, pageSize, entId: _entId});

+ 1 - 1
src/pages/voice/components/MyVoiceList/index.tsx

@@ -40,7 +40,7 @@ type TTask = {
 export default ({ onPlay, onSelect, agent }: Props) => {
   const intervalRef = useRef<NodeJS.Timeout | null>(null);
   const [show, setShow] = useState(false);
-  const { showModal } = useModalStore();
+  const { showModal } = useModalStore((state) => state.actions);
   const bottomSafeHeight = useAppStore((state) => state.bottomSafeHeight);
 
   const fetcher = async ([url, { pageSize, pageIndex }, [entId]]) => {

+ 5 - 3
src/pages/voice/index.tsx

@@ -9,7 +9,7 @@ import style from "./index.module.less";
 import PageCustom from "@/components/page-custom/index";
 import { useVoiceStore } from "@/store/voiceStore";
 import { TVoiceItem } from "@/types/voice";
-import { useAgentStore } from "@/store/agentStore";
+import { useAgentStore, useAgentStoreActions } from "@/store/agentStore";
 
 
 interface Props {}
@@ -20,7 +20,9 @@ const VoiceTabs: React.FC<Props> = ({}) => {
     null
   );
 
-  const {agent, agentCharacter, editAgentCharacter} = useAgentStore()
+  const agent = useAgentStore((state) => state.agent);
+  const agentCharacter = useAgentStore((state) => state.agentCharacter);
+  const {editAgentCharacter} = useAgentStoreActions();
 
   const {
     getVoices,
@@ -142,7 +144,7 @@ const VoiceTabs: React.FC<Props> = ({}) => {
     },
   ];
 
-  
+
 
   return (
     <PageCustom fullPage >

+ 70 - 36
src/service/agent.ts

@@ -2,14 +2,12 @@ import {
   bluebookAiAgent,
 } from '@/xiaolanbenlib/api/index'
 import request from '@/xiaolanbenlib/module/axios.js'
-import { TAgentDetail, TComponentItem, TEditAgentCharacter, TAgentContactCard, TAgentShared, TAgent } from '@/types/agent'
+import { TAgentDetail, TComponentItem, TEditAgentCharacter, TAgentContactCard, TAgentShared, TAgent, TAgentRequiredData } from '@/types/agent'
+
+
+
 
 
-// 创建一个新的智能体--用户点击创建按钮时调用获取新智能体id与名称信息
-// 仅创建一个空智能体
-export const createAgent = () => {
-  return request.post<TAgentDetail>(`${bluebookAiAgent}api/v1/my/agent`)
-}
 
 // 获取我的智能体详细信息
 // 供编辑页使用,预览页使用智能体信息接口获取
@@ -17,24 +15,34 @@ export const getMyAgent = (agentId: string) => {
   return request.get<TAgentDetail>(`${bluebookAiAgent}api/v1/my/agent/${agentId}`)
 }
 
-// 编辑智能体--声音、人设、开场白、问题引导、知识库
-export const editAgentCharacter = (agentId: string, data: TEditAgentCharacter) => {
-  return request.put(`${bluebookAiAgent}api/v1/my/agent/${agentId}/character`, data)
-}
-
-// 编辑智能体--设置形象ID
-export const editAgentAvatar = (agentId: string, avatarId: string|number, enabledChatBg:boolean) => {
-  return request.put(`${bluebookAiAgent}api/v1/my/agent/${agentId}/avatar`, {
-    avatarId,
-    enabledChatBg,
-  })
-}
-
-// 编辑智能体--是否启用背景聊天效果
-export const editAgentChatBg = (agentId: string, enabledChatBg: boolean) => {
-  return request.put(`${bluebookAiAgent}api/v1/my/agent/${agentId}/avatar/chatBg`, {
-    enabledChatBg,
-  })
+// 获取创建智能体时的默认填充内容项
+export const getNewAgentInfo = () => {
+  return request.get<{
+    "address"?: string;
+    "avatarLogo"?: string;
+    "avatarUrl"?: string;
+    "email"?: string;
+    "enabledChatBg"?: boolean;
+    "enabledPersonalKb"?: boolean;
+    "entName"?: string;
+    "greeting"?: string;
+    "mobile"?: string;
+    "name"?: string;
+    "personality"?: string;
+    "position"?: string;
+    "qrCodeUrl"?: string;
+    "questionGuides"?: string[];
+    "voiceId"?: string;
+    "voiceName"?: string;
+  }>(`${bluebookAiAgent}api/v1/my/new/agent/info`)
+}
+// 创建新智能体
+export const createNewAgent = (data: Omit<TAgentRequiredData, 'agentId'>) => {
+  return request.post<TAgentDetail>(`${bluebookAiAgent}api/v1/my/agent/create`, data)
+}
+// 编辑智能体
+export const editAgent = (data: TAgentRequiredData) => {
+  return request.put<TAgentDetail>(`${bluebookAiAgent}api/v1/my/agent/${data.agentId}`, data)
 }
 
 // 设置当前我的默认智能体
@@ -48,19 +56,7 @@ export const editAgentWebsite = (agentId: string, data: {components: TComponentI
 }
 
 
-// 编辑智能体--名片部份内容
-// address (string, optional): 地址,长度最多250 ,
-// email (string, optional): 邮箱,长度最多50 ,
-// entName (string, optional): 企业名称,长度最多100,如果是个人版允许编辑、企业版可以原值传入即可 ,
-// mobile (string, optional): 手机号 ,
-// name (string, optional): 智能体名称--名片的姓名;长度最多20 ,
-// position (string, optional): 职位,长度最多30 ,
-// qrCodeUrl (string, optional): 二维码地址,长度最多250
-
 
-export const editAgentCard = (agentId: string, data: TAgentContactCard) => {
-  return request.put<any, any>(`${bluebookAiAgent}api/v1/my/agent/${agentId}/card`, data)
-}
 
 
 // 我的智能体列表
@@ -124,3 +120,41 @@ export const getEntAgentPartners = (params: {
 
 
 
+// ============ deprecated ===========
+
+// 编辑智能体--设置形象ID
+// deprecated
+// export const editAgentAvatar = (agentId: string, avatarId: string|number, enabledChatBg:boolean) => {
+//   return request.put(`${bluebookAiAgent}api/v1/my/agent/${agentId}/avatar`, {
+//     avatarId,
+//     enabledChatBg,
+//   })
+// }
+
+// 编辑智能体--是否启用背景聊天效果
+// deprecated
+export const editAgentChatBg = (agentId: string, enabledChatBg: boolean) => {
+  return request.put(`${bluebookAiAgent}api/v1/my/agent/${agentId}/avatar/chatBg`, {
+    enabledChatBg,
+  })
+}
+
+// 编辑智能体--名片部份内容
+// address (string, optional): 地址,长度最多250 ,
+// email (string, optional): 邮箱,长度最多50 ,
+// entName (string, optional): 企业名称,长度最多100,如果是个人版允许编辑、企业版可以原值传入即可 ,
+// mobile (string, optional): 手机号 ,
+// name (string, optional): 智能体名称--名片的姓名;长度最多20 ,
+// position (string, optional): 职位,长度最多30 ,
+// qrCodeUrl (string, optional): 二维码地址,长度最多250
+
+// deprecated
+export const editAgentCard = (agentId: string, data: TAgentContactCard) => {
+  return request.put<any, any>(`${bluebookAiAgent}api/v1/my/agent/${agentId}/card`, data)
+}
+
+// 编辑智能体--声音、人设、开场白、问题引导、知识库
+// deprecated
+export const editAgentCharacter = (agentId: string, data: TEditAgentCharacter) => {
+  return request.put(`${bluebookAiAgent}api/v1/my/agent/${agentId}/character`, data)
+}

+ 256 - 196
src/store/agentStore.ts

@@ -1,6 +1,5 @@
 import { create } from "zustand";
 import {
-  createAgent as _createAgent,
   getAgents,
   getMyAgent as _getMyAgent,
   getAgent as _getAgent,
@@ -9,6 +8,8 @@ import {
   editAgentCard as _editAgentCard,
   editAgentCharacter as _editAgentCharacter,
   editAgentWebsite as _editAgentWebsite,
+  createNewAgent as _createNewAgent,
+  editAgent as _editAgent,
 } from "@/service/agent";
 import {
   TAgentDetail,
@@ -16,7 +17,7 @@ import {
   TAgentContactCard,
   TEditAgentCharacter,
   TComponentItem,
-  TAgentTemp,
+  TAgentRequiredData,
 } from "@/types/agent";
 import { isSuccess } from "@/utils";
 import Taro from "@tarojs/taro";
@@ -25,36 +26,39 @@ export interface AgentStoreState {
   agents: TAgent[];
   agent: TAgentDetail | null;
   defaultAgent: TAgentDetail | TAgent | null;
-  agentTemp: TAgentTemp; // 未创建智能体临时存储
+  agentTemp: Omit<TAgentRequiredData, 'agentId'>; // 未创建智能体临时存储
   // 无需登录查看 agent 信息
   agentProfile: TAgentDetail | null;
   agentContactCard: TAgentContactCard | null;// deprecated
   agentCharacter: TEditAgentCharacter | null;// deprecated
   ents: { entName: string; entId: string | number }[];
-  fetchAgents: () => Promise<TAgent[]>;
-  // 请求智能体数据登录状态
-  fetchAgent: (agentId: string) => Promise<TAgentDetail | null>;
-  // 请求智能体数据非登录状态
-  fetchAgentProfile: (
-    agentId: string,
-    shareKey?: string
-  ) => Promise<TAgentDetail | null>;
-  createAgent: () => Promise<TAgentDetail | null>;
-  clearProfileAgent: () => void;
-  setDefaultAgent: (agentId: string) => Promise<TAgentDetail | null>;
-  editAgentCharacter: (
-    agentId: string,
-    data: TEditAgentCharacter
-  ) => Promise<boolean>;
-  editAgentCard: (agentId: string, data: TAgentContactCard) => Promise<boolean>;
-  editAgentWebsite: (
-    agentId: string,
-    data: TComponentItem[]
-  ) => Promise<boolean>;
-  deleteAgent: (agentId: string) => Promise<void>;
-  updateAgentTemp: (updates: Partial<TAgentTemp>) => void;
-  clearAgentTemp: () => void;
-  resetData: () => void;
+  actions: {
+    fetchAgents: () => Promise<TAgent[]>;
+    // 请求智能体数据登录状态
+    fetchAgent: (agentId: string) => Promise<TAgentDetail | null>;
+    // 请求智能体数据非登录状态
+    fetchAgentProfile: (
+      agentId: string,
+      shareKey?: string
+    ) => Promise<TAgentDetail | null>;
+    clearProfileAgent: () => void;
+    setDefaultAgent: (agentId: string) => Promise<TAgentDetail | null>;
+    editAgentCharacter: (
+      agentId: string,
+      data: TEditAgentCharacter
+    ) => Promise<boolean>;
+    editAgentCard: (agentId: string, data: TAgentContactCard) => Promise<boolean>;
+    editAgentWebsite: (
+      agentId: string,
+      data: TComponentItem[]
+    ) => Promise<boolean>;
+    deleteAgent: (agentId: string) => Promise<void>;
+    updateAgentTemp: (updates: Partial<TAgentRequiredData>) => void;
+    clearAgentTemp: () => void;
+    saveAgent: () => Promise<TAgentDetail | null>;
+    resetData: () => void;
+    clearMyAgent: () => void;
+  };
 }
 
 export const useAgentStore = create<AgentStoreState>((set, get) => ({
@@ -66,191 +70,247 @@ export const useAgentStore = create<AgentStoreState>((set, get) => ({
   agentCharacter: null,
   agentTemp: {},
   ents: [],
-  resetData: () => {
-    set({
-      agents: [],
-      agent: null,
-      agentProfile: null,
-      agentContactCard: null,
-      defaultAgent: null,
-      agentCharacter: null,
-      ents: [],
-    });
-  },
-  fetchAgents: async () => {
-    const response = await getAgents();
-    const agentsData = response?.data;
-    // const agentsData = response?.data?.filter(item => !item.isEnt)
-    if (isSuccess(response.status) && agentsData.length) {
-      const defaultAgent = agentsData.find((item) => item.isDefault);
-      set({ agents: agentsData, defaultAgent });
-      return agentsData;
-    }
-    set({ agents: [], defaultAgent: null });
-    return [];
-  },
-  fetchAgent: async (agentId: string) => {
-    const response = await _getMyAgent(agentId);
-    const result = isSuccess(response.status);
-    if (result && response.data) {
-      const agent = response.data;
+  actions: {
+    resetData: () => {
       set({
-        agent: response.data,
-        agentContactCard: {
-          address: agent.address ?? "",
-          email: agent.email ?? "",
-          entName: agent.entName ?? "",
-          mobile: agent.mobile ?? "",
-          name: agent.name ?? "",
-          position: agent.position ?? "",
-          qrCodeUrl: agent.qrCodeUrl ?? "",
-        },
-        agentCharacter: {
-          enabledPersonalKb: agent.enabledPersonalKb ?? false,
-          greeting: agent.greeting ?? `你好,我是${agent.name}`,
-          personality: agent.personality ?? "",
-          questionGuides: agent.questionGuides ?? [],
-          voiceId: agent.voiceId ?? "",
-        },
+        agents: [],
+        agent: null,
+        agentProfile: null,
+        agentContactCard: null,
+        defaultAgent: null,
+        agentCharacter: null,
+        ents: [],
       });
+    },
+    fetchAgents: async () => {
+      const response = await getAgents();
+      const agentsData = response?.data;
+      // const agentsData = response?.data?.filter(item => !item.isEnt)
+      if (isSuccess(response.status) && agentsData.length) {
+        const defaultAgent = agentsData.find((item) => item.isDefault);
+        set({ agents: agentsData, defaultAgent });
+        return agentsData;
+      }
+      set({ agents: [], defaultAgent: null });
+      return [];
+    },
+    fetchAgent: async (agentId: string) => {
+      const response = await _getMyAgent(agentId);
+      const result = isSuccess(response.status);
+      if (result && response.data) {
+        const agent = response.data;
+        const agentTempData: Omit<TAgentRequiredData, 'agentId'> = {
+          address: agent.address ?? undefined,
+          avatarLogo: agent.avatarLogo ?? undefined,
+          avatarUrl: agent.avatarUrl ?? undefined,
+          email: agent.email ?? undefined,
+          enabledChatBg: agent.enabledChatBg ?? undefined,
+          enabledPersonalKb: agent.enabledPersonalKb ?? undefined,
+          entId: agent.entId ? Number(agent.entId) : undefined,
+          entName: agent.entName ?? undefined,
+          greeting: agent.greeting ?? undefined,
+          mobile: agent.mobile ?? undefined,
+          name: agent.name ?? undefined,
+          personality: agent.personality ?? undefined,
+          position: agent.position ?? undefined,
+          qrCodeUrl: agent.qrCodeUrl ?? undefined,
+          questionGuides: agent.questionGuides ?? undefined,
+          voiceId: agent.voiceId ?? undefined,
+          voiceName: agent.voiceName ?? undefined,
+        };
+        set({
+          agent: agent,
+          agentTemp: agentTempData,
+        });
 
-      return response.data;
-    }
-    set({
-      agent: null,
-    });
-    return null;
-  },
-  // 请求无需登录的 getAgent 接口
-  fetchAgentProfile: async (agentId: string, shareKey?: string) => {
-    if (shareKey) {
-      shareKey = decodeURIComponent(shareKey);
-    }
-    const response = await _getAgent(agentId, shareKey);
-    const result = isSuccess(response.status);
-    const agent = response.data;
-    if (result && agent) {
-      agent.components = (agent.components ?? []).filter(
-        (item) => item.enabled
-      );
+        return response.data;
+      }
       set({
-        agentProfile: agent,
+        agent: null,
       });
-      return agent;
-    }
-    return null;
-  },
-  clearProfileAgent: () => {
-    set({
-      agentProfile: null,
-    });
-  },
-  setDefaultAgent: async (agentId: string) => {
-    const response = await _setDefaultAgent(agentId);
-    const result = isSuccess(response.status);
-    if (result) {
-      const agent = await get().fetchAgent(agentId);
+      return null;
+    },
+    // 请求无需登录的 getAgent 接口
+    fetchAgentProfile: async (agentId: string, shareKey?: string) => {
+      if (shareKey) {
+        shareKey = decodeURIComponent(shareKey);
+      }
+      const response = await _getAgent(agentId, shareKey);
+      const result = isSuccess(response.status);
+      const agent = response.data;
+      if (result && agent) {
+        agent.components = (agent.components ?? []).filter(
+          (item) => item.enabled
+        );
+        set({
+          agentProfile: agent,
+        });
+        return agent;
+      }
+      return null;
+    },
+    clearProfileAgent: () => {
       set({
-        defaultAgent: agent,
+        agentProfile: null,
       });
-      return agent;
-    }
-    return null;
-  },
-  // 创建并设置其为默认智能体
-  createAgent: async () => {
-    const response = await _createAgent();
-    const agentDetail = response.data;
-    if (agentDetail?.agentId) {
-      // 创建新智能体,自动设置为默认智能体
-      await get().setDefaultAgent(agentDetail.agentId);
+    },
+    setDefaultAgent: async (agentId: string) => {
+      const response = await _setDefaultAgent(agentId);
+      const result = isSuccess(response.status);
+      if (result) {
+        const agent = await get().actions.fetchAgent(agentId);
+        set({
+          defaultAgent: agent,
+        });
+        return agent;
+      }
+      return null;
+    },
+    saveAgent: async () => {
+      const { agent, agentTemp } = get();
 
-      const a: TAgent = {
-        agentId: agentDetail.agentId ?? "",
-        isDefault: true,
-        isEnt: agentDetail.isEnt ?? false,
-        isNewEnt: agentDetail.isNewEnt ?? false,
-        name: agentDetail.name ?? "",
-        enabledChatBg: false,
-      };
+      // 如果当前agent有agentId,则执行编辑操作
+      if (agent?.agentId) {
+        // 处理null值转换为undefined以符合TAgentRequiredData类型
+        const cleanAgent = {
+          ...agent,
+          address: agent.address ?? undefined,
+          email: agent.email ?? undefined,
+          entName: agent.entName ?? undefined,
+          mobile: agent.mobile ?? undefined,
+          name: agent.name ?? undefined,
+          position: agent.position ?? undefined,
+          qrCodeUrl: agent.qrCodeUrl ?? undefined,
+          avatarUrl: agent.avatarUrl ?? undefined,
+          avatarLogo: agent.avatarLogo ?? undefined,
+          entId: agent.entId ? Number(agent.entId) : undefined,
+        };
+
+        const updateData: TAgentRequiredData = {
+          ...cleanAgent,
+          ...agentTemp,
+          agentId: agent.agentId,
+        };
 
+        const response = await _editAgent(updateData);
+        const result = isSuccess(response.status);
+
+        if (result && response.data) {
+          // 更新当前agent数据
+          set({ agent: response.data });
+          // 清除临时数据
+          get().actions.clearAgentTemp();
+          // 重新获取agents列表以更新缓存
+          await get().actions.fetchAgents();
+          return response.data;
+        }
+        return null;
+      } else {
+        // 如果没有agentId,则创建新智能体
+        if (Object.keys(agentTemp).length === 0) {
+          return null;
+        }
+
+        const response = await _createNewAgent(agentTemp);
+        const result = isSuccess(response.status);
+
+        if (result && response.data) {
+          const newAgent = await get().actions.fetchAgent(response.data.agentId);
+          if (newAgent) {
+            set((state) => ({
+              agents: [...state.agents, newAgent as TAgent],
+              agent: newAgent,
+              defaultAgent: newAgent,
+            }));
+            // 清除临时数据
+            get().actions.clearAgentTemp();
+            return newAgent;
+          }
+        }
+        return null;
+      }
+    },
+    updateAgentTemp: (updates: Partial<TAgentRequiredData>) => {
+      set((state) => ({
+        agentTemp: {
+          ...state.agentTemp,
+          ...updates,
+        },
+      }));
+    },
+    clearAgentTemp: () => {
+      set({ agentTemp: {} });
+    },
+    // 编辑声音,人设,开场白,问题引导,知识库
+    // deprecated
+    editAgentCharacter: async (agentId: string, data: TEditAgentCharacter) => {
+      const response = await _editAgentCharacter(agentId, data);
+      console.log(response.data);
+      const result = isSuccess(response.status);
+      //@ts-ignore
       set((state) => {
         return {
-          agents: [...state.agents, a],
-          defaultAgent: a,
+          agent: {
+            ...state.agent,
+            voiceId: data.voiceId,
+          },
         };
       });
-      return agentDetail;
-    }
-    return null;
-  },
-  updateAgentTemp: (updates: Partial<TAgentTemp>) => {
-    set((state) => ({
-      agentTemp: {
-        ...state.agentTemp,
-        ...updates,
-      },
-    }));
-  },
-  clearAgentTemp: () => {
-    set({ agentTemp: {} });
-  },
-  // 编辑声音,人设,开场白,问题引导,知识库
-  editAgentCharacter: async (agentId: string, data: TEditAgentCharacter) => {
-    const response = await _editAgentCharacter(agentId, data);
-    console.log(response.data);
-    const result = isSuccess(response.status);
-    //@ts-ignore
-    set((state) => {
-      return {
-        agent: {
-          ...state.agent,
-          voiceId: data.voiceId,
-        },
-      };
-    });
-    return result;
-  },
-  editAgentCard: async (agentId: string, data: TAgentContactCard) => {
-    console.log(agentId, data);
-    const response = await _editAgentCard(agentId, data);
-    console.log(response);
-    const result = isSuccess(response.status);
+      return result;
+    },
+    // deprecated
+    editAgentCard: async (agentId: string, data: TAgentContactCard) => {
+      console.log(agentId, data);
+      const response = await _editAgentCard(agentId, data);
+      console.log(response);
+      const result = isSuccess(response.status);
 
-    return result;
-  },
-  editAgentWebsite: async (agentId: string, data: TComponentItem[]) => {
-    console.log(agentId, data);
-    const response = await _editAgentWebsite(agentId, { components: data });
-    console.log(response);
-    const result = isSuccess(response.status);
+      return result;
+    },
+    editAgentWebsite: async (agentId: string, data: TComponentItem[]) => {
+      console.log(agentId, data);
+      const response = await _editAgentWebsite(agentId, { components: data });
+      console.log(response);
+      const result = isSuccess(response.status);
 
-    return result;
-  },
-  deleteAgent: async (agentId: string) => {
-    const response = await _deleteAgent(agentId);
-    if (isSuccess(response.status)) {
-      const de = get()
-        .agents.filter((item: TAgent) => item.agentId !== agentId)
-        .reverse()[0];
-      console.log(agentId, de, "setDefault");
-      // 默认设置自创的智能体
-      if (de) {
-        await get().setDefaultAgent(de.agentId);
-      }
+      return result;
+    },
 
-      // 重新拉取智能体列表
-      const restAgents = await get().fetchAgents();
-      if (restAgents.length <= 0) {
-        set({ agent: null, defaultAgent: null });
-        Taro.reLaunch({ url: "/pages/index/index" });
-        return;
-      }
+    deleteAgent: async (agentId: string) => {
+      const response = await _deleteAgent(agentId);
+      if (isSuccess(response.status)) {
+        const de = get()
+          .agents.filter((item: TAgent) => item.agentId !== agentId)
+          .reverse()[0];
+        console.log(agentId, de, "setDefault");
+        // 默认设置自创的智能体
+        if (de) {
+          await get().actions.setDefaultAgent(de.agentId);
+        }
+
+        // 重新拉取智能体列表
+        const restAgents = await get().actions.fetchAgents();
+        if (restAgents.length <= 0) {
+          set({ agent: null, defaultAgent: null });
+          Taro.reLaunch({ url: "/pages/index/index" });
+          return;
+        }
 
-      const defaultAgent = restAgents.find((item) => !!item.isDefault);
-      if (defaultAgent) {
-        await get().fetchAgent(defaultAgent.agentId);
+        const defaultAgent = restAgents.find((item) => !!item.isDefault);
+        if (defaultAgent) {
+          await get().actions.fetchAgent(defaultAgent.agentId);
+        }
       }
-    }
-  },
+    },
+    clearMyAgent: () => {
+      set({
+        agent: null,
+      });
+    },
+  }
 }));
+
+export const useAgentStoreActions = () => {
+  const actions = useAgentStore((state) => state.actions);
+  return actions;
+};

+ 27 - 15
src/store/modalStore.ts

@@ -1,9 +1,13 @@
 // stores/modalStore.ts
+// 全局唯一弹出层 confirm 确认框,View dom 嵌入在 page-wrapper 组件内
+// 暂时不支持多个弹出层同时弹出
 import { create } from 'zustand';
 
 
 type ModalConfig ={
   content: React.ReactNode;
+  confirmText?: string,
+  cancelText?: string,
   beforeClose?: () => Promise<void> | void; // 用户自定义关闭前回调
   onCancel?: () => Promise<void> | void; // 用户自定义关闭前回调
   showCancelButton?: boolean
@@ -12,24 +16,32 @@ type ModalConfig ={
 type ModalStore = {
   isVisible: boolean;
   config: ModalConfig | null;
-  showModal: (config:ModalConfig) => void;
-  hideModal: () => void;
-  onConfirm: ()=> void
-  onCancel: ()=> void
+  actions: {
+    showModal: (config:ModalConfig) => void;
+    hideModal: () => void;
+    onConfirm: ()=> void;
+    onCancel: ()=> void;
+  };
 };
 
 export const useModalStore = create<ModalStore>((set, get) => ({
   isVisible: false,
   config: null,
-  showModal: (config) => set({ isVisible: true, config }),
-  hideModal: () => set({ isVisible: false }),
-  onConfirm: () => {
-    get().config?.onConfirm?.()
-    get().hideModal();
+  actions: {
+    showModal: (config) => set({ isVisible: true, config }),
+    hideModal: () => set({ isVisible: false }),
+    onConfirm: () => {
+      get().config?.onConfirm?.()
+      get().actions.hideModal();
+    },
+    onCancel: () => {
+      get().config?.onCancel?.()
+      get().actions.hideModal();
+    },
   },
-  onCancel: () => {
-    get().config?.onCancel?.()
-    get().hideModal();
-  },
-  
-}));
+}));
+
+export const useModalStoreActions = () => {
+  const actions = useModalStore(state => state.actions);
+  return actions;
+};

+ 4 - 3
src/types/agent.ts

@@ -42,7 +42,7 @@ export type TComponentItem = {
 }
 export type TAgentDetail = {
   address?: string|null,
-  agentId?: string,
+  agentId: string,
   avatarUrl?: string|null,
   avatarLogo?: string|null,
   components?: TComponentItem[],
@@ -63,6 +63,7 @@ export type TAgentDetail = {
   qrCodeUrl?: string|null,
   questionGuides?: string[],
   voiceId?: string
+  voiceName?: string,
   isMineAgent: boolean
   deletedTip?: string|null // 如果是已删除状态时的提示词 ,
   status?:  'normal' | 'deleted' //  智能体状态:normal 正常/ deleted 已删除 ,
@@ -74,9 +75,9 @@ export type TAgentContactCard = Pick<TAgentDetail, 'address'|'email'|'entName'|'
 export type TEditAgentCharacter = Pick<TAgentDetail, 'enabledChatBg' | 'greeting' | 'personality' | 'questionGuides'| 'voiceId' | 'enabledPersonalKb'>
 
 
-export type TAgentTemp = {
+export type TAgentRequiredData = {
   "address"?: string;
-  "agentId"?: string;
+  "agentId": string;
   "avatarLogo"?: string;
   "avatarUrl"?: string;
   "components"?: Array<{