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:
balibabu 2024-03-07 11:38:32 +08:00 committed by GitHub
parent aaf3084324
commit 6048926a4d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 89 additions and 50 deletions

View File

@ -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;
};

View File

@ -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();

View File

@ -12,6 +12,10 @@
.chunkText; .chunkText;
} }
.chunkCard {
width: 100%;
}
.cardSelected { .cardSelected {
background-color: @selectedBackgroundColor; background-color: @selectedBackgroundColor;
} }

View File

@ -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>
); );
}; };

View File

@ -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;
} }
} }

View File

@ -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}

View File

@ -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={

View File

@ -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;

View File

@ -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',

View File

@ -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`,