From 28ca2387f7c0f84f0d7f5713521e6c271e26f953 Mon Sep 17 00:00:00 2001 From: shiyu Date: Fri, 13 Jun 2025 12:32:43 +0800 Subject: [PATCH] feat(upload): add storage mode selection and retrieval for image uploads --- Api/Management/StorageManagementController.cs | 25 +++++++++++ Api/PictureController.cs | 6 +-- Web/src/api/pictureApi.ts | 6 +++ Web/src/api/storageManagementApi.ts | 8 ++++ .../components/upload/ImageUploadDialog.tsx | 43 ++++++++++++++++++- 5 files changed, 84 insertions(+), 4 deletions(-) diff --git a/Api/Management/StorageManagementController.cs b/Api/Management/StorageManagementController.cs index 3c4dc59..f68bc03 100644 --- a/Api/Management/StorageManagementController.cs +++ b/Api/Management/StorageManagementController.cs @@ -13,6 +13,31 @@ namespace Foxel.Api.Management; [Route("api/management/storage")] public class StorageManagementController(IStorageManagementService storageManagementService) : BaseApiController { + [AllowAnonymous] + [HttpGet("get_available_modes")] + public async Task>>> GetAvailableStorageModes() + { + try + { + var result = await storageManagementService.GetStorageModesAsync(); + var filteredModes = result.Data! + .Where(mode => mode.IsEnabled) + .Select(mode => new StorageModeResponse + { + Id = mode.Id, + Name = mode.Name, + StorageType = mode.StorageType, + IsEnabled = mode.IsEnabled + }) + .ToList(); + return Success(filteredModes, "Available storage modes retrieved successfully."); + } + catch (Exception ex) + { + return Error>($"Failed to get available storage modes: {ex.Message}", 500); + } + } + [HttpGet("get_modes")] public async Task>> GetStorageModes( [FromQuery] int page = 1, diff --git a/Api/PictureController.cs b/Api/PictureController.cs index 9c98db4..7cb504d 100644 --- a/Api/PictureController.cs +++ b/Api/PictureController.cs @@ -63,7 +63,7 @@ public class PictureController(IPictureService pictureService, IStorageService s [HttpPost("upload_picture")] [Consumes("multipart/form-data")] public async Task>> UploadPicture( - [FromForm] UploadPictureRequest request) + [FromForm] UploadPictureRequest request) // UploadPictureRequest 模型需要添加 StorageModeId 属性 { if (request.File.Length == 0) return Error("没有上传文件"); @@ -87,9 +87,9 @@ public class PictureController(IPictureService pictureService, IStorageService s stream, request.File.ContentType, userId, - (PermissionType)request.Permission!, + (PermissionType)request.Permission!, // 确保 PermissionType 的转换是安全的 request.AlbumId, - request.StorageModeId + request.StorageModeId // 传递 StorageModeId ); var picture = result.Picture; diff --git a/Web/src/api/pictureApi.ts b/Web/src/api/pictureApi.ts index 96230f7..a3ed0e6 100644 --- a/Web/src/api/pictureApi.ts +++ b/Web/src/api/pictureApi.ts @@ -73,6 +73,7 @@ export const ImageFormat = { export interface UploadPictureParams { permission?: number; albumId?: number; + storageModeId?: number; // 新增:存储模式ID convertToFormat?: ImageFormat; quality?: number; onProgress?: (percent: number) => void; @@ -208,6 +209,7 @@ export async function uploadPicture( data: { permission?: number; albumId?: number; + storageModeId?: number; // 新增 onProgress?: (percent: number) => void } = {} ): Promise> { @@ -222,6 +224,10 @@ export async function uploadPicture( formData.append('albumId', data.albumId.toString()); } + if (data.storageModeId !== undefined) { // 新增:添加 storageModeId 到 FormData + formData.append('storageModeId', data.storageModeId.toString()); + } + try { const token = localStorage.getItem('token'); const headers: Record = {}; diff --git a/Web/src/api/storageManagementApi.ts b/Web/src/api/storageManagementApi.ts index 58fda42..3c39647 100644 --- a/Web/src/api/storageManagementApi.ts +++ b/Web/src/api/storageManagementApi.ts @@ -139,6 +139,14 @@ export const getStorageTypes = async (): Promise> => { + return fetchApi( + '/management/storage/get_available_modes', + { method: 'GET' } + ); +}; + // 获取默认存储模式ID export const getDefaultStorageModeId = async (): Promise> => { return fetchApi( diff --git a/Web/src/components/upload/ImageUploadDialog.tsx b/Web/src/components/upload/ImageUploadDialog.tsx index ef41576..8e31eb2 100644 --- a/Web/src/components/upload/ImageUploadDialog.tsx +++ b/Web/src/components/upload/ImageUploadDialog.tsx @@ -4,6 +4,7 @@ import { InboxOutlined } from '@ant-design/icons'; import { v4 as uuidv4 } from 'uuid'; import type { UploadFile, AlbumResponse } from '../../api'; import { uploadPicture, getAlbums } from '../../api'; +import { getAvailableStorageModes, type StorageModeResponse } from '../../api/storageManagementApi'; // 新增导入 const { Dragger } = Upload; const { Option } = Select; @@ -19,11 +20,13 @@ const ImageUploadDialog: React.FC = ({ visible, onClose, onUp const [uploading, setUploading] = useState(false); const [form] = Form.useForm(); const [albums, setAlbums] = useState([]); + const [availableStorageModes, setAvailableStorageModes] = useState([]); // 新增状态 const [concurrentUploads, setConcurrentUploads] = useState(3); useEffect(() => { if (visible) { fetchAlbums(); + fetchStorageModes(); // 新增调用 } }, [visible]); @@ -38,6 +41,26 @@ const ImageUploadDialog: React.FC = ({ visible, onClose, onUp } }; + // 新增:获取可用存储模式 + const fetchStorageModes = async () => { + try { + const result = await getAvailableStorageModes(); + if (result.success && result.data) { + setAvailableStorageModes(result.data); + // 尝试设置默认存储模式ID(如果后端有此逻辑,或者选择第一个作为默认) + if (result.data.length > 0) { + // 这里可以根据业务逻辑设置一个默认选中的 storageModeId + // form.setFieldsValue({ storageModeId: result.data[0].id }); + } + } else { + message.error('获取存储模式列表失败: ' + result.message); + } + } catch (error) { + console.error('获取存储模式列表失败:', error); + message.error('获取存储模式列表失败'); + } + }; + const handleBeforeUpload = (file: File) => { // 检查是否为图片文件 const isImage = file.type.startsWith('image/'); @@ -78,6 +101,7 @@ const ImageUploadDialog: React.FC = ({ visible, onClose, onUp const params: { permission?: number; albumId?: number; + storageModeId?: number; // 新增 } = {}; if (values.permission !== undefined) { @@ -86,6 +110,9 @@ const ImageUploadDialog: React.FC = ({ visible, onClose, onUp if (values.albumId) { params.albumId = values.albumId; } + if (values.storageModeId) { // 新增 + params.storageModeId = values.storageModeId; + } let successCount = 0; let failCount = 0; @@ -103,7 +130,7 @@ const ImageUploadDialog: React.FC = ({ visible, onClose, onUp try { // 上传文件 const result = await uploadPicture(item.file, { - ...params, + ...params, // 传递包含 storageModeId 的 params onProgress: (percent) => { setUploadQueue((prev) => prev.map(file => file.id === item.id ? { ...file, percent } : file) @@ -319,6 +346,7 @@ const ImageUploadDialog: React.FC = ({ visible, onClose, onUp initialValues={{ permission: 2, concurrentUploads: 3 + // storageModeId: undefined // 可以设置一个初始值或留空 }} > = ({ visible, onClose, onUp + {/* 新增:存储模式选择 */} + + + +