新增图库

This commit is contained in:
jiangh277
2025-08-04 16:56:39 +08:00
parent 56a0042011
commit 63ae33288d
25 changed files with 1184 additions and 38 deletions

View File

@@ -0,0 +1,125 @@
// src/pages/gallery/components/GridView.tsx
import { ImageItem } from '@/pages/gallery/typings';
import { DeleteOutlined, DownloadOutlined, EyeOutlined, MoreOutlined } from '@ant-design/icons';
import { Button, Checkbox, Dropdown, Menu, Spin } from 'antd';
import React, { FC, useCallback } from 'react';
import '../index.css';
interface GridViewProps {
imageList: ImageItem[];
viewMode: 'small' | 'large' | 'list' | 'table';
batchMode: boolean;
selectedRowKeys: string[];
onPreview: (index: number) => void;
onSelect: (instanceId: string, checked: boolean) => void;
onDownload: (instanceId: string, imageName: string) => void;
onDelete: (instanceId: string, imageName: string) => void;
loadingMore?: boolean;
onScroll: (e: React.UIEvent<HTMLDivElement>) => void;
}
const GridView: FC<GridViewProps> = ({
imageList,
viewMode,
batchMode,
selectedRowKeys,
onPreview,
onSelect,
onDownload,
onDelete,
loadingMore,
onScroll,
}) => {
const getImageSize = useCallback(() => {
switch (viewMode) {
case 'small':
return { width: 150, height: 150 };
case 'large':
return { width: 300, height: 300 };
default:
return { width: 150, height: 150 };
}
}, [viewMode]);
const imageSize = getImageSize();
const getImageMenu = useCallback(
(item: ImageItem) => (
<Menu>
<Menu.Item
key="preview"
icon={<EyeOutlined />}
onClick={() => {
const index = imageList.findIndex((img) => img.instanceId === item.instanceId);
onPreview(index);
}}
>
</Menu.Item>
<Menu.Item
key="download"
icon={<DownloadOutlined />}
onClick={() => onDownload(item.instanceId, item.imageName)}
>
</Menu.Item>
<Menu.Divider />
<Menu.Item
key="delete"
icon={<DeleteOutlined />}
danger
onClick={() => onDelete(item.instanceId, item.imageName)}
>
</Menu.Item>
</Menu>
),
[imageList, onPreview, onDownload, onDelete],
);
return (
<div
className={viewMode === 'small' ? 'small-grid-view' : 'large-grid-view'}
onScroll={onScroll}
>
{imageList.map((item: ImageItem, index: number) => (
<div key={item.instanceId} className="image-card">
{batchMode && (
<Checkbox
className="image-checkbox"
checked={selectedRowKeys.includes(item.instanceId)}
onChange={(e) => onSelect(item.instanceId, e.target.checked)}
/>
)}
<div
className="image-wrapper"
style={{
width: imageSize.width,
height: imageSize.height,
backgroundImage: `url(/file/image/${item.instanceId})`,
backgroundSize: 'cover',
backgroundPosition: 'center',
backgroundRepeat: 'no-repeat',
}}
onClick={() => !batchMode && onPreview(index)}
/>
<div className="image-info">
<div className="image-title" title={item.imageName}>
{item.imageName}
</div>
<Dropdown overlay={getImageMenu(item)} trigger={['click']}>
<Button type="text" icon={<MoreOutlined />} />
</Dropdown>
</div>
</div>
))}
{loadingMore && (
<div style={{ gridColumn: '1 / -1', textAlign: 'center', padding: '20px' }}>
<Spin />
</div>
)}
</div>
);
};
export default GridView;