Files
yinjianm e393b11b61 feat(admin-frontend): 完成节点与礼品卡管理工作台
补齐节点管理真实新增、编辑与排序流程,接入权限组与路由组
维护页,并支持 11 种协议的动态配置表单

开放礼品卡管理入口,交付模板、兑换码、使用记录与统计四页签
工作台,接入 gift-card 相关后台接口

将知识库、权限组与路由管理从占位页升级为真实页面,并修复侧边栏
低高度裁切问题

修复仪表盘 24h 流量排行涨跌始终为 0 的问题,改为对比昨天整日统
计并补充单元测试
2026-04-24 21:58:16 +08:00

8.3 KiB

变更提案: admin-frontend-node-group-management

元信息

类型: 功能增强
方案类型: implementation
优先级: P1
状态: 已完成
创建: 2026-04-24

1. 需求

背景

admin-frontend#/node-groups 目前仍是结构化占位页,而用户已经提供了目标截图,明确要求继续完成“权限组管理”真实工作台。现有 Laravel 后端已经开放 server/group/fetchserver/group/saveserver/group/drop,节点管理页也已接入权限组筛选,但缺少从权限组页进入节点筛选的维护闭环。

目标

  • #/node-groups 从占位页升级为真实权限组管理页面,支持列表、搜索、添加、编辑、删除。
  • 列表中直接展示权限组 ID、组名称、用户数量、节点数量,并给出符合截图习惯的操作位。
  • 补齐与 #/nodes 的联动:从权限组页可以一键带筛选跳转到节点页,节点页也能快速回到权限组维护入口。

约束条件

范围约束: 仅实现 admin-frontend 的权限组前端工作台与节点页联动,不改 Laravel 后端接口行为
技术约束: 继续使用 Vue3 + TypeScript + Element Plus + 现有 axios/adminClient 栈,不新增第三方状态或表格依赖
视觉约束: 以用户截图为直接参考,保留 Apple 化后台的克制留白、系统字体与轻量表格节奏,不套用订阅页黑色 Hero
业务约束: 后端真相源固定为 server/group/fetch、server/group/save、server/group/drop;删除失败原因以前端透传后端文案为准

验收标准

  • [√] #/node-groups 可以展示真实权限组列表,并支持关键字搜索与分页浏览。
  • [√] 页面支持新增、编辑、删除权限组;新增/编辑使用中央弹窗,删除前有明确确认。
  • [√] 节点数量支持跳转到 #/nodes 并自动带入对应权限组筛选;节点页提供回到权限组维护入口的联动按钮。
  • [√] admin-frontend 执行 npm run build 通过,产物可继续输出到 public/assets/admin

2. 方案

技术方案

  1. src/types/api.d.tssrc/api/admin.ts 中补齐权限组保存请求类型与 save/delete 封装。
  2. 新增 src/utils/nodeGroups.ts,统一处理权限组计数归一化、本地搜索和摘要计算,避免视图层堆积业务细节。
  3. 重写 NodeGroupsView.vue,采用“页头说明 + 紧凑工具条 + 白色表格工作台 + 中央编辑弹窗”的结构贴近截图。
  4. 新增 NodeGroupEditorDialog.vue 处理新增/编辑流程;节点数量使用按钮式链接跳转到 /nodes?group={id}
  5. 轻量补齐 NodesView.vue:识别路由查询中的权限组筛选,并提供“管理权限组”入口形成维护闭环。

影响范围

涉及模块:
  - admin-frontend: 权限组管理真实页、节点页筛选联动、API/类型/工具层补齐
  - .helloagents: 方案包、模块文档、CHANGELOG 与状态证据同步
预计变更文件: 8

风险评估

风险 等级 应对
后端删除接口因用户/节点/订阅占用返回失败 前端保持后端错误透传,不自行猜测失败原因
节点页联动仅靠前端路由查询,若权限组已删除会产生空筛选 页面加载后校验 query 对应分组是否存在,不存在则自动回退为“全部权限组”
新页面过度复用黑色 Hero 会与截图不一致 以截图为最高优先级,改为轻量标题区 + 高密度表格,不强行套用订阅页首屏模式

3. 技术设计(可选)

API设计

GET /server/group/fetch

  • 请求: 无
  • 响应: AdminServerGroupItem[],包含 idnameusers_countserver_count

