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