Files
new-api-key-usage/docs/design/交互设计.md
T
skycurtain 0e9db439ba docs: 收尾(阶段 8)——部署文档 + 端到端走查 + 文档状态
- docs/delivery/部署文档.md:前置条件 / 环境变量 / 一条命令链 / systemd 与 Nginx 示例 / 首次运行检查 / 运行约束(后端单实例 · 3 天窗口 · 主密钥 · 401 摘除)/ 升级 / 排查
- 从零端到端走查:清库 → db:push → 启动(空转 + QPU 基线)→ 管理面登记 → 引擎立即补一轮(984 条)→ 查看面查询(未折算「—」)→ 补录购买记录 → 金额出现 → 换算参数时间线;无 pageerror
- 8 篇设计文档状态 → 已实现(2026-09-15)
- README:状态行 / 文档地图(含 delivery)/ 下一步(部署 + 待补验与裁决清单)
- AGENTS.md:项目速览更新
2026-09-15 01:10:55 +08:00

11 KiB
Raw Blame History

交互设计

本工具的界面与页面设计——方向层(页面集合 + 职责)+ 细节层(跨页共性 + 逐页细节)。历史旧稿已删除(2026-09-14,内容已全部并入本文与 README / API 契约)。

项目 内容
状态 已实现(2026-09-15)
关联 README.md(决策与事实)· docs/design/API契约.md(数据形状依据)
范围 方向层(页面集合 + 职责)+ 细节层(跨页共性 + 逐页细节)

0. 大前提(2026-09-13)

0.1 路由分区与可见性

  • /manage 前缀 = 管理面:管理通道的页面路由
  • 无前缀 = 查看面:给使用者直接查看的页面路由
  • 管理面入口隐藏:查看面不放任何指向管理面的入口——使用者无论拥有多少查看 / 统计功能,都无法从界面中进入管理面;直连管理面 URL 则由口令门帘拦截(两层:入口找不到 + 撞门要口令)

0.2 查看面职责:纯查询(对 key 只读)

  • 查看面输入 key 仅用于查询——凭手里已登记的 key 看用量;不再触发登记 / 轮询;输入未登记的 key → 提示「未收录」(措辞归细节层)
  • key 的登记与启停全部在管理面完成——写操作只发生在管理面(2026-09-13 定,取代原「输入即注册」流程)

1. 页面集合(方向层 · 已收口)

1.1 查看面(无前缀)

页面 路由 职责 阶段
用量日志 /usage-log 指定时间范围查看模型请求日志(数据表格呈现);表格上方以数据卡片显示该时段累计用量、预估消费等汇总 一期
数据看板 /dashboard 固定时间窗口的统计视图(如模型消耗分布) 二期候选(一期可不实现)
  • key 维度:输入式(一次可输入多个——延续核心需求「合并查询」);输入未登记的 key → 提示「未收录」
  • 根路径 / 重定向到 /usage-log
  • 卡片口径:累计用量与预估消费直接呈现折算数值(延续全项目「不标注币种」的基调)

1.2 管理面(/manage 前缀)

页面 路由 职责
key 管理 /manage/api-keys 登记 / 清单 / 启停
购买记录 /manage/purchases 登记 / 编辑删除 / 核对提示
换算参数时间线 /manage/qpu 只读查看
  • 根路径 /manage 重定向到 /manage/api-keys
  • 能力边界见 API 契约 §2.2–2.4 与本文件 §3

2. 跨页共性(细节层,2026-09-13 起逐条推)

# 项 定法 状态
1 使用场景与适配 桌面优先(使用者 2–3 人、以看报表为主);不做移动适配 已定
2 视觉基调 浅色单主题(不做暗色切换);组件库默认主题 + 少量调色 已定
3 UI 组件库 naive-ui(2026-09-13 定)——成熟度 / 文档 / 主题变量系统更稳,表格与日期快捷选项能力已验证满足本项目;antdv-next 未采纳(社区新项目:上游为 React 版 antd 6、非 antdv 继任,生态与文档面未成熟) 已定
4 时间显示格式 统一到秒:2026-09-11 19:37:12(当天语境可简写 HH:mm:ss) 已定
5 金额与数字格式 分层:折算金额汇总 2 位小数 / 明细行 4 位小数;token 数与 quota 原值千分位(53,939,847);不标币种不变 已定
6 通用状态模式(加载 / 空 / 未收录 / 错误) 见下方细则(2026-09-13 定) 已定
7 导航 查看面:一期单页不做导航;管理面:侧边栏菜单 + 内容区(传统后台布局);「查看面 →」入口的位置形态随逐页细节 已定
8 表格通用交互 分页器:页码器 + 每页条数选择(20/50/100/200,默认 50);行详情:展开行(n-data-table 内置),展示完整字段 已定
9 时间范围控件 n-date-picker type="datetimerange" + 快捷项(今天 / 近 7 天 / 近 30 天);默认 = 最近 7 天 已定
10 key 输入控件与前端持久化 标签式(n-dynamic-tags),粘贴多行 / 逗号自动拆分;localStorage 记住上次输入、打开自动带出;点「查询」才发请求 已定

