Explorar el Código

Merge branch 'dev/permission' of https://git.zyuas.com/LLM/chat-admin-web into dev/permission

* 'dev/permission' of https://git.zyuas.com/LLM/chat-admin-web:
  修改项目及应用
Ryuiso hace 3 semanas
padre
commit
89ee9cb750

+ 3 - 3
src/apis/index.ts

@@ -186,7 +186,7 @@ export type FetchAuditInfoLibDetailApi = (documentId: string) => Promise<any>;
 export type FetchTakaiAuditConfigLibListApi = (data: FetchAuditConfigLibListApiParams) => Promise<any>;
 export type ModifyTakaiAuditDocumentLibApi = (id: string, data: ModifyDocumentApiParams) => Promise<any>;
 export type AuditTakaiApplicationApi = (appId: string, userId: string) => Promise<any>;
-export type FetchTakaiProjectApi = () => Promise<any>;
+export type FetchTakaiProjectApi = (projectName:any,projectId?: any) => Promise<any>;
 export type FetchUserListApi = (data:any) => Promise<any>;
 
 // token联登校验
@@ -486,8 +486,8 @@ const auditTakaiApplicationApi: AuditTakaiApplicationApi = async (appId, userId)
     return api.put(`/deepseek/api/audit/${appId}/${userId}`);
 };
 
