mirror of
https://github.com/DrizzleTime/Foxel.git
synced 2026-09-08 17:16:50 +08:00
feat: add storage type support and update the configuration interface.
This commit is contained in:
@@ -78,7 +78,8 @@ public class PictureController(IPictureService pictureService,IConfigService con
|
|||||||
request.File.ContentType,
|
request.File.ContentType,
|
||||||
userId,
|
userId,
|
||||||
(PermissionType)request.Permission!,
|
(PermissionType)request.Permission!,
|
||||||
request.AlbumId
|
request.AlbumId,
|
||||||
|
request.StorageType
|
||||||
);
|
);
|
||||||
|
|
||||||
var picture = result.Picture;
|
var picture = result.Picture;
|
||||||
|
|||||||
@@ -10,4 +10,6 @@ public class UploadPictureRequest
|
|||||||
public int? Permission { get; set; } = 1;
|
public int? Permission { get; set; } = 1;
|
||||||
|
|
||||||
public int? AlbumId { get; set; } = null;
|
public int? AlbumId { get; set; } = null;
|
||||||
|
|
||||||
|
public StorageType? StorageType { get; set; } = null;
|
||||||
}
|
}
|
||||||
@@ -32,7 +32,7 @@ public interface IPictureService
|
|||||||
int? userId,
|
int? userId,
|
||||||
PermissionType permission = PermissionType.Public,
|
PermissionType permission = PermissionType.Public,
|
||||||
int? albumId = null,
|
int? albumId = null,
|
||||||
StorageType storageType = StorageType.Telegram
|
StorageType? storageType = null
|
||||||
);
|
);
|
||||||
|
|
||||||
Task<ExifInfo> GetPictureExifInfoAsync(int pictureId);
|
Task<ExifInfo> GetPictureExifInfoAsync(int pictureId);
|
||||||
|
|||||||
@@ -436,13 +436,24 @@ public class PictureService(
|
|||||||
int? userId,
|
int? userId,
|
||||||
PermissionType permission = PermissionType.Public,
|
PermissionType permission = PermissionType.Public,
|
||||||
int? albumId = null,
|
int? albumId = null,
|
||||||
StorageType storageType = StorageType.Local)
|
StorageType? storageType = null)
|
||||||
{
|
{
|
||||||
|
// 如果未指定存储类型,则从配置中获取默认存储类型
|
||||||
|
if (storageType == null)
|
||||||
|
{
|
||||||
|
var defaultStorageTypeStr = configuration["Storage:DefaultStorage"];
|
||||||
|
if (string.IsNullOrEmpty(defaultStorageTypeStr) || !Enum.TryParse<StorageType>(defaultStorageTypeStr, out var defaultStorageType))
|
||||||
|
{
|
||||||
|
defaultStorageType = StorageType.Local; // 如果配置中没有或解析失败,使用本地存储作为默认
|
||||||
|
}
|
||||||
|
storageType = defaultStorageType;
|
||||||
|
}
|
||||||
|
|
||||||
string fileExtension = Path.GetExtension(fileName);
|
string fileExtension = Path.GetExtension(fileName);
|
||||||
string newFileName = $"{Guid.NewGuid()}{fileExtension}";
|
string newFileName = $"{Guid.NewGuid()}{fileExtension}";
|
||||||
|
|
||||||
// 获取对应的存储提供者
|
// 获取对应的存储提供者
|
||||||
var storageProvider = storageProviderFactory.GetProvider(storageType);
|
var storageProvider = storageProviderFactory.GetProvider(storageType.Value);
|
||||||
|
|
||||||
// 使用存储提供者保存文件
|
// 使用存储提供者保存文件
|
||||||
string relativePath = await storageProvider.SaveAsync(fileStream, fileName, contentType);
|
string relativePath = await storageProvider.SaveAsync(fileStream, fileName, contentType);
|
||||||
@@ -493,7 +504,7 @@ public class PictureService(
|
|||||||
User = user,
|
User = user,
|
||||||
Permission = permission,
|
Permission = permission,
|
||||||
AlbumId = albumId,
|
AlbumId = albumId,
|
||||||
StorageType = storageType,
|
StorageType = storageType.Value,
|
||||||
ProcessingStatus = isAnonymous ? ProcessingStatus.Completed : ProcessingStatus.Pending,
|
ProcessingStatus = isAnonymous ? ProcessingStatus.Completed : ProcessingStatus.Pending,
|
||||||
ThumbnailPath = isAnonymous ? relativePath : null
|
ThumbnailPath = isAnonymous ? relativePath : null
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { Tabs, Card, message, Spin } from 'antd';
|
import { Tabs, Card, message, Spin, Select } from 'antd';
|
||||||
|
import { CloudOutlined, DatabaseOutlined } from '@ant-design/icons';
|
||||||
import { getAllConfigs, setConfig } from '../../api';
|
import { getAllConfigs, setConfig } from '../../api';
|
||||||
import ConfigGroup from './ConfigGroup.tsx';
|
import ConfigGroup from './ConfigGroup.tsx';
|
||||||
|
|
||||||
const { TabPane } = Tabs;
|
const { TabPane } = Tabs;
|
||||||
|
const { Option } = Select;
|
||||||
|
|
||||||
interface ConfigStructure {
|
interface ConfigStructure {
|
||||||
[key: string]: {
|
[key: string]: {
|
||||||
@@ -15,6 +17,7 @@ const SystemConfig: React.FC = () => {
|
|||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [configs, setConfigs] = useState<ConfigStructure>({});
|
const [configs, setConfigs] = useState<ConfigStructure>({});
|
||||||
const [activeKey, setActiveKey] = useState('AI');
|
const [activeKey, setActiveKey] = useState('AI');
|
||||||
|
const [storageType, setStorageType] = useState('Telegram');
|
||||||
|
|
||||||
// 获取所有配置项
|
// 获取所有配置项
|
||||||
const fetchConfigs = async () => {
|
const fetchConfigs = async () => {
|
||||||
@@ -32,6 +35,11 @@ const SystemConfig: React.FC = () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
setConfigs(configGroups);
|
setConfigs(configGroups);
|
||||||
|
|
||||||
|
// 设置初始存储类型
|
||||||
|
if (configGroups.Storage?.DefaultStorage) {
|
||||||
|
setStorageType(configGroups.Storage.DefaultStorage);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
message.error('获取配置失败: ' + response.message);
|
message.error('获取配置失败: ' + response.message);
|
||||||
}
|
}
|
||||||
@@ -72,6 +80,13 @@ const SystemConfig: React.FC = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 存储类型选项
|
||||||
|
const storageOptions = [
|
||||||
|
{ value: 'Telegram', label: 'Telegram存储', icon: <CloudOutlined style={{ color: '#0088cc' }} /> },
|
||||||
|
{ value: 'Local', label: '本地存储', icon: <DatabaseOutlined style={{ color: '#52c41a' }} /> },
|
||||||
|
// 未来可以添加更多存储选项
|
||||||
|
];
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchConfigs();
|
fetchConfigs();
|
||||||
}, []);
|
}, []);
|
||||||
@@ -151,11 +166,52 @@ const SystemConfig: React.FC = () => {
|
|||||||
</TabPane>
|
</TabPane>
|
||||||
|
|
||||||
<TabPane tab="存储设置" key="Storage">
|
<TabPane tab="存储设置" key="Storage">
|
||||||
|
<div style={{ marginBottom: 20 }}>
|
||||||
|
<span style={{ marginRight: 8, display: 'inline-block', width: 100 }}>默认存储:</span>
|
||||||
|
<Select
|
||||||
|
value={configs.Storage?.DefaultStorage || 'Telegram'}
|
||||||
|
onChange={(value) => {
|
||||||
|
handleSaveConfig('Storage', 'DefaultStorage', value);
|
||||||
|
}}
|
||||||
|
style={{ width: 200 }}
|
||||||
|
>
|
||||||
|
{storageOptions.map(option => (
|
||||||
|
<Option key={option.value} value={option.value}>
|
||||||
|
<div style={{ display: 'flex', alignItems: 'center' }}>
|
||||||
|
{option.icon}
|
||||||
|
<span style={{ marginLeft: 8 }}>{option.label}</span>
|
||||||
|
</div>
|
||||||
|
</Option>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{ marginBottom: 20 }}>
|
||||||
|
<span style={{ marginRight: 8, display: 'inline-block', width: 100 }}>配置存储:</span>
|
||||||
|
<Select
|
||||||
|
value={storageType}
|
||||||
|
onChange={(value) => {
|
||||||
|
setStorageType(value);
|
||||||
|
}}
|
||||||
|
style={{ width: 200 }}
|
||||||
|
>
|
||||||
|
{storageOptions.map(option => (
|
||||||
|
<Option key={option.value} value={option.value}>
|
||||||
|
<div style={{ display: 'flex', alignItems: 'center' }}>
|
||||||
|
{option.icon}
|
||||||
|
<span style={{ marginLeft: 8 }}>{option.label}</span>
|
||||||
|
</div>
|
||||||
|
</Option>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{storageType === 'Telegram' && (
|
||||||
<ConfigGroup
|
<ConfigGroup
|
||||||
groupName="Storage"
|
groupName="Storage"
|
||||||
configs={{
|
configs={{
|
||||||
"TelegramStorageBotToken": configs.Storage?.["TelegramStorageBotToken"] || '',
|
"TelegramStorageBotToken": configs.Storage?.TelegramStorageBotToken || '',
|
||||||
"TelegramStorageChatId": configs.Storage?.["TelegramStorageChatId"] || ''
|
"TelegramStorageChatId": configs.Storage?.TelegramStorageChatId || ''
|
||||||
}}
|
}}
|
||||||
onSave={handleSaveConfig}
|
onSave={handleSaveConfig}
|
||||||
descriptions={{
|
descriptions={{
|
||||||
@@ -163,6 +219,7 @@ const SystemConfig: React.FC = () => {
|
|||||||
"TelegramStorageChatId": 'Telegram 聊天ID'
|
"TelegramStorageChatId": 'Telegram 聊天ID'
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
</TabPane>
|
</TabPane>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
)}
|
)}
|
||||||
|
|||||||
Reference in New Issue
Block a user