Просмотр исходного кода

✨ feat(policy-news): 优化政策新闻图片管理功能

- 表格图片列:
  - 调整宽度从80px到90px
  - 无图片时显示"无图片"提示文字
  - 多张图片时显示"+N"数量标记
  - 添加图片预览功能

- 文件预览组件:
  - 重命名为专门处理图片文件的预览组件
  - 仅显示图片类型文件
  - 添加序号标识
  - 优化预览遮罩样式

- 表单优化:
  - 将"关联文件"修改为"关联图片"
  - "选择文件"按钮改为"选择图片"
  - 所有文件相关文案更新为图片
  - 添加已选图片预览区域
  - 优化图片数量显示

- 其他改进:
  - 使用file.id作为key值,提高渲染稳定性
  - 过滤非图片类型文件,专注图片管理功能
yourname 7 месяцев назад
Родитель
Сommit
9ea1e3fc00
1 измененных файлов с 94 добавлено и 44 удалено
  1. 94 44
      src/client/admin/pages/PolicyNewsPage.tsx

+ 94 - 44
src/client/admin/pages/PolicyNewsPage.tsx

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