VoiceHub - 校园广播站点歌系统
这是一个使用Nuxt 4全栈框架开发的现代化校园广播站点歌管理系统。系统提供完整的点歌、投票、排期管理、通知推送、数据分析、权限控制和数据库管理功能,支持多角色权限管理和灵活的系统配置。
项目截图
主要功能
🎵 核心功能
- 智能点歌系统:用户可以点歌或给已有歌曲投票,支持网易云音乐、QQ音乐和哔哩哔哩搜索,可选择期望播出日期与播出时段
- 点歌券:支持用户派发与回收。投稿后锁券,正式发布且标记已播放后核销;未播放时取消发布或换日保留绑定,撤回投稿归还点歌券。
- 多平台登录支持:
- OAuth 账户系统:支持通过 GitHub、Casdoor 等 OAuth 提供商快速创建和登录账户
- 直接创建账户:用户通过 OAuth 认证后可创建新账户,但仍需设置本地用户名和密码
- 账户绑定:已有账户的用户可将 OAuth 身份绑定到现有账户,实现多平台统一登录
- WebAuthn 支持:支持 HarmonyOS Passkey、Windows Hello、生物识别和硬件安全密钥(如 YubiKey)登录
- 双因素认证(2FA):支持 TOTP 和邮箱验证,增强账户安全性
- 网易云音乐登录:支持扫码登录,登录后可搜索个人歌单、收藏及播客电台内容
- 一键添加到歌单:登录后支持将排期中的网易云音乐歌曲一键添加到个人歌单
- 从歌单投稿:支持从个人歌单中直接投稿歌曲到系统
- 从最近播放投稿:支持从最近播放记录中投稿歌曲
- 播客电台投稿:支持搜索和投稿播客电台内容
- 投稿限额管理:灵活配置用户投稿限制,支持按时间段、用户角色设置不同的投稿额度,有效控制系统负载
- 歌曲去重功能:智能识别重复歌曲,优化歌曲库管理,避免重复播放
- 歌曲管理:按热度排序,避免重复播放,动态URL防止链接过期,支持黑名单管理
- 音乐播放器:内置音乐播放器,支持进度控制和音质实时切换
- 音质切换:支持多种音质选择(标准、HQ、无损、Hi-Res等),动态获取最新播放链接
- 音乐下载功能:支持管理员下载歌曲到本地,提供多种音质选择和批量下载
- 歌曲重播功能:支持用户对已播放过的歌曲发起重播申请,支持查看申请记录和撤回申请
👥 用户管理
- 用户管理:管理员添加用户,支持按年级班级分类
- 账户创建方式:
- 管理员直接添加账户
- 用户通过 OAuth 快速创建账户
- 用户通过传统用户名/密码注册
- 权限控制:多级权限管理,支持普通用户、管理员、超级管理员
- 账户安全:
- bcrypt 密码加密
- 双因素认证(TOTP、邮箱验证)
- WebAuthn 支持(HarmonyOS Passkey、生物识别、硬件密钥)
- 账户锁定和风险控制
- 身份关联:支持将多个 OAuth 身份绑定到同一账户,实现统一登录
- 黑名单管理:支持歌曲和艺术家黑名单,自动过滤不当内容
📅 排期管理
- 排期管理:管理员可以通过拖拽界面进行歌曲排期和顺序管理
- 排期草稿:支持保存排期草稿功能,允许管理员分步完成排期安排
- 草稿状态不影响公开展示,可随时修改和完善
- 支持草稿发布为正式排期,确保排期质量
- 播出时段:灵活配置播出时段,支持多时段管理
- 排期复制:支持将某日期的排期完整复制到另一日期,原排期保留不变
- 打印排期:支持自定义纸张大小、内容选择、编写备注和PDF导出的打印功能
- 学期管理:管理员可设置当前学期,自动关联点歌记录
- 公开展示:公开展示歌曲播放排期,按日期分组展示
🔔 通知系统
- 实时通知:歌曲被选中、投票和系统通知
- 通知设置:用户可自定义通知偏好,支持独立页面设置
- 批量通知:管理员可向特定用户群体发送通知
- 社交账号绑定:支持绑定MeoW等账号,同步推送通知到外部平台
- 验证码验证:安全的验证码验证机制,支持动态样式反馈
💾 数据管理
- 数据库备份:完整的数据库备份和恢复功能
- 数据库重置:支持安全的数据库重置操作,可选择性保留用户数据或完全重置
- 文件导入导出:支持备份文件的上传、下载和管理
- 数据库自检:自动数据库验证和修复机制,确保系统稳定性
🎨 用户体验
- 现代UI:响应式设计,深色主题,流畅的动画效果
- 玻璃态设计:现代化的视觉效果和交互体验
- 交互反馈:hover效果,点击反馈,状态变化动画
- 移动端优化:适配支持移动设备访问,触摸友好的交互设计
技术栈
前端技术
- Nuxt 4:Vue.js全栈框架,提供SSR和SPA支持
- Vue 3:响应式前端框架,使用Composition API
- TypeScript:类型安全的JavaScript,提供完整的类型定义
- UNO CSS:实用优先的CSS框架,响应式设计
- Vue Router:前端路由管理
后端技术
- Nuxt Server API:服务端API路由,支持中间件和认证
- Drizzle ORM:现代化数据库ORM,提供类型安全的数据库操作和高性能查询
- Neon Database:Serverless PostgreSQL数据库,支持自动启停和无缝扩展
- PostgreSQL:关系型数据库,支持复杂查询和事务处理
- Redis:可选的分布式短期状态服务,仅用于验证码、限流和临时安全状态
- JWT:标准JWT认证机制,支持24小时token有效期
- bcrypt:密码加密,安全的哈希算法
- Multer:文件上传处理,支持多种存储方式
系统架构
系统采用了现代化的 Serverless 全栈架构:
- 前端:使用 Nuxt 4 + Vue 3 组合式API构建响应式用户界面
- 后端:使用 Nuxt Server API 构建 RESTful API 服务
- 数据库:使用 Drizzle ORM + Neon Database,提供类型安全和高性能的数据库操作
- 认证:标准 JWT 认证系统
- 数据读取:PostgreSQL 是唯一业务数据源,歌曲、排期和用户状态不使用 Redis 缓存
- 部署:支持 Vercel、Netlify、EdgeOne 等 Serverless 平台一键部署,并提供 Docker、Linux 一键脚本及飞牛 FnOS (fpk安装包) 等多种部署方式
部署指南
一键部署
本项目可以一键部署到Vercel/Netlify/EdgeOne平台:

