# admin-frontend

## 职责

- 提供 Vue3 管理端登录页、认证状态、路由守卫和主布局
- 封装管理端统计/系统状态、用户管理、节点管理、套餐管理和系统配置接口
- 渲染后台仪表盘、用户管理工作台、节点管理工作台、路由管理工作台、订阅套餐 / 订单 / 优惠券 / 礼品卡管理页、系统配置页、主题管理页、插件管理工作台、公告管理工作台、支付配置工作台，以及工单管理入口
- 提供独立静态部署产物：支持通过 Docker 镜像发布到 GHCR，并在 compose 分支中以独立 `admin` 服务运行

## 行为规范

- 默认构建输出仍为主仓 `public/assets/admin`；当 `ADMIN_BUILD_OUT_DIR` 存在时，构建输出需切换到外部指定目录，供容器镜像独立打包
- 独立容器运行时通过 `Caddyfile` 把根路径重定向到 `/assets/admin/`，避免当前 `base: '/assets/admin/'` 资源前缀失效
- 独立容器运行时会把 `/api` 反向代理到 `XBOARD_BACKEND_UPSTREAM`，compose 分支默认指向 `http://web:7001`，确保前端静态容器仍能直连 Laravel 后端
- 独立容器运行时会把 `/upload/*` 去掉 `/upload` 前缀后反向代理到 `XBOARD_UPLOAD_UPSTREAM`，默认指向 `https://pic.535888.xyz`，保持与 Vite 开发代理一致的图片上传路径
- 前端 GHCR 发布链路与 Laravel 主应用发布链路分离，避免把静态前端构建耦合进现有 PHP 镜像工作流
- 登录成功后优先跳转 `redirect` 指定路由，否则回到 `/dashboard`
- 受保护路由在未登录时会自动附加 `redirect` 查询参数
- API 基础路径使用 `/api/v2/{secure_path}`，其中 `secure_path` 来自运行时配置
- 工单工作台现允许对已关闭工单继续回复；管理员发送新消息后会提示“发送并重开”，并通过统一后端语义把工单状态重新开启
- 工单工作台回复区支持点击选择、拖拽放下和剪贴板粘贴三种图片上传入口，统一复用 `/upload/rest/upload` 图片上传和 Markdown 图片链接插入逻辑；上传期间会禁用发送入口，避免图片链接尚未写入时提前回复
- 仪表盘以真实后端接口返回值为准，不在前端伪造业务统计
- 仪表盘“收入趋势”支持在同一张趋势图中切换“按金额 / 按数量”，数量模式同步切换摘要卡片、Y 轴标签与最近记录
- 仪表盘“作业详情”支持打开失败作业报错弹窗，集中查看 Horizon 失败作业的报错摘要、失败时间与队列信息
- 仪表盘“节点流量排行 / 用户流量排行”均支持独立的 `10个 / 20个` 显示切换，长列表固定在面板内滚动，避免首页高度失控
- `stat/getTrafficRank` 现支持 `limit=10|20`，前端会按当前排行面板的显示数量重新请求；24h 口径也继续显示涨跌百分比
- `stat/getTrafficRank` 在 `24h` 口径下会按“昨天同日”统计做涨跌对比，避免日统计表因 `record_at=00:00` 被秒级窗口错位后全部回落为 `0%`
- 排行项 hover 时会显示“当前流量 / 上期流量 / 变化率”详情卡；当前流量值固定右侧展示，避免长节点名挤压后不易识别
- 仪表盘 Hero 区提供“刷新全部数据”入口，统一触发总览、趋势、排行和系统状态刷新，并在页面内展示最近一次刷新时间
- 仪表盘指标卡中的“待处理工单 / 待处理佣金 / 总用户”现已支持快捷跳转；可点击卡片会显示明确的入口提示，并保留 hover / focus-visible 反馈
- 工单页与订单页可读取 dashboard 来源查询参数：工单页支持 `focus=opening|closed|all`，订单页支持 `workbench=pending|commission`，并会显示低干扰入口提示
- 用户管理页通过真实后端 `user/fetch`、`user/update`、`user/generate`、`user/dumpCSV`、`user/sendMail`、`user/ban`、`user/resetSecret`、`user/destroy` 与 `plan/fetch` 完成数据读写
- 新增用户时采用“先 generate，后按邮箱回查并 update”的两段式流程，以兼容后端基础创建接口
- 用户管理页现已补齐高级筛选弹窗，支持按邮箱、用户 ID、订阅、活跃状态、流量、已用流量、在线设备、到期时间、UUID、Token、账号状态和备注组合筛选；其中“活跃状态”按“有任意订阅 + 剩余流量大于 0 + 最后在线时间在半年内”为活跃规则
- 用户管理页新增勾选 + 批量操作工作流，支持“发送邮件 / 导出 CSV / 批量封禁 / 恢复正常”，作用范围按“已勾选用户 > 当前筛选结果 > 全部用户”自动判定
- 批量恢复正常沿用 `user/ban` 现有接口，通过 `banned=0|1` 兼容，不额外引入重复路由
- 用户管理页的“更多操作”菜单现已补齐 `分配订单 / TA的订单 / TA的邀请 / TA的流量记录 / 重置流量`；其中订单分配复用现有抽屉，用户订单跳转到订单页并自动按 `user_id` 过滤，邀请结果在当前用户页复用 `invite_user_id` 筛选视图
- 用户流量重置优先复用 `traffic-reset/reset-user`，用户行级“重置流量”会走真实后端重置链路并在成功后刷新列表
- 节点管理页通过真实后端 `server/manage/getNodes`、`server/group/fetch` 与 `server/route/fetch` 获取列表 / 关联数据，并通过 `server/manage/save`、`server/manage/sort`、`server/manage/update`、`server/manage/batchUpdate`、`server/manage/copy`、`server/manage/drop` 完成新增、编辑、排序、批量修改与行级操作
- 节点新增 / 编辑采用统一中央大弹窗，支持 `Shadowsocks / VMess / Trojan / Hysteria / VLess / TUIC / SOCKS / Naive / HTTP / Mieru / AnyTLS` 11 种协议的首版动态配置表单
- 节点新增 / 编辑 / 批量修改保存 `group_ids / route_ids` 时统一向后端提交字符串 ID，后端 `Server::whereGroupId()` 同时兼容历史字符串与数字 JSON 值，避免权限组保存后订阅侧无法命中节点
- TUIC 表单默认以 V5 / V4 版本选择、`h3 / h2 / http/1.1` ALPN 选项和 `native / quic` UDP Relay Mode 对齐后端协议模板；AnyTLS Padding Scheme 默认值与 `Server` 模型完整模板保持一致
- 节点排序采用本地草稿 + 上移 / 下移模式，保存时向 `server/manage/sort` 提交 `{ id, order }[]` 顺序 payload
- 节点列表现支持本地分页、在线 / 离线筛选、父/子节点筛选，以及跨分页稳定勾选；批量修改 / 批量删除仅作用于已勾选节点，其中批量修改可统一更新 `host / group_ids / rate / auto_online`
- 节点管理页新增“自动上线”托管开关；开启后后台 `sync:server-auto-online` 会按节点在线状态自动同步 `show`，在线 / 待同步时显示、离线时隐藏，未开启的节点仍保持手动显隐控制；疑似被墙或仍处于墙检测自动隐藏状态的节点不会被自动上线重新发布
- 节点管理页现支持墙状态展示、墙状态筛选与关键词搜索；父节点可通过行级或批量操作发起检测，子节点不单独检测并显示“随父节点”的继承状态
- 节点管理页现支持“墙检测托管”开关、批量设置和刷新数据按钮；父节点开启后参与 `sync:server-gfw-checks` 自动检测，自动墙检统计只计算父节点；子节点不独立检测但可控制是否随父节点自动隐藏 / 恢复
- 节点行级菜单现已补齐“置顶节点”，会复用当前排序结果生成新的顺序 payload 并提交到 `server/manage/sort`
- 权限组管理页使用真实后端 `server/group/fetch`、`server/group/save` 与 `server/group/drop`，支持关键字搜索、新增/编辑中央弹窗、删除确认，以及从节点数量列跳转到 `#/nodes?group={id}` 的筛选联动
- 路由管理页使用真实后端 `server/route/fetch`、`server/route/save` 与 `server/route/drop`，支持路由列表、关键词搜索、新增/编辑中央弹窗、删除与动作值展示
- 路由管理页的节点引用摘要由 `server/manage/getNodes` 返回的 `route_ids` 推导，不在前端伪造额外接口
- 节点页会读取路由查询中的 `group` 参数并自动应用对应权限组筛选，同时提供“管理权限组”入口回到权限组页；`/node-routes` 已升级为真实工作台
- 订阅管理新增独立“订阅管理”侧边栏分组，现已完整实现 `#/subscriptions/plans`、`#/subscriptions/orders`、`#/subscriptions/coupons` 与 `#/subscriptions/gift-cards`
- 套餐管理页使用真实后端 `plan/fetch`、`plan/save`、`plan/update`、`plan/drop`、`plan/sort` 与 `server/group/fetch`
- 侧边栏在低窗口高度下采用“顶部品牌区固定 + 菜单区独立纵向滚动”的结构，避免新增分组后底部导航入口被直接裁切
- 套餐管理页渲染 `ElSwitch` 前，会先把 `show / sell / renew` 归一化成布尔值；开关事件若新旧值相同则直接短路，避免初始化阶段误写后台状态
- 套餐说明编辑采用轻量 Markdown/HTML 编辑器与预览模式，不引入额外富文本依赖
- 订单管理页使用真实后端 `order/fetch`、`order/detail`、`order/assign`、`order/paid`、`order/cancel` 与 `order/update`，支持订单列表、类型/周期/状态筛选、详情抽屉、手动分配、人工标记已支付与佣金状态维护
- 订单详情抽屉会优先展示支付成功快照（支付渠道 / 支付方法 / 平台订单号 / 商户订单号 / 实付金额 / 支付 IP）；旧订单缺字段时回退当前 `payment` 关联或以 `-` 占位
- 订单金额、佣金金额与相关拆解字段以“分”为后端真相源，前端统一在 `src/utils/orders.ts` 中格式化为“元”展示，避免后台金额口径混乱
- 订单管理页的佣金状态不再单看 `commission_status` 默认值；无真实佣金的订单统一显示“无佣金”，只有真实佣金订单才会参与“待确认 / 发放中 / 已发放 / 无效”状态流转
- 订单页新增“确认佣金”工具栏菜单，佣金状态筛选会自动透传 `is_commission=true`，确保“真实待确认订单”不会混入无佣金记录；行级操作列可直接把真实待确认订单手动确认到“发放中”
- 优惠券管理页使用真实后端 `coupon/fetch`、`coupon/generate`、`coupon/update` 与 `coupon/drop`，支持本地搜索、类型筛选、启停、删除与弹窗式新增/编辑
- 礼品卡管理页使用真实后端 `gift-card/templates`、`gift-card/create-template`、`gift-card/update-template`、`gift-card/delete-template`、`gift-card/generate-codes`、`gift-card/codes`、`gift-card/toggle-code`、`gift-card/export-codes`、`gift-card/update-code`、`gift-card/delete-code`、`gift-card/usages`、`gift-card/statistics` 与 `gift-card/types`
- 礼品卡工作台采用单页四页签结构，覆盖模板管理、兑换码管理、使用记录和统计数据；模板编辑使用分组式大抽屉，兑换码生成使用独立对话框
- 礼品卡模板的 `conditions / rewards / limits / special_config` 映射统一收敛到 `src/utils/giftCards.ts`，避免表单展示结构与提交 JSON 结构漂移
- 优惠券编辑弹窗支持金额/比例两种优惠类型、有效期范围、批量生成、自定义券码、指定周期与指定订阅限制
- 系统管理新增独立“系统管理”侧边栏分组，当前已完整实现 `#/system/config`、`#/system/themes`、`#/system/plugins`、`#/system/notices`、`#/system/payments` 与 `#/system/knowledge`
- 系统配置页使用真实后端 `config/fetch`、`config/save`、`config/testSendMail` 与 `config/setTelegramWebhook`，并按站点、安全、订阅、邀请佣金、节点、邮件、Telegram、APP、订阅模板 9 个分组组织长表单
- 主题管理页使用真实后端 `theme/getThemes`、`theme/getThemeConfig`、`theme/saveThemeConfig`、`theme/upload`，并通过 `config/save(frontend_theme)` 完成当前主题切换
- 主题配置抽屉按后端返回的动态 schema 渲染 `input / textarea / select` 字段，不在前端猜测额外配置项
- 插件管理页使用真实后端 `plugin/types`、`plugin/getPlugins`、`plugin/upload`、`plugin/install`、`plugin/uninstall`、`plugin/enable`、`plugin/disable`、`plugin/config` 与 `plugin/upgrade`
- 插件管理首屏采用“搜索 + 类型切换 + 状态筛选 + 上传入口 + 插件卡片”结构；详情抽屉负责 README 展示与动态配置编辑
- 动态插件配置按后端返回的 schema 渲染，当前已兼容 `boolean / string / text / json / select / number` 字段类型；未安装插件仅显示配置结构预览，不允许保存
- 公告管理页使用真实后端 `notice/fetch`、`notice/save`、`notice/show`、`notice/drop` 与 `notice/sort`，支持标题搜索、显隐切换、编辑弹窗、删除与排序模式
- 公告编辑弹窗继续使用轻量 Markdown/HTML 工具栏，不引入额外富文本依赖；`show / popup / tags` 会在工具层统一归一化后再回填到 UI
- 支付配置页使用真实后端 `payment/fetch`、`payment/getPaymentMethods`、`payment/getPaymentForm`、`payment/save`、`payment/show`、`payment/drop` 与 `payment/sort`，支持关键词搜索、启停、删除、新增/编辑与排序模式
- 支付编辑抽屉根据所选支付接口动态拉取真实配置字段，不在前端写死 EPay / TokenPay 等网关表单；通知地址继续以后端拼接结果为准
- 知识库管理页使用真实后端 `knowledge/fetch`、`knowledge/getCategory`、`knowledge/save`、`knowledge/show`、`knowledge/drop` 与 `knowledge/sort`，支持标题搜索、分类筛选、显隐切换、编辑弹窗、删除与排序模式
- 知识编辑弹窗继续使用轻量 Markdown/HTML 工具栏，不引入额外富文本依赖；编辑时会单独请求详情补齐 `body / language`
- `#/system/knowledge` 当前直接渲染 `SystemKnowledgeView` 真实页面，不再回退 `SystemPlaceholderView`
- 当前首页视觉基线为 Apple 风格：纯色分区、系统字体栈、单一蓝色强调和轻量层次
- 性能优化优先级高于装饰性表达，避免远程字体、全局模糊背景和固定特效层

