Skip to content

PAPE3Qu/HBCloud.Web

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

HBCloud 开放网盘

面向使用者的说明放在本文件;面向开发者的说明见 README_DEV.md。

HBCloud 是院内使用的轻量网盘系统:前端 Vue 3 + Vite,后端 FastAPI;文件落盘存储,SQLite 保存用户/回收站/审计索引等结构化信息。

快速上手

这是给“只想赶紧用起来”的同事看的简短提示,更详细的说明在后面章节中。

日常用得最多的 8 件事:

  1. 登录:用「手机号 + 密码」登录,右上角可以随时点「登出」。
  2. 切换空间:左侧点「文件浏览」,上方在「公共空间 / 部门空间 / 个人保险库」之间切换。
  3. 浏览文件夹:双击文件夹进入下级目录,点「首页 / 上级」可以返回。
  4. 上传文件:先进到目标文件夹,点「上传文件」,选中本地文件即可,大文件会自动分片上传。
  5. 整理文件:用「新建文件夹」「重命名」整理结构,勾选后可以「移动到」或「复制到」别的空间/目录。
  6. 打包下载:勾选多个文件或文件夹,点「打包下载」,系统会先压缩再自动开始下载。
  7. 删除与回收站:在文件页删除的内容会先进入「回收站」,左侧有入口,可以在回收站里还原或彻底删除。
  8. 查看使用情况:在列表中点某个文件的「详情」,可以看到下载次数、最近访问时间和最近是谁改过。

本次版本在原有功能不变的基础上,新增/增强了几项能力:

  • 统一了后端日志写入接口:按日期输出文本运行日志到 data/log/,并通过审计接口输出结构化 JSON 审计日志;
  • 文件浏览页新增「固定到快速访问」能力,可以把常用目录收藏成快捷入口;
  • 新增分享链接接口,为单个文件/文件夹生成短链接,便于在其他系统或 IM 中分享;
  • 后端补充分离的用户管理接口,配合前端用户管理页做账号启停用与角色调整;
  • 为上述功能配套增加了少量 SQLite 数据库文件,用于保存收藏夹、分享链接等结构化数据。

下面是原有的详细使用说明和运维文档,如需了解更多细节(权限、统计、备份策略等),可以继续往下看。

本次修复与优化(2026-01-14)

本次迭代以文件浏览页交互与响应式布局为主,主要改动如下:

  • 修复:进入子目录时勾选残留:在文件浏览页勾选后进入子目录,上级目录的选中状态不再残留。
  • 面包屑导航防遮挡(碰撞箱):当面包屑内容与右侧功能区发生空间冲突时,优先从左侧开始隐藏目录段,并使用 ... 表示折叠,确保最右侧目录(当前层级)不会被按钮遮挡。
  • 面包屑最少保留两层:在空间允许时至少保留最后两层目录,便于快速回退到上一级。
  • 第二行紧凑模式:在极端窄屏下,第二行按钮可切换为仅图标以释放空间;若仍不足,则允许右侧按钮向外溢出,而不是覆盖面包屑。
  • 第一行与面包屑解耦:第一行功能按钮不再参与面包屑的碰撞处理逻辑,避免出现竖向错层造成的误判。

本次修复与优化(2026-01-09)