在部署过程中,需要输入必要的环境变量:
DATABASE_URL:PostgreSQL数据库连接地址
JWT_SECRET:JWT令牌签名密钥
Linux 服务器部署
本项目提供了针对 Ubuntu/Debian 服务器的一键部署脚本,支持自动安装 Node.js 22、配置环境变量、安装依赖和构建项目。
一键命令:
bash <(curl -sL https://raw.githubusercontent.com/laoshuikaixue/VoiceHub/main/sh/main.sh)
如果你需要 gh-proxy 加速,使用以下命令:
bash <(curl -sL https://gh-proxy.com/https://raw.githubusercontent.com/laoshuikaixue/VoiceHub/main/sh/main.sh)
Docker 部署
VoiceHub 支持通过 Docker 进行容器化部署,提供了多种部署方式。
方式一:使用 Docker Compose(推荐)
这是最简单的部署方式,会自动创建应用和数据库容器。
使用预构建镜像
查看 docker-compose 并选择适合的配置文件
本地构建镜像
- 克隆项目
git clone https://github.com/laoshuikaixue/VoiceHub.git
cd VoiceHub
- 修改 docker-compose.yml 中的环境变量
environment:
- DATABASE_URL=postgresql://user:password@postgres:5432/voicehub # 可能需要 ?sslmode=disable
- JWT_SECRET=your-jwt-secret-here # 请修改为强随机字符串
- NODE_ENV=production
- 启动服务
docker-compose up -d
- 访问应用
打开浏览器访问 http://localhost:3000
默认管理员账号:
- 用户名:admin
- 密码:admin123
- 默认口令按临时密码处理,首次登录需设置新密码
- 启动时自动检测仍在使用默认口令的超级管理员,补上强制改密标记
方式二:使用预构建镜像
如果你已有 PostgreSQL 数据库,可以直接使用预构建的镜像。
使用 GitHub 镜像源:
docker run -d \
-p 3000:3000 \
-e DATABASE_URL="postgresql://username:password@host:port/database?sslmode=require" \
# 可能需要替换成 ?sslmode=disable
-e JWT_SECRET="your-very-secure-jwt-secret-key" \
-e NODE_ENV=production \
--name voicehub \
ghcr.io/laoshuikaixue/voicehub:latest
使用南京大学镜像源:
docker run -d \
-p 3000:3000 \
-e DATABASE_URL="postgresql://username:password@host:port/database?sslmode=require" \
# 可能需要替换成 ?sslmode=disable
-e JWT_SECRET="your-very-secure-jwt-secret-key" \
-e NODE_ENV=production \
--name voicehub \
ghcr.nju.edu.cn/laoshuikaixue/voicehub:latest
方式三:本地构建镜像
如果需要自定义构建,可以本地构建镜像。
git clone https://github.com/laoshuikaixue/VoiceHub.git
cd VoiceHub
# 构建镜像(不使用缓存,确保完全重新构建)
docker build --no-cache -t voicehub .
# 运行容器
docker run -d \
-p 3000:3000 \
-e DATABASE_URL="postgresql://username:password@host:port/database?sslmode=require" \
# 可能需要替换成 ?sslmode=disable
-e JWT_SECRET="your-very-secure-jwt-secret-key" \
-e NODE_ENV=production \
--name voicehub \
voicehub
Podman 部署
Podman 是一个与 Docker 兼容的容器引擎,无需守护进程,支持 rootless 模式(无需 root 权限)。VoiceHub 的 Docker 配置文件可以直接用于 Podman。
使用 Podman Compose 部署
podman compose -f docker-compose.yml up -d
说明:podman compose 完全兼容 docker-compose.yml 文件,无需修改配置。
rootless 模式
Podman 默认以当前用户身份运行,无需 sudo,安全性更高。但容易遇到文件权限问题(特别是挂载卷时)。
飞牛 (FnOS) 部署
VoiceHub 现已支持飞牛 OS (FnOS) 的 .fpk 安装包。
Nix / NixOS
VoiceHub 提供了一个 Nix flake,用于构建、开发和在 NixOS 上部署。
前提条件
- Nix(带 flake 支持)
- PostgreSQL 数据库
NixOS 部署
将 VoiceHub 添加为 flake input:
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
voicehub.url = "github:laoshuikaixue/VoiceHub";
};
outputs = { self, nixpkgs, voicehub, ... }: {
nixosConfigurations.my-server = nixpkgs.lib.nixosSystem {
specialArgs = { inherit voicehub; };
modules = [
voicehub.nixosModules.default
./configuration.nix
];
};
};
}
然后在 NixOS 配置中使用模块,根据数据库管理方式选择对应场景。
# 场景 A:自动配置本地 PostgreSQL
# environmentFile 只需提供 JWT_SECRET,DATABASE_URL 由模块自动构造
{ pkgs, inputs, config, ... }: {
imports = [ inputs.voicehub.nixosModules.default ];
services.voicehub = {
enable = true;
database.createLocally = true;
environmentFile = config.sops.templates."voicehub-env".path;
runDeployScript = true;
};
sops.templates."voicehub-env" = {
content = ''
JWT_SECRET=${config.sops.placeholder."voicehub/jwt-secret"}
'';
};
}
# 场景 B:手动管理数据库(Neon / Docker / 远程 PG)
# environmentFile 需同时提供 DATABASE_URL 和 JWT_SECRET
{ pkgs, inputs, config, ... }: {
imports = [ inputs.voicehub.nixosModules.default ];
services.voicehub = {
enable = true;
environmentFile = config.sops.templates."voicehub-env".path;
runDeployScript = true;
};
sops.templates."voicehub-env" = {
content = ''
DATABASE_URL=${config.sops.placeholder."voicehub/database-url"}
JWT_SECRET=${config.sops.placeholder."voicehub/jwt-secret"}
'';
};
}
环境文件 (sops.templates."voicehub-env".content) 格式参考:
DATABASE_URL=postgresql://voicehub:secret@localhost:5432/voicehub
JWT_SECRET=your-very-secure-jwt-secret-key
NUXT_PUBLIC_HOST=https://voicehub.example.com
推荐使用 sops-nix 管理 secrets,避免明文存储在 Nix store 中。
模块会自动设置 DynamicUser、ProtectSystem=strict、NoNewPrivileges 等安全加固。
运行时可写数据(音源插件产物 .data、备份 backups、文件日志 logs)存放在 /var/lib/voicehub(systemd StateDirectory,DynamicUser 自动管理权限),升级重建不会丢失;只读产物仍来自 /nix/store。包内 scripts/ 仅包含运行时脚本(deploy、db-sync、create-admin、build 等);pnpm run clear-db、pnpm run safe-migrate、pnpm run db:generate 等维护命令需在源码仓库中执行。
防火墙默认不开放端口,在配置中启用以允许外部访问:
services.voicehub.openFirewall = true;
应用配置并部署:
sudo nixos-rebuild switch --flake .#my-server
查看服务状态和日志:
systemctl status voicehub
journalctl -u voicehub -f
默认监听 0.0.0.0:3000,可通过 services.voicehub.host 和 services.voicehub.port 修改。
使用 Binary Cache 加速构建
VoiceHub CI 会将构建产物推送到 Cachix binary cache,
下游用户可直接下载预构建的 pnpmDeps 和 voicehub 包,跳过本地构建。
在你的 flake 中添加 nixConfig 以启用:
{
nixConfig = {
extra-substituters = [ "https://voicehub.cachix.org" ];
extra-trusted-public-keys = [ "voicehub.cachix.org-1:CKw4/RvZy5c0WVpyo5ZyLbJgdpHZ/+epofIwGOeIOhU=" ];
};
inputs = {
voicehub.url = "github:laoshuikaixue/VoiceHub";
};
}
[!IMPORTANT]
请勿通过 follows 覆盖 VoiceHub 的 nixpkgs input。缓存中的产物使用
VoiceHub 自带的 nixpkgs 构建,替换后 hash 不同,无法命中缓存。
其他功能
开发环境
进入开发 shell(自动提供 Node.js、pnpm、PostgreSQL 客户端):
nix develop
然后在 shell 内:
cp .env.example .env # 配置 DATABASE_URL + JWT_SECRET
pnpm install
pnpm run dev # 启动开发服务器 (port 3000)
构建
nix build # 产出 result/bin/voicehub
构建产物可以直接运行(需要 DATABASE_URL 等环境变量):
DATABASE_URL="postgresql://..." JWT_SECRET="..." ./result/bin/voicehub
或使用附带的环境文件:
nix run .#default --impure
nix run 需要设置 DATABASE_URL 环境变量,否则会启动失败。
更新 pnpm 依赖哈希
当 pnpm-lock.yaml 更新后,需要同步 flake.nix 中的 pnpmDeps 哈希。Nix CI 在构建因哈希过期失败时,会自动计算新哈希、验证构建并提交回触发分支;fork PR 与 bot 自身触发的运行只报错不写回,需要人工更新。
如果需要在本地手动更新,可以先将 flake.nix 中 pnpmDeps.hash 临时改为空字符串,然后运行:
nix build .#voicehub
Nix 会因固定输出哈希不匹配而失败,并输出 got: sha256-...,将该值写回 pnpmDeps.hash 即可。也可以使用 impure 构建辅助命令(需要网络和已安装的 pnpm):
nix run .#build # 在项目目录中执行,生成 .output 目录
本地开发部署
前提条件
- Node.js 22.11+
- PostgreSQL 数据库(推荐使用 Neon)
- Redis 数据库(可选;多实例或 Serverless 部署建议配置)
快速开始
- 克隆项目
git clone https://github.com/laoshuikaixue/VoiceHub.git
cd VoiceHub
- 安装依赖
pnpm install --frozen-lockfile
- 配置环境变量
复制 .env.example 文件并重命名为 .env:
cp .env.example .env
编辑 .env 文件,配置必需的环境变量:
# 数据库连接地址(必填)
DATABASE_URL="postgresql://username:password@host:port/database?sslmode=require"
# 可能需要替换成 ?sslmode=disable
# JWT 认证密钥(必填)
JWT_SECRET="your-very-secure-jwt-secret-key"
# 应用运行环境(可选)
NODE_ENV=development
- 初始化数据库
首次运行需要初始化数据库结构:
# 生成数据库迁移文件
pnpm run db:generate
# 执行数据库迁移
pnpm run db:migrate
或使用一键部署命令(推荐):
pnpm run deploy
- 创建管理员账户
系统会在首次部署时自动创建管理员账户。如需手动创建:
pnpm run create-admin
默认管理员账户:
- 用户名:admin
- 密码:admin123
- 默认口令按临时密码处理,首次登录需设置新密码
- 启动时自动检测仍在使用默认口令的超级管理员,补上强制改密标记
- 启动开发服务器
pnpm run dev
应用将在 http://localhost:3000 启动。
生产环境部署
- 构建生产版本
pnpm run build
- 启动生产服务器
pnpm run start
数据库管理命令
# 新的数据库初始化
pnpm run init-help
# 生成迁移文件
pnpm run db:generate
# 执行数据库迁移
pnpm run db:migrate
# 推送模式变更到数据库(开发环境)
pnpm run db:push
# 启动 Drizzle Studio(数据库管理界面)
pnpm run db:studio
# 清空数据库并重新创建管理员
pnpm run clear-db
# 安全迁移(带备份)
pnpm run safe-migrate
升级与迁移
有关如何升级现有部署和迁移数据,请参阅 升级指南。
系统配置
站点配置管理
VoiceHub 提供了完整的站点配置管理功能,支持通过管理后台动态配置系统参数:
基本信息配置
- 站点标题:自定义系统显示名称
- 站点描述:系统功能描述和介绍
- 站点Logo:支持上传自定义Logo图片
播放时段管理
- 多时段支持:支持配置多个播放时段(如午间、晚间)
- 时段名称:自定义时段显示名称
- 开始/结束时间:精确到分钟的时间控制
- 时段排序:支持拖拽调整时段显示顺序
通知系统配置
- 通知开关:控制系统通知功能的启用状态
- 通知类型:配置不同类型通知的发送规则
- 通知模板:自定义通知消息的格式和内容
AstrBot 群事件投递边界:群事件 push 仅支持常驻部署。合并窗口到期后的冲刷依赖常驻服务的定时任务;Vercel、Netlify 等按请求冻结实例的 Serverless 环境应在 VoiceHub 与 AstrBot 插件两端均选择 pull 模式,由插件主动领取并回执。切换模式前确认旧队列已处理,避免旧模式遗留条目滞留。
数据库备份与恢复
系统提供了完整的数据备份和恢复解决方案:
备份功能
- 完整备份:包含所有数据表的完整系统备份
- 用户数据备份:仅备份用户相关数据(用户、歌曲、投票等)
- 增量备份:支持基于时间的增量备份策略
恢复功能
- 合并模式:将备份数据与现有数据合并,保留现有数据
- 替换模式:完全替换现有数据(谨慎使用)
- 数据验证:恢复前自动验证备份文件完整性
权限与角色管理
VoiceHub 实现了细粒度的权限控制系统:
角色类型
- 超级管理员 (SUPER_ADMIN):拥有所有系统权限,包括用户管理、系统设置中的凭据与策略配置、备份恢复、数据库管理等。可由现有超级管理员在用户管理中授予或撤销,活跃的超级管理员上限 3 个、至少保留 1 个,不参与批量导入
- 管理员 (ADMIN):内容与用户日常管理权限,包括用户管理、排期管理、歌曲管理、点歌券、数据分析,以及投稿与播放限制、限额、卡密、音源平台等运营配置
- 歌曲管理员 (SONG_ADMIN):专门负责歌曲相关管理,包括排期管理、歌曲管理、打印排期等
- 普通用户 (USER):基本的点歌、投票和查看权限
权限分类
- 内容管理权限:排期管理、歌曲管理、打印排期等
- 用户管理权限:创建、编辑、删除用户账户
- 系统管理权限:通知管理、播放时间管理、学期管理、黑名单管理、站点配置、数据库管理等
权限继承与分配
- SUPER_ADMIN:拥有所有权限
- ADMIN:内容与用户日常管理、运营类系统配置
- SONG_ADMIN:拥有内容管理相关权限(排期、歌曲、打印)
- USER:仅拥有基本的点歌和查看权限
权限验证
- 前端基于角色动态显示界面元素和菜单
- 后端API进行严格的权限验证
- 支持页面级和功能级的权限控制
敏感操作二次验证
- 授予或撤销超级管理员身份时,操作者需重新验证凭据:口令与验证器动态码二选一,账号已绑定验证器时默认优先动态验证码;单一凭据验证失败不回落另一种凭据
- 验证通过后在服务端签发短期特权窗口(按场景 + 用户 + 会话绑定,默认 5 分钟),不返回任何客户端令牌,换会话或换场景均不继承
- 验证场景为封闭白名单(
server/utils/step-up.ts),后续接入备份恢复、数据库重置等只需追加场景项
- 验证失败与超管身份变更均写入口令审计流水,并向全体活跃超级管理员推送系统通知
- 范围限定于超级管理员身份变更:仅停用超管账号或对其施加显式拒绝不会触发验证(数量下限仍会拦住归零)
- 从备份恢复是例外:恢复任意备份本身等价于最高权限,其中携带的超管账号不受验证与数量上限约束,恢复后需人工核对超管名单
环境变量说明
| 变量名 |
必填 |
说明 |
示例值 |
| DATABASE_URL |
是 |
PostgreSQL数据库连接字符串 |
postgresql://username:password@host:port/database?sslmode=require |
| JWT_SECRET |
是 |
JWT令牌签名密钥,建议使用强随机字符串 |
your-very-secure-jwt-secret-key |
| TRUSTED_CLIENT_IP_HEADERS |
否 |
受信 CDN/反向代理真实 IP 头,多个值用逗号分隔;未配置时公网直连只使用 TCP 连接地址,内网反代才回退读取转发头 |
eo-connecting-ip |
| NODE_ENV |
否 |
运行环境,development或production |
production |
| REDIS_URL |
否 |
Redis短期状态服务连接字符串,用于验证码、限流和临时锁定 |
redis://default:password@host:port |
| REDIS_KEY_PREFIX |
否 |
Redis键命名空间,多环境共用Redis时应分别设置 |
voicehub:v2: |
| NITRO_PRESET |
否 |
Nitro预设 |
vercel |
| IS_SERVERLESS |
否 |
声明为 Serverless 运行环境(连接池压低、备份改为直接返回数据、群事件投递器不启动)。平台未注入 VERCEL/NETLIFY 且未设置 NITRO_PRESET 时用它,如 EdgeOne Pages |
true |
| NUXT_PUBLIC_HOST |
否 |
显式配置站点外部地址后启用内部 API 的 CORS 来源校验;未配置时仅对回环 Host(反向代理常见场景)跳过,云平台公开 Host 仍校验 |
https://your-app.com |
| NUXT_PUBLIC_SEO_CONFIG |
否 |
用于自定义 PWA/SEO 配置的 JSON 字符串 |
{"title":"VoiceHub校园广播站点歌系统","shortName":"校园广播","description":"校园广播站点歌系统 - 让你的声音被听见","logo":"/images/logo.png"} |
OAuth 配置
系统支持通过 OAuth 提供商(如 GitHub、Casdoor、Google 等)快速创建账户和登录:
OAuth 运行时配置统一保存在管理员后台数据库中;环境变量仅用于兼容旧部署和后台一键导入,导入后以后台保存值为准。
- 在管理员后台配置:
- 导航到系统设置 > OAuth 配置
- 配置基础设置:
- OAuth 重定向 URI:
https://yourdomain.com/api/auth/[provider]/callback
- OAuth State 密钥:强随机字符串,用于 state 参数加密
- 启用需要的 OAuth 提供商并填写相应凭证:
- GitHub:Client ID / Secret
- Casdoor:Server URL / Client ID / Secret / Organization Name
- Google:Client ID / Secret
- 聚合登陆:AppID / AppKey / 接口地址,并可同时启用 QQ、微信、支付宝等平台
- 第三方 OAuth2:完整的 OAuth 端点和字段映射
-
OAuth 提供商配置:
在 OAuth 提供商的开发者控制台配置重定向 URI,确保与后台配置一致
-
账户创建流程:
- 用户点击 OAuth 登录按钮
- 完成 OAuth 认证后,若身份未关联,用户可选择:
- 创建新账户:设置用户名和密码,直接创建新账户
- 绑定现有账户:输入现有用户名和密码进行绑定
- 成功后自动登录
- 安全特性:
- 所有密码使用 bcrypt 加密
- OAuth 状态参数使用 AES 加密校验
- 绑定令牌有 10 分钟有效期
- 支持账户锁定和风险控制
项目结构
VoiceHub/
├── .github/ # GitHub 配置目录
│ └── workflows/ # GitHub Actions 工作流
│ ├── build-fpk.yml # FnOS FPK 安装包构建
│ ├── db-migrate-test.yml # 空库全量数据库迁移校验
│ ├── release.yml # Release 发布流程
│ ├── docker-build.yml # Docker 镜像构建
│ ├── docker-postgres.yml # PostgreSQL Docker 镜像构建
│ ├── nix.yml # Nix 构建校验与 pnpmDeps 哈希同步
│ └── nix-flake-update.yml # Nix flake inputs 月度更新
├── app/ # Nuxt 4 应用主目录
│ ├── app.vue # 应用入口文件
│ ├── assets/ # 静态资源目录
│ │ └── css/ # CSS样式文件
│ │ ├── components.css # 组件样式
│ │ ├── lyric-player.module.css # 歌词播放器样式
│ │ ├── main.css # 主样式文件(含主题引入)
│ │ ├── markdown.css # Markdown样式
│ │ ├── mobile-admin.css # 移动端管理样式
│ │ ├── print-fix.css # 打印样式修复
│ │ ├── sf-pro-icons.css # SF Pro图标字体
│ │ ├── theme-protection.css # 主题保护样式(浏览器兼容性)
│ │ ├── transitions.css # 过渡动画样式
│ │ ├── variables.css # 全局基础样式与媒体查询
│ │ ├── year-review.css # 年度回顾样式
│ │ └── themes/ # 主题目录
│ │ ├── dark.css # 深色主题设计变量
│ │ ├── light.css # 亮色主题设计变量
│ │ └── ModernLight.css # 现代浅色主题设计变量
│ ├── components/ # Vue组件目录
│ │ ├── Account/ # 账号管理组件
│ │ │ └── SocialBindings.vue # 社交账号绑定
│ │ ├── Admin/ # 管理员功能组件
│ │ │ ├── ApiKeyManager.vue # API密钥管理
│ │ │ ├── AuditLogPanel.vue # 管理员操作审计面板
│ │ │ ├── LogManagement.vue # 日志管理(级别/保留天数/查询导出清理)
│ │ │ ├── LogTable.vue # 日志表格容器(表头/加载态/空状态)
│ │ │ ├── BackupAutoSettings.vue # 自动备份设置
│ │ │ ├── BackupManager.vue # 数据库备份管理
│ │ │ ├── BatchUpdateModal.vue # 批量更新模态框
│ │ │ ├── BlacklistManager.vue # 黑名单管理
│ │ │ ├── CardCodeAvailablePicker.vue # 可用点歌券勾选面板
│ │ │ ├── CardCodeDispatchModal.vue # 点歌券派发弹窗
│ │ │ ├── CardCodeRecipientPicker.vue # 派发接收人搜索与年级班级圈选
│ │ │ ├── CardCodesManager.vue # 点歌券管理
│ │ │ ├── DataAnalysisPanel.vue # 数据分析面板
│ │ │ ├── DatabaseManager.vue # 数据库管理
│ │ │ ├── DuplicateSongsModal.vue # 重复歌曲检测弹窗
│ │ │ ├── EmailTemplateManager.vue # 邮件模板管理
│ │ │ ├── MusicSourceController.vue # 音源控制管理
│ │ │ ├── MusicSourcePlugins.vue # LX Music 与 MusicFree 插件音源管理
│ │ │ ├── NotificationHistory.vue # 通知发送历史与用户已读明细
│ │ │ ├── NotificationSender.vue # 通知发送管理
│ │ │ ├── OAuthConfigManager.vue # OAuth 配置管理
│ │ │ ├── OAuthBindingsModal.vue # OAuth 绑定详情弹窗
│ │ │ ├── OverviewDashboard.vue # 管理概览仪表板
│ │ │ ├── PlayTimeManager.vue # 播放时间管理
│ │ │ ├── PermissionMatrix.vue # 权限矩阵页
│ │ │ ├── ProviderConfigSection.vue # OAuth 提供商配置组件
│ │ │ ├── RequestTimeManager.vue # 投稿开放时段 & 重复投稿限制管理
│ │ │ ├── ScheduleForm.vue # 排期表单
│ │ │ ├── ScheduleItemPrint.vue # 排期项目打印
│ │ │ ├── ScheduleManager.vue # 排期管理
│ │ │ ├── SchedulePlaylistExportModal.vue # 排期歌单导出弹窗(CSV)
│ │ │ ├── SchedulePlaylistFilterModal.vue # 排期歌单过滤器
│ │ │ ├── SchedulePrinter.vue # 排期打印功能
│ │ │ ├── ScheduleTablePrint.vue # 排期表格打印功能
│ │ │ ├── SemesterManager.vue # 学期管理
│ │ │ ├── Sidebar.vue # 管理后台侧边栏
│ │ │ ├── SiteConfigManager.vue # 站点配置管理
│ │ │ ├── SmtpManager.vue # SMTP邮件服务管理
│ │ │ ├── SystemBoard.vue # 系统看板(进程/数据库/表规模/生效配置/运行事件)
│ │ │ ├── SongDownloadDialog.vue # 歌曲下载弹窗
│ │ │ ├── SongManagement.vue # 歌曲管理
│ │ │ ├── SongSourceReplaceModal.vue # 歌曲换源弹窗(跨音源搜索与替换)
│ │ │ ├── SubmissionRemarkDialog.vue # 投稿备注弹窗
│ │ │ ├── StepUpDialog.vue # 敏感操作二次验证弹窗
│ │ │ ├── UserManager.vue # 用户管理
│ │ │ ├── UserApprovalModal.vue # 用户注册审核弹窗
│ │ │ ├── UserExportModal.vue # 用户导出弹窗
│ │ │ ├── GradeClassManager.vue # 年级班级配置管理
│ │ │ ├── UserPermissionsModal.vue # 按用户显式授权弹窗
│ │ │ ├── UserSongsModal.vue # 用户歌曲查看弹窗
│ │ │ └── VotersModal.vue # 投票人员查看弹窗
│ │ ├── AMLL/ # Apple Music-Like Lyrics组件
│ │ │ └── LyricPlayer.vue # AMLL歌词播放器
│ │ ├── Auth/ # 认证相关组件
│ │ │ ├── Providers/ # 第三方登录提供商组件
│ │ │ │ ├── Casdoor/ # Casdoor登录组件
│ │ │ │ │ └── Icon.vue # Casdoor图标
│ │ │ │ ├── GitHub/ # GitHub登录组件
│ │ │ │ │ └── Icon.vue # GitHub图标
│ │ │ │ └── Google/ # Google登录组件
│ │ │ │ └── Icon.vue # Google图标
│ │ │ ├── ChangePasswordForm.vue # 修改密码表单
│ │ │ ├── LoginForm.vue # 登录表单
│ │ │ ├── OAuthBindingCard.vue # OAuth绑定卡片
│ │ │ ├── CaptchaInput.vue # 图形验证码输入组件
│ │ │ ├── TurnstileWidget.vue # Cloudflare Turnstile验证组件
│ │ │ ├── EsaCaptchaWidget.vue # 阿里云 ESA AI验证码组件
│ │ │ ├── OAuthButtons.vue # OAuth登录按钮组
│ │ │ ├── OAuthQuickLogin.vue # 微信/QQ内置浏览器快速登录按钮
│ │ │ ├── OAuthBindReminderModal.vue # 微信/QQ内置浏览器账号密码登录绑定引导弹窗
│ │ │ ├── LegalConsentModal.vue # 登录条款全局确认弹窗
│ │ │ ├── TwoFactorSetup.vue # 双重认证设置组件
│ │ │ └── TwoFactorVerify.vue # 双重认证验证组件
│ │ ├── Common/ # 通用组件
│ │ │ └── UserSearchModal.vue # 用户搜索弹窗
│ │ ├── Notifications/ # 通知系统组件
│ │ │ └── NotificationSettings.vue # 通知设置
│ │ ├── Player/ # 播放器相关组件
│ │ │ └── PlayerLyric/ # 播放器歌词子组件
│ │ │ ├── AMLyric.vue # Apple Music风格歌词
│ │ │ └── DefaultLyric.vue # 默认风格歌词
│ │ ├── Songs/ # 歌曲相关组件
│ │ │ ├── AlbumDetailsModal.vue # 网易云音乐专辑详情弹窗
│ │ │ ├── BilibiliEpisodesModal.vue # Bilibili剧集选择弹窗
│ │ │ ├── DuplicateSongModal.vue # 重复歌曲处理对话框
│ │ │ ├── ImportSongsModal.vue # 导入歌曲弹窗
│ │ │ ├── NeteaseLoginModal.vue # 网易云音乐登录弹窗
│ │ │ ├── NeteaseUploadDialog.vue # 网易云云盘上传弹窗
│ │ │ ├── PlaylistSelectionModal.vue # 歌单选择弹窗
│ │ │ ├── PodcastEpisodesModal.vue # 播客节目弹窗
│ │ │ ├── QQMusicLoginModal.vue # QQ音乐登录弹窗
│ │ │ ├── RecentSongsModal.vue # 最近播放弹窗
│ │ │ ├── RequestForm.vue # 点歌表单
│ │ │ ├── ScheduleList.vue # 排期列表展示
│ │ │ ├── SongList.vue # 歌曲列表
│ │ │ └── SubmissionOptionsModal.vue # 投稿选项弹窗
│ │ ├── UI/ # 通用UI组件
│ │ │ ├── AudioPlayer/ # 音频播放器组件模块
│ │ │ │ ├── AudioElement.vue # 音频元素组件
│ │ │ │ ├── PlayerControls.vue # 播放器控制组件
│ │ │ │ ├── PlayerInfo.vue # 播放器信息组件
│ │ │ │ └── VolumeControl.vue # 播放器音量控制组件
│ │ │ ├── Common/ # 通用UI组件
│ │ │ │ ├── AppDatePicker.vue # 自绘日期选择器
│ │ │ │ ├── AppDateTimePicker.vue # 自绘日期时间选择器
│ │ │ │ ├── AppSpinner.vue # 通用加载转圈组件
│ │ │ │ ├── AppTimePicker.vue # 自绘时间选择器
│ │ │ │ ├── CollapsibleSection.vue # 可折叠区域组件
│ │ │ │ ├── CustomSelect.vue # 自定义选择器
│ │ │ │ ├── DataTable.vue # 通用数据表格组件
│ │ │ │ ├── ErrorBoundary.vue # 错误边界组件
│ │ │ │ ├── InputField.vue # 通用输入框组件
│ │ │ │ ├── LoadingState.vue # 加载状态组件
│ │ │ │ ├── MethodCard.vue # 可展开卡片组件
│ │ │ │ ├── Pagination.vue # 翻页组件
│ │ │ │ ├── PasswordField.vue # 密码输入框组件
│ │ │ │ ├── Popover.vue # 弹出框组件
│ │ │ │ ├── SearchFilter.vue # 搜索过滤组件
│ │ │ │ └── StatCard.vue # 统计卡片组件
│ │ │ ├── AppleMusicLyrics.vue # 类Apple Music风格歌词显示组件
│ │ │ ├── AudioPlayer.vue # 主音频播放器组件
│ │ │ ├── BilibiliIframeModal.vue # Bilibili视频预览弹窗
│ │ │ ├── ConfirmDialog.vue # 确认对话框
│ │ │ ├── Icon.vue # 图标组件
│ │ │ ├── ImportantNotificationModal.vue # 重要通知全屏弹窗
│ │ │ ├── LyricsModal.vue # 全屏歌词模态框组件
│ │ │ ├── MarqueeText.vue # 滚动文本显示组件
│ │ │ ├── Notification.vue # 单个通知组件
│ │ │ ├── NotificationContainer.vue # 通知容器组件
│ │ │ ├── PageTransition.vue # 页面过渡动画
│ │ │ ├── ProgressBar.vue # 进度条组件
│ │ │ ├── AppLoadingScreen.vue # 启动加载屏幕组件
│ │ │ ├── SongComments.vue # 网易云与QQ音乐评论组件
│ │ │ └── WarpCanvas.vue # 动态画布背景组件
│ │ ├── year-review/ # 年度回顾组件
│ │ │ ├── IntroSlide.vue # 开场页
│ │ │ ├── FirstSongSlide.vue # 第一首歌页
│ │ │ ├── ArtistSlide.vue # 艺术家页
│ │ │ ├── StatsSlide.vue # 统计页
│ │ │ ├── MiscSlide.vue # 杂项页
│ │ │ ├── OutroSlide.vue # 结尾页
│ │ │ └── ShareCard.vue # 分享卡片
│ │ └── SiteFooter.vue # 站点页脚
│ ├── composables/ # Vue 3 组合式API
│ │ ├── useAdmin.ts # 管理员功能hooks
│ │ ├── useAudioPlayer.ts # 音频播放器hooks
│ │ ├── useAudioPlayerControl.ts # 音频播放器控制hooks
│ │ ├── useAudioPlayerEnhanced.ts # 增强音频播放器hooks
│ │ ├── useAudioPlayerSync.ts # 音频播放器同步hooks
│ │ ├── useAudioQuality.ts # 音质管理hooks
│ │ ├── useAudioVisualizer.ts # 音频可视化hooks
│ │ ├── useAuth.ts # 认证功能hooks
│ │ ├── useBackgroundRenderer.ts # 背景渲染hooks
│ │ ├── useBilibiliPreview.ts # Bilibili视频预览hooks
│ │ ├── useChkszSource.ts # ChKSz音源hooks
│ │ ├── useErrorHandler.ts # 错误处理hooks
│ │ ├── useHomeBootstrap.ts # 首页首屏数据 SSR 预取hooks
│ │ ├── useImportantNotification.ts # 重要通知全局状态与已读处理
│ │ ├── useLegalConsentPrompt.js # 全局登录条款确认弹窗状态hooks
│ │ ├── useLocaleText.ts # i18n 文案访问与服务端错误码本地化hooks
│ │ ├── useLyricManager.ts # 歌词管理hooks
│ │ ├── useLyricPlayer.ts # 类Apple Music风格歌词播放器hooks
│ │ ├── useLyrics.ts # 歌词功能hooks
│ │ ├── useLyricSettings.ts # 歌词设置hooks
│ │ ├── useMediaSession.ts # 媒体会话API hooks
│ │ ├── useMusicSources.ts # 音乐源管理hooks
│ │ ├── useMusicWebSocket.ts # 音乐WebSocket hooks
│ │ ├── useNotifications.ts # 通知功能hooks
│ │ ├── useOAuthBindReminder.ts # 微信/QQ绑定引导浏览器存储状态hooks
│ │ ├── usePlatformConfig.ts # 平台管理配置hooks
│ │ ├── usePermissions.ts # 权限管理hooks
│ │ ├── usePasswordStrength.ts # 密码强度检测hooks
│ │ ├── usePlayerLayout.ts # 播放器布局(固定底部/自由拖拽)偏好hooks
│ │ ├── useRequestDedup.ts # 请求去重hooks
│ │ ├── useSafeLocale.ts # 安全 i18n 文本包装hooks
│ │ ├── useScrollMemory.ts # 页面滚动位置记忆hooks
│ │ ├── useSemesters.ts # 学期管理hooks
│ │ ├── useSiteConfig.js # 站点配置hooks
│ │ ├── useSongPlayer.ts # 歌曲播放器hooks
│ │ ├── useSchedulePlaylistSync.ts # 本标签页排期保存后的队列刷新与生命周期
│ │ ├── useSongs.ts # 歌曲管理hooks
│ │ ├── useStepUp.ts # 敏感操作二次验证弹窗编排hooks
│ │ ├── useSyncedTime.ts # 服务器时间对时hooks
│ │ ├── useTheme.ts # 主题管理
│ │ ├── useThemeImage.ts # 主题图片获取
│ │ ├── useToast.ts # Toast提示hooks
│ │ ├── useWakeLock.ts # 播放屏幕常亮(Wake Lock)hooks
│ │ ├── useUserFilters.ts # 用户过滤器hooks
│ │ └── useZIndex.ts # 浮层动态层级hooks
│ ├── drizzle/ # 数据库相关
│ │ ├── db.ts # 数据库连接
│ │ ├── schema.ts # 数据库模型
│ │ └── migrations/ # 数据库迁移文件
│ │ ├── *.sql # Drizzle 迁移脚本
│ │ └── meta/ # Drizzle 迁移快照
│ ├── layouts/ # 布局组件
│ │ └── default.vue # 默认布局模板
│ ├── middleware/ # 中间件
│ │ └── auth.global.ts # 全局认证中间件
│ ├── pages/ # 页面组件(Nuxt 4路由)
│ │ ├── account/ # 账户管理页面
│ │ │ └── index.vue # 账户中心(绑定管理)
│ │ ├── auth/ # 认证相关页面
│ │ │ └── error.vue # 认证错误页面
│ │ ├── change-password.vue # 修改密码页面
│ │ ├── dashboard.vue # 用户仪表盘
│ │ ├── forgot-password.vue # 找回密码页面
│ │ ├── index.vue # 首页
│ │ ├── legal/ # 协议文档页面
│ │ │ └── [slug].vue # 协议文档内容页
│ │ ├── login.vue # 登录页面
│ │ ├── notification-settings.vue # 通知设置页面
│ │ ├── reset-password.vue # 重置密码页面
│ │ └── year-review.vue # 年度回顾页面
│ ├── plugins/ # Nuxt插件
│ │ ├── auth.client.ts # 客户端认证插件
│ │ ├── auth.server.ts # 服务端认证插件
│ │ ├── locale.ts # 语言初始化与SSR同步插件
│ │ └── time-sync.client.ts # 客户端服务器时间对时插件
│ ├── public/ # 静态文件目录
│ │ ├── images/ # 图片资源
│ │ │ └── beian.png # 备案图标
│ │ ├── themes/ # 主题图片
│ │ │ ├── ClassicDark/ # 经典深色主题图片
│ │ │ │ ├── logo.svg # SVG格式Logo
│ │ │ │ ├── search.svg # 搜索图标
│ │ │ │ └── thumbs-up.svg # 点赞图标
│ │ │ ├── ClassicLight/ # 经典亮色主题图片
│ │ │ │ ├── logo.svg # SVG格式Logo
│ │ │ │ ├── search.svg # 搜索图标
│ │ │ │ └── thumbs-up.svg # 点赞图标
│ │ │ └── ModernLight/ # 现代浅色主题图片
│ │ │ ├── logo.svg # SVG格式Logo
│ │ │ ├── search.svg # 搜索图标
│ │ │ └── thumbs-up.svg # 点赞图标
│ │ ├── favicon.ico # 网站图标
│ │ └── robots.txt # 搜索引擎爬虫配置
│ ├── workers/ # Web Worker
│ │ └── audioEncoderWorker.js # 音频编码 Web Worker
│ └── utils/ # 工具函数
│ ├── core/ # 核心工具
│ │ └── security.ts # 安全相关工具
│ ├── data/ # 生成的数据表
│ │ └── cjkT2sMap.ts # 繁→简单字映射表
│ ├── locale/ # 国际化语言资源
│ │ ├── en-US.ts # 英文语言包
│ │ ├── index.ts # 语言状态、切换及回退逻辑
│ │ └── zh-CN.ts # 简体中文语言包
│ ├── lyric/ # 歌词处理工具
│ │ ├── exclude.ts # 歌词排除规则
│ │ ├── lyricFormat.ts # 歌词格式化
│ │ ├── lyricLanguage.ts # 歌词语言识别(CJK 混合上下文)
│ │ ├── lyricMatchQuality.ts # 歌词版本一致性检测
│ │ ├── lyricParser.ts # 歌词解析器
│ │ ├── lyricText.ts # 歌词行文本/音译提取
│ │ ├── lyricStripper.ts # 歌词清理
│ │ ├── parseLrc.ts # LRC格式解析
│ │ └── qrc-parser.ts # QRC格式解析
│ ├── admin-permissions.ts # 后台权限码目录与有效权限解析
│ ├── bilibiliSource.ts # 哔哩哔哩音源
│ ├── cover-theme.ts # 封面取色与歌词主题色(AMLL 调色板)
│ ├── debounce.ts # 防抖工具
│ ├── esaCaptcha.ts # 阿里云 ESA AI验证码区域与服务端节点共享常量
│ ├── grade-class-input.ts # 年级班级批量输入解析
│ ├── gradeClassWeights.js # 年级排序权重
│ ├── invalidPlaybackUrls.ts # 播放端确认无效的地址登记
│ ├── lyricAdapter.ts # 歌词适配器
│ ├── markdown.js # Markdown工具
│ ├── musicSources.ts # 音乐源配置
│ ├── musicUrl.ts # 音乐URL处理
│ ├── pluginResolver.ts # 插件音源搜索、歌词与媒体解析接入
│ ├── pluginPlatform.ts # 插件音源平台键、插件 ID 与音质映射(LX Music / MusicFree)
│ ├── platforms.ts # 平台元数据共享(白名单/显示名/图标)
│ ├── playerLayout.ts # 播放器布局模式与自由拖拽坐标解析
│ ├── blacklist.ts # 歌曲类型黑名单候选值共享(语种/曲风)
│ ├── sentryUpstreamMusicErrors.ts # Sentry 上游音源错误过滤
│ ├── preview-duration.ts # 播放地址时长与歌曲时长比对(试听片段检测)
│ ├── song-duration.ts # 疑似试听片段时长判定
│ ├── song-name-normalize.ts # 歌曲名称归一化匹配
│ ├── neteaseApi.ts # 网易云音乐API
│ ├── neteaseCatalog.ts # 网易云曲库播放响应的歌曲、音质与试听标记核验
│ ├── qqCookie.ts # QQ音乐登录Cookie存取与续期广播
│ ├── qqUserLibrary.ts # QQ音乐用户资料库(歌单/最近播放)
│ ├── oauth-register.ts # OAuth注册工具
│ ├── email-verification.ts # 注册邮箱验证码
│ ├── embedded-browser.ts # 微信/QQ内置浏览器UA检测
│ ├── password-policy.ts # 统一密码策略
│ ├── settingsPermissions.ts # 系统设置中仅超级管理员可读写字段清单
│ ├── custom-css-policy.ts # 自定义CSS安全策略
│ ├── oauth.ts # OAuth工具
│ ├── autoSchedule.ts # 自动排期算法
│ ├── schedulePlayTime.ts # 排期播出时段判定(带时段排期统计)
│ ├── schedulePlaylist.ts # 排期队列身份匹配与续播位置
│ ├── schedulePlaylistRefresh.ts # 排期队列按需串行刷新与旧结果丢弃
│ ├── timeUtils.ts # 时间工具
│ ├── user-archive.ts # 账号归档判定与筛选参数解析
│ ├── webauthn.js # WebAuthn浏览器兼容工具
│ ├── print-image-cache.ts # 打印导出图片下载缓存
│ └── url.ts # URL处理工具
├── server/ # 服务端代码
│ ├── api/ # API路由
│ │ ├── admin/ # 管理员API
│ │ │ ├── api-keys/ # API密钥管理API
│ │ │ │ ├── [id].delete.ts # 删除API密钥
│ │ │ │ ├── [id].get.ts # 获取API密钥详情
│ │ │ │ ├── [id].put.ts # 更新API密钥
│ │ │ │ ├── index.get.ts # 获取API密钥列表
│ │ │ │ ├── index.post.ts # 创建API密钥
│ │ │ │ ├── logs.get.ts # API使用日志
│ │ │ │ └── permissions.ts # API密钥权限定义
│ │ │ ├── audit-logs/ # 管理员操作审计API
│ │ │ │ ├── export.get.ts # 导出审计日志(CSV/JSONL)
│ │ │ │ ├── index.get.ts # 获取审计日志列表
│ │ │ │ └── stats.get.ts # 获取审计日志统计
│ │ │ ├── backup/ # 备份管理API
│ │ │ │ ├── delete/ # 删除备份子目录
│ │ │ │ │ └── [filename].delete.ts
│ │ │ │ ├── download/ # 下载备份子目录
│ │ │ │ │ └── [filename].get.ts
│ │ │ │ ├── auto-config.get.ts # 获取自动备份配置
│ │ │ │ ├── auto-config.put.ts # 更新自动备份配置
│ │ │ │ ├── clear.post.ts # 清空备份历史
│ │ │ │ ├── download.get.ts # 下载备份
│ │ │ │ ├── export.post.ts # 创建备份
│ │ │ │ ├── github-file.get.ts # 读取 Git 仓库备份文件正文
│ │ │ │ ├── github-history.get.ts # 读取 Git 仓库备份提交历史
│ │ │ │ ├── history.get.ts # 获取备份历史
│ │ │ │ ├── history-clear.post.ts # 清空备份历史记录
│ │ │ │ ├── list.get.ts # 获取备份列表
│ │ │ │ ├── restore-chunk.post.ts # 恢复备份分片
│ │ │ │ ├── restore.post.ts # 恢复备份
│ │ │ │ ├── test-email.post.ts # 测试邮件发送
│ │ │ │ ├── test-github.post.ts # 测试 Git 仓库连接
│ │ │ │ ├── test-s3.post.ts # 测试 S3 连接
│ │ │ │ ├── test-telegram.post.ts # 测试 Telegram Bot
│ │ │ │ ├── test-webdav.post.ts # 测试 WebDAV 连接
│ │ │ │ └── upload.post.ts # 上传备份文件
│ │ │ ├── blacklist/ # 黑名单管理API
│ │ │ │ ├── [id].delete.ts # 删除黑名单项
│ │ │ │ ├── [id].patch.ts # 更新黑名单项
│ │ │ │ ├── index.get.ts # 获取黑名单列表
│ │ │ │ └── index.post.ts # 添加黑名单项
│ │ │ ├── grade-class/ # 年级班级配置API
│ │ │ │ ├── [id].delete.ts # 删除配置项
│ │ │ │ ├── by-grade.delete.ts # 按年级删除配置
│ │ │ │ ├── initialize.post.ts # 从现有用户提取初始化
│ │ │ │ ├── index.get.ts # 获取配置列表
│ │ │ │ └── index.post.ts # 新增配置项
│ │ │ ├── log-management/ # 日志管理API
│ │ │ │ ├── access/ # API 访问日志子目录
│ │ │ │ │ └── export.get.ts # 导出访问日志(CSV/JSONL)
│ │ │ │ ├── access.get.ts # 获取 API 访问日志列表
│ │ │ │ ├── cleanup.post.ts # 按保留天数清理过期日志
│ │ │ │ └── stats.get.ts # 获取日志统计
│ │ │ ├── card-codes/ # 点歌券管理API
│ │ │ │ ├── [id].put.ts # 更新单张点歌券
│ │ │ │ ├── assignments.get.ts # 派发记录查询
│ │ │ │ ├── assign.post.ts # 派发点歌券给用户
│ │ │ │ ├── create.post.ts # 创建点歌券
│ │ │ │ ├── delete.post.ts # 删除点歌券
│ │ │ │ ├── export.get.ts # 导出点歌券
│ │ │ │ ├── index.get.ts # 获取点歌券列表
│ │ │ │ ├── recipients.get.ts # 派发接收人查询
│ │ │ │ ├── recipients-tree.get.ts # 按年级班级树查询接收人
│ │ │ │ ├── redeem-logs.get.ts # 获取点歌券日志
│ │ │ │ ├── recycle.post.ts # 回收已派发未使用的点歌券
│ │ │ │ └── update.post.ts # 批量更新点歌券
│ │ │ ├── database/ # 数据库管理API
│ │ │ │ ├── cleanup.post.ts # 数据库清理
│ │ │ │ ├── performance.get.ts # 数据库性能监控
│ │ │ │ ├── pool-status.get.ts # 连接池状态
│ │ │ │ └── reset.post.ts # 重置数据库
│ │ │ ├── music-source-plugins/ # 音源插件配置、启停、排序与验证
│ │ │ │ ├── [id].delete.ts # 移除音源插件
│ │ │ │ ├── [id].put.ts # 更新音源插件
│ │ │ │ ├── [id]/ # 单个插件操作
│ │ │ │ │ ├── enabled.patch.ts # 启用/停用
│ │ │ │ │ ├── refresh.post.ts # 重新加载插件产物
│ │ │ │ │ └── test.post.ts # 验证插件初始化
│ │ │ │ ├── index.get.ts # 插件列表与配置版本
│ │ │ │ ├── index.post.ts # 新增音源插件
│ │ │ │ └── order.put.ts # 保存解析优先级排序
│ │ │ ├── db-status.get.ts # 数据库状态检查
│ │ │ ├── email-templates/ # 邮件模板管理API
│ │ │ │ ├── index.delete.ts # 删除邮件模板
│ │ │ │ ├── index.get.ts # 获取邮件模板列表
│ │ │ │ ├── index.post.ts # 创建/更新邮件模板
│ │ │ │ └── preview.post.ts # 预览邮件模板
│ │ │ ├── fix-sequence.post.ts # 修复数据库序列
│ │ │ ├── notifications/ # 管理员通知API
│ │ │ │ ├── history/ # 通知批次明细API
│ │ │ │ │ ├── [batchId].delete.ts # 删除通知批次
│ │ │ │ │ ├── [batchId].get.ts # 查询批次用户已读明细
│ │ │ │ │ └── [batchId].put.ts # 修改通知批次
│ │ │ │ ├── history.get.ts # 查询按发送批次归类的通知历史
│ │ │ │ └── send.post.ts # 发送通知
│ │ │ ├── permissions/ # 权限矩阵API
│ │ │ │ ├── matrix.get.ts # 读取角色权限模板与持有者统计
│ │ │ │ └── matrix.put.ts # 保存角色权限模板(安全阀校验)
│ │ │ ├── play-times/ # 播放时间管理API
│ │ │ │ ├── [id].ts # 播放时间操作
│ │ │ │ ├── index.post.ts # 创建播放时间
│ │ │ │ └── index.ts # 播放时间列表
│ │ │ ├── replay-requests/ # 重播申请管理API
│ │ │ │ ├── index.get.ts # 获取重播申请列表
│ │ │ │ └── reject.post.ts # 拒绝重播申请
│ │ │ ├── request-times/ # 点歌时间管理API
│ │ │ │ ├── [id].ts # 点歌时间操作
│ │ │ │ ├── index.post.ts # 创建点歌时间
│ │ │ │ └── index.ts # 点歌时间列表
│ │ │ ├── schedule/ # 排期管理API
│ │ │ │ ├── bulk-draft.post.ts # 批量保存排期草稿
│ │ │ │ ├── bulk-publish.post.ts # 批量发布排期
│ │ │ │ ├── copy.post.ts # 复制排期到指定日期
│ │ │ │ ├── draft.post.ts # 保存排期草稿
│ │ │ │ ├── full.get.ts # 获取完整排期数据(包含草稿)
│ │ │ │ ├── move-date.post.ts # 排期日期迁移
│ │ │ │ ├── publish.post.ts # 发布排期草稿
│ │ │ │ ├── remove-all-date.post.ts # 清空某日全部排期
│ │ │ │ ├── remove.post.ts # 移除排期
│ │ │ │ ├── sequence.post.ts # 更新排期顺序
│ │ │ │ ├── song-pool.delete.ts # 从备选池移除歌曲
│ │ │ │ ├── song-pool.get.ts # 获取备选池列表
│ │ │ │ └── song-pool.post.ts # 歌曲加入备选池
│ │ │ ├── schedule.post.ts # 创建排期
│ │ │ ├── semesters/ # 学期管理API
│ │ │ │ ├── [id].delete.ts # 删除学期
│ │ │ │ ├── [id].put.ts # 更新学期
│ │ │ │ ├── index.get.ts # 获取学期列表
│ │ │ │ ├── index.post.ts # 创建学期
│ │ │ │ └── set-active.post.ts # 设置活跃学期
│ │ │ ├── smtp/ # SMTP邮件服务API
│ │ │ ├── recipients.get.ts # 功能操作使用的轻量接收人查询
│ │ │ │ ├── reload.post.ts # 重新加载SMTP配置
│ │ │ │ ├── test-connection.post.ts # 测试SMTP连接
│ │ │ │ └── test-email.post.ts # 发送测试邮件
│ │ │ ├── songs/ # 管理员歌曲管理API
│ │ │ │ ├── batch-reject.post.ts # 批量驳回歌曲
│ │ │ │ ├── cover.post.ts # 获取歌曲封面
│ │ │ │ ├── delete.post.ts # 删除歌曲
│ │ │ │ ├── duration.post.ts # 更新歌曲时长
│ │ │ │ ├── mark-played.post.ts # 标记歌曲已播放
│ │ │ │ └── reject.post.ts # 驳回歌曲
│ │ │ ├── stats.get.ts # 统计数据
│ │ │ ├── activities.get.ts # 活动管理API
│ │ │ ├── stats/ # 详细统计API
│ │ │ │ ├── active-users.get.ts # 活跃用户统计
│ │ │ │ ├── realtime.get.ts # 实时统计
│ │ │ │ ├── semester-comparison.get.ts # 学期对比统计
│ │ │ │ ├── top-songs.get.ts # 热门歌曲统计
│ │ │ │ ├── trends.get.ts # 趋势分析
│ │ │ │ └── user-engagement.get.ts # 用户参与度统计
│ │ │ ├── system-settings/ # 系统设置API
│ │ │ │ ├── [scope].ts # 按模块隔离的配置读取与更新
│ │ │ │ ├── env-oauth-import.post.ts # 导入环境变量OAuth配置
│ │ │ │ ├── env-oauth.get.ts # 获取环境变量OAuth配置
│ │ │ │ ├── index.post.ts # 更新系统设置
│ │ │ │ ├── index.ts # 获取系统设置
│ │ │ │ └── secretMask.ts # 密钥脱敏工具
│ │ │ ├── system-board/ # 系统看板API
│ │ │ │ ├── events.get.ts # 运行事件流(内存缓冲 + API错误 + 口令审计)
│ │ │ │ ├── index.get.ts # 看板快照(进程/数据库/表规模/生效配置)
│ │ │ │ └── runtime-clear.post.ts # 清空运行事件缓冲
│ │ │ └── users/ # 用户管
> README 内容过长,已截取前 64 KB。完整内容请前往 GitHub 仓库查看。
评论