## 依赖关系

- 依赖 `admin-frontend/Dockerfile`、`admin-frontend/Caddyfile` 与 `.github/workflows/admin-frontend-docker-publish.yml` 提供独立镜像发布能力
- 依赖 `src/api/client.ts` 处理 axios 与认证头
- 依赖 `src/utils/users.ts` 负责用户管理表单转换、筛选组装和状态计算
- 依赖 `src/utils/plans.ts` 负责套餐价格、说明渲染、排序与表单转换
- 依赖 `src/utils/orders.ts` 负责订单金额换算、状态映射、周期标签与筛选参数组装
- 依赖 `src/utils/nodeGroups.ts` 负责权限组计数归一化、本地搜索与摘要计算
- 依赖 `src/utils/coupons.ts` 负责优惠券类型映射、时间范围转换、过期状态计算与表单序列化
- 依赖 `src/utils/giftCards.ts` 负责礼品卡类型/状态映射、模板表单序列化、金额/流量换算与本地筛选逻辑
- 依赖 `src/utils/themes.ts` 负责主题列表排序、动态配置默认值回填与序列化
- 依赖 `src/utils/plugins.ts` 负责插件状态判断、README 渲染、筛选与动态配置表单序列化
- 依赖 `src/utils/payments.ts` 负责支付方式归一化、搜索过滤、排序移动与动态配置序列化
- 依赖 `src/utils/knowledge.ts` 负责知识库分类、Markdown 渲染、过滤与表单转换
- 依赖 `src/utils/notices.ts` 负责公告表单转换、内容摘要、排序与显示字段归一化
- 依赖 `src/utils/systemConfig.ts` 负责系统配置字段元信息、默认值、回填与保存序列化
- 依赖 `src/utils/routes.ts` 负责路由动作映射、匹配规则序列化、节点引用摘要与搜索过滤
- 依赖 `src/utils/nodes.ts` 负责节点在线状态、自动上线统计、父/子节点、墙状态 meta、搜索文本和筛选逻辑
- 依赖 `src/views/tickets/useTicketReplyImages.ts` 收敛工单回复区图片点击上传、拖拽上传、粘贴上传、文件校验和 Markdown 插入
- 依赖 Laravel 后端 `TicketService::reply()` 提供工单“再次回复自动重开”的统一业务语义
- 依赖 Laravel 注入的 `window.settings`
- 构建输出到 `public/assets/admin`
