balibabu
commited on
Commit
·
0cf2c67
1
Parent(s):
b7adc24
feat: add pages to ChunkMethodModal (#143)
Browse files- web/src/assets/svg/chunk-method/law-01.svg +0 -0
- web/src/assets/svg/chunk-method/law-02.svg +0 -0
- web/src/assets/svg/chunk-method/law-03.svg +0 -0
- web/src/assets/svg/chunk-method/law-04.svg +0 -0
- web/src/assets/svg/chunk-method/manual-01.svg +0 -0
- web/src/assets/svg/chunk-method/manual-02.svg +0 -0
- web/src/assets/svg/chunk-method/manual-03.svg +0 -0
- web/src/assets/svg/chunk-method/manual-04.svg +0 -0
- web/src/assets/svg/chunk-method/one-01.svg +0 -0
- web/src/assets/svg/chunk-method/one-02.svg +0 -0
- web/src/assets/svg/chunk-method/one-03.svg +0 -0
- web/src/assets/svg/chunk-method/one-04.svg +0 -0
- web/src/assets/svg/chunk-method/paper-01.svg +0 -0
- web/src/assets/svg/chunk-method/paper-02.svg +0 -0
- web/src/components/max-token-number.tsx +32 -0
- web/src/hooks/documentHooks.ts +7 -1
- web/src/interfaces/database/knowledge.ts +7 -0
- web/src/interfaces/request/document.ts +12 -0
- web/src/pages/add-knowledge/components/knowledge-file/chunk-method-modal.tsx +198 -20
- web/src/pages/add-knowledge/components/knowledge-file/hooks.ts +25 -3
- web/src/pages/add-knowledge/components/knowledge-file/index.less +4 -0
- web/src/pages/add-knowledge/components/knowledge-file/index.tsx +3 -1
- web/src/pages/add-knowledge/components/knowledge-file/model.ts +7 -30
- web/src/pages/add-knowledge/components/knowledge-setting/configuration.tsx +3 -41
- web/src/pages/add-knowledge/components/knowledge-setting/model.ts +0 -2
- web/src/pages/add-knowledge/components/knowledge-setting/utils.ts +14 -11
- web/src/pages/add-knowledge/model.ts +0 -2
- web/src/pages/setting/CPwModal.tsx +0 -78
- web/src/pages/setting/List.tsx +0 -146
- web/src/pages/setting/SAKModal.tsx +0 -66
- web/src/pages/setting/SSModal.tsx +0 -144
- web/src/pages/setting/TntModal.tsx +0 -65
- web/src/pages/setting/index.less +0 -49
- web/src/pages/setting/index.tsx +0 -98
- web/src/pages/{setting → user-setting}/model.ts +151 -151
- web/src/routes.ts +0 -4
web/src/assets/svg/chunk-method/law-01.svg
CHANGED
|
|
web/src/assets/svg/chunk-method/law-02.svg
CHANGED
|
|
web/src/assets/svg/chunk-method/law-03.svg
DELETED
web/src/assets/svg/chunk-method/law-04.svg
DELETED
web/src/assets/svg/chunk-method/manual-01.svg
CHANGED
|
|
web/src/assets/svg/chunk-method/manual-02.svg
CHANGED
|
|
web/src/assets/svg/chunk-method/manual-03.svg
CHANGED
|
|
web/src/assets/svg/chunk-method/manual-04.svg
CHANGED
|
|
web/src/assets/svg/chunk-method/one-01.svg
ADDED
|
web/src/assets/svg/chunk-method/one-02.svg
ADDED
|
web/src/assets/svg/chunk-method/one-03.svg
ADDED
|
web/src/assets/svg/chunk-method/one-04.svg
ADDED
|
web/src/assets/svg/chunk-method/paper-01.svg
CHANGED
|
|
web/src/assets/svg/chunk-method/paper-02.svg
CHANGED
|
|
web/src/components/max-token-number.tsx
ADDED
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { Flex, Form, InputNumber, Slider } from 'antd';
|
2 |
+
|
3 |
+
const MaxTokenNumber = () => {
|
4 |
+
return (
|
5 |
+
<Form.Item
|
6 |
+
label="Token number"
|
7 |
+
tooltip="It determine the token number of a chunk approximately."
|
8 |
+
>
|
9 |
+
<Flex gap={20} align="center">
|
10 |
+
<Flex flex={1}>
|
11 |
+
<Form.Item
|
12 |
+
name={['parser_config', 'chunk_token_num']}
|
13 |
+
noStyle
|
14 |
+
initialValue={128}
|
15 |
+
rules={[{ required: true, message: 'Province is required' }]}
|
16 |
+
>
|
17 |
+
<Slider max={2048} style={{ width: '100%' }} />
|
18 |
+
</Form.Item>
|
19 |
+
</Flex>
|
20 |
+
<Form.Item
|
21 |
+
name={['parser_config', 'chunk_token_num']}
|
22 |
+
noStyle
|
23 |
+
rules={[{ required: true, message: 'Street is required' }]}
|
24 |
+
>
|
25 |
+
<InputNumber max={2048} min={0} />
|
26 |
+
</Form.Item>
|
27 |
+
</Flex>
|
28 |
+
</Form.Item>
|
29 |
+
);
|
30 |
+
};
|
31 |
+
|
32 |
+
export default MaxTokenNumber;
|
web/src/hooks/documentHooks.ts
CHANGED
@@ -1,4 +1,5 @@
|
|
1 |
import { IChunk, IKnowledgeFile } from '@/interfaces/database/knowledge';
|
|
|
2 |
import { api_host } from '@/utils/api';
|
3 |
import { buildChunkHighlights } from '@/utils/documentUtils';
|
4 |
import { useCallback, useMemo } from 'react';
|
@@ -117,7 +118,11 @@ export const useSetDocumentParser = () => {
|
|
117 |
const { knowledgeId } = useGetKnowledgeSearchParams();
|
118 |
|
119 |
const setDocumentParser = useCallback(
|
120 |
-
(
|
|
|
|
|
|
|
|
|
121 |
try {
|
122 |
return dispatch<any>({
|
123 |
type: 'kFModel/document_change_parser',
|
@@ -125,6 +130,7 @@ export const useSetDocumentParser = () => {
|
|
125 |
parser_id: parserId,
|
126 |
doc_id: documentId,
|
127 |
kb_id: knowledgeId,
|
|
|
128 |
},
|
129 |
});
|
130 |
} catch (errorInfo) {
|
|
|
1 |
import { IChunk, IKnowledgeFile } from '@/interfaces/database/knowledge';
|
2 |
+
import { IChangeParserConfigRequestBody } from '@/interfaces/request/document';
|
3 |
import { api_host } from '@/utils/api';
|
4 |
import { buildChunkHighlights } from '@/utils/documentUtils';
|
5 |
import { useCallback, useMemo } from 'react';
|
|
|
118 |
const { knowledgeId } = useGetKnowledgeSearchParams();
|
119 |
|
120 |
const setDocumentParser = useCallback(
|
121 |
+
(
|
122 |
+
parserId: string,
|
123 |
+
documentId: string,
|
124 |
+
parserConfig: IChangeParserConfigRequestBody,
|
125 |
+
) => {
|
126 |
try {
|
127 |
return dispatch<any>({
|
128 |
type: 'kFModel/document_change_parser',
|
|
|
130 |
parser_id: parserId,
|
131 |
doc_id: documentId,
|
132 |
kb_id: knowledgeId,
|
133 |
+
parser_config: parserConfig,
|
134 |
},
|
135 |
});
|
136 |
} catch (errorInfo) {
|
web/src/interfaces/database/knowledge.ts
CHANGED
@@ -28,6 +28,12 @@ export interface Parserconfig {
|
|
28 |
to_page: number;
|
29 |
}
|
30 |
|
|
|
|
|
|
|
|
|
|
|
|
|
31 |
export interface IKnowledgeFile {
|
32 |
chunk_num: number;
|
33 |
create_date: string;
|
@@ -51,6 +57,7 @@ export interface IKnowledgeFile {
|
|
51 |
type: string;
|
52 |
update_date: string;
|
53 |
update_time: number;
|
|
|
54 |
}
|
55 |
|
56 |
export interface ITenantInfo {
|
|
|
28 |
to_page: number;
|
29 |
}
|
30 |
|
31 |
+
export interface IKnowledgeFileParserConfig {
|
32 |
+
chunk_token_num: number;
|
33 |
+
layout_recognize: boolean;
|
34 |
+
pages: number[][];
|
35 |
+
task_page_size: number;
|
36 |
+
}
|
37 |
export interface IKnowledgeFile {
|
38 |
chunk_num: number;
|
39 |
create_date: string;
|
|
|
57 |
type: string;
|
58 |
update_date: string;
|
59 |
update_time: number;
|
60 |
+
parser_config: IKnowledgeFileParserConfig;
|
61 |
}
|
62 |
|
63 |
export interface ITenantInfo {
|
web/src/interfaces/request/document.ts
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
export interface IChangeParserConfigRequestBody {
|
2 |
+
pages: number[][];
|
3 |
+
chunk_token_num: number;
|
4 |
+
layout_recognize: boolean;
|
5 |
+
task_page_size: number;
|
6 |
+
}
|
7 |
+
|
8 |
+
export interface IChangeParserRequestBody {
|
9 |
+
parser_id: string;
|
10 |
+
doc_id: string;
|
11 |
+
parser_config: IChangeParserConfigRequestBody;
|
12 |
+
}
|
web/src/pages/add-knowledge/components/knowledge-file/chunk-method-modal.tsx
CHANGED
@@ -1,10 +1,23 @@
|
|
1 |
import { IModalManagerChildrenProps } from '@/components/modal-manager';
|
2 |
import {
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8 |
|
9 |
import styles from './index.less';
|
10 |
|
@@ -12,41 +25,74 @@ const { CheckableTag } = Tag;
|
|
12 |
|
13 |
interface IProps extends Omit<IModalManagerChildrenProps, 'showModal'> {
|
14 |
loading: boolean;
|
15 |
-
onOk: (
|
|
|
|
|
|
|
16 |
showModal?(): void;
|
17 |
-
|
|
|
|
|
18 |
}
|
19 |
|
|
|
|
|
20 |
const ChunkMethodModal: React.FC<IProps> = ({
|
21 |
-
|
22 |
onOk,
|
23 |
hideModal,
|
24 |
visible,
|
|
|
|
|
25 |
}) => {
|
26 |
-
const
|
27 |
-
|
28 |
-
|
29 |
-
useFetchTenantInfo();
|
30 |
-
|
31 |
-
useEffect(() => {
|
32 |
-
setSelectedTag(parser_id);
|
33 |
-
}, [parser_id]);
|
34 |
|
35 |
const handleOk = async () => {
|
36 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
37 |
};
|
38 |
|
39 |
-
const
|
40 |
-
|
41 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
42 |
};
|
43 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
44 |
return (
|
45 |
<Modal
|
46 |
title="Chunk Method"
|
47 |
open={visible}
|
48 |
onOk={handleOk}
|
49 |
onCancel={hideModal}
|
|
|
50 |
>
|
51 |
<Space size={[0, 8]} wrap>
|
52 |
<div className={styles.tags}>
|
@@ -63,6 +109,138 @@ const ChunkMethodModal: React.FC<IProps> = ({
|
|
63 |
})}
|
64 |
</div>
|
65 |
</Space>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
66 |
</Modal>
|
67 |
);
|
68 |
};
|
|
|
1 |
import { IModalManagerChildrenProps } from '@/components/modal-manager';
|
2 |
import {
|
3 |
+
Button,
|
4 |
+
Divider,
|
5 |
+
Form,
|
6 |
+
InputNumber,
|
7 |
+
Modal,
|
8 |
+
Space,
|
9 |
+
Switch,
|
10 |
+
Tag,
|
11 |
+
} from 'antd';
|
12 |
+
import React, { useEffect, useMemo } from 'react';
|
13 |
+
|
14 |
+
import MaxTokenNumber from '@/components/max-token-number';
|
15 |
+
import { IKnowledgeFileParserConfig } from '@/interfaces/database/knowledge';
|
16 |
+
import { IChangeParserConfigRequestBody } from '@/interfaces/request/document';
|
17 |
+
import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons';
|
18 |
+
import omit from 'lodash/omit';
|
19 |
+
import {} from 'module';
|
20 |
+
import { useFetchParserListOnMount } from './hooks';
|
21 |
|
22 |
import styles from './index.less';
|
23 |
|
|
|
25 |
|
26 |
interface IProps extends Omit<IModalManagerChildrenProps, 'showModal'> {
|
27 |
loading: boolean;
|
28 |
+
onOk: (
|
29 |
+
parserId: string,
|
30 |
+
parserConfig: IChangeParserConfigRequestBody,
|
31 |
+
) => void;
|
32 |
showModal?(): void;
|
33 |
+
parserId: string;
|
34 |
+
parserConfig: IKnowledgeFileParserConfig;
|
35 |
+
documentType: string;
|
36 |
}
|
37 |
|
38 |
+
const hidePagesChunkMethods = ['qa', 'table', 'picture', 'resume', 'one'];
|
39 |
+
|
40 |
const ChunkMethodModal: React.FC<IProps> = ({
|
41 |
+
parserId,
|
42 |
onOk,
|
43 |
hideModal,
|
44 |
visible,
|
45 |
+
documentType,
|
46 |
+
parserConfig,
|
47 |
}) => {
|
48 |
+
const { parserList, handleChange, selectedTag } =
|
49 |
+
useFetchParserListOnMount(parserId);
|
50 |
+
const [form] = Form.useForm();
|
|
|
|
|
|
|
|
|
|
|
51 |
|
52 |
const handleOk = async () => {
|
53 |
+
const values = await form.validateFields();
|
54 |
+
console.info(values);
|
55 |
+
const parser_config = {
|
56 |
+
...values.parser_config,
|
57 |
+
pages: values.pages?.map((x: any) => [x.from, x.to]) ?? [],
|
58 |
+
};
|
59 |
+
console.info(parser_config);
|
60 |
+
onOk(selectedTag, parser_config);
|
61 |
};
|
62 |
|
63 |
+
const showPages = useMemo(() => {
|
64 |
+
return (
|
65 |
+
documentType === 'pdf' &&
|
66 |
+
hidePagesChunkMethods.every((x) => x !== selectedTag)
|
67 |
+
);
|
68 |
+
}, [documentType, selectedTag]);
|
69 |
+
|
70 |
+
const showOne = useMemo(() => {
|
71 |
+
return showPages || selectedTag === 'one';
|
72 |
+
}, [showPages, selectedTag]);
|
73 |
+
|
74 |
+
const afterClose = () => {
|
75 |
+
form.resetFields();
|
76 |
};
|
77 |
|
78 |
+
useEffect(() => {
|
79 |
+
if (visible) {
|
80 |
+
const pages =
|
81 |
+
parserConfig.pages?.map((x) => ({ from: x[0], to: x[1] })) ?? [];
|
82 |
+
form.setFieldsValue({
|
83 |
+
pages: pages.length > 0 ? pages : [{ from: 1, to: 1024 }],
|
84 |
+
parser_config: omit(parserConfig, 'pages'),
|
85 |
+
});
|
86 |
+
}
|
87 |
+
}, [form, parserConfig, visible]);
|
88 |
+
|
89 |
return (
|
90 |
<Modal
|
91 |
title="Chunk Method"
|
92 |
open={visible}
|
93 |
onOk={handleOk}
|
94 |
onCancel={hideModal}
|
95 |
+
afterClose={afterClose}
|
96 |
>
|
97 |
<Space size={[0, 8]} wrap>
|
98 |
<div className={styles.tags}>
|
|
|
109 |
})}
|
110 |
</div>
|
111 |
</Space>
|
112 |
+
<Divider></Divider>
|
113 |
+
{
|
114 |
+
<Form name="dynamic_form_nest_item" autoComplete="off" form={form}>
|
115 |
+
{showPages && (
|
116 |
+
<>
|
117 |
+
<Form.List name="pages">
|
118 |
+
{(fields, { add, remove }) => (
|
119 |
+
<>
|
120 |
+
{fields.map(({ key, name, ...restField }) => (
|
121 |
+
<Space
|
122 |
+
key={key}
|
123 |
+
style={{
|
124 |
+
display: 'flex',
|
125 |
+
}}
|
126 |
+
align="baseline"
|
127 |
+
>
|
128 |
+
<Form.Item
|
129 |
+
{...restField}
|
130 |
+
name={[name, 'from']}
|
131 |
+
dependencies={name > 0 ? [name - 1, 'to'] : []}
|
132 |
+
rules={[
|
133 |
+
{
|
134 |
+
required: true,
|
135 |
+
message: 'Missing start page number',
|
136 |
+
},
|
137 |
+
({ getFieldValue }) => ({
|
138 |
+
validator(_, value) {
|
139 |
+
if (
|
140 |
+
name === 0 ||
|
141 |
+
!value ||
|
142 |
+
getFieldValue(['pages', name - 1, 'to']) <
|
143 |
+
value
|
144 |
+
) {
|
145 |
+
return Promise.resolve();
|
146 |
+
}
|
147 |
+
return Promise.reject(
|
148 |
+
new Error(
|
149 |
+
'The current value must be greater than the previous to!',
|
150 |
+
),
|
151 |
+
);
|
152 |
+
},
|
153 |
+
}),
|
154 |
+
]}
|
155 |
+
>
|
156 |
+
<InputNumber
|
157 |
+
placeholder="from"
|
158 |
+
min={0}
|
159 |
+
precision={0}
|
160 |
+
className={styles.pageInputNumber}
|
161 |
+
/>
|
162 |
+
</Form.Item>
|
163 |
+
<Form.Item
|
164 |
+
{...restField}
|
165 |
+
name={[name, 'to']}
|
166 |
+
dependencies={[name, 'from']}
|
167 |
+
rules={[
|
168 |
+
{
|
169 |
+
required: true,
|
170 |
+
message: 'Missing end page number(excluding)',
|
171 |
+
},
|
172 |
+
({ getFieldValue }) => ({
|
173 |
+
validator(_, value) {
|
174 |
+
if (
|
175 |
+
!value ||
|
176 |
+
getFieldValue(['pages', name, 'from']) < value
|
177 |
+
) {
|
178 |
+
return Promise.resolve();
|
179 |
+
}
|
180 |
+
return Promise.reject(
|
181 |
+
new Error(
|
182 |
+
'The current value must be greater than to!',
|
183 |
+
),
|
184 |
+
);
|
185 |
+
},
|
186 |
+
}),
|
187 |
+
]}
|
188 |
+
>
|
189 |
+
<InputNumber
|
190 |
+
placeholder="to"
|
191 |
+
min={0}
|
192 |
+
precision={0}
|
193 |
+
className={styles.pageInputNumber}
|
194 |
+
/>
|
195 |
+
</Form.Item>
|
196 |
+
{name > 0 && (
|
197 |
+
<MinusCircleOutlined onClick={() => remove(name)} />
|
198 |
+
)}
|
199 |
+
</Space>
|
200 |
+
))}
|
201 |
+
<Form.Item>
|
202 |
+
<Button
|
203 |
+
type="dashed"
|
204 |
+
onClick={() => add()}
|
205 |
+
block
|
206 |
+
icon={<PlusOutlined />}
|
207 |
+
>
|
208 |
+
Add page
|
209 |
+
</Button>
|
210 |
+
</Form.Item>
|
211 |
+
</>
|
212 |
+
)}
|
213 |
+
</Form.List>
|
214 |
+
<Form.Item
|
215 |
+
name={['parser_config', 'task_page_size']}
|
216 |
+
label="Task page size"
|
217 |
+
tooltip={'coming soon'}
|
218 |
+
initialValue={2}
|
219 |
+
rules={[
|
220 |
+
{
|
221 |
+
required: true,
|
222 |
+
message: 'Please input your task page size!',
|
223 |
+
},
|
224 |
+
]}
|
225 |
+
>
|
226 |
+
<InputNumber min={1} max={128} />
|
227 |
+
</Form.Item>
|
228 |
+
</>
|
229 |
+
)}
|
230 |
+
{showOne && (
|
231 |
+
<Form.Item
|
232 |
+
name={['parser_config', 'layout_recognize']}
|
233 |
+
label="Layout recognize"
|
234 |
+
initialValue={true}
|
235 |
+
valuePropName="checked"
|
236 |
+
tooltip={'coming soon'}
|
237 |
+
>
|
238 |
+
<Switch />
|
239 |
+
</Form.Item>
|
240 |
+
)}
|
241 |
+
{selectedTag === 'naive' && <MaxTokenNumber></MaxTokenNumber>}
|
242 |
+
</Form>
|
243 |
+
}
|
244 |
</Modal>
|
245 |
);
|
246 |
};
|
web/src/pages/add-knowledge/components/knowledge-file/hooks.ts
CHANGED
@@ -7,9 +7,13 @@ import {
|
|
7 |
} from '@/hooks/documentHooks';
|
8 |
import { useGetKnowledgeSearchParams } from '@/hooks/routeHook';
|
9 |
import { useOneNamespaceEffectsLoading } from '@/hooks/storeHooks';
|
10 |
-
import {
|
|
|
|
|
|
|
11 |
import { Pagination } from '@/interfaces/common';
|
12 |
import { IKnowledgeFile } from '@/interfaces/database/knowledge';
|
|
|
13 |
import { PaginationProps } from 'antd';
|
14 |
import { useCallback, useEffect, useMemo, useState } from 'react';
|
15 |
import { useDispatch, useNavigate, useSelector } from 'umi';
|
@@ -222,8 +226,8 @@ export const useChangeDocumentParser = (documentId: string) => {
|
|
222 |
]);
|
223 |
|
224 |
const onChangeParserOk = useCallback(
|
225 |
-
async (parserId: string) => {
|
226 |
-
const ret = await setDocumentParser(parserId, documentId);
|
227 |
if (ret === 0) {
|
228 |
hideChangeParserModal();
|
229 |
}
|
@@ -239,3 +243,21 @@ export const useChangeDocumentParser = (documentId: string) => {
|
|
239 |
showChangeParserModal,
|
240 |
};
|
241 |
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7 |
} from '@/hooks/documentHooks';
|
8 |
import { useGetKnowledgeSearchParams } from '@/hooks/routeHook';
|
9 |
import { useOneNamespaceEffectsLoading } from '@/hooks/storeHooks';
|
10 |
+
import {
|
11 |
+
useFetchTenantInfo,
|
12 |
+
useSelectParserList,
|
13 |
+
} from '@/hooks/userSettingHook';
|
14 |
import { Pagination } from '@/interfaces/common';
|
15 |
import { IKnowledgeFile } from '@/interfaces/database/knowledge';
|
16 |
+
import { IChangeParserConfigRequestBody } from '@/interfaces/request/document';
|
17 |
import { PaginationProps } from 'antd';
|
18 |
import { useCallback, useEffect, useMemo, useState } from 'react';
|
19 |
import { useDispatch, useNavigate, useSelector } from 'umi';
|
|
|
226 |
]);
|
227 |
|
228 |
const onChangeParserOk = useCallback(
|
229 |
+
async (parserId: string, parserConfig: IChangeParserConfigRequestBody) => {
|
230 |
+
const ret = await setDocumentParser(parserId, documentId, parserConfig);
|
231 |
if (ret === 0) {
|
232 |
hideChangeParserModal();
|
233 |
}
|
|
|
243 |
showChangeParserModal,
|
244 |
};
|
245 |
};
|
246 |
+
|
247 |
+
export const useFetchParserListOnMount = (parserId: string) => {
|
248 |
+
const [selectedTag, setSelectedTag] = useState('');
|
249 |
+
const parserList = useSelectParserList();
|
250 |
+
|
251 |
+
useFetchTenantInfo();
|
252 |
+
|
253 |
+
useEffect(() => {
|
254 |
+
setSelectedTag(parserId);
|
255 |
+
}, [parserId]);
|
256 |
+
|
257 |
+
const handleChange = (tag: string, checked: boolean) => {
|
258 |
+
const nextSelectedTag = checked ? tag : selectedTag;
|
259 |
+
setSelectedTag(nextSelectedTag);
|
260 |
+
};
|
261 |
+
|
262 |
+
return { parserList, handleChange, selectedTag };
|
263 |
+
};
|
web/src/pages/add-knowledge/components/knowledge-file/index.less
CHANGED
@@ -34,3 +34,7 @@
|
|
34 |
.tochunks {
|
35 |
cursor: pointer;
|
36 |
}
|
|
|
|
|
|
|
|
|
|
34 |
.tochunks {
|
35 |
cursor: pointer;
|
36 |
}
|
37 |
+
|
38 |
+
.pageInputNumber {
|
39 |
+
width: 220px;
|
40 |
+
}
|
web/src/pages/add-knowledge/components/knowledge-file/index.tsx
CHANGED
@@ -224,7 +224,9 @@ const KnowledgeFile = () => {
|
|
224 |
onOk={onCreateOk}
|
225 |
/>
|
226 |
<ChunkMethodModal
|
227 |
-
|
|
|
|
|
228 |
onOk={onChangeParserOk}
|
229 |
visible={changeParserVisible}
|
230 |
hideModal={hideChangeParserModal}
|
|
|
224 |
onOk={onCreateOk}
|
225 |
/>
|
226 |
<ChunkMethodModal
|
227 |
+
parserId={currentRecord.parser_id}
|
228 |
+
parserConfig={currentRecord.parser_config}
|
229 |
+
documentType={currentRecord.type}
|
230 |
onOk={onChangeParserOk}
|
231 |
visible={changeParserVisible}
|
232 |
hideModal={hideChangeParserModal}
|
web/src/pages/add-knowledge/components/knowledge-file/model.ts
CHANGED
@@ -7,10 +7,6 @@ import pick from 'lodash/pick';
|
|
7 |
import { DvaModel } from 'umi';
|
8 |
|
9 |
export interface KFModelState extends BaseState {
|
10 |
-
isShowCEFwModal: boolean;
|
11 |
-
isShowTntModal: boolean;
|
12 |
-
isShowSegmentSetModal: boolean;
|
13 |
-
isShowRenameModal: boolean;
|
14 |
tenantIfo: any;
|
15 |
data: IKnowledgeFile[];
|
16 |
total: number;
|
@@ -21,10 +17,6 @@ export interface KFModelState extends BaseState {
|
|
21 |
const model: DvaModel<KFModelState> = {
|
22 |
namespace: 'kFModel',
|
23 |
state: {
|
24 |
-
isShowCEFwModal: false,
|
25 |
-
isShowTntModal: false,
|
26 |
-
isShowSegmentSetModal: false,
|
27 |
-
isShowRenameModal: false,
|
28 |
tenantIfo: {},
|
29 |
data: [],
|
30 |
total: 0,
|
@@ -43,9 +35,7 @@ const model: DvaModel<KFModelState> = {
|
|
43 |
...payload,
|
44 |
};
|
45 |
},
|
46 |
-
|
47 |
-
return { ...state, isShowRenameModal: payload };
|
48 |
-
},
|
49 |
setCurrentRecord(state, { payload }) {
|
50 |
return { ...state, currentRecord: payload };
|
51 |
},
|
@@ -120,7 +110,7 @@ const model: DvaModel<KFModelState> = {
|
|
120 |
const { retcode } = data;
|
121 |
if (retcode === 0) {
|
122 |
message.success('Modified!');
|
123 |
-
put({
|
124 |
type: 'getKfList',
|
125 |
payload: { kb_id: payload.kb_id },
|
126 |
});
|
@@ -148,10 +138,7 @@ const model: DvaModel<KFModelState> = {
|
|
148 |
const { retcode } = data;
|
149 |
if (retcode === 0) {
|
150 |
message.success('rename success!');
|
151 |
-
|
152 |
-
type: 'setIsShowRenameModal',
|
153 |
-
payload: false,
|
154 |
-
});
|
155 |
yield put({
|
156 |
type: 'getKfList',
|
157 |
payload: { kb_id: payload.kb_id },
|
@@ -164,16 +151,11 @@ const model: DvaModel<KFModelState> = {
|
|
164 |
const { data } = yield call(kbService.document_create, payload);
|
165 |
const { retcode } = data;
|
166 |
if (retcode === 0) {
|
167 |
-
put({
|
168 |
type: 'getKfList',
|
169 |
payload: { kb_id: payload.kb_id },
|
170 |
});
|
171 |
-
|
172 |
-
type: 'kFModel/updateState',
|
173 |
-
payload: {
|
174 |
-
isShowCEFwModal: false,
|
175 |
-
},
|
176 |
-
});
|
177 |
message.success('Created!');
|
178 |
}
|
179 |
return retcode;
|
@@ -202,16 +184,11 @@ const model: DvaModel<KFModelState> = {
|
|
202 |
);
|
203 |
const { retcode } = data;
|
204 |
if (retcode === 0) {
|
205 |
-
put({
|
206 |
type: 'getKfList',
|
207 |
payload: { kb_id: payload.kb_id },
|
208 |
});
|
209 |
-
|
210 |
-
type: 'updateState',
|
211 |
-
payload: {
|
212 |
-
isShowSegmentSetModal: false,
|
213 |
-
},
|
214 |
-
});
|
215 |
message.success('Modified!');
|
216 |
}
|
217 |
return retcode;
|
|
|
7 |
import { DvaModel } from 'umi';
|
8 |
|
9 |
export interface KFModelState extends BaseState {
|
|
|
|
|
|
|
|
|
10 |
tenantIfo: any;
|
11 |
data: IKnowledgeFile[];
|
12 |
total: number;
|
|
|
17 |
const model: DvaModel<KFModelState> = {
|
18 |
namespace: 'kFModel',
|
19 |
state: {
|
|
|
|
|
|
|
|
|
20 |
tenantIfo: {},
|
21 |
data: [],
|
22 |
total: 0,
|
|
|
35 |
...payload,
|
36 |
};
|
37 |
},
|
38 |
+
|
|
|
|
|
39 |
setCurrentRecord(state, { payload }) {
|
40 |
return { ...state, currentRecord: payload };
|
41 |
},
|
|
|
110 |
const { retcode } = data;
|
111 |
if (retcode === 0) {
|
112 |
message.success('Modified!');
|
113 |
+
yield put({
|
114 |
type: 'getKfList',
|
115 |
payload: { kb_id: payload.kb_id },
|
116 |
});
|
|
|
138 |
const { retcode } = data;
|
139 |
if (retcode === 0) {
|
140 |
message.success('rename success!');
|
141 |
+
|
|
|
|
|
|
|
142 |
yield put({
|
143 |
type: 'getKfList',
|
144 |
payload: { kb_id: payload.kb_id },
|
|
|
151 |
const { data } = yield call(kbService.document_create, payload);
|
152 |
const { retcode } = data;
|
153 |
if (retcode === 0) {
|
154 |
+
yield put({
|
155 |
type: 'getKfList',
|
156 |
payload: { kb_id: payload.kb_id },
|
157 |
});
|
158 |
+
|
|
|
|
|
|
|
|
|
|
|
159 |
message.success('Created!');
|
160 |
}
|
161 |
return retcode;
|
|
|
184 |
);
|
185 |
const { retcode } = data;
|
186 |
if (retcode === 0) {
|
187 |
+
yield put({
|
188 |
type: 'getKfList',
|
189 |
payload: { kb_id: payload.kb_id },
|
190 |
});
|
191 |
+
|
|
|
|
|
|
|
|
|
|
|
192 |
message.success('Modified!');
|
193 |
}
|
194 |
return retcode;
|
web/src/pages/add-knowledge/components/knowledge-setting/configuration.tsx
CHANGED
@@ -1,22 +1,12 @@
|
|
1 |
import { normFile } from '@/utils/fileUtil';
|
2 |
import { PlusOutlined } from '@ant-design/icons';
|
3 |
-
import {
|
4 |
-
Button,
|
5 |
-
Flex,
|
6 |
-
Form,
|
7 |
-
Input,
|
8 |
-
InputNumber,
|
9 |
-
Radio,
|
10 |
-
Select,
|
11 |
-
Slider,
|
12 |
-
Space,
|
13 |
-
Upload,
|
14 |
-
} from 'antd';
|
15 |
import {
|
16 |
useFetchKnowledgeConfigurationOnMount,
|
17 |
useSubmitKnowledgeConfiguration,
|
18 |
} from './hooks';
|
19 |
|
|
|
20 |
import { FormInstance } from 'antd/lib';
|
21 |
import styles from './index.less';
|
22 |
|
@@ -121,35 +111,7 @@ const ConfigurationForm = ({ form }: { form: FormInstance }) => {
|
|
121 |
const parserId = getFieldValue('parser_id');
|
122 |
|
123 |
if (parserId === 'naive') {
|
124 |
-
return
|
125 |
-
<Form.Item label="Token number" tooltip="It determine the token number of a chunk approximately.">
|
126 |
-
<Flex gap={20} align="center">
|
127 |
-
<Flex flex={1}>
|
128 |
-
<Form.Item
|
129 |
-
name={['parser_config', 'chunk_token_num']}
|
130 |
-
noStyle
|
131 |
-
initialValue={128}
|
132 |
-
rules={[
|
133 |
-
{ required: true, message: 'Province is required' },
|
134 |
-
]}
|
135 |
-
>
|
136 |
-
<Slider className={styles.variableSlider} max={2048} />
|
137 |
-
</Form.Item>
|
138 |
-
</Flex>
|
139 |
-
<Form.Item
|
140 |
-
name={['parser_config', 'chunk_token_num']}
|
141 |
-
noStyle
|
142 |
-
rules={[{ required: true, message: 'Street is required' }]}
|
143 |
-
>
|
144 |
-
<InputNumber
|
145 |
-
className={styles.sliderInputNumber}
|
146 |
-
max={2048}
|
147 |
-
min={0}
|
148 |
-
/>
|
149 |
-
</Form.Item>
|
150 |
-
</Flex>
|
151 |
-
</Form.Item>
|
152 |
-
);
|
153 |
}
|
154 |
return null;
|
155 |
}}
|
|
|
1 |
import { normFile } from '@/utils/fileUtil';
|
2 |
import { PlusOutlined } from '@ant-design/icons';
|
3 |
+
import { Button, Form, Input, Radio, Select, Space, Upload } from 'antd';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4 |
import {
|
5 |
useFetchKnowledgeConfigurationOnMount,
|
6 |
useSubmitKnowledgeConfiguration,
|
7 |
} from './hooks';
|
8 |
|
9 |
+
import MaxTokenNumber from '@/components/max-token-number';
|
10 |
import { FormInstance } from 'antd/lib';
|
11 |
import styles from './index.less';
|
12 |
|
|
|
111 |
const parserId = getFieldValue('parser_id');
|
112 |
|
113 |
if (parserId === 'naive') {
|
114 |
+
return <MaxTokenNumber></MaxTokenNumber>;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
115 |
}
|
116 |
return null;
|
117 |
}}
|
web/src/pages/add-knowledge/components/knowledge-setting/model.ts
CHANGED
@@ -5,7 +5,6 @@ import { DvaModel } from 'umi';
|
|
5 |
|
6 |
export interface KSModelState {
|
7 |
isShowPSwModal: boolean;
|
8 |
-
isShowTntModal: boolean;
|
9 |
tenantIfo: any;
|
10 |
knowledgeDetails: IKnowledge;
|
11 |
}
|
@@ -14,7 +13,6 @@ const model: DvaModel<KSModelState> = {
|
|
14 |
namespace: 'kSModel',
|
15 |
state: {
|
16 |
isShowPSwModal: false,
|
17 |
-
isShowTntModal: false,
|
18 |
tenantIfo: {},
|
19 |
knowledgeDetails: {} as any,
|
20 |
},
|
|
|
5 |
|
6 |
export interface KSModelState {
|
7 |
isShowPSwModal: boolean;
|
|
|
8 |
tenantIfo: any;
|
9 |
knowledgeDetails: IKnowledge;
|
10 |
}
|
|
|
13 |
namespace: 'kSModel',
|
14 |
state: {
|
15 |
isShowPSwModal: false,
|
|
|
16 |
tenantIfo: {},
|
17 |
knowledgeDetails: {} as any,
|
18 |
},
|
web/src/pages/add-knowledge/components/knowledge-setting/utils.ts
CHANGED
@@ -5,9 +5,9 @@ const getImageName = (prefix: string, length: number) =>
|
|
5 |
|
6 |
export const ImageMap = {
|
7 |
book: getImageName('book', 4),
|
8 |
-
laws: getImageName('law',
|
9 |
manual: getImageName('manual', 4),
|
10 |
-
picture: getImageName('
|
11 |
naive: getImageName('naive', 2),
|
12 |
paper: getImageName('paper', 2),
|
13 |
presentation: getImageName('presentation', 2),
|
@@ -32,10 +32,13 @@ export const TextMap = {
|
|
32 |
The chunk granularity is consistent with 'ARTICLE', and all the upper level text will be included in the chunk.
|
33 |
</p>`,
|
34 |
},
|
35 |
-
manual: {
|
|
|
|
|
36 |
We assume manual has hierarchical section structure. We use the lowest section titles as pivots to slice documents.
|
37 |
So, the figures and tables in the same section will not be sliced apart, and chunk size might be large.
|
38 |
-
</p
|
|
|
39 |
naive: {
|
40 |
title: '',
|
41 |
description: `<p>Supported file formats are <b>DOCX, EXCEL, PPT, IMAGE, PDF, TXT</b>.</p>
|
@@ -100,19 +103,19 @@ export const TextMap = {
|
|
100 |
</li>
|
101 |
<li>Every row in table will be treated as a chunk.</li>
|
102 |
</ul>`,
|
103 |
-
},
|
104 |
-
picture: {
|
105 |
-
|
106 |
-
|
107 |
<p>Image files are supported. Video is coming soon.</p><p>
|
108 |
If the picture has text in it, OCR is applied to extract the text as its text description.
|
109 |
</p><p>
|
110 |
If the text extracted by OCR is not enough, visual LLM is used to get the descriptions.
|
111 |
</p>`,
|
112 |
},
|
113 |
-
one: {
|
114 |
-
|
115 |
-
|
116 |
<p>Supported file formats are <b>DOCX, EXCEL, PDF, TXT</b>.
|
117 |
</p><p>
|
118 |
For a document, it will be treated as an entire chunk, no split at all.
|
|
|
5 |
|
6 |
export const ImageMap = {
|
7 |
book: getImageName('book', 4),
|
8 |
+
laws: getImageName('law', 2),
|
9 |
manual: getImageName('manual', 4),
|
10 |
+
picture: getImageName('media', 2),
|
11 |
naive: getImageName('naive', 2),
|
12 |
paper: getImageName('paper', 2),
|
13 |
presentation: getImageName('presentation', 2),
|
|
|
32 |
The chunk granularity is consistent with 'ARTICLE', and all the upper level text will be included in the chunk.
|
33 |
</p>`,
|
34 |
},
|
35 |
+
manual: {
|
36 |
+
title: '',
|
37 |
+
description: `<p>Only <b>PDF</b> is supported.</p><p>
|
38 |
We assume manual has hierarchical section structure. We use the lowest section titles as pivots to slice documents.
|
39 |
So, the figures and tables in the same section will not be sliced apart, and chunk size might be large.
|
40 |
+
</p>`,
|
41 |
+
},
|
42 |
naive: {
|
43 |
title: '',
|
44 |
description: `<p>Supported file formats are <b>DOCX, EXCEL, PPT, IMAGE, PDF, TXT</b>.</p>
|
|
|
103 |
</li>
|
104 |
<li>Every row in table will be treated as a chunk.</li>
|
105 |
</ul>`,
|
106 |
+
},
|
107 |
+
picture: {
|
108 |
+
title: '',
|
109 |
+
description: `
|
110 |
<p>Image files are supported. Video is coming soon.</p><p>
|
111 |
If the picture has text in it, OCR is applied to extract the text as its text description.
|
112 |
</p><p>
|
113 |
If the text extracted by OCR is not enough, visual LLM is used to get the descriptions.
|
114 |
</p>`,
|
115 |
},
|
116 |
+
one: {
|
117 |
+
title: '',
|
118 |
+
description: `
|
119 |
<p>Supported file formats are <b>DOCX, EXCEL, PDF, TXT</b>.
|
120 |
</p><p>
|
121 |
For a document, it will be treated as an entire chunk, no split at all.
|
web/src/pages/add-knowledge/model.ts
CHANGED
@@ -1,7 +1,6 @@
|
|
1 |
import { DvaModel } from 'umi';
|
2 |
export interface kAModelState {
|
3 |
isShowPSwModal: boolean;
|
4 |
-
isShowTntModal: boolean;
|
5 |
tenantIfo: any;
|
6 |
id: string;
|
7 |
doc_id: string;
|
@@ -11,7 +10,6 @@ const model: DvaModel<kAModelState> = {
|
|
11 |
namespace: 'kAModel',
|
12 |
state: {
|
13 |
isShowPSwModal: false,
|
14 |
-
isShowTntModal: false,
|
15 |
tenantIfo: {},
|
16 |
id: '',
|
17 |
doc_id: '',
|
|
|
1 |
import { DvaModel } from 'umi';
|
2 |
export interface kAModelState {
|
3 |
isShowPSwModal: boolean;
|
|
|
4 |
tenantIfo: any;
|
5 |
id: string;
|
6 |
doc_id: string;
|
|
|
10 |
namespace: 'kAModel',
|
11 |
state: {
|
12 |
isShowPSwModal: false,
|
|
|
13 |
tenantIfo: {},
|
14 |
id: '',
|
15 |
doc_id: '',
|
web/src/pages/setting/CPwModal.tsx
DELETED
@@ -1,78 +0,0 @@
|
|
1 |
-
import { rsaPsw } from '@/utils';
|
2 |
-
import { Form, Input, Modal } from 'antd';
|
3 |
-
import { useTranslation } from 'react-i18next';
|
4 |
-
import { useDispatch, useSelector } from 'umi';
|
5 |
-
|
6 |
-
type FieldType = {
|
7 |
-
newPassword?: string;
|
8 |
-
password?: string;
|
9 |
-
};
|
10 |
-
|
11 |
-
const CpwModal = () => {
|
12 |
-
const dispatch = useDispatch();
|
13 |
-
const settingModel = useSelector((state: any) => state.settingModel);
|
14 |
-
const { isShowPSwModal } = settingModel;
|
15 |
-
const { t } = useTranslation();
|
16 |
-
const [form] = Form.useForm();
|
17 |
-
|
18 |
-
const handleCancel = () => {
|
19 |
-
dispatch({
|
20 |
-
type: 'settingModel/updateState',
|
21 |
-
payload: {
|
22 |
-
isShowPSwModal: false,
|
23 |
-
},
|
24 |
-
});
|
25 |
-
};
|
26 |
-
const handleOk = async () => {
|
27 |
-
try {
|
28 |
-
const values = await form.validateFields();
|
29 |
-
var password = rsaPsw(values.password);
|
30 |
-
var new_password = rsaPsw(values.newPassword);
|
31 |
-
|
32 |
-
dispatch({
|
33 |
-
type: 'settingModel/setting',
|
34 |
-
payload: {
|
35 |
-
password,
|
36 |
-
new_password,
|
37 |
-
},
|
38 |
-
});
|
39 |
-
} catch (errorInfo) {
|
40 |
-
console.log('Failed:', errorInfo);
|
41 |
-
}
|
42 |
-
};
|
43 |
-
|
44 |
-
return (
|
45 |
-
<Modal
|
46 |
-
title="Basic Modal"
|
47 |
-
open={isShowPSwModal}
|
48 |
-
onOk={handleOk}
|
49 |
-
onCancel={handleCancel}
|
50 |
-
>
|
51 |
-
<Form
|
52 |
-
form={form}
|
53 |
-
labelCol={{ span: 8 }}
|
54 |
-
wrapperCol={{ span: 16 }}
|
55 |
-
style={{ maxWidth: 600 }}
|
56 |
-
autoComplete="off"
|
57 |
-
>
|
58 |
-
<Form.Item<FieldType>
|
59 |
-
label="旧密码"
|
60 |
-
name="password"
|
61 |
-
rules={[{ required: true, message: 'Please input value' }]}
|
62 |
-
>
|
63 |
-
<Input.Password />
|
64 |
-
</Form.Item>
|
65 |
-
<Form.Item<FieldType>
|
66 |
-
label="新密码"
|
67 |
-
name="newPassword"
|
68 |
-
rules={[
|
69 |
-
{ required: true, message: 'Please input your newPassword!' },
|
70 |
-
]}
|
71 |
-
>
|
72 |
-
<Input.Password />
|
73 |
-
</Form.Item>
|
74 |
-
</Form>
|
75 |
-
</Modal>
|
76 |
-
);
|
77 |
-
};
|
78 |
-
export default CpwModal;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
web/src/pages/setting/List.tsx
DELETED
@@ -1,146 +0,0 @@
|
|
1 |
-
import { useTranslation } from 'react-i18next';
|
2 |
-
|
3 |
-
import { useEffect, useState } from 'react';
|
4 |
-
import styles from './index.less';
|
5 |
-
|
6 |
-
import { RadarChartOutlined } from '@ant-design/icons';
|
7 |
-
import { ProCard } from '@ant-design/pro-components';
|
8 |
-
import { Button, Card, Col, Row, Tag } from 'antd';
|
9 |
-
import { useDispatch, useSelector } from 'umi';
|
10 |
-
|
11 |
-
interface DataType {
|
12 |
-
key: React.Key;
|
13 |
-
name: string;
|
14 |
-
age: number;
|
15 |
-
address: string;
|
16 |
-
description: string;
|
17 |
-
}
|
18 |
-
|
19 |
-
const SettingList = () => {
|
20 |
-
const dispatch = useDispatch();
|
21 |
-
const settingModel = useSelector((state: any) => state.settingModel);
|
22 |
-
const { llmInfo = {}, factoriesList, myLlm = [] } = settingModel;
|
23 |
-
const { OpenAI = [], tongyi = [] } = llmInfo;
|
24 |
-
const [collapsed, setCollapsed] = useState(true);
|
25 |
-
const { t } = useTranslation();
|
26 |
-
|
27 |
-
useEffect(() => {
|
28 |
-
dispatch({
|
29 |
-
type: 'settingModel/factories_list',
|
30 |
-
payload: {},
|
31 |
-
});
|
32 |
-
dispatch({
|
33 |
-
type: 'settingModel/llm_list',
|
34 |
-
payload: {},
|
35 |
-
});
|
36 |
-
dispatch({
|
37 |
-
type: 'settingModel/my_llm',
|
38 |
-
payload: {},
|
39 |
-
});
|
40 |
-
}, [dispatch]);
|
41 |
-
|
42 |
-
return (
|
43 |
-
<div
|
44 |
-
className={styles.list}
|
45 |
-
style={{
|
46 |
-
display: 'flex',
|
47 |
-
flexDirection: 'column',
|
48 |
-
padding: 24,
|
49 |
-
gap: 12,
|
50 |
-
}}
|
51 |
-
>
|
52 |
-
{myLlm.map((item: any) => {
|
53 |
-
return (
|
54 |
-
<ProCard
|
55 |
-
key={item.llm_factory}
|
56 |
-
// title={<div>可折叠-图标自定义</div>}
|
57 |
-
collapsibleIconRender={({
|
58 |
-
collapsed: buildInCollapsed,
|
59 |
-
}: {
|
60 |
-
collapsed: boolean;
|
61 |
-
}) => {
|
62 |
-
return (
|
63 |
-
<div>
|
64 |
-
<h3>
|
65 |
-
<RadarChartOutlined />
|
66 |
-
{item.llm_factory}
|
67 |
-
</h3>
|
68 |
-
<div>
|
69 |
-
{item.tags.split(',').map((d: string) => {
|
70 |
-
return <Tag key={d}>{d}</Tag>;
|
71 |
-
})}
|
72 |
-
</div>
|
73 |
-
{buildInCollapsed ? (
|
74 |
-
<span>显示{OpenAI.length}个模型</span>
|
75 |
-
) : (
|
76 |
-
<span>收起{OpenAI.length}个模型 </span>
|
77 |
-
)}
|
78 |
-
</div>
|
79 |
-
);
|
80 |
-
}}
|
81 |
-
extra={
|
82 |
-
<Button
|
83 |
-
size="small"
|
84 |
-
type="link"
|
85 |
-
onClick={(e) => {
|
86 |
-
e.stopPropagation();
|
87 |
-
dispatch({
|
88 |
-
type: 'settingModel/updateState',
|
89 |
-
payload: {
|
90 |
-
llm_factory: item.llm_factory,
|
91 |
-
isShowSAKModal: true,
|
92 |
-
},
|
93 |
-
});
|
94 |
-
}}
|
95 |
-
>
|
96 |
-
设置
|
97 |
-
</Button>
|
98 |
-
}
|
99 |
-
style={{ marginBlockStart: 16 }}
|
100 |
-
headerBordered
|
101 |
-
collapsible
|
102 |
-
defaultCollapsed
|
103 |
-
></ProCard>
|
104 |
-
);
|
105 |
-
})}
|
106 |
-
|
107 |
-
<Row gutter={{ xs: 8, sm: 16, md: 24, lg: 32 }}>
|
108 |
-
{factoriesList.map((item: any) => {
|
109 |
-
return (
|
110 |
-
<Col key={item.name} xs={24} sm={12} md={8} lg={6}>
|
111 |
-
<Card
|
112 |
-
title={item.name}
|
113 |
-
bordered={false}
|
114 |
-
extra={
|
115 |
-
<Button
|
116 |
-
size="small"
|
117 |
-
type="link"
|
118 |
-
onClick={(e) => {
|
119 |
-
e.stopPropagation();
|
120 |
-
dispatch({
|
121 |
-
type: 'settingModel/updateState',
|
122 |
-
payload: {
|
123 |
-
llm_factory: item.name,
|
124 |
-
isShowSAKModal: true,
|
125 |
-
},
|
126 |
-
});
|
127 |
-
}}
|
128 |
-
>
|
129 |
-
设置
|
130 |
-
</Button>
|
131 |
-
}
|
132 |
-
>
|
133 |
-
<div>
|
134 |
-
{item.tags.split(',').map((d: string) => {
|
135 |
-
return <Tag key={d}>{d}</Tag>;
|
136 |
-
})}
|
137 |
-
</div>
|
138 |
-
</Card>
|
139 |
-
</Col>
|
140 |
-
);
|
141 |
-
})}
|
142 |
-
</Row>
|
143 |
-
</div>
|
144 |
-
);
|
145 |
-
};
|
146 |
-
export default SettingList;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
web/src/pages/setting/SAKModal.tsx
DELETED
@@ -1,66 +0,0 @@
|
|
1 |
-
import { Form, Input, Modal } from 'antd';
|
2 |
-
import { useTranslation } from 'react-i18next';
|
3 |
-
import { useDispatch, useSelector } from 'umi';
|
4 |
-
|
5 |
-
type FieldType = {
|
6 |
-
api_key?: string;
|
7 |
-
};
|
8 |
-
|
9 |
-
const SakModal = () => {
|
10 |
-
const dispatch = useDispatch();
|
11 |
-
const settingModel = useSelector((state: any) => state.settingModel);
|
12 |
-
const { isShowSAKModal, llm_factory } = settingModel;
|
13 |
-
const { t } = useTranslation();
|
14 |
-
const [form] = Form.useForm();
|
15 |
-
|
16 |
-
const handleCancel = () => {
|
17 |
-
dispatch({
|
18 |
-
type: 'settingModel/updateState',
|
19 |
-
payload: {
|
20 |
-
isShowSAKModal: false,
|
21 |
-
},
|
22 |
-
});
|
23 |
-
};
|
24 |
-
const handleOk = async () => {
|
25 |
-
try {
|
26 |
-
const values = await form.validateFields();
|
27 |
-
|
28 |
-
dispatch({
|
29 |
-
type: 'settingModel/set_api_key',
|
30 |
-
payload: {
|
31 |
-
api_key: values.api_key,
|
32 |
-
llm_factory: llm_factory,
|
33 |
-
},
|
34 |
-
});
|
35 |
-
} catch (errorInfo) {
|
36 |
-
console.log('Failed:', errorInfo);
|
37 |
-
}
|
38 |
-
};
|
39 |
-
|
40 |
-
return (
|
41 |
-
<Modal
|
42 |
-
title="Basic Modal"
|
43 |
-
open={isShowSAKModal}
|
44 |
-
onOk={handleOk}
|
45 |
-
onCancel={handleCancel}
|
46 |
-
>
|
47 |
-
<Form
|
48 |
-
form={form}
|
49 |
-
name="validateOnly"
|
50 |
-
labelCol={{ span: 8 }}
|
51 |
-
wrapperCol={{ span: 16 }}
|
52 |
-
style={{ maxWidth: 600 }}
|
53 |
-
autoComplete="off"
|
54 |
-
>
|
55 |
-
<Form.Item<FieldType>
|
56 |
-
label="API Key"
|
57 |
-
name="api_key"
|
58 |
-
rules={[{ required: true, message: 'Please input ' }]}
|
59 |
-
>
|
60 |
-
<Input />
|
61 |
-
</Form.Item>
|
62 |
-
</Form>
|
63 |
-
</Modal>
|
64 |
-
);
|
65 |
-
};
|
66 |
-
export default SakModal;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
web/src/pages/setting/SSModal.tsx
DELETED
@@ -1,144 +0,0 @@
|
|
1 |
-
import { Form, Modal, Select } from 'antd';
|
2 |
-
import { useTranslation } from 'react-i18next';
|
3 |
-
import { useDispatch, useSelector } from 'umi';
|
4 |
-
|
5 |
-
type FieldType = {
|
6 |
-
embd_id?: string;
|
7 |
-
img2txt_id?: string;
|
8 |
-
llm_id?: string;
|
9 |
-
asr_id?: string;
|
10 |
-
};
|
11 |
-
|
12 |
-
const SsModal = () => {
|
13 |
-
const dispatch = useDispatch();
|
14 |
-
const settingModel = useSelector((state: any) => state.settingModel);
|
15 |
-
const { isShowSSModal, llmInfo = {}, tenantIfo } = settingModel;
|
16 |
-
const [form] = Form.useForm();
|
17 |
-
const { t } = useTranslation();
|
18 |
-
|
19 |
-
const handleCancel = () => {
|
20 |
-
dispatch({
|
21 |
-
type: 'settingModel/updateState',
|
22 |
-
payload: {
|
23 |
-
isShowSSModal: false,
|
24 |
-
},
|
25 |
-
});
|
26 |
-
};
|
27 |
-
|
28 |
-
const handleOk = async () => {
|
29 |
-
try {
|
30 |
-
const values = await form.validateFields();
|
31 |
-
const retcode = await dispatch<any>({
|
32 |
-
type: 'settingModel/set_tenant_info',
|
33 |
-
payload: {
|
34 |
-
...values,
|
35 |
-
tenant_id: tenantIfo.tenant_id,
|
36 |
-
},
|
37 |
-
});
|
38 |
-
retcode === 0 &&
|
39 |
-
dispatch({
|
40 |
-
type: 'settingModel/updateState',
|
41 |
-
payload: {
|
42 |
-
isShowSSModal: false,
|
43 |
-
},
|
44 |
-
});
|
45 |
-
} catch (errorInfo) {
|
46 |
-
console.log('Failed:', errorInfo);
|
47 |
-
}
|
48 |
-
};
|
49 |
-
|
50 |
-
const handleChange = () => {};
|
51 |
-
|
52 |
-
return (
|
53 |
-
<Modal
|
54 |
-
title="Basic Modal"
|
55 |
-
open={isShowSSModal}
|
56 |
-
onOk={handleOk}
|
57 |
-
onCancel={handleCancel}
|
58 |
-
>
|
59 |
-
<Form
|
60 |
-
form={form}
|
61 |
-
name="validateOnly"
|
62 |
-
// labelCol={{ span: 8 }}
|
63 |
-
// wrapperCol={{ span: 16 }}
|
64 |
-
style={{ maxWidth: 600 }}
|
65 |
-
autoComplete="off"
|
66 |
-
layout="vertical"
|
67 |
-
>
|
68 |
-
<Form.Item<FieldType>
|
69 |
-
label="embedding 模型"
|
70 |
-
name="embd_id"
|
71 |
-
rules={[{ required: true, message: 'Please input value' }]}
|
72 |
-
initialValue={tenantIfo.embd_id}
|
73 |
-
>
|
74 |
-
<Select
|
75 |
-
// style={{ width: 200 }}
|
76 |
-
onChange={handleChange}
|
77 |
-
// fieldNames={label:}
|
78 |
-
options={Object.keys(llmInfo).map((t) => {
|
79 |
-
const options = llmInfo[t]
|
80 |
-
.filter((d: any) => d.model_type === 'embedding')
|
81 |
-
.map((d: any) => ({ label: d.llm_name, value: d.llm_name }));
|
82 |
-
return { label: t, options };
|
83 |
-
})}
|
84 |
-
/>
|
85 |
-
</Form.Item>
|
86 |
-
<Form.Item<FieldType>
|
87 |
-
label="chat 模型"
|
88 |
-
name="llm_id"
|
89 |
-
rules={[{ required: true, message: 'Please input value' }]}
|
90 |
-
initialValue={tenantIfo.llm_id}
|
91 |
-
>
|
92 |
-
<Select
|
93 |
-
// style={{ width: 200 }}
|
94 |
-
onChange={handleChange}
|
95 |
-
// fieldNames={label:}
|
96 |
-
options={Object.keys(llmInfo).map((t) => {
|
97 |
-
const options = llmInfo[t]
|
98 |
-
.filter((d: any) => d.model_type === 'chat')
|
99 |
-
.map((d: any) => ({ label: d.llm_name, value: d.llm_name }));
|
100 |
-
return { label: t, options };
|
101 |
-
})}
|
102 |
-
/>
|
103 |
-
</Form.Item>
|
104 |
-
<Form.Item<FieldType>
|
105 |
-
label="image2text 模型"
|
106 |
-
name="img2txt_id"
|
107 |
-
rules={[{ required: true, message: 'Please input value' }]}
|
108 |
-
initialValue={tenantIfo.img2txt_id}
|
109 |
-
>
|
110 |
-
<Select
|
111 |
-
// style={{ width: 200 }}
|
112 |
-
onChange={handleChange}
|
113 |
-
// fieldNames={label:}
|
114 |
-
options={Object.keys(llmInfo).map((t) => {
|
115 |
-
const options = llmInfo[t]
|
116 |
-
.filter((d: any) => d.model_type === 'image2text')
|
117 |
-
.map((d: any) => ({ label: d.llm_name, value: d.llm_name }));
|
118 |
-
return { label: t, options };
|
119 |
-
})}
|
120 |
-
/>
|
121 |
-
</Form.Item>
|
122 |
-
<Form.Item<FieldType>
|
123 |
-
label="speech2text 模型"
|
124 |
-
name="asr_id"
|
125 |
-
rules={[{ required: true, message: 'Please input value' }]}
|
126 |
-
initialValue={tenantIfo.asr_id}
|
127 |
-
>
|
128 |
-
<Select
|
129 |
-
// style={{ width: 200 }}
|
130 |
-
onChange={handleChange}
|
131 |
-
// fieldNames={label:}
|
132 |
-
options={Object.keys(llmInfo).map((t) => {
|
133 |
-
const options = llmInfo[t]
|
134 |
-
.filter((d: any) => d.model_type === 'speech2text')
|
135 |
-
.map((d: any) => ({ label: d.llm_name, value: d.llm_name }));
|
136 |
-
return { label: t, options };
|
137 |
-
})}
|
138 |
-
/>
|
139 |
-
</Form.Item>
|
140 |
-
</Form>
|
141 |
-
</Modal>
|
142 |
-
);
|
143 |
-
};
|
144 |
-
export default SsModal;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
web/src/pages/setting/TntModal.tsx
DELETED
@@ -1,65 +0,0 @@
|
|
1 |
-
import { useOneNamespaceEffectsLoading } from '@/hooks/storeHooks';
|
2 |
-
import { Modal, Table } from 'antd';
|
3 |
-
import { ColumnsType } from 'antd/es/table';
|
4 |
-
import { useTranslation } from 'react-i18next';
|
5 |
-
import { useDispatch, useSelector } from 'umi';
|
6 |
-
import styles from './index.less';
|
7 |
-
|
8 |
-
interface DataType {
|
9 |
-
key: React.Key;
|
10 |
-
name: string;
|
11 |
-
role: string;
|
12 |
-
time: string;
|
13 |
-
}
|
14 |
-
|
15 |
-
const TntModal = () => {
|
16 |
-
const dispatch = useDispatch();
|
17 |
-
const settingModel = useSelector((state: any) => state.settingModel);
|
18 |
-
const { isShowTntModal, tenantIfo, factoriesList } = settingModel;
|
19 |
-
const { t } = useTranslation();
|
20 |
-
const loading = useOneNamespaceEffectsLoading('settingModel', [
|
21 |
-
'getTenantInfo',
|
22 |
-
]);
|
23 |
-
|
24 |
-
const columns: ColumnsType<DataType> = [
|
25 |
-
{ title: '姓名', dataIndex: 'name', key: 'name' },
|
26 |
-
{ title: '活动时间', dataIndex: 'update_date', key: 'update_date' },
|
27 |
-
{ title: '角色', dataIndex: 'role', key: 'age' },
|
28 |
-
];
|
29 |
-
|
30 |
-
const handleCancel = () => {
|
31 |
-
dispatch({
|
32 |
-
type: 'settingModel/updateState',
|
33 |
-
payload: {
|
34 |
-
isShowTntModal: false,
|
35 |
-
},
|
36 |
-
});
|
37 |
-
};
|
38 |
-
|
39 |
-
const handleOk = async () => {
|
40 |
-
dispatch({
|
41 |
-
type: 'settingModel/updateState',
|
42 |
-
payload: {
|
43 |
-
isShowTntModal: false,
|
44 |
-
},
|
45 |
-
});
|
46 |
-
};
|
47 |
-
|
48 |
-
return (
|
49 |
-
<Modal
|
50 |
-
title="用户"
|
51 |
-
open={isShowTntModal}
|
52 |
-
onOk={handleOk}
|
53 |
-
onCancel={handleCancel}
|
54 |
-
>
|
55 |
-
<div className={styles.tenantIfo}>{tenantIfo.name}</div>
|
56 |
-
<Table
|
57 |
-
rowKey="name"
|
58 |
-
loading={loading}
|
59 |
-
columns={columns}
|
60 |
-
dataSource={factoriesList}
|
61 |
-
/>
|
62 |
-
</Modal>
|
63 |
-
);
|
64 |
-
};
|
65 |
-
export default TntModal;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
web/src/pages/setting/index.less
DELETED
@@ -1,49 +0,0 @@
|
|
1 |
-
.settingPage {
|
2 |
-
padding: 10px;
|
3 |
-
}
|
4 |
-
|
5 |
-
.avatar {
|
6 |
-
display: flex;
|
7 |
-
justify-content: center;
|
8 |
-
}
|
9 |
-
|
10 |
-
.tenantIfo {
|
11 |
-
height: 50px;
|
12 |
-
background-color: #f4dfdf;
|
13 |
-
margin-bottom: 10px;
|
14 |
-
padding: 5px;
|
15 |
-
box-sizing: border-box;
|
16 |
-
display: flex;
|
17 |
-
align-items: center;
|
18 |
-
}
|
19 |
-
|
20 |
-
.list {
|
21 |
-
:global {
|
22 |
-
.ant-pro-card-header {
|
23 |
-
height: 150px;
|
24 |
-
background-color: rgb(229, 231, 235);
|
25 |
-
}
|
26 |
-
}
|
27 |
-
}
|
28 |
-
|
29 |
-
ul {
|
30 |
-
li {
|
31 |
-
display: flex;
|
32 |
-
justify-content: space-between;
|
33 |
-
margin-bottom: 5px;
|
34 |
-
|
35 |
-
.statusDisaabled {
|
36 |
-
width: 10px;
|
37 |
-
height: 10px;
|
38 |
-
border-radius: 40%;
|
39 |
-
background: rgba(0, 0, 0, 0.4);
|
40 |
-
}
|
41 |
-
|
42 |
-
.statusAvailable {
|
43 |
-
width: 10px;
|
44 |
-
height: 10px;
|
45 |
-
border-radius: 50%;
|
46 |
-
background: green;
|
47 |
-
}
|
48 |
-
}
|
49 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
web/src/pages/setting/index.tsx
DELETED
@@ -1,98 +0,0 @@
|
|
1 |
-
import { Button, FloatButton } from 'antd';
|
2 |
-
import i18n from 'i18next';
|
3 |
-
import { useTranslation } from 'react-i18next';
|
4 |
-
|
5 |
-
import authorizationUtil from '@/utils/authorizationUtil';
|
6 |
-
import { useEffect } from 'react';
|
7 |
-
import { useDispatch, useSelector } from 'umi';
|
8 |
-
import CPwModal from './CPwModal';
|
9 |
-
import List from './List';
|
10 |
-
import SAKModal from './SAKModal';
|
11 |
-
import SSModal from './SSModal';
|
12 |
-
import TntModal from './TntModal';
|
13 |
-
import styles from './index.less';
|
14 |
-
|
15 |
-
const Setting = () => {
|
16 |
-
const dispatch = useDispatch();
|
17 |
-
const settingModel = useSelector((state: any) => state.settingModel);
|
18 |
-
const { t } = useTranslation();
|
19 |
-
const userInfo = authorizationUtil.getUserInfoObject();
|
20 |
-
|
21 |
-
const changeLang = (val: string) => {
|
22 |
-
// 改变状态里的 语言 进行切换
|
23 |
-
i18n.changeLanguage(val);
|
24 |
-
};
|
25 |
-
|
26 |
-
useEffect(() => {
|
27 |
-
dispatch({
|
28 |
-
type: 'settingModel/getTenantInfo',
|
29 |
-
payload: {},
|
30 |
-
});
|
31 |
-
}, []);
|
32 |
-
|
33 |
-
const showCPwModal = () => {
|
34 |
-
dispatch({
|
35 |
-
type: 'settingModel/updateState',
|
36 |
-
payload: {
|
37 |
-
isShowPSwModal: true,
|
38 |
-
},
|
39 |
-
});
|
40 |
-
};
|
41 |
-
const showTntModal = () => {
|
42 |
-
dispatch({
|
43 |
-
type: 'settingModel/updateState',
|
44 |
-
payload: {
|
45 |
-
isShowTntModal: true,
|
46 |
-
},
|
47 |
-
});
|
48 |
-
};
|
49 |
-
const showSSModal = () => {
|
50 |
-
dispatch({
|
51 |
-
type: 'settingModel/updateState',
|
52 |
-
payload: {
|
53 |
-
isShowSSModal: true,
|
54 |
-
},
|
55 |
-
});
|
56 |
-
};
|
57 |
-
return (
|
58 |
-
<div className={styles.settingPage}>
|
59 |
-
<div className={styles.avatar}>
|
60 |
-
<img
|
61 |
-
style={{ width: 50, marginRight: 5 }}
|
62 |
-
src="https://os.alipayobjects.com/rmsportal/QBnOOoLaAfKPirc.png"
|
63 |
-
alt=""
|
64 |
-
/>
|
65 |
-
<div>
|
66 |
-
<div>账号:{userInfo.name}</div>
|
67 |
-
<div>
|
68 |
-
<span>密码:******</span>
|
69 |
-
<Button type="link" onClick={showCPwModal}>
|
70 |
-
修改密码
|
71 |
-
</Button>
|
72 |
-
</div>
|
73 |
-
</div>
|
74 |
-
</div>
|
75 |
-
<div>
|
76 |
-
<Button type="link" onClick={showTntModal}>
|
77 |
-
租户
|
78 |
-
</Button>
|
79 |
-
<Button type="link" onClick={showSSModal}>
|
80 |
-
系统模型设置
|
81 |
-
</Button>
|
82 |
-
<List />
|
83 |
-
</div>
|
84 |
-
<CPwModal />
|
85 |
-
<SAKModal />
|
86 |
-
<SSModal />
|
87 |
-
<TntModal />
|
88 |
-
<FloatButton
|
89 |
-
shape="square"
|
90 |
-
description={t('setting.btn')}
|
91 |
-
onClick={() => i18n.changeLanguage(i18n.language == 'en' ? 'zh' : 'en')}
|
92 |
-
type="default"
|
93 |
-
style={{ right: 94, fontSize: 14 }}
|
94 |
-
/>
|
95 |
-
</div>
|
96 |
-
);
|
97 |
-
};
|
98 |
-
export default Setting;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
web/src/pages/{setting → user-setting}/model.ts
RENAMED
@@ -1,151 +1,151 @@
|
|
1 |
-
import { ITenantInfo } from '@/interfaces/database/knowledge';
|
2 |
-
import {
|
3 |
-
IFactory,
|
4 |
-
IMyLlmValue,
|
5 |
-
IThirdOAIModelCollection as IThirdAiModelCollection,
|
6 |
-
} from '@/interfaces/database/llm';
|
7 |
-
import { IUserInfo } from '@/interfaces/database/userSetting';
|
8 |
-
import userService from '@/services/userService';
|
9 |
-
import { message } from 'antd';
|
10 |
-
import { DvaModel } from 'umi';
|
11 |
-
|
12 |
-
export interface SettingModelState {
|
13 |
-
llm_factory: string;
|
14 |
-
tenantIfo: Nullable<ITenantInfo>;
|
15 |
-
llmInfo: IThirdAiModelCollection;
|
16 |
-
myLlmList: Record<string, IMyLlmValue>;
|
17 |
-
factoryList: IFactory[];
|
18 |
-
userInfo: IUserInfo;
|
19 |
-
}
|
20 |
-
|
21 |
-
const model: DvaModel<SettingModelState> = {
|
22 |
-
namespace: 'settingModel',
|
23 |
-
state: {
|
24 |
-
llm_factory: '',
|
25 |
-
tenantIfo: null,
|
26 |
-
llmInfo: {},
|
27 |
-
myLlmList: {},
|
28 |
-
factoryList: [],
|
29 |
-
userInfo: {} as IUserInfo,
|
30 |
-
},
|
31 |
-
reducers: {
|
32 |
-
updateState(state, { payload }) {
|
33 |
-
return {
|
34 |
-
...state,
|
35 |
-
...payload,
|
36 |
-
};
|
37 |
-
},
|
38 |
-
setUserInfo(state, { payload }) {
|
39 |
-
return {
|
40 |
-
...state,
|
41 |
-
userInfo: payload,
|
42 |
-
};
|
43 |
-
},
|
44 |
-
},
|
45 |
-
effects: {
|
46 |
-
*setting({ payload = {} }, { call, put }) {
|
47 |
-
const { data } = yield call(userService.setting, payload);
|
48 |
-
const { retcode } = data;
|
49 |
-
if (retcode === 0) {
|
50 |
-
message.success('Modified!');
|
51 |
-
yield put({
|
52 |
-
type: 'getUserInfo',
|
53 |
-
});
|
54 |
-
}
|
55 |
-
},
|
56 |
-
*getUserInfo({ payload = {} }, { call, put }) {
|
57 |
-
const { data } = yield call(userService.user_info, payload);
|
58 |
-
const { retcode, data: res } = data;
|
59 |
-
|
60 |
-
// const userInfo = {
|
61 |
-
// avatar: res.avatar,
|
62 |
-
// name: res.nickname,
|
63 |
-
// email: res.email,
|
64 |
-
// };
|
65 |
-
// authorizationUtil.setUserInfo(userInfo);
|
66 |
-
if (retcode === 0) {
|
67 |
-
yield put({ type: 'setUserInfo', payload: res });
|
68 |
-
// localStorage.setItem('userInfo',res.)
|
69 |
-
}
|
70 |
-
},
|
71 |
-
*getTenantInfo({ payload = {} }, { call, put }) {
|
72 |
-
const { data } = yield call(userService.get_tenant_info, payload);
|
73 |
-
const { retcode, data: res } = data;
|
74 |
-
// llm_id 对应chat_id
|
75 |
-
// asr_id 对应speech2txt
|
76 |
-
|
77 |
-
if (retcode === 0) {
|
78 |
-
res.chat_id = res.llm_id;
|
79 |
-
res.speech2text_id = res.asr_id;
|
80 |
-
yield put({
|
81 |
-
type: 'updateState',
|
82 |
-
payload: {
|
83 |
-
tenantIfo: res,
|
84 |
-
},
|
85 |
-
});
|
86 |
-
}
|
87 |
-
},
|
88 |
-
*set_tenant_info({ payload = {} }, { call, put }) {
|
89 |
-
const { data } = yield call(userService.set_tenant_info, payload);
|
90 |
-
const { retcode } = data;
|
91 |
-
if (retcode === 0) {
|
92 |
-
message.success('Modified!');
|
93 |
-
yield put({
|
94 |
-
type: 'getTenantInfo',
|
95 |
-
});
|
96 |
-
}
|
97 |
-
return retcode;
|
98 |
-
},
|
99 |
-
|
100 |
-
*factories_list({ payload = {} }, { call, put }) {
|
101 |
-
const { data } = yield call(userService.factories_list);
|
102 |
-
const { retcode, data: res } = data;
|
103 |
-
if (retcode === 0) {
|
104 |
-
yield put({
|
105 |
-
type: 'updateState',
|
106 |
-
payload: {
|
107 |
-
factoryList: res,
|
108 |
-
},
|
109 |
-
});
|
110 |
-
}
|
111 |
-
},
|
112 |
-
*llm_list({ payload = {} }, { call, put }) {
|
113 |
-
const { data } = yield call(userService.llm_list, payload);
|
114 |
-
const { retcode, data: res } = data;
|
115 |
-
if (retcode === 0) {
|
116 |
-
yield put({
|
117 |
-
type: 'updateState',
|
118 |
-
payload: {
|
119 |
-
llmInfo: res,
|
120 |
-
},
|
121 |
-
});
|
122 |
-
}
|
123 |
-
},
|
124 |
-
*my_llm({ payload = {} }, { call, put }) {
|
125 |
-
const { data } = yield call(userService.my_llm);
|
126 |
-
const { retcode, data: res } = data;
|
127 |
-
if (retcode === 0) {
|
128 |
-
yield put({
|
129 |
-
type: 'updateState',
|
130 |
-
payload: {
|
131 |
-
myLlmList: res,
|
132 |
-
},
|
133 |
-
});
|
134 |
-
}
|
135 |
-
},
|
136 |
-
*set_api_key({ payload = {} }, { call, put }) {
|
137 |
-
const { data } = yield call(userService.set_api_key, payload);
|
138 |
-
const { retcode } = data;
|
139 |
-
if (retcode === 0) {
|
140 |
-
message.success('Modified!');
|
141 |
-
yield put({ type: 'my_llm' });
|
142 |
-
yield put({ type: 'factories_list' });
|
143 |
-
yield put({
|
144 |
-
type: 'updateState',
|
145 |
-
});
|
146 |
-
}
|
147 |
-
return retcode;
|
148 |
-
},
|
149 |
-
},
|
150 |
-
};
|
151 |
-
export default model;
|
|
|
1 |
+
import { ITenantInfo } from '@/interfaces/database/knowledge';
|
2 |
+
import {
|
3 |
+
IFactory,
|
4 |
+
IMyLlmValue,
|
5 |
+
IThirdOAIModelCollection as IThirdAiModelCollection,
|
6 |
+
} from '@/interfaces/database/llm';
|
7 |
+
import { IUserInfo } from '@/interfaces/database/userSetting';
|
8 |
+
import userService from '@/services/userService';
|
9 |
+
import { message } from 'antd';
|
10 |
+
import { DvaModel } from 'umi';
|
11 |
+
|
12 |
+
export interface SettingModelState {
|
13 |
+
llm_factory: string;
|
14 |
+
tenantIfo: Nullable<ITenantInfo>;
|
15 |
+
llmInfo: IThirdAiModelCollection;
|
16 |
+
myLlmList: Record<string, IMyLlmValue>;
|
17 |
+
factoryList: IFactory[];
|
18 |
+
userInfo: IUserInfo;
|
19 |
+
}
|
20 |
+
|
21 |
+
const model: DvaModel<SettingModelState> = {
|
22 |
+
namespace: 'settingModel',
|
23 |
+
state: {
|
24 |
+
llm_factory: '',
|
25 |
+
tenantIfo: null,
|
26 |
+
llmInfo: {},
|
27 |
+
myLlmList: {},
|
28 |
+
factoryList: [],
|
29 |
+
userInfo: {} as IUserInfo,
|
30 |
+
},
|
31 |
+
reducers: {
|
32 |
+
updateState(state, { payload }) {
|
33 |
+
return {
|
34 |
+
...state,
|
35 |
+
...payload,
|
36 |
+
};
|
37 |
+
},
|
38 |
+
setUserInfo(state, { payload }) {
|
39 |
+
return {
|
40 |
+
...state,
|
41 |
+
userInfo: payload,
|
42 |
+
};
|
43 |
+
},
|
44 |
+
},
|
45 |
+
effects: {
|
46 |
+
*setting({ payload = {} }, { call, put }) {
|
47 |
+
const { data } = yield call(userService.setting, payload);
|
48 |
+
const { retcode } = data;
|
49 |
+
if (retcode === 0) {
|
50 |
+
message.success('Modified!');
|
51 |
+
yield put({
|
52 |
+
type: 'getUserInfo',
|
53 |
+
});
|
54 |
+
}
|
55 |
+
},
|
56 |
+
*getUserInfo({ payload = {} }, { call, put }) {
|
57 |
+
const { data } = yield call(userService.user_info, payload);
|
58 |
+
const { retcode, data: res } = data;
|
59 |
+
|
60 |
+
// const userInfo = {
|
61 |
+
// avatar: res.avatar,
|
62 |
+
// name: res.nickname,
|
63 |
+
// email: res.email,
|
64 |
+
// };
|
65 |
+
// authorizationUtil.setUserInfo(userInfo);
|
66 |
+
if (retcode === 0) {
|
67 |
+
yield put({ type: 'setUserInfo', payload: res });
|
68 |
+
// localStorage.setItem('userInfo',res.)
|
69 |
+
}
|
70 |
+
},
|
71 |
+
*getTenantInfo({ payload = {} }, { call, put }) {
|
72 |
+
const { data } = yield call(userService.get_tenant_info, payload);
|
73 |
+
const { retcode, data: res } = data;
|
74 |
+
// llm_id 对应chat_id
|
75 |
+
// asr_id 对应speech2txt
|
76 |
+
|
77 |
+
if (retcode === 0) {
|
78 |
+
res.chat_id = res.llm_id;
|
79 |
+
res.speech2text_id = res.asr_id;
|
80 |
+
yield put({
|
81 |
+
type: 'updateState',
|
82 |
+
payload: {
|
83 |
+
tenantIfo: res,
|
84 |
+
},
|
85 |
+
});
|
86 |
+
}
|
87 |
+
},
|
88 |
+
*set_tenant_info({ payload = {} }, { call, put }) {
|
89 |
+
const { data } = yield call(userService.set_tenant_info, payload);
|
90 |
+
const { retcode } = data;
|
91 |
+
if (retcode === 0) {
|
92 |
+
message.success('Modified!');
|
93 |
+
yield put({
|
94 |
+
type: 'getTenantInfo',
|
95 |
+
});
|
96 |
+
}
|
97 |
+
return retcode;
|
98 |
+
},
|
99 |
+
|
100 |
+
*factories_list({ payload = {} }, { call, put }) {
|
101 |
+
const { data } = yield call(userService.factories_list);
|
102 |
+
const { retcode, data: res } = data;
|
103 |
+
if (retcode === 0) {
|
104 |
+
yield put({
|
105 |
+
type: 'updateState',
|
106 |
+
payload: {
|
107 |
+
factoryList: res,
|
108 |
+
},
|
109 |
+
});
|
110 |
+
}
|
111 |
+
},
|
112 |
+
*llm_list({ payload = {} }, { call, put }) {
|
113 |
+
const { data } = yield call(userService.llm_list, payload);
|
114 |
+
const { retcode, data: res } = data;
|
115 |
+
if (retcode === 0) {
|
116 |
+
yield put({
|
117 |
+
type: 'updateState',
|
118 |
+
payload: {
|
119 |
+
llmInfo: res,
|
120 |
+
},
|
121 |
+
});
|
122 |
+
}
|
123 |
+
},
|
124 |
+
*my_llm({ payload = {} }, { call, put }) {
|
125 |
+
const { data } = yield call(userService.my_llm);
|
126 |
+
const { retcode, data: res } = data;
|
127 |
+
if (retcode === 0) {
|
128 |
+
yield put({
|
129 |
+
type: 'updateState',
|
130 |
+
payload: {
|
131 |
+
myLlmList: res,
|
132 |
+
},
|
133 |
+
});
|
134 |
+
}
|
135 |
+
},
|
136 |
+
*set_api_key({ payload = {} }, { call, put }) {
|
137 |
+
const { data } = yield call(userService.set_api_key, payload);
|
138 |
+
const { retcode } = data;
|
139 |
+
if (retcode === 0) {
|
140 |
+
message.success('Modified!');
|
141 |
+
yield put({ type: 'my_llm' });
|
142 |
+
yield put({ type: 'factories_list' });
|
143 |
+
yield put({
|
144 |
+
type: 'updateState',
|
145 |
+
});
|
146 |
+
}
|
147 |
+
return retcode;
|
148 |
+
},
|
149 |
+
},
|
150 |
+
};
|
151 |
+
export default model;
|
web/src/routes.ts
CHANGED
@@ -52,10 +52,6 @@ const routes = [
|
|
52 |
path: '/chat',
|
53 |
component: '@/pages/chat',
|
54 |
},
|
55 |
-
{
|
56 |
-
path: '/setting',
|
57 |
-
component: '@/pages/setting',
|
58 |
-
},
|
59 |
{
|
60 |
path: '/user-setting',
|
61 |
component: '@/pages/user-setting',
|
|
|
52 |
path: '/chat',
|
53 |
component: '@/pages/chat',
|
54 |
},
|
|
|
|
|
|
|
|
|
55 |
{
|
56 |
path: '/user-setting',
|
57 |
component: '@/pages/user-setting',
|