Skip to content

面板概览与导航 ​

本文引用的文件

目录 ​

  1. 简介
  2. 项目结构与职责划分
  3. 核心组件:管理面板外壳
  4. 架构总览
  5. 菜单结构说明
  6. 页面初始化流程
  7. URL、路由与深度链接
  8. 前端到后端接口映射
  9. 权限控制与未授权处理
  10. 常见使用场景
  11. 多语言文案在面板中的使用方式
  12. 故障排查与常见问题
  13. 结论

简介 ​

本文面向管理员和前端维护者,解释 SkinNexus 管理面板的工作方式:AdminPanel.vue 如何根据当前用户角色、站点配置和插件能力决定左侧菜单;前端 adminApi.js 如何把管理视图的数据请求统一发送到 /api/admin/v1/*;后端 adminapi.go 如何通过会话或令牌校验权限并暴露具体端点。文档还覆盖仪表盘、用户、玩家/角色、材质、插件、主题市场、设置、审计、报告、Union、状态等模块的职责边界,以及站长登录、跳转到用户列表、查看诊断信息等典型流程。

项目结构与职责划分 ​

管理面板涉及三层代码:

  • 前端外壳:AdminPanel.vue 负责侧边栏、子视图切换、深度链接和权限态展示。
  • 前端数据层:adminApi.js 提供带管理员令牌注入的统一请求函数。
  • 后端接口层:adminapi.go 注册 /api/admin/v1/* 路由,实现会话/令牌鉴权、业务聚合和分页响应。

图表来源

章节来源

核心组件:管理面板外壳 ​

AdminPanel.vue 是管理面板的容器,不直接承载所有业务逻辑,而是:

  • 定义静态菜单项,包括仪表盘、用户、玩家、邀请码、设置、状态、访问日志、举报、材质、审计、任务队列、Union、插件和市场。
  • 根据站点配置隐藏可选菜单:当站点未启用邀请码时隐藏“邀请码”;未启用 Union 时隐藏“Union”。
  • 根据插件 UI 注册表动态追加插件菜单项。
  • 根据当前 URL 同步激活的标签页,并渲染对应的子视图组件。
  • 在未通过会话或令牌验证前,只显示侧边栏和管理员令牌输入框,避免每个子视图反复触发 403。

关键行为包括:

  • visibleNav 根据 invite_required 和 union_enabled 过滤菜单。
  • go(id) 切换到内置菜单项。
  • openPlugin(path) 切换到插件页面。
  • ready 控制主内容区域是否渲染子视图。
  • reloadTick 通过 key 变更强制重新挂载当前视图,从而触发其自身的数据加载。

章节来源

架构总览 ​

管理面板采用“外壳 + 子视图 + 共享 API 客户端”的分层模式:

图表来源

菜单结构说明 ​

AdminPanel 的菜单由三部分构成:内置菜单、站点标志位过滤、插件扩展菜单。

菜单项内部 id主要职责可见性条件
仪表盘dashboard展示用户数、角色数、材质数、弱哈希余量、存储用量、签名密钥指纹始终可见
用户管理users查询、重置密码、修改邮箱昵称、调整权限、删除用户始终可见
角色管理players管理站长的玩家/角色列表、改名、改所有者、替换材质、删除始终可见
邀请码invitation生成、编辑、列出邀请码仅当站点启用邀请码时可见
站点设置settings获取和保存站点配置项始终可见
运行状态status展示版本、构建信息、运行时环境、数据库信息和模块开关始终可见
访问日志access分页查看网页、启动器、Yggdrasil、Union 访问记录始终可见
举报处理reports列出举报、处理举报始终可见
材质库textures查询、审核、打击、删除材质始终可见
操作审计audit按操作人、动作、关键词查询后台审计日志始终可见
任务队列jobs列出任务、查看详情、取消或恢复任务始终可见
Unionunion联盟状态、轮换、黑名单、诊断等操作仅当站点启用 Union 时可见
插件plugins查看已安装插件、回滚、卸载、配置、绕过守卫始终可见
插件市场market浏览市场目录、安装插件、上传插件包始终可见

此外,插件可通过 pluginUI.js 注册管理面板扩展页面,这些扩展会出现在侧边栏中,并根据插件声明的权限要求过滤。

章节来源

页面初始化流程 ​

管理面板的初始化不是单一函数调用,而是由外层应用、面板外壳和子视图共同完成:

  1. 外层判断管理员身份App.vue 从 /api/v1/me 获取当前用户对象,并通过 user.permission > 0 判断是否为管理员。只有管理员才会看到“管理面板”入口。

  2. 进入面板后加载初始状态AdminPanel.vue 在 onMounted 中执行以下工作:

    • 如果当前会话已经是管理员(permission > 0),则不再需要机器令牌。
    • 加载插件 UI 中声明的管理面板页面,并按当前权限过滤。
    • 尝试加载站点配置标志位,用于决定是否显示邀请码和 Union 菜单。
    • 如果没有会话管理员且没有本地存储的管理员令牌,则 ready 保持为假,只显示令牌输入区。
  3. 渲染左侧导航 模板遍历 visibleNav,用 i18n 的 t() 渲染菜单标题,并渲染插件扩展菜单。

  4. 加载目标视图数据 当 ready 为真时,面板渲染当前组件。每个子视图通常在自己的 onMounted 中发起数据请求;面板通过 reloadTick 改变 key 来重新挂载当前视图,从而实现刷新。

图表来源

章节来源

URL、路由与深度链接 ​

管理面板支持浏览器地址栏深度链接,使刷新、分享和后退按钮能回到上次打开的标签页。

  • /admin:默认仪表盘。
  • /admin/users:用户管理。
  • /admin/players:角色管理。
  • /admin/textures:材质库。
  • /admin/settings:站点设置。
  • /admin/status:运行状态。
  • /admin/access:访问日志。
  • /admin/reports:举报处理。
  • /admin/audit:操作审计。
  • /admin/jobs:任务队列。
  • /admin/union:Union。
  • /admin/plugins:插件。
  • /admin/market:插件市场。
  • /admin/plugin/<path>:插件扩展页面。

面板内部通过监听 current 和 currentPlugin 的变化写入 history.pushState,同时监听 popstate 以支持后退。未知路径会回退到仪表盘,而不是报错。

图表来源

章节来源

前端到后端接口映射 ​

adminApi.js 是管理面板统一的 HTTP 客户端。它的主要职责不是定义每个业务端点,而是:

  • 从本地存储读取 X-Admin-Token。
  • 给每次请求添加该头部。
  • 将网络超时、非成功状态码转换为带 status 的错误对象。
  • 遇到 401 或 403 时,将 needToken 设为真,让面板外壳显示令牌输入区。

后端在 adminapi.go 中集中注册 /api/admin/v1/* 路由。前端各子视图根据业务语义调用不同路径,例如:

  • 仪表盘统计:GET /api/admin/v1/overview
  • 运行状态:GET /api/admin/v1/status
  • 部署自检:GET /api/admin/v1/diagnostics
  • 用户列表:GET /api/admin/v1/users
  • 材质列表:GET /api/admin/v1/textures
  • 审计日志:GET /api/admin/v1/audit
  • 访问日志:GET /api/admin/v1/access-logs
  • 举报列表和处理:GET /api/admin/v1/reports、POST /api/admin/v1/reports/{id}/resolve
  • 站点设置:GET /api/admin/v1/settings、PUT /api/admin/v1/settings
  • Union 相关:GET /api/admin/v1/union/status 及一系列运维操作端点
  • 插件与市场:GET /api/admin/v1/plugins、GET /api/admin/v1/market/catalog、POST /api/admin/v1/market/install、POST /api/admin/v1/market/upload

图表来源

章节来源

权限控制与未授权处理 ​

权限控制分为两层:前端判断是否显示入口,后端对每个管理接口做最终鉴权。

前端权限 ​

  • App.vue 使用 /api/v1/me 返回的 permission 字段判断管理员。普通用户不会看到“管理面板”入口。
  • AdminPanel.vue 进一步区分两种情况:
    • 会话管理员:permission > 0,可直接进入面板,无需手动粘贴令牌。
    • 非会话管理员:需要填写 X-Admin-Token,面板才会把 ready 设为真。

后端权限 ​

adminapi.go 的鉴权逻辑允许两种方式:

  1. 管理员网页会话:Cookie 携带站点会话,服务器查得用户且 permission > 0。
  2. 管理员令牌:请求头 X-Admin-Token 与后端环境变量 SKIN_ADMIN_TOKEN 常量比较。

如果两者都不满足,后端返回 403,错误消息指向“管理员令牌无效或未登录”。对于尚未完成邮箱验证但具有管理员权限的会话,后端还会拒绝可写操作,提示必须先完成邮箱验证。

图表来源

未授权跳转与空菜单 ​

  • 前端不会因 401/403 自动跳转到登录页,而是通过 adminApi.js 把 needToken 置为真,让 AdminPanel.vue 显示令牌输入区。
  • 如果站点关闭了邀请码,邀请码菜单会被隐藏;如果关闭了 Union,Union 菜单被隐藏。
  • 如果所有菜单都被隐藏,面板仍会渲染外壳,但左侧导航为空。此时应检查站点配置和插件权限,而不是假设后端一定出错。

章节来源

常见使用场景 ​

场景一:站长登录后进入仪表盘 ​

  1. 站长通过正常登录获得会话。
  2. App.vue 发现 permission > 0,显示管理面板入口。
  3. 进入 /admin 后,AdminPanel.vue 检测到会话管理员,跳过令牌输入。
  4. 仪表盘视图加载 /api/admin/v1/overview,显示用户、角色、材质、弱哈希余量等统计。

章节来源

场景二:跳转到用户列表 ​

  1. 管理员点击“用户管理”。
  2. AdminPanel.vue 更新 current 为 users,并渲染 UsersView。
  3. 用户视图发起 GET /api/admin/v1/users。
  4. 后端返回分页用户列表,包含总数和当前页码。

章节来源

场景三:查看诊断信息 ​

  1. 管理员进入“运行状态”或相关诊断页面。
  2. 前端调用 /api/admin/v1/status 或 /api/admin/v1/diagnostics。
  3. 后端返回版本、Go 版本、数据库引擎、迁移版本、容器信息、运行时间、模块开关等部署事实。

章节来源

多语言文案在面板中的使用方式 ​

面板的多语言由 Vue I18n 驱动,i18n.js 负责选择语言并持久化到 cookie 和本地存储。管理面板中的菜单标题和部分提示使用 useI18n().t() 渲染。

中文文案集中在 zh-CN.json,英文文案在 en.json。面板相关键包括:

  • admin.title:管理面板标题。
  • admin.tokenPlaceholder:令牌输入框占位符。
  • admin.load:加载按钮文案。
  • admin.reload:刷新按钮文案。
  • admin.navDashboard:仪表盘。
  • admin.navUsers:用户管理。
  • admin.navPlayers:角色管理。
  • admin.navSettings:站点设置。
  • admin.navStatus:运行状态。
  • admin.navAccess:访问日志。
  • admin.navReports:举报处理。
  • admin.navTextures:材质库。
  • admin.navAudit:操作审计。
  • admin.navJobs:任务队列。
  • admin.navUnion:Union。
  • admin.navPlugins:插件。
  • admin.navMarket:插件市场。

新增或修改菜单文案时,应同步更新中英文翻译文件,并确保 AdminPanel.vue 使用的 labelKey 与翻译键一致。

章节来源

故障排查与常见问题 ​

现象可能原因排查建议
登录后看不到管理面板入口用户 permission 不大于 0检查 /api/v1/me 返回的权限字段
进入面板后只显示令牌输入框会话不是管理员,也没有本地存储的管理员令牌确认已用管理员账号登录,或在令牌框填入 SKIN_ADMIN_TOKEN
点击菜单无反应URL 路径不存在或匹配不到内置菜单检查地址栏是否为 /admin/<id>,未知路径会回退到仪表盘
邀请码菜单不出现站点未启用邀请码检查站点配置 invite_required
Union 菜单不出现站点未启用 Union检查站点配置 union_enabled
接口返回 401 或 403令牌无效、会话失效、或非管理员清除本地令牌重试,或用管理员会话重新登录
审计或设置操作报需邮箱验证管理员账号未完成邮箱验证先完成邮箱验证,再执行敏感操作
刷新后视图丢失深度链接未正确写入或 URL 被改写检查 /admin 或 /admin/<id> 是否正确
插件菜单不显示插件未注册、权限不足或被过滤检查插件 UI 注册表和当前用户权限

章节来源

结论 ​

管理面板的核心设计是“前端外壳负责导航与可见性,后端负责鉴权与数据”。AdminPanel.vue 根据会话权限、站点配置和插件能力组合出最终菜单;adminApi.js 把管理请求统一带上管理员令牌;adminapi.go 在 /api/admin/v1/* 上实现细粒度后端权限控制。理解这三层关系后,可以安全地扩展新菜单、对接新接口,并在权限、语言和深度链接方面保持一致行为。

AGPL-3.0 · SkinNexus