状态模式细则(#6,2026-09-13 定)

状态 呈现
加载中 表格 n-data-table 内置 loading;卡片区 n-skeleton
初始(未输入 key) 页面中央引导「输入你的 key 开始查询」——不渲染卡片与表格
未收录 卡片区下方 warning 提示条:「以下 key 未收录:sk-…a1b2(请联系管理员登记)」;已收录部分照常展示
时段无记录 表格空态「该时段没有记录」;卡片数值显示 0
新 key 未首同步 data_until 为 null → 卡片「数据截止」位显示「数据同步中…」
查询失败(网络 / 5xx) 页面内 error 提示条「查询失败:」+「重试」按钮
操作反馈(管理面) n-message toast(登记 / 启停 / 保存的成功与失败)

3. 逐页细节(细节层)

3.1 /usage-log(推导中)

布局(2026-09-13 定)

┌────────────────────────────────────────────────────────────┐
│ 筛选区:[key 标签输入框]  [时间范围 datetimerange]  [查询]      │
├────────────────────────────────────────────────────────────┤
│ 卡片区:┌调用次数┐ ┌Token 用量┐ ┌预估消费┐      数据截止 21:10:00 │
│        │ 1,873  │ │1,469,134│ │  23.45  │      (小字 + 悬停明细)│
│        │消费·错误│ │ 缓存 89k │ │额度 53.9M│                    │
├────────────────────────────────────────────────────────────┤
│ (如有)未收录提示条                                          │
├────────────────────────────────────────────────────────────┤
│ 明细表格(展开行详情)                                        │
│ 分页器(页码 + 每页条数)                                     │
└────────────────────────────────────────────────────────────┘
  • 「数据截止」不进卡片(它是注记不是指标):卡片区右端小字 + 悬停弹出 per-key 明细(各 key 同步进度 / 未收录 / 已停用)——meta 信息完整呈现且不挤占卡片位
  • 卡片主 / 副行:调用次数(主总行数,副「消费 X · 错误 Y」)· Token 用量(主 prompt+completion,副缓存命中)· 预估消费(主金额,副「额度记账」quota 原值,供对账)

明细列与呈现(2026-09-13 定)

  • 默认 8 列:时间(到秒)· key(token_name)· 模型 · 类型(Tag)· 输入 tokens · 输出 tokens · 消费(amount_rmb,4 位小数)· 耗时
  • 展开行(点行展开):完整字段——缓存 tokens · 流式 · request_id · content(错误详情)· 请求路径 · quota 原值 · 订阅归属完整组
  • 错误行:类型列 n-tag(消费 = 中性 / 错误 = 红),无整行底色;错误详情在展开行
  • 订阅归属:默认列展示订阅名(other.subscription_plan_title,如「Max」);完整归属(额度实况 / 期间范围)在展开行——purchases §6 的「明细展示订阅归属」完整落地

3.2 /manage/api-keys(2026-09-13 推完)

  • 清单 8 列:key 名(token_name)· 状态徽章 · 累计已用 · 累计剩余(无限额度显示「不限」)· 到期 · 登记时间 · 数据截止 · 操作;其余字段(总额度 / 模型限制 / consecutive_401s / 额度新鲜度)归展开行
  • 状态徽章三面孔:运行中(绿)· 已停用(灰,manual)· 已失效(红,auto_401,tooltip 注明「连续 401 自动摘除」);数据未首同步的状态体现在「数据截止」列(「同步中」)
  • 登记:页头「+ 登记 key」→ n-modal 弹窗(粘贴 sk-key)→ 提交;三类失败各有文案——上游拒绝该 key / 该 key 已登记 / 上游暂不可用(稍后重试);成功后 toast + 清单插入新行(log_synced_at: null → 「同步中」)
  • 启停:行内按钮;停用弹确认(n-popconfirm,防误点);启用直接执行(安全动作,成功后 toast + 行内状态更新;失败按错误码提示)
  • 「查看面 →」入口放侧边栏底部(低调,见 §2 #7)

3.3 其余页(待推)

页 重点 状态
/manage/purchases — 2026-09-13 推完
/manage/qpu — 2026-09-13 推完
口令门帘 — 2026-09-13 推完

/manage/purchases 细节(2026-09-13 定)

  • 清单 8 列:时间 · 类型(订阅 / 充值)· 实付金额 · 订阅(#N)· 期间 · 额度(quota_granted)· 备注 · 操作(编辑 · 删除;删除弹确认)
  • 表单用右侧抽屉(n-drawer):kind 单选 · paid_at · paid_amount(必填)· quota_granted(必填)· subscription_id · 期间(period_end 未结束可空)· note;校验含期间顺序(start < end)
  • 核对提示与补录:存在「观测到但未登记」时清单上方提示条「观测到 N 个未登记的订阅」;下方折叠区列出全部观测项(#N · 名称 · 日志条数 · 时间范围 · 观测额度 · 已登记 / 未登记);点「补录」开表单,预填 subscription_id 与 quota_granted(观测值),期间不预填(观测范围 ≠ 订阅期间)

/manage/qpu 细节(2026-09-13 定)

  • 表格两列:生效时间 · QPU 值(id 不显示);最新一行标「当前生效」
  • 页首说明文案:「quota → 额度美元的换算比率历史;引擎自动采样、只记变化点;当前生效值 = 最近一行」
  • 只有基线一行也属正常态(无特殊空态)

口令门帘(2026-09-13 定)

  • 形态:访问 /manage/* 未验证时 → 全屏居中卡片(口令输入 + 「进入」);进入后跳转原目标页
  • 校验:直接用任一管理面请求校验(401 即口令错)——不需新端点;口令存 sessionStorage(关标签即忘、刷新仍在),请求拦截器自动附加 X-Manage-Token
  • 错误:401 → 输入框下方「口令不正确」;不做「记住我」