e7fba5abe5
- 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 反映部署方式变更
38 lines
1.4 KiB
Python
38 lines
1.4 KiB
Python
from datetime import datetime
|
|
|
|
from sqlalchemy import Boolean, DateTime, Integer, String, Text, func
|
|
from sqlalchemy.orm import Mapped, mapped_column
|
|
|
|
from app.database import Base
|
|
|
|
|
|
class Storage(Base):
|
|
"""备份目标存储(local 路径 或 S3 桶)。
|
|
|
|
config_json 是 Fernet 加密的 JSON 字符串,结构因 type 而异:
|
|
- local: {"path": "/data/backups"}
|
|
- s3: {"endpoint_url": "...", "region": "...", "bucket": "...",
|
|
"access_key": "...", "secret_key": "...", "use_ssl": true,
|
|
"path_prefix": "optional/prefix"}
|
|
"""
|
|
|
|
__tablename__ = "storages"
|
|
|
|
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
|
name: Mapped[str] = mapped_column(String(64), unique=True, nullable=False)
|
|
type: Mapped[str] = mapped_column(String(16), nullable=False) # 'local' / 's3'
|
|
config_json: Mapped[str] = mapped_column(Text, nullable=False)
|
|
is_default: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)
|
|
created_at: Mapped[datetime] = mapped_column(
|
|
DateTime, server_default=func.now(), nullable=False
|
|
)
|
|
updated_at: Mapped[datetime] = mapped_column(
|
|
DateTime, server_default=func.now(), onupdate=func.now(), nullable=False
|
|
)
|
|
|
|
@property
|
|
def config(self) -> dict:
|
|
"""解密 config_json 返回 dict,支持 from_attributes 序列化。"""
|
|
from app.utils.crypto import decrypt_dict
|
|
return decrypt_dict(self.config_json)
|