|
|
@@ -353,19 +353,47 @@ const PolicyNewsPage: React.FC = () => {
|
|
|
{
|
|
|
title: '图片',
|
|
|
dataIndex: 'files',
|
|
|
- width: 80,
|
|
|
+ width: 90,
|
|
|
key: 'files',
|
|
|
render: (files: any[]) => {
|
|
|
- if (!Array.isArray(files) || files.length === 0) return null;
|
|
|
- const firstImage = files.find(file => file?.fileType?.startsWith('image/'));
|
|
|
- if (!firstImage) return null;
|
|
|
+ if (!Array.isArray(files) || files.length === 0) {
|
|
|
+ return <span style={{ color: '#999', fontSize: 12 }}>无图片</span>;
|
|
|
+ }
|
|
|
+
|
|
|
+ const imageFiles = files.filter(file => file?.type?.startsWith('image/'));
|
|
|
+ if (imageFiles.length === 0) {
|
|
|
+ return <span style={{ color: '#999', fontSize: 12 }}>无图片</span>;
|
|
|
+ }
|
|
|
+
|
|
|
+ const firstImage = imageFiles[0];
|
|
|
+
|
|
|
return (
|
|
|
- <Image
|
|
|
- width={50}
|
|
|
- height={50}
|
|
|
- src={firstImage.fullUrl}
|
|
|
- style={{ objectFit: 'cover', borderRadius: 4 }}
|
|
|
- />
|
|
|
+ <div style={{ display: 'flex', alignItems: 'center', gap: 4 }}>
|
|
|
+ <Image
|
|
|
+ width={45}
|
|
|
+ height={45}
|
|
|
+ src={firstImage.fullUrl}
|
|
|
+ style={{ objectFit: 'cover', borderRadius: 4 }}
|
|
|
+ preview={{
|
|
|
+ mask: <span style={{ fontSize: 12 }}>预览</span>
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ {imageFiles.length > 1 && (
|
|
|
+ <span style={{
|
|
|
+ backgroundColor: '#1890ff',
|
|
|
+ color: 'white',
|
|
|
+ borderRadius: '50%',
|
|
|
+ width: 16,
|
|
|
+ height: 16,
|
|
|
+ fontSize: 10,
|
|
|
+ display: 'flex',
|
|
|
+ alignItems: 'center',
|
|
|
+ justifyContent: 'center'
|
|
|
+ }}>
|
|
|
+ +{imageFiles.length - 1}
|
|
|
+ </span>
|
|
|
+ )}
|
|
|
+ </div>
|
|
|
);
|
|
|
},
|
|
|
},
|
|
|
@@ -448,14 +476,17 @@ const PolicyNewsPage: React.FC = () => {
|
|
|
return file?.fullUrl || file?.url || '';
|
|
|
};
|
|
|
|
|
|
- // 文件预览组件
|
|
|
+ // 文件预览组件 - 专门用于显示图片文件
|
|
|
const FilePreview = ({ files }: { files: any[] }) => {
|
|
|
if (!Array.isArray(files) || files.length === 0) return null;
|
|
|
|
|
|
+ const imageFiles = files.filter(file => file?.type?.startsWith('image/'));
|
|
|
+ if (imageFiles.length === 0) return null;
|
|
|
+
|
|
|
return (
|
|
|
<div style={{ display: 'flex', flexWrap: 'wrap', gap: 8 }}>
|
|
|
- {files.map((file) => (
|
|
|
- <div key={file?.id || Math.random()} style={{
|
|
|
+ {imageFiles.map((file) => (
|
|
|
+ <div key={file?.id} style={{
|
|
|
position: 'relative',
|
|
|
width: 80,
|
|
|
height: 80,
|
|
|
@@ -463,38 +494,38 @@ const PolicyNewsPage: React.FC = () => {
|
|
|
borderRadius: 4,
|
|
|
overflow: 'hidden'
|
|
|
}}>
|
|
|
- {file.fileType?.startsWith('image/') ? (
|
|
|
- <Image
|
|
|
- src={file.fullUrl}
|
|
|
- alt={file.originalName}
|
|
|
- style={{ width: '100%', height: '100%', objectFit: 'cover' }}
|
|
|
- />
|
|
|
- ) : (
|
|
|
- <div style={{
|
|
|
- display: 'flex',
|
|
|
- alignItems: 'center',
|
|
|
- justifyContent: 'center',
|
|
|
- height: '100%',
|
|
|
- backgroundColor: '#f5f5f5'
|
|
|
- }}>
|
|
|
- <FileOutlined style={{ fontSize: 24, color: '#666' }} />
|
|
|
- </div>
|
|
|
- )}
|
|
|
+ <Image
|
|
|
+ src={file.fullUrl}
|
|
|
+ alt={file.name}
|
|
|
+ style={{ width: '100%', height: '100%', objectFit: 'cover' }}
|
|
|
+ preview={{
|
|
|
+ mask: (
|
|
|
+ <div style={{
|
|
|
+ display: 'flex',
|
|
|
+ flexDirection: 'column',
|
|
|
+ alignItems: 'center',
|
|
|
+ justifyContent: 'center',
|
|
|
+ color: 'white',
|
|
|
+ backgroundColor: 'rgba(0,0,0,0.7)',
|
|
|
+ height: '100%'
|
|
|
+ }}>
|
|
|
+ <EyeOutlined style={{ fontSize: 16 }} />
|
|
|
+ <span style={{ fontSize: 10, marginTop: 2 }}>预览</span>
|
|
|
+ </div>
|
|
|
+ )
|
|
|
+ }}
|
|
|
+ />
|
|
|
<div style={{
|
|
|
position: 'absolute',
|
|
|
- bottom: 0,
|
|
|
- left: 0,
|
|
|
+ top: 0,
|
|
|
right: 0,
|
|
|
- backgroundColor: 'rgba(0,0,0,0.7)',
|
|
|
+ backgroundColor: 'rgba(0,0,0,0.5)',
|
|
|
color: 'white',
|
|
|
fontSize: 10,
|
|
|
padding: '2px 4px',
|
|
|
- textAlign: 'center',
|
|
|
- whiteSpace: 'nowrap',
|
|
|
- overflow: 'hidden',
|
|
|
- textOverflow: 'ellipsis'
|
|
|
+ borderRadius: '0 0 0 4px'
|
|
|
}}>
|
|
|
- {file.originalName}
|
|
|
+ {imageFiles.length > 1 && imageFiles.indexOf(file) + 1}
|
|
|
</div>
|
|
|
</div>
|
|
|
))}
|
|
|
@@ -709,7 +740,7 @@ const PolicyNewsPage: React.FC = () => {
|
|
|
<Switch checkedChildren="是" unCheckedChildren="否" />
|
|
|
</Form.Item>
|
|
|
|
|
|
- <Form.Item label="关联文件">
|
|
|
+ <Form.Item label="关联图片">
|
|
|
<Space direction="vertical" style={{ width: '100%' }}>
|
|
|
<Space>
|
|
|
<Button
|
|
|
@@ -717,7 +748,7 @@ const PolicyNewsPage: React.FC = () => {
|
|
|
icon={<PlusOutlined />}
|
|
|
onClick={openFileSelector}
|
|
|
>
|
|
|
- 选择文件
|
|
|
+ 选择图片
|
|
|
</Button>
|
|
|
<Button
|
|
|
type="dashed"
|
|
|
@@ -726,16 +757,34 @@ const PolicyNewsPage: React.FC = () => {
|
|
|
清空选择
|
|
|
</Button>
|
|
|
<span style={{ color: '#666', marginLeft: 8 }}>
|
|
|
- 已选择 {selectedFileIds.length} 个文件
|
|
|
+ 已选择 {selectedFileIds.length} 张图片
|
|
|
</span>
|
|
|
</Space>
|
|
|
|
|
|
- {data.find(item => item.id === editingRecord?.id)?.files && editingRecord && (
|
|
|
+ {/* 显示已选图片预览 */}
|
|
|
+ {selectedFileIds.length > 0 && (
|
|
|
+ <div>
|
|
|
+ <div style={{ marginBottom: 8, fontSize: 12, color: '#666' }}>
|
|
|
+ 已选择图片预览:
|
|
|
+ </div>
|
|
|
+ <FilePreview
|
|
|
+ files={selectedFileIds.map(id => ({
|
|
|
+ id,
|
|
|
+ type: 'image/jpeg',
|
|
|
+ fullUrl: `/api/v1/files/${id}`,
|
|
|
+ name: `图片${id}`
|
|
|
+ }))}
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ )}
|
|
|
+
|
|
|
+ {/* 显示编辑模式下已关联的图片 */}
|
|
|
+ {editingRecord && editingRecord.files && editingRecord.files.length > 0 && (
|
|
|
<div>
|
|
|
<div style={{ marginBottom: 8, fontSize: 12, color: '#666' }}>
|
|
|
- 当前已关联文件:
|
|
|
+ 当前已关联图片:
|
|
|
</div>
|
|
|
- <FilePreview files={editingRecord.files || []} />
|
|
|
+ <FilePreview files={editingRecord.files.filter(f => f?.type?.startsWith('image/'))} />
|
|
|
</div>
|
|
|
)}
|
|
|
</Space>
|
|
|
@@ -772,6 +821,7 @@ const PolicyNewsPage: React.FC = () => {
|
|
|
uploadPath="/policy-news"
|
|
|
uploadButtonText="上传新图片"
|
|
|
multiple={true}
|
|
|
+ selectedFileIds={selectedFileIds}
|
|
|
/>
|
|
|
</Modal>
|
|
|
</div>
|