import * as React from 'react'; import { useLocation } from 'react-router-dom'; import { observer } from 'mobx-react'; import './style.less'; import { Button, Input, Form, Divider, Splitter, Select, InputNumber, InputNumberProps, Radio, Switch, Row, Col, Slider, Space, RadioChangeEvent, Spin, message, Typography, Tooltip, Cascader, Tag, Modal, Table,TablePaginationConfig,Drawer } from 'antd'; import type { TableProps } from 'antd'; import { PlusCircleOutlined, MinusCircleOutlined, ArrowLeftOutlined, InfoCircleOutlined,CloseCircleOutlined,LinkOutlined } from '@ant-design/icons'; import { apis } from '@/apis'; import router from '@/router'; import LocalStorage from '@/LocalStorage'; import Chat from '@/components/chat'; import store from './store'; import DrawerIndex from '@/pages/deepseek/knowledgeLib/detail/drawerIndex' const { TextArea } = Input; const FormItem = Form.Item; const { Option } = Select; const MAX_COUNT = 5; const Index = 1; const QuestionAnswerInfo: React.FC = () => { const { state,onChangePagination,onFetchUserListApi } = store; const { page,sourceData } = state; const [form] = Form.useForm(); // top_p const [topPValue, setTopPValue] = React.useState(0.1); const TopPDecimalStep: React.FC = () => { const onChange: InputNumberProps['onChange'] = (value) => { if (Number.isNaN(value)) { return; } setTopPValue(value as number); }; return ( ); }; const [tempValue, setTempValue] = React.useState(0.01); // temperature const TempDecimalStep: React.FC = () => { const onChange: InputNumberProps['onChange'] = (value) => { if (Number.isNaN(value)) { return; } setTempValue(value as number); }; return ( ); }; type ModelList = { label: string, value: string, }[]; type KnowledgeList = { label: string, value: string, createBy: string, }[]; type AppTypeList = { label: string, value: string, children: { label: string, value: string, }[], }[]; const tagRender = (props:any) => { const { label, value, closable, onClose } = props; return ( {label} {/* 在删除按钮后添加自定义图标 */} { 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); // 这里可以添加你的业务逻辑,如:打开详情、编辑等 }} /> ); }; const [step, setStep] = React.useState(1); const [pageLoading, setPageLoading] = React.useState(false); const [modelList, setModelList] = React.useState([]); const [knowledgeList, setKnowledgeList] = React.useState([]); const [isVisible, setIsVisible] = React.useState(true); const [isVisibleCus, setIsVisibleCus] = React.useState(false); const [isVisibleSlice, setIsVisibleSlice] = React.useState(false); const [isVisibleRerank, setIsVisibleRerank] = React.useState(true); const [isDeepThinkVisible, setIsDeepThinkVisible] = React.useState(true); const [name, setName] = React.useState(''); const [appTypeList, setAppTypeList] = React.useState([]); const [appVisibleList, setAppVisibleList] = React.useState([]); // 是否公开 const [visibleFlag, setVisibleFlag] = React.useState(0); // 是否公开用来判断是否展示VIP用户 const [updateFlag, setUpdateFlag] = React.useState(); const [createFlag, setCreateFlag] = React.useState(); const [appProjectList, setAppProjectList] = React.useState([]); const [isAppPro, setIsAppPro] = React.useState(false); const [appId, setAppId] = React.useState(''); const [fetchUserTypeList, setFetchUserTypeList] = React.useState([]); // 用户类型 const [userName, setUserName] = React.useState(''); // 用户名 const [userNickName, setUserNickName] = React.useState(''); // 用户昵称 const [userType, setUserType] = React.useState(''); // 用户类型 const [vipList, setVipList] = React.useState([]); // 用户列表 const style: React.CSSProperties = { display: 'flex', flexDirection: 'column', gap: 8, width: 300, }; const location = useLocation(); const init = async (id: string) => { await Promise.all([ api.fetchKnowlegde(), api.fetchAppType(), // api.fetchModelList(), api.fetchAppProType(), api.fetchAppVisible(id) ]) if (id) { await api.fetchDetail(id); } onFetchUserListApi('','',''); await api.fetchUserType(); } React.useEffect(() => { const id = location?.state?.id; init(id); const uFlag = LocalStorage.getStatusFlag('deepseek:application:update'); setUpdateFlag(uFlag); const cFlag = LocalStorage.getStatusFlag('deepseek:application:create'); setCreateFlag(cFlag); }, []); // 定义一个状态来存储输入框数组 const [inputs, setInputs] = React.useState([{ id: 1, value: '' }]); // 添加新输入框的函数 const addInput = () => { const newId = inputs.length + 1; // 生成新的唯一ID setInputs([...inputs, { id: newId, value: '' }]); }; // 删除输入框(按id删除+最少数量限制) const delInput = (id: number) => { if (inputs.length <= 1) { message.warning("至少保留1个预设问题"); return; } setInputs(inputs.filter(input => input.id !== id)); }; // 处理输入变更的函数 const handleChange = (id: number, value: string) => { setInputs(inputs.map(input => (input.id === id ? { ...input, value } : input))); }; const handleAppChange = (typeId: number) => { if (typeId === 41) { // 根据实际值进行判断 setIsAppPro(true); } else { setIsAppPro(false); } }; const onChangeShow = (checked: boolean) => { console.log(`switch to ${checked}`); }; const onChangeModel = (checked: boolean) => { setIsVisibleRerank(!isVisibleRerank); }; const onChangeCount = (value: string) => { if (value === 'fixed') { setIsVisibleSlice(!isVisibleSlice); } else { setIsVisibleSlice(false); } }; // 召回方式 const onChangeRecallMethod = (e: RadioChangeEvent) => { }; // 获取应用详情 const api = { fetchDetail: async (app_id: string) => { setPageLoading(true); try { const res = await apis.fetchTakaiApplicationDetail(app_id); const sd = res.data.questionlist.map((item: any, index: number) => { return { "id": index + 1, "value": item.question, } }); const info = res.data.detail; setAppId(info.appId); setTopPValue(info.topP as number); setTempValue(info.temperature as number); setName(info.name); interface Item2 { index_type_id: number, knowledge_id: string } interface Item { show_recall_result: boolean, recall_method: string, rerank_status: boolean, slice_config_type: string, slice_count: number, recall_slice_splicing_method: string, param_desc: string, rerank_model_name: string, rerank_index_type_list: [Item2], recall_index_type_list: [Item2] } const data_info: Item = JSON.parse(info.knowledgeInfo); if (data_info.param_desc === 'custom') { setIsVisibleCus(!isVisibleCus); //自定义回答风格 } if (data_info.rerank_status === true) { setIsVisibleRerank(data_info.rerank_status) //模型 } //召回切片数量 if (data_info.slice_config_type === 'fixed') { setIsVisibleSlice(!isVisibleSlice); } else { setIsVisibleSlice(false); } if (info.typeId === 41) { setIsAppPro(true); } else { setIsAppPro(false); } if (info.model === 'Qwen3-30B') { setIsDeepThinkVisible(true); } else { setIsDeepThinkVisible(false); } form.setFieldsValue({ id: info.id, name: info.name, //应用名称 desc: info.desc, //应用描述 prompt: info.prompt, //应用提示语 top_p: info.topP as number, //topP temperature: info.temperature as number, //温度 knowledge_ids: info.knowledgeIds, model: info.model, isDeepThink: info.isDeepThink, icon_color: info.icon_color, icon_type: info.icon_type, 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, //显示顺序 param_desc: data_info.param_desc, //回答风格 show_recall_result: data_info.show_recall_result, //是否展示召回结果 recall_method: data_info.recall_method, //召回方式 rerank_status: data_info.rerank_status, //开启rerank rerank_model_name: 'rerank', //模型名称 slice_config_type: data_info.slice_config_type, // 召回切片数量 slice_count: data_info.slice_count, // 切片数量 recall_slice_splicing_method: data_info.recall_slice_splicing_method, // 切片内容 // rerank_status = 1 rerank_index_type_list // recall_method = 'embedding' || 'mixed' recall_index_type_list //recall_index_type_list: info.recall_index_type_list, //知识库id //rerank_index_type_list: info.rerank_index_type_list, //知识库id }) setVisibleFlag(info.visible || '0') if(info.vipList&&info.vipList.length>0){ setVipList(info.vipList); } if (sd.length > 0) { setInputs(sd); } } catch (error) { console.error(error); } finally { setPageLoading(false); } }, //获取知识库列表 fetchKnowlegde: async () => { try { const res = await apis.fetchTakaiKnowledgeList(); const list = res.data.map((item: any) => { return { label: item.name, value: item.knowledgeId, createBy: item.createBy, } }); setKnowledgeList(list); } catch (error: any) { console.error(error); } }, // 获取应用类型 fetchAppType: async () => { try { const res = await apis.fetchTakaiAppTypeList('app_type'); const list = res.data.map((item: any) => { return { label: item.dictLabel, value: item.dictCode, } }); setAppTypeList(list); } catch (error: any) { console.error(error); } }, // 获取是否公开类型 fetchAppVisible: async (id: string) => { try { const res = await apis.fetchTakaiAppTypeList('app_visible'); const list = res.data.map((item: any) => { return { label: item.dictLabel, value: item.dictValue, } }); setAppVisibleList(list); if (!id) { form.setFieldsValue({ visible: list[0]?.value }); setVisibleFlag(list[0]?.value); } } catch (error: any) { console.error(error); } }, // 获取用户类型 fetchUserType: async () => { try { const res = await apis.fetchTakaiAppTypeList('sys_user_type'); const list = res.data.map((item: any) => { return { label: item.dictLabel, value: item.dictValue, } }); setFetchUserTypeList(list); } catch (error: any) { console.error(error); } }, // 获取模型列表 fetchModelList: async () => { try { const res = await apis.fetchModelList(); const list = res.data.data.map((item: any) => { return { label: item.modelName, value: item.modelCode, } }); setModelList(list); } catch (error: any) { console.error(error); } }, // 项目级应用下的类型 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)=>{ acc.push({ label: val.label, value: `${item.value}-${val.value}`, }) }) } return acc; },[]); setAppProjectList(list); } catch (error: any) { console.error(error); } }, // 获取用户列表信息 fetchUserListApi: async () => { try { const res = await apis.fetchUserListApi({ pageNum:page.pageNumber, pageSize: page.pageSize, userName:userName, nickName:userNickName, userType:userType }); // setSourceData(res.rows) } catch (error) { console.error(error); } } } const handleRedioClick = (value: string) => { setIsVisibleCus(false); if (value === 'strict') { setTopPValue(0.5); setTempValue(0.01); } else if (value === 'moderate') { setTopPValue(0.7); setTempValue(0.50); } else if (value === 'flexib') { setTopPValue(0.9); setTempValue(0.90); } } const saveConfig = (type: 'SAVE' | 'SUBMIT') => { form.validateFields().then(async (values) => { const data = values; console.log(values, 'values'); // 问题列表 const question: string[] = []; if (inputs) { inputs.map((item, index) => { question.push(item.value); }); } console.log(question, 'question'); interface Item { index_type_id: number, knowledge_id: string } const indexTypeList: Item[] = []; if (values.knowledge_ids && values.knowledge_ids.length > 0) { console.log("knowledge_ids", values.knowledge_ids); const index_type: Item = { index_type_id: 0, knowledge_id: values.knowledge_ids }; indexTypeList.push(index_type); } const userInfo = LocalStorage.getUserInfo(); const userId = (userInfo?.id ?? '').toString(); const data_info = { param_desc: values.param_desc, //回答风格 show_recall_result: values.show_recall_result, //是否展示召回结果 recall_method: values.recall_method, //召回方式 rerank_status: values.rerank_status, //开启rerank rerank_model_name: values.rerank_model_name, //模型名称 slice_config_type: values.slice_config_type, // 召回切片数量 slice_count: values.slice_count, // 切片数量 recall_slice_splicing_method: values.recall_slice_splicing_method, // 切片内容 rerank_index_type_list: values.rerank_status === true ? indexTypeList : [], //知识库id recall_index_type_list: values.recall_method === 'embedding' || 'mixed' ? indexTypeList : [] // rerank_status = 1 rerank_index_type_list // recall_method = 'embedding' || 'embedding' recall_index_type_list }; // const knowledgeIds: string[] = []; // knowledgeIds.push(values.knowledge_ids); const info = { id: values.id, name: values.name, //应用名称 desc: values.desc, //应用描述 prompt: values.prompt, //应用提示语 top_p: topPValue.toString(), //topP temperature: tempValue.toString(), //温度 knowledge_ids: values.knowledge_ids, slice_count: values.slice_count, model: values.model, isDeepThink: values.isDeepThink, icon_color: values.icon_color, icon_type: values.icon_type, questionList: question, knowledge_info: JSON.stringify(data_info), max_token: values.max_token, //应用最大token typeId: values.typeId, // 应用类型 visible: values.visible, // 是否公开 sort: values.sort||null, // 显示顺序 vipList: vipList, // vip用户列表 appProId: values?.appProId?.[0]?.split('-') ?? null,// 项目 userId: userId, // 用户id }; console.log(info, 'info data'); const id = location?.state?.id; let res = null; if (id) { // 编辑应用 res = await apis.modifyTakaiApplicationApi(id, info); } else { // 创建应用 res = await await apis.createTakaiApplicationApi(info); } console.log(res, 'create or modify'); if (res.data === 9) { message.error('没有配置审核人,请联系管理员'); } else if (res.data === 1) { message.success('操作成功') } else { message.error('操作失败'); } if (type === 'SUBMIT') { router.navigate({ pathname: '/deepseek/questionAnswer' }); } }).catch((error) => { console.error(error); error.errorFields && error.errorFields.map((item: any) => { console.log(item, 'item'); message.error(`字段 ${item.name} ${item.errors[0]}`); }); }); } /* 选择VIP用户弹窗start */ const [isModalOpen, setIsModalOpen] = React.useState(false); let falgVipList:any = []; const handleOk = () => { setIsModalOpen(false); let vipListFalg:any = [...vipList]; const vipIds = new Set(vipListFalg.map((vip:any) => vip.userId)); const merged = [...vipListFalg]; falgVipList.forEach((item:any) => { if (!vipIds.has(item.userId)) { merged.push(item); } }); setVipList([...merged]); }; const handleCancel = async () => { setIsModalOpen(false); }; interface DataType { name: string; key: string; nickName: string; userName: string; deptName: string; userTypeName: string; } // const [sourceData, setSourceData] = React.useState([]); const paginationConfig: TablePaginationConfig = { // 显示数据总量 showTotal: (total: number) => { return `共 ${total} 条`; }, // 展示分页条数切换 showSizeChanger: false, // 指定每页显示条数 // 快速跳转至某页 showQuickJumper: false, current: page.pageNumber, pageSize: page.pageSize, total: page.total, onChange: async (page, pageSize) => { await onChangePagination(page, pageSize,userName,userNickName,userType); }, }; const vipModal = () => { const columns: TableProps['columns'] = [ { title: '昵称', dataIndex: 'nickName', render: (text) =>

{text}

, }, { title: '用户名称', dataIndex: 'userName', render: (text) =>

{text}

, }, { title: '部门', dataIndex: 'deptName', }, { title: '用户类型', dataIndex: 'userTypeName', }, ]; const rowSelection: TableProps['rowSelection'] = { type: 'checkbox', onChange: (selectedRowKeys: React.Key[], selectedRows: DataType[]) => { console.log(`selectedRowKeys: ${selectedRowKeys}`, 'selectedRows: ', selectedRows); falgVipList = selectedRows }, getCheckboxProps: (record: DataType) => ({ disabled: record.name === 'Disabled User', // Column configuration not to be checked name: record.name, }), }; return ( <>
{ setUserNickName(e.target.value) }} /> { setUserName(e.target.value) }} /> {/* */}
pagination={paginationConfig} rowKey="userName" rowSelection={rowSelection} columns={columns} dataSource={sourceData} />
) } /* 选择VIP用户弹窗end */ /* 查看引用知识库抽屉start */ const [openDrawer, setOpenDrawer] = React.useState(false); const [drawerItem,setDrawerItem] = React.useState({}); const onCloseDrawer = () => { setOpenDrawer(false); } const DrawerDetail = ()=>{ return ( ) } /* 查看引用知识库抽屉end */ return ( <>
{ isAppPro && <> } {/* VIP用户 */} {visibleFlag==1&&

{vipList.map((item: any) => ({ const newVipList = vipList.filter((vip:any) => vip.userId !== item.userId); setVipList(newVipList); e.preventDefault(); }}> {item.userName} ) )}

{vipList.length>0&&{ setVipList([]); }} />}

}