本次迭代以提升大文件打包稳定性与前端体验为主,主要改动如下:

  • 打包下载限制:后端在打包入口增加了可配置的大小阈值(默认 1GB),超限返回明确错误并由前端展示友好提示。
  • 前端提示与校验:在附件选择器与文件浏览页增加已选总大小实时展示与 1GB 警示文案;对文件夹选中会异步请求后端目录大小并累加到总量中。
  • 轻量异步打包:新增轻量异步打包模块(JSON 任务存储 + 后台 worker),新增 API /api/files/pack-async(提交任务)和 /api/files/pack-status(轮询状态),避免长请求超时;并对异步任务做并发限制(并发数=2)。
  • 后端目录大小接口:新增 /api/files/dir-size 接口,用于计算目录实际大小,供前端在选择文件夹时查询。
  • 快速访问(收藏)优化:修复单次点击打开快速访问面板的时序问题(使用路由 query 触发并在文件页 mount 时处理);点击快速访问可在跳转时打开面板(仅打开弹窗,不自动选中文件/目录)。
  • 详情面板交互改进:详情侧栏增加遮罩层,点击遮罩或页面其它位置即可关闭(除面板内部点击外)。
  • 移动/复制弹窗:在选择目标为部门空间时不再自动预选部门,改为等待用户手动选择。
  • 动态页预览修复:修复首页动态页 PDF/图片预览的 URL 构建与预览行为,移除调试日志,确保 disposition=inline 能正常工作。
  • 开发环境改进:调整 vite.config.js 强制监听 127.0.0.1 避免 IPv6 导致的跨域/请求失败问题;修复登录重定向(去掉多余的 # 片段)。
  • 若干错误处理与审计兼容性:保留现有同步打包接口以作回退,异步实现会在任务关键点调用现有审计点(start/finish/fail),并将打包阈值提取为配置项以便调整。

如需回退或调整阈值,请在 backend/config.py 中修改 PACK_MAX_SIZE_BYTES(或通过环境变量覆盖)。


HBCloud 河北分院开放网盘 使用说明

适用对象:全院内部用户、各科室管理员、系统管理员
系统组成:后端(FastAPI)、前端(Vue 3 + Vite)、存储目录(data/public、data/departments、data/safe 等)


技术栈与运行环境(与当前代码一致)

后端

  • 语言:Python 3.8.10(项目当前可在 Windows 环境运行)
  • Web 框架:FastAPI
  • 鉴权:JWT(前端存 localStorage,后端校验 exp 过期)
  • 存储:以文件系统为主 + SQLite 辅助索引
    • data/users.db:用户/角色/部门权限组(含 dept_roles 表)
    • data/recycle_bin.db:回收站回收记录(recycle_items 表)
    • data/audit_index/file_detail.db:文件详情统计索引(下载次数、最后访问/编辑)
  • 压缩/打包:后端负责生成 ZIP 并提供下载

前端

  • 框架:Vue 3(Composition API)
  • 构建:Vite
  • 路由:Vue Router
  • HTTP:Axios
  • 页面:
    • 文件浏览:src/views/FileBrowser.vue
    • 回收站:src/views/RecycleBin.vue
    • 空间权限(部门空间开放/关闭、部门成员/管理员配置):src/views/SpacePermission.vue
    • 用户管理:src/views/UserManage.vue(通过 /api/users/* 接口对账号做启停用、角色调整等)

目录

  1. 总体功能概览
  2. 登录与账号
  3. 空间类型与权限
  4. 文件浏览与基本操作
  5. 压缩、解压与打包下载
  6. 移动与复制
  7. 文件详情统计
  8. 部门空间管理
  9. 首页动态与附件
  10. 留言反馈
  11. 后台数据存储结构
  12. 使用建议与注意事项
  13. 批量导入用户账号
  14. 删除用户账号
  15. 代码结构(开发者)
  16. 权限角色说明(矩阵)
  17. 分享链接功能
  18. 账号管理与日志

总体功能概览

HBCloud 河北分院开放网盘主要功能:

  • 统一的文件存储与共享(公共空间 / 部门空间 / 个人保险库)
  • 文件浏览、上传、下载、预览、搜索
  • 压缩/解压、打包下载、移动、复制
  • 部门空间管理(创建/删除部门)
  • 首页动态发布与附件关联
  • 文件访问与编辑行为统计(下载次数、最后访问时间、最后编辑人/时间)
  • 用户反馈收集

前端主要页面:

  • 首页:公告动态、附件一键打包下载、使用小贴士、留言反馈
  • 文件浏览:所有空间的文件管理操作入口
  • 登录页:登录、注册、修改密码

登录与账号

  • 登录方式:手机号 + 密码
  • 注册:
    • 由管理员提供邀请码,用户可在登录页切换到「注册」标签,自助注册账号;
    • 注册成功后自动登录并跳转到首页。
  • 安全策略:
    • 密码连续输错 5 次,账号会被暂时锁定约 5 分钟;
    • JWT 登录凭证默认有效期为 24 小时,超过有效期需要重新登录;
    • 后端对 exp 到期的 token 自动判定为失效并返回 401,前端会自动清除本地登录信息并跳转到登录页。
  • 修改密码:
    • 在登录页卡片右侧有「修改密码」小字入口;
    • 填写:手机号、原密码、新密码、确认新密码;
    • 成功后会提示重新登录,同时本地登录状态会被清除;
    • 忘记密码请联系系统管理员协助重置。
  • 退出登录:
    • 顶部点击「登出」,系统会清除本地 hbcloud_token / hbcloud_user 并跳转登录页。

后端用户存储已切换为 SQLite:

  • 数据库文件:data/users.db
  • 表结构:users(id, phone, name, password_hash, role, is_active, created_at, updated_at, login_failed_count, login_locked_until)
  • 密码加密:使用 pbkdf2_sha256(通过 passlib.context.CryptContext 实现)。

空间类型与权限

系统当前支持三类空间:公共空间(public)、部门空间(department)、个人保险库(safe)。

公共空间(public)

  • 位置:data/public/
  • 用途:院内统一共享的制度文件、模板、流程说明等。
  • 权限:具备访问权限的用户均可浏览、下载;上传/修改权限由部署策略决定。

部门空间(department)

  • 位置:data/departments/<departmentId>/
  • 用途:各科室/部门内部资料。
  • 结构:
    • 每个部门有独立目录 <departmentId>/
    • config.json 内保存部门名称、创建人信息及删除密码哈希等;
  • 权限:
    • 一般仅对应部门成员及管理员可访问;
    • 超级管理员可管理所有部门空间。

部门“权限组配置”(dept_roles)

部门管理员/成员关系存储在 data/users.dbdept_roles 表:

  • dept:部门管理员
  • member:部门成员

前端在「空间权限」页面提供配置入口:

  • 设置部门空间是否开放(isOpen
  • 配置部门管理员/成员手机号列表

个人保险库(safe)

  • 位置:data/safe/<手机号>/
  • 用途:与个人相关的工作资料、敏感信息或草稿等,仅本人可见。
  • 权限:
    • 普通用户:只能访问自己手机号对应的目录(如 data/safe/189xxxxxxx/);
    • 超级管理员:可在特定排错场景下访问所有保险库目录。

文件浏览与基本操作

路径与导航

在「文件浏览」页面:

  • 顶部可选择:空间类型(公共/部门/保险库)、部门(仅当空间为 department 时);
  • 路径导航:
    • 「首页」按钮:回到当前空间的根路径;
    • 「上级」按钮:返回上一级目录;
    • 中间显示当前路径:如 当前路径:/docs/sub

上传文件

  • 支持多文件普通上传;
  • 当单个文件较大(> 指定阈值)时,自动启用分片上传:
    • 前端按片上传,后端合并校验大小和 MD5;
    • 校验失败会删除临时文件并返回错误。

新建文件夹

  • 按钮:「新建文件夹」;
  • 约束:
    • 名称不能为空;
    • 不能包含 \ / < > | : ? * 等非法字符;
    • 不允许同一目录下重名。

重命名

  • 支持文件/文件夹重命名;
  • 重命名后:
    • 同一文件视为延续,下载次数和访问记录会一并迁移到新名称;
    • 最后编辑人/时间更新为当前操作者与当前时间。

删除与回收站

  • 支持批量删除与单条删除;
  • 在「文件浏览」页执行的删除,默认为软删除
    • 文件/文件夹不会立即从磁盘物理删除,而是移动到后端的回收站目录 data/recycle/...
    • 同时在 data/recycle_bin.db 中写入一条回收记录;
    • 在文件详情统计库 file_detail.db 中,原有的下载次数、访问时间等不会立刻被清理;
  • 回收站:
    • 左侧导航有「回收站」入口,可查看当前账号有权限看到的所有已删除项;
    • 支持按类型(全部 / 文件/文件夹 / 部门)、空间(所有空间 / public / department / safe)及关键字(名称或原路径)筛选;
    • 支持勾选后批量操作:
      • 还原选中:将选中的文件/文件夹/部门恢复到原空间与原路径(若原位置已有同名项,会自动重命名为 xxx(恢复) / xxx(恢复-n));
      • 彻底删除选中:物理删除对应文件/目录,同时清除文件详情索引(对普通文件调用 delete_meta),操作不可恢复;
    • 超级管理员还可以使用「清空回收站」按钮,一次性彻底删除所有回收项;
  • 前端删除提示文案已更新为软删除语义,例如:
    • 批量删除:将把选中的 N 个项目移入回收站,可在回收站中恢复或彻底删除,是否继续?
    • 单个删除:将把“xxx”移入回收站,可在回收站中恢复或彻底删除,是否继续?

下载与预览

  • 单文件操作列提供「下载」;
  • 支持图片、PDF 等在新标签页预览;
  • 实现:统一使用 /api/files/download
    • disposition=attachment 用于下载;
    • disposition=inline 用于预览;
  • 统计:
    • 仅 GET 请求计为一次真实访问(无论 inline 还是 attachment);
    • HEAD 请求只用于探测,不计入访问次数。

搜索

  • 范围:当前目录及其子目录;
  • 方式:输入关键字后回车或点击「搜索」;
  • 支持文件名模糊匹配;
  • 「清除搜索」可恢复普通文件列表。

固定到快速访问(收藏夹)

功能入口在文件浏览页左侧「快速访问」区域,配合后端 /api/files/favorites 系列接口使用。

  • 在某个目录中,可以通过前端提供的「固定到快速访问」按钮/操作,将当前路径加入个人收藏列表;
  • 已收藏的目录会显示在左侧「快速访问」区域,点击即可一键跳转;
  • 后端使用 data/favorite_paths.db(表 favorite_paths)保存收藏记录,按手机号(user_phone)、空间类型(space_type)、部门 ID(department_id)、路径(path)和显示名(display_name)进行区分;
  • 当使用脚本 backend/tools/delete_user_by_phone.py 删除某个账号时,会自动调用收藏服务清理该用户在 favorite_paths.db 中的相关记录,避免产生无主数据。

压缩、解压与打包下载

压缩为 ZIP

  • 至少选中一个文件或文件夹;
  • 通过「压缩」按钮,将多个项目打包成 ZIP;
  • 生成的 ZIP 位于当前目录,可再次下载或解压。

解压 ZIP

  • 必须选中一个 .zip 文件;
  • 支持选择是否覆盖同名文件;
  • 解压后新产生的文件会根据后续访问/编辑行为自动建立统计数据。

文件浏览器中的打包下载

  • 勾选多个项目后使用「打包下载」:
    • 前端调用 /api/files/pack-temp 在公共空间的临时目录生成 ZIP;
    • 再使用 /api/files/download 进行实际下载;
  • 打包时:
    • 不存在的文件会被跳过,不会中断整个打包过程;
    • 若全部选中项都已不存在,则接口会返回错误提示;
  • 所有被打入 ZIP 的源文件,其下载次数和最后访问时间都会增加/更新一次。

首页动态附件的打包下载

  • 首页每条动态支持「打包下载全部附件」;
  • 行为:
    • 前端同样通过 /api/files/pack-temp 生成临时 ZIP;
    • 部分附件不存在时:
      • 仍然生成 ZIP,包含所有仍存在的附件;
      • 后端返回缺失数量 missingCount,前端会提示「有 N 个附件已不存在或被移动」;
    • 所有附件都不存在时:
      • /pack-temp 返回 400,前端提示无法打包下载。

移动与复制

移动到

  • 支持跨空间、跨部门移动:
    • 公共 ↔ 部门 ↔ 个人保险库;
  • 冲突策略:
    • 跳过:保留目标同名,跳过本条移动;
    • 覆盖:删除目标同名项后再移动;
  • 统计:
    • 下载次数、最后访问时间、最后编辑信息会随同移动;
    • 本次移动行为会更新最后编辑人/时间;
  • 体验:
    • 移动成功后,文件浏览器会自动跳转到目标空间与目标目录,并刷新列表,方便立即查看移动结果。

复制到

  • 行为:
    • 支持跨空间复制;
    • 目标文件视为全新文件:下载次数从 0 开始,最后编辑人为执行复制的用户;
    • 源文件的统计保持不变;
  • 体验:
    • 复制成功后,文件浏览器同样会自动跳转到目标空间与目标目录,便于检查新副本。

文件详情统计

在文件列表中点击「详情」,可查看该文件的:

  • 下载次数;
  • 最后访问时间;
  • 最后编辑人;
  • 最后编辑时间。

数据源为 SQLite 索引库:data/audit_index/file_detail.db

更新规则

  • 下载次数 / 最后访问时间
    • 单文件下载(inline/attachment)或参与打包下载时都会累计;
  • 最后编辑信息
    • 上传、重命名、移动、复制(目标文件)、解压、从回收站还原等操作会更新最后编辑人和时间;
  • 删除:
    • 在文件页执行删除时,文件实际被移入回收站,file_detail.db 中对应记录不会立即删除
    • 只有在回收站执行「彻底删除」时,后端才会调用 delete_meta 清理对应的统计记录;
    • 因此,同一个文件先被删除再从回收站还原,其历史统计数据会被延续,并在还原时追加一次编辑记录。

清理过期统计数据

  • 提供维护接口:POST /api/maintenance/clear-file-detail
    • 仅超级管理员可调用;
    • 调用后会清空 file_detail 表中的所有统计记录;
    • 实际文件不受影响,后续访问/编辑会重新建立新的统计数据。

部门空间管理

  • 「文件浏览」页提供:
    • 新建部门:设置部门 ID、名称和 6 位删除密码;
    • 删除部门:需输入正确删除密码或由超级管理员直接删除;
  • 删除部门属于不可逆操作
    • 目录会进入回收站,仅作为“文件内容恢复兜底”;
    • 部门权限组配置与文件统计索引等数据库信息会在删除时清理,不随还原自动恢复。

首页动态与附件

  • 首页支持发布动态(公告/更新说明):标题、正文、发布者、所属部门等;
  • 支持添加来自公共/部门空间的附件:最多 5 个文件或 1 个文件夹(不可混用);
  • 已发布动态:
    • 发布人本人可编辑/删除;
    • 超级管理员可管理所有动态;
    • 其他用户只能查看和下载附件;
  • 动态中的附件若被后续移动或删除:
    • 单个附件点击时,如资源不存在会提示已被移动/删除;
    • 批量打包下载时,会提示哪些附件已失效,仅打包当前仍存在的部分。

留言反馈

  • 右侧「留言 / 反馈」支持提交使用建议和问题;
  • 后端统一写入 data/feedbacks.json,仅管理员在后台查看;
  • 已收到的反馈数量会显示在首页侧栏。

后台数据存储结构

主要目录和文件(默认根目录:data/):

  • data/public/:公共空间文件
    • __packs__/:打包下载生成的临时 ZIP
  • data/departments/:部门空间
    • <deptId>/:部门目录
      • config.json:部门配置(名称、创建人、删除密码哈希等)
  • data/safe/:个人保险库
    • <phone>/:每个手机号私有目录
  • data/recycle/:回收站物理存储根目录
    • common/YYYYMM/<id>/<文件或文件夹>:公共/部门空间中被软删除的文件和目录
    • dept/YYYYMM/<id>/<deptId>:整部门软删除后的部门目录
    • safe-r/<phone>/YYYYMM/<id>/<文件或文件夹>:个人保险库中被软删除的文件和目录
    • 与之配套的元数据存放在 data/recycle_bin.dbrecycle_items 表中,回收站页面即基于此表进行分页查询与还原/彻底删除。
  • data/tmp_big_uploads/:大文件上传分片临时目录
  • data/audit_logs/
    • audit.log:当前审计日志
    • audit_YYYYMMDD_HHMMSS.log:历史轮转日志
  • data/audit_index/
    • file_detail.db:文件详情索引(下载次数、访问/编辑时间)
  • data/home_posts.json:首页动态数据
  • data/feedbacks.json:用户反馈
  • data/users.db:用户账号信息(SQLite)
  • data/log/:其他运行日志(按日期划分,后端统一通过 write_log() 写入)
  • data/favorite_paths.db:用户快速访问/收藏目录(后端 services/files/favorites.py 使用)
  • data/share_links.db:分享链接记录(后端 routers/share_links.py 使用)

使用建议与注意事项

  1. 避免直接在操作系统文件管理器中移动/重命名后端托管的文件,否则索引与统计会失配;
  2. 重要资料建议定期备份,同时合理规划目录结构和命名规范;
  3. 删除操作分两步:
    • 在文件页删除:先移入回收站,如有误删可在回收站中还原;
    • 在回收站彻底删除/清空:才会真正物理删除文件并清除统计,此步不可恢复
  4. 发现统计异常或希望重新统计,可使用清理接口清空 file_detail,让统计从新规则重新开始;
  5. 登录凭证过期或无效时,前端会自动退回登录页,重新登录即可恢复所有操作权限。

批量导入用户账号

系统用户信息现在存储在 SQLite 数据库 data/users.db 中。支持通过命令行脚本按 CSV 批量导入普通用户账号(role = user)。

1. 准备 CSV 模板

在项目根目录下新建一个 CSV 文件,例如 users.csv,使用 UTF-8 编码,首行为表头,至少包含以下两列:

phone,name
13800000001,张三
13800000002,李四

说明:

  • phone:登录账号手机号,必须唯一且非空;
  • name:用户姓名,将显示在系统中;
  • 所有通过该脚本导入的账号,其角色固定为普通用户 user
  • 初始密码由系统自动为每个用户随机生成 12 位(字母 + 数字),只在导入时在命令行输出一次,便于管理员分发给用户。

2. 运行导入脚本

在服务器或开发环境中,进入项目根目录,执行:

cd D:/software/HBCloud.Web
python backend/tools/import_users_from_csv.py users.csv

脚本行为:

  • 读取指定 CSV 文件中的每一行;
  • 对于每一条 phone,name
    • 若手机号为空或姓名为空,则跳过并在控制台提示;
    • 若该手机号在数据库中已存在,则跳过并提示(不会覆盖原用户或其密码);
    • 否则:
      • 自动生成一个 12 位随机初始密码(由大小写字母和数字组成);
      • 使用与系统一致的密码哈希算法(pbkdf2_sha256)写入 data/users.dbusers 表;
      • 在控制台打印:创建用户:<phone> (<name>) 初始密码:<plain_password>

注意:初始密码仅在导入时在终端输出一次,导入完成后不会再在系统中明文保存。请妥善记录并安全地分发给对应用户。


删除用户账号

在测试或日常维护中,如需按手机号删除某个账号,可使用后端提供的命令行脚本,无需手动编写 SQL。

1. 删除指定手机号的账号

在项目根目录下执行:

cd D:/software/HBCloud.Web
python backend/tools/delete_user_by_phone.py 13800000001

脚本行为:

  • 连接 data/users.db
  • 执行 DELETE FROM users WHERE phone = ? 删除该手机号对应的账号记录;
  • 若删除成功,会输出:已删除手机号为 13800000001 的账号。
  • 若未找到该手机号,会输出:未找到手机号为 13800000001 的账号(无需删除)。

2. 注意事项

  • 删除账号仅影响登录用户表,不会自动删除对应的个人保险库目录(如 data/safe/13800000001/);
  • 删除账号不会影响已有的审计日志和文件详情统计记录;这些记录只保留当前的姓名/手机号字符串;
  • 如需更复杂的账号管理(批量禁用、重置密码等),可在此基础上扩展专用工具或管理界面。

代码结构(开发者)

本节面向需要二次开发或排查问题的同事,简要说明后端拆分后的代码结构,特别是原 routers/files.py 拆分为多个 services/files/*.py 模块的情况。

项目主要目录:

  • 后端:backend/

    • 启动入口:backend/main.py / backend/app.py

    • 配置:backend/config.py

    • 路由:backend/routers/

      • auth.py:登录、注册、修改密码等认证相关接口
      • users.py:用户管理接口(为前端用户管理页提供 REST API,如查询用户列表、启停用账号、调整角色等)
      • home.py:首页动态(公告)相关接口
      • feedbacks.py:留言 / 反馈相关接口
      • audit.py:审计相关接口
      • maintenance.py:维护任务(如清理统计数据)
      • files.py:文件相关路由入口,仅做参数解析、权限校验,具体业务由 services/files 下的模块实现
      • share_links.py:分享链接相关接口,用于创建/访问/失效分享短链接,持久化到 data/share_links.db
    • 文件服务:backend/services/files/

      • base.py
        • 公共工具与基础封装,例如:路径解析(计算某个空间/部门/用户对应的物理路径)、统一的异常处理、审计日志写入以及简单文本日志写入(write_log() 会将按日滚动的运行日志写到 data/log/
        • 其他文件服务模块会复用这些基础能力。
      • listing.py
        • 负责「文件浏览」页的列表数据:按空间类型和当前目录列出文件/文件夹;
        • 构建路径导航信息(首页 / 上级 / 当前路径)。
      • upload.py
        • 普通上传和大文件分片上传,实现与 README 中「上传文件」「大文件分片上传」一致的行为;
        • 负责创建临时分片目录、合并分片、校验大小和 MD5,失败时清理临时文件。
      • download.py
        • 单文件下载与预览,对应 /api/files/download 接口;
        • 根据 disposition=attachment/inline 区分下载和预览;
        • 负责更新下载次数与最后访问时间(写入 data/audit_index/file_detail.db)。
      • operations.py
        • 文件 / 文件夹的日常操作:新建文件夹、重命名、删除(软删除)、移动到、复制到等;
        • 删除时不会立刻物理删除,而是将文件/目录移动到 data/recycle/...,并写入 data/recycle_bin.db(与 README 中的「删除与回收站」逻辑对应);
        • 移动 / 复制时处理跨空间(public / department / safe)、命名冲突(跳过 / 覆盖)并更新最后编辑人/时间。
      • pack.py
        • 打包下载相关逻辑,对应「文件浏览器中的打包下载」和「首页动态附件的打包下载」;
        • 在临时目录(如 data/public/__packs__/data/tmp_packs/)创建 ZIP 文件;
        • 遇到部分文件不存在时,按规则跳过并返回缺失数量 missingCount,供前端提示。
      • search_zip.py
        • 如启用了 ZIP 相关的搜索 / 检索功能,会在此集中处理;
        • 例如在压缩包中查找特定文件名等(按实际实现为准)。
      • dept.py
        • 部门空间相关的后端操作,如:
          • 新建部门目录 data/departments/<deptId>/
          • 创建 / 维护 config.json(部门名称、创建人、删除密码哈希等);
          • 删除部门(递归删除部门目录,或配合回收站做软删除)。
      • recycle.py
        • 回收站的核心业务逻辑,与 README 中「删除与回收站」章节完全对应;
        • 职责包括:
          • 将删除的文件 / 文件夹 / 部门移动到 data/recycle/commondata/recycle/deptdata/recycle/safe-r 等目录;
          • data/recycle_bin.dbrecycle_items 表中写入回收记录;
          • 提供分页列表查询接口(支持按空间类型、项目类型、关键字过滤),供前端回收站页面使用;
          • 还原操作:将选中项恢复到原空间和原路径,若冲突则自动重命名为 xxx(恢复) / xxx(恢复-n)
          • 彻底删除:物理删除文件/目录,并对普通文件调用 delete_meta 清理 file_detail.db 中的统计记录;
          • 清空回收站:供超级管理员一键清空所有回收项。
      • favorites.py:收藏夹/快速访问相关逻辑,直接操作 favorite_paths.db,供 /api/files/favorites 系列接口复用
    • 后端工具脚本:backend/tools/

      • import_users_from_csv.py:批量导入用户账号,对应 README 中「批量导入用户账号」章节;
      • delete_user_by_phone.py:按手机号删除用户账号,对应「删除用户账号」章节。
  • 前端:frontend/

    • 入口与构建:
      • index.htmlvite.config.jspackage.json
    • 源码结构:
      • src/main.js:前端入口
      • src/App.vue:根组件
      • src/router/index.js:路由配置(首页、文件浏览、登录、回收站等)
      • src/views/
        • Home.vue:首页动态与附件打包下载
        • FileBrowser.vue:文件浏览、上传、移动/复制、打包下载等
        • Login.vue:登录 / 注册 / 修改密码
        • RecycleBin.vue:回收站页面
        • UserManage.vue:用户管理页
      • src/services/
        • recycle.js:前端回收站相关的 API 封装,与后端 routers/files.py + services/files/recycle.py 对应。

通过上述拆分:

  • 原先集中在单个 routers/files.py 中的大量文件业务逻辑,已经拆到 backend/services/files/ 下的多个模块中;
  • routers/files.py 主要承担「HTTP 层」工作:路由定义、请求参数解析、权限校验,然后调用对应服务模块;
  • 这样便于后续在某个环节做定制(例如单独修改回收站规则、打包策略),不会影响其他文件操作。

数据存储路径与备份建议

为了防止硬盘故障或误操作导致的数据丢失,建议对以下目录和文件做定期备份(例如每天、每周或按院内信息安全制度要求执行备份策略)。

1. 文件数据(最核心)

这些是用户真正上传/管理的业务文件,优先级最高:

  • data/public/
    • 公共空间的所有文件与目录;
    • 包含打包下载用的临时目录 __packs__/(可根据需要选择是否备份)。
  • data/departments/
    • 各科室/部门空间的文件目录,例如:
      • data/departments/IT/
      • data/departments/HR/
    • 每个部门目录下还包含 config.json,记录部门名称、删除密码哈希等元信息。
  • data/safe/
    • 个人保险库空间,以手机号划分目录,例如:
      • data/safe/13800000001/
      • data/safe/18903510509/
    • 仅对应用户本人可见,建议与公共/部门空间一起纳入备份。

建议
对以上三个目录采用定期完整备份 + 增量备份方式,例如:

  • 每天凌晨对 data/public/data/departments/data/safe/ 做增量备份;
  • 每周/每月做一次完整备份;
  • 备份目标可为院内备份服务器、对象存储或磁带库等。

2. 用户与权限数据

  • data/users.db

    • SQLite 用户数据库;
    • 存储账号手机号、姓名、密码哈希、角色、账号状态等;
    • 建议纳入高优先级备份,一旦丢失会导致所有账号信息需要重建。
  • (如有启用)data/departments/*/config.json

    • 每个部门空间下的配置文件;
    • 一般不大,但对部门空间管理重要,建议和部门目录一起备份。

3. 日志与审计信息

这部分用于排错、审计和统计,重要性略低于业务文件和用户库,但仍建议保留一段时间的历史备份。

  • 审计日志:

    • data/audit_logs/audit.log
    • data/audit_logs/audit_YYYYMMDD_HHMMSS.log(轮转归档)
    • 记录文件访问、下载、编辑等行为,用于审计与问题追踪。
  • 文件详情索引库:

    • data/audit_index/file_detail.db
    • 记录每个文件的下载次数、最近访问时间、最近编辑人/时间等。
    • 丢失后不会影响文件本身,但统计数据会从 0 开始重新累积。
  • 运行日志(如有):

    • data/log/ 及子目录
    • 记录后端运行日志、错误信息等,有助于排错与历史追溯。

建议

  • 至少保留最近 3–6 个月的审计日志与运行日志;
  • 可按日期或大小做日志轮转(当前 audit.log 已内置大小轮转机制);
  • 定期将 data/audit_logs/data/audit_index/data/log/ 做打包备份,便于统一存档和清理老数据。

4. 业务配置与结构化数据

  • 首页动态(公告):

    • data/home_posts.json
    • 存储首页动态的标题、内容、发布人、所属部门、附件关联等;
    • 文件本身不大,但丢失会导致公告列表清空。
  • 用户反馈:

    • data/feedbacks.json
    • 存储「留言 / 反馈」功能提交的内容及时间等;
    • 体量通常较小,建议与其他 JSON 配置一起备份。

建议

  • data/home_posts.jsondata/feedbacks.json 一并纳入常规备份;
  • 若使用了其他 JSON 配置(如自定义系统参数),也一并整理到 README 中说明。

5. 备份策略示例(可根据实际环境调整)

假设部署目录为 D:\software\HBCloud.Web,数据目录为 D:\software\HBCloud.Web\data,可以考虑类似策略:

  1. 每日增量备份(建议在业务低峰期执行,例如凌晨 1 点)

    • 备份目标目录:
      • data/public/
      • data/departments/
      • data/safe/
      • data/users.db
      • data/home_posts.json
      • data/feedbacks.json
      • data/audit_logs/
      • data/audit_index/
    • 工具可自由选择(如 robocopy、rsync、备份软件等)。
  2. 每周/每月完整备份

    • 对整个 data/ 目录做一次完整快照;
    • 完整备份可长期保存(例如 6 个月以上),方便回溯。
  3. 异地/多副本备份

    • 视院内信息安全规范,考虑将部分关键备份复制到:
      • 异机存储(另一台物理服务器或虚拟机);
      • 只读介质(磁带、离线硬盘);
      • 对象存储等。
  4. 定期恢复演练

    • 建议定期在测试环境演练“从备份恢复”的流程,确认:
      • 文件能正确恢复;
      • users.db 恢复后账号可以正常登录;
      • 首页动态和反馈数据完整;
      • 审计与统计数据能被系统正常读取。

6. 不建议直接备份的内容

  • 前端构建产物、后端代码本身:
    • 例如 frontend/dist/backend/ 代码等;
    • 这部分应由源码仓库存管或按发布流程重新部署;
    • 一般不需要纳入日常数据备份,可以通过源码/发布包恢复。

7. 清理与空间管理

  • 日志类目录(data/audit_logs/data/log/)可以配合备份策略定期清理老文件:
    • 如只保留近 6 个月的日志,其余打包归档后转移到冷存储或删除;
  • file_detail.db 统计库:
    • 如数据过多或规则改动,可使用维护接口清空统计重新累积;
    • 请注意:清空不会影响文件和权限,仅重置统计数字。

建议根据院内 IT 部门的统一备份规范,结合上述路径,制定一个可执行的备份计划,并在 README 或内部运维文档中固定下来,便于后续交接和长期维护。


备份与恢复 FAQ(运维人员)

Q1:当前服务器上哪些路径需要重点纳入备份?

建议至少涵盖以下路径(假设项目在 Q:\software\HBCloud.Web):

  • 业务文件:
    • Q:\software\HBCloud.Web\data\public (公共空间)
    • Q:\software\HBCloud.Web\data\departments (部门空间)
    • Q:\software\HBCloud.Web\data\safe (个人保险库)
  • 用户与配置:
    • Q:\software\HBCloud.Web\data\users.db (用户账号)
    • Q:\software\HBCloud.Web\data\home_posts.json (首页动态)
    • Q:\software\HBCloud.Web\data\feedbacks.json (反馈)
  • 日志与统计(可选但推荐):
    • Q:\software\HBCloud.Web\data\audit_logs (审计日志)
    • Q:\software\HBCloud.Web\data\audit_index (文件统计索引)
    • Q:\software\HBCloud.Web\data\log (运行日志,如有)

最简单的方式是:直接备份整个 Q:\software\HBCloud.Web\data 目录


Q2:用 Windows Server Backup 备份,是全量还是增量?

在 WinServer2019 上使用 Windows Server Backup(WSB):

  • 如果备份目标选择的是「备份到卷/磁盘」(例如 C: 盘,交由 WSB 管理):
    • 第一次备份 ≈ 全量基线;
    • 后续每次备份 = 块级增量
    • 在恢复界面上,每次备份都表现为一个“完整快照”,可以单独选择恢复。
  • 如果备份目标选择为「网络共享目录」:
    • 每次备份都会写一份完整备份;
    • WSB 会根据空间策略自动删除更旧的版本。

因此,推荐将 Q 盘的数据备份到 C 盘作为“备份卷”,让 WSB 以增量方式维护多个恢复点。


Q3:我在 Q 盘删掉了一个很大的文件,备份占用空间会立刻变小吗?

  • 源盘(Q 盘):
    • 立刻释放空间,Q:\software\HBCloud.Web\data\... 下被删文件会立即腾出空间。
  • 备份盘(C 盘上的 WSB 备份):
    • 旧备份版本中仍然保留这个文件的数据块,不会因为你删了源文件就立刻变小
    • 只有当 WSB 按策略清理更老的备份版本且该文件只存在于那些被删掉的版本中时,对应空间才会被真正释放。

换句话说:备份是时间点快照,不会随着源盘删除自动“瘦身”旧快照。


Q4:误删了一个(或一批)文件,如何恢复?

前提:误删前至少有一次成功的备份。

  1. 打开「Windows Server Backup」。
  2. 选择「恢复(Recover…)」:
    • 选择备份位置(通常是本机)。
    • 选择一个“删除之前”的备份时间点。
    • 选择恢复类型为「Files and folders」。
  3. 在目录树中定位到对应路径,例如:
    • 单个文件:Q:\software\HBCloud.Web\data\public\...\某文件.ext
    • 整个目录:Q:\software\HBCloud.Web\data\departments\IT\...
  4. 选择恢复目标:
    • 建议先恢复到一个「临时目录」(如 Q:\_restore_tmp\...),再人工比对和迁移;
    • 避免直接覆盖当前线上数据,以免覆盖最近的新增/修改。

大量删除 的场景:

  • 若明确只影响某个子目录,可直接恢复该目录到临时位置再比对;
  • 若影响范围较大,可考虑恢复整个 data 目录到另一位置,再用文件对比工具(如 robocopy、Beyond Compare 等)选择性同步。

Q5:源目录结构发生移动/重命名,对备份和恢复的影响?

从备份系统的角度看:

  • 移动/重命名 = “旧路径删除 + 新路径新增”;
  • 每次备份记录的是「当时的最终目录结构」,不会“自动理解”你的重命名,但会保留每个时间点的结果。

在恢复时:

  • 若希望恢复到「移动/重命名之前」的结构:
    • 选移动之前的某一次备份;
  • 若希望恢复到「移动/重命名之后」的结构:
    • 选移动之后的某一次备份。

与系统内部索引的关系:

  • 统计信息保存在 data/audit_index/file_detail.db
  • 在系统内通过「移动/重命名」按钮操作时,后端会同步更新 file_detail.db,保持统计与路径一致;
  • 若你仅恢复了 data/public 等文件目录而未同步恢复 file_detail.db,文件本身不会受影响,但统计信息可能与当前实际不完全一致(后续访问/编辑会按新行为继续累积)。

建议

  • 做「完整时间点恢复」时,可选择同时恢复 data/audit_index/file_detail.db,保持统计与文件状态一致;
  • 若只关心文件不关心历史统计,可单独恢复文件目录,必要时再用清理接口重置统计。

Q6:如何配合 Windows Server Backup 做一个简单的日常备份策略?

假设:

  • 应用和数据在 Q 盘:Q:\software\HBCloud.Web\data
  • C 盘空间充足,可作为备份目标盘;
  • 需要每天备份一次。

推荐做法:

  1. 安装「Windows Server Backup」。
  2. 使用「Backup Schedule…」创建计划:
    • 备份配置:Custom(自定义);
    • 备份项目:选择 Q:\software\HBCloud.Web\data 整个目录;
    • 时间:每天凌晨 01:00;
    • 备份目标:选择 C 盘作为备份卷(由 WSB 管理)。
  3. 定期(例如每季度)在测试环境做一次「恢复演练」:
    • 从某个备份版本恢复 data 到临时目录;
    • 启动一套测试环境,验证登录、文件访问、公告与统计是否正常。

如有更细的合规/审计要求(例如日志至少保存 1 年),可在此基础上增加:

  • 定期将 data/audit_logsdata/log 打包复制到长期归档介质(如 NAS 或磁带);
  • 周期性清理本机上已不再需要的历史日志文件。

权限角色说明(矩阵)

系统中涉及到的“角色”分两类:系统角色部门内角色

1) 系统角色(全局)

系统角色 说明
super 超级管理员:拥有全局最高权限(含查看/清空回收站、管理所有部门、访问所有空间等)。
op 运维管理员:可管理大部分系统/空间操作权限(通常等同于“全局管理员”,但不包含部分仅 super 的敏感操作)。
user 普通用户:默认角色;其在部门空间的权限取决于部门空间是否开放(isOpen)以及其在该部门的部门内角色(dept/member)。

2) 部门内角色(dept_roles)

