基于 filebrowser v2.63.15 深度定制的中文文件管理系统,面向企业内网的文件/图纸检索、预览、分享与治理场景。核心特征:单文件 exe 交付、4000 条文件列表无卡顿滚动、PDF/DWG/Office/音视频/图片全格式预览、应用层回收站 + 文件锁 + 操作日志 + 流量统计、iOS 风格 UI(亮/暗双主题)、Windows 一键编译与一键启动脚本。
- 一、核心能力一览
- 项目截图
- 二、定制内容清单
- 三、目录结构
- 四、开发环境要求
- 五、本地开发
- 六、构建打包
- 七、部署运行
- 八、数据库与账号管理
- 九、品牌与自定义 Logo
- 十、URL 自动登录
- 十一、常见问题
- 十二、技术栈与二次开发指引
- 十三、HTTP API 一览
| 分组 | 能力 |
|---|---|
| 浏览与检索 | 列表视图虚拟滚动(可变行高,4000+ 条无卡顿);网格/画廊保持原生渲染;多关键词 AND 搜索(文件名全词匹配)+ 全局内存索引加速(启动预热、每分钟增量刷新);产品编号索引反查;时间筛选;目录范围树(admin 配置用户 scope 时懒加载,支持 --mount 挂载节点) |
| pdf.js 6 渲染 + 侧栏缩略图;产品编号「数据库 + PDF Keywords」双写;文本编辑、去水印(前置解密仅权限加密的 PDF)、PDF 合并、文本/位图栅格化 | |
| Office / 表格 | Word、Excel 由内置 ONLYOFFICE 离线引擎(x2t.wasm) 直接浏览器端编辑保存(按权限可写/只读);桌面上没有 Office 时 DOCX/PPTX 转图片兜底;CSV 由独立查看器(CsvViewer)渲染;OOXML 工作簿外链检测与「断开全部外链并转值」 |
| CAD 图纸 | DWG/DXF 浏览器端预览(LibreDWG WASM 解析 + three.js 渲染,方案见 docs/dwg-preview-技术方案.md) |
| 音视频与图片 | 浏览器无法原生解码的容器(XVID/DivX/WMV/FLV/MPEG-2…)服务端 ffmpeg 实时转码为流式 fMP4;video.js 8 播放器(进度/缓冲条按源文件坐标工作);图片/音频/视频目录内左右循环切换;全量图片 LazyImage 懒加载 + BlurUp 占位(20×20 JPEG Base64,BoltDB 持久缓存) |
| EPUB / TIFF | epubjs + vue-reader 阅读器;utif 解 TIFF |
| 安全与治理 | 应用层回收站(同卷 rename 进 .recycle,支持恢复/彻底删除/清空/过期清理);文件锁(admin 为单个文件设访问密码,预览/下载/转码/转换/字幕等资源型接口统一拦截,返回 423);操作日志(异步批量落库,admin 按动作/用户/路径/时间分页查询与清空);流量统计与限速(内存计数 + 周期落库,admin 查看与重置);账号封禁心跳(/api/status/auth,被禁即 410 → 前端强制下线);命令执行白名单(WebSocket 终端) |
| 工程化 | //go:embed frontend/dist 单文件 exe;build-windows.bat + build-core.ps1 一键构建;run-filebrowser.ps1 一键编译/运行(Junction 规避路径括号);start-dev.ps1 开发环境一键启动 |
左侧导航 + 顶部搜索栏 + iOS SegmentedControl 视图切换 + 可变行高虚拟滚动列表(名称 / 大小 / 最后修改):
pdf.js 渲染 + 侧栏页码缩略图 + 缩放 + 编辑文字 / 去水印 / 打印 / 下载;底部显示「第 x 页 / 共 y 页」:
截图中为通用测试样本(
bitcoin.pdf、presentation.pptx、test_*.csv等),非真实业务数据。
与原版 filebrowser v2.63.15 相比的全部改动。
| 文件 | 改动 |
|---|---|
frontend/src/i18n/index.ts |
detectLocale() 固定返回 zh-cn;createI18n 默认 locale: "zh-cn" |
frontend/src/stores/auth.ts |
setLocale(user.locale || "zh-cn"),登录后中文兜底 |
settings/storage.go |
默认 Defaults.Locale = "zh-cn" |
cmd/root.go |
quickSetup 初始 Locale: "zh-cn" |
cmd/users.go |
--locale flag 默认 zh-cn |
frontend/src/i18n/zh-cn.json |
补齐漏翻译的英文 key(currentPassword、冲突处理、按钮等) |
| 文件 | 改动 |
|---|---|
frontend/public/index.html |
<title>、apple-mobile-web-app-title、manifest 名称 → "文件管理系统" |
frontend/index.html |
开发模式入口同步修改 |
frontend/src/utils/constants.ts |
name 默认值改为系统名称 |
frontend/src/components/Sidebar.vue |
底部 credits 显示系统名称 + 版本 |
frontend/src/views/Login.vue |
Logo alt 改为系统名称 |
| 文件 | 内容 |
|---|---|
frontend/src/css/_variables.css |
iOS 配色体系:主色 #007AFF、浅色背景 #F2F2F7、深色 #000 / 表面 #1C1C1E |
frontend/src/css/_buttons.css |
胶囊按钮(border-radius: 980px)+ 按压缩放反馈 |
frontend/src/css/_inputs.css |
圆角灰底输入框 + 蓝色聚焦光晕 |
frontend/src/css/login.css |
iOS 登录卡片(渐变背景 + 圆角 + 柔和阴影),登录标题完整显示不溢出 |
frontend/src/css/header.css |
毛玻璃头部(backdrop-filter)+ 标题加粗 + 搜索框大宽度 + 尺寸状态锁定 |
frontend/src/css/_shell.css |
Shell 终端顶部圆角 + 阴影 |
frontend/src/css/_share.css |
分享卡片圆角 14px |
frontend/src/css/upload-files.css |
进度条 iOS 蓝 |
frontend/src/css/styles.css |
.credits flex 单行布局;编辑器容器/面包屑;全局搜索过渡动画颜色化(避免布局抖动) |
frontend/src/css/ios.css(3500+ 行 / ~112KB) |
全部 iOS 覆盖:toast、卡片圆角、SegmentedControl、Sheet 弹窗、按压反馈、滚动条、select/checkbox、macOS 风格 loading 组件、空文件夹 SVG(#8E8E93 灰色)、面包屑毛玻璃(含 :root.dark 深色覆盖)、右键菜单等 |
frontend/src/css/context-menu.css |
macOS 风格右键菜单(min-height: 36px、图标 18px、下载计数胶囊) |
frontend/src/css/dashboard.css / listing.css / listing-icons.css / mobile.css |
设置页、列表、图标、移动端(≤1024px 抽屉式)适配 |
frontend/src/css/epubReader.css / mdPreview.css |
EPUB 阅读器、Markdown 预览 |
frontend/src/components/MacOSSelect.vue / MacOsAudioPlay.vue |
macOS 风格下拉选择、音频播放条 |
frontend/src/components/header/HeaderBar.vue |
<slot /> 包裹 .slot-wrapper(顶部按钮单行);搜索框大宽度布局 |
frontend/src/components/DropdownModal.vue |
下拉菜单 iOS 圆角 |
frontend/src/views/files/FileListing.vue |
视图切换改为 iOS SegmentedControl 三段控件 |
双主题:
html.light/html.dark,所有自定义组件(含 video.js 动态生成的 DOM)都做了深色覆盖;frontend/src/utils/theme.ts负责主题类切换。
| 功能 | 实现 |
|---|---|
| URL 自动登录 | frontend/src/views/Login.vue 的 autoLoginFromURL():解析 ?u=&p= 或 ?username=&password=,登录后跳转并清除敏感参数 |
| 去除二次密码校验 | http/users.go 三处 CheckPwd 校验禁用(_ = body.CurrentPassword);前端不再弹 CurrentPassword |
| 弱密码黑名单移除 | users/password.go 移除 commonPasswords 检查(允许 123456 等,最小长度可配) |
| 移除外部链接 | Global 设置页帮助链接、Sidebar GitHub 链接、CustomToast 报告问题按钮全部移除 |
| 自定义 Logo 指引 | 设置页品牌区新增 logo.svg 说明(通过 branding.files 目录生效) |
| 右键菜单自适应位置 | ContextMenu.vue 用 position: fixed + 组件内边界检测,自动 flip 到可视区 |
| 编辑器/重命名后列表刷新 | Editor.vue save 成功后置 fileStore.reload = true;Rename.vue 同步处理 |
| 后端 auth Cookie | http/auth.go printToken 写入 Set-Cookie: auth=xxx; Path=/; SameSite=Lax,浏览器原生 <img> / 新标签页可直接鉴权(避免 blob URL) |
| 模块 | 前端 | 后端 | 要点 |
|---|---|---|---|
| 应用层回收站 | views/Recycle.vue、api/recycle.ts |
recycle/、http/recycle.go |
删除时同卷 Rename 进各卷根 .recycle(秒级、不搬数据);恢复到原路径(冲突自动改名 name (2).ext);彻底删除 / 清空;启动跑一次 + 每小时清理过期条目 |
| 文件锁 | views/FileLocks.vue、prompts/FileLockSet.vue、prompts/UnlockFile.vue、prompts/FileLockReset.vue、utils/filelock.ts |
filelock/、http/filelock.go |
admin 为单个文件设置/修改/移除访问密码;未解锁时预览/下载/转码/文档转换/字幕统一拒绝(423);管理页可重置密码、移除锁 |
| 操作日志 | views/settings/OpLog.vue、api/oplog.ts |
oplog/、http/oplog.go、http/oplog_api.go |
记录用户/分享访客、时间、IP、文件与动作(上传/下载/预览/删除/分享/编辑/新建等);写入由 http 层异步缓冲、单 goroutine 批量落库;admin 分页查询与清空;过期清理 |
| 流量统计与限速 | views/settings/Traffic.vue、api/traffic.ts |
traffic/、http/traffic.go |
每用户一条累计下行字节记录(users.User.TrafficLimit,0 = 不限制);内存计数 + 周期落库;admin 查看并重置 |
| 账号封禁 | components/settings/BanGuard.vue、utils/banFlag.ts |
http/auth.go(/api/status/auth) |
前端定时轮询,被禁时 withUser 返回 410 → 强制下线 |
| 配额 | components/settings/QuotaExceeded.vue、utils/quotaFlag.ts |
users/(Quota) |
超出配额时的提示与拦截 |
| 命令执行(终端) | components/Shell.vue |
http/commands.go、runner/、srv/、rules/ |
WebSocket 交互式终端;命令白名单(rule 配置),仅白名单含 * 的用户可访问 /api/oslist;Windows 用 powershell.exe -NoProfile -NonInteractive -Command,输出按 GBK→UTF-8 解码 |
| scope 多目录 + 挂载 | components/settings/ScopeSelector.vue、api/scopetree.ts |
users/(ScopeDirs / BuildScopeFs)、http/scopetree.go、files/ |
scope 支持 & 语法引用 --mount 挂载名(如 /图纸&/挂载名);/api/scopetree 供 admin 懒加载目录树 |
| 产品编号 | prompts/ProductCode.vue、Breadcrumbs.vue 右侧编辑按钮、api/productcode.ts |
productcode/、http/productcode.go、cmd/productcode.go |
storm 存 path → code 索引(列表查询/反查)+ PDF Keywords 写 "product-code:xxx"(离线追溯),临时文件 + 原子改名;CLI productcode ls/find |
| 工作簿外链清理 | prompts/ + api/xlsxlinks.ts |
xlsxlinks/、http/xlsxlinks.go |
检测 .xlsx/.xlsm 中缓存的外部工作簿数据,用户确认后「断开全部外链并转值」(POST /api/xlsxlinks/force) |
| 路径主键迁移 | — | http/migrate_keys.go |
把历史「用户视角逻辑路径」为主键的文件锁/产品编号记录,一次性换算为物理磁盘路径(幂等) |
仅 列表视图 启用虚拟滚动,网格 / 画廊视图保持原渲染与样式逻辑不变。
- 组件:
frontend/src/components/files/VirtualList.vue;使用方:views/files/FileListing.vue - 关键技术点:
- 支持
mode="parent"父滚动驱动模式(用外层#listing作为滚动容器,避免双滚动条) measuredHeights缓存已测行高 +offsets前缀和数组,支持可变行高(含产品编号 subtitle 的行)selfOffsetTop用滚动容器坐标系计算(BBox 差值 +container.scrollTop),修复「向上滚动元素消失」;#listing必须position: relativemeasuredOnce锁:首次测量前强制startIndex = 0,避免 BBox 未就绪导致的偏移跳变buffer=8:可视区前后各多渲染 8 行,滚动无白屏
- 支持
search/提供全局内存索引:启动全量预热(Open+Readdir批量枚举),之后每分钟增量刷新(copy-on-write,不阻塞请求);命中索引时为纯内存匹配,大目录稳定在百毫秒级- 未建索引的场景(作用域用户等)自动回退实时批量扫描,同样不逐文件
Stat - 匹配语义:按词边界切分标识符 → 字母/数字段拆分 → 段级滑窗等值匹配(大小写敏感);CJK 走子串 fallback;纯数字词条(2/4 位)对长数字段做滑窗匹配;多关键词 AND,全部命中文件名才算结果
- 搜索范围由当前目录决定:子目录用
/api/search/{subdir},根目录用/api/search/ - 变更操作(新建/删除/移动等)后异步刷新索引(
RefreshGlobalIndexAsync)
所有 <img> 统一收敛到 frontend/src/components/files/LazyImage.vue:
- 懒加载:IntersectionObserver +
rootMargin: 300px,进入可视区前 300px 提前触发;离开视图不取消已发起请求 - iOS 风格加载指示器:12 根径向 bar + 错位 fade(
ios-spinner-fade 1s,负animation-delay分 12 相位) - BlurUp 占位:后端生成 20×20 JPEG Base64(
filemetacache/持久缓存,key = RealPath + ModTimeUnix + Size),CSSfilter: blur(16px) scale(1.1)+ 0.4s opacity fade - 错误占位 + 重试:失败显示占位图标 + Retry 按钮,点击
reload()(换 src + 时间戳) - 与原生
<img>100% 兼容:inheritAttrs: false+useAttrs把 class/style/alt/id/draggable 全部只绑定到 inner<img>;defineExpose({ imgEl })暴露原始 DOM eager首屏兜底:登录页 Logo、HeaderBar Logo、VirtualList 缩略图(thumbsEager=true)直接加载,避免闪烁fill尺寸模式:fill=true= 填满父容器(width/height: 100%+object-fit: contain)
已替换的页面/组件:views/files/Preview.vue、components/files/ExtendedImage.vue、components/header/HeaderBar.vue、views/Login.vue、views/Share.vue、VirtualList 内所有文件行。
views/files/Preview.vue的isMediaPreview覆盖image / audio / video:图片也显示左右切换按钮- 按钮
position: fixed常驻可见,目录内同类媒体形成循环序列,切换时标题实时同步(route params 优先) - 服务端转码
http/transcode.go:浏览器无法原生解码的容器(.avi/.wmv/.flv/.mpg/.mpeg/.vob/.rm/.rmvb/.ts/.m2ts/.3gp/.asf)经 ffmpeg → 流式 fMP4(H.264/AAC,movflags frag_keyframe+empty_moov+default_base_moof)?probe=1返回 ffprobe 时长 JSON;?start=N在-i之前-ss快速起播- 最多 4 路并发转码(超限 503);客户端断开通过
CommandContext取消 ffmpeg
components/files/VideoPlayer.vue:转码流时间轴始终从 0 开始,播放器内部维护startOffset并在 TECH 层重写currentTime/setCurrentTime/buffered,使进度条、时间显示、缓冲条都工作在源文件坐标;切换源用player.src()而非 dispose 重建
| 脚本 | 用途 |
|---|---|
start-dev.ps1 |
开发环境一键启动。先杀残留进程(8080 端口 + go/filebrowser 进程名)释放 boltdb 锁 → go build -o filebrowser-dev.exe . → 首次 config init + 创建 admin/123456,已有库则幂等重置密码 → 以 -d filebrowser.db -r dev-files -a 127.0.0.1 -p 8080 启动。注意:本脚本不做前端构建 |
run-filebrowser.ps1 |
一键编译 / 自定义运行(生产或自定义根目录/端口/数据库)。自动在 %TEMP% 建 NTFS Junction(fb_proj → 项目根),规避路径中的 (、)、空格、中文;提供 4 个无歧义长参数 -DbFile -JRootPath -KBindAddr -QListenPort;-Mode Build 仅编译 |
build-windows.bat + build-core.ps1 |
标准构建入口(bat 只做参数规范化,逻辑在 pwsh 脚本)。skipFrontend 跳过前端构建(只改后端时秒出 exe)、skipBackend 只构建前端。产物:output/windows-{arch}/filebrowser.exe |
create-search-fixtures.ps1 |
生成搜索测试夹具(目录/文件名样本) |
test-search-performance.ps1、test_batch_api.ps1 |
搜索性能与批量接口的联调脚本 |
dev-https.ps1 |
本地 HTTPS 开发证书辅助脚本 |
my-filebrowser/
├── main.go # 入口
├── go.mod / go.sum # Go 依赖(Go 1.25.0)
├── .gitignore # 已忽略 dev-files、*.exe、*.log、frontend/public/onlyoffice 等
├── build-windows.bat # ⭐ Windows 构建入口(转调 build-core.ps1)
├── build-core.ps1 # ⭐ 构建核心逻辑(前端 pnpm build → go build → output/)
├── run-filebrowser.ps1 # ⭐⭐ 一键编译/自定义运行(Junction + 无歧义长参数)
├── start-dev.ps1 # ⭐⭐ 开发环境一键启动(dev-files 根 + admin/123456 幂等重置)
├── create-search-fixtures.ps1 # 搜索测试夹具生成
├── test-search-performance.ps1 # 搜索性能联调
├── test_batch_api.ps1 # 批量接口联调
├── dev-https.ps1 # 本地 HTTPS 辅助
├── dummy.pdf / test.docx # 前端预览测试用例
├── Dockerfile / Dockerfile.s6 / compose.yaml / .dockerignore
├── Taskfile.yml / .golangci.yml / .goreleaser.yml / .versionrc
├── dev-files/ # 开发运行根目录(已 gitignore;start-dev.ps1 自动创建)
├── output/ # 构建产物(output/windows-amd64/filebrowser.exe,已 gitignore)
├── docs/ # 设计文档与文档资源
│ ├── images/ # README 截图(file-listing.png / pdf-preview.png)
│ ├── recycle-bin-design.md # 回收站设计
│ └── dwg-preview-技术方案.md # DWG 预览方案
├── www/ # mkdocs 文档站点源(自带 Dockerfile / mkdocs.yml)
├── cmd/ # CLI 子命令
│ ├── root.go # 根命令与全部 flags
│ ├── config_*.go # config init/cat/set/export/import
│ ├── users_*.go # users add/ls/find/update/rm/export/import
│ ├── cmds_*.go # 命令白名单 add/ls/rm
│ ├── rules*.go # rule add/ls/rm
│ ├── productcode.go # productcode ls/find
│ └── hash.go / docs.go / version.go
├── http/ # HTTP 路由与处理器(约 50 个文件)
│ ├── http.go # NewHandler:全部路由注册
│ ├── static.go / headers.go / utils*.go / jsonutil.go
│ ├── auth.go # 登录/续签/auth Cookie/封禁心跳
│ ├── users.go # 用户管理 API(移除二次密码校验)
│ ├── resource.go # 资源读写(GET/POST/PUT/PATCH/DELETE)+ 文件锁标记
│ ├── search.go # /api/search
│ ├── preview.go / preview_enum.go / preview_placeholder.go / img 缩略图
│ ├── docconvert*.go # DOCX → 图片(Windows 走 Word COM)
│ ├── pptconvert*.go # PPTX → 图片
│ ├── pdfdecrypt.go # 仅权限加密 PDF 解密
│ ├── transcode.go # ffmpeg 流式转码
│ ├── raw.go / tus_handlers.go / public.go # 流式下载、TUS 断点续传、公开分享
│ ├── recycle.go / filelock.go / oplog*.go / traffic.go # 治理类接口
│ ├── productcode.go / xlsxlinks.go # 产品编号、工作簿外链
│ ├── commands.go / scopetree.go / share.go / settings.go / subtitle.go
│ ├── migrate_keys.go # 路径主键迁移(逻辑路径 → 物理路径)
│ └── *_test.go # 覆盖回收站/文件锁/日志/权限/列举性能等
├── auth/ # 认证方式(JSON / 无认证 / 代理)
├── branding/ # 默认品牌资源(logo/banner/icon)
├── diskcache/ # 磁盘缓存(fileCache,缩略图等)
├── errors/ # 错误类型
├── filelock/ # 文件锁:逐文件访问密码与解锁令牌
├── filemetacache/ # 逐文件派生元数据持久缓存(BlurUp 占位图等)
├── files/ # 文件模型、列举、scope 受限 FS
├── fileutils/ # 路径/文件工具
├── frontend/ # ⭐ 前端(Vue 3 + Vite 8)
│ ├── index.html # 开发模式入口
│ ├── public/index.html # 生产模板(Go template,标题已定制)
│ ├── public/onlyoffice/ # ONLYOFFICE 离线引擎(~580MB,未入 git,需 setup 脚本)
│ ├── public/cad-workers/ # DWG 解析/渲染 Web Worker
│ ├── public/pdfjs/ # pdf.js worker
│ ├── scripts/ # download-onlyoffice.mjs 等维护脚本
│ ├── vite.config.ts # 代理 8080、gzip 压缩、manualChunks
│ ├── package.json # Node >=24、pnpm >=10
│ └── src/
│ ├── main.ts / App.vue
│ ├── api/ # 接口封装(files/search/recycle/filelock/oplog/traffic/productcode/xlsxlinks…)
│ ├── i18n/ # 国际化(默认 zh-cn)
│ ├── css/ # 样式(ios.css 3500+ 行 / styles.css / context-menu.css …)
│ ├── components/
│ │ ├── files/ # VirtualList / LazyImage / ExtendedImage / ImageCarousel /
│ │ │ # VideoPlayer / DwgViewer / CsvViewer / OnlyOfficeEditor / ListingItem
│ │ ├── header/ # HeaderBar / Action
│ │ ├── settings/ # UserForm / Permissions / ScopeSelector / BanGuard / Themes / Rules …
│ │ ├── prompts/ # 全部弹窗(删除/移动/复制/上传/分享/文件锁/产品编号/PDF 合并…)
│ │ ├── ContextMenu.vue / Breadcrumbs.vue / Search.vue / Shell.vue / Sidebar.vue
│ │ └── MacOSSelect.vue / MacOsAudioPlay.vue / DropdownModal.vue / ProgressBar.vue
│ ├── views/
│ │ ├── Login.vue # 登录(URL 自动登录)
│ │ ├── Share.vue # 分享页
│ │ ├── Files.vue / Settings.vue / Layout.vue
│ │ ├── Recycle.vue # 回收站
│ │ ├── FileLocks.vue # 文件锁管理
│ │ ├── settings/ # Profile / Shares / Global / Users / User / Traffic / OpLog
│ │ ├── files/ # FileListing / Preview / Editor
│ │ └── Errors.vue # 403 / 404 / 500
│ ├── router/ # 路由(含 requiresAuth / requiresAdmin)
│ ├── stores/ # Pinia(auth/file/layout/upload/clipboard/router)
│ └── utils/ # theme/encodings/previewLoaders/pdfTextEdit/pdfWatermark/pdfDownsample…
├── img/ # 图片尺寸、缩略图、EXIF、BlurUp Base64
├── oplog/ # 操作日志持久化
├── productcode/ # 产品编号双写(DB 索引 + PDF Keywords)
├── recycle/ # 回收站(.recycle 同卷 rename)
├── rules/ # 命令/访问规则
├── runner/ # 命令执行器(shell 选择、编码、超时)
├── search/ # 搜索匹配语义 + 全局索引
├── settings/ # 系统设置(默认语言 zh-cn 等)
├── share/ # 分享链接模型
├── srv/ # WebSocket 服务(终端/上传进度)
├── storage/bolt/ # BoltDB 嵌入式存储(用户/分享/配置/锁/日志/流量)
├── traffic/ # 流量统计与限速持久化
├── users/ # 用户模型、密码策略、scope
├── version/ # 版本号(被 ldflags 注入)
└── xlsxlinks/ # OOXML 外部链接检测与清理
| 工具 | 版本要求 | 说明 |
|---|---|---|
| Go | 1.25.x | go.mod 声明 go 1.25.0;编译单 exe |
| Node.js | >=24.0.0 | package.json engines.node;旧版本(20/22)会有 Vite 8 + vue-tsc 3 API 不兼容 |
| pnpm | >=10.0.0 | packageManager: pnpm@10.33.4 |
| Git | 任意 | 源码管理 |
| PowerShell 7+ | 可选 | 用于跑 build-core.ps1;系统自带 Windows PowerShell 5.1 也能用 |
| ffmpeg | 可选 | 视频转码(/api/transcode)依赖系统 ffmpeg / ffprobe |
| Word / PowerPoint | 可选(仅 Windows) | DOCX/PPTX 转图片兜底预览依赖本机 Office COM |
国内网络建议配置镜像:
# npm / pnpm 镜像
pnpm config set registry https://mirrors.tencent.com/npm/
# Go 模块镜像
$env:GOPROXY = "https://mirrors.tencent.com/go/,direct"前端 Vite 开发服务器(5173)代理 /api、/static、/raw、/share 到后端(8080);两端分别起两个终端。
cd frontend
pnpm install --frozen-lockfile
# 可选:ONLYOFFICE 离线编辑器资源(Word/Excel 浏览器端编辑需要)
# frontend/public/onlyoffice 约 580MB,未纳入 git,缺省时该功能不可用
pnpm run setup:onlyoffice推荐方式(一键脚本,幂等):
# 自动创建 dev-files/、初始化/重置 admin/123456、启动 127.0.0.1:8080
powershell -ExecutionPolicy Bypass -File .\start-dev.ps1
# admin / 123456手动方式(与脚本等效):
# ======= 仅首次:初始化数据库 + admin 用户 =======
go run . config init --database=dev.db
go run . users add admin 123456 --perm.admin --locale zh-cn --database=dev.db
go run . config set --branding.name="文件管理系统" --database=dev.db
# ======= 启动服务 =======
go run . --database=dev.db --address=127.0.0.1 --port=8080 --root=./dev-files
# admin / 123456提示:
dev-files/用于存放调试样本(PDF / DWG / MP4 / MP3 / DOCX / XLSX / EPUB / CSV / PPTX / 中日韩文件名),用于验证虚拟滚动、懒加载、预览切换、转码、文件锁等。
cd frontend
pnpm run dev
# 默认 http://localhost:5173修改前端代码后浏览器实时刷新;修改后端代码后重启 go run .。
后端通过 //go:embed dist/* 把 frontend/dist 编译进二进制,因此:
# 让改动生效的正确顺序
pnpm -C frontend exec vite build # 1) 重新构建前端产物到 frontend/dist
go build -o filebrowser-dev.exe . # 2) 重新编译,把新产物嵌进 exe
# 3) 重启服务(start-dev.ps1 会先清残留进程再编译再启动)start-dev.ps1 只做 go build,不做前端构建,所以只跑它是不会带上 CSS 改动的;前端 dev server(5173)走的是源码热更,不受此限制。
pnpm run typecheck # vue-tsc(CI 必跑)
pnpm run lint # ESLint
pnpm run test # Vitest
pnpm run build=pnpm run typecheck && vite build,类型检查失败会中断构建。只想快速出产物可用pnpm -C frontend exec vite build。
目标是单文件 filebrowser.exe:前端 frontend/dist/ 通过 //go:embed 整体打入 Go 二进制,运行时无外部依赖。
cd # 到项目根目录(包含 build-windows.bat / build-core.ps1 的那一级)
# 完整构建:前端 build → go build → output\windows-{arch}\filebrowser.exe
.\build-windows.bat
# 快速迭代:跳过前端构建(只改后端时),几秒出 exe
.\build-windows.bat skipFrontend
# 只做前端构建(调试构建配置 / 产物分析)
.\build-windows.bat skipBackend产物:output\windows-amd64\filebrowser.exe(构建时若原 exe 被占用会改写到 .new)。
# ====== 前端 ======
cd frontend
pnpm install --frozen-lockfile
pnpm run build # 产物:frontend/dist/(含 .gz 预压缩)
# ====== 后端 ======
cd ..
$Version = "2.63.15"
$CommitSHA = (git rev-parse --short HEAD 2>$null) -replace "`n",""
$ldflags = "-s -w -X `"github.com/filebrowser/filebrowser/v2/version.Version=$Version`" -X `"github.com/filebrowser/filebrowser/v2/version.CommitSHA=$CommitSHA`""
New-Item -ItemType Directory -Force output\windows-amd64 | Out-Null
& go build -trimpath -ldflags $ldflags -o output\windows-amd64\filebrowser.exe .⚠
go build的-ldflags和它的值必须是两个独立 token(空格分开),不能写成-ldflags=$ldflags,PowerShell 不会在等号里展开变量,Go 会收到字面量$ldflags直接报invalid value "$ldflags" for flag -ldflags。
⚠ 前端
frontend/public/onlyoffice(~580MB)不入 git,构建机上若未执行pnpm run setup:onlyoffice,打出来的 exe 将不含 Word/Excel 在线编辑能力。
cd frontend && pnpm install --frozen-lockfile && pnpm run build && cd ..
VERSION=2.63.15
COMMIT=$(git rev-parse --short HEAD)
go build -trimpath -ldflags="-s -w \
-X github.com/filebrowser/filebrowser/v2/version.Version=$VERSION \
-X github.com/filebrowser/filebrowser/v2/version.CommitSHA=$COMMIT" \
-o output/filebrowser .CGO_ENABLED=0 GOOS=windows GOARCH=amd64 \
go build -trimpath -ldflags="-s -w -X ..." \
-o output/filebrowser.exe .仓库未提供 .bat 封装,直接使用 exe + 脚本:
# 1) 初始化(首次)
.\filebrowser.exe config init --database=.\filebrowser.db
.\filebrowser.exe users add admin "密码" --perm.admin --locale zh-cn --database=.\filebrowser.db
.\filebrowser.exe config set --branding.name="文件管理系统" --database=.\filebrowser.db
# 2) 启动(对外提供服务时改 0.0.0.0)
.\filebrowser.exe -d .\filebrowser.db -r "D:\data" -a 0.0.0.0 -p 8080
# 3) 停止
Stop-Process -Name filebrowser -ForceUNC 网络共享盘(
\\服务器\共享目录)可直接作为-r根目录;也可用--mount 名字:路径挂载多卷,并在用户 scope 里用/图纸&/挂载名引用。生产场景推荐
run-filebrowser.ps1(Junction 规避路径括号 + 无歧义长参数),或参照start-dev.ps1改一份自己的启动脚本(固定数据库/端口/自动重置管理员密码)。
./filebrowser config init --database=/opt/fb/filebrowser.db
./filebrowser users add admin "密码" --perm.admin --locale zh-cn --database=/opt/fb/filebrowser.db
./filebrowser config set --branding.name="文件管理系统" --database=/opt/fb/filebrowser.db
nohup ./filebrowser --database=/opt/fb/filebrowser.db \
--address=0.0.0.0 --port=8080 --root=/opt/fb/files > fb.log 2>&1 &建议用 systemd / docker / s6-overlay 托管进程。
# 仓库提供 Dockerfile(alpine)与 Dockerfile.s6(s6-overlay),另有 compose.yaml
docker build -t filebrowser-custom -f Dockerfile .
docker run -d -p 8080:80 \
-v /opt/fb/database:/database \
-v /opt/fb/files:/srv \
-e FB_DATABASE=/database/filebrowser.db \
-e FB_ROOT=/srv \
-e FB_BRANDING_NAME="文件管理系统" \
filebrowser-custom| 参数 | 说明 | 默认值 |
|---|---|---|
--address |
监听地址 | 127.0.0.1(生产改为 0.0.0.0) |
--port |
端口 | 8080 |
--root |
文件根目录 | 当前目录 |
--database |
BoltDB 数据库路径 | ./filebrowser.db |
--mount |
命名挂载(可多次,名字:路径),供 scope & 语法引用 |
空 |
--cacheDir |
磁盘缓存目录(缩略图等) | 空(禁用) |
--disableExec |
关闭命令执行(终端) | 跟随配置 |
--branding.name |
系统名称(网页标题) | 空 |
--locale |
后端 CLI 输出语言(前端已强制 zh-cn) | zh-cn |
单文件 BoltDB(Go 嵌入式 KV),无需单独安装数据库。除用户/分享/配置外,还存放文件锁、产品编号索引、操作日志、流量累计、BlurUp 占位图缓存等。
filebrowser.exe config init --database=filebrowser.db# 创建(默认中文;--perm.admin=true 授予超级管理员)
filebrowser.exe users add admin "密码" --perm.admin --locale zh-cn --database=filebrowser.db
# 重置密码
filebrowser.exe users update admin --password "新密码" --locale zh-cn --database=filebrowser.db
# 列出 / 查找 / 导入导出
filebrowser.exe users ls --database=filebrowser.db
filebrowser.exe users find admin --database=filebrowser.db
filebrowser.exe users export users.json --database=filebrowser.db
filebrowser.exe users import users.json --database=filebrowser.db
# 删除(谨慎)
filebrowser.exe users rm olduser --database=filebrowser.db开发场景推荐
start-dev.ps1:首次自动创建 admin/123456,后续每次启动都会幂等把 admin 密码重置为 123456(即使 admin 被手动删除也会兜底重建)。
# 列出全部 path → code 映射 / 按编号反查文件
filebrowser.exe productcode ls --database=filebrowser.db
filebrowser.exe productcode find BCQG1-1.05 --database=filebrowser.db- 最小长度:默认 12 位,可用
config set --minimumPasswordLength=6调低(内网场景) - 弱密码黑名单已移除:
123456/admin/password等可直接使用
filebrowser.exe config set --branding.name="文件管理系统" --database=filebrowser.db后端对 /img/* 请求会优先从 branding.files 目录读取(见 http/static.go),替换 Logo 不需要重新编译:
- 准备
logo.svg(正方形;建议同时导出 192/512 PNG 做 PWA 图标) - 放入品牌目录,如
D:\branding\D:\branding\logo.svg D:\branding\img\icons\android-chrome-192x192.png D:\branding\img\icons\android-chrome-512x512.png - 配置:
filebrowser.exe config set --branding.files="D:\branding" --database=filebrowser.db
- 重启服务生效
filebrowser.exe config set --branding.theme=dark --database=filebrowser.db
filebrowser.exe config set --branding.theme=light --database=filebrowser.db # 默认iOS 风格颜色 token 在 frontend/src/css/_variables.css,可直接调主色 #007AFF、圆角半径等;主题类由 frontend/src/utils/theme.ts 写到 html.light / html.dark。
实现:frontend/src/views/Login.vue 的 autoLoginFromURL()
http://host:8080/?u=admin&p=123456
参数别名与自定义跳转:
http://host:8080/?username=admin&password=123456&redirect=/settings/profile
u/username:用户名p/password:密码redirect:登录成功后跳转的内部路径(默认/files/)- 登录成功后浏览器 History 会用
replaceState移除u/p敏感参数
⚠ 安全提示:密码会出现在浏览器历史、反向代理 access log、WAF 审计日志中;仅内网可信场景使用,外网部署建议删除
autoLoginFromURL()调用。
| 问题 | 解决方案 |
|---|---|
| 改了 CSS/组件但页面没变化 | 后端把 frontend/dist 嵌进 exe。必须 pnpm -C frontend exec vite build → go build -o filebrowser-dev.exe . → 重启服务。start-dev.ps1 只做 go build,不会重新构建前端 |
| 深色模式下编辑器顶部残留浅灰条 | 同上:源码已修(ios.css 的 :root.dark .breadcrumbs + styles.css 的 #editor-container .breadcrumbs 透明化),但运行中的 exe 内嵌的是旧 dist。重新构建前端 + 重编译并重启即可 |
pnpm run build 报类型错误中断 |
build 脚本会先跑 vue-tsc。修类型,或用 pnpm -C frontend exec vite build 跳过类型检查直接出产物 |
访问 /assets/xxx.css 返回 HTML |
静态资源前缀是 /static/(如 /static/assets/index-xxx.css),/pdfjs/* 也由同一 handler 提供。裸 /assets/... 会落到 SPA 兜底返回 index.html |
| Word/Excel 在线编辑不可用 | frontend/public/onlyoffice 未入 git,需执行 pnpm run setup:onlyoffice(约 580MB),随后重新构建前端与 exe |
| DWG/DXF 预览空白 | 需要 frontend/public/cad-workers/ 下的 WASM/Worker 资源,且必须重新 vite build 让资源进入 dist;浏览器控制台若报 WASM MIME 错误,检查是否被反代改写了 application/wasm |
| 视频只有声音/黑屏或提示"无法找到兼容源" | 该类容器浏览器无法原生解码,需服务端 ffmpeg 可用(/api/transcode);并发超 4 路会返回 503,稍后重试 |
| 上传/下载被 423 拒绝 | 该文件被 admin 设置了访问密码(文件锁)。在预览弹窗输入密码解锁,或让 admin 在「文件锁」页移除锁 |
| 回收站里的文件在哪,能否手动清理 | 各卷根目录下的 .recycle(同卷 rename)。请通过「回收站」页面操作;直接删目录会绕过索引记录 |
| 登录后界面是英文 | 确认用定制版 exe(config cat 输出 Locale: zh-cn);Ctrl+F5 强刷;仍英文则检查 frontend/dist 是否为中文包产物 |
| 4000 条文件滚动卡顿 | 确认当前是「列表视图」(中间 SegmentedControl);网格 / 画廊不走虚拟滚动 |
| 往上滚时文件条目消失 | 已修复(VirtualList.vue 用滚动容器 BBox 差值计算 selfOffsetTop,且 #listing 必须 position: relative)。仍复现请检查自定义 CSS 是否改了 #listing 定位 |
| 搜索没结果 / 结果不全 | 多关键词是 AND 语义(全部命中文件名才算命中);子目录搜索用 /api/search/{subdir}。刚变更的文件索引异步刷新,可稍等或重新进入目录 |
| HeaderBar Logo 被拉成大图 | 已修复(LazyImage inheritAttrs:false + 去掉 height:auto 强制样式);仍出问题请重新构建前端 |
| 图片 loading 不是 iOS 菊花 | 旧缓存 → Ctrl+Shift+Delete 清缓存;夜间模式菊花颜色可用 --lazy-image-spinner 调整 |
| 提示 password is too easy | 用了旧 exe,请切换到本分支构建的版本(弱密码黑名单已移除) |
| 端口 8080 被占用 | netstat -ano | findstr :8080 找 PID 后结束进程;start-dev.ps1 启动时会自动清理占用 8080 与名字匹配的进程 |
| 忘记 admin 密码 | 重跑 start-dev.ps1(每次启动都幂等重置 admin/123456),或 CLI users update admin --password "123456" |
| 打包后 exe 运行报「前端资源缺失」 | 必须先构建前端(build-windows.bat 不带 skipFrontend);否则 frontend/dist 为空,embed 打进的是空目录 |
go build 报 invalid value "$ldflags" |
PowerShell 中必须写 -ldflags $ldflags(空格分两个 token),不能写 -ldflags=$ldflags |
PowerShell 运行脚本报 MissingArgument |
禁止用 -RawArgs @(...) 与 -d/-r/-a/-p 短 flag(-File 模式解析歧义)。改用 run-filebrowser.ps1 的 -DbFile -JRootPath -KBindAddr -QListenPort |
start-dev.ps1 中文乱码 / 「Error: timeout」 |
脚本须为 UTF-8 with BOM;timeout 是 boltdb 锁被残留进程占用,脚本已内置进程清理与 3 次重试 |
| MinGW ld.exe 报找不到库文件 / 路径截断 | 项目路径含 (、)、空格、中文时用 run-filebrowser.ps1(自动建 Junction 映射为无空格 ASCII 路径) |
Vite 代理 /api 报 502 |
先确认后端 8080 真的在跑;vite.config.ts 已对 [] 编码、multipart 超时、error/econnreset 做了结构化兜底 |
| 层 | 选型 | 说明 |
|---|---|---|
| 后端 | Go 1.25 + Gorilla/Mux + BoltDB(asdine/storm/v3) |
单文件嵌入 + 零外部依赖数据库;pdfcpu(产品编号)、go-astisub(字幕)、gopsutil(系统信息)、cobra/viper(CLI) |
| 前端 | Vue 3.5 + Vite 8 + Pinia 3 + vue-i18n 11 + vue-router 5 + TypeScript 5.9 | 类型安全;HMR 开发;vue-tsc 类型检查。样式为手写 CSS(frontend/src/css/),仅 scope 目录树用到 Element Plus 的 ElTree/ElTag |
| 文档/表格 | pdfjs-dist 6、pdf-lib、docx-preview、mammoth、xlsx、csv-parse、epubjs + vue-reader、utif |
PDF / Office / 表格 / EPUB / TIFF |
| CAD | @mlightcad/libredwg-converter + three + cad-simple-viewer |
DWG/DXF 浏览器端解析渲染(WASM + Web Worker) |
| 音视频 | video.js 8(+ hotkeys / mobile-ui)+ 服务端 ffmpeg |
播放器与实时转码 |
| 编辑器 | ace-builds(文本)、内置 ONLYOFFICE 离线引擎(Word/Excel) |
在线编辑与保存 |
| 构建 | //go:embed 打包 frontend/dist + go build -trimpath -ldflags 注入版本;vite-plugin-compression2 预压缩 .gz |
产物 100% 单文件 |
| 质量门禁 | ESLint 10 + Prettier 3 + vue-tsc 3 + Vitest 4 | pnpm typecheck 与 pnpm test 必跑 |
| 需求 | 修改位置 |
|---|---|
| 改界面文案 | frontend/src/i18n/zh-cn.json |
| 改主题色 / 圆角 / 阴影 | frontend/src/css/_variables.css(token)→ frontend/src/css/ios.css(组件覆盖) |
| 新增页面 | frontend/src/views/xxx.vue + frontend/src/router/index.ts 注册路由 |
| 改登录逻辑 / 自动登录 | frontend/src/views/Login.vue |
| 改文件列表渲染 / 虚拟滚动 | views/files/FileListing.vue + components/files/VirtualList.vue |
| 改图片懒加载 / 菊花 / 错误态 | components/files/LazyImage.vue |
| 改预览(PDF / 图片 / 音视频 / Office / DWG) | views/files/Preview.vue + components/files/ 下对应组件 |
| 改视频转码行为(并发数、参数) | http/transcode.go + components/files/VideoPlayer.vue |
| 改搜索匹配语义 / 索引 | search/ + http/search.go |
| 改回收站策略(保留期、清空) | recycle/ + http/recycle.go |
| 改文件锁拦截范围 | filelock/ + http/filelock.go(资源型接口守卫) |
| 改操作日志字段 / 保留期 | oplog/ + http/oplog.go、http/oplog_api.go |
| 改流量统计与限速 | traffic/ + http/traffic.go |
| 改用户 API / 密码策略 | http/users.go + users/password.go + frontend/src/api/users.ts |
| 改 scope 多目录 / 挂载 | users/(ScopeDirs / BuildScopeFs)+ http/scopetree.go |
| 加新的 CLI 子命令 | cmd/*.go(参考 cmds_add.go 结构) |
| 一键启动脚本(开发) | start-dev.ps1 |
| 一键编译/运行脚本 | run-filebrowser.ps1;标准构建 build-windows.bat + build-core.ps1 |
# 后端日志:直接运行会打到 stdout,也可重定向
go run . --database=dev.db --port=8080 --root=./dev-files 2>&1 | Tee-Object -FilePath fb.log
# 或更推荐:start-dev.ps1 自动处理账号/根目录/端口占用
powershell -ExecutionPolicy Bypass -File .\start-dev.ps1
# 前端样式/交互调试(无需后端每次重启)
cd frontend; pnpm run dev # 5173 代理到 8080
# 只改后端想看结果
.\build-windows.bat skipFrontend; .\output\windows-amd64\filebrowser.exe --database=...
# 自定义根目录启动
powershell -ExecutionPolicy Bypass -File .\run-filebrowser.ps1 -Mode Run `
-DbFile .\filebrowser.db -JRootPath "D:\data" -KBindAddr 127.0.0.1 -QListenPort 8080# 1. 前端已默认产出 .gz(vite-plugin-compression2),后端 /static 直接透传 .gz
# 2. go build 已用 -trimpath -ldflags="-s -w"
# 3. 可选 UPX(部分杀软可能误报)
upx --best --lzma .\output\windows-amd64\filebrowser.exe所有业务接口挂在 /api 下;/static、/pdfjs 提供内嵌前端资源;其余路径由前端 SPA 兜底。
| 分组 | 接口 |
|---|---|
| 认证 | POST /api/login、POST /api/signup、POST /api/renew、GET /api/status/auth(封禁心跳) |
| 用户 | GET/POST /api/users、GET/PUT/DELETE /api/users/{id} |
| 资源 | GET /api/resources(列表/详情)、GET /api/resources/recursive、POST(新建文件/目录)、PUT(保存内容)、PATCH(重命名/移动/复制)、DELETE(删除 → 回收站) |
| 上传 | POST/HEAD/GET/PATCH/DELETE /api/tus(TUS 断点续传) |
| 下载 / 预览 | GET /api/raw/{path}、GET /api/preview/{size}/{path}、GET /api/subtitle/{path} |
| 转换 | GET /api/convert/doc/{path}、GET /api/convert/ppt/{path}、POST /api/pdf/decrypt |
| 视频 | GET /api/transcode/{path}(?probe=1 / ?start=N) |
| 搜索 | GET /api/search/{path}(多关键词 AND) |
| 分享 | GET /api/shares、GET/POST/DELETE /api/share/{path} |
| 公开(无需登录) | GET /api/public/dl/{hash}、GET /api/public/share/{hash}、`GET /api/public/convert/doc |
| 设置 / 范围 | GET/PUT /api/settings、GET /api/scopetree |
| 命令 / 系统 | GET /api/command、GET /api/oslist(仅白名单含 *;仅接受 Windows 绝对路径目录) |
| 产品编号 | GET /api/productcode/search、POST /api/productcode/batch、GET/PUT /api/productcode/{path} |
| 文件锁 | POST /api/filelock/unlock、GET /api/filelock(admin 列表)、PUT/DELETE /api/filelock/{path}(admin 设/移密码) |
| 回收站 | GET /api/recycle、POST /api/recycle/restore、DELETE /api/recycle(彻底删除)、DELETE /api/recycle/all(清空) |
| 操作日志 | GET /api/oplog、DELETE /api/oplog/all |
| 流量 | GET /api/traffic、POST /api/traffic/reset/{id} |
| 工作簿外链 | POST /api/xlsxlinks/force |
已移除:
GET /api/usage(前端不再展示磁盘占用率,避免不必要的系统级df调用)。 文件锁生效时,预览 / 下载 / 转码 / 文档转换 / 字幕等资源型接口在未解锁时统一返回 423。
| 标签 | 发布说明 |
|---|---|
| v2.63.15-custom-1 | 基础定制:中文语言 + 品牌名 + 登录页 iOS 风格 |
| v2.63.15-custom-2 | 弹窗/输入框/toast 深度 iOS 化;移除弱密码黑名单;部署脚本(UNC) |
| v2.63.15-custom-3 | URL 自动登录;外部链接移除;自定义 Logo 指引;夜间模式 |
| v2.63.15-custom-4 ⭐ | 列表视图虚拟滚动;LazyImage 全图替换 + iOS 菊花;图片预览左右切换;build-windows.bat + build-core.ps1(skipFrontend);右键菜单自适应位置 |
| v2.63.15-custom-5 ⭐⭐ | 搜索框 22→54em + 聚焦尺寸锁定 + 点击宽度稳定(仅视觉属性过渡)+ 搜索原子更新/取消;后端 auth Cookie 写入;编辑器保存后列表刷新;PDF 产品编号双写(storm 索引 + PDF Keywords);run-filebrowser.ps1 一键编译/运行(Junction 规避路径括号 + 无歧义长参数,纯 Go 无需 CGO);start-dev.ps1 开发环境一键启动 |
| v2.63.15-custom-6 ⭐⭐⭐ | 应用层回收站(.recycle 同卷 rename + 恢复/彻底删除/清空/过期清理);文件锁(逐文件访问密码,资源型接口统一 423 拦截);操作日志(异步批量落库 + admin 分页查询/清空);流量统计与限速(内存计数 + 周期落库 + admin 重置);账号封禁心跳;DWG/DXF 预览(LibreDWG WASM + three.js);视频实时转码(ffmpeg → 流式 fMP4,覆盖 XVID/WMV/FLV/MPEG-2 等);ONLYOFFICE 离线 Word/Excel 编辑(x2t.wasm,含离线资源下载脚本);多关键词 AND 搜索 + 全局内存索引(启动预热 + 每分钟增量);工作簿外链检测与清理;scope 多目录 + --mount 挂载;PDF 文本编辑/去水印/合并;Excel/CSV 查看器;移除磁盘占用率接口(/api/usage);iOS 主题深色模式全面补齐(含编辑器面包屑);移除日志/审计临时产物 |

