mirror of
https://git.mirrors.martin98.com/https://github.com/infiniflow/ragflow.git
synced 2025-08-13 01:18:59 +08:00
feat: fixed the issue that some PDF documents could not be displayed on the chunk list page in small screens and logout (#105)
* feat: logout * feat: fixed the issue that some PDF documents could not be displayed on the chunk list page in small screens
This commit is contained in:
parent
aaf3084324
commit
6048926a4d
@ -64,3 +64,13 @@ export const useSelectParserList = (): Array<{
|
|||||||
|
|
||||||
return parserList;
|
return parserList;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const useLogout = () => {
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
|
const logout = useCallback((): number => {
|
||||||
|
return dispatch<any>({ type: 'loginModel/logout' });
|
||||||
|
}, [dispatch]);
|
||||||
|
|
||||||
|
return logout;
|
||||||
|
};
|
||||||
|
@ -1,19 +1,27 @@
|
|||||||
import { useFetchUserInfo, useSelectUserInfo } from '@/hooks/userSettingHook';
|
import {
|
||||||
|
useFetchUserInfo,
|
||||||
|
useLogout,
|
||||||
|
useSelectUserInfo,
|
||||||
|
} from '@/hooks/userSettingHook';
|
||||||
import authorizationUtil from '@/utils/authorizationUtil';
|
import authorizationUtil from '@/utils/authorizationUtil';
|
||||||
import type { MenuProps } from 'antd';
|
import type { MenuProps } from 'antd';
|
||||||
import { Avatar, Button, Dropdown } from 'antd';
|
import { Avatar, Button, Dropdown } from 'antd';
|
||||||
import React, { useMemo } from 'react';
|
import React, { useCallback, useMemo } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { history } from 'umi';
|
import { history } from 'umi';
|
||||||
|
|
||||||
const App: React.FC = () => {
|
const App: React.FC = () => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const userInfo = useSelectUserInfo();
|
const userInfo = useSelectUserInfo();
|
||||||
|
const logout = useLogout();
|
||||||
|
|
||||||
const logout = () => {
|
const handleLogout = useCallback(async () => {
|
||||||
authorizationUtil.removeAll();
|
const retcode = await logout();
|
||||||
history.push('/login');
|
if (retcode === 0) {
|
||||||
};
|
authorizationUtil.removeAll();
|
||||||
|
history.push('/login');
|
||||||
|
}
|
||||||
|
}, [logout]);
|
||||||
|
|
||||||
const toSetting = () => {
|
const toSetting = () => {
|
||||||
history.push('/setting');
|
history.push('/setting');
|
||||||
@ -23,7 +31,7 @@ const App: React.FC = () => {
|
|||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
key: '1',
|
key: '1',
|
||||||
onClick: logout,
|
onClick: handleLogout,
|
||||||
label: <Button type="text">{t('header.logout')}</Button>,
|
label: <Button type="text">{t('header.logout')}</Button>,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -32,7 +40,7 @@ const App: React.FC = () => {
|
|||||||
label: <Button type="text">{t('header.setting')}</Button>,
|
label: <Button type="text">{t('header.setting')}</Button>,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
}, [t]);
|
}, [t, handleLogout]);
|
||||||
|
|
||||||
useFetchUserInfo();
|
useFetchUserInfo();
|
||||||
|
|
||||||
|
@ -12,6 +12,10 @@
|
|||||||
.chunkText;
|
.chunkText;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.chunkCard {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.cardSelected {
|
.cardSelected {
|
||||||
background-color: @selectedBackgroundColor;
|
background-color: @selectedBackgroundColor;
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
import Image from '@/components/image';
|
import Image from '@/components/image';
|
||||||
import { IChunk } from '@/interfaces/database/knowledge';
|
import { IChunk } from '@/interfaces/database/knowledge';
|
||||||
import { Card, Checkbox, CheckboxProps, Flex, Popover, Switch } from 'antd';
|
import { Card, Checkbox, CheckboxProps, Flex, Popover, Switch } from 'antd';
|
||||||
|
import classNames from 'classnames';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
|
|
||||||
import styles from './index.less';
|
import styles from './index.less';
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
@ -44,33 +46,35 @@ const ChunkCard = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<Card
|
||||||
<Card className={selected ? styles.cardSelected : ''}>
|
className={classNames(styles.chunkCard, {
|
||||||
<Flex gap={'middle'} justify={'space-between'}>
|
[styles.cardSelected]: selected,
|
||||||
<Checkbox onChange={handleCheck} checked={checked}></Checkbox>
|
})}
|
||||||
{item.img_id && (
|
>
|
||||||
<Popover
|
<Flex gap={'middle'} justify={'space-between'}>
|
||||||
placement="topRight"
|
<Checkbox onChange={handleCheck} checked={checked}></Checkbox>
|
||||||
content={
|
{item.img_id && (
|
||||||
<Image id={item.img_id} className={styles.imagePreview}></Image>
|
<Popover
|
||||||
}
|
placement="topRight"
|
||||||
>
|
content={
|
||||||
<Image id={item.img_id} className={styles.image}></Image>
|
<Image id={item.img_id} className={styles.imagePreview}></Image>
|
||||||
</Popover>
|
}
|
||||||
)}
|
>
|
||||||
|
<Image id={item.img_id} className={styles.image}></Image>
|
||||||
|
</Popover>
|
||||||
|
)}
|
||||||
|
|
||||||
<section
|
<section
|
||||||
onDoubleClick={handleContentDoubleClick}
|
onDoubleClick={handleContentDoubleClick}
|
||||||
onClick={handleContentClick}
|
onClick={handleContentClick}
|
||||||
className={styles.content}
|
className={styles.content}
|
||||||
dangerouslySetInnerHTML={{ __html: item.content_with_weight }}
|
dangerouslySetInnerHTML={{ __html: item.content_with_weight }}
|
||||||
></section>
|
></section>
|
||||||
<div>
|
<div>
|
||||||
<Switch checked={enabled} onChange={onChange} />
|
<Switch checked={enabled} onChange={onChange} />
|
||||||
</div>
|
</div>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Card>
|
</Card>
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -12,6 +12,10 @@
|
|||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.pagePdfWrapper {
|
||||||
|
width: 60%;
|
||||||
|
}
|
||||||
|
|
||||||
.pageContent {
|
.pageContent {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@ -29,12 +33,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.chunkContainer {
|
.chunkContainer {
|
||||||
height: calc(100vh - 320px);
|
height: calc(100vh - 332px);
|
||||||
overflow: auto;
|
|
||||||
width: 100%;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.pageFooter {
|
.pageFooter {
|
||||||
|
padding-top: 10px;
|
||||||
height: 32px;
|
height: 32px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,6 +38,7 @@ const Chunk = () => {
|
|||||||
const { removeChunk } = useDeleteChunkByIds();
|
const { removeChunk } = useDeleteChunkByIds();
|
||||||
const documentInfo = useSelectDocumentInfo();
|
const documentInfo = useSelectDocumentInfo();
|
||||||
const { handleChunkCardClick, selectedChunkId } = useHandleChunkCardClick();
|
const { handleChunkCardClick, selectedChunkId } = useHandleChunkCardClick();
|
||||||
|
const isPdf = documentInfo.type === 'pdf';
|
||||||
|
|
||||||
const getChunkList = useCallback(() => {
|
const getChunkList = useCallback(() => {
|
||||||
const payload: PayloadType = {
|
const payload: PayloadType = {
|
||||||
@ -164,7 +165,7 @@ const Chunk = () => {
|
|||||||
></ChunkToolBar>
|
></ChunkToolBar>
|
||||||
<Divider></Divider>
|
<Divider></Divider>
|
||||||
<Flex flex={1} gap={'middle'}>
|
<Flex flex={1} gap={'middle'}>
|
||||||
<Flex flex={1} vertical>
|
<Flex vertical className={isPdf ? styles.pagePdfWrapper : ''}>
|
||||||
<div className={styles.pageContent}>
|
<div className={styles.pageContent}>
|
||||||
<Spin spinning={loading} className={styles.spin} size="large">
|
<Spin spinning={loading} className={styles.spin} size="large">
|
||||||
<Space
|
<Space
|
||||||
@ -204,7 +205,7 @@ const Chunk = () => {
|
|||||||
</div>
|
</div>
|
||||||
</Flex>
|
</Flex>
|
||||||
|
|
||||||
{documentInfo.type === 'pdf' && (
|
{isPdf && (
|
||||||
<section className={styles.documentPreview}>
|
<section className={styles.documentPreview}>
|
||||||
<DocumentPreview
|
<DocumentPreview
|
||||||
selectedChunkId={selectedChunkId}
|
selectedChunkId={selectedChunkId}
|
||||||
|
@ -177,7 +177,7 @@ const MessageItem = ({
|
|||||||
<Flex vertical gap={8} flex={1}>
|
<Flex vertical gap={8} flex={1}>
|
||||||
<b>{isAssistant ? '' : userInfo.nickname}</b>
|
<b>{isAssistant ? '' : userInfo.nickname}</b>
|
||||||
<div className={styles.messageText}>
|
<div className={styles.messageText}>
|
||||||
{item.content ? (
|
{item.content !== '' ? (
|
||||||
<Markdown
|
<Markdown
|
||||||
rehypePlugins={[rehypeWrapReference]}
|
rehypePlugins={[rehypeWrapReference]}
|
||||||
components={
|
components={
|
||||||
|
@ -25,18 +25,13 @@ const model: DvaModel<LoginModelState> = {
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
subscriptions: {
|
|
||||||
setup({ dispatch, history }) {
|
|
||||||
history.listen((location) => {});
|
|
||||||
},
|
|
||||||
},
|
|
||||||
effects: {
|
effects: {
|
||||||
*login({ payload = {} }, { call, put }) {
|
*login({ payload = {} }, { call }) {
|
||||||
const { data, response } = yield call(userService.login, payload);
|
const { data, response } = yield call(userService.login, payload);
|
||||||
const { retcode, data: res } = data;
|
const { retcode, data: res } = data;
|
||||||
const authorization = response.headers.get(Authorization);
|
const authorization = response.headers.get(Authorization);
|
||||||
if (retcode === 0) {
|
if (retcode === 0) {
|
||||||
message.success('登录成功!');
|
message.success('logged!');
|
||||||
const token = res.access_token;
|
const token = res.access_token;
|
||||||
const userInfo = {
|
const userInfo = {
|
||||||
avatar: res.avatar,
|
avatar: res.avatar,
|
||||||
@ -51,15 +46,23 @@ const model: DvaModel<LoginModelState> = {
|
|||||||
}
|
}
|
||||||
return retcode;
|
return retcode;
|
||||||
},
|
},
|
||||||
*register({ payload = {} }, { call, put }) {
|
*register({ payload = {} }, { call }) {
|
||||||
const { data, response } = yield call(userService.register, payload);
|
const { data } = yield call(userService.register, payload);
|
||||||
console.log();
|
console.log();
|
||||||
const { retcode, data: res, retmsg } = data;
|
const { retcode } = data;
|
||||||
if (retcode === 0) {
|
if (retcode === 0) {
|
||||||
message.success('注册成功!');
|
message.success('注册成功!');
|
||||||
}
|
}
|
||||||
return retcode;
|
return retcode;
|
||||||
},
|
},
|
||||||
|
*logout({ payload = {} }, { call }) {
|
||||||
|
const { data } = yield call(userService.logout, payload);
|
||||||
|
const { retcode } = data;
|
||||||
|
if (retcode === 0) {
|
||||||
|
message.success('logout');
|
||||||
|
}
|
||||||
|
return retcode;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
export default model;
|
export default model;
|
||||||
|
@ -4,6 +4,7 @@ import request from '@/utils/request';
|
|||||||
|
|
||||||
const {
|
const {
|
||||||
login,
|
login,
|
||||||
|
logout,
|
||||||
register,
|
register,
|
||||||
setting,
|
setting,
|
||||||
user_info,
|
user_info,
|
||||||
@ -20,6 +21,10 @@ const methods = {
|
|||||||
url: login,
|
url: login,
|
||||||
method: 'post',
|
method: 'post',
|
||||||
},
|
},
|
||||||
|
logout: {
|
||||||
|
url: logout,
|
||||||
|
method: 'get',
|
||||||
|
},
|
||||||
register: {
|
register: {
|
||||||
url: register,
|
url: register,
|
||||||
method: 'post',
|
method: 'post',
|
||||||
|
@ -5,6 +5,7 @@ export { api_host };
|
|||||||
export default {
|
export default {
|
||||||
// 用户
|
// 用户
|
||||||
login: `${api_host}/user/login`,
|
login: `${api_host}/user/login`,
|
||||||
|
logout: `${api_host}/user/logout`,
|
||||||
register: `${api_host}/user/register`,
|
register: `${api_host}/user/register`,
|
||||||
setting: `${api_host}/user/setting`,
|
setting: `${api_host}/user/setting`,
|
||||||
user_info: `${api_host}/user/info`,
|
user_info: `${api_host}/user/info`,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user