部门内角色存储在 data/users.dbdept_roles 表中,只对部门空间生效。

部门内角色 说明
dept 部门管理员(科室管理员):可管理该部门空间成员、并拥有该部门空间的读写权限。
member 部门成员:拥有该部门空间的读写权限(不受 isOpen 影响)。
(空) 非该部门成员:是否可读取决于 isOpen;写入永远禁止。

权限矩阵(常用操作)

说明:以下矩阵基于当前后端实现的权限校验逻辑(backend/services/files/base.pydept_roles.pyrouters/* 等)。

A. 三类空间的读/写权限

空间类型 操作 super op 普通用户(非部门成员) dept / member
公共空间(public) 读取(列表/下载/搜索/打包下载)
公共空间(public) 写入(上传/新建/重命名/删除/移动/复制/解压/压缩) ✅* ✅*
部门空间(department) 读取(isOpen = true)
部门空间(department) 读取(isOpen = false)
部门空间(department) 写入(上传/新建/重命名/删除/移动/复制/解压/压缩)
个人保险库(safe) 读取 ✅(可读全部) ❌(默认不跨人员) ✅(仅自己) ✅(仅自己)
个人保险库(safe) 写入 ✅(可写全部) ❌(默认不跨人员) ✅(仅自己) ✅(仅自己)

* 注:公共空间的“写入”是否对所有用户开放,取决于部署方的使用约定与前端入口(当前实现允许,只要已登录即可调用相应接口)。如需收紧为仅管理员可写,可在后端增加统一写权限校验。

B. 回收站权限

操作 super op 普通用户 备注
查看回收站列表 会根据条目所属空间/权限做过滤;个人保险库仅本人可见。
还原(restore)文件/文件夹 ✅(需对目标空间有写权限) 部门空间还原需具备该部门写权限;保险库仅还原自己。
彻底删除(purge)文件/文件夹 ✅(需对目标空间有写权限) 彻底删除不可恢复;普通文件会同步清理 file_detail 统计索引。
清空回收站(empty) super 允许。

C. 部门管理与空间权限配置

操作 super op 普通用户 dept(部门管理员) 备注
创建部门 ✅* ✅* 当前实现允许任意登录用户创建;如需收紧可改为仅 super/op。
删除部门 ✅(免密码) ✅(需密码)** ✅(需密码) ✅(需密码) 部门删除按“不可逆”口径:权限组/统计索引等会被清理,仅目录可在回收站兜底恢复。
查看部门空间配置(isOpen 等) 当前接口未做额外限制(可按需收紧)。
修改部门空间 isOpen ✅(仅本部门) routers/files.py 中的权限校验决定:非 super/op 需是本部门 dept。
配置部门管理员/成员(dept_roles) ✅(仅本部门) 同上:非 super/op 需是本部门 dept。

* 注:如希望“部门创建”仅限管理员,可在后端 create_department 增加 role in (super,op) 限制。

** 注:op 是否需要密码取决于当前实现口径:super 在删除部门时可跳过删除密码;op 仍按普通用户处理(需要提供正确的 6 位删除密码)。如希望 op 也可免密码,可调整 delete_department 逻辑。


分享链接功能

用途:为单个文件或文件夹生成短链接,便于在院内其他系统(如 OA)或 IM 中直接访问对应内容。

  • 分享对象:公共空间、部门空间、个人保险库中的单个文件或文件夹(具体受当前用户权限限制);
  • 后端路由:backend/routers/share_links.py 提供创建分享、获取分享详情等接口(统一前缀 /api/share/...);
  • 数据库存储:
    • data/share_links.db 为 SQLite 文件,用于保存 share_id、目标路径、空间类型、创建人、创建时间、访问计数、有效期等字段;
  • 访问流程(简要):
    • 前端在文件列表中选择某个文件/目录,调用分享接口生成 share_id
    • 前端或其他系统可使用该 share_id 拼接访问地址;
    • 后端根据 share_id 查表校验是否存在/未过期/未超访问次数,再决定是否允许访问或下载。

账号管理与日志

这一部分只做简要说明,方便和「用户管理页」以及「日志文件」对上号。

  • 账号管理:
    • 前端 UserManage.vue 配合 backend/routers/users.py,实现用户列表查看、账号启用/禁用、角色调整等操作;
    • 这些接口会在内部调用用户服务,并根据操作结果返回标准 JSON 给前端展示;
  • 日志与审计:
    • 文本运行日志:
      • 后端通过 services/files/base.py 中的 write_log(message) 统一写入 data/log/YYYY-MM-DD.log
      • 用于快速 grep 某天的关键操作摘要(如账号锁定、批量禁用等);
    • 审计日志:
      • 通过 routers/audit.py 暴露的接口在 data/audit_logs/audit.log 中记录结构化 JSON;
      • 便于后续安全审计、问题回溯与统计分析。

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors