mirror of
https://github.com/DrizzleTime/Foxel.git
synced 2026-05-12 02:20:28 +08:00
feat(upload): add storage mode selection and retrieval for image uploads
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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> = {};
|
||||
|
||||
@@ -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>(
|
||||
|
||||
@@ -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="图片权限"
|
||||
|
||||
Reference in New Issue
Block a user