feat(upload): add storage mode selection and retrieval for image uploads

This commit is contained in:
shiyu
2025-06-13 12:32:43 +08:00
parent d4bf9493c1
commit 28ca2387f7
5 changed files with 84 additions and 4 deletions

View File

@@ -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<ActionResult<BaseResult<List<StorageModeResponse>>>> 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<List<StorageModeResponse>>($"Failed to get available storage modes: {ex.Message}", 500);
}
}
[HttpGet("get_modes")]
public async Task<ActionResult<PaginatedResult<StorageModeResponse>>> GetStorageModes(
[FromQuery] int page = 1,

View File

@@ -63,7 +63,7 @@ public class PictureController(IPictureService pictureService, IStorageService s
[HttpPost("upload_picture")]
[Consumes("multipart/form-data")]
public async Task<ActionResult<BaseResult<PictureResponse>>> UploadPicture(
[FromForm] UploadPictureRequest request)
[FromForm] UploadPictureRequest request) // UploadPictureRequest 模型需要添加 StorageModeId 属性
{
if (request.File.Length == 0)
return Error<PictureResponse>("没有上传文件");
@@ -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;

View File

@@ -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<BaseResult<PictureResponse>> {
@@ -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<string, string> = {};

View File

@@ -139,6 +139,14 @@ export const getStorageTypes = async (): Promise<BaseResult<StorageTypeResponse[
);
};
// 获取可用的存储模式 (通常是启用的模式,用于选择)
export const getAvailableStorageModes = async (): Promise<BaseResult<StorageModeResponse[]>> => {
return fetchApi<StorageModeResponse[]>(
'/management/storage/get_available_modes',
{ method: 'GET' }
);
};
// 获取默认存储模式ID
export const getDefaultStorageModeId = async (): Promise<BaseResult<number | null>> => {
return fetchApi<number | null>(

View File

@@ -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<UploadDialogProps> = ({ visible, onClose, onUp
const [uploading, setUploading] = useState(false);
const [form] = Form.useForm();
const [albums, setAlbums] = useState<AlbumResponse[]>([]);
const [availableStorageModes, setAvailableStorageModes] = useState<StorageModeResponse[]>([]); // 新增状态
const [concurrentUploads, setConcurrentUploads] = useState<number>(3);
useEffect(() => {
if (visible) {
fetchAlbums();
fetchStorageModes(); // 新增调用
}
}, [visible]);
@@ -38,6 +41,26 @@ const ImageUploadDialog: React.FC<UploadDialogProps> = ({ 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<UploadDialogProps> = ({ visible, onClose, onUp
const params: {
permission?: number;
albumId?: number;
storageModeId?: number; // 新增
} = {};
if (values.permission !== undefined) {
@@ -86,6 +110,9 @@ const ImageUploadDialog: React.FC<UploadDialogProps> = ({ 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<UploadDialogProps> = ({ 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<UploadDialogProps> = ({ visible, onClose, onUp
initialValues={{
permission: 2,
concurrentUploads: 3
// storageModeId: undefined // 可以设置一个初始值或留空
}}
>
<Form.Item
@@ -332,6 +360,19 @@ const ImageUploadDialog: React.FC<UploadDialogProps> = ({ visible, onClose, onUp
</Select>
</Form.Item>
{/* 新增:存储模式选择 */}
<Form.Item
name="storageModeId"
label="选择存储模式"
rules={[{ required: true, message: '请选择存储模式!' }]}
>
<Select placeholder="选择图片存储模式">
{availableStorageModes.map(mode => (
<Option key={mode.id} value={mode.id}>{mode.name} ({mode.storageTypeName})</Option>
))}
</Select>
</Form.Item>
<Form.Item
name="permission"
label="图片权限"