基于彩虹外链云盘二开 + 美化
- 本项目开源地址:https://github.com/hefollo/pan
- 原开源项目地址:https://github.com/netcccyun/pan
本项目采用 MIT 许可证。原项目 netcccyun/pan 同样采用 MIT 许可证,本项目保留原作者版权声明及二次开发作者署名。
MIT 许可允许使用、修改、分发和商用;分发软件副本或实质性部分时,须保留版权声明及许可声明。第三方依赖和素材如有独立许可证,按各自许可证执行。
彩虹外链网盘是一款基于 PHP 开发的网盘与外链分享程序,支持多种类型文件上传,并可生成对应的外链地址,适用于文件分享、图床、音视频外链等多种使用场景。
本项目是在开源版本基础上进行二次开发与界面美化的版本,保留了原有核心功能,并在外观、用户体系、付费权限、邮件通知等方面做了扩展。
文件与外链
- 支持所有常见格式文件上传,可多选批量上传、Ctrl+V 粘贴上传、拖拽上传
- 生成文件外链、图片外链、音乐外链、视频外链,并同时给出 UBB 代码和 HTML 代码
- 文本、图片、音乐、视频在线预览,TXT 等文本内容在线查看
- 文件内容在线编辑,支持
txt、md、json、js、css、html、xml、svg、csv、ini、conf、yaml、sql、vue、ts、jsx等格式;谁能用由会员等级决定,等级不带的用户可以单独购买在线编辑包 - 覆盖上传:用新文件替换已有文件,对外链接保持不变
- 上传时可设置访问密码、可选择是否在首页文件列表公开;后台可设置这个勾选框默认勾不勾(「上传时默认在首页公开」)
- 首页文件列表只显示正常状态的文件:被封禁、待审核的文件不出现在首页,上传者自己的「我的文件」里仍能看到
- 文件列表支持关键字搜索、按类型筛选(图片 / 视频 / 音频 / 文档 / 压缩包),加密文件带锁形标记;
apk、exe这类不在五类里的扩展名不单独出标签,但仍计入「全部」 - 列表可按上传时间或文件大小正反排序(
?sort=new|old|big|small),部分外观下还能在列表和网格视图之间切换 - 用户文件夹(后台开关,谁能用由会员等级决定):「我的文件」里建多级文件夹,文件和文件夹可剪切、复制、粘贴、拖拽移动,在文件夹里上传直接放进去;文件夹只是分类,不改变文件实际存放位置,外链不变
- 「我的文件」里的操作以及进出文件夹、翻页、筛选、搜索都只局部刷新列表,页面不会整页闪
- 可作为网盘使用,也可作为图床或音乐在线试听网站使用
用户与登录
- QQ / 微信快捷登录
- 邮箱注册与登录:填邮箱收验证码即可注册,支持算术验证码
- 找回密码:忘记密码可凭邮箱验证码自行重置,不必找站长改库
- 一个账号多种登录方式:邮箱账号可绑定 QQ / 微信,快捷登录账号可绑定邮箱并设置密码,注册时用的那种方式不可解绑
- 个人中心:概览、我的文件、订单记录、上传 API 密钥、账号设置,最多五个页签(后两者跟着后台开关隐藏),文件可重命名、设访问密码、切公开私密、单个与批量删除、复制外链
- 自定义头像:个人中心里上传自己的头像,选图后可拖动、缩放裁出要显示的部分;显示在个人中心、导航栏和后台用户列表,随时可以恢复默认
- 用户管理:给用户设置会员等级和到期时间,需要时可以单独调整某个人的每日上传数量、单文件大小、下载速度,支持封禁、解封、查看用户文件、删除用户
付费与运营
- 会员等级与购买权限:每个等级一张权限表,把等级做成套餐出售,支持补差价升级,另有加量包和在线编辑包两种附加包;付款成功后权限立即生效
- 支付宝当面付、易支付两种收款方式,可只开一种或同时开启
- 订单记录:按状态筛选、查看累计金额、补发权限、清理未支付订单
- 赞助页与赞助名单
邮件
- 四种发信通道可选:SMTP、Resend、Brevo、SendGrid,可同时勾选多个
- 后台一键测试发信,失败时显示具体原因
- 发信记录:每封验证码邮件的发送结果、通道、来源都有据可查
- 内容检测命中通知:有文件被拦截或转人工时给站长发邮件,可设合并间隔避免刷屏
存储与安全
- 支持本地存储及阿里云 OSS、腾讯云 COS、华为云 OBS、又拍云、七牛云、通用 S3 兼容存储、WebDAV、OneDrive、OpenList
- 存储类型设置改为卡片式:一眼看清每种存储支持直传 / 直链 / 断点续传,卡片上还标出每个存储里压着多少文件,并可一键做连接测试(用当前填写的参数测,不必先保存)
- 有文件之后也能换存储:每个文件记着自己存在哪儿,切换只影响之后的新上传,已上传的文件照常能下、外链不失效
- 可同时开放多个存储:上传页出现「存储位置」下拉让用户自己挑,每个存储还能限定所有人 / 仅登录用户 / 仅限会员(等级带「可用全部存储」)可用
- 图片违规检测,可对接阿里云 / 腾讯云内容安全,也可用自建服务在本机跑模型(文件不出服务器、没有调用费)
- 视频违规检测(自建服务):ffmpeg 抽帧逐帧判分,上传后先挂起、检测完自动放行或封禁,后台能看命中了哪几帧
- 违规文件公示,向访客公开已封禁文件的处理情况
- 覆盖记录审计,管理员可复查每一次内容替换
- 每日上传数量与每分钟上传次数限制
- 下载限速跟着文件的上传者走:上传者是什么等级,他的文件被任何人下载时就是什么速度;游客上传、登录用户上传的文件可分别设定默认速度,留空即不限速
- 上传 API 密钥:用户可自助创建密钥用程序上传,支持 IP 白名单、有效期、随时停用
后台
- 后台首页概览:文件总数 / 今日上传 / 昨日上传 / 用户总数四张卡,下面是文件类型分布——图片、视频、音频、文档、压缩包、其它六类各自的数量、占用空间和占比条,可在「按数量」和「按占用」之间切换,右上角显示全站总占用
- 程序更新检查:首页「版本信息」里直接显示仓库有没有新版本,另有「程序更新日志」页列出最近提交,点进去能看到每次改了什么
- 在线更新:「程序更新日志」页一键把站点更新到仓库最新提交,先列出要改哪些文件再确认,覆盖前自动备份,可一键还原
- 更新源可选:服务器连不上 GitHub 时,在「程序更新日志」页把主更新源换成备用源(自动同步 GitHub 的镜像)、内置的加速站,或者自己填一个加速站地址,版本检查、更新日志和在线更新都跟着换;经加速站下载的更新包不做核对,建议只在 GitHub 和备用源都连不上时用
- 文件管理支持按文件名 / Hash / 格式 / 上传者 IP 搜索,按状态筛选,批量删除、封禁、解封
- 后台左上角名称和浏览器标签跟随「网站标题」:首页是「网站标题管理中心」,其它页面是「页面名 - 网站标题管理中心」,改完网站标题立即生效
- 后台登录页为左右双栏(改自社区贡献者 txziyuan 的 PR #1),配色跟随站点外观和后台自定义配色,左栏显示网站标题和网站描述;输错时直接在页面上提示、保留已填账号,登录成功自动进入后台
界面
- 28 套外观:15 套配色型 + 13 套布局型,前台、后台、公告条、赞助页、弹窗全部联动;每套外观还能在后台单独换整套配色(挑个主色,全站颜色跟着走)
- 广告公告位设置,可自定义顶部公告与首页广告位
- 网站图标:后台「网站信息设置」里上传自己的图标(ICO / PNG / JPG / GIF / WebP),显示在浏览器标签和收藏夹里;图标单独存放,覆盖上传更新包、在线更新都不会把它换回默认图标,随时可以恢复默认
- 页脚运行时间:版权信息下方显示「本站已安全运行:x年x天x时x分钟x秒」并每秒刷新,后台「网站信息设置」里可开关、可设建站时间(精确到秒)
- 页脚代码(原「统计代码」):像广告位一样一条一条添加,放统计脚本、备案号、徽章链接等,每条可单独开关,按列表顺序排在版权信息后面(和版权同一行,一条一格,放不下自动换行);只有脚本、看不见的统计代码不占格子
- 页脚位置统一:所有页面、所有外观的页脚都在同一个位置,左右和内容区对齐,上方一条细分隔线(页脚自带底色的涂鸦风、天际风和 macOS 窗口风除外);内容不满一屏时页脚贴在窗口底部,不再悬在半空(macOS 窗口风的页脚是窗口底部的状态栏,跟着窗口走)
- 禁止访问 IP:和页脚代码一样一条一条添加,每条可填单个 IP(IPv4 / IPv6)或网段(如
1.2.3.0/24)、写备注、单独停用;条目多时列表在固定高度的框里滚动,可按 IP / 备注搜索,也能一次粘贴多个 IP 批量添加(自动跳过已有的);命中的访客访问前台直接返回 403,已登录后台的管理员不受影响,填错的写法保存时会被拒绝并指出是哪几条 - 手机端适配:28 套外观在手机上文件列表都排成卡片(文件名完整显示、可换行,大小 / 格式 / 时间和下载、查看按钮都在卡片里,不用横向滑动),导航菜单纵向展开,前台后台点选菜单项后菜单都会自动收起
登录与注册
购买权限页
个人中心
一级菜单收成「首页 / 文件 / 用户 / 设置 / 退出」五项,「设置」下拉再按「站点 / 上传与存储 / 用户与付费 / 安全与合规 / 其它」分组,不用在十几个二级页面里翻找。侧栏型外观(控制台侧栏风 / 数据控制台风 / 深色工作台风 / 渐变仪表盘风,以及工作台家族里除云端门户风外的六套)下这些分组 是常驻展开的静态列表,不需要点开;云端门户风前台是顶部横向导航,后台也保持顶栏。
后台首页
上面四张卡是文件总数、今日上传、昨日上传、用户总数;下面整块是文件类型分布,六类各一行,显示数量、占用空间和占比条,可切换按数量或按占用空间计算占比,右上角是全站总占用。右下角「版本信息」里带更新检查,详见程序更新检查。
文件管理
用户管理
覆盖记录
存储类型设置
内容检测设置
内容检测记录
外观设置
购买套餐设置
订单记录
邮件发信设置
发信记录
用户 IP 地址获取设置
后台「系统设置 - 外观设置」可切换 28 套外观,前台页面、后台管理界面、顶部公告条、友链广告位、赞助页和各类弹窗会一起联动。
外观分成两类:布局型改的是页面结构(导航位置、内容排版),配色型只改颜色和质感、保持默认的顶部导航布局。
网速慢时不会先闪出原版的默认样式:外观样式表(assets/css/style.css)到达之前,页面只显示当前外观的底色,样式一到直接显示换肤后的页面;样式表加载失败或 15 秒还没到时照常显示,不会一直空白。
手机上(宽度 767px 以下)首页文件列表和违规公示列表每行是一张卡片:文件名一行、大小 · 格式 · 时间一行、操作按钮一行;门户风和 macOS 窗口风沿用自己的卡片网格。这套规则在 assets/css/style.css 末尾带「手机端适配」标记的那一段里,靠 index.php / violation.php 输出的 filelist-wrap 和 fl-* 类名定位各列,改列表的列时要一起改。
| 外观 | 结构 | 后台 |
|---|---|---|
| 控制台侧栏风 | 顶部导航变为左侧固定侧栏,内容区为圆角卡片布局 | 同步改为侧栏 |
| 数据控制台风 | 更紧凑的侧栏,标题与搜索独立成顶栏,文件列表上方增加统计卡与类型筛选 | 同步改为侧栏 |
| 上传门户风 | 居中的门户式顶部导航,首页增加大号上传引导区,文件列表改为卡片网格 | 只换配色,保留顶栏 |
| 深色工作台风 | 深色底 + 72px 图标导航条(鼠标移上去展开文字),右侧常驻文件预览面板 | 同步改为侧栏 |
| macOS 窗口风 | 整站套进一个 macOS 窗口:带红黄绿三颗灯的标题栏 + 底部状态栏,文件列表默认是访达式图标网格,可一键切回列表视图 | 同步套窗口,登录页也是 |
| 渐变仪表盘风 | 白色悬浮圆角侧栏(默认展开显示文字),列表页顶部是问候栏 + 紫色渐变额度卡与统计卡,右侧一列存储分布、最近上传、快捷入口面板 | 同步改为侧栏 |
| 蓝白工作台风 | 白色分组侧栏(工作空间 / 个人中心,底部升级卡)+ 顶部搜索条(Ctrl K 聚焦),列表页是蓝白横幅 + 四张统计卡 + 带类型筛选、排序、列表/网格切换的文件面板,右侧一列今日上传、我的权限、快捷操作、最近动态 | 同步改为侧栏 |
| 深空科技风 | 蓝白工作台的深色版:深蓝星空底 + 发光描边,横幅是大标题加三个卖点,权限卡多一行 | 同步改为侧栏 |
| 紫韵会员风 | 蓝紫渐变横幅、彩色统计卡,右侧首块是金色会员权限卡带升级入口,列表下方加一条卖点横幅 | 同步改为侧栏 |
| 清爽极简风 | 近乎纯白,横幅不做卡片直接铺在页面上,四条勾选卖点 + 两个大按钮,五张统计卡,最近动态是时间轴 | 同步改为侧栏 |
| 蓝天白云风 | 天蓝渐变横幅、右上角三枚浮标卖点,五张统计卡,列表下方是会员升级横幅 | 同步改为侧栏 |
| 潮酷涂鸦风 | 粗黑描边 + 硬投影 + 米色底的撞色风格:黑色侧栏配橙色选中项,超大标题横幅带手写标语和两个大按钮,五张统计卡各一个高饱和颜色 | 同步改为侧栏 |
| 云端门户风 | 家族里唯一的顶部横向导航:天空渐变大横幅带远山和居中大搜索框,浅色统计卡,右侧一列蓝色上传卡、存储空间、最近上传 | 保持顶栏 |
三套侧栏外观(控制台侧栏风 / 数据控制台风 / 深色工作台风)的侧栏底部会显示「今日上传」和「我的权限」两张卡片;渐变仪表盘风把同样的信息放进了顶部那张额度卡;其余外观则在文件列表页和上传页顶部显示一条权限条,内容一致。
工作台家族(7 套)
最后这七套共用同一套页面结构——分组侧栏 + 顶部搜索条 + 主视觉横幅 + 统计卡 + 文件面板 + 右侧数据列,区别在配色、横幅表现和几块可选内容(推广横幅、存储空间、会员卡等)。云端门户风是其中的例外,它把侧栏换成了顶部横向导航,搜索框搬进横幅里。
深色系
| 主题 | 风格 |
|---|---|
| 黑夜风格 | 深色背景、蓝色高亮,适合夜间浏览 |
| 霓虹科技黑夜 | 蓝紫霓虹、科技感边框 |
| 暗黑科技后台风 | 深色点阵背景、半透明暗色面板,偏数据管理感 |
浅色系
| 主题 | 风格 |
|---|---|
| 蓝白清爽 | 默认主题,蓝白配色 |
| 青瓷微澜 | 青瓷色同心波纹,留白通透 |
| 淡紫点阵 | 薰衣草底色配细密点阵 |
| 米白纸张 | 极简纸张质感,横线纸纹配墨黑标题 |
| 淡粉暖调 | 浅粉底色配玫瑰色高亮 |
| 天蓝细纹 | 青蓝色调配斜向细纹 |
| 薄荷蜂巢 | 薄荷绿蜂巢暗纹 |
毛玻璃系
采用多层网格渐变背景叠磨砂玻璃面板,带内侧高光描边与彩色辉光。
| 主题 | 风格 |
|---|---|
| 蓝紫渐变玻璃 | 蓝紫渐变,半透明玻璃卡片 |
| 落日熔金 | 珊瑚橙到品红的落日渐变,浓烈张扬 |
| 深海玻璃 | 深海蓝绿渐变配青色辉光,通透安静 |
| 翡翠流光 | 翡翠绿到松石色,清透有质感 |
| 樱雾玻璃 | 粉紫到天青的浅色雾面渐变,轻盈明亮 |
外观设置页顶部有一条吸顶的「外观配色」工具条(连同「保存外观」按钮),滚到最底下也一直停在上方。挑一个主色和副色,这套外观的整套配色一起换掉,不是只换几个按钮。
| 项目 | 作用范围 |
|---|---|
| 主色 / 副色 | 该外观用到的全部有色部分:按钮、进度条、导航高亮、面板、卡片、边框、文字、图标、阴影、整页背景,前台和后台一起变 |
| 渐变角度 | 按钮、分页高亮等渐变元素的方向 |
| 中间色 | 渐变仪表盘风顶部那张额度卡的三段渐变 |
| 界面底色:页面底色 / 面板底色 / 正文色 / 边框色 | 灰白系不跟着主色的色相走,所以单独可调。改「面板底色」会把这套外观里所有白卡片、表格、下拉面板的底色一起换掉 |
| 整页背景渐变(起点 / 中间 / 终点 / 角度) | 本来就铺渐变背景的外观:黑夜风格、霓虹科技黑夜、蓝紫渐变玻璃、落日熔金、深海玻璃、翡翠流光、樱雾玻璃 |
换色方式是色相映射而不是简单替换:拿该外观原本的主色、辅色当锚点,算出新旧颜色之间的色相 / 饱和度 / 明度差,再把同一份差值套到这套外观的每一个颜色上。所以:
- 主色本身落在原来主色的位置,其余颜色按原有关系跟着走,深浅层次和对比度保持不变
- 纯白、纯黑、灰色(阴影、分隔线)不动,近白的卡片底不会被压暗,深色外观的近黑底也不会糊成一片
- 红色危险、绿色成功这类状态色跟主色系差得远,自动保持原样
- 米白纸张、暗黑科技后台风这种本来就是单色系的外观,走「整套灰阶染上新色相」的路子
- 因此白卡片、页面留白这类灰白底不会跟着主色变,要改它们用上面的「界面底色」四项;这四项按属性类别定点替换(背景类属性认面板底色、文字类属性认正文色、边框类属性认边框色),所以把白卡片换成米色时,按钮上的白字不会跟着变
- 只有这四项本身的颜色会被替换,由它们派生出来的次级底色(如
--surface-soft、--tint)仍按原值走,改动幅度太大时可能需要一起微调
其它细节:
- 工具条里的外观下拉框和下面的外观卡片是同一个选择,两边双向同步:在哪边选都会同时选中另一边,保存的外观和正在调的颜色永远是同一套
- 每套外观各存各的,改哪套只影响哪套,换回去颜色还在;「恢复默认配色」把当前外观还原成内置配色
- 工具条可以「收起 / 展开」,收起状态记在浏览器里
- 只有改过的外观才会落库,没动过的外观一个字节都不多输出,页面和原来完全一样
- 换色样式由
includes/theme_recolor.php从style.css/admin.css里抽取该外观的规则重算后生成,缓存在assets/css/custom/(按外观 + 颜色 + 源文件时间哈希命名,改了源样式会自动重算;目录不可写时退回页面内联输出) - 静态 404 页在保存外观时一并写入,错误页配色跟站点一致
后台「系统设置 - 用户登录设置」控制登录功能总开关,「邮件发信设置」里控制邮箱注册。
- QQ / 微信快捷登录:配置快捷登录接口后可用,新用户登录后自动注册账号
- 邮箱注册:填邮箱 → 收 6 位验证码 → 设置密码 → 注册完成并直接登录
- 算术验证码:获取验证码前需要算一道简单算术题(如
5 + 3 = ?),可在后台关闭 - 两种方式可以并存,登录页会自动显示可用的入口
后台可配置验证码有效期、同邮箱发送间隔、每日发送上限、全站发信上限,以及一次性邮箱域名黑名单。
找回密码
登录页有「忘记密码」入口,流程是:填邮箱 → 收 6 位验证码 → 填验证码和新密码 → 回登录页用新密码登一次。
- 不管邮箱在不在站里,提示语都是同一句「如果该邮箱已注册,验证码已经发出」,避免被拿来试探站里有哪些邮箱;只有真存在的账号才会收到信
- 重置成功后不自动登录,让用户拿新密码真登一次、自己确认改对了
- 入口门槛看的是「发信可用 + 站里有邮箱账号」,不跟注册开关走——关掉注册之后老用户照样能找回密码
- 密码改完,其它设备上的登录状态会立刻失效
- 之前因为密码试错被临时锁定的,重置成功后锁定一并解除,不会出现「刚改完还是登不进去」
登录后从导航栏昵称下拉进入「个人中心」(/user.php),导航栏的「我的文件」也直接落到这里的文件页。游客没有账号,「我的文件」仍然是按浏览器缓存记录显示的首页列表。
页面最多五个页签,其中两个会跟着后台开关自动隐藏:
| 页签 | 内容 |
|---|---|
| 概览 | 文件数、占用空间、今日上传 / 上限、单文件上限四张数字卡,下面是会员等级、每日上传(含加量包及其到期时间)、单文件大小、有效期、在线编辑的开通情况,以及自己文件的类型分布条 |
| 我的文件 | 按文件名搜索、按类型筛选,可重命名、设置或取消访问密码、切换公开 / 私密、复制外链、单个与批量删除,每页 20 条;后台开了用户文件夹时还能按文件夹整理(见下一节) |
| 订单记录 | 自己的订单号、套餐、金额、支付方式、状态、下单与支付时间;打开页面时会顺手补查一次当面付的漏单。购买功能没开时不显示 |
| 上传 API 密钥 | 接口地址与调用说明,创建 / 停用 / 删除自己的密钥,查看前缀、IP 白名单、到期与最近使用时间。上传 API 没开时不显示 |
| 账号设置 | 账号资料(注册方式、注册时间、最后登录)、头像、修改昵称、登录方式绑定、修改或设置密码 |
「私密」只是不在首页公共列表里出现,外链本身照样能打开,页面上也写着这句提示;真要限制访问得给文件设访问密码。
账号绑定
- 邮箱注册的账号可以绑定 QQ / 微信,之后两种方式都能登录同一个账号
- QQ / 微信登录的账号可以绑定邮箱并同时设置密码,绑定后就能用邮箱 + 密码登录
- 注册时用的那种方式是主身份,不可解绑,所以「至少保留一种登录方式」天然成立
- 同一个邮箱不会落到两个账号上:注册查重时会连绑定关系一起查
- 站点没配发信通道时,绑定邮箱的入口会置灰并说明原因
头像
- 点个人中心头部的头像,或者「账号设置 - 头像」里的「上传头像」选图;选好后弹出裁剪框,拖动图片调位置,拖滑块或滚轮缩放,确认后上传,页面不刷新直接换上
- 支持 JPG、PNG、GIF、WebP(动图只取第一帧)。图片在浏览器里先裁成 256×256 再传,手机拍的大图也只传一百来 KB
- 服务端按文件内容认类型,不看文件名;装了 GD 扩展时会再重新编码一遍,没装 GD 也能用
- 头像显示在个人中心、导航栏用户名旁边、带顶栏头像的几套布局型外观,以及后台用户列表;图片失效时自动退回原来的图标或昵称首字
- 传过头像之后会出现「恢复默认」。QQ / 微信登录的账号原本带着快捷登录的头像,传了自己的头像再恢复默认后,下次用 QQ / 微信登录时会重新取回
- 后台「用户管理」里,传过头像的用户多一个「清除头像」;删除用户时头像文件一并删除
- 头像文件保存在站点的
assets/avatar/目录(每人一个文件,第一次上传时自动创建),需要assets/可写
后台「系统设置 - 文件上传设置」里的「用户文件夹」,默认关闭。打开后,「我的文件」(个人中心的文件页,以及游客的 ?m=mine)里可以按文件夹整理文件。
| 设置 | 说明 |
|---|---|
| 用户文件夹 | 总开关。关闭后列表恢复平铺,已建的文件夹保留,再次开启即恢复 |
| 谁能用 | 由会员等级决定:到「会员等级设置」里给相应的等级勾选「用户文件夹」,给「游客」勾上就是所有人都能用 |
| 另外放行的 UID | 选填。名单里的登录用户不管是什么等级都能用文件夹 |
能做什么
- 新建多级文件夹(最多 10 层,每人最多 500 个)、改名、删除;删除文件夹时子文件夹一起删,里面的文件不会被删除,全部移回根目录
- 勾选文件或文件夹后剪切 / 复制,进入目标文件夹点「粘贴」;也支持 Ctrl+X / Ctrl+C / Ctrl+V
- 「移动或复制到…」用目录树选目标,也可以直接把行拖到文件夹上或上方的路径上
- 在某个文件夹里点「上传到这里」,上传的文件直接放进这个文件夹
- 搜索、按类型筛选时跨全部文件夹查找,结果里标出每个文件所在的文件夹
需要知道的
- 文件夹只是分类记录,不改变文件在存储里的实际位置:移动、改名都不影响外链,所有存储类型都一样
- 复制出来的文件和秒传一样指向同一份内容,不多占存储,有自己独立的外链;复制不算当天的上传数量,也不计入每分钟次数;被冻结或待审核的文件不能复制
- 一次最多移动或复制 200 个文件
- 游客没有账号,文件夹和游客上传的文件一样只保存在当前浏览器会话里,换浏览器或清缓存就找不到了;游客登录后,文件夹会连同文件一起转到账号名下
- 开启后游客的「我的文件」也可以给文件改名,规则和个人中心一致
- 管理员在后台删除用户时,他的文件夹一并删除,文件回到根目录
「我的文件」里的操作(重命名、删除、移动、复制、改访问密码、切公开私密、覆盖上传)以及进出文件夹、翻页、筛选、搜索,都只局部刷新列表,页面不会整页闪一下;地址栏会跟着变,浏览器的前进 / 后退照常可用。这一点和文件夹开关无关,开关关着也一样。
后台「系统设置 - 邮件发信设置」,用于发送验证码(注册、找回密码、绑定 / 更换邮箱)和站内通知。
| 通道 | 说明 |
|---|---|
| SMTP | 填自己的邮箱账号和授权码,QQ 邮箱、163、企业邮箱都可用 |
| Resend / Brevo / SendGrid | 走 HTTPS 接口发信,不受服务器封禁邮件端口的影响 |
- 没有默认通道,勾选哪个用哪个,一个都不勾就是关闭发信
- 勾选多个时按顺序依次尝试,前一个失败自动切到下一个
- 页面底部可以测试发信,填一个邮箱点一下就知道通不通,失败时显示具体原因
「发信记录」页记录每一次验证码发送:时间、邮箱、用途、状态(已发送 / 已验证 / 发送失败 / 已作废)、通道或失败原因、来源地址。顶部还有最近 1 小时、24 小时的发送量与上限对比,方便判断接口有没有被滥用。
站点自己发的通知信(比如下面的内容检测命中通知)不写进发信记录。那张表同时也是验证码限额的计算依据,通知信混进去会把用户注册要用的额度顶掉。通知信发失败只记日志,不影响上传。
站点用会员等级管理用户能做什么,并把等级做成套餐卖给用户,付款成功后权限立即生效,全程不需要人工介入。后台入口在「系统设置 - 会员等级设置」「购买套餐设置」和「订单记录」,前台入口是导航栏的「购买权限」。
一个等级就是一张权限表,在后台「会员等级设置」里增删改:
| 权限项 | 说明 |
|---|---|
| 每日上传数量 / 单文件大小 | 填 -1 跟随站点设置,0 不限,或者具体数值 |
| 下载速度 | 这个等级的用户上传的文件被下载时的速度(谁来下载都一样),取值同上,见下载限速 |
| 在线编辑 / 用户文件夹 / 上传 API | 这个等级能不能用对应的功能 |
| 可用全部存储 | 能不能用多存储里标了「仅限会员」的存储 |
| 上传免审核 | 不做视频人工审核、不受禁止上传的类型和文件名限制(内容检测照常做) |
内置三个等级,不能删除:
- 游客:没有登录的访客
- 普通用户:注册后默认的等级,会员到期后也回到这里
- 管理员:不受任何限制——数量、大小、速度都不限,全部功能可用,上传免审核、不做内容检测、不限上传频率。只能在「用户管理」里手动给某个账号,不能出售;它只是前台账号的权限,不等于能登录后台
其余等级自己建,有高低顺序。程序内置一套推荐等级(入门 / 基础 / 标准 / 进阶 / 尊享 / 旗舰会员)和配套的套餐,在「会员等级设置」或「购买套餐设置」点「一键导入推荐等级和套餐」即可导入(同名自动跳过),导入后名称、权限、价格随便改。
用户是什么等级、什么时候到期在「用户管理」里看和改;需要给某一个人特殊照顾时,可以在弹窗的「单独调整」里改他的每日数量、单文件大小、下载速度(有效期内优先于等级,用户购买或升级等级时会被清掉)。
两种可以只开一个,也可以同时开着让用户在购买页自己选。
| 方式 | 流程 | 需要填写 |
|---|---|---|
| 支付宝当面付 | 页面内直接出二维码,扫码付款 | 应用 ID、支付宝公钥、商户应用私钥 |
| 易支付 | 点「立即购买」后弹窗选支付宝 / 微信 / QQ钱包,跳转到收银台 | 接口地址、商户 ID(PID)、商户密钥(KEY) |
还可以设置付款时显示的商品名称、易支付开放哪几个支付通道,以及购买页顶部的公告文字。
套餐在后台「购买套餐设置」里增删改,购买页按分类分区展示。套餐只有三种:
- 会员等级:买了成为该等级的会员。同一个等级可以挂月卡、季卡、年卡、永久等多个套餐,只是天数和价格不同
- 加量包:每天多传 N 个,加在当前等级的每日数量上,重复购买一直累加
- 在线编辑包:给等级不带在线编辑的用户单独开通在线编辑;有效期天数随便填,填 1 就是按天卖
购买规则:
- 新购 / 续费:没有会员等级的按标价买;同一个等级再买是续费,天数接在现有到期时间之后;买到永久套餐就是永久
- 补差价升级:限时会员想换成更高的等级,在购买页顶部点「补差价升级」,只补到期前这段时间的差价,到期时间不变。差价 =(目标等级日价 − 当前等级日价)× 剩余天数,日价取该等级在售限时套餐里天数最短那个的「价格 ÷ 天数」,所以买年卡的人升级时不会因为年卡日均便宜而多补钱。升级后想延长时间,再买新等级的套餐续费
- 买永久套餐:限时会员买永久套餐时,剩余天数按日价折抵;永久会员升到更高等级的永久套餐,只补两个永久套餐的差价
- 等级比自己低的套餐、买了不会有任何作用的套餐(比如每日数量已经不限还买加量包、等级已经自带在线编辑还买在线编辑包),购买页会说明原因并且不出购买按钮;管理员等级不需要也不能购买
- 金额一律由服务端按用户当前的等级和到期时间计算,不接受前端传值
- 加量包和在线编辑包各有自己的到期时间,和会员到期时间互不影响
- 没有在线编辑权限的登录用户在自己的可编辑文件上仍能看到「在线编辑」入口,点进去会提示去购买
从旧版升级上来的站点:原来按数值发放的时长卡、大文件包、永久卡在升级时自动下架(列表里标为「旧版套餐」,可以直接删除),已经买了的用户权益保留到原来的到期时间;原来的「高级用户」会被挪到一个自动建立的「高级用户(旧)」等级,权益和到期时间不变。升级后到后台点一次「一键导入推荐等级和套餐」,购买页才有等级可买。
按状态筛选、查看累计金额,每笔订单都能查询支付状态、补发权限或关闭,另有「清理未支付订单」一键清理废单。
后台「系统设置 - 文件上传设置」可以设置:
- 全站每日上传数量、单文件大小上限
- 每分钟上传次数
- 允许 / 禁止的文件类型、文件名关键词过滤
- 上传时默认在首页公开:决定上传页「在首页文件列表显示」一打开是勾上还是不勾(默认勾上),用户上传时仍可自己改;首页的快捷上传区也按它,上传 API 不受影响
登录用户按账号统计,游客按来源地址统计。用户的额度由会员等级决定,可以通过购买套餐获得,也可以在「用户管理」里给某个人改等级或单独调整。用户在「我的文件」里复制出来的文件不算上传,不计入每日数量和每分钟次数。
站点如果套了 Cloudflare 或其它反向代理,需要在「系统设置 - 用户IP地址设置」里选对获取方式,页面上会直接显示每种方式当前取到的地址,对照着选即可。
这一项不只影响统计显示。IP 黑名单、上传频率限制、上传 API 的 IP 白名单都按这里取到的地址判断。套了 Cloudflare 就应当选「3_Cloudflare(自动校验来源)」——它会核对请求确实来自 Cloudflare 的网段才认
CF-Connecting-IP,否则随便谁伪造一个请求头就能绕过上面这些限制。
限速跟着文件的上传者走,不看下载的人。 上传者不限速,他上传的文件任何人下载都不限速;反过来,会员去下载别人上传的文件,按的是别人的速度,不会因为自己是会员而变快。
一个文件被下载时的速度,按下面的顺序取第一个符合的:
| 上传者 | 速度 |
|---|---|
| 管理员等级 | 不限速 |
| 在「用户管理」里被单独调过速度(到期时间之内) | 调整值 |
| 有会员等级,且等级填了下载速度 | 等级的速度 |
| 其余登录用户(等级填的是跟随站点设置) | 「存储类型设置」里「登录用户上传的文件」那一档 |
| 游客,或上传者账号已经删除 | 「存储类型设置」里「游客上传的文件」那一档 |
两档默认速度在后台「上传与存储 - 存储类型设置」页的「下载速度权限」里设置。
- 单位可选 KB/s 或 MB/s,填 0 或留空表示不限速
- 下载的人是谁不影响速度,唯一的例外是下载者自己是管理员等级时不限速;后台管理员在后台里下载文件也不限速
- 限速是按单个连接算的,多线程下载工具同时开多个连接时总速度会成倍
- 内容检测服务回源取图用的是本站签发的带签名地址(一小时内有效),只有验过签名的请求才不限速
- 被限速的下载会强制走网站中转,不再跳转到对象存储直链——直链一旦发出去就管不住速度了
- 整站用了 CDN 的话,不要对
down.php设强制缓存,否则请求命中 CDN 后会绕开本站限速直接按 CDN 带宽下载
除了网页上传,站点还提供一个文件上传接口(api.php),方便用程序或第三方工具上传。后台「系统设置 - 上传API设置」和「系统设置 - 用户设置」里控制。
调用方式
POST /api.php
Content-Type: multipart/form-data
文件字段:file
身份走请求头,两种写法都认:
Authorization: Bearer pan_xxxxxxxx...
X-API-Key: pan_xxxxxxxx...
部分服务器(含默认配置的 Apache)不会把
Authorization头传给 PHP,这种情况改用X-API-Key即可。
谁能调用
谁能用上传 API 由会员等级决定,到「会员等级设置」里给相应的等级勾选「上传 API」:
| 情况 | 结果 |
|---|---|
| 带密钥 | 看密钥所属账号的会员等级有没有「上传 API」 |
| 不带密钥 | 只有给「游客」等级勾了「上传 API」才允许,相当于公开接口 |
用户自助管理密钥
开启上传 API 后,个人中心多出「上传 API 密钥」页签,用户可以自己创建和管理:
- 密钥正文只在创建时显示一次,数据库里只存哈希,丢了只能重新建一把
- 可设 IP 白名单(支持单个 IP 和 CIDR 网段),不填表示不限
- 可设有效期,到期自动失效;也可以随时停用或删除
- 每个账号最多能建几把、默认有效期多少天,都在后台配
- 通过接口传上来的文件进入密钥所属账号的「我的文件」,和网页上传的文件一样受每日数量、单文件大小、内容检测等全部限制
接口不借用浏览器的登录 Cookie,只认显式传的密钥,避免跨站请求偷偷用别人的身份上传。后台还可以另外配来源域名白名单。
后台「系统设置 - 内容检测设置」可以对上传的图片和视频自动判定,三种引擎任选: 阿里云内容安全、腾讯云内容安全,或自建检测服务(在自己服务器上跑本地模型, 文件不出服务器、没有调用费,部署见 tools/nsfw/README.md)。
判定结果分三档,不是简单的拦或不拦:
| 结果 | 文件状态 | 说明 |
|---|---|---|
| 放行 | 正常 | 低于转人工阈值 |
| 待人工 | 待审核 | 落在两个阈值之间,前台下载不了,等人工确认 |
| 已拦截 | 封禁 | 高于封禁阈值,同时记入违规公示(默认不公开,需人工确认后放出) |
留中间这一档是因为本地模型的误判率比商用接口高得多,一刀切封掉会天天误伤。
图片是上传请求里同步跑完的,几百毫秒无感。视频要抽帧,十几秒起步,所以是异步的:
- 上传完先挂起(前台显示「需审核通过后才能在线播放和下载」),抽帧打分在后台跑
- 跑完自动放行或封禁,不会卡住上传,也没有「先能下载、过一会儿突然被封」的窗口
- 判定口径和图片不同:够 N 帧命中才封(默认 2 帧),只命中 1 帧转人工——转场、 肤色、泳装剧照都可能让某一帧飙到 0.9,只看最高分会误判到没法用
- 命中的那一帧会存成证据帧,人工复核时直接看图,不用去播放器里找
- 检测服务万一挂了,超时会自动放行(默认 30 分钟),不会让视频永远卡在待审
视频检测需要服务器上有 ffmpeg,一键安装脚本会自动处理;没有 ffmpeg 时后台设置页会 直接标红提示,图片检测不受影响。
后台「内容检测记录」记录每一个检测过的文件,包括放行的——只看被拦下的,永远不知道 有多少该拦的漏了过去。页面上能看到评分、各模型明细、耗时、视频命中了哪几帧、 最高分在第几秒,可以按结果和图片/视频分别筛选,也能就地把文件状态改成正常 / 封禁 / 待审。
检测判为「已拦截」或「待人工」时可以给站长发一封邮件,省得盯着后台看。在「内容检测设置」里开关:
- 只有这两种结果会发信;放行的没人要看,检测失败属于服务本身的毛病,记录页上看得见
- 收件邮箱留空就发给发件邮箱自己
- 可设合并间隔:一次传几十张图、中间十几张命中的场面很常见,一条一封会把信箱刷爆。设成 0 是每条一封,大于 0 则同一时间窗内只发一封,漏掉的条数并进下一封里说明
- 邮件里的后台链接按后台目录的真实名字生成,改过后台目录名也点得开
- 需要先配好发信通道,否则开关旁边会提示未就绪
面向合规场景,把已封禁文件的处理情况对外公开。
- 前台入口在导航栏「违规公示」,地址
/violation.php - 后台「文件管理」里封禁文件会自动生成公示记录,解封会自动撤下,批量操作同样生效
- 被封禁或待审核的文件不会出现在首页文件列表里,首页的文件数、类型统计也不计入它们
- 后台「系统设置 - 违规公示管理」可查看全部记录、修改文件名与备注、单条开关是否公示、手动补录或删除记录
- 支持一键导入历史已封禁文件
- 可在「网站信息设置」里关闭整个公示功能,并自定义公示页顶部的说明文字
公示页只输出脱敏信息:文件名打码、IP 只显示前两段,不输出文件哈希、下载链接或任何可访问地址。开启内容检测时,机器自动命中封禁的文件会留档但默认不公示,需人工确认后手动放出。
用户的覆盖上传和在线编辑都会改变已有链接背后的内容,后台「覆盖记录」用于复查这类改动。
- 记录覆盖前后的文件名、大小、格式,图片可直接预览新内容
- 记录操作者 UID / IP、时间和方式(覆盖上传 / 在线编辑)
- 显示该文件当前状态(正常 / 待审 / 已封禁 / 已删除)
- 每条记录可直接查看、封禁、删除文件、标记已复查或删除记录
- 默认只显示未复查的条目,页面顶部提示积压数量,支持一键全部标记已复查
后台两个地方可以看到程序有没有更新:
- 后台首页「版本信息」:显示「已是最新版本」「发现新版本 xxxx」「检查失败」等状态,旁边是最近一次提交的标题和时间
- 设置 - 其它 - 程序更新日志:本地与仓库的版本号对照,以及仓库
main分支最近 20 条提交(短 SHA、标题、作者、时间、提交说明),点短 SHA 直接跳到 GitHub(或所选更新源)上那次提交
判断依据
线上站点是用整包覆盖上传的,服务器上没有 .git 目录,所以不是在服务器上跑 git,而是去读更新源的公开只读接口。默认的更新源是 GitHub(连不上时可以换,见更新源):
| 要什么 | 从哪来 |
|---|---|
仓库的 VERSION / DB_VERSION |
raw.githubusercontent.com 上的 includes/common.php,取不到时回落到 GitHub 的 contents 接口 |
| 最近的提交列表 | GitHub 的 commits 接口 |
拿到仓库的 VERSION 与本地的比大小就得出结论;如果仓库的 DB_VERSION 也比本地高,页面会额外提醒「传完文件必须再跑一次 /install/update.php」。
版本号一致不代表代码一致。
VERSION只在改动assets/js/这类静态资源时才会提,只改 PHP 的提交不会动它。所以「已是最新版本」是个弱结论,真要知道改了什么,看提交列表。用过一次在线更新之后,站点会记住自己装的是哪个提交,之后改为按「落后几个提交」判断,不再只看版本号。
行为说明
- 结果缓存在数据库里:查成功缓存 30 分钟,查失败或只查到一半缓存 5 分钟;「重新检查」有 60 秒的最小间隔。GitHub 未登录接口的额度是每个 IP 每小时 60 次,按这个节奏用不完
- 首页那次检查是单独的异步请求,不会拖慢页面上的统计数字
- 服务器连不上 GitHub 时(国内主机比较常见),首页显示「检查失败」,更新日志页会写出具体原因,提示可以换一个主更新源,并给出直接去 GitHub 的链接,不影响后台其它功能
- 数据全部在服务端获取并转义后输出,不使用 JSONP,也不会把接口返回的内容当 HTML 执行
国内不少服务器连不上 GitHub。「程序更新日志」页「版本检查」面板里有一个「主更新源」下拉框,可以自己选从哪里检查和下载:
| 主更新源 | 说明 | 地址 |
|---|---|---|
| GitHub(默认) | 仓库本身,提交最新 | 写死 |
备用源(gitea.hefollo.com) |
作者自建的 Gitea 镜像,定时从 GitHub 同步,可能比 GitHub 晚几个小时才看到新提交 | 写死 |
加速站(gh-proxy.com) |
公共的 GitHub 加速站,第三方站点,只负责中转 | 写死 |
| 自定义加速源 | 自己选的 GitHub 加速站,同样只负责中转 | 站长在页面上填 |
- 选中的源同时管三件事:版本号、提交列表、在线更新下载的更新包。选了之后一直记着,不会自动切换,连不上时页面会提示手动换一个
- 镜像和加速站正常情况下给的都是仓库原样的内容,同一个提交在各个源上的提交号一样,来回切换不影响「落后几个提交」的判断;每个源各有各的缓存
- 备用源还没同步到站点现在装的提交时,页面显示「更新源还没同步到当前提交」,这时不提供在线更新(用它更新等于把站点改回旧代码)。等它同步,或者换一个源即可
- 所有源都开着证书校验
加速站与自定义加速源
GitHub 和备用源是可信源(仓库本身和作者自己的镜像)。加速站是第三方的中转站点,经它下载的更新包不做核对:它给什么,站点就装什么。
- 不核对的原因:会用加速站,正是因为服务器连不上 GitHub;而核对要直连 GitHub 或备用源才做得了,这种时候只会把更新拦住
- 所以能连上 GitHub 或备用源时优先用这两个;加速站留给两个都连不上的服务器,并且只用自己信得过的
- 下载仍然开着证书校验,压缩包检查、版本号降级保护、覆盖前备份都照常(见在线更新);更新后发现不对,可以在页面下方一键还原到更新之前
早先的版本会把加速站下载的包和 GitHub / 备用源逐文件核对,现在已经去掉。核对的代码还留在
includes/online_update.php里没删,想恢复的话,把includes/update_check.php的update_sources()里对应那个源的verify改回true。
自定义加速源的填法:在下拉框里选「自定义加速源」,下面会出现地址输入框,填好点「保存并使用」;清空后保存就是删除。
- 填的是加速站的站点地址,用法是「这个地址 + 完整的 GitHub 地址」(例如填
https://gh.example.com,实际请求的是https://gh.example.com/https://github.com/...),市面上的 GitHub 加速站大多是这种用法 - 只接受
https://开头的域名,不接受 IP、localhost、带参数或账号密码的地址 - 很多加速站只代理文件、不代理提交列表接口。加速站取不到提交列表时,提交列表会改从 GitHub 或备用源取,页面上会写明取自哪里;这两个也连不上的话就没有提交列表,没法在线更新,得换一个代理提交列表接口的加速站(内置的那个是代理的)
- 这是唯一一个可以在页面上填的更新源地址。经它下载的包同样不做核对,填谁的地址就等于信任谁给的代码,只填自己信得过的加速站。GitHub 和备用源的地址不能在页面上改
「设置 - 其它 - 程序更新日志」页里的「在线更新」可以直接把站点更新到仓库 main 分支最新的提交,服务器上不需要装 git,也不需要 SSH:
- 点「检查要更新哪些文件」:服务器从当前更新源(默认 GitHub)下载这个提交的 zip,和站点现有文件逐个比对,列出将修改、将新增的文件。这一步不改任何文件。
- 确认后点「确认更新」:先把要被覆盖的旧文件打成备份,再逐个写入。写到一半出错会自动退回原样。
- 如果这次更新改过数据库,更新完成后结果里会出现「立即升级数据库」按钮,点一下即可,不用再输管理员密码,升级完自动回到本页。
不会动的东西:config.php、install/install.lock、includes/vendor/、上传的文件、用户头像、外观自定义配色、后台上传的网站图标(上传过图标的话,根目录的 favicon.ico 也不动),以及 README、tools/、tests/ 这些不随站点发布的文件。仓库里删掉的文件也不会从站点删除(和整包覆盖一样)。后台目录改过名的,仓库里的 admin/ 会写到实际的后台目录。
备份与还原:备份存在 data/update_backup/(目录禁止访问,文件名带随机串),保留最近 5 份。页面下方可以一键还原到某次更新之前的文件;数据库结构不会跟着退回。
安全限制:只能更新到页面列出的仓库提交;下载开着证书校验,下载地址只能是程序里写死的更新源或站长自己填的加速源(经加速站 / 自定义加速源下载的包不做核对,见更新源);只有管理员能操作,请求必须带页面令牌;仓库版本比站点还低、或者所选更新源还没同步到站点现在装的提交时拒绝更新(避免把站点改回旧代码);zip 里有可疑路径或符号链接时整包拒收。
需要的条件:PHP 的 zip(ZipArchive)和 cURL 扩展、站点目录 PHP 可写、服务器能连上所选的更新源(GitHub 是 api.github.com 和 codeload.github.com,备用源是 gitea.hefollo.com;选加速站或自定义加速源时,能连上加速站本身就行,前提是它代理提交列表接口)。不满足时页面会写明原因,照旧上传整包即可。
- Windows 主机的 PHP 常常没有 CA 根证书,下载会报证书错误,在
php.ini里把curl.cainfo指向一份cacert.pem即可。- 之前用整包上传的站点,第一次在线更新可能会显示大量文件「有变化」——多半只是换行符不同(Windows 打的包是 CRLF,GitHub 上是 LF),属正常。
includes/composer.json有变化时页面会提醒:在线更新不碰includes/vendor/,依赖要另外补。- 根目录的
404.html会被后台写进当前外观,和仓库里的不完全一样。比对时不看外观那几处,只有 404 页本身有改动才会列出来;换成自己写的 404 页则照常列出,更新时会被仓库里的盖掉。
改成自己的仓库
自己 fork 之后,改 includes/update_check.php 顶部的两个常量即可(检查和在线更新都用这一个仓库):
define('UPDATE_REPO', 'hefollo/pan'); // 改成 你的用户名/仓库名
define('UPDATE_BRANCH', 'main');同一个地方还有备用源的地址。它指向一个自动同步上面那个仓库的 Gitea 站点,只填站点地址(必须是 https,结尾不带斜杠),仓库名和分支沿用上面两个常量:
define('UPDATE_MIRROR_BASE', 'https://gitea.hefollo.com'); // 改成你自己的 Gitea;没有就设成 '',下拉框里不再出现备用源内置加速站的地址也在这里,可以换成别的同类加速站(用法同样是「地址 + 完整的 GitHub 地址」):
define('UPDATE_ACCEL_BASE', 'https://gh-proxy.com'); // 设成 '' 则下拉框里不再出现内置加速站备用源和 GitHub 一样被当作可信源,
UPDATE_MIRROR_BASE只能填你自己能完全控制的 Gitea,不要填别人的镜像。经内置加速站下载的包不做核对,UPDATE_ACCEL_BASE也只换成信得过的站点。
- 可在「网站信息设置」里整个关闭:关闭后前台导航不显示入口、直接访问地址也会跳回首页,后台的「赞助名单管理」菜单同时隐藏,名单数据保留
- 赞助名单在后台「系统设置 - 赞助名单管理」维护
- 同一页面可配置微信、QQ 钱包、支付宝三张收款码,支持完整网址或相对
includes/sponsor/的路径;某一项留空则赞助页上不显示该收款方式 - 赞助页配色跟随站点当前外观主题
文件的对外链接使用独立的随机 token:
- 同一份内容被多人上传时,每个人都会得到独立的记录和独立的链接,各自的文件名、密码、隐藏设置互不影响,物理文件仍然只存一份
- 覆盖上传和在线编辑只会改变当前这一条记录指向的内容,不会连带修改其他人的文件
- 删除文件时,只有当没有任何记录再引用这份内容时,才会真正清理物理文件
| 存储类型 | 浏览器直传 | 直链下载 | 断点续传 |
|---|---|---|---|
| 本地存储 | - | - | 支持 |
| 阿里云 OSS | 支持 | 支持 | 支持 |
| 腾讯云 COS | 支持 | 支持 | 支持 |
| 华为云 OBS | 支持 | 支持 | 支持 |
| 又拍云 | 支持 | 支持 | - |
| 七牛云 | 支持 | 支持 | 支持 |
| 通用 S3 兼容存储 | 支持 | 支持 | 支持 |
| WebDAV | - | - | 支持 |
| OneDrive | - | 支持 | 支持 |
| OpenList / AList | - | 支持 | 支持 |
「浏览器直传」指文件由浏览器直接传给存储、不经过本站服务器;「直链下载」指下载时由本站 302 跳到存储自己的地址,不消耗本站流量。WebDAV、OneDrive 和 OpenList 的直传需要 PUT 或上传会话,和前端这套 POST 表单直传对不上,所以固定走网站中转。
后台「存储类型设置」页上,每种存储都有「连接测试」按钮:它用已保存的参数往存储里写一个几十字节的小文件,读回来核对后再删掉,一次跑通写、读、删三项权限。
文件表的每条记录都记着自己当初存到哪个存储(pre_file.storage),下载、预览、在线编辑、删除都按这个字段回到原存储去取,所以换存储只影响之后的新上传,已经上传的文件照常能下,外链也不会失效。存储卡片上会标出「N 个文件在此」,一眼能看出哪几份参数还在被老文件依赖。
换存储时要注意:
- 旧存储的参数原样留着别删。删了或者改错了,压在那儿的老文件就真的取不回来了——卡片上的数字就是提醒。
- 旧存储的服务不能停。老文件的流量仍然走旧存储,欠费、停机、删桶都会让它们下不下来。
- 秒传(同内容重复上传)会跟着已有记录指向同一个存储,不会把老内容再复制一份到新存储。
- 覆盖上传和在线编辑写的是新内容,一律落到当前存储,该记录的
storage也会一并更新。 - 如果后台填了「文件下载域名」,而旧文件在阿里云 OSS / 腾讯云 COS / 华为云 OBS / 又拍云 / 七牛云这几家里,那个域名是给新存储绑的,拼出来的直链对不上;这种情况下旧文件会自动改走网站中转,内容一定对,只是多耗一点本站带宽。域名留空则不受影响。
程序目前不会把老文件搬到新存储,也就是说旧存储要一直留着。需要「搬完就退掉旧存储」的话得另做一个迁移工具。
后台「存储类型设置 → 多存储上传」可以一次开放几个存储,让用户在上传页自己挑存储位置,并且给每个存储限定谁能用。
| 配置项 | 说明 |
|---|---|
| 同时开放多个存储 | 总开关。关着的时候整套不生效,所有新文件都写到卡片里选中的那个存储 |
| 开放哪些、给谁用 | 每个存储可单独勾选开放,并选择门槛:所有人(含未登录访客)/ 仅登录用户 / 仅限会员 |
「仅限会员」指当前会员等级勾了「可用全部存储」的账号(管理员等级恒有),哪些等级有这一项在「会员等级设置」里定。
当前存储必开、且对所有人开放,这一行在后台是锁死的。它是兜底:用户没选、选了个不该他用的、或者池子配空了,都会落到它上面。它在上传页的下拉里也永远排第一、默认选中,这样「下拉的默认项」和「漏传参数时的兜底」是同一个,不会错位。
上传页只有在总开关打开、且当前访客够格用的存储不止一个时才显示「存储位置」下拉;只有一个时连框都不出,和单存储时的页面完全一样。
实现上有一处必须注意:目标存储在 pre_upload 那一刻就定死,并写进会话里的 upload_state 带到后续请求。因为浏览器直传是拿某个存储的密钥签好参数、由浏览器直接 POST 进那个桶的,一次上传又横跨 pre_upload / upload_part / complete_upload 好几个请求,中途重新计算目标就会出现「签的是 A、记录写的是 B」,或者分块被写进两个不同的存储。用户提交的存储名一律用 storage_pick() 拿允许列表校验,改请求参数指定不到没开放给自己的存储。
开了多存储之后,有几件事和单存储时不一样:
- 直传要给每个开放的存储都配好跨域(CORS),只配了一个的话,用户选到另一个会传不上去。选中的存储本身不支持直传(WebDAV / OneDrive / OpenList)时会自动改走网站中转。
- 秒传优先:站内已经有同样内容的文件时直接复用那一份,不会按用户选的存储再存一遍,这时用户选了什么就不作数了。
- 在线编辑保存的新内容一律写到当前存储,不跟着原文件回原存储,记录的
storage会同步更新。 - API 上传接口(
api.php)没有存储参数,固定写当前存储。 - 「文件下载域名」全站只有一个值,只对当前存储生效;存在别的对象存储里的文件会自动改走网站中转。想让每个存储都走直链,把这个域名留空,各家用自己的默认域名。
通用 S3 使用 AWS Signature Version 4 签名协议,可用于 AWS S3、MinIO、Cloudflare R2、Backblaze B2,以及其他兼容 S3 API 的对象存储服务。
进入后台的「存储类型设置」,展开「通用 S3 兼容存储」,填写以下参数:
| 配置项 | 说明 |
|---|---|
| Access Key | 对象存储平台提供的访问密钥 ID |
| Secret Key | 对象存储平台提供的访问密钥密码 |
| Endpoint | S3 API 地址,需填写完整的 http:// 或 https:// 地址 |
| Region | Bucket 所在区域,例如 us-east-1;Cloudflare R2 通常填写 auto |
| Bucket | 存储桶名称 |
| 对象前缀 | 文件在 Bucket 内的目录前缀,默认是 file/;留空则使用根目录 |
| 地址风格 | 可选择虚拟主机风格 bucket.endpoint 或路径风格 endpoint/bucket |
常见配置提示:
- AWS S3:Endpoint 可填写对应区域的 S3 地址,Region 必须与 Bucket 实际区域一致
- MinIO:填写 MinIO API 地址和端口,通常选择「路径风格」
- Cloudflare R2:Endpoint 通常为
https://<账户ID>.r2.cloudflarestorage.com,Region 填写auto - Backblaze B2:填写平台提供的 S3 Endpoint,并使用该 Endpoint 对应的 Region
- 如果平台报 Bucket、域名或签名不匹配,可切换「地址风格」后重试
通用 S3 支持网站中转上传、POST Policy 浏览器直传、签名下载、断点下载、文件删除和文件信息读取。使用浏览器直传前,需要确认存储平台支持 S3 POST Policy,并为 Bucket 配置允许本站域名发起 POST 请求的 CORS 规则;部分平台不支持这种直传方式,此时请在后台选择「网站中转」。
适配坚果云、Nextcloud / ownCloud、Alist、群晖 WebDAV、Apache mod_dav 等标准 WebDAV 服务。
| 配置项 | 说明 |
|---|---|
| WebDAV 地址 | 服务商给的 WebDAV 根地址,例如坚果云 https://dav.jianguoyun.com/dav/、Nextcloud https://域名/remote.php/dav/files/用户名/ |
| 账号 | WebDAV 账号 |
| 密码 | WebDAV 密码;坚果云要用「安全选项」里生成的应用密码,不是登录密码 |
| 存储目录 | 相对根地址的子目录,留空默认为 file,目录不存在会自动创建 |
WebDAV 上传下载都经过本站服务器中转,因此本站的带宽就是网盘的实际速度上限。认证固定使用 Basic:CURLAUTH_ANY 会先发一次不带凭据的请求探路,服务端回 401 后 curl 需要把已经发出去的文件流倒回去重发,PUT 大文件时会直接失败。
支持个人版、商业版和世纪互联版(中国区)。
- 到 Azure 应用注册新建一个应用
- 把后台「存储类型设置 → OneDrive」里显示的回调地址原样填进应用的「重定向 URI(Web)」,通常是
https://你的域名/admin/set_stor.php - 在「API 权限」里加上
Files.ReadWrite.All和offline_access - 在「证书和密码」里生成客户端密码,复制**值(Value)**而不是密码 ID
- 回到后台填好账号类型、应用 ID、应用机密并保存,再点「获取授权」,跳转到微软登录页完成授权
授权拿到的 refresh_token 保存在配置表里,access_token 过期会自动续期,微软轮换的新 refresh_token 也会一并存下。上传走本站中转,超过 4MB 的文件自动改用上传会话分片上传(每片 10MB,失败的分片会重试两次,整个文件不用从头再来)。
下载可以选「直接链接」,本站会 302 到微软给的一小时临时地址,不消耗本站流量;代价是下载下来的文件名会变成站内的存储名(没有扩展名),在意文件名就选「网站中转」。
对接自建的 OpenList,同时兼容 AList v3 的接口。OpenList 后面挂什么盘(阿里云盘、百度网盘、OneDrive、本地磁盘、对象存储……)由它自己管,本站只跟它的 HTTP 接口打交道。
| 配置项 | 说明 |
|---|---|
| OpenList 地址 | 站点根地址,不要带 /api;自建没上 HTTPS 的要把 http:// 一起写上,例如 http://192.168.1.5:5244 |
| 账号 / 密码 | 登录用的账号密码,建议单独建一个只对存储目录有读写权限的用户,不要用 admin |
| 固定令牌 | 可不填。填了就直接拿它调接口,不再用账号密码登录;对应 OpenList 后台「其他设置」里的令牌 |
| 存储目录 | OpenList 里的完整路径,第一段必须是已经挂载好的存储名,例如挂载路径是 /aliyun 就填 /aliyun/pan/file;留空默认为 /pan/file,目录不存在会自动创建 |
用账号密码登录拿到的令牌缓存在配置表里,按 24 小时轮换(服务端默认签发 48 小时);令牌被服务端提前作废时(改过密码、重启清了会话)会自动重新登录一次再重发请求。
上传走本站中转(PUT /api/fs/put),因此本站带宽就是实际速度上限。下载可以选「直接链接」,本站先问 POST /api/fs/get 要到 raw_url 再 302 过去:底层是对象存储或网盘时会直接跳到上游地址,底层开了代理时跳的是 OpenList 自己的带签名地址。和 OneDrive 一样,直链下载拿到的文件名会变成站内的存储名(没有扩展名),在意文件名就选「网站中转」。
需要注意 OpenList 的接口不管成功失败 HTTP 状态码基本都是 200,真正的结果在响应体的 code 字段里,所以驱动一律解完 JSON 再判断成败。
- PHP >= 7.1,需启用 cURL 扩展
- MySQL / MariaDB
- 建议启用 GD 扩展:上传头像时服务端会重新裁剪编码一遍;没有 GD 也能上传头像
- 当前程序版本
VERSION为1637,数据库版本DB_VERSION为1027 - 视频检测还需要服务器上有 ffmpeg(自建检测服务的一键脚本会自动安装)
全新安装访问 install/ 目录按提示完成即可,装完直接就能用,不需要再跑升级。安装最后一屏会显示随机生成的管理员密码,只显示这一次,务必先存下来再关页面。
从旧版本升级时,覆盖程序文件后必须访问一次(用后台在线更新时,改过数据库的版本页面会提示,按提示做即可):
http(s)://你的域名/install/update.php
后台已登录时更省事:数据库没升级时打开后台会被「请先完成网站升级」拦住,拦截页上有「已登录后台:一键升级数据库」按钮,点一下直接升级(免输密码,只对这一次有效),完成后回到后台的程序更新日志页。没登录或按钮用不了时,照常打开上面的地址输入管理员账号密码。
看到「网站数据库升级完成」即可。升级脚本会建表、补齐配置项,并把历史数据迁移到新结构。若跳过这一步,程序会因为数据库版本落后而提示「请先完成网站升级」。从 1023 升到 1024 会新建用户文件夹表、给文件表加两个字段,已有文件全部落在根目录,不受影响。从 1024 升到 1025 会给套餐、订单、用户三张表各加一个下载限速字段,默认值是「不改动 / 按身份速度」,已有套餐和用户的行为不变。从 1025 升到 1026 会给套餐、订单表各加一个在线编辑字段,给用户表加在线编辑的开通状态和到期时间两个字段,默认都是「不含 / 未开通」,已有套餐、用户和「在线编辑权限」设置的行为不变。从 1026 升到 1027 会新建会员等级表、给用户 / 套餐 / 订单表加字段,并把原有的权限迁移成会员等级(原高级用户、已买套餐的用户、在线编辑 / 文件夹 / API 的开放范围升级前后不变,旧套餐下架,详见套餐),这一步改动了用户和套餐数据,升级前请先备份数据库。
用户上传的头像放在 assets/avatar/,它是站点运行时产生的数据:更新包里没有这个目录,覆盖上传和后台在线更新都不会动它;站点搬家时要连同这个目录一起搬,否则头像会退回成图标。升到 1637(加入头像功能)没有改数据库,不需要跑升级。
站长在后台「网站信息设置」上传的网站图标放在 assets/siteicon/,同样是运行时数据:更新包里没有这个目录,搬家时要一起搬。上传时程序还会把图标写一份到站点根目录的 favicon.ico——直接打开文件直链、404 页这些地方,浏览器只认这个地址。覆盖上传更新包会把根目录这一份换回默认图标,登录后台打开任意页面就会自动补回;后台在线更新则不会动它。第一次升级到带这个功能的版本时,之前手工换上去的 favicon.ico 仍会被更新包盖掉,传完到「网站信息设置」上传一次图标,以后就不用再管。需要 assets/ 和根目录的 favicon.ico 可写;assets/img/favicon.ico 是默认图标的副本,「恢复默认」靠它还原,不要删。加入这个功能没有改数据库,不需要跑升级。
静态资源的缓存串分两种,改代码时要注意区别:
assets/css/style.css、assets/css/admin.css、assets/js/buy.js用asset_ver(),取的是文件修改时间(style.css?v=1756...)。改完传上去地址自动就变了,不用管。- 其余 JS(
layout-studio.js、layout-mac.js、layout-workspace.js、uploadnew.js、usercenter.js、replace-upload.js、folders.js、filelist-live.js)和includes/ads.php用的是includes/common.php里的VERSION常量。改过这些文件就要把VERSION加一,否则浏览器和 CDN 会继续用旧文件。服务器开着 OPcache 的话(宝塔默认开),覆盖 PHP 文件后要重启一次 PHP-FPM,否则会继续执行缓存里的旧代码。
assets/css/style.css装着全部外观,约 450KB,建议在服务器上给 CSS 开 gzip(压缩后约 70KB),慢网下打开快很多。往这个文件里加样式时,要加在文件最末尾那两条(html{background:none}、body{visibility:visible})之前:它们负责在样式到达后放出页面,必须排在最后。
- 外观扩展至 28 套(15 套配色型 + 13 套布局型,含 macOS 窗口风、渐变仪表盘风,以及蓝白工作台风一家七套),前后台、公告条、赞助页及弹窗联动
- 新增个人中心:额度与用量概览、我的文件管理(重命名/密码/公开私密/批量删除/复制外链)、订单记录、账号设置
- 新增账号绑定:一个账号可同时用邮箱和 QQ / 微信登录,注册时用的那种方式不可解绑
- 新增邮箱注册与登录,含算术验证码与发信记录
- 新增找回密码:凭邮箱验证码自助重置,统一口径不泄露邮箱是否已注册,不跟注册开关走
- 新增购买权限模块:套餐管理、支付宝当面付与易支付、订单记录与对账
- 新增邮件发信设置,支持 SMTP 与三种 HTTP API 通道,可测试发信
- 新增用户管理与权限设置,可单独设置每位用户的额度与有效期
- 新增覆盖上传功能及配套的后台审计界面
- 新增内容检测:图片同步检测、视频抽帧异步检测,支持阿里云 / 腾讯云 / 自建本地模型三种引擎,带独立的检测记录页和证据帧
- 新增内容检测命中通知:拦截或转人工时给站长发邮件,可设合并间隔,后台链接跟随实际目录名生成
- 新增违规文件公示功能
- 文件状态改为三态可切换(正常 / 封禁 / 待审核),文件管理和内容检测记录都能就地改
- 赞助名单可整体开关,关闭后前后台入口一并隐藏
- 新增广告公告位设置
- 新增页脚运行时间,后台可开关并设定建站时间
- 「统计代码」改为可添加多条的「页脚代码」列表;升级后原来填的统计代码自动成为第一条,里面自己贴的旧「本站已安全运行」脚本不再输出,改由页脚运行时间开关控制
- 「禁止访问 IP」由一个「用 | 隔开」的文本框改为逐条添加的列表,支持网段和 IPv6,原来填的 IP 自动拆成一条条;去掉了首页公告弹窗(站点公告请用顶部公告条)
- 新增在线查看文本内容与在线编辑功能
- 新增通用 S3 兼容存储,可对接 AWS S3、MinIO、Cloudflare R2、Backblaze B2 等平台
- 新增 WebDAV 存储,可对接坚果云、Nextcloud、Alist、群晖等
- 新增 OneDrive 存储,后台一键授权,支持个人版 / 商业版 / 世纪互联版
- 新增 OpenList 存储,可对接自建的 OpenList / AList 聚合网盘,兼容 AList v3 接口
- 存储不再是全站唯一:文件表记下每条记录存在哪个存储,换存储后旧文件仍从原存储读取,外链不失效
- 新增多存储上传:可同时开放多个存储供用户在上传页自选,并按所有人 / 仅登录用户 / 仅限会员分级授权
- 存储类型设置页重做:卡片式选择、按能力显示传输方式、密钥默认打码、每种存储都能做连接测试
- 文件访问链接改为独立 token,同内容多次上传互不干扰
- 上传限制新增每分钟次数,并可配置反向代理下的真实 IP 获取方式
- 新增下载限速:限速跟着文件的上传者走(上传者不限速,他的文件任何人下载都不限速),游客上传、登录用户上传的文件可分别设定默认速度,会员等级可以各带自己的速度,限速下载强制走本站中转
- 修正预览地址后面加
?greencheck=1就能绕过下载限速:这个参数改成带签名的,只有本站签发给内容检测服务的地址才不限速 - 新增会员等级:取消原来的「普通 / 高级」用户,每个等级一张权限表(每日数量、单文件大小、下载速度、在线编辑、文件夹、上传 API、可用存储、免审核),套餐改为卖等级;内置只能后台手动给、不受任何限制的管理员等级
- 新增补差价升级:限时会员换更高等级只补到期前的差价、到期时间不变;买永久套餐时折抵剩余天数
- 附加包:加量包和在线编辑包各有自己的到期时间,不影响会员到期时间
- 修正后台添加套餐时分类留空会保存失败、页面却提示「套餐已添加」
- 新增用户上传 API 密钥:三种鉴权模式,用户可自助创建管理,支持 IP 白名单与有效期,密钥只存哈希
- 新增后台首页文件类型分布:六类文件的数量、占用空间与占比条,可按数量或按占用空间看,并给出全站总占用
- 新增程序更新检查与更新日志页:读 GitHub 上
main分支的版本号与提交列表,后台直接看到有没有新版本、这些版本改了什么 - 新增后台在线更新:从 GitHub 下载最新提交的 zip 按发布口径覆盖,先预检再确认,覆盖前自动备份、失败自动回滚、可一键还原,服务器不需要 git
- 新增更新源选择:连不上 GitHub 的服务器可以在后台把主更新源换成作者自建的 Gitea 镜像、内置的公共加速站,或者自己填一个加速站地址,版本检查、更新日志、在线更新一起换;源还没同步到站点当前提交时拒绝覆盖
- 经加速站下载的更新包不做核对(早先的逐文件核对已去掉:用加速站的服务器正是连不上 GitHub 的,核对只会把更新拦住);页面上如实写明,能连上 GitHub 或备用源时建议优先用这两个
- 新增用户文件夹:多级文件夹、剪切 / 复制 / 粘贴、拖拽移动、上传到指定文件夹,谁能用由会员等级决定;复制不占存储、不计入每日上传数,外链不受移动影响
- 「我的文件」改为局部刷新:操作后和切换文件夹、翻页、筛选、搜索时不再整页刷新
- 后台名称与浏览器标签跟随网站标题
- 网速慢时不再先闪出默认样式:外观样式到达前只显示外观底色,加载失败或超时自动放出页面
- 后台登录页改为双栏设计(改自社区贡献者的 PR),配色跟随站点外观,登录提示直接显示在页面上
- 首页文件列表不再显示被封禁、待审核的文件;首页文件数、类型统计在上传、删除、封禁后立即更新(原来要等缓存过期)
- 新增「上传时默认在首页公开」开关
- 前后台界面整体美化与手机端适配
- 全部外观的手机端文件列表改为卡片布局;修正多套布局型外观手机导航菜单展开后挤在一起、个别深色外观菜单看不清字的问题
- 手机上点选导航后菜单自动收起:后台动态换页、前台「我的文件」局部刷新时菜单原来会一直展开着;修正后台首页在手机上左右各越出 3px
- 页脚重新设计:修正首页、违规公示页的页脚和其他页面左右位置不一致、内容少的页面页脚悬在半空的问题;版权与页脚代码排成一行并加分隔线,侧栏类外观的页脚和内容区对齐
- 新增用户自定义头像:个人中心裁剪上传、恢复默认,导航栏与后台用户列表显示头像,后台可清除用户头像
- 新增后台自定义网站图标:「网站信息设置」里上传,图标单独存放,覆盖上传更新包和在线更新都不会把它换回默认;直链和 404 页用的根目录
favicon.ico被更新包盖掉后,管理员进后台时自动补回 - 修正在线更新「重新核对站点文件」每次都把
404.html列为有变化、更新后依然如此的问题
感谢原开源项目 netcccyun/pan 的作者提供基础程序支持。
LINUX DO:真诚、友善、团结、专业的技术社区。











































