mirror of
https://git.mirrors.martin98.com/https://github.com/infiniflow/ragflow.git
synced 2025-04-20 13:10:05 +08:00
feat: remove loading from model and use DvaModel instead of redundant types such as kAModelType (#47)
* feat: use DvaModel instead of redundant types such as kAModelType * feat: set the type for registerServer * feat: remove loading from model
This commit is contained in:
parent
96a1a44cb6
commit
362ec6c364
11
web/src/hooks/storeHooks.ts
Normal file
11
web/src/hooks/storeHooks.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import { getOneNamespaceEffectsLoading } from '@/utils/stroreUtil';
|
||||
import { useSelector } from 'umi';
|
||||
|
||||
// Get the loading status of given effects under a certain namespace
|
||||
export const useOneNamespaceEffectsLoading = (
|
||||
namespace: string,
|
||||
effectNames: Array<string>,
|
||||
) => {
|
||||
const effects = useSelector((state: any) => state.loading.effects);
|
||||
return getOneNamespaceEffectsLoading(namespace, effects, effectNames);
|
||||
};
|
@ -1,53 +1,65 @@
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import { connect, Dispatch } from 'umi';
|
||||
import i18n from 'i18next';
|
||||
import { useTranslation, Trans } from 'react-i18next'
|
||||
import { Input, Modal, Form } from 'antd'
|
||||
import styles from './index.less';
|
||||
import type { chunkModelState } from './model'
|
||||
import EditTag from './editTag'
|
||||
import { Form, Input, Modal } from 'antd';
|
||||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useDispatch } from 'umi';
|
||||
import EditTag from './editTag';
|
||||
|
||||
type FieldType = {
|
||||
content_ltks?: string;
|
||||
};
|
||||
interface kFProps {
|
||||
dispatch: Dispatch;
|
||||
chunkModel: chunkModelState;
|
||||
getChunkList: () => void;
|
||||
isShowCreateModal: boolean;
|
||||
doc_id: string;
|
||||
chunk_id: string
|
||||
chunk_id: string;
|
||||
}
|
||||
const Index: React.FC<kFProps> = ({ dispatch, getChunkList, doc_id, isShowCreateModal, chunk_id }) => {
|
||||
|
||||
const Index: React.FC<kFProps> = ({
|
||||
getChunkList,
|
||||
doc_id,
|
||||
isShowCreateModal,
|
||||
chunk_id,
|
||||
}) => {
|
||||
const dispatch = useDispatch();
|
||||
const [form] = Form.useForm();
|
||||
|
||||
// const { , chunkInfo } = chunkModel
|
||||
const [important_kwd, setImportantKwd] = useState(['Unremovable', 'Tag 2', 'Tag 3']);
|
||||
const { t } = useTranslation()
|
||||
const [important_kwd, setImportantKwd] = useState([
|
||||
'Unremovable',
|
||||
'Tag 2',
|
||||
'Tag 3',
|
||||
]);
|
||||
const { t } = useTranslation();
|
||||
const handleCancel = () => {
|
||||
dispatch({
|
||||
type: 'chunkModel/updateState',
|
||||
payload: {
|
||||
isShowCreateModal: false
|
||||
}
|
||||
isShowCreateModal: false,
|
||||
},
|
||||
});
|
||||
};
|
||||
useEffect(() => {
|
||||
console.log(chunk_id, isShowCreateModal)
|
||||
|
||||
const getChunk = useCallback(async () => {
|
||||
if (chunk_id && isShowCreateModal) {
|
||||
dispatch({
|
||||
const data = await dispatch<any>({
|
||||
type: 'chunkModel/get_chunk',
|
||||
payload: {
|
||||
chunk_id
|
||||
chunk_id,
|
||||
},
|
||||
callback(info: any) {
|
||||
console.log(info)
|
||||
const { content_ltks, important_kwd = [] } = info
|
||||
form.setFieldsValue({ content_ltks })
|
||||
setImportantKwd(important_kwd)
|
||||
}
|
||||
});
|
||||
|
||||
if (data?.retcode === 0) {
|
||||
const { content_ltks, important_kwd = [] } = data.data;
|
||||
form.setFieldsValue({ content_ltks });
|
||||
setImportantKwd(important_kwd);
|
||||
}
|
||||
}, [chunk_id, isShowCreateModal])
|
||||
const [form] = Form.useForm()
|
||||
}
|
||||
}, [chunk_id, isShowCreateModal]);
|
||||
|
||||
useEffect(() => {
|
||||
getChunk();
|
||||
}, [getChunk]);
|
||||
|
||||
const handleOk = async () => {
|
||||
try {
|
||||
const values = await form.validateFields();
|
||||
@ -57,26 +69,30 @@ const Index: React.FC<kFProps> = ({ dispatch, getChunkList, doc_id, isShowCreate
|
||||
content_ltks: values.content_ltks,
|
||||
doc_id,
|
||||
chunk_id,
|
||||
important_kwd
|
||||
important_kwd,
|
||||
},
|
||||
callback: () => {
|
||||
dispatch({
|
||||
type: 'chunkModel/updateState',
|
||||
payload: {
|
||||
isShowCreateModal: false
|
||||
}
|
||||
// callback: () => {
|
||||
// dispatch({
|
||||
// type: 'chunkModel/updateState',
|
||||
// payload: {
|
||||
// isShowCreateModal: false,
|
||||
// },
|
||||
// });
|
||||
// getChunkList && getChunkList();
|
||||
// },
|
||||
});
|
||||
getChunkList && getChunkList()
|
||||
}
|
||||
});
|
||||
|
||||
} catch (errorInfo) {
|
||||
console.log('Failed:', errorInfo);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Modal title="Basic Modal" open={isShowCreateModal} onOk={handleOk} onCancel={handleCancel}>
|
||||
<Modal
|
||||
title="Basic Modal"
|
||||
open={isShowCreateModal}
|
||||
onOk={handleOk}
|
||||
onCancel={handleCancel}
|
||||
>
|
||||
<Form
|
||||
form={form}
|
||||
name="validateOnly"
|
||||
@ -95,8 +111,6 @@ const Index: React.FC<kFProps> = ({ dispatch, getChunkList, doc_id, isShowCreate
|
||||
<EditTag tags={important_kwd} setTags={setImportantKwd} />
|
||||
</Form>
|
||||
</Modal>
|
||||
|
||||
|
||||
);
|
||||
}
|
||||
export default connect(({ chunkModel, loading }) => ({ chunkModel, loading }))(Index);
|
||||
};
|
||||
export default Index;
|
||||
|
@ -1,12 +1,11 @@
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
import { PlusOutlined } from '@ant-design/icons';
|
||||
import type { InputRef } from 'antd';
|
||||
import { Input, Space, Tag, theme, Tooltip } from 'antd';
|
||||
interface editTagsProps {
|
||||
tags: any[],
|
||||
setTags: (tags: any[]) => void
|
||||
import { Input, Space, Tag, Tooltip, theme } from 'antd';
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
interface EditTagsProps {
|
||||
tags: any[];
|
||||
setTags: (tags: any[]) => void;
|
||||
}
|
||||
const App: React.FC<editTagsProps> = ({ tags, setTags }) => {
|
||||
const EditTag: React.FC<EditTagsProps> = ({ tags, setTags }) => {
|
||||
const { token } = theme.useToken();
|
||||
|
||||
const [inputVisible, setInputVisible] = useState(false);
|
||||
@ -139,4 +138,4 @@ const App: React.FC<editTagsProps> = ({ tags, setTags }) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default App;
|
||||
export default EditTag;
|
||||
|
@ -1,117 +1,144 @@
|
||||
import React, { useEffect, useState, useCallback } from 'react';
|
||||
import { useNavigate, connect, Dispatch } from 'umi'
|
||||
import { Card, Row, Col, Input, Select, Switch, Pagination, Spin, Button, Popconfirm } from 'antd';
|
||||
import { MinusSquareOutlined, DeleteOutlined, } from '@ant-design/icons';
|
||||
import { api_host } from '@/utils/api';
|
||||
import { getOneNamespaceEffectsLoading } from '@/utils/stroreUtil';
|
||||
import { DeleteOutlined, MinusSquareOutlined } from '@ant-design/icons';
|
||||
import type { PaginationProps } from 'antd';
|
||||
import { api_host } from '@/utils/api'
|
||||
import CreateModal from './components/createModal'
|
||||
import {
|
||||
Button,
|
||||
Card,
|
||||
Col,
|
||||
Input,
|
||||
Pagination,
|
||||
Popconfirm,
|
||||
Row,
|
||||
Select,
|
||||
Spin,
|
||||
Switch,
|
||||
} from 'antd';
|
||||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
import { useDispatch, useNavigate, useSelector } from 'umi';
|
||||
import CreateModal from './components/createModal';
|
||||
|
||||
|
||||
import styles from './index.less'
|
||||
import { debounce } from 'lodash';
|
||||
import type { chunkModelState } from './model'
|
||||
interface chunkProps {
|
||||
dispatch: Dispatch;
|
||||
chunkModel: chunkModelState;
|
||||
doc_id: string
|
||||
}
|
||||
const Index: React.FC<chunkProps> = ({ chunkModel, dispatch, doc_id }) => {
|
||||
const [keywords, SetKeywords] = useState('')
|
||||
const [available_int, setAvailableInt] = useState(-1)
|
||||
const navigate = useNavigate()
|
||||
const [pagination, setPagination] = useState({ page: 1, size: 30 })
|
||||
// const [datas, setDatas] = useState(data)
|
||||
const { data = [], total, loading, chunk_id, isShowCreateModal } = chunkModel
|
||||
console.log(chunkModel)
|
||||
const getChunkList = (value?: string) => {
|
||||
dispatch({
|
||||
type: 'chunkModel/updateState',
|
||||
payload: {
|
||||
loading: true
|
||||
}
|
||||
});
|
||||
interface payloadType {
|
||||
import styles from './index.less';
|
||||
|
||||
interface PayloadType {
|
||||
doc_id: string;
|
||||
keywords?: string;
|
||||
available_int?: number
|
||||
available_int?: number;
|
||||
}
|
||||
const payload: payloadType = {
|
||||
|
||||
interface IProps {
|
||||
doc_id: string;
|
||||
}
|
||||
|
||||
const Chunk = ({ doc_id }: IProps) => {
|
||||
const dispatch = useDispatch();
|
||||
const chunkModel = useSelector((state: any) => state.chunkModel);
|
||||
const [keywords, SetKeywords] = useState('');
|
||||
const [available_int, setAvailableInt] = useState(-1);
|
||||
const navigate = useNavigate();
|
||||
const [pagination, setPagination] = useState({ page: 1, size: 30 });
|
||||
// const [datas, setDatas] = useState(data)
|
||||
const { data = [], total, chunk_id, isShowCreateModal } = chunkModel;
|
||||
const effects = useSelector((state: any) => state.loading.effects);
|
||||
const loading = getOneNamespaceEffectsLoading('chunkModel', effects, [
|
||||
'create_hunk',
|
||||
'chunk_list',
|
||||
'switch_chunk',
|
||||
]);
|
||||
|
||||
const getChunkList = (value?: string) => {
|
||||
const payload: PayloadType = {
|
||||
doc_id,
|
||||
keywords: value || keywords,
|
||||
available_int
|
||||
}
|
||||
available_int,
|
||||
};
|
||||
if (payload.available_int === -1) {
|
||||
delete payload.available_int
|
||||
delete payload.available_int;
|
||||
}
|
||||
dispatch({
|
||||
type: 'chunkModel/chunk_list',
|
||||
payload: {
|
||||
...payload,
|
||||
...pagination
|
||||
}
|
||||
});
|
||||
}
|
||||
const confirm = (id: string) => {
|
||||
console.log(id)
|
||||
dispatch({
|
||||
type: 'chunkModel/rm_chunk',
|
||||
payload: {
|
||||
chunk_ids: [id]
|
||||
...pagination,
|
||||
},
|
||||
callback: getChunkList
|
||||
});
|
||||
};
|
||||
const confirm = async (id: string) => {
|
||||
const retcode = await dispatch<any>({
|
||||
type: 'chunkModel/rm_chunk',
|
||||
payload: {
|
||||
chunk_ids: [id],
|
||||
},
|
||||
});
|
||||
|
||||
retcode === 0 && getChunkList();
|
||||
};
|
||||
|
||||
const handleEditchunk = (chunk_id?: string) => {
|
||||
dispatch({
|
||||
type: 'chunkModel/updateState',
|
||||
payload: {
|
||||
isShowCreateModal: true,
|
||||
chunk_id,
|
||||
doc_id
|
||||
doc_id,
|
||||
},
|
||||
callback: getChunkList
|
||||
});
|
||||
}
|
||||
const onShowSizeChange: PaginationProps['onShowSizeChange'] = (page, size) => {
|
||||
setPagination({ page, size })
|
||||
getChunkList();
|
||||
};
|
||||
const switchChunk = (id: string, available_int: boolean) => {
|
||||
dispatch({
|
||||
type: 'chunkModel/updateState',
|
||||
payload: {
|
||||
loading: true
|
||||
}
|
||||
});
|
||||
dispatch({
|
||||
|
||||
const onShowSizeChange: PaginationProps['onShowSizeChange'] = (
|
||||
page,
|
||||
size,
|
||||
) => {
|
||||
setPagination({ page, size });
|
||||
};
|
||||
|
||||
const switchChunk = async (id: string, available_int: boolean) => {
|
||||
const retcode = await dispatch<any>({
|
||||
type: 'chunkModel/switch_chunk',
|
||||
payload: {
|
||||
chunk_ids: [id],
|
||||
available_int: Number(available_int),
|
||||
doc_id
|
||||
doc_id,
|
||||
},
|
||||
callback: getChunkList
|
||||
});
|
||||
}
|
||||
|
||||
retcode === 0 && getChunkList();
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
getChunkList()
|
||||
}, [doc_id, available_int, pagination])
|
||||
const debounceChange = debounce(getChunkList, 300)
|
||||
const debounceCallback = useCallback((value: string) => debounceChange(value), [])
|
||||
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
|
||||
const value = e.target.value
|
||||
SetKeywords(value)
|
||||
debounceCallback(value)
|
||||
}
|
||||
getChunkList();
|
||||
}, [doc_id, available_int, pagination]);
|
||||
|
||||
const debounceChange = debounce(getChunkList, 300);
|
||||
const debounceCallback = useCallback(
|
||||
(value: string) => debounceChange(value),
|
||||
[],
|
||||
);
|
||||
|
||||
const handleInputChange = (
|
||||
e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>,
|
||||
) => {
|
||||
const value = e.target.value;
|
||||
SetKeywords(value);
|
||||
debounceCallback(value);
|
||||
};
|
||||
const handleSelectChange = (value: number) => {
|
||||
setAvailableInt(value)
|
||||
}
|
||||
console.log('loading', loading)
|
||||
return (<>
|
||||
setAvailableInt(value);
|
||||
};
|
||||
return (
|
||||
<>
|
||||
<div className={styles.chunkPage}>
|
||||
<div className={styles.filter}>
|
||||
<div>
|
||||
<Input placeholder="搜索" style={{ width: 220 }} value={keywords} allowClear onChange={handleInputChange} />
|
||||
<Input
|
||||
placeholder="搜索"
|
||||
style={{ width: 220 }}
|
||||
value={keywords}
|
||||
allowClear
|
||||
onChange={handleInputChange}
|
||||
/>
|
||||
<Select
|
||||
showSearch
|
||||
placeholder="是否启用"
|
||||
@ -134,41 +161,69 @@ const Index: React.FC<chunkProps> = ({ chunkModel, dispatch, doc_id }) => {
|
||||
},
|
||||
]}
|
||||
/>
|
||||
|
||||
</div>
|
||||
<Button onClick={() => { handleEditchunk() }} type='link'>添加分段</Button>
|
||||
<Button
|
||||
onClick={() => {
|
||||
handleEditchunk();
|
||||
}}
|
||||
type="link"
|
||||
>
|
||||
添加分段
|
||||
</Button>
|
||||
</div>
|
||||
<div className={styles.pageContent}>
|
||||
<Spin spinning={loading} className={styles.spin} size='large'>
|
||||
<Spin spinning={loading} className={styles.spin} size="large">
|
||||
<Row gutter={{ xs: 8, sm: 16, md: 24, lg: 24 }}>
|
||||
{
|
||||
data.map((item: any) => {
|
||||
return (<Col className="gutter-row" key={item.chunk_id} xs={24} sm={12} md={12} lg={8}>
|
||||
<Card className={styles.card}
|
||||
onClick={() => { handleEditchunk(item.chunk_id) }}
|
||||
{data.map((item: any) => {
|
||||
return (
|
||||
<Col
|
||||
className="gutter-row"
|
||||
key={item.chunk_id}
|
||||
xs={24}
|
||||
sm={12}
|
||||
md={12}
|
||||
lg={8}
|
||||
>
|
||||
<img style={{ width: '50px' }} src={`${api_host}/document/image/${item.img_id}`} alt="" />
|
||||
<Card
|
||||
className={styles.card}
|
||||
onClick={() => {
|
||||
handleEditchunk(item.chunk_id);
|
||||
}}
|
||||
>
|
||||
<img
|
||||
style={{ width: '50px' }}
|
||||
src={`${api_host}/document/image/${item.img_id}`}
|
||||
alt=""
|
||||
/>
|
||||
<div className={styles.container}>
|
||||
<div className={styles.content}>
|
||||
<span className={styles.context}>
|
||||
{item.content_ltks}
|
||||
</span>
|
||||
<span className={styles.delete}>
|
||||
<Switch size="small" defaultValue={item.available_int == '1'} onChange={(checked: boolean, e: any) => {
|
||||
<Switch
|
||||
size="small"
|
||||
defaultValue={item.available_int == '1'}
|
||||
onChange={(checked: boolean, e: any) => {
|
||||
e.stopPropagation();
|
||||
e.nativeEvent.stopImmediatePropagation(); switchChunk(item.chunk_id, checked)
|
||||
}} />
|
||||
e.nativeEvent.stopImmediatePropagation();
|
||||
switchChunk(item.chunk_id, checked);
|
||||
}}
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
<div className={styles.footer}>
|
||||
<span className={styles.text}>
|
||||
<MinusSquareOutlined />{item.doc_num}文档
|
||||
<MinusSquareOutlined />
|
||||
{item.doc_num}文档
|
||||
</span>
|
||||
<span className={styles.text}>
|
||||
<MinusSquareOutlined />{item.chunk_num}个
|
||||
<MinusSquareOutlined />
|
||||
{item.chunk_num}个
|
||||
</span>
|
||||
<span className={styles.text}>
|
||||
<MinusSquareOutlined />{item.token_num}千字符
|
||||
<MinusSquareOutlined />
|
||||
{item.token_num}千字符
|
||||
</span>
|
||||
<span style={{ float: 'right' }}>
|
||||
<Popconfirm
|
||||
@ -176,31 +231,29 @@ const Index: React.FC<chunkProps> = ({ chunkModel, dispatch, doc_id }) => {
|
||||
description="Are you sure to delete this task?"
|
||||
onConfirm={(e: any) => {
|
||||
e.stopPropagation();
|
||||
e.nativeEvent.stopImmediatePropagation()
|
||||
console.log(confirm)
|
||||
confirm(item.chunk_id)
|
||||
|
||||
e.nativeEvent.stopImmediatePropagation();
|
||||
console.log(confirm);
|
||||
confirm(item.chunk_id);
|
||||
}}
|
||||
okText="Yes"
|
||||
cancelText="No"
|
||||
>
|
||||
<DeleteOutlined onClick={(e) => {
|
||||
<DeleteOutlined
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
e.nativeEvent.stopImmediatePropagation()
|
||||
}} />
|
||||
e.nativeEvent.stopImmediatePropagation();
|
||||
}}
|
||||
/>
|
||||
</Popconfirm>
|
||||
|
||||
</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</Card>
|
||||
</Col>)
|
||||
})
|
||||
}
|
||||
</Col>
|
||||
);
|
||||
})}
|
||||
</Row>
|
||||
</Spin>
|
||||
|
||||
</div>
|
||||
<div className={styles.pageFooter}>
|
||||
<Pagination
|
||||
@ -215,11 +268,15 @@ const Index: React.FC<chunkProps> = ({ chunkModel, dispatch, doc_id }) => {
|
||||
total={total}
|
||||
/>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<CreateModal doc_id={doc_id} isShowCreateModal={isShowCreateModal} chunk_id={chunk_id} getChunkList={getChunkList} />
|
||||
<CreateModal
|
||||
doc_id={doc_id}
|
||||
isShowCreateModal={isShowCreateModal}
|
||||
chunk_id={chunk_id}
|
||||
getChunkList={getChunkList}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
export default connect(({ chunkModel, loading }) => ({ chunkModel, loading }))(Index);
|
||||
export default Chunk;
|
||||
|
@ -1,8 +1,7 @@
|
||||
import kbService from '@/services/kbService';
|
||||
import { Effect, Reducer } from 'umi';
|
||||
import { DvaModel } from 'umi';
|
||||
|
||||
export interface chunkModelState {
|
||||
loading: boolean;
|
||||
export interface ChunkModelState {
|
||||
data: any[];
|
||||
total: number;
|
||||
isShowCreateModal: boolean;
|
||||
@ -10,25 +9,10 @@ export interface chunkModelState {
|
||||
doc_id: string;
|
||||
chunkInfo: any;
|
||||
}
|
||||
export interface chunkgModelType {
|
||||
namespace: 'chunkModel';
|
||||
state: chunkModelState;
|
||||
effects: {
|
||||
chunk_list: Effect;
|
||||
get_chunk: Effect;
|
||||
create_hunk: Effect;
|
||||
switch_chunk: Effect;
|
||||
rm_chunk: Effect;
|
||||
};
|
||||
reducers: {
|
||||
updateState: Reducer<chunkModelState>;
|
||||
};
|
||||
// subscriptions: { setup: Subscription };
|
||||
}
|
||||
const Model: chunkgModelType = {
|
||||
|
||||
const model: DvaModel<ChunkModelState> = {
|
||||
namespace: 'chunkModel',
|
||||
state: {
|
||||
loading: false,
|
||||
data: [],
|
||||
total: 0,
|
||||
isShowCreateModal: false,
|
||||
@ -36,6 +20,14 @@ const Model: chunkgModelType = {
|
||||
doc_id: '',
|
||||
chunkInfo: {},
|
||||
},
|
||||
reducers: {
|
||||
updateState(state, { payload }) {
|
||||
return {
|
||||
...state,
|
||||
...payload,
|
||||
};
|
||||
},
|
||||
},
|
||||
// subscriptions: {
|
||||
// setup({ dispatch, history }) {
|
||||
// history.listen(location => {
|
||||
@ -44,7 +36,7 @@ const Model: chunkgModelType = {
|
||||
// }
|
||||
// },
|
||||
effects: {
|
||||
*chunk_list({ payload = {}, callback }, { call, put }) {
|
||||
*chunk_list({ payload = {} }, { call, put }) {
|
||||
const { data, response } = yield call(kbService.chunk_list, payload);
|
||||
|
||||
const { retcode, data: res, retmsg } = data;
|
||||
@ -55,28 +47,23 @@ const Model: chunkgModelType = {
|
||||
payload: {
|
||||
data: res.chunks,
|
||||
total: res.total,
|
||||
loading: false,
|
||||
},
|
||||
});
|
||||
callback && callback();
|
||||
}
|
||||
},
|
||||
*switch_chunk({ payload = {}, callback }, { call, put }) {
|
||||
*switch_chunk({ payload = {} }, { call, put }) {
|
||||
const { data, response } = yield call(kbService.switch_chunk, payload);
|
||||
const { retcode, data: res, retmsg } = data;
|
||||
if (retcode === 0) {
|
||||
callback && callback();
|
||||
}
|
||||
return retcode;
|
||||
},
|
||||
*rm_chunk({ payload = {}, callback }, { call, put }) {
|
||||
*rm_chunk({ payload = {} }, { call, put }) {
|
||||
console.log('shanchu');
|
||||
const { data, response } = yield call(kbService.rm_chunk, payload);
|
||||
const { retcode, data: res, retmsg } = data;
|
||||
if (retcode === 0) {
|
||||
callback && callback();
|
||||
}
|
||||
|
||||
return retcode;
|
||||
},
|
||||
*get_chunk({ payload = {}, callback }, { call, put }) {
|
||||
*get_chunk({ payload = {} }, { call, put }) {
|
||||
const { data, response } = yield call(kbService.get_chunk, payload);
|
||||
const { retcode, data: res, retmsg } = data;
|
||||
if (retcode === 0) {
|
||||
@ -86,28 +73,16 @@ const Model: chunkgModelType = {
|
||||
chunkInfo: res,
|
||||
},
|
||||
});
|
||||
callback && callback(res);
|
||||
}
|
||||
return data;
|
||||
},
|
||||
*create_hunk({ payload = {} }, { call, put }) {
|
||||
yield put({
|
||||
type: 'updateState',
|
||||
payload: {
|
||||
loading: true,
|
||||
},
|
||||
});
|
||||
let service = kbService.create_chunk;
|
||||
if (payload.chunk_id) {
|
||||
service = kbService.set_chunk;
|
||||
}
|
||||
const { data, response } = yield call(service, payload);
|
||||
const { retcode, data: res, retmsg } = data;
|
||||
yield put({
|
||||
type: 'updateState',
|
||||
payload: {
|
||||
loading: false,
|
||||
},
|
||||
});
|
||||
if (retcode === 0) {
|
||||
yield put({
|
||||
type: 'updateState',
|
||||
@ -118,13 +93,5 @@ const Model: chunkgModelType = {
|
||||
}
|
||||
},
|
||||
},
|
||||
reducers: {
|
||||
updateState(state, { payload }) {
|
||||
return {
|
||||
...state,
|
||||
...payload,
|
||||
};
|
||||
},
|
||||
},
|
||||
};
|
||||
export default Model;
|
||||
export default model;
|
||||
|
@ -1,59 +1,56 @@
|
||||
import React from 'react'
|
||||
import { connect, Dispatch } from 'umi';
|
||||
import i18n from 'i18next';
|
||||
import { useTranslation, Trans } from 'react-i18next'
|
||||
import { Input, Modal, Form } from 'antd'
|
||||
import styles from './index.less';
|
||||
import type { kFModelState } from './model'
|
||||
import { Form, Input, Modal } from 'antd';
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useDispatch, useSelector } from 'umi';
|
||||
|
||||
type FieldType = {
|
||||
name?: string;
|
||||
};
|
||||
interface kFProps {
|
||||
dispatch: Dispatch;
|
||||
kFModel: kFModelState;
|
||||
getKfList: () => void;
|
||||
kb_id: string
|
||||
kb_id: string;
|
||||
}
|
||||
const Index: React.FC<kFProps> = ({ kFModel, dispatch, getKfList, kb_id }) => {
|
||||
const { isShowCEFwModal } = kFModel
|
||||
const { t } = useTranslation()
|
||||
|
||||
const FileCreatingModal: React.FC<kFProps> = ({ getKfList, kb_id }) => {
|
||||
const dispatch = useDispatch();
|
||||
const kFModel = useSelector((state: any) => state.kFModel);
|
||||
const { isShowCEFwModal } = kFModel;
|
||||
const [form] = Form.useForm();
|
||||
const { t } = useTranslation();
|
||||
|
||||
const handleCancel = () => {
|
||||
dispatch({
|
||||
type: 'kFModel/updateState',
|
||||
payload: {
|
||||
isShowCEFwModal: false
|
||||
}
|
||||
isShowCEFwModal: false,
|
||||
},
|
||||
});
|
||||
};
|
||||
const [form] = Form.useForm()
|
||||
const handleOk = async () => {
|
||||
try {
|
||||
const values = await form.validateFields();
|
||||
dispatch({
|
||||
const retcode = await dispatch<any>({
|
||||
type: 'kFModel/document_create',
|
||||
payload: {
|
||||
name: values.name,
|
||||
kb_id
|
||||
kb_id,
|
||||
},
|
||||
callback: () => {
|
||||
dispatch({
|
||||
type: 'kFModel/updateState',
|
||||
payload: {
|
||||
isShowCEFwModal: false
|
||||
}
|
||||
});
|
||||
getKfList && getKfList()
|
||||
if (retcode === 0) {
|
||||
getKfList && getKfList();
|
||||
}
|
||||
});
|
||||
|
||||
} catch (errorInfo) {
|
||||
console.log('Failed:', errorInfo);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Modal title="Basic Modal" open={isShowCEFwModal} onOk={handleOk} onCancel={handleCancel}>
|
||||
<Modal
|
||||
title="Basic Modal"
|
||||
open={isShowCEFwModal}
|
||||
onOk={handleOk}
|
||||
onCancel={handleCancel}
|
||||
>
|
||||
<Form
|
||||
form={form}
|
||||
name="validateOnly"
|
||||
@ -69,11 +66,8 @@ const Index: React.FC<kFProps> = ({ kFModel, dispatch, getKfList, kb_id }) => {
|
||||
>
|
||||
<Input />
|
||||
</Form.Item>
|
||||
|
||||
</Form>
|
||||
</Modal>
|
||||
|
||||
|
||||
);
|
||||
}
|
||||
export default connect(({ kFModel, loading }) => ({ kFModel, loading }))(Index);
|
||||
};
|
||||
export default FileCreatingModal;
|
||||
|
@ -1,15 +1,15 @@
|
||||
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { connect, Dispatch, useNavigate } from 'umi'
|
||||
import { Space, Table, Input, Button, Switch, Dropdown, } from 'antd';
|
||||
import { getOneNamespaceEffectsLoading } from '@/utils/stroreUtil';
|
||||
import { DownOutlined } from '@ant-design/icons';
|
||||
import type { MenuProps } from 'antd';
|
||||
import { DownOutlined } from '@ant-design/icons'
|
||||
import { debounce } from 'lodash';
|
||||
import { Button, Dropdown, Input, Space, Switch, Table } from 'antd';
|
||||
import type { ColumnsType } from 'antd/es/table';
|
||||
import UploadFile from './upload'
|
||||
import CreateEPModal from './createEFileModal'
|
||||
import SegmentSetModal from './segmentSetModal'
|
||||
import styles from './index.less'
|
||||
import type { kFModelState } from './model'
|
||||
import { debounce } from 'lodash';
|
||||
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { useDispatch, useNavigate, useSelector } from 'umi';
|
||||
import CreateEPModal from './createEFileModal';
|
||||
import styles from './index.less';
|
||||
import SegmentSetModal from './segmentSetModal';
|
||||
import UploadFile from './upload';
|
||||
|
||||
interface DataType {
|
||||
name: string;
|
||||
@ -19,77 +19,84 @@ interface DataType {
|
||||
size: string;
|
||||
status: string;
|
||||
id: string;
|
||||
parser_id: string
|
||||
parser_id: string;
|
||||
}
|
||||
|
||||
interface kFProps {
|
||||
dispatch: Dispatch;
|
||||
kFModel: kFModelState;
|
||||
kb_id: string
|
||||
interface KFProps {
|
||||
kb_id: string;
|
||||
}
|
||||
|
||||
const Index: React.FC<kFProps> = ({ kFModel, dispatch, kb_id }) => {
|
||||
const { data, loading } = kFModel
|
||||
const [inputValue, setInputValue] = useState('')
|
||||
const [doc_id, setDocId] = useState('0')
|
||||
const [parser_id, setParserId] = useState('0')
|
||||
const KnowledgeFile: React.FC<KFProps> = ({ kb_id }) => {
|
||||
const dispatch = useDispatch();
|
||||
const kFModel = useSelector((state: any) => state.kFModel);
|
||||
const effects = useSelector((state: any) => state.loading.effects);
|
||||
const { data } = kFModel;
|
||||
const loading = getOneNamespaceEffectsLoading('kFModel', effects, [
|
||||
'getKfList',
|
||||
'updateDocumentStatus',
|
||||
]);
|
||||
const [inputValue, setInputValue] = useState('');
|
||||
const [doc_id, setDocId] = useState('0');
|
||||
const [parser_id, setParserId] = useState('0');
|
||||
let navigate = useNavigate();
|
||||
|
||||
const getKfList = (keywords?: string) => {
|
||||
const payload = {
|
||||
kb_id,
|
||||
keywords
|
||||
}
|
||||
keywords,
|
||||
};
|
||||
if (!keywords) {
|
||||
delete payload.keywords
|
||||
delete payload.keywords;
|
||||
}
|
||||
dispatch({
|
||||
type: 'kFModel/getKfList',
|
||||
payload
|
||||
payload,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (kb_id) {
|
||||
getKfList()
|
||||
getKfList();
|
||||
}
|
||||
}, [kb_id])
|
||||
const debounceChange = debounce(getKfList, 300)
|
||||
const debounceCallback = useCallback((value: string) => debounceChange(value), [])
|
||||
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
|
||||
const value = e.target.value
|
||||
setInputValue(value)
|
||||
debounceCallback(e.target.value)
|
||||
}, [kb_id]);
|
||||
|
||||
}
|
||||
const debounceChange = debounce(getKfList, 300);
|
||||
const debounceCallback = useCallback(
|
||||
(value: string) => debounceChange(value),
|
||||
[],
|
||||
);
|
||||
const handleInputChange = (
|
||||
e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>,
|
||||
) => {
|
||||
const value = e.target.value;
|
||||
setInputValue(value);
|
||||
debounceCallback(e.target.value);
|
||||
};
|
||||
const onChangeStatus = (e: boolean, doc_id: string) => {
|
||||
dispatch({
|
||||
type: 'kFModel/updateDocumentStatus',
|
||||
payload: {
|
||||
doc_id,
|
||||
status: Number(e)
|
||||
status: Number(e),
|
||||
kb_id,
|
||||
},
|
||||
callback() {
|
||||
getKfList()
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
const onRmDocument = () => {
|
||||
dispatch({
|
||||
type: 'kFModel/document_rm',
|
||||
payload: {
|
||||
doc_id
|
||||
doc_id,
|
||||
kb_id,
|
||||
},
|
||||
callback() {
|
||||
getKfList()
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
};
|
||||
const showCEFModal = () => {
|
||||
dispatch({
|
||||
type: 'kFModel/updateState',
|
||||
payload: {
|
||||
isShowCEFwModal: true
|
||||
}
|
||||
isShowCEFwModal: true,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
@ -97,8 +104,8 @@ const Index: React.FC<kFProps> = ({ kFModel, dispatch, kb_id }) => {
|
||||
dispatch({
|
||||
type: 'kFModel/updateState',
|
||||
payload: {
|
||||
isShowSegmentSetModal: true
|
||||
}
|
||||
isShowSegmentSetModal: true,
|
||||
},
|
||||
});
|
||||
};
|
||||
const actionItems: MenuProps['items'] = useMemo(() => {
|
||||
@ -109,70 +116,85 @@ const Index: React.FC<kFProps> = ({ kFModel, dispatch, kb_id }) => {
|
||||
<div>
|
||||
<UploadFile kb_id={kb_id} getKfList={getKfList} />
|
||||
</div>
|
||||
|
||||
),
|
||||
},
|
||||
{
|
||||
key: '2',
|
||||
label: (
|
||||
<div>
|
||||
<Button type="link" onClick={showCEFModal}> 导入虚拟文件</Button>
|
||||
<Button type="link" onClick={showCEFModal}>
|
||||
{' '}
|
||||
导入虚拟文件
|
||||
</Button>
|
||||
</div>
|
||||
),
|
||||
// disabled: true,
|
||||
},
|
||||
]
|
||||
];
|
||||
}, [kb_id]);
|
||||
const chunkItems: MenuProps['items'] = [
|
||||
{
|
||||
key: '1',
|
||||
label: (
|
||||
<div>
|
||||
|
||||
<Button type="link" onClick={showSegmentSetModal}> 分段设置</Button>
|
||||
<Button type="link" onClick={showSegmentSetModal}>
|
||||
{' '}
|
||||
分段设置
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
),
|
||||
},
|
||||
{
|
||||
key: '2',
|
||||
label: (
|
||||
<div>
|
||||
<Button type="link" onClick={onRmDocument}> 删除</Button>
|
||||
<Button type="link" onClick={onRmDocument}>
|
||||
{' '}
|
||||
删除
|
||||
</Button>
|
||||
</div>
|
||||
),
|
||||
// disabled: true,
|
||||
},
|
||||
]
|
||||
];
|
||||
const toChunk = (id: string) => {
|
||||
console.log(id)
|
||||
console.log(id);
|
||||
navigate(`/knowledge/add/setting?activeKey=file&id=${kb_id}&doc_id=${id}`);
|
||||
}
|
||||
};
|
||||
const columns: ColumnsType<DataType> = [
|
||||
{
|
||||
title: '名称',
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
render: (text: any, { id }) => <div className={styles.tochunks} onClick={() => toChunk(id)}><img className={styles.img} src='https://gw.alipayobjects.com/zos/antfincdn/efFD%24IOql2/weixintupian_20170331104822.jpg' alt="" />{text}</div>,
|
||||
className: `${styles.column}`
|
||||
render: (text: any, { id }) => (
|
||||
<div className={styles.tochunks} onClick={() => toChunk(id)}>
|
||||
<img
|
||||
className={styles.img}
|
||||
src="https://gw.alipayobjects.com/zos/antfincdn/efFD%24IOql2/weixintupian_20170331104822.jpg"
|
||||
alt=""
|
||||
/>
|
||||
{text}
|
||||
</div>
|
||||
),
|
||||
className: `${styles.column}`,
|
||||
},
|
||||
{
|
||||
title: '数据总量',
|
||||
dataIndex: 'chunk_num',
|
||||
key: 'chunk_num',
|
||||
className: `${styles.column}`
|
||||
className: `${styles.column}`,
|
||||
},
|
||||
{
|
||||
title: 'Tokens',
|
||||
dataIndex: 'token_num',
|
||||
key: 'token_num',
|
||||
className: `${styles.column}`
|
||||
className: `${styles.column}`,
|
||||
},
|
||||
{
|
||||
title: '文件大小',
|
||||
dataIndex: 'size',
|
||||
key: 'size',
|
||||
className: `${styles.column}`
|
||||
className: `${styles.column}`,
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
@ -181,9 +203,12 @@ const Index: React.FC<kFProps> = ({ kFModel, dispatch, kb_id }) => {
|
||||
className: `${styles.column}`,
|
||||
render: (_, { status: string, id }) => (
|
||||
<>
|
||||
<Switch defaultChecked={status === '1'} onChange={(e) => {
|
||||
onChangeStatus(e, id)
|
||||
}} />
|
||||
<Switch
|
||||
defaultChecked={status === '1'}
|
||||
onChange={(e) => {
|
||||
onChangeStatus(e, id);
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
),
|
||||
},
|
||||
@ -194,10 +219,12 @@ const Index: React.FC<kFProps> = ({ kFModel, dispatch, kb_id }) => {
|
||||
render: (_, record) => (
|
||||
<Space size="middle">
|
||||
<Dropdown menu={{ items: chunkItems }} trigger={['click']}>
|
||||
<a onClick={() => {
|
||||
setDocId(record.id)
|
||||
setParserId(record.parser_id)
|
||||
}}>
|
||||
<a
|
||||
onClick={() => {
|
||||
setDocId(record.id);
|
||||
setParserId(record.parser_id);
|
||||
}}
|
||||
>
|
||||
分段设置 <DownOutlined />
|
||||
</a>
|
||||
</Dropdown>
|
||||
@ -205,10 +232,17 @@ const Index: React.FC<kFProps> = ({ kFModel, dispatch, kb_id }) => {
|
||||
),
|
||||
},
|
||||
];
|
||||
return <>
|
||||
return (
|
||||
<>
|
||||
<div className={styles.filter}>
|
||||
<div className="search">
|
||||
<Input placeholder="搜索" value={inputValue} style={{ width: 220 }} allowClear onChange={handleInputChange} />
|
||||
<Input
|
||||
placeholder="搜索"
|
||||
value={inputValue}
|
||||
style={{ width: 220 }}
|
||||
allowClear
|
||||
onChange={handleInputChange}
|
||||
/>
|
||||
</div>
|
||||
<div className="operate">
|
||||
<Dropdown menu={{ items: actionItems }} trigger={['click']}>
|
||||
@ -216,13 +250,24 @@ const Index: React.FC<kFProps> = ({ kFModel, dispatch, kb_id }) => {
|
||||
导入文件 <DownOutlined />
|
||||
</a>
|
||||
</Dropdown>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<Table rowKey='id' columns={columns} dataSource={data} loading={loading} pagination={false} scroll={{ scrollToFirstRowOnChange: true, x: true }} />
|
||||
<Table
|
||||
rowKey="id"
|
||||
columns={columns}
|
||||
dataSource={data}
|
||||
loading={loading}
|
||||
pagination={false}
|
||||
scroll={{ scrollToFirstRowOnChange: true, x: true }}
|
||||
/>
|
||||
<CreateEPModal getKfList={getKfList} kb_id={kb_id} />
|
||||
<SegmentSetModal getKfList={getKfList} parser_id={parser_id} doc_id={doc_id} />
|
||||
<SegmentSetModal
|
||||
getKfList={getKfList}
|
||||
parser_id={parser_id}
|
||||
doc_id={doc_id}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default connect(({ kFModel, loading }) => ({ kFModel, loading }))(Index);
|
||||
export default KnowledgeFile;
|
||||
|
@ -1,57 +1,47 @@
|
||||
import kbService from '@/services/kbService';
|
||||
import { message } from 'antd';
|
||||
import { Effect, Reducer, Subscription } from 'umi';
|
||||
import pick from 'lodash/pick';
|
||||
import { DvaModel } from 'umi';
|
||||
|
||||
export interface kFModelState {
|
||||
export interface KFModelState {
|
||||
isShowCEFwModal: boolean;
|
||||
isShowTntModal: boolean;
|
||||
isShowSegmentSetModal: boolean;
|
||||
loading: boolean;
|
||||
tenantIfo: any;
|
||||
data: any[];
|
||||
}
|
||||
export interface kFModelType {
|
||||
namespace: 'kFModel';
|
||||
state: kFModelState;
|
||||
effects: {
|
||||
createKf: Effect;
|
||||
updateKf: Effect;
|
||||
getKfDetail: Effect;
|
||||
getKfList: Effect;
|
||||
updateDocumentStatus: Effect;
|
||||
document_rm: Effect;
|
||||
document_create: Effect;
|
||||
document_change_parser: Effect;
|
||||
};
|
||||
reducers: {
|
||||
updateState: Reducer<kFModelState>;
|
||||
};
|
||||
subscriptions: { setup: Subscription };
|
||||
}
|
||||
const Model: kFModelType = {
|
||||
|
||||
const model: DvaModel<KFModelState> = {
|
||||
namespace: 'kFModel',
|
||||
state: {
|
||||
isShowCEFwModal: false,
|
||||
isShowTntModal: false,
|
||||
isShowSegmentSetModal: false,
|
||||
loading: false,
|
||||
tenantIfo: {},
|
||||
data: [],
|
||||
},
|
||||
reducers: {
|
||||
updateState(state, { payload }) {
|
||||
return {
|
||||
...state,
|
||||
...payload,
|
||||
};
|
||||
},
|
||||
},
|
||||
subscriptions: {
|
||||
setup({ dispatch, history }) {
|
||||
history.listen((location) => {});
|
||||
},
|
||||
},
|
||||
effects: {
|
||||
*createKf({ payload = {}, callback }, { call, put }) {
|
||||
*createKf({ payload = {} }, { call, put }) {
|
||||
const { data, response } = yield call(kbService.createKb, payload);
|
||||
const { retcode, data: res, retmsg } = data;
|
||||
if (retcode === 0) {
|
||||
message.success('创建成功!');
|
||||
}
|
||||
},
|
||||
*updateKf({ payload = {}, callback }, { call, put }) {
|
||||
*updateKf({ payload = {} }, { call, put }) {
|
||||
const { data, response } = yield call(kbService.updateKb, payload);
|
||||
const { retcode, data: res, retmsg } = data;
|
||||
if (retcode === 0) {
|
||||
@ -67,23 +57,12 @@ const Model: kFModelType = {
|
||||
}
|
||||
},
|
||||
*getKfList({ payload = {} }, { call, put }) {
|
||||
yield put({
|
||||
type: 'updateState',
|
||||
payload: {
|
||||
loading: true,
|
||||
},
|
||||
});
|
||||
const { data, response } = yield call(
|
||||
kbService.get_document_list,
|
||||
payload,
|
||||
);
|
||||
const { retcode, data: res, retmsg } = data;
|
||||
yield put({
|
||||
type: 'updateState',
|
||||
payload: {
|
||||
loading: false,
|
||||
},
|
||||
});
|
||||
|
||||
if (retcode === 0) {
|
||||
yield put({
|
||||
type: 'updateState',
|
||||
@ -93,64 +72,64 @@ const Model: kFModelType = {
|
||||
});
|
||||
}
|
||||
},
|
||||
*updateDocumentStatus({ payload = {}, callback }, { call, put }) {
|
||||
yield put({
|
||||
type: 'updateState',
|
||||
payload: {
|
||||
loading: true,
|
||||
},
|
||||
});
|
||||
*updateDocumentStatus({ payload = {} }, { call, put }) {
|
||||
const { data, response } = yield call(
|
||||
kbService.document_change_status,
|
||||
payload,
|
||||
pick(payload, ['doc_id', 'status']),
|
||||
);
|
||||
const { retcode, data: res, retmsg } = data;
|
||||
if (retcode === 0) {
|
||||
message.success('修改成功!');
|
||||
yield put({
|
||||
type: 'updateState',
|
||||
payload: {
|
||||
loading: false,
|
||||
},
|
||||
put({
|
||||
type: 'getKfList',
|
||||
payload: { kb_id: payload.kb_id },
|
||||
});
|
||||
callback && callback();
|
||||
}
|
||||
},
|
||||
*document_rm({ payload = {}, callback }, { call, put }) {
|
||||
const { data, response } = yield call(kbService.document_rm, payload);
|
||||
*document_rm({ payload = {} }, { call, put }) {
|
||||
const { data, response } = yield call(kbService.document_rm, {
|
||||
doc_id: payload.doc_id,
|
||||
});
|
||||
const { retcode, data: res, retmsg } = data;
|
||||
if (retcode === 0) {
|
||||
message.success('删除成功!');
|
||||
callback && callback();
|
||||
put({
|
||||
type: 'getKfList',
|
||||
payload: { kb_id: payload.kb_id },
|
||||
});
|
||||
}
|
||||
},
|
||||
*document_create({ payload = {}, callback }, { call, put }) {
|
||||
*document_create({ payload = {} }, { call, put }) {
|
||||
const { data, response } = yield call(kbService.document_create, payload);
|
||||
const { retcode, data: res, retmsg } = data;
|
||||
if (retcode === 0) {
|
||||
message.success('创建成功!');
|
||||
callback && callback();
|
||||
}
|
||||
put({
|
||||
type: 'kFModel/updateState',
|
||||
payload: {
|
||||
isShowCEFwModal: false,
|
||||
},
|
||||
*document_change_parser({ payload = {}, callback }, { call, put }) {
|
||||
});
|
||||
message.success('创建成功!');
|
||||
}
|
||||
return retcode;
|
||||
},
|
||||
*document_change_parser({ payload = {} }, { call, put }) {
|
||||
const { data, response } = yield call(
|
||||
kbService.document_change_parser,
|
||||
payload,
|
||||
);
|
||||
const { retcode, data: res, retmsg } = data;
|
||||
if (retcode === 0) {
|
||||
put({
|
||||
type: 'updateState',
|
||||
payload: {
|
||||
isShowSegmentSetModal: false,
|
||||
},
|
||||
});
|
||||
message.success('修改成功!');
|
||||
callback && callback();
|
||||
}
|
||||
},
|
||||
},
|
||||
reducers: {
|
||||
updateState(state, { payload }) {
|
||||
return {
|
||||
...state,
|
||||
...payload,
|
||||
};
|
||||
return retcode;
|
||||
},
|
||||
},
|
||||
};
|
||||
export default Model;
|
||||
export default model;
|
||||
|
@ -1,91 +1,87 @@
|
||||
import React from 'react';
|
||||
import { connect, Dispatch } from 'umi';
|
||||
import i18n from 'i18next';
|
||||
import { useTranslation, } from 'react-i18next'
|
||||
import { Modal, Tag, Space } from 'antd'
|
||||
import { useEffect, useState } from 'react';
|
||||
import { Modal, Space, Tag } from 'antd';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useDispatch, useSelector } from 'umi';
|
||||
import styles from './index.less';
|
||||
import type { kFModelState } from './model'
|
||||
import type { settingModelState } from '@/pages/setting/model'
|
||||
const { CheckableTag } = Tag;
|
||||
interface kFProps {
|
||||
dispatch: Dispatch;
|
||||
kFModel: kFModelState;
|
||||
settingModel: settingModelState;
|
||||
getKfList: () => void;
|
||||
parser_id: string;
|
||||
doc_id: string;
|
||||
}
|
||||
const Index: React.FC<kFProps> = ({ kFModel, settingModel, dispatch, getKfList, parser_id, doc_id }) => {
|
||||
const [selectedTag, setSelectedTag] = useState('')
|
||||
const { tenantIfo = {} } = settingModel
|
||||
const { parser_ids = '' } = tenantIfo
|
||||
const SegmentSetModal: React.FC<kFProps> = ({
|
||||
getKfList,
|
||||
parser_id,
|
||||
doc_id,
|
||||
}) => {
|
||||
const dispatch = useDispatch();
|
||||
const kFModel = useSelector((state: any) => state.kFModel);
|
||||
const settingModel = useSelector((state: any) => state.settingModel);
|
||||
const [selectedTag, setSelectedTag] = useState('');
|
||||
const { tenantIfo = {} } = settingModel;
|
||||
const { parser_ids = '' } = tenantIfo;
|
||||
const { isShowSegmentSetModal } = kFModel;
|
||||
const { t } = useTranslation();
|
||||
|
||||
useEffect(() => {
|
||||
dispatch({
|
||||
type: 'settingModel/getTenantInfo',
|
||||
payload: {
|
||||
}
|
||||
payload: {},
|
||||
});
|
||||
setSelectedTag(parser_id)
|
||||
}, [parser_id])
|
||||
const { isShowSegmentSetModal } = kFModel
|
||||
const { t } = useTranslation()
|
||||
setSelectedTag(parser_id);
|
||||
}, [parser_id]);
|
||||
|
||||
const handleCancel = () => {
|
||||
dispatch({
|
||||
type: 'kFModel/updateState',
|
||||
payload: {
|
||||
isShowSegmentSetModal: false
|
||||
}
|
||||
});
|
||||
};
|
||||
const handleOk = () => {
|
||||
console.log(1111, selectedTag)
|
||||
dispatch({
|
||||
type: 'kFModel/document_change_parser',
|
||||
payload: {
|
||||
parser_id: selectedTag,
|
||||
doc_id
|
||||
isShowSegmentSetModal: false,
|
||||
},
|
||||
callback: () => {
|
||||
dispatch({
|
||||
type: 'kFModel/updateState',
|
||||
payload: {
|
||||
isShowSegmentSetModal: false
|
||||
}
|
||||
});
|
||||
getKfList && getKfList()
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const handleOk = async () => {
|
||||
console.log(1111, selectedTag);
|
||||
const retcode = await dispatch<any>({
|
||||
type: 'kFModel/document_change_parser',
|
||||
payload: {
|
||||
parser_id: selectedTag,
|
||||
doc_id,
|
||||
},
|
||||
});
|
||||
|
||||
retcode === 0 && getKfList && getKfList();
|
||||
};
|
||||
|
||||
const handleChange = (tag: string, checked: boolean) => {
|
||||
const nextSelectedTag = checked
|
||||
? tag
|
||||
: selectedTag;
|
||||
const nextSelectedTag = checked ? tag : selectedTag;
|
||||
console.log('You are interested in: ', nextSelectedTag);
|
||||
setSelectedTag(nextSelectedTag);
|
||||
};
|
||||
|
||||
return (
|
||||
<Modal title="Basic Modal" open={isShowSegmentSetModal} onOk={handleOk} onCancel={handleCancel}>
|
||||
<Modal
|
||||
title="Basic Modal"
|
||||
open={isShowSegmentSetModal}
|
||||
onOk={handleOk}
|
||||
onCancel={handleCancel}
|
||||
>
|
||||
<Space size={[0, 8]} wrap>
|
||||
<div className={styles.tags}>
|
||||
{
|
||||
parser_ids.split(',').map((tag: string) => {
|
||||
return (<CheckableTag
|
||||
{parser_ids.split(',').map((tag: string) => {
|
||||
return (
|
||||
<CheckableTag
|
||||
key={tag}
|
||||
checked={selectedTag === tag}
|
||||
onChange={(checked) => handleChange(tag, checked)}
|
||||
>
|
||||
{tag}
|
||||
</CheckableTag>)
|
||||
})
|
||||
}
|
||||
</CheckableTag>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</Space>
|
||||
</Modal>
|
||||
|
||||
|
||||
);
|
||||
}
|
||||
export default connect(({ kFModel, settingModel, loading }) => ({ kFModel, settingModel, loading }))(Index);
|
||||
};
|
||||
export default SegmentSetModal;
|
||||
|
@ -1,33 +1,39 @@
|
||||
import React from 'react';
|
||||
import { connect } from 'umi'
|
||||
import uploadService from '@/services/uploadService';
|
||||
import type { UploadProps } from 'antd';
|
||||
import { Button, Upload } from 'antd';
|
||||
import uploadService from '@/services/uploadService'
|
||||
import React from 'react';
|
||||
interface PropsType {
|
||||
kb_id: string;
|
||||
getKfList: () => void
|
||||
getKfList: () => void;
|
||||
}
|
||||
|
||||
type UploadRequestOption = Parameters<
|
||||
NonNullable<UploadProps["customRequest"]>
|
||||
NonNullable<UploadProps['customRequest']>
|
||||
>[0];
|
||||
const Index: React.FC<PropsType> = ({ kb_id, getKfList }) => {
|
||||
const createRequest: (props: UploadRequestOption) => void = async function ({ file, onSuccess, onError }) {
|
||||
|
||||
const FileUpload: React.FC<PropsType> = ({ kb_id, getKfList }) => {
|
||||
const createRequest: (props: UploadRequestOption) => void = async function ({
|
||||
file,
|
||||
onSuccess,
|
||||
onError,
|
||||
}) {
|
||||
const { retcode, data } = await uploadService.uploadFile(file, kb_id);
|
||||
if (retcode === 0) {
|
||||
onSuccess && onSuccess(data, file);
|
||||
|
||||
} else {
|
||||
onError && onError(data);
|
||||
}
|
||||
getKfList && getKfList()
|
||||
getKfList && getKfList();
|
||||
};
|
||||
const uploadProps: UploadProps = {
|
||||
customRequest: createRequest,
|
||||
showUploadList: false,
|
||||
};
|
||||
return (<Upload {...uploadProps} >
|
||||
return (
|
||||
<Upload {...uploadProps}>
|
||||
<Button type="link">导入文件</Button>
|
||||
</Upload>)
|
||||
}
|
||||
</Upload>
|
||||
);
|
||||
};
|
||||
|
||||
export default connect(({ kFModel, settingModel, loading }) => ({ kFModel, settingModel, loading }))(Index);
|
||||
export default FileUpload;
|
||||
|
@ -1,147 +1,149 @@
|
||||
import React, { useEffect, useState, useCallback, } from 'react';
|
||||
import { useNavigate, connect, Dispatch } from 'umi'
|
||||
import { Card, Row, Col, Input, Select, Switch, Pagination, Spin, Button, Popconfirm } from 'antd';
|
||||
import { MinusSquareOutlined, DeleteOutlined, } from '@ant-design/icons';
|
||||
import { api_host } from '@/utils/api';
|
||||
import { DeleteOutlined, MinusSquareOutlined } from '@ant-design/icons';
|
||||
import type { PaginationProps } from 'antd';
|
||||
import { api_host } from '@/utils/api'
|
||||
import CreateModal from '../knowledge-chunk/components/createModal'
|
||||
import {
|
||||
Card,
|
||||
Col,
|
||||
Input,
|
||||
Pagination,
|
||||
Popconfirm,
|
||||
Row,
|
||||
Select,
|
||||
Spin,
|
||||
Switch,
|
||||
} from 'antd';
|
||||
import React, { useCallback, useEffect } from 'react';
|
||||
import { useDispatch, useSelector } from 'umi';
|
||||
import CreateModal from '../knowledge-chunk/components/createModal';
|
||||
|
||||
|
||||
import styles from './index.less'
|
||||
import { useOneNamespaceEffectsLoading } from '@/hooks/storeHooks';
|
||||
import { debounce } from 'lodash';
|
||||
import type { kSearchModelState } from './model'
|
||||
import type { chunkModelState } from '../knowledge-chunk/model'
|
||||
import styles from './index.less';
|
||||
interface chunkProps {
|
||||
dispatch: Dispatch;
|
||||
kSearchModel: kSearchModelState;
|
||||
chunkModel: chunkModelState;
|
||||
kb_id: string
|
||||
}
|
||||
const Index: React.FC<chunkProps> = ({ kSearchModel, chunkModel, dispatch, kb_id }) => {
|
||||
|
||||
const { data = [], total, loading, d_list = [], question, doc_ids, pagination, } = kSearchModel
|
||||
const { chunk_id, doc_id, isShowCreateModal } = chunkModel
|
||||
const getChunkList = () => {
|
||||
dispatch({
|
||||
type: 'kSearchModel/updateState',
|
||||
payload: {
|
||||
loading: true
|
||||
}
|
||||
});
|
||||
interface payloadType {
|
||||
kb_id: string;
|
||||
question?: string;
|
||||
doc_ids: any[];
|
||||
similarity_threshold?: number
|
||||
}
|
||||
const payload: payloadType = {
|
||||
kb_id,
|
||||
|
||||
const KnowledgeSearching: React.FC<chunkProps> = ({ kb_id }) => {
|
||||
const dispatch = useDispatch();
|
||||
const kSearchModel = useSelector((state: any) => state.kSearchModel);
|
||||
const chunkModel = useSelector((state: any) => state.chunkModel);
|
||||
const loading = useOneNamespaceEffectsLoading('kSearchModel', [
|
||||
'chunk_list',
|
||||
'switch_chunk',
|
||||
]);
|
||||
|
||||
const {
|
||||
data = [],
|
||||
total,
|
||||
d_list = [],
|
||||
question,
|
||||
doc_ids,
|
||||
similarity_threshold: 0.1
|
||||
}
|
||||
pagination,
|
||||
} = kSearchModel;
|
||||
const { chunk_id, doc_id, isShowCreateModal } = chunkModel;
|
||||
|
||||
const getChunkList = () => {
|
||||
dispatch({
|
||||
type: 'kSearchModel/chunk_list',
|
||||
payload: {
|
||||
...payload,
|
||||
...pagination
|
||||
}
|
||||
kb_id,
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
const confirm = (id: string) => {
|
||||
console.log(id)
|
||||
dispatch({
|
||||
type: 'kSearchModel/rm_chunk',
|
||||
payload: {
|
||||
chunk_ids: [id]
|
||||
chunk_ids: [id],
|
||||
kb_id,
|
||||
},
|
||||
callback: getChunkList
|
||||
});
|
||||
};
|
||||
const handleEditchunk = (item: any) => {
|
||||
const { chunk_id, doc_id } = item
|
||||
const { chunk_id, doc_id } = item;
|
||||
dispatch({
|
||||
type: 'chunkModel/updateState',
|
||||
payload: {
|
||||
isShowCreateModal: true,
|
||||
chunk_id,
|
||||
doc_id
|
||||
doc_id,
|
||||
},
|
||||
callback: getChunkList
|
||||
});
|
||||
}
|
||||
const onShowSizeChange: PaginationProps['onShowSizeChange'] = (page, size) => {
|
||||
getChunkList();
|
||||
};
|
||||
const onShowSizeChange: PaginationProps['onShowSizeChange'] = (
|
||||
page,
|
||||
size,
|
||||
) => {
|
||||
dispatch({
|
||||
type: 'kSearchModel/updateState',
|
||||
payload: {
|
||||
pagination: { page, size }
|
||||
}
|
||||
pagination: { page, size },
|
||||
},
|
||||
});
|
||||
};
|
||||
useEffect(() => {
|
||||
dispatch({
|
||||
type: 'kSearchModel/updateState',
|
||||
payload: {
|
||||
loading: false,
|
||||
doc_ids: [],
|
||||
question: ""
|
||||
}
|
||||
question: '',
|
||||
},
|
||||
});
|
||||
dispatch({
|
||||
type: 'kSearchModel/getKfList',
|
||||
payload: {
|
||||
kb_id
|
||||
}
|
||||
|
||||
kb_id,
|
||||
},
|
||||
});
|
||||
}, [])
|
||||
}, []);
|
||||
const switchChunk = (item: any, available_int: boolean) => {
|
||||
const { chunk_id, doc_id } = item
|
||||
dispatch({
|
||||
type: 'kSearchModel/updateState',
|
||||
payload: {
|
||||
loading: true
|
||||
}
|
||||
});
|
||||
const { chunk_id, doc_id } = item;
|
||||
|
||||
dispatch({
|
||||
type: 'kSearchModel/switch_chunk',
|
||||
payload: {
|
||||
chunk_ids: [chunk_id],
|
||||
doc_id,
|
||||
available_int
|
||||
available_int,
|
||||
kb_id,
|
||||
},
|
||||
callback: getChunkList
|
||||
});
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
getChunkList()
|
||||
}, [doc_ids, pagination, question])
|
||||
getChunkList();
|
||||
}, [doc_ids, pagination, question]);
|
||||
const debounceChange = debounce((value) => {
|
||||
dispatch({
|
||||
type: 'kSearchModel/updateState',
|
||||
payload: {
|
||||
question: value
|
||||
}
|
||||
question: value,
|
||||
},
|
||||
});
|
||||
}, 300)
|
||||
const debounceCallback = useCallback((value: string) => debounceChange(value), [])
|
||||
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
|
||||
const value = e.target.value
|
||||
debounceCallback(value)
|
||||
}
|
||||
const handleSelectChange = (value:
|
||||
any[]) => {
|
||||
}, 300);
|
||||
|
||||
const debounceCallback = useCallback(
|
||||
(value: string) => debounceChange(value),
|
||||
[],
|
||||
);
|
||||
const handleInputChange = (
|
||||
e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>,
|
||||
) => {
|
||||
const value = e.target.value;
|
||||
debounceCallback(value);
|
||||
};
|
||||
const handleSelectChange = (value: any[]) => {
|
||||
dispatch({
|
||||
type: 'kSearchModel/updateState',
|
||||
payload: {
|
||||
doc_ids: value
|
||||
}
|
||||
doc_ids: value,
|
||||
},
|
||||
});
|
||||
}
|
||||
console.log('loading', loading)
|
||||
return (<>
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className={styles.chunkPage}>
|
||||
<div className={styles.filter}>
|
||||
<Select
|
||||
@ -152,44 +154,71 @@ const Index: React.FC<chunkProps> = ({ kSearchModel, chunkModel, dispatch, kb_id
|
||||
style={{ width: 300, marginBottom: 20 }}
|
||||
options={d_list}
|
||||
fieldNames={{ label: 'name', value: 'id' }}
|
||||
mode='multiple'
|
||||
mode="multiple"
|
||||
/>
|
||||
|
||||
<Input.TextArea autoSize={{ minRows: 6, maxRows: 6 }} placeholder="搜索" style={{ width: 300 }} allowClear onChange={handleInputChange} />
|
||||
|
||||
<Input.TextArea
|
||||
autoSize={{ minRows: 6, maxRows: 6 }}
|
||||
placeholder="搜索"
|
||||
style={{ width: 300 }}
|
||||
allowClear
|
||||
onChange={handleInputChange}
|
||||
/>
|
||||
</div>
|
||||
<div className={styles.pageContainer}>
|
||||
<div className={styles.pageContent}>
|
||||
<Spin spinning={loading} className={styles.spin} size='large'>
|
||||
<Spin spinning={loading} className={styles.spin} size="large">
|
||||
<Row gutter={{ xs: 8, sm: 16, md: 24, lg: 24 }}>
|
||||
{
|
||||
data.map((item: any) => {
|
||||
return (<Col className="gutter-row" key={item.chunk_id} xs={24} sm={12} md={12} lg={8}>
|
||||
<Card className={styles.card}
|
||||
onClick={() => { handleEditchunk(item) }}
|
||||
{data.map((item: any) => {
|
||||
return (
|
||||
<Col
|
||||
className="gutter-row"
|
||||
key={item.chunk_id}
|
||||
xs={24}
|
||||
sm={12}
|
||||
md={12}
|
||||
lg={8}
|
||||
>
|
||||
<img style={{ width: '50px' }} src={`${api_host}/document/image/${item.img_id}`} alt="" />
|
||||
<Card
|
||||
className={styles.card}
|
||||
onClick={() => {
|
||||
handleEditchunk(item);
|
||||
}}
|
||||
>
|
||||
<img
|
||||
style={{ width: '50px' }}
|
||||
src={`${api_host}/document/image/${item.img_id}`}
|
||||
alt=""
|
||||
/>
|
||||
<div className={styles.container}>
|
||||
<div className={styles.content}>
|
||||
<span className={styles.context}>
|
||||
{item.content_ltks}
|
||||
</span>
|
||||
<span className={styles.delete}>
|
||||
<Switch size="small" defaultValue={item.doc_ids == '1'} onChange={(checked: boolean, e: any) => {
|
||||
<Switch
|
||||
size="small"
|
||||
defaultValue={item.doc_ids == '1'}
|
||||
onChange={(checked: boolean, e: any) => {
|
||||
e.stopPropagation();
|
||||
e.nativeEvent.stopImmediatePropagation(); switchChunk(item, checked)
|
||||
}} />
|
||||
e.nativeEvent.stopImmediatePropagation();
|
||||
switchChunk(item, checked);
|
||||
}}
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
<div className={styles.footer}>
|
||||
<span className={styles.text}>
|
||||
<MinusSquareOutlined />{item.doc_num}文档
|
||||
<MinusSquareOutlined />
|
||||
{item.doc_num}文档
|
||||
</span>
|
||||
<span className={styles.text}>
|
||||
<MinusSquareOutlined />{item.chunk_num}个
|
||||
<MinusSquareOutlined />
|
||||
{item.chunk_num}个
|
||||
</span>
|
||||
<span className={styles.text}>
|
||||
<MinusSquareOutlined />{item.token_num}千字符
|
||||
<MinusSquareOutlined />
|
||||
{item.token_num}千字符
|
||||
</span>
|
||||
<span style={{ float: 'right' }}>
|
||||
<Popconfirm
|
||||
@ -197,31 +226,29 @@ const Index: React.FC<chunkProps> = ({ kSearchModel, chunkModel, dispatch, kb_id
|
||||
description="Are you sure to delete this task?"
|
||||
onConfirm={(e: any) => {
|
||||
e.stopPropagation();
|
||||
e.nativeEvent.stopImmediatePropagation()
|
||||
console.log(confirm)
|
||||
confirm(item.chunk_id)
|
||||
|
||||
e.nativeEvent.stopImmediatePropagation();
|
||||
console.log(confirm);
|
||||
confirm(item.chunk_id);
|
||||
}}
|
||||
okText="Yes"
|
||||
cancelText="No"
|
||||
>
|
||||
<DeleteOutlined onClick={(e) => {
|
||||
<DeleteOutlined
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
e.nativeEvent.stopImmediatePropagation()
|
||||
}} />
|
||||
e.nativeEvent.stopImmediatePropagation();
|
||||
}}
|
||||
/>
|
||||
</Popconfirm>
|
||||
|
||||
</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</Card>
|
||||
</Col>)
|
||||
})
|
||||
}
|
||||
</Col>
|
||||
);
|
||||
})}
|
||||
</Row>
|
||||
</Spin>
|
||||
|
||||
</div>
|
||||
<div className={styles.pageFooter}>
|
||||
<Pagination
|
||||
@ -237,11 +264,15 @@ const Index: React.FC<chunkProps> = ({ kSearchModel, chunkModel, dispatch, kb_id
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<CreateModal getChunkList={getChunkList} isShowCreateModal={isShowCreateModal} chunk_id={chunk_id} doc_id={doc_id} />
|
||||
<CreateModal
|
||||
getChunkList={getChunkList}
|
||||
isShowCreateModal={isShowCreateModal}
|
||||
chunk_id={chunk_id}
|
||||
doc_id={doc_id}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
export default connect(({ kSearchModel, chunkModel, loading }) => ({ kSearchModel, chunkModel, loading }))(Index);
|
||||
export default KnowledgeSearching;
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { Effect, Reducer, Subscription } from 'umi'
|
||||
import { message } from 'antd';
|
||||
import kbService from '@/services/kbService';
|
||||
import omit from 'lodash/omit';
|
||||
import { DvaModel } from 'umi';
|
||||
|
||||
export interface kSearchModelState {
|
||||
export interface KSearchModelState {
|
||||
loading: boolean;
|
||||
data: any[];
|
||||
total: number;
|
||||
@ -13,26 +13,10 @@ export interface kSearchModelState {
|
||||
question: string;
|
||||
doc_ids: any[];
|
||||
pagination: any;
|
||||
doc_id: string
|
||||
doc_id: string;
|
||||
}
|
||||
|
||||
}
|
||||
export interface chunkgModelType {
|
||||
namespace: 'kSearchModel';
|
||||
state: kSearchModelState;
|
||||
effects: {
|
||||
chunk_list: Effect;
|
||||
get_chunk: Effect;
|
||||
create_hunk: Effect;
|
||||
switch_chunk: Effect;
|
||||
rm_chunk: Effect;
|
||||
getKfList: Effect;
|
||||
};
|
||||
reducers: {
|
||||
updateState: Reducer<kSearchModelState>;
|
||||
};
|
||||
subscriptions: { setup: Subscription };
|
||||
}
|
||||
const Model: chunkgModelType = {
|
||||
const model: DvaModel<KSearchModelState> = {
|
||||
namespace: 'kSearchModel',
|
||||
state: {
|
||||
loading: false,
|
||||
@ -45,114 +29,132 @@ const Model: chunkgModelType = {
|
||||
question: '',
|
||||
doc_ids: [],
|
||||
pagination: { page: 1, size: 30 },
|
||||
doc_id: ''
|
||||
doc_id: '',
|
||||
},
|
||||
reducers: {
|
||||
updateState(state, { payload }) {
|
||||
return {
|
||||
...state,
|
||||
...payload,
|
||||
};
|
||||
},
|
||||
},
|
||||
subscriptions: {
|
||||
setup({ dispatch, history }) {
|
||||
history.listen(location => {
|
||||
console.log(location)
|
||||
history.listen((location) => {
|
||||
console.log(location);
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
effects: {
|
||||
*getKfList({ payload = {} }, { call, put }) {
|
||||
const { data, response } = yield call(kbService.get_document_list, payload);
|
||||
const { data, response } = yield call(
|
||||
kbService.get_document_list,
|
||||
payload,
|
||||
);
|
||||
|
||||
const { retcode, data: res, retmsg } = data
|
||||
const { retcode, data: res, retmsg } = data;
|
||||
if (retcode === 0) {
|
||||
yield put({
|
||||
type: 'updateState',
|
||||
payload: {
|
||||
d_list: res
|
||||
}
|
||||
d_list: res,
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
* chunk_list({ payload = {}, callback }, { call, put }) {
|
||||
const { data, response } = yield call(kbService.retrieval_test, payload);
|
||||
const { retcode, data: res, retmsg } = data
|
||||
*chunk_list({ payload = {} }, { call, put, select }) {
|
||||
const { question, doc_ids, pagination }: KSearchModelState = yield select(
|
||||
(state: any) => state.kSearchModel,
|
||||
);
|
||||
const { data } = yield call(kbService.retrieval_test, {
|
||||
...payload,
|
||||
...pagination,
|
||||
question,
|
||||
doc_ids,
|
||||
similarity_threshold: 0.1,
|
||||
});
|
||||
const { retcode, data: res, retmsg } = data;
|
||||
if (retcode === 0) {
|
||||
console.log(res)
|
||||
yield put({
|
||||
type: 'updateState',
|
||||
payload: {
|
||||
data: res.chunks,
|
||||
total: res.total,
|
||||
loading: false
|
||||
}
|
||||
},
|
||||
});
|
||||
callback && callback()
|
||||
|
||||
}
|
||||
},
|
||||
*switch_chunk({ payload = {}, callback }, { call, put }) {
|
||||
const { data, response } = yield call(kbService.switch_chunk, payload);
|
||||
const { retcode, data: res, retmsg } = data
|
||||
*switch_chunk({ payload = {} }, { call, put }) {
|
||||
const { data } = yield call(
|
||||
kbService.switch_chunk,
|
||||
omit(payload, ['kb_id']),
|
||||
);
|
||||
const { retcode } = data;
|
||||
if (retcode === 0) {
|
||||
callback && callback()
|
||||
|
||||
yield put({
|
||||
type: 'chunk_list',
|
||||
payload: {
|
||||
kb_id: payload.kb_id,
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
*rm_chunk({ payload = {}, callback }, { call, put }) {
|
||||
console.log('shanchu')
|
||||
const { data, response } = yield call(kbService.rm_chunk, payload);
|
||||
const { retcode, data: res, retmsg } = data
|
||||
*rm_chunk({ payload = {} }, { call, put }) {
|
||||
const { data } = yield call(kbService.rm_chunk, {
|
||||
chunk_ids: payload.chunk_ids,
|
||||
});
|
||||
const { retcode, data: res, retmsg } = data;
|
||||
if (retcode === 0) {
|
||||
callback && callback()
|
||||
|
||||
// TODO: Can be extracted
|
||||
yield put({
|
||||
type: 'chunk_list',
|
||||
payload: {
|
||||
kb_id: payload.kb_id,
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
* get_chunk({ payload = {}, callback }, { call, put }) {
|
||||
*get_chunk({ payload = {} }, { call, put }) {
|
||||
const { data, response } = yield call(kbService.get_chunk, payload);
|
||||
const { retcode, data: res, retmsg } = data
|
||||
const { retcode, data: res, retmsg } = data;
|
||||
if (retcode === 0) {
|
||||
|
||||
yield put({
|
||||
type: 'updateState',
|
||||
payload: {
|
||||
chunkInfo: res
|
||||
}
|
||||
chunkInfo: res,
|
||||
},
|
||||
});
|
||||
callback && callback(res)
|
||||
|
||||
}
|
||||
},
|
||||
*create_hunk({ payload = {} }, { call, put }) {
|
||||
yield put({
|
||||
type: 'updateState',
|
||||
payload: {
|
||||
loading: true
|
||||
}
|
||||
loading: true,
|
||||
},
|
||||
});
|
||||
let service = kbService.create_chunk
|
||||
let service = kbService.create_chunk;
|
||||
if (payload.chunk_id) {
|
||||
service = kbService.set_chunk
|
||||
service = kbService.set_chunk;
|
||||
}
|
||||
const { data, response } = yield call(service, payload);
|
||||
const { retcode, data: res, retmsg } = data
|
||||
const { retcode, data: res, retmsg } = data;
|
||||
yield put({
|
||||
type: 'updateState',
|
||||
payload: {
|
||||
loading: false
|
||||
}
|
||||
loading: false,
|
||||
},
|
||||
});
|
||||
if (retcode === 0) {
|
||||
yield put({
|
||||
type: 'updateState',
|
||||
payload: {
|
||||
isShowCreateModal: false
|
||||
}
|
||||
isShowCreateModal: false,
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
reducers: {
|
||||
updateState(state, { payload }) {
|
||||
return {
|
||||
...state,
|
||||
...payload
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
export default Model;
|
||||
export default model;
|
||||
|
@ -1,59 +1,53 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useNavigate, connect, Dispatch } from 'umi'
|
||||
import { Button, Form, Input, Radio, Select, Tag, Space, } from 'antd';
|
||||
import type { kSModelState } from './model'
|
||||
import type { settingModelState } from '@/pages/setting/model'
|
||||
import styles from './index.less'
|
||||
import { Button, Form, Input, Radio, Select, Space, Tag } from 'antd';
|
||||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
import { useDispatch, useNavigate, useSelector } from 'umi';
|
||||
import styles from './index.less';
|
||||
const { CheckableTag } = Tag;
|
||||
const layout = {
|
||||
labelCol: { span: 8 },
|
||||
wrapperCol: { span: 16 },
|
||||
labelAlign: 'left' as const
|
||||
labelAlign: 'left' as const,
|
||||
};
|
||||
const { Option } = Select
|
||||
const { Option } = Select;
|
||||
/* eslint-disable no-template-curly-in-string */
|
||||
|
||||
interface kSProps {
|
||||
dispatch: Dispatch;
|
||||
kSModel: kSModelState;
|
||||
settingModel: settingModelState;
|
||||
kb_id: string
|
||||
kb_id: string;
|
||||
}
|
||||
const Index: React.FC<kSProps> = ({ settingModel, kSModel, dispatch, kb_id }) => {
|
||||
const KnowledgeSetting: React.FC<kSProps> = ({ kb_id }) => {
|
||||
const dispatch = useDispatch();
|
||||
const settingModel = useSelector((state: any) => state.settingModel);
|
||||
let navigate = useNavigate();
|
||||
const { tenantIfo = {} } = settingModel
|
||||
const { parser_ids = '', embd_id = '' } = tenantIfo
|
||||
const { tenantIfo = {} } = settingModel;
|
||||
const { parser_ids = '', embd_id = '' } = tenantIfo;
|
||||
const [form] = Form.useForm();
|
||||
const [selectedTag, setSelectedTag] = useState('');
|
||||
const values = Form.useWatch([], form);
|
||||
|
||||
useEffect(() => {
|
||||
const getTenantInfo = useCallback(async () => {
|
||||
dispatch({
|
||||
type: 'settingModel/getTenantInfo',
|
||||
payload: {
|
||||
}
|
||||
payload: {},
|
||||
});
|
||||
if (kb_id) {
|
||||
|
||||
dispatch({
|
||||
const data = await dispatch<any>({
|
||||
type: 'kSModel/getKbDetail',
|
||||
payload: {
|
||||
kb_id
|
||||
kb_id,
|
||||
},
|
||||
callback(detail: any) {
|
||||
console.log(detail)
|
||||
const { description, name, permission, embd_id } = detail
|
||||
form.setFieldsValue({ description, name, permission, embd_id })
|
||||
setSelectedTag(detail.parser_id)
|
||||
}
|
||||
});
|
||||
if (data.retcode === 0) {
|
||||
const { description, name, permission, embd_id } = data.data;
|
||||
form.setFieldsValue({ description, name, permission, embd_id });
|
||||
setSelectedTag(data.data.parser_id);
|
||||
}
|
||||
}
|
||||
}, [kb_id]);
|
||||
|
||||
const onFinish = async () => {
|
||||
try {
|
||||
await form.validateFields();
|
||||
|
||||
}, [kb_id])
|
||||
const [selectedTag, setSelectedTag] = useState('')
|
||||
const values = Form.useWatch([], form);
|
||||
console.log(values, '......变化')
|
||||
const onFinish = () => {
|
||||
form.validateFields().then(
|
||||
() => {
|
||||
if (kb_id) {
|
||||
dispatch({
|
||||
type: 'kSModel/updateKb',
|
||||
@ -61,49 +55,46 @@ const Index: React.FC<kSProps> = ({ settingModel, kSModel, dispatch, kb_id }) =>
|
||||
...values,
|
||||
parser_id: selectedTag,
|
||||
kb_id,
|
||||
embd_id: undefined
|
||||
}
|
||||
embd_id: undefined,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
dispatch({
|
||||
const retcode = await dispatch<any>({
|
||||
type: 'kSModel/createKb',
|
||||
payload: {
|
||||
...values,
|
||||
parser_id: selectedTag
|
||||
parser_id: selectedTag,
|
||||
},
|
||||
callback(id: string) {
|
||||
});
|
||||
retcode === 0 &&
|
||||
navigate(`/knowledge/add/setting?activeKey=file&id=${kb_id}`);
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
console.warn(error);
|
||||
}
|
||||
},
|
||||
() => {
|
||||
|
||||
},
|
||||
);
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
getTenantInfo();
|
||||
}, [getTenantInfo]);
|
||||
|
||||
const handleChange = (tag: string, checked: boolean) => {
|
||||
const nextSelectedTag = checked
|
||||
? tag
|
||||
: selectedTag;
|
||||
const nextSelectedTag = checked ? tag : selectedTag;
|
||||
console.log('You are interested in: ', nextSelectedTag);
|
||||
setSelectedTag(nextSelectedTag);
|
||||
};
|
||||
|
||||
return <Form
|
||||
return (
|
||||
<Form
|
||||
{...layout}
|
||||
form={form}
|
||||
name="validateOnly"
|
||||
style={{ maxWidth: 1000, padding: 14 }}
|
||||
>
|
||||
<Form.Item name='name' label="知识库名称" rules={[{ required: true }]}>
|
||||
<Form.Item name="name" label="知识库名称" rules={[{ required: true }]}>
|
||||
<Input />
|
||||
</Form.Item>
|
||||
<Form.Item name='description' label="知识库描述">
|
||||
<Form.Item name="description" label="知识库描述">
|
||||
<Input.TextArea />
|
||||
</Form.Item>
|
||||
<Form.Item name="permission" label="可见权限">
|
||||
@ -120,9 +111,12 @@ const Index: React.FC<kSProps> = ({ settingModel, kSModel, dispatch, kb_id }) =>
|
||||
>
|
||||
<Select placeholder="Please select a country">
|
||||
{embd_id.split(',').map((item: string) => {
|
||||
return <Option value={item} key={item}>{item}</Option>
|
||||
return (
|
||||
<Option value={item} key={item}>
|
||||
{item}
|
||||
</Option>
|
||||
);
|
||||
})}
|
||||
|
||||
</Select>
|
||||
</Form.Item>
|
||||
<div style={{ marginTop: '5px' }}>
|
||||
@ -130,29 +124,23 @@ const Index: React.FC<kSProps> = ({ settingModel, kSModel, dispatch, kb_id }) =>
|
||||
</div>
|
||||
<Space size={[0, 8]} wrap>
|
||||
<div className={styles.tags}>
|
||||
{
|
||||
parser_ids.split(',').map((tag: string) => {
|
||||
return (<CheckableTag
|
||||
{parser_ids.split(',').map((tag: string) => {
|
||||
return (
|
||||
<CheckableTag
|
||||
key={tag}
|
||||
checked={selectedTag === tag}
|
||||
onChange={(checked) => handleChange(tag, checked)}
|
||||
>
|
||||
{tag}
|
||||
</CheckableTag>)
|
||||
})
|
||||
}
|
||||
</CheckableTag>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</Space>
|
||||
<Space size={[0, 8]} wrap>
|
||||
|
||||
</Space>
|
||||
<Space size={[0, 8]} wrap></Space>
|
||||
<div className={styles.preset}>
|
||||
<div className={styles.left}>
|
||||
xxxxx文章
|
||||
</div>
|
||||
<div className={styles.right}>
|
||||
预估份数
|
||||
</div>
|
||||
<div className={styles.left}>xxxxx文章</div>
|
||||
<div className={styles.right}>预估份数</div>
|
||||
</div>
|
||||
<Form.Item wrapperCol={{ ...layout.wrapperCol, offset: 8 }}>
|
||||
<Button type="primary" onClick={onFinish}>
|
||||
@ -163,8 +151,7 @@ const Index: React.FC<kSProps> = ({ settingModel, kSModel, dispatch, kb_id }) =>
|
||||
</Button>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
|
||||
export default connect(({ settingModel, kSModel, loading }) => ({ settingModel, kSModel, loading }))(Index);
|
||||
export default KnowledgeSetting;
|
||||
|
@ -1,72 +1,54 @@
|
||||
import { message } from 'antd';
|
||||
import { Effect, Reducer, Subscription } from 'umi'
|
||||
import kbService from '@/services/kbService';
|
||||
import { message } from 'antd';
|
||||
import { DvaModel } from 'umi';
|
||||
|
||||
export interface kSModelState {
|
||||
export interface KSModelState {
|
||||
isShowPSwModal: boolean;
|
||||
isShowTntModal: boolean;
|
||||
loading: boolean;
|
||||
tenantIfo: any
|
||||
tenantIfo: any;
|
||||
}
|
||||
export interface kSModelType {
|
||||
namespace: 'kSModel';
|
||||
state: kSModelState;
|
||||
effects: {
|
||||
createKb: Effect;
|
||||
updateKb: Effect;
|
||||
getKbDetail: Effect;
|
||||
};
|
||||
reducers: {
|
||||
updateState: Reducer<kSModelState>;
|
||||
};
|
||||
subscriptions: { setup: Subscription };
|
||||
}
|
||||
const Model: kSModelType = {
|
||||
|
||||
const model: DvaModel<KSModelState> = {
|
||||
namespace: 'kSModel',
|
||||
state: {
|
||||
isShowPSwModal: false,
|
||||
isShowTntModal: false,
|
||||
loading: false,
|
||||
tenantIfo: {}
|
||||
},
|
||||
subscriptions: {
|
||||
setup({ dispatch, history }) {
|
||||
history.listen(location => {
|
||||
});
|
||||
}
|
||||
},
|
||||
effects: {
|
||||
* createKb({ payload = {}, callback }, { call, put }) {
|
||||
const { data, response } = yield call(kbService.createKb, payload);
|
||||
const { retcode, data: res, retmsg } = data
|
||||
if (retcode === 0) {
|
||||
message.success('创建知识库成功!');
|
||||
callback && callback(res.kb_id)
|
||||
}
|
||||
},
|
||||
* updateKb({ payload = {}, callback }, { call, put }) {
|
||||
const { data, response } = yield call(kbService.updateKb, payload);
|
||||
const { retcode, data: res, retmsg } = data
|
||||
if (retcode === 0) {
|
||||
message.success('更新知识库成功!');
|
||||
}
|
||||
},
|
||||
*getKbDetail({ payload = {}, callback }, { call, put }) {
|
||||
const { data, response } = yield call(kbService.get_kb_detail, payload);
|
||||
const { retcode, data: res, retmsg } = data
|
||||
if (retcode === 0) {
|
||||
// localStorage.setItem('userInfo',res.)
|
||||
callback && callback(res)
|
||||
}
|
||||
},
|
||||
tenantIfo: {},
|
||||
},
|
||||
reducers: {
|
||||
updateState(state, { payload }) {
|
||||
return {
|
||||
...state,
|
||||
...payload
|
||||
...payload,
|
||||
};
|
||||
},
|
||||
},
|
||||
subscriptions: {
|
||||
setup({ dispatch, history }) {
|
||||
history.listen((location) => {});
|
||||
},
|
||||
},
|
||||
effects: {
|
||||
*createKb({ payload = {} }, { call, put }) {
|
||||
const { data } = yield call(kbService.createKb, payload);
|
||||
const { retcode } = data;
|
||||
if (retcode === 0) {
|
||||
message.success('创建知识库成功!');
|
||||
}
|
||||
return retcode;
|
||||
},
|
||||
*updateKb({ payload = {} }, { call, put }) {
|
||||
const { data } = yield call(kbService.updateKb, payload);
|
||||
const { retcode, data: res, retmsg } = data;
|
||||
if (retcode === 0) {
|
||||
message.success('更新知识库成功!');
|
||||
}
|
||||
},
|
||||
*getKbDetail({ payload = {} }, { call, put }) {
|
||||
const { data } = yield call(kbService.get_kb_detail, payload);
|
||||
|
||||
return data;
|
||||
},
|
||||
},
|
||||
};
|
||||
export default Model;
|
||||
export default model;
|
||||
|
@ -1,69 +1,64 @@
|
||||
import { connect, useNavigate, useLocation, Dispatch } from 'umi'
|
||||
import React, { useState, useEffect, useMemo } from 'react';
|
||||
import { getWidth } from '@/utils';
|
||||
import { BarsOutlined, SearchOutlined, ToolOutlined } from '@ant-design/icons';
|
||||
import type { MenuProps } from 'antd';
|
||||
import { Menu } from 'antd';
|
||||
import {
|
||||
ToolOutlined,
|
||||
BarsOutlined,
|
||||
SearchOutlined
|
||||
} from '@ant-design/icons';
|
||||
import File from './components/knowledge-file'
|
||||
import Setting from './components/knowledge-setting'
|
||||
import Search from './components/knowledge-search'
|
||||
import Chunk from './components/knowledge-chunk'
|
||||
import styles from './index.less'
|
||||
import { getWidth } from '@/utils'
|
||||
import { kAModelState } from './model'
|
||||
import React, { useEffect, useMemo, useState } from 'react';
|
||||
import { useDispatch, useLocation, useNavigate, useSelector } from 'umi';
|
||||
import Chunk from './components/knowledge-chunk';
|
||||
import File from './components/knowledge-file';
|
||||
import Search from './components/knowledge-search';
|
||||
import Setting from './components/knowledge-setting';
|
||||
import styles from './index.less';
|
||||
|
||||
const KnowledgeAdding = () => {
|
||||
const dispatch = useDispatch();
|
||||
const kAModel = useSelector((state: any) => state.kAModel);
|
||||
const { id, activeKey, doc_id } = kAModel;
|
||||
|
||||
interface kAProps {
|
||||
dispatch: Dispatch;
|
||||
kAModel: kAModelState;
|
||||
}
|
||||
const Index: React.FC<kAProps> = ({ kAModel, dispatch }) => {
|
||||
const [collapsed, setCollapsed] = useState(false);
|
||||
const { id, activeKey, doc_id } = kAModel
|
||||
const [windowWidth, setWindowWidth] = useState(getWidth());
|
||||
let navigate = useNavigate();
|
||||
const location = useLocation();
|
||||
|
||||
// 标记一下
|
||||
console.log(doc_id, '>>>>>>>>>>>>>doc_id')
|
||||
console.log(doc_id, '>>>>>>>>>>>>>doc_id');
|
||||
useEffect(() => {
|
||||
const widthSize = () => {
|
||||
const width = getWidth()
|
||||
console.log(width)
|
||||
const width = getWidth();
|
||||
console.log(width);
|
||||
|
||||
setWindowWidth(width);
|
||||
};
|
||||
window.addEventListener("resize", widthSize);
|
||||
window.addEventListener('resize', widthSize);
|
||||
return () => {
|
||||
window.removeEventListener("resize", widthSize);
|
||||
window.removeEventListener('resize', widthSize);
|
||||
};
|
||||
}, []);
|
||||
useEffect(() => {
|
||||
console.log(location)
|
||||
const search = location.search.slice(1)
|
||||
const map = search.split('&').reduce((obj, cur) => {
|
||||
const [key, value] = cur.split('=')
|
||||
obj[key] = value
|
||||
return obj
|
||||
}, {})
|
||||
const search: string = location.search.slice(1);
|
||||
const map = search.split('&').reduce<Record<string, string>>((obj, cur) => {
|
||||
const [key, value] = cur.split('=');
|
||||
obj[key] = value;
|
||||
return obj;
|
||||
}, {});
|
||||
|
||||
dispatch({
|
||||
type: 'kAModel/updateState',
|
||||
payload: {
|
||||
doc_id: undefined,
|
||||
...map,
|
||||
|
||||
}
|
||||
},
|
||||
});
|
||||
}, [location])
|
||||
}, [location]);
|
||||
|
||||
useEffect(() => {
|
||||
if (windowWidth.width > 957) {
|
||||
setCollapsed(false)
|
||||
setCollapsed(false);
|
||||
} else {
|
||||
setCollapsed(true)
|
||||
setCollapsed(true);
|
||||
}
|
||||
}, [windowWidth.width])
|
||||
}, [windowWidth.width]);
|
||||
|
||||
type MenuItem = Required<MenuProps>['items'][number];
|
||||
|
||||
function getItem(
|
||||
@ -73,7 +68,6 @@ const Index: React.FC<kAProps> = ({ kAModel, dispatch }) => {
|
||||
disabled?: boolean,
|
||||
children?: MenuItem[],
|
||||
type?: 'group',
|
||||
|
||||
): MenuItem {
|
||||
return {
|
||||
key,
|
||||
@ -81,20 +75,22 @@ const Index: React.FC<kAProps> = ({ kAModel, dispatch }) => {
|
||||
children,
|
||||
label,
|
||||
type,
|
||||
disabled
|
||||
disabled,
|
||||
} as MenuItem;
|
||||
}
|
||||
const items: MenuItem[] = useMemo(() => {
|
||||
const disabled = !id
|
||||
const disabled = !id;
|
||||
return [
|
||||
getItem('配置', 'setting', <ToolOutlined />),
|
||||
getItem('知识库', 'file', <BarsOutlined />, disabled),
|
||||
getItem('搜索测试', 'search', <SearchOutlined />, disabled),
|
||||
]
|
||||
];
|
||||
}, [id]);
|
||||
|
||||
const handleSelect: MenuProps['onSelect'] = (e) => {
|
||||
navigate(`/knowledge/add/setting?activeKey=${e.key}&id=${id}`);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className={styles.container}>
|
||||
@ -102,7 +98,9 @@ const Index: React.FC<kAProps> = ({ kAModel, dispatch }) => {
|
||||
<Menu
|
||||
selectedKeys={[activeKey]}
|
||||
mode="inline"
|
||||
className={windowWidth.width > 957 ? styles.defaultWidth : styles.minWidth}
|
||||
className={
|
||||
windowWidth.width > 957 ? styles.defaultWidth : styles.minWidth
|
||||
}
|
||||
inlineCollapsed={collapsed}
|
||||
items={items}
|
||||
onSelect={handleSelect}
|
||||
@ -113,11 +111,10 @@ const Index: React.FC<kAProps> = ({ kAModel, dispatch }) => {
|
||||
{activeKey === 'setting' && <Setting kb_id={id} />}
|
||||
{activeKey === 'search' && <Search kb_id={id} />}
|
||||
{activeKey === 'file' && !!doc_id && <Chunk doc_id={doc_id} />}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default connect(({ kAModel, loading }) => ({ kAModel, loading }))(Index);
|
||||
export default KnowledgeAdding;
|
||||
|
@ -1,6 +1,4 @@
|
||||
import { Effect, Reducer, Subscription } from 'umi'
|
||||
import { message } from 'antd';
|
||||
import kbService from '@/services/kbService';
|
||||
import { DvaModel } from 'umi';
|
||||
export interface kAModelState {
|
||||
isShowPSwModal: boolean;
|
||||
isShowTntModal: boolean;
|
||||
@ -8,20 +6,10 @@ export interface kAModelState {
|
||||
tenantIfo: any;
|
||||
activeKey: string;
|
||||
id: string;
|
||||
doc_id: string
|
||||
doc_id: string;
|
||||
}
|
||||
export interface kAModelType {
|
||||
namespace: 'kAModel';
|
||||
state: kAModelState;
|
||||
effects: {
|
||||
|
||||
};
|
||||
reducers: {
|
||||
updateState: Reducer<kAModelState>;
|
||||
};
|
||||
subscriptions: { setup: Subscription };
|
||||
}
|
||||
const Model: kAModelType = {
|
||||
const model: DvaModel<kAModelState> = {
|
||||
namespace: 'kAModel',
|
||||
state: {
|
||||
isShowPSwModal: false,
|
||||
@ -30,25 +18,21 @@ const Model: kAModelType = {
|
||||
tenantIfo: {},
|
||||
activeKey: 'setting',
|
||||
id: '',
|
||||
doc_id: ''
|
||||
|
||||
},
|
||||
subscriptions: {
|
||||
setup({ dispatch, history }) {
|
||||
history.listen(location => {
|
||||
});
|
||||
}
|
||||
},
|
||||
effects: {
|
||||
|
||||
doc_id: '',
|
||||
},
|
||||
reducers: {
|
||||
updateState(state, { payload }) {
|
||||
return {
|
||||
...state,
|
||||
...payload
|
||||
...payload,
|
||||
};
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
subscriptions: {
|
||||
setup({ dispatch, history }) {
|
||||
history.listen((location) => {});
|
||||
},
|
||||
},
|
||||
effects: {},
|
||||
};
|
||||
export default Model;
|
||||
export default model;
|
||||
|
@ -1,15 +1,8 @@
|
||||
import React from 'react';
|
||||
import { connect, Dispatch } from 'umi';
|
||||
import type { chatModelState } from './model'
|
||||
import { useSelector } from 'umi';
|
||||
|
||||
interface chatProps {
|
||||
chatModel: chatModelState;
|
||||
dispatch: Dispatch
|
||||
}
|
||||
|
||||
const View: React.FC<chatProps> = ({ chatModel, dispatch }) => {
|
||||
const { name } = chatModel;
|
||||
const Chat = () => {
|
||||
const { name } = useSelector((state: any) => state.chatModel);
|
||||
return <div>chat:{name} </div>;
|
||||
};
|
||||
|
||||
export default connect(({ chatModel, loading }) => ({ chatModel, loading }))(View);
|
||||
export default Chat;
|
||||
|
@ -1,30 +1,14 @@
|
||||
import { Effect, Reducer, Subscription } from 'umi';
|
||||
import { DvaModel } from 'umi';
|
||||
|
||||
export interface chatModelState {
|
||||
export interface ChatModelState {
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface chatModelType {
|
||||
namespace: 'chatModel';
|
||||
state: chatModelState;
|
||||
effects: {
|
||||
query: Effect;
|
||||
};
|
||||
reducers: {
|
||||
save: Reducer<chatModelState>;
|
||||
};
|
||||
subscriptions: { setup: Subscription };
|
||||
}
|
||||
|
||||
const Model: chatModelType = {
|
||||
const model: DvaModel<ChatModelState> = {
|
||||
namespace: 'chatModel',
|
||||
state: {
|
||||
name: 'kate',
|
||||
},
|
||||
|
||||
effects: {
|
||||
*query({ payload }, { call, put }) { },
|
||||
},
|
||||
reducers: {
|
||||
save(state, action) {
|
||||
return {
|
||||
@ -36,11 +20,13 @@ const Model: chatModelType = {
|
||||
subscriptions: {
|
||||
setup({ dispatch, history }) {
|
||||
return history.listen((query) => {
|
||||
console.log(query)
|
||||
|
||||
console.log(query);
|
||||
});
|
||||
},
|
||||
},
|
||||
effects: {
|
||||
*query({ payload }, { call, put }) {},
|
||||
},
|
||||
};
|
||||
|
||||
export default Model;
|
||||
export default model;
|
||||
|
@ -1,40 +1,39 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { UploadOutlined } from '@ant-design/icons';
|
||||
import { Button, Upload } from 'antd';
|
||||
import type { UploadFile } from 'antd/es/upload/interface';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
|
||||
|
||||
const App: React.FC = () => {
|
||||
const [fileList, setFileList] = useState([{
|
||||
const File: React.FC = () => {
|
||||
const [fileList, setFileList] = useState([
|
||||
{
|
||||
uid: '0',
|
||||
name: 'xxx.png',
|
||||
status: 'uploading',
|
||||
percent: 10,
|
||||
}])
|
||||
},
|
||||
]);
|
||||
const obj = {
|
||||
uid: '-1',
|
||||
name: 'yyy.png',
|
||||
status: 'done',
|
||||
url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
|
||||
thumbUrl: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
|
||||
}
|
||||
thumbUrl:
|
||||
'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
|
||||
};
|
||||
useEffect(() => {
|
||||
const timer = setInterval(() => {
|
||||
setFileList((fileList: any) => {
|
||||
const percent = fileList[0]?.percent
|
||||
const percent = fileList[0]?.percent;
|
||||
if (percent + 10 >= 100) {
|
||||
clearInterval(timer)
|
||||
return [obj]
|
||||
clearInterval(timer);
|
||||
return [obj];
|
||||
}
|
||||
const list = [{ ...fileList[0], percent: percent + 10 }]
|
||||
console.log(list)
|
||||
return list
|
||||
|
||||
})
|
||||
}, 300)
|
||||
}, [])
|
||||
const list = [{ ...fileList[0], percent: percent + 10 }];
|
||||
console.log(list);
|
||||
return list;
|
||||
});
|
||||
}, 300);
|
||||
}, []);
|
||||
return (
|
||||
|
||||
<>
|
||||
<Upload
|
||||
action="https://run.mocky.io/v3/435e224c-44fb-4773-9faf-380c5e6a2188"
|
||||
@ -45,7 +44,7 @@ const App: React.FC = () => {
|
||||
<Button icon={<UploadOutlined />}>Upload</Button>
|
||||
</Upload>
|
||||
</>
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
export default App;
|
||||
export default File;
|
||||
|
@ -5,21 +5,22 @@ import {
|
||||
PlusOutlined,
|
||||
} from '@ant-design/icons';
|
||||
import { Card, Col, FloatButton, Popconfirm, Row } from 'antd';
|
||||
import React, { useEffect } from 'react';
|
||||
import { Dispatch, connect, useNavigate } from 'umi';
|
||||
import { useCallback, useEffect } from 'react';
|
||||
import { useDispatch, useNavigate, useSelector } from 'umi';
|
||||
import styles from './index.less';
|
||||
import type { knowledgeModelState } from './model';
|
||||
interface KnowledgeProps {
|
||||
dispatch: Dispatch;
|
||||
knowledgeModel: knowledgeModelState;
|
||||
}
|
||||
const Index: React.FC<KnowledgeProps> = ({ knowledgeModel, dispatch }) => {
|
||||
const navigate = useNavigate();
|
||||
// const [datas, setDatas] = useState(data)
|
||||
const { data = [] } = knowledgeModel;
|
||||
console.log(knowledgeModel);
|
||||
|
||||
// const x = useSelector((state) => state.knowledgeModel);
|
||||
const Knowledge = () => {
|
||||
const dispatch = useDispatch();
|
||||
const knowledgeModel = useSelector((state: any) => state.knowledgeModel);
|
||||
const navigate = useNavigate();
|
||||
const { data = [] } = knowledgeModel;
|
||||
|
||||
const fetchList = useCallback(() => {
|
||||
dispatch({
|
||||
type: 'knowledgeModel/getList',
|
||||
payload: {},
|
||||
});
|
||||
}, []);
|
||||
|
||||
const confirm = (id: string) => {
|
||||
dispatch({
|
||||
@ -27,12 +28,6 @@ const Index: React.FC<KnowledgeProps> = ({ knowledgeModel, dispatch }) => {
|
||||
payload: {
|
||||
kb_id: id,
|
||||
},
|
||||
callback: () => {
|
||||
dispatch({
|
||||
type: 'knowledgeModel/getList',
|
||||
payload: {},
|
||||
});
|
||||
},
|
||||
});
|
||||
};
|
||||
const handleAddKnowledge = () => {
|
||||
@ -42,11 +37,8 @@ const Index: React.FC<KnowledgeProps> = ({ knowledgeModel, dispatch }) => {
|
||||
navigate(`add/setting?activeKey=file&id=${id}`);
|
||||
};
|
||||
useEffect(() => {
|
||||
dispatch({
|
||||
type: 'knowledgeModel/getList',
|
||||
payload: {},
|
||||
});
|
||||
}, []);
|
||||
fetchList();
|
||||
}, [fetchList]);
|
||||
return (
|
||||
<>
|
||||
<div className={styles.knowledge}>
|
||||
@ -125,7 +117,4 @@ const Index: React.FC<KnowledgeProps> = ({ knowledgeModel, dispatch }) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default connect(({ knowledgeModel, loading }) => ({
|
||||
knowledgeModel,
|
||||
loading,
|
||||
}))(Index);
|
||||
export default Knowledge;
|
||||
|
@ -1,58 +1,38 @@
|
||||
import kbService from '@/services/kbService';
|
||||
import { Effect, Reducer } from 'umi';
|
||||
import { DvaModel } from 'umi';
|
||||
|
||||
export interface knowledgeModelState {
|
||||
loading: boolean;
|
||||
export interface KnowledgeModelState {
|
||||
data: any[];
|
||||
}
|
||||
export interface knowledgegModelType {
|
||||
namespace: 'knowledgeModel';
|
||||
state: knowledgeModelState;
|
||||
effects: {
|
||||
rmKb: Effect;
|
||||
getList: Effect;
|
||||
};
|
||||
reducers: {
|
||||
updateState: Reducer<knowledgeModelState>;
|
||||
};
|
||||
// subscriptions: { setup: Subscription };
|
||||
}
|
||||
const Model: knowledgegModelType = {
|
||||
|
||||
const model: DvaModel<KnowledgeModelState> = {
|
||||
namespace: 'knowledgeModel',
|
||||
state: {
|
||||
loading: false,
|
||||
data: [],
|
||||
},
|
||||
// subscriptions: {
|
||||
// setup({ dispatch, history }) {
|
||||
// history.listen((location) => {
|
||||
// console.log(location);
|
||||
// });
|
||||
// },
|
||||
// },
|
||||
reducers: {
|
||||
updateState(state, { payload }) {
|
||||
return {
|
||||
...state,
|
||||
...payload,
|
||||
};
|
||||
},
|
||||
},
|
||||
effects: {
|
||||
*rmKb({ payload = {}, callback }, { call, put }) {
|
||||
const { data, response } = yield call(kbService.rmKb, payload);
|
||||
const { retcode, data: res, retmsg } = data;
|
||||
const { data } = yield call(kbService.rmKb, payload);
|
||||
const { retcode } = data;
|
||||
if (retcode === 0) {
|
||||
callback && callback();
|
||||
yield put({
|
||||
type: 'getList',
|
||||
payload: {},
|
||||
});
|
||||
}
|
||||
},
|
||||
*getList({ payload = {} }, { call, put }) {
|
||||
yield put({
|
||||
type: 'updateState',
|
||||
payload: {
|
||||
loading: true,
|
||||
},
|
||||
});
|
||||
const { data, response } = yield call(kbService.getList, payload);
|
||||
const { data } = yield call(kbService.getList, payload);
|
||||
const { retcode, data: res, retmsg } = data;
|
||||
yield put({
|
||||
type: 'updateState',
|
||||
payload: {
|
||||
loading: false,
|
||||
},
|
||||
});
|
||||
|
||||
if (retcode === 0) {
|
||||
yield put({
|
||||
type: 'updateState',
|
||||
@ -63,13 +43,5 @@ const Model: knowledgegModelType = {
|
||||
}
|
||||
},
|
||||
},
|
||||
reducers: {
|
||||
updateState(state, { payload }) {
|
||||
return {
|
||||
...state,
|
||||
...payload,
|
||||
};
|
||||
},
|
||||
},
|
||||
};
|
||||
export default Model;
|
||||
export default model;
|
||||
|
@ -1,15 +1,20 @@
|
||||
import { rsaPsw } from '@/utils';
|
||||
import { Button, Checkbox, Form, Input } from 'antd';
|
||||
import { FC, useEffect, useState } from 'react';
|
||||
import { Dispatch, Icon, connect, useNavigate } from 'umi';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { Icon, useDispatch, useNavigate, useSelector } from 'umi';
|
||||
import styles from './index.less';
|
||||
|
||||
interface LoginProps {
|
||||
dispatch: Dispatch;
|
||||
}
|
||||
const View: FC<LoginProps> = ({ dispatch }) => {
|
||||
let navigate = useNavigate();
|
||||
const Login = () => {
|
||||
const [title, setTitle] = useState('login');
|
||||
let navigate = useNavigate();
|
||||
const dispatch = useDispatch();
|
||||
const effectsLoading: any = useSelector<any>( // TODO: Type needs to be improved
|
||||
(state) => state.loading.effects,
|
||||
);
|
||||
|
||||
const signLoading =
|
||||
effectsLoading['loginModel/login'] || effectsLoading['loginModel/register'];
|
||||
|
||||
const changeTitle = () => {
|
||||
setTitle((title) => (title === 'login' ? 'register' : 'login'));
|
||||
};
|
||||
@ -26,27 +31,29 @@ const View: FC<LoginProps> = ({ dispatch }) => {
|
||||
|
||||
var rsaPassWord = rsaPsw(params.password);
|
||||
if (title === 'login') {
|
||||
const ret = await dispatch({
|
||||
const retcode = await dispatch<any>({
|
||||
type: 'loginModel/login',
|
||||
payload: {
|
||||
email: params.email,
|
||||
password: rsaPassWord,
|
||||
},
|
||||
});
|
||||
console.info(ret);
|
||||
if (retcode === 0) {
|
||||
navigate('/knowledge');
|
||||
}
|
||||
} else {
|
||||
dispatch({
|
||||
// TODO: Type needs to be improved
|
||||
const retcode = await dispatch<any>({
|
||||
type: 'loginModel/register',
|
||||
payload: {
|
||||
nickname: params.nickname,
|
||||
email: params.email,
|
||||
password: rsaPassWord,
|
||||
},
|
||||
callback() {
|
||||
setTitle('login');
|
||||
},
|
||||
});
|
||||
if (retcode === 0) {
|
||||
setTitle('login');
|
||||
}
|
||||
}
|
||||
} catch (errorInfo) {
|
||||
console.log('Failed:', errorInfo);
|
||||
@ -106,7 +113,7 @@ const View: FC<LoginProps> = ({ dispatch }) => {
|
||||
label="Password"
|
||||
rules={[{ required: true, message: 'Please input value' }]}
|
||||
>
|
||||
<Input size="large" placeholder="Please input value" />
|
||||
<Input.Password size="large" placeholder="Please input value" />
|
||||
</Form.Item>
|
||||
{title === 'login' && (
|
||||
<Form.Item name="remember" valuePropName="checked">
|
||||
@ -132,7 +139,13 @@ const View: FC<LoginProps> = ({ dispatch }) => {
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<Button type="primary" block size="large" onClick={onCheck}>
|
||||
<Button
|
||||
type="primary"
|
||||
block
|
||||
size="large"
|
||||
onClick={onCheck}
|
||||
loading={signLoading}
|
||||
>
|
||||
{title === 'login' ? 'Sign in' : 'Continue'}
|
||||
</Button>
|
||||
{title === 'login' && (
|
||||
@ -175,6 +188,4 @@ const View: FC<LoginProps> = ({ dispatch }) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default connect(({ loginModel, loading }) => ({ loginModel, loading }))(
|
||||
View,
|
||||
);
|
||||
export default Login;
|
||||
|
@ -2,32 +2,29 @@ import { Authorization } from '@/constants/authorization';
|
||||
import userService from '@/services/userService';
|
||||
import authorizationUtil from '@/utils/authorizationUtil';
|
||||
import { message } from 'antd';
|
||||
import { Effect, Reducer, Subscription } from 'umi';
|
||||
import { DvaModel } from 'umi';
|
||||
|
||||
export interface loginModelState {
|
||||
export interface LoginModelState {
|
||||
list: any[];
|
||||
info: any;
|
||||
visible: boolean;
|
||||
}
|
||||
export interface logingModelType {
|
||||
namespace: 'loginModel';
|
||||
state: loginModelState;
|
||||
effects: {
|
||||
login: Effect;
|
||||
register: Effect;
|
||||
};
|
||||
reducers: {
|
||||
updateState: Reducer<loginModelState>;
|
||||
};
|
||||
subscriptions: { setup: Subscription };
|
||||
}
|
||||
const Model: logingModelType = {
|
||||
|
||||
const model: DvaModel<LoginModelState> = {
|
||||
namespace: 'loginModel',
|
||||
state: {
|
||||
list: [],
|
||||
info: {},
|
||||
visible: false,
|
||||
},
|
||||
reducers: {
|
||||
updateState(state, { payload }) {
|
||||
return {
|
||||
...state,
|
||||
...payload,
|
||||
};
|
||||
},
|
||||
},
|
||||
subscriptions: {
|
||||
setup({ dispatch, history }) {
|
||||
history.listen((location) => {});
|
||||
@ -53,29 +50,18 @@ const Model: logingModelType = {
|
||||
userInfo: JSON.stringify(userInfo),
|
||||
Token: token,
|
||||
});
|
||||
// setTimeout(() => {
|
||||
// window.location.href = '/file';
|
||||
// }, 300);
|
||||
}
|
||||
return data;
|
||||
return retcode;
|
||||
},
|
||||
*register({ payload = {}, callback }, { call, put }) {
|
||||
*register({ payload = {} }, { call, put }) {
|
||||
const { data, response } = yield call(userService.register, payload);
|
||||
console.log();
|
||||
const { retcode, data: res, retmsg } = data;
|
||||
if (retcode === 0) {
|
||||
message.success('注册成功!');
|
||||
callback && callback();
|
||||
}
|
||||
},
|
||||
},
|
||||
reducers: {
|
||||
updateState(state, { payload }) {
|
||||
return {
|
||||
...state,
|
||||
...payload,
|
||||
};
|
||||
return retcode;
|
||||
},
|
||||
},
|
||||
};
|
||||
export default Model;
|
||||
export default model;
|
||||
|
@ -1,9 +1,9 @@
|
||||
import userService from '@/services/userService';
|
||||
import authorizationUtil from '@/utils/authorizationUtil';
|
||||
import { message } from 'antd';
|
||||
import { Effect, Reducer, Subscription } from 'umi';
|
||||
import { DvaModel } from 'umi';
|
||||
|
||||
export interface settingModelState {
|
||||
export interface SettingModelState {
|
||||
isShowPSwModal: boolean;
|
||||
isShowTntModal: boolean;
|
||||
isShowSAKModal: boolean;
|
||||
@ -16,25 +16,7 @@ export interface settingModelState {
|
||||
factoriesList: any[];
|
||||
}
|
||||
|
||||
export interface settingModelType {
|
||||
namespace: 'settingModel';
|
||||
state: settingModelState;
|
||||
effects: {
|
||||
setting: Effect;
|
||||
getUserInfo: Effect;
|
||||
getTenantInfo: Effect;
|
||||
set_tenant_info: Effect;
|
||||
factories_list: Effect;
|
||||
llm_list: Effect;
|
||||
my_llm: Effect;
|
||||
set_api_key: Effect;
|
||||
};
|
||||
reducers: {
|
||||
updateState: Reducer<settingModelState>;
|
||||
};
|
||||
subscriptions: { setup: Subscription };
|
||||
}
|
||||
const Model: settingModelType = {
|
||||
const model: DvaModel<SettingModelState> = {
|
||||
namespace: 'settingModel',
|
||||
state: {
|
||||
isShowPSwModal: false,
|
||||
@ -48,6 +30,14 @@ const Model: settingModelType = {
|
||||
myLlm: [],
|
||||
factoriesList: [],
|
||||
},
|
||||
reducers: {
|
||||
updateState(state, { payload }) {
|
||||
return {
|
||||
...state,
|
||||
...payload,
|
||||
};
|
||||
},
|
||||
},
|
||||
subscriptions: {
|
||||
setup({ dispatch, history }) {
|
||||
history.listen((location) => {});
|
||||
@ -176,13 +166,5 @@ const Model: settingModelType = {
|
||||
}
|
||||
},
|
||||
},
|
||||
reducers: {
|
||||
updateState(state, { payload }) {
|
||||
return {
|
||||
...state,
|
||||
...payload,
|
||||
};
|
||||
},
|
||||
},
|
||||
};
|
||||
export default Model;
|
||||
export default model;
|
||||
|
@ -19,101 +19,83 @@ const {
|
||||
get_chunk,
|
||||
switch_chunk,
|
||||
rm_chunk,
|
||||
retrieval_test } = api;
|
||||
interface kbService {
|
||||
createKb: () => void;
|
||||
updateKb: () => void;
|
||||
rmKb: () => void;
|
||||
get_kb_detail: () => void;
|
||||
getList: () => void;
|
||||
get_document_list: () => void;
|
||||
document_change_status: () => void;
|
||||
document_rm: () => void;
|
||||
document_create: () => void;
|
||||
document_change_parser: () => void;
|
||||
chunk_list: () => void;
|
||||
create_chunk: () => void;
|
||||
set_chunk: () => void;
|
||||
get_chunk: () => void;
|
||||
switch_chunk: () => void;
|
||||
rm_chunk: () => void;
|
||||
retrieval_test: () => void;
|
||||
}
|
||||
const kbService: kbService = registerServer(
|
||||
{
|
||||
retrieval_test,
|
||||
} = api;
|
||||
|
||||
const methods = {
|
||||
// 知识库管理
|
||||
createKb: {
|
||||
url: create_kb,
|
||||
method: 'post'
|
||||
method: 'post',
|
||||
},
|
||||
updateKb: {
|
||||
url: update_kb,
|
||||
method: 'post'
|
||||
method: 'post',
|
||||
},
|
||||
rmKb: {
|
||||
url: rm_kb,
|
||||
method: 'post'
|
||||
method: 'post',
|
||||
},
|
||||
get_kb_detail: {
|
||||
url: get_kb_detail,
|
||||
method: 'get'
|
||||
method: 'get',
|
||||
},
|
||||
getList: {
|
||||
url: kb_list,
|
||||
method: 'get'
|
||||
method: 'get',
|
||||
},
|
||||
// 文件管理
|
||||
get_document_list: {
|
||||
url: get_document_list,
|
||||
method: 'get'
|
||||
method: 'get',
|
||||
},
|
||||
document_change_status: {
|
||||
url: document_change_status,
|
||||
method: 'post'
|
||||
method: 'post',
|
||||
},
|
||||
document_rm: {
|
||||
url: document_rm,
|
||||
method: 'post'
|
||||
method: 'post',
|
||||
},
|
||||
document_create: {
|
||||
url: document_create,
|
||||
method: 'post'
|
||||
method: 'post',
|
||||
},
|
||||
document_change_parser: {
|
||||
url: document_change_parser,
|
||||
method: 'post'
|
||||
method: 'post',
|
||||
},
|
||||
// chunk管理
|
||||
chunk_list: {
|
||||
url: chunk_list,
|
||||
method: 'post'
|
||||
method: 'post',
|
||||
},
|
||||
create_chunk: {
|
||||
url: create_chunk,
|
||||
method: 'post'
|
||||
method: 'post',
|
||||
},
|
||||
set_chunk: {
|
||||
url: set_chunk,
|
||||
method: 'post'
|
||||
method: 'post',
|
||||
},
|
||||
get_chunk: {
|
||||
url: get_chunk,
|
||||
method: 'get'
|
||||
method: 'get',
|
||||
},
|
||||
switch_chunk: {
|
||||
url: switch_chunk,
|
||||
method: 'post'
|
||||
method: 'post',
|
||||
},
|
||||
rm_chunk: {
|
||||
url: rm_chunk,
|
||||
method: 'post'
|
||||
method: 'post',
|
||||
},
|
||||
retrieval_test: {
|
||||
url: retrieval_test,
|
||||
method: 'post'
|
||||
method: 'post',
|
||||
},
|
||||
},
|
||||
request
|
||||
);
|
||||
};
|
||||
|
||||
const kbService = registerServer<keyof typeof methods>(methods, request);
|
||||
|
||||
export default kbService;
|
||||
|
@ -3,55 +3,61 @@ import registerServer from '@/utils/registerServer';
|
||||
import request from '@/utils/request';
|
||||
|
||||
const {
|
||||
login, register, setting, user_info, tenant_info, factories_list, llm_list, my_llm, set_api_key, set_tenant_info } = api;
|
||||
interface userServiceType {
|
||||
login: (params: any) => void
|
||||
}
|
||||
const userService = registerServer(
|
||||
{
|
||||
login,
|
||||
register,
|
||||
setting,
|
||||
user_info,
|
||||
tenant_info,
|
||||
factories_list,
|
||||
llm_list,
|
||||
my_llm,
|
||||
set_api_key,
|
||||
set_tenant_info,
|
||||
} = api;
|
||||
|
||||
const methods = {
|
||||
login: {
|
||||
url: login,
|
||||
method: 'post',
|
||||
|
||||
},
|
||||
register: {
|
||||
url: register,
|
||||
method: 'post'
|
||||
method: 'post',
|
||||
},
|
||||
setting: {
|
||||
url: setting,
|
||||
method: 'post'
|
||||
method: 'post',
|
||||
},
|
||||
user_info: {
|
||||
url: user_info,
|
||||
method: 'get'
|
||||
method: 'get',
|
||||
},
|
||||
get_tenant_info: {
|
||||
url: tenant_info,
|
||||
method: 'get'
|
||||
method: 'get',
|
||||
},
|
||||
set_tenant_info: {
|
||||
url: set_tenant_info,
|
||||
method: 'post'
|
||||
method: 'post',
|
||||
},
|
||||
factories_list: {
|
||||
url: factories_list,
|
||||
method: 'get'
|
||||
method: 'get',
|
||||
},
|
||||
llm_list: {
|
||||
url: llm_list,
|
||||
method: 'get'
|
||||
method: 'get',
|
||||
},
|
||||
my_llm: {
|
||||
url: my_llm,
|
||||
method: 'get'
|
||||
method: 'get',
|
||||
},
|
||||
set_api_key: {
|
||||
url: set_api_key,
|
||||
method: 'post'
|
||||
method: 'post',
|
||||
},
|
||||
},
|
||||
request
|
||||
);
|
||||
} as const;
|
||||
|
||||
const userService = registerServer<keyof typeof methods>(methods, request);
|
||||
|
||||
export default userService;
|
||||
|
@ -1,17 +1,24 @@
|
||||
const registerServer = (opt: any, request: any): any => {
|
||||
let server = {};
|
||||
import { RequestMethod } from 'umi-request';
|
||||
|
||||
type Service<T extends string> = Record<T, (params: any) => any>;
|
||||
|
||||
const registerServer = <T extends string>(
|
||||
opt: Record<T, { url: string; method: string }>,
|
||||
request: RequestMethod,
|
||||
) => {
|
||||
const server: Service<T> = {} as Service<T>;
|
||||
for (let key in opt) {
|
||||
server[key] = (params: any) => {
|
||||
server[key] = (params) => {
|
||||
if (opt[key].method === 'post' || opt[key].method === 'POST') {
|
||||
return request(opt[key].url, {
|
||||
method: opt[key].method,
|
||||
data: params
|
||||
data: params,
|
||||
});
|
||||
}
|
||||
|
||||
if (opt[key].method === 'get' || opt[key].method === 'GET') {
|
||||
return request.get(opt[key].url, {
|
||||
params
|
||||
params,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { message, notification } from 'antd';
|
||||
import { extend } from 'umi-request';
|
||||
import { RequestMethod, extend } from 'umi-request';
|
||||
|
||||
import { Authorization } from '@/constants/authorization';
|
||||
import api from '@/utils/api';
|
||||
@ -9,7 +9,7 @@ const { login } = api;
|
||||
|
||||
const ABORT_REQUEST_ERR_MESSAGE = 'The user aborted a request.'; // 手动中断请求。errorHandler 抛出的error message
|
||||
|
||||
const retcodeMessage = {
|
||||
const RetcodeMessage = {
|
||||
200: '服务器成功返回请求的数据。',
|
||||
201: '新建或修改数据成功。',
|
||||
202: '一个请求已经进入后台排队(异步任务)。',
|
||||
@ -26,7 +26,7 @@ const retcodeMessage = {
|
||||
503: '服务不可用,服务器暂时过载或维护。',
|
||||
504: '网关超时。',
|
||||
};
|
||||
type retcode =
|
||||
type ResultCode =
|
||||
| 200
|
||||
| 201
|
||||
| 202
|
||||
@ -45,7 +45,7 @@ type retcode =
|
||||
/**
|
||||
* 异常处理程序
|
||||
*/
|
||||
interface responseType {
|
||||
interface ResponseType {
|
||||
retcode: number;
|
||||
data: any;
|
||||
retmsg: string;
|
||||
@ -62,7 +62,7 @@ const errorHandler = (error: {
|
||||
} else {
|
||||
if (response && response.status) {
|
||||
const errorText =
|
||||
retcodeMessage[response.status as retcode] || response.statusText;
|
||||
RetcodeMessage[response.status as ResultCode] || response.statusText;
|
||||
const { status, url } = response;
|
||||
notification.error({
|
||||
message: `请求错误 ${status}: ${url}`,
|
||||
@ -81,7 +81,7 @@ const errorHandler = (error: {
|
||||
/**
|
||||
* 配置request请求时的默认参数
|
||||
*/
|
||||
const request = extend({
|
||||
const request: RequestMethod = extend({
|
||||
errorHandler, // 默认错误处理
|
||||
timeout: 3000000,
|
||||
getResponse: true,
|
||||
@ -108,7 +108,7 @@ request.interceptors.request.use((url: string, options: any) => {
|
||||
|
||||
request.interceptors.response.use(async (response: any, request) => {
|
||||
console.log(response, request);
|
||||
const data: responseType = await response.clone().json();
|
||||
const data: ResponseType = await response.clone().json();
|
||||
// response 拦截
|
||||
|
||||
if (data.retcode === 401 || data.retcode === 401) {
|
||||
|
9
web/src/utils/stroreUtil.ts
Normal file
9
web/src/utils/stroreUtil.ts
Normal file
@ -0,0 +1,9 @@
|
||||
export const getOneNamespaceEffectsLoading = (
|
||||
namespace: string,
|
||||
effects: Record<string, boolean>,
|
||||
effectNames: Array<string>,
|
||||
) => {
|
||||
return effectNames.some(
|
||||
(effectName) => effects[`${namespace}/${effectName}`],
|
||||
);
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user