feat: SFTP 上传的文件经磁盘扫描补录后可在文件浏览页展示
SFTP 上传的文件直接落盘到 upload_root(chroot 根),不经 HTTP 路径,无 DB 记录, 文件浏览页(读 uploaded_file 表)看不到。新增磁盘扫描机制: - UploadService.scan_sftp_files(force=False):遍历 uploads/ 下所有文件(排除 .work/ 与 .part 残品),与 DB 已有 storage_path 比对,磁盘有 DB 无的补录(source="sftp", 流式算 size + sha256)。 - 频率限制:模块级 _last_scan_time,两次扫描间隔 < 3s 则跳过返回 0(只读 DB 缓存), force=True 强制扫。 - file_admin_controller 的 list 接口返回前触发 scan_sftp_files(),文件浏览页打开/ 刷新即自动同步 SFTP 文件(受 3s 频率限制,不会每次翻页都扫磁盘)。 - UploadedFileDAO 加 list_storage_paths() 批量查已记录路径集合供比对。 SFTP 文件补录后可正常下载/删除(与 HTTP 上传文件一致)。
This commit is contained in:
@@ -29,6 +29,11 @@ class UploadedFileDAO:
|
||||
"""返回数据库中文件总条数。"""
|
||||
return self.db.scalar(select(func.count()).select_from(UploadedFile)) or 0
|
||||
|
||||
def list_storage_paths(self) -> set[str]:
|
||||
"""返回所有已记录的 storage_path 集合(供磁盘扫描比对,识别未入库文件)。"""
|
||||
stmt = select(UploadedFile.storage_path)
|
||||
return {row for row in self.db.scalars(stmt).all()}
|
||||
|
||||
def list(self, limit: int = 100, offset: int = 0) -> list[UploadedFile]:
|
||||
stmt = (
|
||||
select(UploadedFile)
|
||||
|
||||
Reference in New Issue
Block a user