241 lines
7.5 KiB
TypeScript
241 lines
7.5 KiB
TypeScript
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';
|
||
import classNames from 'classnames';
|
||
import { useCallback, useState } from 'react';
|
||
import { useTranslation } from 'react-i18next';
|
||
import ChunkCard from './components/chunk-card';
|
||
import CreatingModal from './components/chunk-creating-modal';
|
||
import ChunkToolBar from './components/chunk-toolbar';
|
||
import DocumentPreview from './components/document-preview/preview';
|
||
import {
|
||
useChangeChunkTextMode,
|
||
useDeleteChunkByIds,
|
||
useGetChunkHighlights,
|
||
useHandleChunkCardClick,
|
||
useUpdateChunk,
|
||
} from './hooks';
|
||
|
||
import styles from './index.less';
|
||
|
||
const Chunk = () => {
|
||
const [selectedChunkIds, setSelectedChunkIds] = useState<string[]>([]);
|
||
const { removeChunk } = useDeleteChunkByIds();
|
||
const {
|
||
data: { documentInfo, data = [], total },
|
||
pagination,
|
||
loading,
|
||
searchString,
|
||
handleInputChange,
|
||
available,
|
||
handleSetAvailable,
|
||
} = useFetchNextChunkList();
|
||
const { handleChunkCardClick, selectedChunkId } = useHandleChunkCardClick();
|
||
const isPdf = documentInfo?.type === 'pdf';
|
||
|
||
const { t } = useTranslation();
|
||
const { changeChunkTextMode, textMode } = useChangeChunkTextMode();
|
||
const { switchChunk } = useSwitchChunk();
|
||
const {
|
||
chunkUpdatingLoading,
|
||
onChunkUpdatingOk,
|
||
showChunkUpdatingModal,
|
||
hideChunkUpdatingModal,
|
||
chunkId,
|
||
chunkUpdatingVisible,
|
||
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,
|
||
) => {
|
||
setSelectedChunkIds([]);
|
||
pagination.onChange?.(page, size);
|
||
};
|
||
|
||
const selectAllChunk = useCallback(
|
||
(checked: boolean) => {
|
||
setSelectedChunkIds(checked ? data.map((x) => x.chunk_id) : []);
|
||
},
|
||
[data],
|
||
);
|
||
|
||
const handleSingleCheckboxClick = useCallback(
|
||
(chunkId: string, checked: boolean) => {
|
||
setSelectedChunkIds((previousIds) => {
|
||
const idx = previousIds.findIndex((x) => x === chunkId);
|
||
const nextIds = [...previousIds];
|
||
if (checked && idx === -1) {
|
||
nextIds.push(chunkId);
|
||
} else if (!checked && idx !== -1) {
|
||
nextIds.splice(idx, 1);
|
||
}
|
||
return nextIds;
|
||
});
|
||
},
|
||
[],
|
||
);
|
||
|
||
const showSelectedChunkWarning = useCallback(() => {
|
||
message.warning(t('message.pleaseSelectChunk'));
|
||
}, [t]);
|
||
|
||
const handleRemoveChunk = useCallback(async () => {
|
||
if (selectedChunkIds.length > 0) {
|
||
const resCode: number = await removeChunk(selectedChunkIds, documentId);
|
||
if (resCode === 0) {
|
||
setSelectedChunkIds([]);
|
||
}
|
||
} else {
|
||
showSelectedChunkWarning();
|
||
}
|
||
}, [selectedChunkIds, documentId, removeChunk, showSelectedChunkWarning]);
|
||
|
||
const handleSwitchChunk = useCallback(
|
||
async (available?: number, chunkIds?: string[]) => {
|
||
let ids = chunkIds;
|
||
if (!chunkIds) {
|
||
ids = selectedChunkIds;
|
||
if (selectedChunkIds.length === 0) {
|
||
showSelectedChunkWarning();
|
||
return;
|
||
}
|
||
}
|
||
|
||
const resCode: number = await switchChunk({
|
||
chunk_ids: ids,
|
||
available_int: available,
|
||
doc_id: documentId,
|
||
});
|
||
if (!chunkIds && resCode === 0) {
|
||
}
|
||
},
|
||
[switchChunk, documentId, selectedChunkIds, showSelectedChunkWarning],
|
||
);
|
||
|
||
const { highlights, setWidthAndHeight } =
|
||
useGetChunkHighlights(selectedChunkId);
|
||
|
||
return (
|
||
<>
|
||
<div className={styles.chunkPage}>
|
||
<ChunkToolBar
|
||
selectAllChunk={selectAllChunk}
|
||
createChunk={showChunkUpdatingModal}
|
||
removeChunk={handleRemoveChunk}
|
||
checked={selectedChunkIds.length === data.length}
|
||
switchChunk={handleSwitchChunk}
|
||
changeChunkTextMode={changeChunkTextMode}
|
||
searchString={searchString}
|
||
handleInputChange={handleInputChange}
|
||
available={available}
|
||
handleSetAvailable={handleSetAvailable}
|
||
></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}
|
||
>
|
||
<Spin spinning={loading} className={styles.spin} size="large">
|
||
<div className={styles.pageContent}>
|
||
<Space
|
||
direction="vertical"
|
||
size={'middle'}
|
||
className={classNames(styles.chunkContainer, {
|
||
[styles.chunkOtherContainer]: !isPdf,
|
||
})}
|
||
>
|
||
{data.map((item) => (
|
||
<ChunkCard
|
||
item={item}
|
||
key={item.chunk_id}
|
||
editChunk={showChunkUpdatingModal}
|
||
checked={selectedChunkIds.some(
|
||
(x) => x === item.chunk_id,
|
||
)}
|
||
handleCheckboxClick={handleSingleCheckboxClick}
|
||
switchChunk={handleSwitchChunk}
|
||
clickChunkCard={handleChunkCardClick}
|
||
selected={item.chunk_id === selectedChunkId}
|
||
textMode={textMode}
|
||
></ChunkCard>
|
||
))}
|
||
</Space>
|
||
</div>
|
||
</Spin>
|
||
<div className={styles.pageFooter}>
|
||
<Pagination
|
||
{...pagination}
|
||
total={total}
|
||
size={'small'}
|
||
onChange={onPaginationChange}
|
||
/>
|
||
</div>
|
||
</Flex>
|
||
{isPdf && (
|
||
<section className={styles.documentPreview}>
|
||
<DocumentPreview
|
||
highlights={highlights}
|
||
setWidthAndHeight={setWidthAndHeight}
|
||
></DocumentPreview>
|
||
</section>
|
||
)}
|
||
</Flex>
|
||
</div>
|
||
{chunkUpdatingVisible && (
|
||
<CreatingModal
|
||
doc_id={documentId}
|
||
chunkId={chunkId}
|
||
hideModal={hideChunkUpdatingModal}
|
||
visible={chunkUpdatingVisible}
|
||
loading={chunkUpdatingLoading}
|
||
onOk={onChunkUpdatingOk}
|
||
parserId={documentInfo.parser_id}
|
||
/>
|
||
)}
|
||
</>
|
||
);
|
||
};
|
||
|
||
export default Chunk;
|