POST /server/group/save

  • 请求: { id?: number, name: string }
  • 响应: boolean

POST /server/group/drop

  • 请求: { id: number }
  • 响应: boolean

数据模型

字段 类型 说明
id number 权限组 ID
name string 权限组名称
users_count number 绑定用户数量
server_count number 绑定节点数量

4. 核心场景

场景: 运营新增权限组

模块: admin-frontend 条件: 管理员进入 #/node-groups 行为: 点击“添加权限组”,填写组名称并提交 结果: 列表刷新并出现新的权限组记录

场景: 运营从权限组进入节点排查

模块: admin-frontend 条件: 某权限组已存在关联节点 行为: 在权限组列表点击“节点数量”跳转 结果: #/nodes 自动带入对应权限组筛选,仅展示该组关联节点


5. 技术决策

admin-frontend-node-group-management#D001: 权限组页改为截图导向的轻量工作台,而不是延续黑色 Hero

日期: 2026-04-24 状态: 采纳 背景: 用户提供的参考图就是目标界面,重点是轻量标题区、工具条和高密度表格。 选项分析:

选项 优点 缺点
A: 延续节点/订阅页的黑色 Hero 与部分已有页面一致 与当前截图不符,页面信息密度被拉低
B: 采用截图式轻量工作台 更贴近用户目标,便于高频运营维护 与部分页面的 Hero 结构不完全统一
决策: 选择方案 B
理由: 本轮任务已有明确视觉参考,参考优先级高于通用页面套路。
影响: NodeGroupsView.vue 的首屏结构与样式策略

admin-frontend-node-group-management#D002: 新增与编辑复用同一个中央弹窗

日期: 2026-04-24 状态: 采纳 背景: 后端保存接口统一为 server/group/save,截图也展示了中央编辑弹窗。 选项分析:

选项 优点 缺点
A: 新增/编辑拆成两个独立组件 职责更独立 代码重复,交互不连续
B: 统一弹窗组件按模式切换 与后端接口一致,界面行为稳定 组件需处理回填逻辑
决策: 选择方案 B
理由: 能最小化重复代码,同时贴合截图中的工作流。
影响: NodeGroupEditorDialog.vue 的设计与表单逻辑

admin-frontend-node-group-management#D003: 节点数量列承担“跳转到节点筛选”联动入口

日期: 2026-04-24 状态: 采纳 背景: 用户选择了“完整闭环”,不仅要做权限组页,还要补齐节点页联动。 选项分析:

选项 优点 缺点
A: 只做权限组页 CRUD 实现最小 无法形成节点维护闭环
B: 在节点数量列加入带筛选跳转,并让节点页识别 query 联动直接、改动范围可控 需要额外处理路由筛选同步
决策: 选择方案 B
理由: 这是当前范围内成本最低、用户价值最高的联动方式。
影响: NodeGroupsView.vueNodesView.vue

6. 成果设计

设计方向

  • 美学基调: 精密运营台账风——保留 Apple 化后台的轻薄分区与系统字体,但将视觉重心收敛到“标题、工具条、表格、弹窗”四个层级,避免营销感首屏
  • 记忆点: 大面积留白中的细线表格与圆角操作按钮,让“节点数量可跳转”的数据列成为页面最有识别度的互动点
  • 参考: 用户提供的权限组管理截图与编辑弹窗截图

视觉要素

  • 配色: 以 #ffffff / #f5f5f7 为背景层,正文使用 --xboard-text-strong--xboard-text-secondary,交互强调保持 #0071e3
  • 字体: 延续项目现有系统字体栈,不额外引入新字体;通过更克制的字号梯度和字重对比强化“台账式”阅读效率
  • 布局: 顶部使用轻标题区,正文直接进入紧凑工具条与全宽表格;编辑器保持中央对话框,不用抽屉
  • 动效: 仅保留按钮 hover、表格行内操作反馈、分页与弹窗开合的默认 Element Plus 过渡
  • 氛围: 依靠细边框、极轻阴影、圆角输入框与足够留白构成“干净但不空”的后台质感

技术约束

  • 可访问性: 搜索框、主按钮、编辑/删除操作与节点跳转入口都要保留可见焦点;危险删除继续使用明确确认文案
  • 响应式: 桌面优先显示完整表格;窄屏下工具条允许换行,底部分页与统计信息可纵向堆叠