-const fetchTakaiProjectApi: FetchTakaiProjectApi = async () => {
-    return api.get(`/system/project/alllist?pageNum=1&pageSize=1000`);
+const fetchTakaiProjectApi: FetchTakaiProjectApi = async (projectName:any,projectId?:any) => {
+    return api.get(`/system/project/alllist?projectName=${projectName}&projectId=${projectId||''}`);
 };
 // /system/user/appVipList   用户列表信息
 const fetchUserListApi:FetchUserListApi = async (data:any) => {

+ 132 - 84
src/pages/deepseek/questionAnswer/info/index.tsx

@@ -7,11 +7,11 @@ import {
     Radio, Switch, Row, Col, Slider, Space, RadioChangeEvent,
     Spin, message, Typography, Tooltip,
     Cascader,
-    Tag, Modal, Table,TablePaginationConfig,Drawer
+    Tag, Modal, Table, TablePaginationConfig, Drawer
 } from 'antd';
 import type { TableProps } from 'antd';
 
-import { PlusCircleOutlined, MinusCircleOutlined, ArrowLeftOutlined, InfoCircleOutlined,CloseCircleOutlined,LinkOutlined } from '@ant-design/icons';
+import { PlusCircleOutlined, MinusCircleOutlined, ArrowLeftOutlined, InfoCircleOutlined, CloseCircleOutlined, LinkOutlined } from '@ant-design/icons';
 import { apis } from '@/apis';
 import router from '@/router';
 import LocalStorage from '@/LocalStorage';
@@ -27,8 +27,8 @@ const Index = 1;
 
 const QuestionAnswerInfo: React.FC = () => {
 
-    const { state,onChangePagination,onFetchUserListApi } = store;
-    const { page,sourceData } = state;
+    const { state, onChangePagination, onFetchUserListApi } = store;
+    const { page, sourceData } = state;
 
 
     const [form] = Form.useForm();
@@ -125,7 +125,7 @@ const QuestionAnswerInfo: React.FC = () => {
             value: string,
         }[],
     }[];
-    const tagRender = (props:any) => {
+    const tagRender = (props: any) => {
         const { label, value, closable, onClose } = props;
         return (
             <Tag
@@ -141,30 +141,30 @@ const QuestionAnswerInfo: React.FC = () => {
                     fontSize: 12,
                     cursor: 'pointer',
                 }}
-                 onMouseDown={(e) => {
-                    e.stopPropagation();
-                    e.preventDefault();
-                 }}
-                 onMouseUp={(e) => {
-                    e.stopPropagation();
-                    e.preventDefault();
-                 }}
-                // 自定义图标点击事件
-                onClick={(e) => {
-                    // 阻止事件冒泡到Tag,避免触发删除
-                    e.stopPropagation();
-                    e.preventDefault();
-                    knowledgeList.forEach((item) => {
-                        if (item.value === value) {
-                            // router.navigate({ pathname: `/deepseek/knowledgeLib/${value}/${item.createBy}`,},);
-                            setDrawerItem(item);
-                            setOpenDrawer(true)
-                            e.stopPropagation();
-                        }
-                    });
-                    // console.log('点击了额外图标,当前选项值:', value,props);
-                    // 这里可以添加你的业务逻辑,如:打开详情、编辑等
-                }} />
+                    onMouseDown={(e) => {
+                        e.stopPropagation();
+                        e.preventDefault();
+                    }}
+                    onMouseUp={(e) => {
+                        e.stopPropagation();
+                        e.preventDefault();
+                    }}
+                    // 自定义图标点击事件
+                    onClick={(e) => {
+                        // 阻止事件冒泡到Tag,避免触发删除
+                        e.stopPropagation();
+                        e.preventDefault();
+                        knowledgeList.forEach((item) => {
+                            if (item.value === value) {
+                                // router.navigate({ pathname: `/deepseek/knowledgeLib/${value}/${item.createBy}`,},);
+                                setDrawerItem(item);
+                                setOpenDrawer(true)
+                                e.stopPropagation();
+                            }
+                        });
+                        // console.log('点击了额外图标,当前选项值:', value,props);
+                        // 这里可以添加你的业务逻辑,如:打开详情、编辑等
+                    }} />
             </Tag>
         );
     };
@@ -181,7 +181,7 @@ const QuestionAnswerInfo: React.FC = () => {
     const [name, setName] = React.useState('');
     const [appTypeList, setAppTypeList] = React.useState<AppTypeList>([]);
     const [appVisibleList, setAppVisibleList] = React.useState<AppTypeList>([]); // 是否公开
-    const [visibleFlag, setVisibleFlag] = React.useState<string|number>(0); // 是否公开用来判断是否展示VIP用户
+    const [visibleFlag, setVisibleFlag] = React.useState<string | number>(0); // 是否公开用来判断是否展示VIP用户
     const [updateFlag, setUpdateFlag] = React.useState<boolean>();
     const [createFlag, setCreateFlag] = React.useState<boolean>();
     const [appProjectList, setAppProjectList] = React.useState<AppTypeList>([]);
@@ -207,13 +207,13 @@ const QuestionAnswerInfo: React.FC = () => {
             api.fetchKnowlegde(),
             api.fetchAppType(),
             // api.fetchModelList(),
-            api.fetchAppProType(),
+            // api.fetchAppProType(),
             api.fetchAppVisible(id)
         ])
         if (id) {
             await api.fetchDetail(id);
         }
-        onFetchUserListApi('','','');
+        onFetchUserListApi('', '', '');
         await api.fetchUserType();
     }
     React.useEffect(() => {
@@ -338,13 +338,12 @@ const QuestionAnswerInfo: React.FC = () => {
                 } else {
                     setIsAppPro(false);
                 }
-
+                projectApi.fetchProject('', info.appProId); // 获取项目列表
                 // if (info.model === 'Qwen3-30B') {
                 //     setIsDeepThinkVisible(true);
                 // } else {
-                    setIsDeepThinkVisible(false);
+                setIsDeepThinkVisible(false);
                 // }
-
                 form.setFieldsValue({
                     id: info.id,
                     name: info.name,  //应用名称
@@ -361,7 +360,6 @@ const QuestionAnswerInfo: React.FC = () => {
                     questionList: sd, //问题列表
                     max_token: info.maxToken, //应用最大token
                     updateDate: info.updateDate, // 更新时间
-                    appProId: info.appProId?.join('-'),// 项目
                     typeId: info.typeId, //应用类型
                     visible: info.visible || '0', //是否公开
                     sort: info.sort || null, //显示顺序
@@ -379,7 +377,7 @@ const QuestionAnswerInfo: React.FC = () => {
                     //rerank_index_type_list: info.rerank_index_type_list, //知识库id
                 })
                 setVisibleFlag(info.visible || '0')
-                if(info.vipList&&info.vipList.length>0){
+                if (info.vipList && info.vipList.length > 0) {
                     setVipList(info.vipList);
                 }
                 if (sd.length > 0) {
@@ -482,10 +480,10 @@ const QuestionAnswerInfo: React.FC = () => {
         fetchAppProType: async () => {
             try {
                 const res = await apis.fetchTakaiAppTypeList('projectTree');
-                console.log('res.data',res.data)
-                const list: AppTypeList = res.data?.reduce((acc:any,item: any) => {
-                    if(item.children.length>0){
-                        item.children.forEach((val:any)=>{
+                console.log('res.data', res.data)
+                const list: AppTypeList = res.data?.reduce((acc: any, item: any) => {
+                    if (item.children.length > 0) {
+                        item.children.forEach((val: any) => {
                             acc.push({
                                 label: val.label,
                                 value: `${item.value}-${val.value}`,
@@ -493,7 +491,7 @@ const QuestionAnswerInfo: React.FC = () => {
                         })
                     }
                     return acc;
-                },[]);
+                }, []);
                 setAppProjectList(list);
             } catch (error: any) {
                 console.error(error);
@@ -503,11 +501,11 @@ const QuestionAnswerInfo: React.FC = () => {
         fetchUserListApi: async () => {
             try {
                 const res = await apis.fetchUserListApi({
-                    pageNum:page.pageNumber,
+                    pageNum: page.pageNumber,
                     pageSize: page.pageSize,
-                    userName:userName,
-                    nickName:userNickName,
-                    userType:userType
+                    userName: userName,
+                    nickName: userNickName,
+                    userType: userType
                 });
                 // setSourceData(res.rows)
             } catch (error) {
@@ -515,7 +513,40 @@ const QuestionAnswerInfo: React.FC = () => {
             }
         }
     }
+    type ProjectTypeList = {
+        label: string,
+        value: string,
+    }[];
+    const [fetching, setFetching] = React.useState(false);
+    const [projectList, setProjectList] = React.useState<ProjectTypeList>([]);
 
+    // 获取项目列表
+    const projectApi = {
+        fetchProject: async (name: string = '', projectId?: string) => {
+            try {
+                setFetching(true);
+                const res = await apis.fetchTakaiProjectLibApi(name, projectId);
+                const list = res.data.map((item: any) => {
+                    return {
+                        label: item.projectName,
+                        value: item.projectId,
+                    }
+                });
+                setFetching(false);
+                setProjectList(list);
+                if (projectId) {
+                    const findItem = list.find((item: any) => item.value == projectId);
+                    if (findItem) {
+                        form.setFieldsValue({
+                            appProId: findItem.value
+                        });
+                    }
+                }
+            } catch (error: any) {
+                console.error(error);
+            }
+        },
+    };
     const handleRedioClick = (value: string) => {
         setIsVisibleCus(false);
         if (value === 'strict') {
@@ -593,9 +624,10 @@ const QuestionAnswerInfo: React.FC = () => {
                 max_token: values.max_token, //应用最大token
                 typeId: values.typeId, // 应用类型
                 visible: values.visible, // 是否公开
-                sort: values.sort||null, // 显示顺序
+                sort: values.sort || null, // 显示顺序
                 vipList: vipList, // vip用户列表
-                appProId: Array.isArray(values?.appProId) ? values.appProId?.[0]?.split('-') : values?.appProId?.split('-')?? null, // 项目
+                // appProId: Array.isArray(values?.appProId) ? values.appProId?.[0]?.split('-') : values?.appProId?.split('-') ?? null, // 项目
+                appProId: values?.appProId, // 项目
                 userId: userId, // 用户id
             };
             // console.log(info, 'info data----');
@@ -641,14 +673,14 @@ const QuestionAnswerInfo: React.FC = () => {
         选择VIP用户弹窗start
     */
     const [isModalOpen, setIsModalOpen] = React.useState(false);
-    let falgVipList:any = [];
+    let falgVipList: any = [];
     const handleOk = () => {
         setIsModalOpen(false);
-        let vipListFalg:any = [...vipList];
-        const vipIds = new Set(vipListFalg.map((vip:any) => vip.userId));
+        let vipListFalg: any = [...vipList];
+        const vipIds = new Set(vipListFalg.map((vip: any) => vip.userId));
         const merged = [...vipListFalg];
 
-        falgVipList.forEach((item:any) => {
+        falgVipList.forEach((item: any) => {
             if (!vipIds.has(item.userId)) {
                 merged.push(item);
             }
@@ -682,7 +714,7 @@ const QuestionAnswerInfo: React.FC = () => {
         pageSize: page.pageSize,
         total: page.total,
         onChange: async (page, pageSize) => {
-            await onChangePagination(page, pageSize,userName,userNickName,userType);
+            await onChangePagination(page, pageSize, userName, userNickName, userType);
         },
     };
 
@@ -728,22 +760,22 @@ const QuestionAnswerInfo: React.FC = () => {
                     width='80%'
                 >
                     <div className='modal_top'>
-                        <Input placeholder="请输入用户昵称" allowClear onChange={(e)=>{
+                        <Input placeholder="请输入用户昵称" allowClear onChange={(e) => {
                             setUserNickName(e.target.value)
                         }} />
-                        <Input placeholder="请输入用户名称" allowClear onChange={(e)=>{
+                        <Input placeholder="请输入用户名称" allowClear onChange={(e) => {
                             setUserName(e.target.value)
                         }} />
                         <Select
                             placeholder='请选择用户类型'
                             style={{ width: 150 }}
                             onChange={(e) => {
-                                if(e === undefined){
+                                if (e === undefined) {
                                     setUserType('')
                                     return
                                 }
                                 setUserType(e)
-                             }}
+                            }}
                             allowClear={true}
                         >
                             {
@@ -759,7 +791,7 @@ const QuestionAnswerInfo: React.FC = () => {
                             border: '1px solid #1677ff',
                             color: '#1677ff'
                         }}
-                        onClick={() => { onFetchUserListApi(userName,userNickName,userType) }}
+                            onClick={() => { onFetchUserListApi(userName, userNickName, userType) }}
                         > 搜索 </Button>
                         {/* <Button value="large"
                             onClick={() => { api.fetchUserListApi() }}
@@ -773,33 +805,33 @@ const QuestionAnswerInfo: React.FC = () => {
     /*
         选择VIP用户弹窗end
     */
-   /*
-    查看引用知识库抽屉start
-   */
+    /*
+     查看引用知识库抽屉start
+    */
     const [openDrawer, setOpenDrawer] = React.useState(false);
-    const [drawerItem,setDrawerItem] = React.useState<any>({});
+    const [drawerItem, setDrawerItem] = React.useState<any>({});
     const onCloseDrawer = () => {
         setOpenDrawer(false);
     }
 
-    const DrawerDetail = ()=>{
+    const DrawerDetail = () => {
         return (
-             <Drawer
+            <Drawer
                 title={drawerItem?.label}
                 width={'80%'}
                 closable={{ 'aria-label': 'Close Button' }}
                 onClose={onCloseDrawer}
                 open={openDrawer}
-                style={{zIndex:11111}}
+                style={{ zIndex: 11111 }}
             >
                 <DrawerIndex drawerItem={drawerItem}></DrawerIndex>
             </Drawer>
         )
     }
 
-   /*
-    查看引用知识库抽屉end
-   */
+    /*
+     查看引用知识库抽屉end
+    */
     return (
         <>
             <div className='questionAnswerInfo'>
@@ -810,13 +842,13 @@ const QuestionAnswerInfo: React.FC = () => {
                         initialValues={{
                             isDeepThink: 'N',
                             max_token: 4096,
-                            model:'Qwen3-30B-vl-chat',
+                            model: 'Qwen3-30B-vl-chat',
                             show_recall_result: true,
-                            rerank_model_name:'rerank',
-                            slice_config_type:'customized',
+                            rerank_model_name: 'rerank',
+                            slice_config_type: 'customized',
                             rerank_status: true,
-                            param_desc:'strict',
-                            recall_method:'mixed'
+                            param_desc: 'strict',
+                            recall_method: 'mixed'
                         }}
                     >
                         <div style={{ display: step === 1 ? 'block' : 'none' }} className='questionAnswerInfo-content'>
@@ -825,7 +857,7 @@ const QuestionAnswerInfo: React.FC = () => {
                                 name='name'
                                 rules={[{ required: true, message: '问答应用名称不能为空' }]}
                             >
-                                <Input placeholder="请输入问答应用名称" className='form-element-standard' style={{ height: '48px'}}/>
+                                <Input placeholder="请输入问答应用名称" className='form-element-standard' style={{ height: '48px' }} />
                             </FormItem>
                             <FormItem
                                 label='应用类型'
@@ -833,7 +865,7 @@ const QuestionAnswerInfo: React.FC = () => {
                             >
                                 <Select
                                     className='form-element-select'
-                                    style={{ height: '48px'}}
+                                    style={{ height: '48px' }}
                                     placeholder='请选择问答应用类型'
                                     onChange={handleAppChange}
                                     allowClear={true}
@@ -855,12 +887,28 @@ const QuestionAnswerInfo: React.FC = () => {
                                         name='appProId'
                                         rules={[{ required: true, message: '项目不能为空' }]}
                                     >
-                                        <Cascader
+                                        {/* <Cascader
                                             options={appProjectList}
                                             placeholder="请选择项目"
                                             showSearch
                                             className="form-element-select"
-                                            style={{ height: '48px'}}
+                                            style={{ height: '48px' }}
+                                        /> */}
+                                        <Select
+                                            showSearch
+                                            placeholder="请输入项目名称"
+                                            defaultActiveFirstOption={false}
+                                            filterOption={false}
+                                            className="form-element-select"
+                                            style={{ height: '48px' }}
+                                            notFoundContent={fetching ? <Spin size="small" /> : 'No results found'}
+                                            onSearch={(e) => {
+                                                projectApi.fetchProject(e);
+                                            }}
+                                            allowClear
+                                            onChange={(value) => {
+                                            }}
+                                            options={projectList}
                                         />
                                     </FormItem>
                                 </>
@@ -871,7 +919,7 @@ const QuestionAnswerInfo: React.FC = () => {
                             >
                                 <Select
                                     className='form-element-select'
-                                    style={{ height: '48px'}}
+                                    style={{ height: '48px' }}
                                     placeholder='请选择是否公开'
                                     allowClear={true}
                                     onChange={(e) => {
@@ -891,17 +939,17 @@ const QuestionAnswerInfo: React.FC = () => {
                                 label='显示顺序'
                                 name='sort'
                             >
-                                <InputNumber placeholder="请输入显示顺序" value={''} className='form-element-standard' style={{ height: '48px',lineHeight:'48px'}}/>
+                                <InputNumber placeholder="请输入显示顺序" value={''} className='form-element-standard' style={{ height: '48px', lineHeight: '48px' }} />
                             </FormItem>
                             {/* VIP用户 */}
-                            {visibleFlag==1&&<FormItem
+                            {visibleFlag == 1 && <FormItem
                                 label='指定用户'
                             >
                                 <div className='tags-info'>
                                     <p className='tags-list'>
                                         {vipList.map((item: any) =>
-                                        (<Tag key={item.userId} color="blue" closeIcon onClose={(e)=>{
-                                            const newVipList = vipList.filter((vip:any) => vip.userId !== item.userId);
+                                        (<Tag key={item.userId} color="blue" closeIcon onClose={(e) => {
+                                            const newVipList = vipList.filter((vip: any) => vip.userId !== item.userId);
                                             setVipList(newVipList);
                                             e.preventDefault();
                                         }}>
@@ -910,7 +958,7 @@ const QuestionAnswerInfo: React.FC = () => {
                                         )}
                                     </p>
                                     <p>
-                                        {vipList.length>0&&<CloseCircleOutlined className='cup' onClick={()=>{
+                                        {vipList.length > 0 && <CloseCircleOutlined className='cup' onClick={() => {
                                             setVipList([]);
                                         }} />}
                                         <Button style={{
@@ -1159,7 +1207,7 @@ const QuestionAnswerInfo: React.FC = () => {
                                                             // if (value === 'Qwen3-30B') {
                                                             //     setIsDeepThinkVisible(false);
                                                             // } else {
-                                                                setIsDeepThinkVisible(false);
+                                                            setIsDeepThinkVisible(false);
                                                             // }
                                                         }}
                                                     >

+ 122 - 97
src/pages/deepseek/questionAnswer/list/index.tsx

@@ -163,6 +163,7 @@ const QuestionAnswerList: React.FC = () => {
   const [isSearchExpanded, setIsSearchExpanded] = React.useState(false);
   const searchWrapperRef = React.useRef<HTMLDivElement>(null);
   const searchInputRef = React.useRef<any>(null);
+  const fetchRef = React.useRef<any>(null);
 
   const appApi = {
     fetchList: async (typeId: any, projectId: any, forceRefresh: boolean = false, pageNumber?: number, name?: string) => {
@@ -279,7 +280,7 @@ const QuestionAnswerList: React.FC = () => {
         // 1. 先请求应用列表,获取项目名称数据
         const userInfo = LocalStorage.getUserInfo();
         const userId = (userInfo?.id ?? '1').toString();
-        
+
         const appListRes = await apis.fetchTakaiAppList({
           keyword: '',
           name: '',
@@ -289,14 +290,14 @@ const QuestionAnswerList: React.FC = () => {
           userId: userId,
           projectId: null
         });
-        
+
         // 提取所有的 projectName 并去重
         const projectNames = appListRes.rows.map((item: any) => item.projectName).filter(Boolean);
         const uniqueProjectNames = new Set(projectNames);
-        
+
         // 2. 请求应用类型列表
         const res = await apis.fetchTakaiAppTypeList('app_type');
-        
+
         // 3. 对比数据,保留所有类型,但标记是否有对应的项目数据
         const list = res.data.map((item: any) => {
           return {
@@ -304,7 +305,7 @@ const QuestionAnswerList: React.FC = () => {
             value: item.dictCode,
           }
         });
-        
+
         // 不过滤项目级应用,始终显示所有类型
         setAppTypeList(list);
       } catch (error: any) {
@@ -331,30 +332,25 @@ const QuestionAnswerList: React.FC = () => {
           return acc;
         }, []);
         setAppProjectList(list);
-        // const res = await apis.fetchTakaiAppTypeList('projectTree');
-        // const list = res.data.map((item: any) => {
-        //   return {
-        //     label: item.dictLabel,
-        //     value: item.dictCode,
-        //   }
-        // });
-        // setAppProjectList(list);
       } catch (error: any) {
         console.error(error);
       }
     },
   };
-
+  const [fetching, setFetching] = React.useState(false);
+  // 获取项目列表
   const projectApi = {
-    fetchProject: async () => {
+    fetchProject: async (name: string = '') => {
       try {
-        const res = await apis.fetchTakaiProjectLibApi();
+        setFetching(true);
+        const res = await apis.fetchTakaiProjectLibApi(name);
         const list = res.data.map((item: any) => {
           return {
             label: item.projectName,
             value: item.projectId,
           }
         });
+        setFetching(false);
         setProjectList(list);
       } catch (error: any) {
         console.error(error);
@@ -382,13 +378,13 @@ const QuestionAnswerList: React.FC = () => {
 
   const init = async () => {
     await appTypeApi.fetchAppType();
-    await projectApi.fetchProject();
-    await appProTypeApi.fetchAppProType();
+    // await projectApi.fetchProject();
+    // await appProTypeApi.fetchAppProType();
     await levelTypeApi.fetchLevelAppType();
 
     // 检查是否从导航跳转过来,需要选中"项目级应用"
     const shouldSelectProjectApp = location.state?.selectProjectApp;
-    
+
     if (!shouldSelectProjectApp) {
       // 默认加载全部数据
       await appApi.fetchList(null, null, true); // 强制刷新
@@ -420,25 +416,25 @@ const QuestionAnswerList: React.FC = () => {
   // 监听 appTypeList 变化,处理从导航跳转过来选中"项目级应用"的逻辑
   React.useEffect(() => {
     const shouldSelectProjectApp = location.state?.selectProjectApp;
-    
+
     if (shouldSelectProjectApp && appTypeList.length > 0) {
       // 找到"项目级应用"的配置
       const projectAppType = appTypeList.find(item => item.label === '项目级应用');
-      
+
       if (projectAppType) {
         const projectAppValue = projectAppType.value;
         setSelectedType(projectAppValue);
         form.setFieldsValue({ typeId: projectAppValue });
-        
+
         // 如果是项目级应用(value为'41'),显示子面板
         if (projectAppValue === '41') {
           setShowSubPanel(true);
         }
-        
+
         // 加载对应的数据
         appApi.fetchList(projectAppValue, null, true);
         indexApi.fetchIndex(projectAppValue, null);
-        
+
         // 清除 location.state,避免重复触发
         window.history.replaceState({}, document.title);
       }
@@ -450,7 +446,7 @@ const QuestionAnswerList: React.FC = () => {
     if (appTypeList.length > 0) {
       const projectAppType = appTypeList.find(item => item.label === '项目级应用');
       const isProjectApp = projectAppType && selectedType === projectAppType.value;
-      
+
       // 触发自定义事件通知 Header 组件
       const event = new CustomEvent('projectAppActiveChange', {
         detail: { isActive: isProjectApp }
@@ -477,25 +473,25 @@ const QuestionAnswerList: React.FC = () => {
       const keyword = form.getFieldValue('keyword');
       const typeId = form.getFieldValue('proTypeId') || form.getFieldValue('typeId');
       let projectId = form.getFieldValue('projectId');
-      
+
       // 处理类型ID
       const finalTypeId = typeId === '全部' ? null : typeId;
-      
+
       // 处理项目ID
       if (projectId instanceof Array && projectId.length === 2) {
         projectId = projectId[1];
       }
-      
+
       // 标记正在分页切换,避免触发 useEffect
       isPaginatingRef.current = true;
-      
+
       // 更新页码和页大小
       setPage({
         pageNumber: pageNumber,
         pageSize: pageSize,
         total: page.total,
       });
-      
+
       // 调用接口获取新页数据
       appApi.fetchList(finalTypeId, projectId, true, pageNumber, keyword || '');
     },
@@ -506,7 +502,7 @@ const QuestionAnswerList: React.FC = () => {
   const handleClickSearch = async () => {
     form.validateFields().then(async (values) => {
       const keyword = values.keyword;
-      
+
       // 处理类型ID
       if (values.proTypeId) {
         values.typeId = values.proTypeId;
@@ -589,7 +585,6 @@ const QuestionAnswerList: React.FC = () => {
   };
 
 
-
   const handleAppTypeChange = (value: string) => {
     if (value === '41') {
       // 如果是项目级应用,切换面板状态
@@ -604,7 +599,7 @@ const QuestionAnswerList: React.FC = () => {
 
     // 获取当前搜索关键字
     const keyword = form.getFieldValue('keyword') || '';
-    
+
     // 自动提交逻辑
     if (value === '全部') {
       // 全部选项,传递null给后端
@@ -628,7 +623,7 @@ const QuestionAnswerList: React.FC = () => {
     <div>
       {/* 更新通知弹窗 - 只在此页面显示 */}
       <UpdateNotification version={CURRENT_VERSION} />
-      
+
       <div style={{ padding: '16px 20px', display: 'flex' }}>
         <Form
           form={form}
@@ -684,13 +679,34 @@ const QuestionAnswerList: React.FC = () => {
 
             {/* 子选项面板 */}
             {showSubPanel && selectedType === '41' && (
-
               <FormItem
                 label='类型'
                 name='proTypeId'
                 rules={[{ required: true, message: '类型不能为空' }]}
               >
                 <Select
+                  showSearch
+                  placeholder="请输入项目名称"
+                  defaultActiveFirstOption={false}
+                  filterOption={false}
+                  notFoundContent={fetching ? <Spin size="small" /> : 'No results found'}
+                  onSearch={(e) => {
+                    projectApi.fetchProject(e);
+                  }}
+                  allowClear
+                  style={{ width: 200 }}
+                  onChange={(value) => {
+                    const currentProTypeId = form.getFieldValue('proTypeId');
+                    const currentTypeId = currentProTypeId || form.getFieldValue('typeId');
+                    const keyword = form.getFieldValue('keyword') || '';
+                    const finalTypeId = currentTypeId === '全部' ? null : currentTypeId;
+
+                    appApi.fetchList(finalTypeId, value, true, 1, keyword);
+                    indexApi.fetchIndex(finalTypeId, value);
+                  }}
+                  options={projectList}
+                />
+                {/* <Select
                   placeholder='请选择'
                   allowClear
                   style={{ width: 200 }}
@@ -717,33 +733,45 @@ const QuestionAnswerList: React.FC = () => {
                       </Option>
                     })
                   }
-                </Select>
+                </Select> */}
               </FormItem>
             )}
           </div>
           {/* {
-                            appProjectList.map((subItem, index) => (
-                                <div key={index}>
-                                    {subItem.label}
-                                </div>
-                            ))
-                        } */ }
-       {appTypeList.find(item => item.value === selectedType)?.label === '项目级应用' && (
+                appProjectList.map((subItem, index) => (
+                    <div key={index}>
+                        {subItem.label}
+                    </div>
+                ))
+          } */ }
+          {appTypeList.find(item => item.value === selectedType)?.label === '项目级应用' && (
             <FormItem name='projectId'>
-              <Cascader
-                options={appProjectList}
-                placeholder="请选择项目"
+              <Select
                 showSearch
+                placeholder="请输入项目名称"
+                defaultActiveFirstOption={false}
+                filterOption={false}
+                notFoundContent={fetching ? <Spin size="small" /> : 'No results found'}
+                onSearch={(e) => {
+                  projectApi.fetchProject(e);
+                }}
+                allowClear
                 style={{ width: 200 }}
-                maxTagTextLength={10}
-                popupClassName="cascader-dropdown-fixed-width"
-                dropdownRender={(menus) => (
-                  <div style={{ maxWidth: 200 }}>
-                    {menus}
-                  </div>
-                )}
                 onChange={(value) => {
-                  // 项目选择器自动提交逻辑
+                  const currentProTypeId = form.getFieldValue('proTypeId');
+                  const currentTypeId = currentProTypeId || form.getFieldValue('typeId');
+                  const keyword = form.getFieldValue('keyword') || '';
+                  const finalTypeId = currentTypeId === '全部' ? null : currentTypeId;
+
+                  appApi.fetchList(finalTypeId, value, true, 1, keyword);
+                  indexApi.fetchIndex(finalTypeId, value);
+                }}
+                options={projectList}
+              />
+            </FormItem>
+          )}
+          {/* 
+                // 项目选择器自动提交逻辑
                   const currentProTypeId = form.getFieldValue('proTypeId');
                   const keyword = form.getFieldValue('keyword') || '';
                   let projectId: any = value;
@@ -753,33 +781,30 @@ const QuestionAnswerList: React.FC = () => {
                   }
                   appApi.fetchList(currentProTypeId, projectId, true, 1, keyword); // 强制刷新
                   indexApi.fetchIndex(currentProTypeId, projectId);
-                }}
-              />
-            </FormItem>
-          )}
-            {/*<Select*/}
-            {/*  placeholder='请选择项目'*/}
-            {/*  allowClear*/}
-            {/*  onChange={(value) => {*/}
-            {/*    // 项目选择器自动提交逻辑*/}
-            {/*    const currentTypeId = form.getFieldValue('typeId');*/}
-            {/*    const typeId = currentTypeId === '全部' ? null : currentTypeId;*/}
-            {/*    appApi.fetchList(typeId, value);*/}
-            {/*    indexApi.fetchIndex(typeId, value);*/}
-            {/*  }}*/}
-            {/*>*/}
-            {/*  {*/}
-            {/*    projectList.map((item, index) => {*/}
-            {/*      return <Option value={item.value} key={index}>*/}
-            {/*        {item.label}*/}
-            {/*      </Option>*/}
-            {/*    })*/}
-            {/*  }*/}
-            {/*</Select>*/}
+        */}
+          {/*<Select*/}
+          {/*  placeholder='请选择项目'*/}
+          {/*  allowClear*/}
+          {/*  onChange={(value) => {*/}
+          {/*    // 项目选择器自动提交逻辑*/}
+          {/*    const currentTypeId = form.getFieldValue('typeId');*/}
+          {/*    const typeId = currentTypeId === '全部' ? null : currentTypeId;*/}
+          {/*    appApi.fetchList(typeId, value);*/}
+          {/*    indexApi.fetchIndex(typeId, value);*/}
+          {/*  }}*/}
+          {/*>*/}
+          {/*  {*/}
+          {/*    projectList.map((item, index) => {*/}
+          {/*      return <Option value={item.value} key={index}>*/}
+          {/*        {item.label}*/}
+          {/*      </Option>*/}
+          {/*    })*/}
+          {/*  }*/}
+          {/*</Select>*/}
           {/* </FormItem> */}
           <FormItem>
             <Space size={12}>
-              <div 
+              <div
                 className={`search-expand-wrapper ${isSearchExpanded ? 'expanded' : ''}`}
                 ref={searchWrapperRef}
               >
@@ -836,7 +861,7 @@ const QuestionAnswerList: React.FC = () => {
 
         </Form>
       </div>
-      
+
       {/* 新手使用提示区块 */}
       {showGuide && (
         <div style={{ padding: '12px 20px 12px 20px' }}>
@@ -908,10 +933,10 @@ const QuestionAnswerList: React.FC = () => {
       )}
       {
         listLoading ? (
-          <div style={{ 
-            display: 'flex', 
-            justifyContent: 'center', 
-            alignItems: 'center', 
+          <div style={{
+            display: 'flex',
+            justifyContent: 'center',
+            alignItems: 'center',
             minHeight: '400px',
             padding: '50px 0'
           }}>
@@ -1015,20 +1040,20 @@ const QuestionAnswerList: React.FC = () => {
                               }}>ID:{item.appId}</span>
                               <Divider type="vertical" style={{ color: '999', margin: 0, height: 12 }} />
                               <span
-                                  style={ {
-                                    color: '#999',
-                                    fontSize: 12,
-                                    display: 'inline-block',
-                                    maxWidth: '100%',        // 限制最大宽度
-                                    flex: 1,      // 使span占据剩余空间
-                                    whiteSpace: 'nowrap',    // 禁止换行
-                                    overflow: 'hidden',      // 隐藏溢出内容
-                                    textOverflow: 'ellipsis', // 显示省略号
-                                    verticalAlign: 'middle'  // 垂直居中
-                                  } }
-                                  title={ item.projectName }   // 鼠标悬停时显示完整名称
+                                style={{
+                                  color: '#999',
+                                  fontSize: 12,
+                                  display: 'inline-block',
+                                  maxWidth: '100%',        // 限制最大宽度
+                                  flex: 1,      // 使span占据剩余空间
+                                  whiteSpace: 'nowrap',    // 禁止换行
+                                  overflow: 'hidden',      // 隐藏溢出内容
+                                  textOverflow: 'ellipsis', // 显示省略号
+                                  verticalAlign: 'middle'  // 垂直居中
+                                }}
+                                title={item.projectName}   // 鼠标悬停时显示完整名称
                               >
-                                          {item.projectName}
+                                {item.projectName}
                               </span>
                               {/*<span style={{ color: '#999', fontSize: 12 }}>*/}
                               {/*  {*/}
@@ -1155,7 +1180,7 @@ const QuestionAnswerList: React.FC = () => {
                             border: '1px solid #1677ff',
                             color: '#1677ff',
                             marginTop: '2px',
-                            marginLeft: createFlag && item.status === '5' || (item.status === '5' || item.status === '4' || item.status === '3' || item.status === '' || item.status === null) && updateFlag||userInfoAll.id === item.createBy ? '10px' : 0,
+                            marginLeft: createFlag && item.status === '5' || (item.status === '5' || item.status === '4' || item.status === '3' || item.status === '' || item.status === null) && updateFlag || userInfoAll.id === item.createBy ? '10px' : 0,
                             fontSize: 12,
                           }} type="primary" variant="outlined" onClick={() => { useNowAppLication(item.appId) }}>立即使用</Button>
                         </div>