|
|
@@ -1,12 +1,13 @@
|
|
|
-import React, { useState, useEffect } from 'react';
|
|
|
-import { Table, Card, Tabs, Button, Space, Tag, Switch, Popconfirm, message, Modal, Form, Input, Select, Upload, Image } from 'antd';
|
|
|
-import { PlusOutlined, EditOutlined, DeleteOutlined, EyeOutlined, LinkOutlined, UploadOutlined } from '@ant-design/icons';
|
|
|
+import React, { useState } from 'react';
|
|
|
+import { Table, Card, Tabs, Button, Space, Tag, Switch, Popconfirm, message, Modal, Form, Input, Image } from 'antd';
|
|
|
+import { PlusOutlined, EditOutlined, DeleteOutlined, EyeOutlined, LinkOutlined } from '@ant-design/icons';
|
|
|
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
|
|
-import { homeIconClient, fileClient } from '@/client/api';
|
|
|
+import { homeIconClient } from '@/client/api';
|
|
|
import type { HomeIcon } from '@/server/modules/home/home-icon.entity';
|
|
|
import type { File as FileType } from '@/server/modules/files/file.entity';
|
|
|
import type { InferResponseType, InferRequestType } from 'hono/client';
|
|
|
-import MinioUploader from '@/client/admin/components/MinioUploader';
|
|
|
+import FileSelector from '@/client/admin/components/FileSelector';
|
|
|
+import SelectedFilePreview from '@/client/admin/components/SelectedFilePreview';
|
|
|
|
|
|
const { TabPane } = Tabs;
|
|
|
const { TextArea } = Input;
|
|
|
@@ -158,24 +159,7 @@ const HomeIconsPage: React.FC = () => {
|
|
|
};
|
|
|
|
|
|
const [fileModalVisible, setFileModalVisible] = useState(false);
|
|
|
-
|
|
|
- // 获取文件列表
|
|
|
- const { data: filesData } = useQuery({
|
|
|
- queryKey: ['files-for-selection'],
|
|
|
- queryFn: async () => {
|
|
|
- const response = await fileClient.$get({
|
|
|
- query: { page: 1, pageSize: 50, keyword: 'image' }
|
|
|
- });
|
|
|
- if (response.status !== 200) throw new Error('获取文件列表失败');
|
|
|
- return response.json();
|
|
|
- }
|
|
|
- });
|
|
|
|
|
|
- const handleUploadSuccess = (fileKey: string, fileUrl: string, file: any) => {
|
|
|
- message.success('文件上传成功!请在文件管理页面查看文件ID,然后选择文件');
|
|
|
- // 刷新文件列表
|
|
|
- queryClient.invalidateQueries({ queryKey: ['files-for-selection'] });
|
|
|
- };
|
|
|
|
|
|
const handleSelectFile = (file: FileType) => {
|
|
|
form.setFieldsValue({ fileId: file.id });
|
|
|
@@ -369,29 +353,10 @@ const HomeIconsPage: React.FC = () => {
|
|
|
>
|
|
|
{({ getFieldValue }) => {
|
|
|
const fileId = getFieldValue('fileId');
|
|
|
- const selectedFile = filesData?.data?.find((f: FileType) => f.id === fileId);
|
|
|
-
|
|
|
- return fileId && selectedFile ? (
|
|
|
- <div style={{
|
|
|
- padding: '12px',
|
|
|
- backgroundColor: '#f6ffed',
|
|
|
- border: '1px solid #b7eb8f',
|
|
|
- borderRadius: '4px',
|
|
|
- marginBottom: '16px',
|
|
|
- display: 'flex',
|
|
|
- alignItems: 'center',
|
|
|
- gap: '12px'
|
|
|
- }}>
|
|
|
- <Image
|
|
|
- src={selectedFile.path}
|
|
|
- alt={selectedFile.name}
|
|
|
- style={{ width: 60, height: 60, objectFit: 'cover', borderRadius: 4 }}
|
|
|
- />
|
|
|
- <div>
|
|
|
- <div style={{ fontWeight: 'bold' }}>{selectedFile.name}</div>
|
|
|
- <div style={{ color: '#666', fontSize: '12px' }}>ID: {selectedFile.id}</div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
+ // 这里需要重新获取文件信息,或者通过父组件传入选中的文件
|
|
|
+ // 由于我们抽离了组件,这里需要创建一个获取文件详情的query
|
|
|
+ return fileId ? (
|
|
|
+ <SelectedFilePreview fileId={fileId} />
|
|
|
) : (
|
|
|
<div style={{
|
|
|
padding: '8px 12px',
|
|
|
@@ -438,86 +403,17 @@ const HomeIconsPage: React.FC = () => {
|
|
|
<Switch checkedChildren="启用" unCheckedChildren="禁用" />
|
|
|
</Form.Item>
|
|
|
|
|
|
- <Form.Item label="文件上传">
|
|
|
- <MinioUploader
|
|
|
- uploadPath={`/home-icons/${activeTab}`}
|
|
|
- accept="image/*"
|
|
|
- maxSize={5}
|
|
|
- onUploadSuccess={handleUploadSuccess}
|
|
|
- buttonText={`上传${activeTab === 'banner' ? '轮播图' : '分类图标'}`}
|
|
|
- />
|
|
|
- </Form.Item>
|
|
|
</Form>
|
|
|
</Modal>
|
|
|
|
|
|
- {/* 文件选择模态框 */}
|
|
|
- <Modal
|
|
|
- title="选择图标文件"
|
|
|
- open={fileModalVisible}
|
|
|
+ <FileSelector
|
|
|
+ visible={fileModalVisible}
|
|
|
onCancel={() => setFileModalVisible(false)}
|
|
|
- width={800}
|
|
|
- footer={null}
|
|
|
- >
|
|
|
- <div style={{ marginBottom: 16 }}>
|
|
|
- <Button
|
|
|
- type="primary"
|
|
|
- icon={<UploadOutlined />}
|
|
|
- onClick={() => setFileModalVisible(false)}
|
|
|
- style={{ marginRight: 8 }}
|
|
|
- >
|
|
|
- 上传新文件
|
|
|
- </Button>
|
|
|
- <span style={{ color: '#666', fontSize: '12px' }}>
|
|
|
- 提示:先上传文件,然后从列表中选择
|
|
|
- </span>
|
|
|
- </div>
|
|
|
-
|
|
|
- <div style={{ maxHeight: 400, overflowY: 'auto' }}>
|
|
|
- {filesData?.data?.filter((f: FileType) => f.type?.startsWith('image/')).map((file: FileType) => (
|
|
|
- <div
|
|
|
- key={file.id}
|
|
|
- style={{
|
|
|
- display: 'flex',
|
|
|
- alignItems: 'center',
|
|
|
- padding: '12px',
|
|
|
- border: '1px solid #f0f0f0',
|
|
|
- borderRadius: '4px',
|
|
|
- marginBottom: '8px',
|
|
|
- cursor: 'pointer',
|
|
|
- transition: 'all 0.3s'
|
|
|
- }}
|
|
|
- onClick={() => handleSelectFile(file)}
|
|
|
- onMouseEnter={(e) => {
|
|
|
- e.currentTarget.style.backgroundColor = '#f6ffed';
|
|
|
- e.currentTarget.style.borderColor = '#b7eb8f';
|
|
|
- }}
|
|
|
- onMouseLeave={(e) => {
|
|
|
- e.currentTarget.style.backgroundColor = '';
|
|
|
- e.currentTarget.style.borderColor = '#f0f0f0';
|
|
|
- }}
|
|
|
- >
|
|
|
- <Image
|
|
|
- src={file.path}
|
|
|
- alt={file.name}
|
|
|
- style={{ width: 60, height: 60, objectFit: 'cover', borderRadius: 4, marginRight: 12 }}
|
|
|
- />
|
|
|
- <div style={{ flex: 1 }}>
|
|
|
- <div style={{ fontWeight: 'bold', marginBottom: '4px' }}>{file.name}</div>
|
|
|
- <div style={{ color: '#666', fontSize: '12px' }}>
|
|
|
- ID: {file.id} | 大小: {((file.size || 0) / 1024 / 1024).toFixed(2)}MB
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <Button type="primary" size="small">选择</Button>
|
|
|
- </div>
|
|
|
- ))}
|
|
|
- </div>
|
|
|
-
|
|
|
- {(!filesData?.data || filesData.data.filter((f: FileType) => f.type?.startsWith('image/')).length === 0) && (
|
|
|
- <div style={{ textAlign: 'center', padding: '40px', color: '#999' }}>
|
|
|
- 暂无图片文件,请先上传
|
|
|
- </div>
|
|
|
- )}
|
|
|
- </Modal>
|
|
|
+ onSelect={handleSelectFile}
|
|
|
+ accept="image/*"
|
|
|
+ uploadPath={`/home-icons/${activeTab}`}
|
|
|
+ uploadButtonText={`上传${activeTab === 'banner' ? '轮播图' : '分类图标'}`}
|
|
|
+ />
|
|
|
</div>
|
|
|
);
|
|
|
};
|