Files
Xboard/.helloagents/context.md
T
yinjianm e847252e12 fix(api): 修复节点流量限额共享统计与父子显隐联动
统一节点流量统计与限额展示口径,节点详情新增昨日流量,
并让今日、昨日和本月使用清晰的半开时间窗口聚合

同 machine_id 或同 host 的节点现在共享当前账期已用流量,
管理端优先使用后端 traffic_limit_snapshot 展示月额度状态,
mi-node 下发的 current_used 也改为共享账期统计

新增 parent_auto_hidden 标记与父节点显隐联动服务,父节点
因自动上线或流量限额变为不可展示时会隐藏当前显示的子节点,
恢复时只恢复这批自动隐藏的子节点,避免覆盖手动操作
2026-04-29 02:24:57 +08:00

131 lines
8.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 项目上下文
## 基本信息
- 项目: Xboard-new
- 当前工作目录: `E:\code\php\Xboard-new`
- 主要栈: Laravel(PHP) + Vue3/TypeScript/Vite/Element Plus (`admin-frontend`)
## 技术上下文
- 管理端前端位于 `admin-frontend/`
- `admin-frontend` 现支持通过 `ADMIN_BUILD_OUT_DIR` 覆写构建输出目录:仓内默认仍写到 `../public/assets/admin`,容器构建可切到独立 `dist`
- 前端容器化运行采用 `admin-frontend/Dockerfile``Node 20 + Caddy` 多阶段构建),静态站点入口重定向到 `/assets/admin/`
- 前端容器会通过 `XBOARD_BACKEND_UPSTREAM``/api` 反向代理到后端 `web` 服务;compose 分支当前默认值为 `http://web:7001`
- 前端容器会通过 `XBOARD_UPLOAD_UPSTREAM``/upload/*` 去掉 `/upload` 前缀后反向代理到图片上传服务,默认值为 `https://pic.535888.xyz`
- GHCR 前端镜像发布工作流位于 `.github/workflows/admin-frontend-docker-publish.yml`,镜像名为 `ghcr.io/<owner>/xboard-admin-frontend`
- 后端镜像发布工作流位于 `.github/workflows/docker-publish.yml`,使用 `paths-ignore` 排除 `admin-frontend/**``.helloagents/**` 与前端发布 workflow;仅这些路径变化时不触发后端镜像发布,混有后端相关文件时仍会触发
- 管理端 API 通过 `window.settings.secure_path``VITE_ADMIN_PATH` 解析 `/api/v2/{secure_path}` 前缀
- 登录接口复用 `/api/v2/passport/auth/login`
- 工单回复链路当前以 `TicketService::reply()` 为统一真相源:管理员或用户再次回复已关闭工单时都会自动把工单状态改回开启,同时继续维护 `reply_status``last_reply_user_id`
- 邮件发送链路当前以 `SendEmailJob` + `MailService` 为统一入口:`send_email` 队列的单个 job 超时为 60 秒,SMTP 传输超时默认由 `MAIL_TIMEOUT=30` 控制,Redis `retry_after` 默认由 `QUEUE_RETRY_AFTER=90` 控制。
- 管理端仪表盘现已接入:
- `stat/getStats`
- `stat/getOrder`
- `stat/getTrafficRank`
- `system/getSystemStatus`
- `system/getQueueStats`
- 管理端用户管理现已接入:
- `user/fetch`
- `user/generate`
- `user/update`
- `user/dumpCSV`
- `user/sendMail`
- `user/ban`
- `user/resetSecret`
- `user/destroy`
- `plan/fetch`
- `traffic-reset/reset-user`
- 管理端节点管理现已接入:
- `server/manage/getNodes`
- `server/manage/save`
- `server/manage/sort`
- `server/manage/batchUpdate`
- `server/group/fetch`
- `server/group/save`
- `server/group/drop`
- `server/route/fetch`
- `server/route/save`
- `server/route/drop`
- `server/manage/update`
- `server/manage/copy`
- `server/manage/drop`
- `server/manage/batchDelete`
- `server/manage/checkGfw`
- `server/manage/resetTraffic`
- `server/manage/batchResetTraffic`
- 节点月流量限额由 Xboard 保存和编排:`v2_server.transfer_enable` 作为月额度,`traffic_limit_*` 字段记录启用、重置日/时间/时区和节点端运行状态;`ServerTrafficLimitService` 负责下发 `traffic_limit`、手动/定时重置、metrics 状态回写、父节点限额下线时的子节点联动显隐和通知 mi-node
- 管理端套餐管理现已接入:
- `plan/fetch`
- `plan/save`
- `plan/update`
- `plan/drop`
- `plan/sort`
- `server/group/fetch`
- 管理端订单管理现已接入:
- `order/fetch`
- `order/detail`
- `order/assign`
- `order/paid`
- `order/cancel`
- `order/update`
- 管理端礼品卡管理现已接入:
- `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`
- 管理端公告管理现已接入:
- `notice/fetch`
- `notice/save`
- `notice/show`
- `notice/drop`
- `notice/sort`
- 管理端支付配置现已接入:
- `payment/fetch`
- `payment/getPaymentMethods`
- `payment/getPaymentForm`
- `payment/save`
- `payment/show`
- `payment/drop`
- `payment/sort`
- 订单支付成功后会额外快照保存 `payment_channel / payment_method / payment_amount / payment_ip`,管理端订单详情优先展示真实支付成功信息,再回退当前支付配置
- 客户端订阅导出入口位于 `app/Http/Controllers/V1/Client/ClientController.php`,会根据 `flag` / `User-Agent` 匹配 `app/Protocols/*` 导出器
- `Stash` 订阅导出位于 `app/Protocols/Stash.php`,当前对 `AnyTLS` 采用保守兼容:仅客户端版本 `>= 3.3.0` 时导出
- 用户主题源代码当前不在仓内,仅保留 `theme/Xboard/assets/umi.js` 编译产物;涉及用户侧工单交互时,优先通过后端语义修复保证前后台一致
## 项目概述
- 主仓仍以 Laravel 为后端真相源
- `admin-frontend` 负责独立管理后台 UI 与交互逻辑
- `admin-frontend` 现在同时支持两种交付路径:仓内构建产物写回 `public/assets/admin`,或独立构建为 GHCR 静态镜像供 compose 分支部署
- `deploy/xboard-server/` 是可复制到服务器的一键部署模板,包含 `web / horizon / scheduler / admin / ws-server / redis` Compose 拓扑、`.env.example`、初始化/部署/更新/状态检查脚本和部署说明
- 订阅协议导出由 Laravel 主仓内的 `app/Protocols/*` 提供,客户端兼容问题需以对应导出器实现为准
- `public/assets/admin` 为构建产物输出位置
## 开发约定
- 管理端路由使用 Hash 模式
- 管理端当前业务路由包含 `/dashboard``/users``/tickets``/nodes``/node-groups``/node-routes``/subscriptions/plans``/subscriptions/orders``/subscriptions/coupons``/subscriptions/gift-cards``/system/config``/system/notices``/system/payments``/system/plugins``/system/themes``/system/knowledge`
- `#/nodes` 当前已升级为真实节点工作台:支持搜索、在线 / 离线筛选、显隐筛选、父/子节点筛选、墙状态筛选、分页浏览、显隐切换、自动上线托管开关、墙检测托管开关、刷新数据、复制、单节点置顶、仅对已勾选节点生效的批量修改 / 批量删除,以及 11 种协议的新增 / 编辑弹窗和排序对话框
- 节点自动上线由后端 `ServerAutoOnlineService` 统一执行,只处理 `auto_online=1` 的节点:在线 / 待同步时自动 `show=1`,离线时自动 `show=0`;父节点自动隐藏时会通过 `parent_auto_hidden` 标记隐藏当时仍显示的直接子节点,父节点自动恢复时只恢复这批子节点;管理端保存 / 开启自动上线、REST 心跳和 WebSocket 状态上报会触发当前节点即时同步,`sync:server-auto-online` 每 5 分钟继续兜底;未开启自动上线的节点继续保持手动显隐控制;墙状态为 `blocked` 或仍处于 `gfw_auto_hidden` 且未恢复正常时会否决自动显示
- 节点自动墙检测由后端 `sync:server-gfw-checks` 定时命令执行,只为开启 `gfw_check_enabled` 的父节点创建检测任务;父节点兼容 `parent_id IS NULL` 与历史 `parent_id=0` 两种表示,`gfw_check_enabled` 仅明确为 `false` 时关闭;子节点不独立检测,但可控制是否随父节点自动隐藏 / 恢复
- 节点新增 / 编辑弹窗支持配置月流量限额、重置日期、重置时间和时区;节点列表流量详情卡会展示月额度、当前已用、限额状态和下次重置。限额超额后的父节点真实下线由 mi-node 本地执行,Xboard 不通过父节点自身 `show``auto_online` 伪装下线;若超额节点是父节点,Xboard 会同步隐藏当时仍显示的直接子节点并在恢复时只恢复 `parent_auto_hidden=1` 的子节点
- Compose 部署必须确保 Laravel Scheduler 持续运行;`deploy/xboard-server/compose.yaml` 通过独立 `scheduler` 服务执行 `php artisan schedule:work`,否则自动墙检测只会在手动触发时创建任务
- Bearer Token 存储于 `sessionStorage/localStorage`
- `admin-frontend` 的视觉方向当前以 Apple 风格为基线,优先纯色分区、系统字体栈和低装饰成本
## 当前约束
- 本地静态 preview 环境默认缺少 Laravel 注入的 `window.settings` 与真实管理 API,受保护页面只能验证结构与跳转,不能替代完整联调
- 当前主工作树存在多组未提交业务改动;`compose` 分支变更需在独立 worktree 中处理,避免污染 `master`
- 后端接口契约以仓库内 Controller/Route 为准,不在前端推断字段