balibabu commited on
Commit
0cf2c67
·
1 Parent(s): b7adc24

feat: add pages to ChunkMethodModal (#143)

Browse files
Files changed (36) hide show
  1. web/src/assets/svg/chunk-method/law-01.svg +0 -0
  2. web/src/assets/svg/chunk-method/law-02.svg +0 -0
  3. web/src/assets/svg/chunk-method/law-03.svg +0 -0
  4. web/src/assets/svg/chunk-method/law-04.svg +0 -0
  5. web/src/assets/svg/chunk-method/manual-01.svg +0 -0
  6. web/src/assets/svg/chunk-method/manual-02.svg +0 -0
  7. web/src/assets/svg/chunk-method/manual-03.svg +0 -0
  8. web/src/assets/svg/chunk-method/manual-04.svg +0 -0
  9. web/src/assets/svg/chunk-method/one-01.svg +0 -0
  10. web/src/assets/svg/chunk-method/one-02.svg +0 -0
  11. web/src/assets/svg/chunk-method/one-03.svg +0 -0
  12. web/src/assets/svg/chunk-method/one-04.svg +0 -0
  13. web/src/assets/svg/chunk-method/paper-01.svg +0 -0
  14. web/src/assets/svg/chunk-method/paper-02.svg +0 -0
  15. web/src/components/max-token-number.tsx +32 -0
  16. web/src/hooks/documentHooks.ts +7 -1
  17. web/src/interfaces/database/knowledge.ts +7 -0
  18. web/src/interfaces/request/document.ts +12 -0
  19. web/src/pages/add-knowledge/components/knowledge-file/chunk-method-modal.tsx +198 -20
  20. web/src/pages/add-knowledge/components/knowledge-file/hooks.ts +25 -3
  21. web/src/pages/add-knowledge/components/knowledge-file/index.less +4 -0
  22. web/src/pages/add-knowledge/components/knowledge-file/index.tsx +3 -1
  23. web/src/pages/add-knowledge/components/knowledge-file/model.ts +7 -30
  24. web/src/pages/add-knowledge/components/knowledge-setting/configuration.tsx +3 -41
  25. web/src/pages/add-knowledge/components/knowledge-setting/model.ts +0 -2
  26. web/src/pages/add-knowledge/components/knowledge-setting/utils.ts +14 -11
  27. web/src/pages/add-knowledge/model.ts +0 -2
  28. web/src/pages/setting/CPwModal.tsx +0 -78
  29. web/src/pages/setting/List.tsx +0 -146
  30. web/src/pages/setting/SAKModal.tsx +0 -66
  31. web/src/pages/setting/SSModal.tsx +0 -144
  32. web/src/pages/setting/TntModal.tsx +0 -65
  33. web/src/pages/setting/index.less +0 -49
  34. web/src/pages/setting/index.tsx +0 -98
  35. web/src/pages/{setting → user-setting}/model.ts +151 -151
  36. 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
- (parserId: string, documentId: string) => {
 
 
 
 
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
- useFetchTenantInfo,
4
- useSelectParserList,
5
- } from '@/hooks/userSettingHook';
6
- import { Modal, Space, Tag } from 'antd';
7
- import React, { useEffect, useState } from 'react';
 
 
 
 
 
 
 
 
 
 
 
 
 
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: (parserId: string) => void;
 
 
 
16
  showModal?(): void;
17
- parser_id: string;
 
 
18
  }
19
 
 
 
20
  const ChunkMethodModal: React.FC<IProps> = ({
21
- parser_id,
22
  onOk,
23
  hideModal,
24
  visible,
 
 
25
  }) => {
26
- const [selectedTag, setSelectedTag] = useState('');
27
- const parserList = useSelectParserList();
28
-
29
- useFetchTenantInfo();
30
-
31
- useEffect(() => {
32
- setSelectedTag(parser_id);
33
- }, [parser_id]);
34
 
35
  const handleOk = async () => {
36
- onOk(selectedTag);
 
 
 
 
 
 
 
37
  };
38
 
39
- const handleChange = (tag: string, checked: boolean) => {
40
- const nextSelectedTag = checked ? tag : selectedTag;
41
- setSelectedTag(nextSelectedTag);
 
 
 
 
 
 
 
 
 
 
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 { useFetchTenantInfo } from '@/hooks/userSettingHook';
 
 
 
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
- parser_id={currentRecord.parser_id}
 
 
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
- setIsShowRenameModal(state, { payload }) {
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
- yield put({
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
- put({
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
- put({
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', 4),
9
  manual: getImageName('manual', 4),
10
- picture: getImageName('picture', 2),
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: { title: '', description: `<p>Only <b>PDF</b> is supported.</p><p>
 
 
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
- title: '',
106
- description: `
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
- title: '',
115
- description: `
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',