balibabu
commited on
Commit
·
04aba1b
1
Parent(s):
e1bc1d4
feat: prevent the user from entering the knowledge base if he is not logged in (#45)
Browse files- web/.umirc.ts +5 -8
- web/routes.js +0 -89
- web/src/constants/authorization.ts +3 -0
- web/src/constants/common.ts +0 -0
- web/src/hooks/authHook.ts +10 -0
- web/src/layouts/components/user/index.tsx +48 -33
- web/src/layouts/index.tsx +44 -33
- web/src/pages/add-knowledge/components/knowledge-chunk/model.ts +39 -45
- web/src/pages/add-knowledge/components/knowledge-file/model.ts +46 -44
- web/src/pages/knowledge/index.tsx +103 -81
- web/src/pages/knowledge/model.ts +9 -9
- web/src/pages/login/index.tsx +92 -70
- web/src/pages/login/model.ts +27 -22
- web/src/pages/setting/index.tsx +99 -84
- web/src/pages/setting/model.ts +55 -46
- web/src/routes.ts +43 -0
- web/src/utils/authorizationUtil.ts +43 -0
- web/src/utils/history.ts +3 -0
- web/src/utils/request.ts +21 -16
- web/src/wrappers/auth.tsx +10 -11
web/.umirc.ts
CHANGED
@@ -1,22 +1,20 @@
|
|
1 |
-
import { defineConfig } from
|
2 |
-
import routes from './routes'
|
3 |
|
4 |
export default defineConfig({
|
5 |
outputPath: 'dist',
|
6 |
// alias: { '@': './src' },
|
7 |
-
routes,
|
8 |
npmClient: 'npm',
|
9 |
base: '/',
|
|
|
10 |
publicPath: '/web/dist/',
|
11 |
esbuildMinifyIIFE: true,
|
12 |
-
icons: {
|
13 |
-
|
14 |
-
},
|
15 |
hash: true,
|
16 |
history: {
|
17 |
type: 'browser',
|
18 |
},
|
19 |
-
plugins: ['@react-dev-inspector/umi4-plugin','@umijs/plugins/dist/dva'
|
20 |
dva: {},
|
21 |
// proxy: {
|
22 |
// '/v1': {
|
@@ -26,4 +24,3 @@ export default defineConfig({
|
|
26 |
// },
|
27 |
// },
|
28 |
});
|
29 |
-
|
|
|
1 |
+
import { defineConfig } from 'umi';
|
2 |
+
import routes from './src/routes';
|
3 |
|
4 |
export default defineConfig({
|
5 |
outputPath: 'dist',
|
6 |
// alias: { '@': './src' },
|
|
|
7 |
npmClient: 'npm',
|
8 |
base: '/',
|
9 |
+
routes,
|
10 |
publicPath: '/web/dist/',
|
11 |
esbuildMinifyIIFE: true,
|
12 |
+
icons: {},
|
|
|
|
|
13 |
hash: true,
|
14 |
history: {
|
15 |
type: 'browser',
|
16 |
},
|
17 |
+
plugins: ['@react-dev-inspector/umi4-plugin', '@umijs/plugins/dist/dva'],
|
18 |
dva: {},
|
19 |
// proxy: {
|
20 |
// '/v1': {
|
|
|
24 |
// },
|
25 |
// },
|
26 |
});
|
|
web/routes.js
DELETED
@@ -1,89 +0,0 @@
|
|
1 |
-
|
2 |
-
|
3 |
-
const routes = [
|
4 |
-
{
|
5 |
-
path: '/login',
|
6 |
-
component: '@/pages/login',
|
7 |
-
layout: false
|
8 |
-
},
|
9 |
-
{
|
10 |
-
path: '/',
|
11 |
-
component: '@/layouts', // 默认页面
|
12 |
-
redirect: '/knowledge',
|
13 |
-
// wrappers: [
|
14 |
-
// '@/wrappers/auth',
|
15 |
-
// ]
|
16 |
-
},
|
17 |
-
|
18 |
-
{
|
19 |
-
id: 2,
|
20 |
-
name: '知识库',
|
21 |
-
icon: 'home',
|
22 |
-
auth: [3, 4, 100],
|
23 |
-
path: '/knowledge',
|
24 |
-
component: '@/pages/knowledge',
|
25 |
-
pathname: 'knowledge'
|
26 |
-
},
|
27 |
-
{
|
28 |
-
id: 2,
|
29 |
-
name: '知识库',
|
30 |
-
icon: 'home',
|
31 |
-
auth: [3, 4, 100],
|
32 |
-
path: '/knowledge/add/*',
|
33 |
-
component: '@/pages/add-knowledge',
|
34 |
-
pathname: 'knowledge',
|
35 |
-
// routes: [{
|
36 |
-
// id: 3,
|
37 |
-
// name: '设置',
|
38 |
-
// icon: 'home',
|
39 |
-
// auth: [3, 4, 100],
|
40 |
-
// path: '/knowledge/add/setting',
|
41 |
-
// component: '@/pages/setting',
|
42 |
-
// pathname: "setting"
|
43 |
-
// }, {
|
44 |
-
// id: 1,
|
45 |
-
// name: '文件',
|
46 |
-
// icon: 'file',
|
47 |
-
// auth: [3, 4, 100],
|
48 |
-
// path: '/knowledge/add/file',
|
49 |
-
// component: '@/pages/file',
|
50 |
-
// pathname: 'file'
|
51 |
-
// },]
|
52 |
-
},
|
53 |
-
{
|
54 |
-
id: 3,
|
55 |
-
name: '聊天',
|
56 |
-
icon: 'home',
|
57 |
-
auth: [3, 4, 100],
|
58 |
-
path: '/chat',
|
59 |
-
component: '@/pages/chat',
|
60 |
-
pathname: "chat"
|
61 |
-
},
|
62 |
-
{
|
63 |
-
id: 3,
|
64 |
-
name: '设置',
|
65 |
-
icon: 'home',
|
66 |
-
auth: [3, 4, 100],
|
67 |
-
path: '/setting',
|
68 |
-
component: '@/pages/setting',
|
69 |
-
pathname: "setting"
|
70 |
-
},
|
71 |
-
{
|
72 |
-
id: 1,
|
73 |
-
name: '文件',
|
74 |
-
icon: 'file',
|
75 |
-
auth: [3, 4, 100],
|
76 |
-
path: '/file',
|
77 |
-
component: '@/pages/file',
|
78 |
-
pathname: 'file'
|
79 |
-
},
|
80 |
-
{
|
81 |
-
path: '/*',
|
82 |
-
component: '@/pages/404',
|
83 |
-
layout: false
|
84 |
-
}
|
85 |
-
|
86 |
-
];
|
87 |
-
|
88 |
-
|
89 |
-
module.exports = routes;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
web/src/constants/authorization.ts
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
export const Authorization = 'Authorization';
|
2 |
+
export const Token = 'token';
|
3 |
+
export const UserInfo = 'userInfo';
|
web/src/constants/common.ts
ADDED
File without changes
|
web/src/hooks/authHook.ts
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import authorizationUtil from '@/utils/authorizationUtil';
|
2 |
+
import { useState } from 'react';
|
3 |
+
|
4 |
+
export const useAuth = () => {
|
5 |
+
const [isLogin, setIsLogin] = useState(
|
6 |
+
() => !!authorizationUtil.getAuthorization(),
|
7 |
+
);
|
8 |
+
|
9 |
+
return { isLogin };
|
10 |
+
};
|
web/src/layouts/components/user/index.tsx
CHANGED
@@ -1,38 +1,53 @@
|
|
1 |
-
import
|
2 |
import type { MenuProps } from 'antd';
|
3 |
-
import { Button, Dropdown
|
4 |
-
import {
|
5 |
-
import { useTranslation
|
|
|
6 |
|
7 |
const App: React.FC = () => {
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
27 |
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
|
|
|
|
37 |
|
38 |
-
export default App;
|
|
|
1 |
+
import authorizationUtil from '@/utils/authorizationUtil';
|
2 |
import type { MenuProps } from 'antd';
|
3 |
+
import { Button, Dropdown } from 'antd';
|
4 |
+
import React, { useMemo } from 'react';
|
5 |
+
import { useTranslation } from 'react-i18next';
|
6 |
+
import { history } from 'umi';
|
7 |
|
8 |
const App: React.FC = () => {
|
9 |
+
const { t } = useTranslation();
|
10 |
+
|
11 |
+
const logout = () => {
|
12 |
+
authorizationUtil.removeAll();
|
13 |
+
history.push('/login');
|
14 |
+
};
|
15 |
+
|
16 |
+
const toSetting = () => {
|
17 |
+
history.push('/setting');
|
18 |
+
};
|
19 |
+
|
20 |
+
const items: MenuProps['items'] = useMemo(() => {
|
21 |
+
return [
|
22 |
+
{
|
23 |
+
key: '1',
|
24 |
+
label: (
|
25 |
+
<Button type="text" onClick={logout}>
|
26 |
+
{t('header.logout')}
|
27 |
+
</Button>
|
28 |
+
),
|
29 |
+
},
|
30 |
+
{
|
31 |
+
key: '2',
|
32 |
+
label: (
|
33 |
+
<Button type="text" onClick={toSetting}>
|
34 |
+
{t('header.setting')}
|
35 |
+
</Button>
|
36 |
+
),
|
37 |
+
},
|
38 |
+
];
|
39 |
+
}, []);
|
40 |
|
41 |
+
return (
|
42 |
+
<>
|
43 |
+
<Dropdown menu={{ items }} placement="bottomLeft" arrow>
|
44 |
+
<img
|
45 |
+
style={{ width: '50px', height: '50px', borderRadius: '25px' }}
|
46 |
+
src="https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png"
|
47 |
+
/>
|
48 |
+
</Dropdown>
|
49 |
+
</>
|
50 |
+
);
|
51 |
+
};
|
52 |
|
53 |
+
export default App;
|
web/src/layouts/index.tsx
CHANGED
@@ -1,22 +1,18 @@
|
|
|
|
|
|
|
|
1 |
import React, { useEffect, useState } from 'react';
|
2 |
-
import {
|
3 |
-
import {
|
4 |
-
import classnames from 'classnames'
|
5 |
import '../locales/config';
|
6 |
-
import
|
7 |
-
import
|
8 |
-
RedditOutlined
|
9 |
-
} from '@ant-design/icons';
|
10 |
-
import { Layout, Button, theme, Space, } from 'antd';
|
11 |
-
import styles from './index.less'
|
12 |
-
import User from './components/user'
|
13 |
-
import { head } from 'lodash';
|
14 |
|
15 |
const { Header, Content } = Layout;
|
16 |
|
17 |
const App: React.FC = (props) => {
|
18 |
-
const { t } = useTranslation()
|
19 |
-
const navigate = useNavigate()
|
20 |
const {
|
21 |
token: { colorBgContainer, borderRadiusLG },
|
22 |
} = theme.useToken();
|
@@ -25,34 +21,49 @@ const App: React.FC = (props) => {
|
|
25 |
const location = useLocation();
|
26 |
useEffect(() => {
|
27 |
if (location.pathname !== '/') {
|
28 |
-
const path = location.pathname.split('/')
|
29 |
-
setCurrent(path[1]);
|
30 |
}
|
31 |
-
console.log(location.pathname.split('/'))
|
32 |
-
}, [location.pathname])
|
33 |
|
34 |
const handleChange = (path: string) => {
|
35 |
-
setCurrent(path)
|
36 |
navigate(path);
|
37 |
};
|
38 |
-
const tagsData = [
|
|
|
|
|
|
|
|
|
39 |
|
40 |
return (
|
41 |
-
<Layout className={styles.layout}
|
42 |
<Layout>
|
43 |
-
<Header
|
44 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
45 |
<img src={logo} alt="" style={{ height: 30, width: 30 }} />
|
46 |
<Space size={[0, 8]} wrap>
|
47 |
-
{tagsData.map((item) =>
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
|
|
|
|
|
|
|
|
54 |
</Space>
|
55 |
-
<User
|
56 |
</Header>
|
57 |
<Content
|
58 |
style={{
|
@@ -61,14 +72,14 @@ const App: React.FC = (props) => {
|
|
61 |
minHeight: 280,
|
62 |
background: colorBgContainer,
|
63 |
borderRadius: borderRadiusLG,
|
64 |
-
overflow: 'auto'
|
65 |
}}
|
66 |
>
|
67 |
<Outlet />
|
68 |
</Content>
|
69 |
</Layout>
|
70 |
-
</Layout
|
71 |
);
|
72 |
};
|
73 |
|
74 |
-
export default App;
|
|
|
1 |
+
import logo from '@/assets/logo.png';
|
2 |
+
import { Layout, Space, theme } from 'antd';
|
3 |
+
import classnames from 'classnames';
|
4 |
import React, { useEffect, useState } from 'react';
|
5 |
+
import { useTranslation } from 'react-i18next';
|
6 |
+
import { Outlet, useLocation, useNavigate } from 'umi';
|
|
|
7 |
import '../locales/config';
|
8 |
+
import User from './components/user';
|
9 |
+
import styles from './index.less';
|
|
|
|
|
|
|
|
|
|
|
|
|
10 |
|
11 |
const { Header, Content } = Layout;
|
12 |
|
13 |
const App: React.FC = (props) => {
|
14 |
+
const { t } = useTranslation();
|
15 |
+
const navigate = useNavigate();
|
16 |
const {
|
17 |
token: { colorBgContainer, borderRadiusLG },
|
18 |
} = theme.useToken();
|
|
|
21 |
const location = useLocation();
|
22 |
useEffect(() => {
|
23 |
if (location.pathname !== '/') {
|
24 |
+
const path = location.pathname.split('/');
|
25 |
+
// setCurrent(path[1]);
|
26 |
}
|
27 |
+
console.log(location.pathname.split('/'));
|
28 |
+
}, [location.pathname]);
|
29 |
|
30 |
const handleChange = (path: string) => {
|
31 |
+
// setCurrent(path)
|
32 |
navigate(path);
|
33 |
};
|
34 |
+
const tagsData = [
|
35 |
+
{ path: '/knowledge', name: 'knowledge' },
|
36 |
+
{ path: '/chat', name: 'chat' },
|
37 |
+
{ path: '/file', name: 'file' },
|
38 |
+
];
|
39 |
|
40 |
return (
|
41 |
+
<Layout className={styles.layout}>
|
42 |
<Layout>
|
43 |
+
<Header
|
44 |
+
style={{
|
45 |
+
padding: '0 8px',
|
46 |
+
background: colorBgContainer,
|
47 |
+
display: 'flex',
|
48 |
+
justifyContent: 'space-between',
|
49 |
+
alignItems: 'center',
|
50 |
+
}}
|
51 |
+
>
|
52 |
<img src={logo} alt="" style={{ height: 30, width: 30 }} />
|
53 |
<Space size={[0, 8]} wrap>
|
54 |
+
{tagsData.map((item) => (
|
55 |
+
<span
|
56 |
+
key={item.name}
|
57 |
+
className={classnames(styles['tag'], {
|
58 |
+
[styles['checked']]: current === item.name,
|
59 |
+
})}
|
60 |
+
onClick={() => handleChange(item.path)}
|
61 |
+
>
|
62 |
+
{item.name}
|
63 |
+
</span>
|
64 |
+
))}
|
65 |
</Space>
|
66 |
+
<User></User>
|
67 |
</Header>
|
68 |
<Content
|
69 |
style={{
|
|
|
72 |
minHeight: 280,
|
73 |
background: colorBgContainer,
|
74 |
borderRadius: borderRadiusLG,
|
75 |
+
overflow: 'auto',
|
76 |
}}
|
77 |
>
|
78 |
<Outlet />
|
79 |
</Content>
|
80 |
</Layout>
|
81 |
+
</Layout>
|
82 |
);
|
83 |
};
|
84 |
|
85 |
+
export default App;
|
web/src/pages/add-knowledge/components/knowledge-chunk/model.ts
CHANGED
@@ -1,6 +1,5 @@
|
|
1 |
-
import { Effect, Reducer, Subscription } from 'umi'
|
2 |
-
import { message } from 'antd';
|
3 |
import kbService from '@/services/kbService';
|
|
|
4 |
|
5 |
export interface chunkModelState {
|
6 |
loading: boolean;
|
@@ -9,7 +8,7 @@ export interface chunkModelState {
|
|
9 |
isShowCreateModal: boolean;
|
10 |
chunk_id: string;
|
11 |
doc_id: string;
|
12 |
-
chunkInfo: any
|
13 |
}
|
14 |
export interface chunkgModelType {
|
15 |
namespace: 'chunkModel';
|
@@ -24,7 +23,7 @@ export interface chunkgModelType {
|
|
24 |
reducers: {
|
25 |
updateState: Reducer<chunkModelState>;
|
26 |
};
|
27 |
-
subscriptions: { setup: Subscription };
|
28 |
}
|
29 |
const Model: chunkgModelType = {
|
30 |
namespace: 'chunkModel',
|
@@ -35,91 +34,86 @@ const Model: chunkgModelType = {
|
|
35 |
isShowCreateModal: false,
|
36 |
chunk_id: '',
|
37 |
doc_id: '',
|
38 |
-
chunkInfo: {}
|
39 |
-
},
|
40 |
-
subscriptions: {
|
41 |
-
setup({ dispatch, history }) {
|
42 |
-
history.listen(location => {
|
43 |
-
console.log(location)
|
44 |
-
});
|
45 |
-
}
|
46 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
47 |
effects: {
|
48 |
-
*
|
49 |
const { data, response } = yield call(kbService.chunk_list, payload);
|
50 |
|
51 |
-
const { retcode, data: res, retmsg } = data
|
52 |
if (retcode === 0) {
|
53 |
-
console.log(res)
|
54 |
yield put({
|
55 |
type: 'updateState',
|
56 |
payload: {
|
57 |
data: res.chunks,
|
58 |
total: res.total,
|
59 |
-
loading: false
|
60 |
-
}
|
61 |
});
|
62 |
-
callback && callback()
|
63 |
-
|
64 |
}
|
65 |
},
|
66 |
*switch_chunk({ payload = {}, callback }, { call, put }) {
|
67 |
const { data, response } = yield call(kbService.switch_chunk, payload);
|
68 |
-
const { retcode, data: res, retmsg } = data
|
69 |
if (retcode === 0) {
|
70 |
-
callback && callback()
|
71 |
-
|
72 |
}
|
73 |
},
|
74 |
*rm_chunk({ payload = {}, callback }, { call, put }) {
|
75 |
-
console.log('shanchu')
|
76 |
const { data, response } = yield call(kbService.rm_chunk, payload);
|
77 |
-
const { retcode, data: res, retmsg } = data
|
78 |
if (retcode === 0) {
|
79 |
-
callback && callback()
|
80 |
-
|
81 |
}
|
82 |
},
|
83 |
-
*
|
84 |
const { data, response } = yield call(kbService.get_chunk, payload);
|
85 |
-
const { retcode, data: res, retmsg } = data
|
86 |
if (retcode === 0) {
|
87 |
-
|
88 |
yield put({
|
89 |
type: 'updateState',
|
90 |
payload: {
|
91 |
-
chunkInfo: res
|
92 |
-
}
|
93 |
});
|
94 |
-
callback && callback(res)
|
95 |
-
|
96 |
}
|
97 |
},
|
98 |
*create_hunk({ payload = {} }, { call, put }) {
|
99 |
yield put({
|
100 |
type: 'updateState',
|
101 |
payload: {
|
102 |
-
loading: true
|
103 |
-
}
|
104 |
});
|
105 |
-
let service = kbService.create_chunk
|
106 |
if (payload.chunk_id) {
|
107 |
-
service = kbService.set_chunk
|
108 |
}
|
109 |
const { data, response } = yield call(service, payload);
|
110 |
-
const { retcode, data: res, retmsg } = data
|
111 |
yield put({
|
112 |
type: 'updateState',
|
113 |
payload: {
|
114 |
-
loading: false
|
115 |
-
}
|
116 |
});
|
117 |
if (retcode === 0) {
|
118 |
yield put({
|
119 |
type: 'updateState',
|
120 |
payload: {
|
121 |
-
isShowCreateModal: false
|
122 |
-
}
|
123 |
});
|
124 |
}
|
125 |
},
|
@@ -128,9 +122,9 @@ const Model: chunkgModelType = {
|
|
128 |
updateState(state, { payload }) {
|
129 |
return {
|
130 |
...state,
|
131 |
-
...payload
|
132 |
};
|
133 |
-
}
|
134 |
-
}
|
135 |
};
|
136 |
export default Model;
|
|
|
|
|
|
|
1 |
import kbService from '@/services/kbService';
|
2 |
+
import { Effect, Reducer } from 'umi';
|
3 |
|
4 |
export interface chunkModelState {
|
5 |
loading: boolean;
|
|
|
8 |
isShowCreateModal: boolean;
|
9 |
chunk_id: string;
|
10 |
doc_id: string;
|
11 |
+
chunkInfo: any;
|
12 |
}
|
13 |
export interface chunkgModelType {
|
14 |
namespace: 'chunkModel';
|
|
|
23 |
reducers: {
|
24 |
updateState: Reducer<chunkModelState>;
|
25 |
};
|
26 |
+
// subscriptions: { setup: Subscription };
|
27 |
}
|
28 |
const Model: chunkgModelType = {
|
29 |
namespace: 'chunkModel',
|
|
|
34 |
isShowCreateModal: false,
|
35 |
chunk_id: '',
|
36 |
doc_id: '',
|
37 |
+
chunkInfo: {},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
38 |
},
|
39 |
+
// subscriptions: {
|
40 |
+
// setup({ dispatch, history }) {
|
41 |
+
// history.listen(location => {
|
42 |
+
// console.log(location)
|
43 |
+
// });
|
44 |
+
// }
|
45 |
+
// },
|
46 |
effects: {
|
47 |
+
*chunk_list({ payload = {}, callback }, { call, put }) {
|
48 |
const { data, response } = yield call(kbService.chunk_list, payload);
|
49 |
|
50 |
+
const { retcode, data: res, retmsg } = data;
|
51 |
if (retcode === 0) {
|
52 |
+
console.log(res);
|
53 |
yield put({
|
54 |
type: 'updateState',
|
55 |
payload: {
|
56 |
data: res.chunks,
|
57 |
total: res.total,
|
58 |
+
loading: false,
|
59 |
+
},
|
60 |
});
|
61 |
+
callback && callback();
|
|
|
62 |
}
|
63 |
},
|
64 |
*switch_chunk({ payload = {}, callback }, { call, put }) {
|
65 |
const { data, response } = yield call(kbService.switch_chunk, payload);
|
66 |
+
const { retcode, data: res, retmsg } = data;
|
67 |
if (retcode === 0) {
|
68 |
+
callback && callback();
|
|
|
69 |
}
|
70 |
},
|
71 |
*rm_chunk({ payload = {}, callback }, { call, put }) {
|
72 |
+
console.log('shanchu');
|
73 |
const { data, response } = yield call(kbService.rm_chunk, payload);
|
74 |
+
const { retcode, data: res, retmsg } = data;
|
75 |
if (retcode === 0) {
|
76 |
+
callback && callback();
|
|
|
77 |
}
|
78 |
},
|
79 |
+
*get_chunk({ payload = {}, callback }, { call, put }) {
|
80 |
const { data, response } = yield call(kbService.get_chunk, payload);
|
81 |
+
const { retcode, data: res, retmsg } = data;
|
82 |
if (retcode === 0) {
|
|
|
83 |
yield put({
|
84 |
type: 'updateState',
|
85 |
payload: {
|
86 |
+
chunkInfo: res,
|
87 |
+
},
|
88 |
});
|
89 |
+
callback && callback(res);
|
|
|
90 |
}
|
91 |
},
|
92 |
*create_hunk({ payload = {} }, { call, put }) {
|
93 |
yield put({
|
94 |
type: 'updateState',
|
95 |
payload: {
|
96 |
+
loading: true,
|
97 |
+
},
|
98 |
});
|
99 |
+
let service = kbService.create_chunk;
|
100 |
if (payload.chunk_id) {
|
101 |
+
service = kbService.set_chunk;
|
102 |
}
|
103 |
const { data, response } = yield call(service, payload);
|
104 |
+
const { retcode, data: res, retmsg } = data;
|
105 |
yield put({
|
106 |
type: 'updateState',
|
107 |
payload: {
|
108 |
+
loading: false,
|
109 |
+
},
|
110 |
});
|
111 |
if (retcode === 0) {
|
112 |
yield put({
|
113 |
type: 'updateState',
|
114 |
payload: {
|
115 |
+
isShowCreateModal: false,
|
116 |
+
},
|
117 |
});
|
118 |
}
|
119 |
},
|
|
|
122 |
updateState(state, { payload }) {
|
123 |
return {
|
124 |
...state,
|
125 |
+
...payload,
|
126 |
};
|
127 |
+
},
|
128 |
+
},
|
129 |
};
|
130 |
export default Model;
|
web/src/pages/add-knowledge/components/knowledge-file/model.ts
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
-
import { message } from 'antd';
|
2 |
-
import { Effect, Reducer, Subscription } from 'umi'
|
3 |
import kbService from '@/services/kbService';
|
|
|
|
|
4 |
|
5 |
export interface kFModelState {
|
6 |
isShowCEFwModal: boolean;
|
@@ -8,7 +8,7 @@ export interface kFModelState {
|
|
8 |
isShowSegmentSetModal: boolean;
|
9 |
loading: boolean;
|
10 |
tenantIfo: any;
|
11 |
-
data: any[]
|
12 |
}
|
13 |
export interface kFModelType {
|
14 |
namespace: 'kFModel';
|
@@ -36,60 +36,60 @@ const Model: kFModelType = {
|
|
36 |
isShowSegmentSetModal: false,
|
37 |
loading: false,
|
38 |
tenantIfo: {},
|
39 |
-
data: []
|
40 |
},
|
41 |
subscriptions: {
|
42 |
setup({ dispatch, history }) {
|
43 |
-
history.listen(location => {
|
44 |
-
|
45 |
-
}
|
46 |
},
|
47 |
effects: {
|
48 |
-
*
|
49 |
const { data, response } = yield call(kbService.createKb, payload);
|
50 |
-
const { retcode, data: res, retmsg } = data
|
51 |
if (retcode === 0) {
|
52 |
-
|
53 |
message.success('创建成功!');
|
54 |
}
|
55 |
},
|
56 |
-
*
|
57 |
const { data, response } = yield call(kbService.updateKb, payload);
|
58 |
-
const { retcode, data: res, retmsg } = data
|
59 |
if (retcode === 0) {
|
60 |
message.success('修改成功!');
|
61 |
-
|
62 |
}
|
63 |
},
|
64 |
*getKfDetail({ payload = {}, callback }, { call, put }) {
|
65 |
const { data, response } = yield call(kbService.get_kb_detail, payload);
|
66 |
-
const { retcode, data: res, retmsg } = data
|
67 |
if (retcode === 0) {
|
68 |
// localStorage.setItem('userInfo',res.)
|
69 |
-
callback && callback(res)
|
70 |
}
|
71 |
},
|
72 |
*getKfList({ payload = {} }, { call, put }) {
|
73 |
yield put({
|
74 |
type: 'updateState',
|
75 |
payload: {
|
76 |
-
loading: true
|
77 |
-
}
|
78 |
});
|
79 |
-
const { data, response } = yield call(
|
80 |
-
|
|
|
|
|
|
|
81 |
yield put({
|
82 |
type: 'updateState',
|
83 |
payload: {
|
84 |
-
loading: false
|
85 |
-
}
|
86 |
});
|
87 |
if (retcode === 0) {
|
88 |
yield put({
|
89 |
type: 'updateState',
|
90 |
payload: {
|
91 |
-
data: res
|
92 |
-
}
|
93 |
});
|
94 |
}
|
95 |
},
|
@@ -97,58 +97,60 @@ const Model: kFModelType = {
|
|
97 |
yield put({
|
98 |
type: 'updateState',
|
99 |
payload: {
|
100 |
-
loading: true
|
101 |
-
}
|
102 |
});
|
103 |
-
const { data, response } = yield call(
|
104 |
-
|
|
|
|
|
|
|
105 |
if (retcode === 0) {
|
106 |
message.success('修改成功!');
|
107 |
yield put({
|
108 |
type: 'updateState',
|
109 |
payload: {
|
110 |
-
loading: false
|
111 |
-
}
|
112 |
});
|
113 |
-
callback && callback()
|
114 |
}
|
115 |
-
|
116 |
},
|
117 |
*document_rm({ payload = {}, callback }, { call, put }) {
|
118 |
const { data, response } = yield call(kbService.document_rm, payload);
|
119 |
-
const { retcode, data: res, retmsg } = data
|
120 |
if (retcode === 0) {
|
121 |
message.success('删除成功!');
|
122 |
-
callback && callback()
|
123 |
}
|
124 |
-
|
125 |
},
|
126 |
*document_create({ payload = {}, callback }, { call, put }) {
|
127 |
const { data, response } = yield call(kbService.document_create, payload);
|
128 |
-
const { retcode, data: res, retmsg } = data
|
129 |
if (retcode === 0) {
|
130 |
message.success('创建成功!');
|
131 |
-
callback && callback()
|
132 |
}
|
133 |
-
|
134 |
},
|
135 |
*document_change_parser({ payload = {}, callback }, { call, put }) {
|
136 |
-
const { data, response } = yield call(
|
137 |
-
|
|
|
|
|
|
|
138 |
if (retcode === 0) {
|
139 |
message.success('修改成功!');
|
140 |
-
callback && callback()
|
141 |
}
|
142 |
-
|
143 |
},
|
144 |
},
|
145 |
reducers: {
|
146 |
updateState(state, { payload }) {
|
147 |
return {
|
148 |
...state,
|
149 |
-
...payload
|
150 |
};
|
151 |
-
}
|
152 |
-
}
|
153 |
};
|
154 |
export default Model;
|
|
|
|
|
|
|
1 |
import kbService from '@/services/kbService';
|
2 |
+
import { message } from 'antd';
|
3 |
+
import { Effect, Reducer, Subscription } from 'umi';
|
4 |
|
5 |
export interface kFModelState {
|
6 |
isShowCEFwModal: boolean;
|
|
|
8 |
isShowSegmentSetModal: boolean;
|
9 |
loading: boolean;
|
10 |
tenantIfo: any;
|
11 |
+
data: any[];
|
12 |
}
|
13 |
export interface kFModelType {
|
14 |
namespace: 'kFModel';
|
|
|
36 |
isShowSegmentSetModal: false,
|
37 |
loading: false,
|
38 |
tenantIfo: {},
|
39 |
+
data: [],
|
40 |
},
|
41 |
subscriptions: {
|
42 |
setup({ dispatch, history }) {
|
43 |
+
history.listen((location) => {});
|
44 |
+
},
|
|
|
45 |
},
|
46 |
effects: {
|
47 |
+
*createKf({ payload = {}, callback }, { call, put }) {
|
48 |
const { data, response } = yield call(kbService.createKb, payload);
|
49 |
+
const { retcode, data: res, retmsg } = data;
|
50 |
if (retcode === 0) {
|
|
|
51 |
message.success('创建成功!');
|
52 |
}
|
53 |
},
|
54 |
+
*updateKf({ payload = {}, callback }, { call, put }) {
|
55 |
const { data, response } = yield call(kbService.updateKb, payload);
|
56 |
+
const { retcode, data: res, retmsg } = data;
|
57 |
if (retcode === 0) {
|
58 |
message.success('修改成功!');
|
|
|
59 |
}
|
60 |
},
|
61 |
*getKfDetail({ payload = {}, callback }, { call, put }) {
|
62 |
const { data, response } = yield call(kbService.get_kb_detail, payload);
|
63 |
+
const { retcode, data: res, retmsg } = data;
|
64 |
if (retcode === 0) {
|
65 |
// localStorage.setItem('userInfo',res.)
|
66 |
+
callback && callback(res);
|
67 |
}
|
68 |
},
|
69 |
*getKfList({ payload = {} }, { call, put }) {
|
70 |
yield put({
|
71 |
type: 'updateState',
|
72 |
payload: {
|
73 |
+
loading: true,
|
74 |
+
},
|
75 |
});
|
76 |
+
const { data, response } = yield call(
|
77 |
+
kbService.get_document_list,
|
78 |
+
payload,
|
79 |
+
);
|
80 |
+
const { retcode, data: res, retmsg } = data;
|
81 |
yield put({
|
82 |
type: 'updateState',
|
83 |
payload: {
|
84 |
+
loading: false,
|
85 |
+
},
|
86 |
});
|
87 |
if (retcode === 0) {
|
88 |
yield put({
|
89 |
type: 'updateState',
|
90 |
payload: {
|
91 |
+
data: res,
|
92 |
+
},
|
93 |
});
|
94 |
}
|
95 |
},
|
|
|
97 |
yield put({
|
98 |
type: 'updateState',
|
99 |
payload: {
|
100 |
+
loading: true,
|
101 |
+
},
|
102 |
});
|
103 |
+
const { data, response } = yield call(
|
104 |
+
kbService.document_change_status,
|
105 |
+
payload,
|
106 |
+
);
|
107 |
+
const { retcode, data: res, retmsg } = data;
|
108 |
if (retcode === 0) {
|
109 |
message.success('修改成功!');
|
110 |
yield put({
|
111 |
type: 'updateState',
|
112 |
payload: {
|
113 |
+
loading: false,
|
114 |
+
},
|
115 |
});
|
116 |
+
callback && callback();
|
117 |
}
|
|
|
118 |
},
|
119 |
*document_rm({ payload = {}, callback }, { call, put }) {
|
120 |
const { data, response } = yield call(kbService.document_rm, payload);
|
121 |
+
const { retcode, data: res, retmsg } = data;
|
122 |
if (retcode === 0) {
|
123 |
message.success('删除成功!');
|
124 |
+
callback && callback();
|
125 |
}
|
|
|
126 |
},
|
127 |
*document_create({ payload = {}, callback }, { call, put }) {
|
128 |
const { data, response } = yield call(kbService.document_create, payload);
|
129 |
+
const { retcode, data: res, retmsg } = data;
|
130 |
if (retcode === 0) {
|
131 |
message.success('创建成功!');
|
132 |
+
callback && callback();
|
133 |
}
|
|
|
134 |
},
|
135 |
*document_change_parser({ payload = {}, callback }, { call, put }) {
|
136 |
+
const { data, response } = yield call(
|
137 |
+
kbService.document_change_parser,
|
138 |
+
payload,
|
139 |
+
);
|
140 |
+
const { retcode, data: res, retmsg } = data;
|
141 |
if (retcode === 0) {
|
142 |
message.success('修改成功!');
|
143 |
+
callback && callback();
|
144 |
}
|
|
|
145 |
},
|
146 |
},
|
147 |
reducers: {
|
148 |
updateState(state, { payload }) {
|
149 |
return {
|
150 |
...state,
|
151 |
+
...payload,
|
152 |
};
|
153 |
+
},
|
154 |
+
},
|
155 |
};
|
156 |
export default Model;
|
web/src/pages/knowledge/index.tsx
CHANGED
@@ -1,109 +1,131 @@
|
|
1 |
-
import
|
2 |
-
import {
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
import
|
|
|
|
|
|
|
|
|
8 |
interface KnowledgeProps {
|
9 |
dispatch: Dispatch;
|
10 |
-
knowledgeModel: knowledgeModelState
|
11 |
}
|
12 |
const Index: React.FC<KnowledgeProps> = ({ knowledgeModel, dispatch }) => {
|
13 |
-
const navigate = useNavigate()
|
14 |
// const [datas, setDatas] = useState(data)
|
15 |
-
const { data = [] } = knowledgeModel
|
16 |
-
console.log(knowledgeModel)
|
|
|
|
|
|
|
17 |
const confirm = (id: string) => {
|
18 |
dispatch({
|
19 |
type: 'knowledgeModel/rmKb',
|
20 |
payload: {
|
21 |
-
kb_id: id
|
22 |
},
|
23 |
callback: () => {
|
24 |
dispatch({
|
25 |
type: 'knowledgeModel/getList',
|
26 |
-
payload: {
|
27 |
-
|
28 |
-
}
|
29 |
});
|
30 |
-
}
|
31 |
});
|
32 |
};
|
33 |
const handleAddKnowledge = () => {
|
34 |
navigate(`add/setting?activeKey=setting`);
|
35 |
-
}
|
36 |
const handleEditKnowledge = (id: string) => {
|
37 |
navigate(`add/setting?activeKey=file&id=${id}`);
|
38 |
-
}
|
39 |
useEffect(() => {
|
40 |
dispatch({
|
41 |
type: 'knowledgeModel/getList',
|
42 |
-
payload: {
|
43 |
-
|
44 |
-
}
|
45 |
});
|
46 |
-
}, [])
|
47 |
-
return (
|
48 |
-
|
49 |
-
<
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
56 |
>
|
57 |
-
<
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
</
|
87 |
-
<
|
88 |
-
<
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
96 |
</div>
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
</>
|
106 |
-
)
|
107 |
};
|
108 |
|
109 |
-
export default connect(({ knowledgeModel, loading }) => ({
|
|
|
|
|
|
|
|
1 |
+
import { formatDate } from '@/utils/date';
|
2 |
+
import {
|
3 |
+
DeleteOutlined,
|
4 |
+
MinusSquareOutlined,
|
5 |
+
PlusOutlined,
|
6 |
+
} from '@ant-design/icons';
|
7 |
+
import { Card, Col, FloatButton, Popconfirm, Row } from 'antd';
|
8 |
+
import React, { useEffect } from 'react';
|
9 |
+
import { Dispatch, connect, useNavigate } from 'umi';
|
10 |
+
import styles from './index.less';
|
11 |
+
import type { knowledgeModelState } from './model';
|
12 |
interface KnowledgeProps {
|
13 |
dispatch: Dispatch;
|
14 |
+
knowledgeModel: knowledgeModelState;
|
15 |
}
|
16 |
const Index: React.FC<KnowledgeProps> = ({ knowledgeModel, dispatch }) => {
|
17 |
+
const navigate = useNavigate();
|
18 |
// const [datas, setDatas] = useState(data)
|
19 |
+
const { data = [] } = knowledgeModel;
|
20 |
+
console.log(knowledgeModel);
|
21 |
+
|
22 |
+
// const x = useSelector((state) => state.knowledgeModel);
|
23 |
+
|
24 |
const confirm = (id: string) => {
|
25 |
dispatch({
|
26 |
type: 'knowledgeModel/rmKb',
|
27 |
payload: {
|
28 |
+
kb_id: id,
|
29 |
},
|
30 |
callback: () => {
|
31 |
dispatch({
|
32 |
type: 'knowledgeModel/getList',
|
33 |
+
payload: {},
|
|
|
|
|
34 |
});
|
35 |
+
},
|
36 |
});
|
37 |
};
|
38 |
const handleAddKnowledge = () => {
|
39 |
navigate(`add/setting?activeKey=setting`);
|
40 |
+
};
|
41 |
const handleEditKnowledge = (id: string) => {
|
42 |
navigate(`add/setting?activeKey=file&id=${id}`);
|
43 |
+
};
|
44 |
useEffect(() => {
|
45 |
dispatch({
|
46 |
type: 'knowledgeModel/getList',
|
47 |
+
payload: {},
|
|
|
|
|
48 |
});
|
49 |
+
}, []);
|
50 |
+
return (
|
51 |
+
<>
|
52 |
+
<div className={styles.knowledge}>
|
53 |
+
<FloatButton
|
54 |
+
onClick={handleAddKnowledge}
|
55 |
+
icon={<PlusOutlined />}
|
56 |
+
type="primary"
|
57 |
+
style={{ right: 24, top: 100 }}
|
58 |
+
/>
|
59 |
+
<Row gutter={{ xs: 8, sm: 16, md: 24, lg: 32 }}>
|
60 |
+
{data.map((item: any) => {
|
61 |
+
return (
|
62 |
+
<Col
|
63 |
+
className="gutter-row"
|
64 |
+
key={item.name}
|
65 |
+
xs={24}
|
66 |
+
sm={12}
|
67 |
+
md={8}
|
68 |
+
lg={6}
|
69 |
>
|
70 |
+
<Card
|
71 |
+
className={styles.card}
|
72 |
+
onClick={() => {
|
73 |
+
handleEditKnowledge(item.id);
|
74 |
+
}}
|
75 |
+
>
|
76 |
+
<div className={styles.container}>
|
77 |
+
<div className={styles.content}>
|
78 |
+
<span className={styles.context}>{item.name}</span>
|
79 |
+
<span className={styles.delete}>
|
80 |
+
<Popconfirm
|
81 |
+
title="Delete the task"
|
82 |
+
description="Are you sure to delete this task?"
|
83 |
+
onConfirm={(e: any) => {
|
84 |
+
e.stopPropagation();
|
85 |
+
e.nativeEvent.stopImmediatePropagation();
|
86 |
+
confirm(item.id);
|
87 |
+
}}
|
88 |
+
okText="Yes"
|
89 |
+
cancelText="No"
|
90 |
+
>
|
91 |
+
<DeleteOutlined
|
92 |
+
onClick={(e) => {
|
93 |
+
e.stopPropagation();
|
94 |
+
e.nativeEvent.stopImmediatePropagation();
|
95 |
+
}}
|
96 |
+
/>
|
97 |
+
</Popconfirm>
|
98 |
+
</span>
|
99 |
+
</div>
|
100 |
+
<div className={styles.footer}>
|
101 |
+
<span className={styles.text}>
|
102 |
+
<MinusSquareOutlined />
|
103 |
+
{item.doc_num}文档
|
104 |
+
</span>
|
105 |
+
<span className={styles.text}>
|
106 |
+
<MinusSquareOutlined />
|
107 |
+
{item.chunk_num}个
|
108 |
+
</span>
|
109 |
+
<span className={styles.text}>
|
110 |
+
<MinusSquareOutlined />
|
111 |
+
{item.token_num}千字符
|
112 |
+
</span>
|
113 |
+
<span style={{ float: 'right' }}>
|
114 |
+
{formatDate(item.update_date)}
|
115 |
+
</span>
|
116 |
+
</div>
|
117 |
</div>
|
118 |
+
</Card>
|
119 |
+
</Col>
|
120 |
+
);
|
121 |
+
})}
|
122 |
+
</Row>
|
123 |
+
</div>
|
124 |
+
</>
|
125 |
+
);
|
|
|
|
|
126 |
};
|
127 |
|
128 |
+
export default connect(({ knowledgeModel, loading }) => ({
|
129 |
+
knowledgeModel,
|
130 |
+
loading,
|
131 |
+
}))(Index);
|
web/src/pages/knowledge/model.ts
CHANGED
@@ -1,5 +1,5 @@
|
|
1 |
import kbService from '@/services/kbService';
|
2 |
-
import { Effect, Reducer
|
3 |
|
4 |
export interface knowledgeModelState {
|
5 |
loading: boolean;
|
@@ -15,7 +15,7 @@ export interface knowledgegModelType {
|
|
15 |
reducers: {
|
16 |
updateState: Reducer<knowledgeModelState>;
|
17 |
};
|
18 |
-
subscriptions: { setup: Subscription };
|
19 |
}
|
20 |
const Model: knowledgegModelType = {
|
21 |
namespace: 'knowledgeModel',
|
@@ -23,13 +23,13 @@ const Model: knowledgegModelType = {
|
|
23 |
loading: false,
|
24 |
data: [],
|
25 |
},
|
26 |
-
subscriptions: {
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
},
|
33 |
effects: {
|
34 |
*rmKb({ payload = {}, callback }, { call, put }) {
|
35 |
const { data, response } = yield call(kbService.rmKb, payload);
|
|
|
1 |
import kbService from '@/services/kbService';
|
2 |
+
import { Effect, Reducer } from 'umi';
|
3 |
|
4 |
export interface knowledgeModelState {
|
5 |
loading: boolean;
|
|
|
15 |
reducers: {
|
16 |
updateState: Reducer<knowledgeModelState>;
|
17 |
};
|
18 |
+
// subscriptions: { setup: Subscription };
|
19 |
}
|
20 |
const Model: knowledgegModelType = {
|
21 |
namespace: 'knowledgeModel',
|
|
|
23 |
loading: false,
|
24 |
data: [],
|
25 |
},
|
26 |
+
// subscriptions: {
|
27 |
+
// setup({ dispatch, history }) {
|
28 |
+
// history.listen((location) => {
|
29 |
+
// console.log(location);
|
30 |
+
// });
|
31 |
+
// },
|
32 |
+
// },
|
33 |
effects: {
|
34 |
*rmKb({ payload = {}, callback }, { call, put }) {
|
35 |
const { data, response } = yield call(kbService.rmKb, payload);
|
web/src/pages/login/index.tsx
CHANGED
@@ -1,19 +1,18 @@
|
|
1 |
-
import {
|
2 |
-
import {
|
|
|
|
|
3 |
import styles from './index.less';
|
4 |
-
import { rsaPsw } from '@/utils'
|
5 |
-
import { useState, useEffect, FC } from 'react';
|
6 |
|
7 |
interface LoginProps {
|
8 |
dispatch: Dispatch;
|
9 |
}
|
10 |
-
const View: FC<LoginProps> = ({
|
11 |
-
|
12 |
-
|
13 |
-
const [title, setTitle] = useState('login')
|
14 |
const changeTitle = () => {
|
15 |
-
setTitle((title) => title === 'login' ? 'register' : 'login')
|
16 |
-
}
|
17 |
const [form] = Form.useForm();
|
18 |
const [checkNick, setCheckNick] = useState(false);
|
19 |
|
@@ -25,15 +24,17 @@ const View: FC<LoginProps> = ({
|
|
25 |
try {
|
26 |
const params = await form.validateFields();
|
27 |
|
28 |
-
var rsaPassWord = rsaPsw(params.password)
|
29 |
if (title === 'login') {
|
30 |
-
dispatch({
|
31 |
type: 'loginModel/login',
|
32 |
payload: {
|
33 |
email: params.email,
|
34 |
-
password: rsaPassWord
|
35 |
-
}
|
36 |
});
|
|
|
|
|
37 |
} else {
|
38 |
dispatch({
|
39 |
type: 'loginModel/register',
|
@@ -43,8 +44,8 @@ const View: FC<LoginProps> = ({
|
|
43 |
password: rsaPassWord,
|
44 |
},
|
45 |
callback() {
|
46 |
-
setTitle('login')
|
47 |
-
}
|
48 |
});
|
49 |
}
|
50 |
} catch (errorInfo) {
|
@@ -56,103 +57,124 @@ const View: FC<LoginProps> = ({
|
|
56 |
// wrapperCol: { span: 8 },
|
57 |
};
|
58 |
|
59 |
-
|
60 |
const toGoogle = () => {
|
61 |
-
window.location.href =
|
62 |
-
|
|
|
63 |
return (
|
64 |
<div className={styles.loginPage}>
|
65 |
-
|
66 |
<div className={styles.loginLeft}>
|
67 |
<div className={styles.modal}>
|
68 |
<div className={styles.loginTitle}>
|
69 |
-
<div>
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
</span>
|
75 |
</div>
|
76 |
|
77 |
-
<Form
|
|
|
|
|
|
|
|
|
|
|
78 |
<Form.Item
|
79 |
{...formItemLayout}
|
80 |
name="email"
|
81 |
label="Email"
|
82 |
rules={[{ required: true, message: 'Please input value' }]}
|
83 |
>
|
84 |
-
<Input size=
|
85 |
</Form.Item>
|
86 |
-
{
|
87 |
-
|
88 |
{...formItemLayout}
|
89 |
name="nickname"
|
90 |
label="Nickname"
|
91 |
-
rules={[
|
|
|
|
|
92 |
>
|
93 |
-
<Input size=
|
94 |
</Form.Item>
|
95 |
-
}
|
96 |
<Form.Item
|
97 |
{...formItemLayout}
|
98 |
name="password"
|
99 |
label="Password"
|
100 |
rules={[{ required: true, message: 'Please input value' }]}
|
101 |
>
|
102 |
-
<Input size=
|
103 |
</Form.Item>
|
104 |
-
{
|
105 |
-
|
106 |
-
name="remember"
|
107 |
-
valuePropName="checked"
|
108 |
-
|
109 |
-
>
|
110 |
<Checkbox> Remember me</Checkbox>
|
111 |
</Form.Item>
|
112 |
-
}
|
113 |
-
<div>
|
114 |
-
|
115 |
-
|
116 |
-
<
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
|
|
|
|
123 |
Already have an account?
|
124 |
<Button type="link" onClick={changeTitle}>
|
125 |
Sign in
|
126 |
</Button>
|
127 |
-
</div>
|
128 |
-
}
|
129 |
</div>
|
130 |
-
<Button type="primary" block size=
|
131 |
{title === 'login' ? 'Sign in' : 'Continue'}
|
132 |
</Button>
|
133 |
-
{
|
134 |
-
|
135 |
-
<
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
<div
|
142 |
-
<Icon
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
143 |
Sign in with Github
|
144 |
</div>
|
145 |
-
</Button
|
146 |
-
|
147 |
-
|
148 |
</Form>
|
149 |
</div>
|
150 |
</div>
|
151 |
-
<div className={styles.loginRight}>
|
152 |
-
|
153 |
-
</div>
|
154 |
</div>
|
155 |
);
|
156 |
};
|
157 |
|
158 |
-
export default connect(({ loginModel, loading }) => ({ loginModel, loading }))(
|
|
|
|
|
|
1 |
+
import { rsaPsw } from '@/utils';
|
2 |
+
import { Button, Checkbox, Form, Input } from 'antd';
|
3 |
+
import { FC, useEffect, useState } from 'react';
|
4 |
+
import { Dispatch, Icon, connect, useNavigate } from 'umi';
|
5 |
import styles from './index.less';
|
|
|
|
|
6 |
|
7 |
interface LoginProps {
|
8 |
dispatch: Dispatch;
|
9 |
}
|
10 |
+
const View: FC<LoginProps> = ({ dispatch }) => {
|
11 |
+
let navigate = useNavigate();
|
12 |
+
const [title, setTitle] = useState('login');
|
|
|
13 |
const changeTitle = () => {
|
14 |
+
setTitle((title) => (title === 'login' ? 'register' : 'login'));
|
15 |
+
};
|
16 |
const [form] = Form.useForm();
|
17 |
const [checkNick, setCheckNick] = useState(false);
|
18 |
|
|
|
24 |
try {
|
25 |
const params = await form.validateFields();
|
26 |
|
27 |
+
var rsaPassWord = rsaPsw(params.password);
|
28 |
if (title === 'login') {
|
29 |
+
const ret = await dispatch({
|
30 |
type: 'loginModel/login',
|
31 |
payload: {
|
32 |
email: params.email,
|
33 |
+
password: rsaPassWord,
|
34 |
+
},
|
35 |
});
|
36 |
+
console.info(ret);
|
37 |
+
navigate('/knowledge');
|
38 |
} else {
|
39 |
dispatch({
|
40 |
type: 'loginModel/register',
|
|
|
44 |
password: rsaPassWord,
|
45 |
},
|
46 |
callback() {
|
47 |
+
setTitle('login');
|
48 |
+
},
|
49 |
});
|
50 |
}
|
51 |
} catch (errorInfo) {
|
|
|
57 |
// wrapperCol: { span: 8 },
|
58 |
};
|
59 |
|
|
|
60 |
const toGoogle = () => {
|
61 |
+
window.location.href =
|
62 |
+
'https://github.com/login/oauth/authorize?scope=user:email&client_id=302129228f0d96055bee';
|
63 |
+
};
|
64 |
return (
|
65 |
<div className={styles.loginPage}>
|
|
|
66 |
<div className={styles.loginLeft}>
|
67 |
<div className={styles.modal}>
|
68 |
<div className={styles.loginTitle}>
|
69 |
+
<div>{title === 'login' ? 'Sign in' : 'Create an account'}</div>
|
70 |
+
<span>
|
71 |
+
{title === 'login'
|
72 |
+
? 'We’re so excited to see you again!'
|
73 |
+
: 'Glad to have you on board!'}
|
74 |
</span>
|
75 |
</div>
|
76 |
|
77 |
+
<Form
|
78 |
+
form={form}
|
79 |
+
layout="vertical"
|
80 |
+
name="dynamic_rule"
|
81 |
+
style={{ maxWidth: 600 }}
|
82 |
+
>
|
83 |
<Form.Item
|
84 |
{...formItemLayout}
|
85 |
name="email"
|
86 |
label="Email"
|
87 |
rules={[{ required: true, message: 'Please input value' }]}
|
88 |
>
|
89 |
+
<Input size="large" placeholder="Please input value" />
|
90 |
</Form.Item>
|
91 |
+
{title === 'register' && (
|
92 |
+
<Form.Item
|
93 |
{...formItemLayout}
|
94 |
name="nickname"
|
95 |
label="Nickname"
|
96 |
+
rules={[
|
97 |
+
{ required: true, message: 'Please input your nickname' },
|
98 |
+
]}
|
99 |
>
|
100 |
+
<Input size="large" placeholder="Please input your nickname" />
|
101 |
</Form.Item>
|
102 |
+
)}
|
103 |
<Form.Item
|
104 |
{...formItemLayout}
|
105 |
name="password"
|
106 |
label="Password"
|
107 |
rules={[{ required: true, message: 'Please input value' }]}
|
108 |
>
|
109 |
+
<Input size="large" placeholder="Please input value" />
|
110 |
</Form.Item>
|
111 |
+
{title === 'login' && (
|
112 |
+
<Form.Item name="remember" valuePropName="checked">
|
|
|
|
|
|
|
|
|
113 |
<Checkbox> Remember me</Checkbox>
|
114 |
</Form.Item>
|
115 |
+
)}
|
116 |
+
<div>
|
117 |
+
{' '}
|
118 |
+
{title === 'login' && (
|
119 |
+
<div>
|
120 |
+
Don’t have an account?
|
121 |
+
<Button type="link" onClick={changeTitle}>
|
122 |
+
Sign up
|
123 |
+
</Button>
|
124 |
+
</div>
|
125 |
+
)}
|
126 |
+
{title === 'register' && (
|
127 |
+
<div>
|
128 |
Already have an account?
|
129 |
<Button type="link" onClick={changeTitle}>
|
130 |
Sign in
|
131 |
</Button>
|
132 |
+
</div>
|
133 |
+
)}
|
134 |
</div>
|
135 |
+
<Button type="primary" block size="large" onClick={onCheck}>
|
136 |
{title === 'login' ? 'Sign in' : 'Continue'}
|
137 |
</Button>
|
138 |
+
{title === 'login' && (
|
139 |
+
<>
|
140 |
+
<Button
|
141 |
+
block
|
142 |
+
size="large"
|
143 |
+
onClick={toGoogle}
|
144 |
+
style={{ marginTop: 15 }}
|
145 |
+
>
|
146 |
+
<div>
|
147 |
+
<Icon
|
148 |
+
icon="local:google"
|
149 |
+
style={{ verticalAlign: 'middle', marginRight: 5 }}
|
150 |
+
/>
|
151 |
+
Sign in with Google
|
152 |
+
</div>
|
153 |
+
</Button>
|
154 |
+
<Button
|
155 |
+
block
|
156 |
+
size="large"
|
157 |
+
onClick={toGoogle}
|
158 |
+
style={{ marginTop: 15 }}
|
159 |
+
>
|
160 |
+
<div>
|
161 |
+
<Icon
|
162 |
+
icon="local:github"
|
163 |
+
style={{ verticalAlign: 'middle', marginRight: 5 }}
|
164 |
+
/>
|
165 |
Sign in with Github
|
166 |
</div>
|
167 |
+
</Button>
|
168 |
+
</>
|
169 |
+
)}
|
170 |
</Form>
|
171 |
</div>
|
172 |
</div>
|
173 |
+
<div className={styles.loginRight}></div>
|
|
|
|
|
174 |
</div>
|
175 |
);
|
176 |
};
|
177 |
|
178 |
+
export default connect(({ loginModel, loading }) => ({ loginModel, loading }))(
|
179 |
+
View,
|
180 |
+
);
|
web/src/pages/login/model.ts
CHANGED
@@ -1,6 +1,8 @@
|
|
1 |
-
import {
|
2 |
-
import { message } from 'antd';
|
3 |
import userService from '@/services/userService';
|
|
|
|
|
|
|
4 |
|
5 |
export interface loginModelState {
|
6 |
list: any[];
|
@@ -28,49 +30,52 @@ const Model: logingModelType = {
|
|
28 |
},
|
29 |
subscriptions: {
|
30 |
setup({ dispatch, history }) {
|
31 |
-
history.listen(location => {
|
32 |
-
}
|
33 |
},
|
34 |
effects: {
|
35 |
*login({ payload = {} }, { call, put }) {
|
36 |
-
console.log(111, payload)
|
37 |
const { data, response } = yield call(userService.login, payload);
|
38 |
-
const { retcode, data: res, retmsg } = data
|
39 |
-
console.log()
|
40 |
-
const
|
41 |
if (retcode === 0) {
|
42 |
message.success('登录成功!');
|
43 |
const token = res.access_token;
|
44 |
const userInfo = {
|
45 |
avatar: res.avatar,
|
46 |
name: res.nickname,
|
47 |
-
email: res.email
|
48 |
};
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
|
|
|
|
55 |
}
|
|
|
56 |
},
|
57 |
*register({ payload = {}, callback }, { call, put }) {
|
58 |
const { data, response } = yield call(userService.register, payload);
|
59 |
-
console.log()
|
60 |
-
const { retcode, data: res, retmsg } = data
|
61 |
if (retcode === 0) {
|
62 |
message.success('注册成功!');
|
63 |
-
callback && callback()
|
64 |
}
|
65 |
-
}
|
66 |
},
|
67 |
reducers: {
|
68 |
updateState(state, { payload }) {
|
69 |
return {
|
70 |
...state,
|
71 |
-
...payload
|
72 |
};
|
73 |
-
}
|
74 |
-
}
|
75 |
};
|
76 |
export default Model;
|
|
|
1 |
+
import { Authorization } from '@/constants/authorization';
|
|
|
2 |
import userService from '@/services/userService';
|
3 |
+
import authorizationUtil from '@/utils/authorizationUtil';
|
4 |
+
import { message } from 'antd';
|
5 |
+
import { Effect, Reducer, Subscription } from 'umi';
|
6 |
|
7 |
export interface loginModelState {
|
8 |
list: any[];
|
|
|
30 |
},
|
31 |
subscriptions: {
|
32 |
setup({ dispatch, history }) {
|
33 |
+
history.listen((location) => {});
|
34 |
+
},
|
35 |
},
|
36 |
effects: {
|
37 |
*login({ payload = {} }, { call, put }) {
|
38 |
+
console.log(111, payload);
|
39 |
const { data, response } = yield call(userService.login, payload);
|
40 |
+
const { retcode, data: res, retmsg } = data;
|
41 |
+
console.log();
|
42 |
+
const authorization = response.headers.get(Authorization);
|
43 |
if (retcode === 0) {
|
44 |
message.success('登录成功!');
|
45 |
const token = res.access_token;
|
46 |
const userInfo = {
|
47 |
avatar: res.avatar,
|
48 |
name: res.nickname,
|
49 |
+
email: res.email,
|
50 |
};
|
51 |
+
authorizationUtil.setItems({
|
52 |
+
Authorization: authorization,
|
53 |
+
userInfo: JSON.stringify(userInfo),
|
54 |
+
Token: token,
|
55 |
+
});
|
56 |
+
// setTimeout(() => {
|
57 |
+
// window.location.href = '/file';
|
58 |
+
// }, 300);
|
59 |
}
|
60 |
+
return data;
|
61 |
},
|
62 |
*register({ payload = {}, callback }, { call, put }) {
|
63 |
const { data, response } = yield call(userService.register, payload);
|
64 |
+
console.log();
|
65 |
+
const { retcode, data: res, retmsg } = data;
|
66 |
if (retcode === 0) {
|
67 |
message.success('注册成功!');
|
68 |
+
callback && callback();
|
69 |
}
|
70 |
+
},
|
71 |
},
|
72 |
reducers: {
|
73 |
updateState(state, { payload }) {
|
74 |
return {
|
75 |
...state,
|
76 |
+
...payload,
|
77 |
};
|
78 |
+
},
|
79 |
+
},
|
80 |
};
|
81 |
export default Model;
|
web/src/pages/setting/index.tsx
CHANGED
@@ -1,90 +1,105 @@
|
|
1 |
-
import {
|
2 |
import i18n from 'i18next';
|
3 |
-
import { useTranslation
|
4 |
-
import {
|
5 |
-
|
6 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7 |
import styles from './index.less';
|
8 |
-
import CPwModal from './CPwModal'
|
9 |
-
import SAKModal from './SAKModal'
|
10 |
-
import TntModal from './TntModal'
|
11 |
-
import SSModal from './SSModal'
|
12 |
-
import List from './List'
|
13 |
-
import { useEffect, useState, FC } from 'react';
|
14 |
interface CPwModalProps {
|
15 |
-
|
16 |
-
|
17 |
}
|
18 |
const Index: FC<CPwModalProps> = ({ settingModel, dispatch }) => {
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
</
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { Button, FloatButton } from 'antd';
|
2 |
import i18n from 'i18next';
|
3 |
+
import { useTranslation } from 'react-i18next';
|
4 |
+
import { Dispatch, connect } from 'umi';
|
|
|
5 |
|
6 |
+
import authorizationUtil from '@/utils/authorizationUtil';
|
7 |
+
import { FC, useEffect } from 'react';
|
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 |
interface CPwModalProps {
|
15 |
+
dispatch: Dispatch;
|
16 |
+
settingModel: any;
|
17 |
}
|
18 |
const Index: FC<CPwModalProps> = ({ settingModel, dispatch }) => {
|
19 |
+
// const [llm_factory, set_llm_factory] = useState('')
|
20 |
+
const { t } = useTranslation();
|
21 |
+
const userInfo = authorizationUtil.getUserInfoObject();
|
22 |
+
const changeLang = (val: string) => {
|
23 |
+
// 改变状态里的 语言 进行切换
|
24 |
+
i18n.changeLanguage(val);
|
25 |
+
};
|
26 |
+
useEffect(() => {
|
27 |
+
dispatch({
|
28 |
+
type: 'settingModel/getTenantInfo',
|
29 |
+
payload: {},
|
30 |
+
});
|
31 |
+
}, []);
|
32 |
+
const showCPwModal = () => {
|
33 |
+
dispatch({
|
34 |
+
type: 'settingModel/updateState',
|
35 |
+
payload: {
|
36 |
+
isShowPSwModal: true,
|
37 |
+
},
|
38 |
+
});
|
39 |
+
};
|
40 |
+
const showTntModal = () => {
|
41 |
+
dispatch({
|
42 |
+
type: 'settingModel/updateState',
|
43 |
+
payload: {
|
44 |
+
isShowTntModal: true,
|
45 |
+
},
|
46 |
+
});
|
47 |
+
};
|
48 |
+
const showSSModal = () => {
|
49 |
+
dispatch({
|
50 |
+
type: 'settingModel/updateState',
|
51 |
+
payload: {
|
52 |
+
isShowSSModal: true,
|
53 |
+
},
|
54 |
+
});
|
55 |
+
// dispatch({
|
56 |
+
// type: 'settingModel/getTenantInfo',
|
57 |
+
// payload: {
|
58 |
+
// }
|
59 |
+
// });
|
60 |
+
};
|
61 |
+
return (
|
62 |
+
<div className={styles.settingPage}>
|
63 |
+
<div className={styles.avatar}>
|
64 |
+
<img
|
65 |
+
style={{ width: 50, marginRight: 5 }}
|
66 |
+
src="https://os.alipayobjects.com/rmsportal/QBnOOoLaAfKPirc.png"
|
67 |
+
alt=""
|
68 |
+
/>
|
69 |
+
<div>
|
70 |
+
<div>账号:{userInfo.name}</div>
|
71 |
+
<div>
|
72 |
+
<span>密码:******</span>
|
73 |
+
<Button type="link" onClick={showCPwModal}>
|
74 |
+
修改密码
|
75 |
+
</Button>
|
76 |
+
</div>
|
77 |
+
</div>
|
78 |
+
</div>
|
79 |
+
<div>
|
80 |
+
<Button type="link" onClick={showTntModal}>
|
81 |
+
租户
|
82 |
+
</Button>
|
83 |
+
<Button type="link" onClick={showSSModal}>
|
84 |
+
系统模型设置
|
85 |
+
</Button>
|
86 |
+
<List />
|
87 |
+
</div>
|
88 |
+
<CPwModal />
|
89 |
+
<SAKModal />
|
90 |
+
<SSModal />
|
91 |
+
<TntModal />
|
92 |
+
<FloatButton
|
93 |
+
shape="square"
|
94 |
+
description={t('setting.btn')}
|
95 |
+
onClick={() => i18n.changeLanguage(i18n.language == 'en' ? 'zh' : 'en')}
|
96 |
+
type="default"
|
97 |
+
style={{ right: 94, fontSize: 14 }}
|
98 |
+
/>
|
99 |
+
</div>
|
100 |
+
);
|
101 |
+
};
|
102 |
+
export default connect(({ settingModel, loading }) => ({
|
103 |
+
settingModel,
|
104 |
+
loading,
|
105 |
+
}))(Index);
|
web/src/pages/setting/model.ts
CHANGED
@@ -1,6 +1,7 @@
|
|
1 |
-
import { Effect, Reducer, Subscription } from 'umi';
|
2 |
-
import { message } from 'antd';
|
3 |
import userService from '@/services/userService';
|
|
|
|
|
|
|
4 |
|
5 |
export interface settingModelState {
|
6 |
isShowPSwModal: boolean;
|
@@ -9,10 +10,10 @@ export interface settingModelState {
|
|
9 |
isShowSSModal: boolean;
|
10 |
llm_factory: string;
|
11 |
loading: boolean;
|
12 |
-
tenantIfo: any
|
13 |
-
llmInfo: any
|
14 |
-
myLlm: any[]
|
15 |
-
factoriesList: any[]
|
16 |
}
|
17 |
|
18 |
export interface settingModelType {
|
@@ -45,32 +46,31 @@ const Model: settingModelType = {
|
|
45 |
tenantIfo: {},
|
46 |
llmInfo: {},
|
47 |
myLlm: [],
|
48 |
-
factoriesList: []
|
49 |
},
|
50 |
subscriptions: {
|
51 |
setup({ dispatch, history }) {
|
52 |
-
history.listen(location => {
|
53 |
-
|
54 |
-
}
|
55 |
},
|
56 |
effects: {
|
57 |
*setting({ payload = {}, callback }, { call, put }) {
|
58 |
const { data, response } = yield call(userService.setting, payload);
|
59 |
-
const { retcode, data: res, retmsg } = data
|
60 |
if (retcode === 0) {
|
61 |
message.success('密码修改成功!');
|
62 |
-
callback && callback()
|
63 |
}
|
64 |
},
|
65 |
*getUserInfo({ payload = {} }, { call, put }) {
|
66 |
const { data, response } = yield call(userService.user_info, payload);
|
67 |
-
const { retcode, data: res, retmsg } = data
|
68 |
const userInfo = {
|
69 |
avatar: res.avatar,
|
70 |
name: res.nickname,
|
71 |
-
email: res.email
|
72 |
};
|
73 |
-
|
74 |
if (retcode === 0) {
|
75 |
// localStorage.setItem('userInfo',res.)
|
76 |
}
|
@@ -79,91 +79,100 @@ const Model: settingModelType = {
|
|
79 |
yield put({
|
80 |
type: 'updateState',
|
81 |
payload: {
|
82 |
-
loading: true
|
83 |
-
}
|
84 |
});
|
85 |
-
const { data, response } = yield call(
|
86 |
-
|
|
|
|
|
|
|
87 |
// llm_id 对应chat_id
|
88 |
// asr_id 对应speech2txt
|
89 |
|
90 |
yield put({
|
91 |
type: 'updateState',
|
92 |
payload: {
|
93 |
-
loading: false
|
94 |
-
}
|
95 |
});
|
96 |
if (retcode === 0) {
|
97 |
-
res.chat_id = res.llm_id
|
98 |
-
res.speech2text_id = res.asr_id
|
99 |
yield put({
|
100 |
type: 'updateState',
|
101 |
payload: {
|
102 |
-
tenantIfo: res
|
103 |
-
}
|
104 |
});
|
105 |
}
|
106 |
},
|
107 |
*set_tenant_info({ payload = {} }, { call, put }) {
|
108 |
-
const { data, response } = yield call(
|
109 |
-
|
|
|
|
|
|
|
110 |
// llm_id 对应chat_id
|
111 |
// asr_id 对应speech2txt
|
112 |
if (retcode === 0) {
|
113 |
yield put({
|
114 |
type: 'updateState',
|
115 |
payload: {
|
116 |
-
isShowSSModal: false
|
117 |
-
}
|
118 |
});
|
119 |
yield put({
|
120 |
-
type: 'getTenantInfo'
|
121 |
-
})
|
122 |
}
|
123 |
},
|
124 |
|
125 |
*factories_list({ payload = {} }, { call, put }) {
|
126 |
-
const { data, response } = yield call(
|
127 |
-
|
|
|
|
|
|
|
128 |
if (retcode === 0) {
|
129 |
yield put({
|
130 |
type: 'updateState',
|
131 |
payload: {
|
132 |
-
factoriesList: res
|
133 |
-
}
|
134 |
});
|
135 |
}
|
136 |
},
|
137 |
*llm_list({ payload = {} }, { call, put }) {
|
138 |
const { data, response } = yield call(userService.llm_list, payload);
|
139 |
-
const { retcode, data: res, retmsg } = data
|
140 |
if (retcode === 0) {
|
141 |
yield put({
|
142 |
type: 'updateState',
|
143 |
payload: {
|
144 |
-
llmInfo: res
|
145 |
-
}
|
146 |
});
|
147 |
}
|
148 |
},
|
149 |
*my_llm({ payload = {} }, { call, put }) {
|
150 |
const { data, response } = yield call(userService.my_llm, payload);
|
151 |
-
const { retcode, data: res, retmsg } = data
|
152 |
if (retcode === 0) {
|
153 |
yield put({
|
154 |
type: 'updateState',
|
155 |
payload: {
|
156 |
-
myLlm: res
|
157 |
-
}
|
158 |
});
|
159 |
}
|
160 |
},
|
161 |
*set_api_key({ payload = {}, callback }, { call, put }) {
|
162 |
const { data, response } = yield call(userService.set_api_key, payload);
|
163 |
-
const { retcode, data: res, retmsg } = data
|
164 |
if (retcode === 0) {
|
165 |
message.success('设置API KEY成功!');
|
166 |
-
callback && callback()
|
167 |
}
|
168 |
},
|
169 |
},
|
@@ -171,9 +180,9 @@ const Model: settingModelType = {
|
|
171 |
updateState(state, { payload }) {
|
172 |
return {
|
173 |
...state,
|
174 |
-
...payload
|
175 |
};
|
176 |
-
}
|
177 |
-
}
|
178 |
};
|
179 |
export default Model;
|
|
|
|
|
|
|
1 |
import userService from '@/services/userService';
|
2 |
+
import authorizationUtil from '@/utils/authorizationUtil';
|
3 |
+
import { message } from 'antd';
|
4 |
+
import { Effect, Reducer, Subscription } from 'umi';
|
5 |
|
6 |
export interface settingModelState {
|
7 |
isShowPSwModal: boolean;
|
|
|
10 |
isShowSSModal: boolean;
|
11 |
llm_factory: string;
|
12 |
loading: boolean;
|
13 |
+
tenantIfo: any;
|
14 |
+
llmInfo: any;
|
15 |
+
myLlm: any[];
|
16 |
+
factoriesList: any[];
|
17 |
}
|
18 |
|
19 |
export interface settingModelType {
|
|
|
46 |
tenantIfo: {},
|
47 |
llmInfo: {},
|
48 |
myLlm: [],
|
49 |
+
factoriesList: [],
|
50 |
},
|
51 |
subscriptions: {
|
52 |
setup({ dispatch, history }) {
|
53 |
+
history.listen((location) => {});
|
54 |
+
},
|
|
|
55 |
},
|
56 |
effects: {
|
57 |
*setting({ payload = {}, callback }, { call, put }) {
|
58 |
const { data, response } = yield call(userService.setting, payload);
|
59 |
+
const { retcode, data: res, retmsg } = data;
|
60 |
if (retcode === 0) {
|
61 |
message.success('密码修改成功!');
|
62 |
+
callback && callback();
|
63 |
}
|
64 |
},
|
65 |
*getUserInfo({ payload = {} }, { call, put }) {
|
66 |
const { data, response } = yield call(userService.user_info, payload);
|
67 |
+
const { retcode, data: res, retmsg } = data;
|
68 |
const userInfo = {
|
69 |
avatar: res.avatar,
|
70 |
name: res.nickname,
|
71 |
+
email: res.email,
|
72 |
};
|
73 |
+
authorizationUtil.setUserInfo(userInfo);
|
74 |
if (retcode === 0) {
|
75 |
// localStorage.setItem('userInfo',res.)
|
76 |
}
|
|
|
79 |
yield put({
|
80 |
type: 'updateState',
|
81 |
payload: {
|
82 |
+
loading: true,
|
83 |
+
},
|
84 |
});
|
85 |
+
const { data, response } = yield call(
|
86 |
+
userService.get_tenant_info,
|
87 |
+
payload,
|
88 |
+
);
|
89 |
+
const { retcode, data: res, retmsg } = data;
|
90 |
// llm_id 对应chat_id
|
91 |
// asr_id 对应speech2txt
|
92 |
|
93 |
yield put({
|
94 |
type: 'updateState',
|
95 |
payload: {
|
96 |
+
loading: false,
|
97 |
+
},
|
98 |
});
|
99 |
if (retcode === 0) {
|
100 |
+
res.chat_id = res.llm_id;
|
101 |
+
res.speech2text_id = res.asr_id;
|
102 |
yield put({
|
103 |
type: 'updateState',
|
104 |
payload: {
|
105 |
+
tenantIfo: res,
|
106 |
+
},
|
107 |
});
|
108 |
}
|
109 |
},
|
110 |
*set_tenant_info({ payload = {} }, { call, put }) {
|
111 |
+
const { data, response } = yield call(
|
112 |
+
userService.set_tenant_info,
|
113 |
+
payload,
|
114 |
+
);
|
115 |
+
const { retcode, data: res, retmsg } = data;
|
116 |
// llm_id 对应chat_id
|
117 |
// asr_id 对应speech2txt
|
118 |
if (retcode === 0) {
|
119 |
yield put({
|
120 |
type: 'updateState',
|
121 |
payload: {
|
122 |
+
isShowSSModal: false,
|
123 |
+
},
|
124 |
});
|
125 |
yield put({
|
126 |
+
type: 'getTenantInfo',
|
127 |
+
});
|
128 |
}
|
129 |
},
|
130 |
|
131 |
*factories_list({ payload = {} }, { call, put }) {
|
132 |
+
const { data, response } = yield call(
|
133 |
+
userService.factories_list,
|
134 |
+
payload,
|
135 |
+
);
|
136 |
+
const { retcode, data: res, retmsg } = data;
|
137 |
if (retcode === 0) {
|
138 |
yield put({
|
139 |
type: 'updateState',
|
140 |
payload: {
|
141 |
+
factoriesList: res,
|
142 |
+
},
|
143 |
});
|
144 |
}
|
145 |
},
|
146 |
*llm_list({ payload = {} }, { call, put }) {
|
147 |
const { data, response } = yield call(userService.llm_list, payload);
|
148 |
+
const { retcode, data: res, retmsg } = data;
|
149 |
if (retcode === 0) {
|
150 |
yield put({
|
151 |
type: 'updateState',
|
152 |
payload: {
|
153 |
+
llmInfo: res,
|
154 |
+
},
|
155 |
});
|
156 |
}
|
157 |
},
|
158 |
*my_llm({ payload = {} }, { call, put }) {
|
159 |
const { data, response } = yield call(userService.my_llm, payload);
|
160 |
+
const { retcode, data: res, retmsg } = data;
|
161 |
if (retcode === 0) {
|
162 |
yield put({
|
163 |
type: 'updateState',
|
164 |
payload: {
|
165 |
+
myLlm: res,
|
166 |
+
},
|
167 |
});
|
168 |
}
|
169 |
},
|
170 |
*set_api_key({ payload = {}, callback }, { call, put }) {
|
171 |
const { data, response } = yield call(userService.set_api_key, payload);
|
172 |
+
const { retcode, data: res, retmsg } = data;
|
173 |
if (retcode === 0) {
|
174 |
message.success('设置API KEY成功!');
|
175 |
+
callback && callback();
|
176 |
}
|
177 |
},
|
178 |
},
|
|
|
180 |
updateState(state, { payload }) {
|
181 |
return {
|
182 |
...state,
|
183 |
+
...payload,
|
184 |
};
|
185 |
+
},
|
186 |
+
},
|
187 |
};
|
188 |
export default Model;
|
web/src/routes.ts
ADDED
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
const routes = [
|
2 |
+
{
|
3 |
+
path: '/login',
|
4 |
+
component: '@/pages/login',
|
5 |
+
layout: false,
|
6 |
+
},
|
7 |
+
{
|
8 |
+
path: '/',
|
9 |
+
component: '@/layouts',
|
10 |
+
layout: false,
|
11 |
+
wrappers: ['@/wrappers/auth'],
|
12 |
+
routes: [
|
13 |
+
{ path: '/', redirect: '/knowledge' },
|
14 |
+
{
|
15 |
+
path: '/knowledge',
|
16 |
+
component: '@/pages/knowledge',
|
17 |
+
},
|
18 |
+
{
|
19 |
+
path: '/knowledge/add/*',
|
20 |
+
component: '@/pages/add-knowledge',
|
21 |
+
},
|
22 |
+
{
|
23 |
+
path: '/chat',
|
24 |
+
component: '@/pages/chat',
|
25 |
+
},
|
26 |
+
{
|
27 |
+
path: '/setting',
|
28 |
+
component: '@/pages/setting',
|
29 |
+
},
|
30 |
+
{
|
31 |
+
path: '/file',
|
32 |
+
component: '@/pages/file',
|
33 |
+
},
|
34 |
+
],
|
35 |
+
},
|
36 |
+
{
|
37 |
+
path: '/*',
|
38 |
+
component: '@/pages/404',
|
39 |
+
layout: false,
|
40 |
+
},
|
41 |
+
];
|
42 |
+
|
43 |
+
export default routes;
|
web/src/utils/authorizationUtil.ts
ADDED
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { Authorization, Token, UserInfo } from '@/constants/authorization';
|
2 |
+
|
3 |
+
const KeySet = [Authorization, Token, UserInfo];
|
4 |
+
|
5 |
+
const storage = {
|
6 |
+
getAuthorization: () => {
|
7 |
+
return localStorage.getItem(Authorization);
|
8 |
+
},
|
9 |
+
getToken: () => {
|
10 |
+
return localStorage.getItem(Token);
|
11 |
+
},
|
12 |
+
getUserInfo: () => {
|
13 |
+
return localStorage.getItem(UserInfo);
|
14 |
+
},
|
15 |
+
getUserInfoObject: () => {
|
16 |
+
return JSON.parse(localStorage.getItem('userInfo') || '');
|
17 |
+
},
|
18 |
+
setAuthorization: (value: string) => {
|
19 |
+
localStorage.setItem(Authorization, value);
|
20 |
+
},
|
21 |
+
setToken: (value: string) => {
|
22 |
+
localStorage.setItem(Token, value);
|
23 |
+
},
|
24 |
+
setUserInfo: (value: string | Object) => {
|
25 |
+
let valueStr = typeof value !== 'string' ? JSON.stringify(value) : value;
|
26 |
+
localStorage.setItem(UserInfo, valueStr);
|
27 |
+
},
|
28 |
+
setItems: (pairs: Record<string, string>) => {
|
29 |
+
Object.entries(pairs).forEach(([key, value]) => {
|
30 |
+
localStorage.setItem(key, value);
|
31 |
+
});
|
32 |
+
},
|
33 |
+
removeAuthorization: () => {
|
34 |
+
localStorage.removeItem(Authorization);
|
35 |
+
},
|
36 |
+
removeAll: () => {
|
37 |
+
KeySet.forEach((x) => {
|
38 |
+
localStorage.removeItem(x);
|
39 |
+
});
|
40 |
+
},
|
41 |
+
};
|
42 |
+
|
43 |
+
export default storage;
|
web/src/utils/history.ts
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
import { createBrowserHistory } from 'history';
|
2 |
+
|
3 |
+
export const history = createBrowserHistory();
|
web/src/utils/request.ts
CHANGED
@@ -1,14 +1,14 @@
|
|
1 |
-
|
2 |
import { extend } from 'umi-request';
|
3 |
-
import { notification, message } from 'antd';
|
4 |
|
|
|
5 |
import api from '@/utils/api';
|
|
|
|
|
6 |
const { login } = api;
|
7 |
|
8 |
const ABORT_REQUEST_ERR_MESSAGE = 'The user aborted a request.'; // 手动中断请求。errorHandler 抛出的error message
|
9 |
|
10 |
-
|
11 |
-
|
12 |
const retcodeMessage = {
|
13 |
200: '服务器成功返回请求的数据。',
|
14 |
201: '新建或修改数据成功。',
|
@@ -24,7 +24,7 @@ const retcodeMessage = {
|
|
24 |
500: '服务器发生错误,请检查服务器。',
|
25 |
502: '网关错误。',
|
26 |
503: '服务不可用,服务器暂时过载或维护。',
|
27 |
-
504: '网关超时。'
|
28 |
};
|
29 |
type retcode =
|
30 |
| 200
|
@@ -49,16 +49,20 @@ interface responseType {
|
|
49 |
retcode: number;
|
50 |
data: any;
|
51 |
retmsg: string;
|
52 |
-
status: number
|
53 |
}
|
54 |
-
const errorHandler = (error: {
|
|
|
|
|
|
|
55 |
const { response } = error;
|
56 |
// 手动中断请求 abort
|
57 |
if (error.message === ABORT_REQUEST_ERR_MESSAGE) {
|
58 |
console.log('user abort request');
|
59 |
} else {
|
60 |
if (response && response.status) {
|
61 |
-
const errorText =
|
|
|
62 |
const { status, url } = response;
|
63 |
notification.error({
|
64 |
message: `请求错误 ${status}: ${url}`,
|
@@ -80,21 +84,21 @@ const errorHandler = (error: { response: Response, message: string }): Response
|
|
80 |
const request = extend({
|
81 |
errorHandler, // 默认错误处理
|
82 |
timeout: 3000000,
|
83 |
-
getResponse: true
|
84 |
});
|
85 |
|
86 |
request.interceptors.request.use((url: string, options: any) => {
|
87 |
-
const
|
88 |
return {
|
89 |
url,
|
90 |
options: {
|
91 |
...options,
|
92 |
headers: {
|
93 |
-
...(options.skipToken ? undefined : { Authorization }),
|
94 |
-
...options.headers
|
95 |
},
|
96 |
-
interceptors: true
|
97 |
-
}
|
98 |
};
|
99 |
});
|
100 |
|
@@ -103,7 +107,7 @@ request.interceptors.request.use((url: string, options: any) => {
|
|
103 |
* */
|
104 |
|
105 |
request.interceptors.response.use(async (response: any, request) => {
|
106 |
-
console.log(response, request)
|
107 |
const data: responseType = await response.clone().json();
|
108 |
// response 拦截
|
109 |
|
@@ -113,6 +117,8 @@ request.interceptors.response.use(async (response: any, request) => {
|
|
113 |
description: data.retmsg,
|
114 |
duration: 3,
|
115 |
});
|
|
|
|
|
116 |
} else if (data.retcode !== 0) {
|
117 |
if (data.retcode === 100) {
|
118 |
message.error(data.retmsg);
|
@@ -126,7 +132,6 @@ request.interceptors.response.use(async (response: any, request) => {
|
|
126 |
|
127 |
return response;
|
128 |
} else {
|
129 |
-
|
130 |
return response;
|
131 |
}
|
132 |
});
|
|
|
1 |
+
import { message, notification } from 'antd';
|
2 |
import { extend } from 'umi-request';
|
|
|
3 |
|
4 |
+
import { Authorization } from '@/constants/authorization';
|
5 |
import api from '@/utils/api';
|
6 |
+
import authorizationUtil from '@/utils/authorizationUtil';
|
7 |
+
|
8 |
const { login } = api;
|
9 |
|
10 |
const ABORT_REQUEST_ERR_MESSAGE = 'The user aborted a request.'; // 手动中断请求。errorHandler 抛出的error message
|
11 |
|
|
|
|
|
12 |
const retcodeMessage = {
|
13 |
200: '服务器成功返回请求的数据。',
|
14 |
201: '新建或修改数据成功。',
|
|
|
24 |
500: '服务器发生错误,请检查服务器。',
|
25 |
502: '网关错误。',
|
26 |
503: '服务不可用,服务器暂时过载或维护。',
|
27 |
+
504: '网关超时。',
|
28 |
};
|
29 |
type retcode =
|
30 |
| 200
|
|
|
49 |
retcode: number;
|
50 |
data: any;
|
51 |
retmsg: string;
|
52 |
+
status: number;
|
53 |
}
|
54 |
+
const errorHandler = (error: {
|
55 |
+
response: Response;
|
56 |
+
message: string;
|
57 |
+
}): Response => {
|
58 |
const { response } = error;
|
59 |
// 手动中断请求 abort
|
60 |
if (error.message === ABORT_REQUEST_ERR_MESSAGE) {
|
61 |
console.log('user abort request');
|
62 |
} else {
|
63 |
if (response && response.status) {
|
64 |
+
const errorText =
|
65 |
+
retcodeMessage[response.status as retcode] || response.statusText;
|
66 |
const { status, url } = response;
|
67 |
notification.error({
|
68 |
message: `请求错误 ${status}: ${url}`,
|
|
|
84 |
const request = extend({
|
85 |
errorHandler, // 默认错误处理
|
86 |
timeout: 3000000,
|
87 |
+
getResponse: true,
|
88 |
});
|
89 |
|
90 |
request.interceptors.request.use((url: string, options: any) => {
|
91 |
+
const authorization = authorizationUtil.getAuthorization();
|
92 |
return {
|
93 |
url,
|
94 |
options: {
|
95 |
...options,
|
96 |
headers: {
|
97 |
+
...(options.skipToken ? undefined : { [Authorization]: authorization }),
|
98 |
+
...options.headers,
|
99 |
},
|
100 |
+
interceptors: true,
|
101 |
+
},
|
102 |
};
|
103 |
});
|
104 |
|
|
|
107 |
* */
|
108 |
|
109 |
request.interceptors.response.use(async (response: any, request) => {
|
110 |
+
console.log(response, request);
|
111 |
const data: responseType = await response.clone().json();
|
112 |
// response 拦截
|
113 |
|
|
|
117 |
description: data.retmsg,
|
118 |
duration: 3,
|
119 |
});
|
120 |
+
authorizationUtil.removeAll();
|
121 |
+
// history.push('/login'); // Will not jump to the login page
|
122 |
} else if (data.retcode !== 0) {
|
123 |
if (data.retcode === 100) {
|
124 |
message.error(data.retmsg);
|
|
|
132 |
|
133 |
return response;
|
134 |
} else {
|
|
|
135 |
return response;
|
136 |
}
|
137 |
});
|
web/src/wrappers/auth.tsx
CHANGED
@@ -1,12 +1,11 @@
|
|
1 |
-
import {
|
|
|
2 |
|
3 |
-
export default (
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
}
|
12 |
-
}
|
|
|
1 |
+
import { useAuth } from '@/hooks/authHook';
|
2 |
+
import { Navigate, Outlet } from 'umi';
|
3 |
|
4 |
+
export default () => {
|
5 |
+
const { isLogin } = useAuth();
|
6 |
+
if (isLogin) {
|
7 |
+
return <Outlet />;
|
8 |
+
} else {
|
9 |
+
return <Navigate to="/login" />;
|
10 |
+
}
|
11 |
+
};
|
|
|
|