diff --git a/docs/user-stories.md b/docs/user-stories.md index abc747e..3d6bb86 100644 --- a/docs/user-stories.md +++ b/docs/user-stories.md @@ -10,7 +10,7 @@ > > **v1.16(2026-08-17)· B 交互(UE)优化(rant `2026-08-17T15:50:05`).** **toast 分级**(成功 success / 错误 error / 信息 info,39 个调用点全部分级着色);**按钮 loading 态**(充值 / 加额 / 部门确认 / 上架提交 → 转圈 + 禁用,模拟反馈后恢复);**API Key 复制反馈**(复制后按钮短暂变「已复制 ✓」,1.2s 恢复,降级路径「请 Ctrl+C」);**键盘可达**(充值金额 / 加额金额·原因 / 部门名称·配额 Enter 提交;topup/raise/dept 行内卡片 Esc 关闭;打开时自动聚焦)。**rant 15:50:05 全部验收项满足,UI 美化与 UE 优化波收官(PR #38/#39/#40,docs v1.14→v1.16)。** > **v1.17(2026-08-17)· 多角度 UI/UE 深化(rant `2026-08-17T16:57:17`,分批 PR).** **A. 清除原生弹窗 ✓(PR #41)**:约 5 处原生确认/输入弹窗(key 删除、共享下架、部门删除、API Key 新建/改名、运营者/成员充值)全部改为**行内二次确认**(按钮变「确认删除?」红色态,3 秒无操作或 Esc 还原,再次点击执行)与**行内编辑**(行内展开输入框,Enter 确认 / Esc 取消);抽象可复用 `confirmInline` / `inlineForm` 组件全站统一;`grep ui/` 无原生弹窗残留。**B. 相对时间显示 ✓(PR #42)**:新增 `timeAgo` 格式化(`刚刚 / N 分钟前 / N 小时前 / 昨天 / MM-DD`,hover `title` 显示完整绝对时间),交易列表、加额申请列表、共享列表(新增「上架时间」列)与 API Key 最近使用时间统一使用。**C. 数字列对齐 ✓(PR #43)**:价格 / 点数 / 已用 / 额度 / 余额等**数字列统一右对齐 + 等宽字体**(`--mono` + `tabular-nums`,新增 `.table .num` 类,覆盖市场输入/输出价与上下文、交易 Token 用量/点数、共享已用/额度·单价·收益、成员配额/剩余、部门成员数·月分配·已用·剩余、运营者余额、加额申请点数),时间列 / 状态列保持左对齐;金额统一 `D.fmt`(整数千分位、小数 2 位)全覆盖检查无遗漏。其余 D–G(`:focus-visible` 与快捷键、行内校验错误、视图过渡、细节一致性)分批落地。**D. 键盘可达性 / 无障碍 ✓(PR #44)**:全局 `:focus-visible` 焦点环(accent 色 outline,Tab 导航清晰可见;输入类控件沿用边框高亮不叠加);**全局快捷键**:`/` 聚焦市场搜索框(输入框内不触发)、数字 **1-7** 切换侧边栏视图(仪表盘/市场/共享/钱包/交易/管理/设置,带 title 与右侧键位角标提示,Cmd/Ctrl+数字 不劫持)、Esc 关闭行内新建 Key;侧边栏导航按钮补 `title`(快捷键提示)。**E. 表单行内校验错误 ✓(PR #45)**:新增 `setFieldError(input, msg)` / `clearFieldError(input)`(输入框**红边框** + 字段下方**红字小号行内文案**,输入修正自动清除,打开表单时重置);覆盖**充值金额**(自定义金额非法)、**申请加额**(点数/原因)、**部门表单**(名称/配额/重名)、**共享上架表单**(API Key/厂商·Plan·模型·额度),提交失败不再仅依赖 toast,聚焦首个错误字段。**F. 视图切换过渡 ✓(PR #46)**:页面切换加轻量动画(`.view:not(.hidden)` **fade + 轻微上移 6px,150ms** `viewIn`,替代生硬切换);数据表格更新无闪烁(`.table tbody` **fade-in** `tbodyIn`,新增 `pulseTbody` 在静态 tbody 重渲染后重启动画,动态表格整表重建自动生效)。**G. 细节一致性 ✓(PR #47)**:一致性审计确认——**所有数字/金额统一 `D.fmt`(千分位/2 位小数)**(侧边栏余额、统计卡、表格、钱包点数格式一致)、已用/额度展示统一;表格操作按钮统一小号样式(`padding:4px 10px;font-size:12px`);**行内编辑校验统一走行内错误**(inlineForm 校验失败由 toast 改为 `setFieldError` 红边框+行内文案,API Key 改名/运营者充值/成员充值 3 处对齐 item E);子文本字号统一(11px→12px);上架 toast 单价措辞统一「点/1M(自动)」;移除 3 处「(未生效)」残留文案。**rant 16:57:17 全部验收项满足(A–G 七项,PR #41–#47),UI/UE 深化波收官。** -> **v1.18(2026-08-17)· UI/UE 第三轮多角度深化(rant `2026-08-17T18:06:09`,分批 PR).** **A. 仪表盘数据可视化 ✓(PR #48)**:纯 SVG sparkline(零外部依赖,手写 path,颜色用现有 CSS 变量):「本月点数变化」卡片按天聚合近 7 日净变化画迷你折线图(渐变填充,每点 `
| 成员 | 申请点数 | 原因 | 状态 | |||
|---|---|---|---|---|---|---|
| " + esc(r.user) + " " + esc(r.email) + " | " +
- "+" + D.fmt(r.amount) + " 点 | " + - "" + esc(r.reason) + " | " + - "" + badge(r.status, RAISE_STATUS) + " | " + - "" + (r.status === "pending" + " | ||
| " + esc(r.user) + " " + esc(r.email) + " | " +
+ '+' + D.fmt(r.amount) + " 点 | " + + "" + esc(r.reason) + " | " + + "" + badge(r.status, RAISE_STATUS) + " | " + + "" + (r.status === "pending"
? " | ||
| " + (col.render ? col.render(row) : esc(row[col.key] == null ? "" : row[col.key])) + " | "; + html += "' + + (col.render ? col.render(row) : esc(row[col.key] == null ? "" : row[col.key])) + " | "; }); html += "|||||
| " + esc(k.name) + " | " + - "" + esc(maskAtk(k.id)) + " | " +
- "" + esc(k.created) + " | " + - "" + timeCell(k.last) + " | " + - "" + (k.status === "active" ? '启用' : '' + esc(k.status || "—") + "") + " | " + - "||
| " + esc(k.name) + " | " + + "" + esc(maskAtk(k.id)) + " | " +
+ "" + esc(k.created) + " | " + + "" + timeCell(k.last) + " | " + + "" + (k.status === "active" ? '启用' : '' + esc(k.status || "—") + "") + " | " + + "||
| " + esc(e.name) + " | " + - "" + (e.dept ? esc(e.dept) : '未分配') + " | " + - '' + D.fmt(e.used) + " / " + D.fmt(e.quota) + " | " + - '' + D.fmt(e.quota - e.used) + " | " + - "" + (e.used / e.quota > 0.9 ? '接近限额' : '正常') + " | " + - "||
| " + esc(e.name) + " | " + + "" + (e.dept ? esc(e.dept) : '未分配') + " | " + + '' + D.fmt(e.used) + " / " + D.fmt(e.quota) + " | " + + '' + D.fmt(e.quota - e.used) + " | " + + "" + (e.used / e.quota > 0.9 ? '接近限额' : '正常') + " | " + + "||
| " + esc(d.name) + " | " + - '' + deptMemberCount(d.name) + " 人 | " + - '' + D.fmt(d.quota) + " 点 | " + - '' + D.fmt(used) + " 点 | " + - '' + D.fmt(d.quota - used) + " 点 | " + - "" + st + " | " + - "|
| " + esc(d.name) + " | " + + '' + deptMemberCount(d.name) + " 人 | " + + '' + D.fmt(d.quota) + " 点 | " + + '' + D.fmt(used) + " 点 | " + + '' + D.fmt(d.quota - used) + " 点 | " + + "" + st + " | " + + "|
| " + esc(u.name) + " | " + - "" + esc(u.email) + " | " + - '' + D.fmt(u.balance) + " 点 | " + - "||||
| " + esc(u.name) + " | " + + "" + esc(u.email) + " | " + + '' + D.fmt(u.balance) + " 点 | " + + "