fix(storage): 修复存储目标编辑不显示配置 & 添加文件列表API

- fix(storage): StorageOut 增加 config 字段并解密返回,编辑时可回填
- fix(storage): Storage ORM 模型添加 config property 支持序列化
- fix(env): 修正 SECRET_KEY 截断、FERNET_KEY 非法占位符问题
- fix(deploy): 后端从 Docker 容器迁移到 systemd 服务,存储目标路径改为宿主机真实路径
- feat(api): 新增 GET /api/storages/{id}/files 文件浏览端点
- feat(frontend): 新增 listFiles API 调用
- docs: 更新 README 反映部署方式变更
This commit is contained in:
Your Name
2026-07-27 13:45:18 +08:00
parent 07b2016f33
commit e7fba5abe5
11 changed files with 188 additions and 85 deletions
+3 -3
View File
@@ -15,9 +15,9 @@ server {
try_files $uri $uri/ /index.html;
}
# 反代到后端
# 反代到宿主机后端(不再使用 Docker 网络)
location /api/ {
proxy_pass http://backend:8000;
proxy_pass http://10.168.1.209:8765;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
@@ -32,7 +32,7 @@ server {
# 健康检查透传
location /api/health {
proxy_pass http://backend:8000/api/health;
proxy_pass http://10.168.1.209:8765/api/health;
}
# 缓存静态资源
+3
View File
@@ -1,6 +1,7 @@
import { api } from './client'
import type {
StorageCreate,
StorageFile,
StorageOut,
StorageTestResponse,
StorageUpdate,
@@ -16,4 +17,6 @@ export const storageApi = {
remove: (id: number) => api.delete(`/storages/${id}`).then((r) => r.data),
test: (id: number) =>
api.post<StorageTestResponse>(`/storages/${id}/test`).then((r) => r.data),
listFiles: (id: number, prefix?: string) =>
api.get<StorageFile[]>(`/storages/${id}/files`, { params: { prefix: prefix || '' } }).then((r) => r.data),
}
+15 -3
View File
@@ -63,12 +63,24 @@ export function Storages() {
const onEdit = (row: StorageOut) => {
setEditing(row)
form.resetFields()
form.setFieldsValue({
const vals: FormValues = {
name: row.name,
type: row.type,
is_default: row.is_default,
// config 明文不返回(后端不暴露),让用户重填
})
}
// 从后端返回的解密 config 中回填字段
if (row.type === 'local' && row.config?.path) {
vals.local_path = row.config.path
} else if (row.type === 's3' && row.config) {
vals.s3_endpoint_url = row.config.endpoint_url || ''
vals.s3_region = row.config.region || 'us-east-1'
vals.s3_bucket = row.config.bucket || ''
vals.s3_access_key = row.config.access_key || ''
// secret_key 不回填(安全)
vals.s3_use_ssl = row.config.use_ssl ?? true
vals.s3_path_prefix = row.config.path_prefix || ''
}
form.setFieldsValue(vals)
setOpen(true)
}
+7
View File
@@ -24,6 +24,7 @@ export interface StorageOut {
name: string
type: 'local' | 's3'
is_default: boolean
config: Record<string, any>
created_at: string
updated_at: string
}
@@ -61,6 +62,12 @@ export interface StorageTestResponse {
message: string
}
export interface StorageFile {
key: string
size: number
last_modified: string
}
// ===== Job =====
export interface MySQLSourceConfig {
host: string