Merge pull request #98 from zstar1003/dev

feat(知识块管理): 实现chunk关联图片预览显示功能
This commit is contained in:
zstar 2025-05-16 17:16:52 +08:00 committed by GitHub
commit 16b2c75dfe
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 129 additions and 23 deletions

View File

@ -1,6 +1,5 @@
import i18n from '@/locales/config';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
import { App, ConfigProvider, ConfigProviderProps, theme } from 'antd';
import pt_BR from 'antd/lib/locale/pt_BR';
import deDE from 'antd/locale/de_DE';
@ -68,7 +67,7 @@ function Root({ children }: React.PropsWithChildren) {
>
<App>{children}</App>
</ConfigProvider>
<ReactQueryDevtools buttonPosition={'top-left'} />
{/* <ReactQueryDevtools buttonPosition={'top-left'} /> */}
</>
);
}

View File

@ -0,0 +1,15 @@
.primitiveImg {
display: inline-block;
max-height: 100px;
}
.image {
max-width: 100px;
object-fit: contain;
}
.imagePreview {
display: block;
max-width: 45vw;
max-height: 40vh;
}

View File

@ -0,0 +1,37 @@
import { Popover } from 'antd';
import classNames from 'classnames';
import styles from './index.less';
interface IImage {
id: string;
className: string;
}
const ChunkImage = ({ id, className, ...props }: IImage) => {
const imgSrc = id;
return (
<img
{...props}
src={imgSrc}
alt=""
className={classNames(styles.primitiveImg, className)}
/>
);
};
export default ChunkImage;
export const ImageWithPopover = ({ id }: { id: string }) => {
return (
<Popover
placement="left"
content={
<ChunkImage id={id} className={styles.imagePreview}></ChunkImage>
}
>
<ChunkImage id={id} className={styles.image}></ChunkImage>
</Popover>
);
};

View File

@ -90,3 +90,39 @@
cursor: pointer;
}
.imagePreviewPane {
width: 200px;
min-width: 200px;
background-color: #f0f9ff;
border-radius: 8px;
padding: 16px;
display: flex;
flex-direction: column;
h4 {
text-align: center;
margin-bottom: 12px;
font-weight: 500;
}
p {
text-align: center;
margin-bottom: 12px;
font-weight: 500;
}
.imagePreviewContainer {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
.fullSizeImage {
max-width: 100%;
max-height: 100%;
object-fit: contain;
}
}
}

View File

@ -1,3 +1,4 @@
import ChunkImage from '@/components/chunk_image';
import { useFetchNextChunkList, useSwitchChunk } from '@/hooks/chunk-hooks';
import type { PaginationProps } from 'antd';
import { Divider, Flex, Pagination, Space, Spin, message } from 'antd';
@ -46,6 +47,14 @@ const Chunk = () => {
documentId,
} = useUpdateChunk();
// 获取选中的chunk
const selectedChunk = data.find((item) => item.chunk_id === selectedChunkId);
// 获取图片ID兼容两种字段名
const getImageId = (chunk: any) => {
return chunk?.image_id || chunk?.img_id;
};
const onPaginationChange: PaginationProps['onShowSizeChange'] = (
page,
size,
@ -134,6 +143,35 @@ const Chunk = () => {
></ChunkToolBar>
<Divider></Divider>
<Flex flex={1} gap={'middle'}>
{/* 左侧图片预览窗格 */}
<div className={styles.imagePreviewPane}>
<h4>{t('关联图片显示区域')}</h4>
{selectedChunk ? (
getImageId(selectedChunk) ? (
<div className={styles.imagePreviewContainer}>
<ChunkImage
id={getImageId(selectedChunk)}
className={styles.fullSizeImage}
/>
</div>
) : (
<div className={styles.placeholderContainer}>
{' '}
<p>{t('chunk.noImageAssociated', '此区块没有关联图片')}</p>
</div>
)
) : (
<div className={styles.placeholderContainer}>
{' '}
<p>
{t(
'chunk.selectChunkToViewImage',
'请选择一个块以查看其图片',
)}
</p>
</div>
)}
</div>
<Flex
vertical
className={isPdf ? styles.pagePdfWrapper : styles.pageWrapper}

View File

@ -1,16 +1,7 @@
import { useInfiniteFetchKnowledgeList } from '@/hooks/knowledge-hooks';
import { useFetchUserInfo } from '@/hooks/user-setting-hooks';
import { PlusOutlined, SearchOutlined } from '@ant-design/icons';
import {
Button,
Divider,
Empty,
Flex,
Input,
Skeleton,
Space,
Spin,
} from 'antd';
import { SearchOutlined } from '@ant-design/icons';
import { Divider, Empty, Flex, Input, Skeleton, Space, Spin } from 'antd';
import { useTranslation } from 'react-i18next';
import InfiniteScroll from 'react-infinite-scroll-component';
import { useSaveKnowledge } from './hooks';
@ -26,7 +17,6 @@ const KnowledgeList = () => {
const {
visible,
hideModal,
showModal,
onCreateOk,
loading: creatingLoading,
} = useSaveKnowledge();
@ -67,15 +57,6 @@ const KnowledgeList = () => {
onChange={handleInputChange}
prefix={<SearchOutlined />}
/>
{/*<Button
type="primary"
icon={<PlusOutlined />}
onClick={showModal}
className={styles.topButton}
>
{t('createKnowledgeBase')}
</Button>*/}
</Space>
</div>
<Spin spinning={loading}>