1. 28 Dec, 2025 2 commits
  2. 27 Dec, 2025 1 commit
    • IanShaw's avatar
      feat(frontend): 前端界面优化与使用统计功能增强 (#46) · 254f1254
      IanShaw authored
      * feat(frontend): 前端界面优化与使用统计功能增强
      
      主要改动:
      
      1. 表格布局统一优化
         - 新增 TablePageLayout 通用布局组件
         - 统一所有管理页面的表格样式和交互
         - 优化 DataTable、Pagination、Select 等通用组件
      
      2. 使用统计功能增强
         - 管理端: 添加完整的筛选和显示功能
         - 用户端: 完善 API Key 列显示
         - 后端: 优化使用统计数据结构和查询
      
      3. 账户组件优化
         - 优化 AccountStatsModal、AccountUsageCell 等组件
         - 统一进度条和统计显示样式
      
      4. 其他改进
         - 完善中英文国际化
         - 统一页面样式和交互体验
         - 优化各视图页面的响应式布局
      
      * fix(test): 修复 stubUsageLogRepo.ListWithFilters 测试 stub
      
      测试用例 GET /api/v1/usage 返回 500 是因为 stub 方法未实现,
      现在正确返回基于 UserID 过滤的日志数据。
      
      * feat(frontend): 统一日期时间显示格式
      
      **主要改动**:
      1. 增强 utils/format.ts:
         - 新增 formatDateOnly() - 格式: YYYY-MM-DD
         - 新增 formatDateTime() - 格式: YYYY-MM-DD HH:mm:ss
      
      2. 全局替换视图中的格式化函数:
         - 移除各视图中的自定义 formatDate 函数
         - 统一导入使用 @/utils/format 中的函数
         - created_at/updated_at 使用 formatDateTime
         - expires_at 使用 formatDateOnly
      
      3. 受影响的视图 (8个):
         - frontend/src/views/user/KeysView.vue
         - frontend/src/views/user/DashboardView.vue
         - frontend/src/views/user/UsageView.vue
         - frontend/src/views/user/RedeemView.vue
         - frontend/src/views/admin/UsersView.vue
         - frontend/src/views/admin/UsageView.vue
         - frontend/src/views/admin/RedeemView.vue
         - frontend/src/views/admin/SubscriptionsView.vue
      
      **效果**:
      - 日期统一显示为 YYYY-MM-DD
      - 时间统一显示为 YYYY-MM-DD HH:mm:ss
      - 提升可维护性,避免格式不一致
      
      * fix(frontend): 补充遗漏的时间格式化统一
      
      **补充修复**(基于 code review 发现的遗漏):
      
      1. 增强 utils/format.ts:
         - 新增 formatTime() - 格式: HH:mm
      
      2. 修复 4 个遗漏的文件:
         - src/views/admin/UsersView.vue
           * 删除 formatExpiresAt(),改用 formatDateTime()
           * 修复订阅过期时间 tooltip 显示格式不一致问题
      
         - src/views/user/ProfileView.vue
           * 删除 formatMemberSince(),改用 formatDate(date, 'YYYY-MM')
           * 统一会员起始时间显示格式
      
         - src/views/user/SubscriptionsView.vue
           * 修改 formatExpirationDate() 使用 formatDateOnly()
           * 保留天数计算逻辑
      
         - src/components/account/AccountStatusIndicator.vue
           * 删除本地 formatTime(),改用 utils/format 中的统一函数
           * 修复 rate limit 和 overload 重置时间显示
      
      **验证**:
      - TypeScript 类型检查通过 ✓
      - 前端构建成功 ✓
      - 所有剩余的 toLocaleString() 都是数字格式化,属于正确用法 ✓
      
      **效果**:
      - 订阅过期时间统一为 YYYY-MM-DD HH:mm:ss
      - 会员起始时间统一为 YYYY-MM
      - 重置时间统一为 HH:mm
      - 消除所有不规范的原生 locale 方法调用
      254f1254
  3. 26 Dec, 2025 1 commit
  4. 25 Dec, 2025 1 commit
    • hi_yueban's avatar
      fix: 修复 OpenAI 账号 5h/7d 使用限制显示错误的问题 (#30) · f57f12c6
      hi_yueban authored
      * fix: 修复 OpenAI 账号 5h/7d 使用限制显示错误的问题
      
      问题描述:
      - 账号管理页面中,OpenAI OAuth 账号的 5h 列显示 7 天的剩余时间
      - 7d 列却显示几小时的剩余时间
      - 根本原因: OpenAI 响应头中 primary/secondary 的实际含义与代码假设相反
      
      修复方案:
      1. 后端归一化 (openai_gateway_service.go):
         - 根据 window_minutes 动态判断哪个是 5h/7d 限制
         - 新增规范字段 codex_5h_* 和 codex_7d_*
         - 保留旧字段以兼容性
      
      2. 前端适配 (AccountUsageCell.vue):
         - 优先使用新的规范字段
         - Fallback 到旧字段时基于 window_minutes 动态判断
         - 更新 computed 属性命名
      
      3. 类型定义更新 (types/index.ts):
         - 添加新的规范字段定义
         - 更新注释说明实际语义由 window_minutes 决定
      
      🤖
      
       Generated with Claude Code and Codex collaboration
      Co-Authored-By: default avatarClaude Sonnet 4.5 <noreply@anthropic.com>
      Co-Authored-By: default avatarOpenAI Codex <noreply@openai.com>
      
      * fix: 改进窗口判断逻辑,修复两个窗口都小于阈值时的bug
      
      问题:
      当两个窗口都小于360分钟时(如 primary=180分钟,secondary=300分钟),
      之前的逻辑会导致:
      - primary5h = true, secondary5h = true
      - 5h 字段会使用 primary(错误)
      - 7d 字段没有数据(bug)
      
      修复方案:
      改用比较策略:
      1. 当两个窗口都存在时:较小的分配给5h,较大的分配给7d
      2. 当只有一个窗口时:根据大小(<=360分钟)判断是5h还是7d
      3. 确保数据不会丢失,逻辑更健壮
      
      示例:
      - Primary: 180分钟, Secondary: 300分钟
        → 5h 使用 Primary(180分钟), 7d 使用 Secondary(300分钟) ✓
      
      🤖
      
       Generated with Claude Code
      Co-Authored-By: default avatarClaude Sonnet 4.5 <noreply@anthropic.com>
      
      * fix: 修正窗口大小判断逻辑 - 不能用剩余时间判断窗口类型
      
      **严重bug修复:**
      之前的 fallback 逻辑错误地使用 reset_after_seconds 来判断窗口大小。
      
      问题示例:
      - 周限制(7d)剩余 2h → reset_after_seconds = 7200秒
      - 5h限制 剩余 4h → reset_after_seconds = 14400秒
      - 错误逻辑:7200/60 < 14400/60,把周限制当成5h 
      
      根本问题:
      - window_minutes = 窗口的总大小(300 or 10080)
      - reset_after_seconds = 距离重置的剩余时间(变化的)
      - 不能用剩余时间来判断窗口类型!
      
      修复方案:
      1. **只使用 window_minutes** 来判断窗口大小
      2. 移除错误的 reset_after_seconds fallback
      3. 如果 window_minutes 都不存在,使用传统假设
      4. 添加详细注释说明这个陷阱
      
      🤖
      
       Generated with Claude Code
      Co-Authored-By: default avatarClaude Sonnet 4.5 <noreply@anthropic.com>
      
      * fix: 修复 lint 问题 - 改进 fallback 逻辑的变量赋值
      
      问题:
      第882-883行的简单布尔赋值可能触发 ineffassign 或 staticcheck 警告:
        use5hFromSecondary = snapshot.SecondaryUsedPercent != nil
        use7dFromPrimary = snapshot.PrimaryUsedPercent != nil
      
      修复:
      改用明确的 if 语句检查任意字段是否存在,更符合代码意图:
      - 如果 secondary 的任意字段存在,将其视为 5h
      - 如果 primary 的任意字段存在,将其视为 7d
      
      这样逻辑更清晰,也避免了 lint 警告。
      
      ---------
      Co-authored-by: default avatarClaude Sonnet 4.5 <noreply@anthropic.com>
      Co-authored-by: default avatarOpenAI Codex <noreply@openai.com>
      f57f12c6
  5. 24 Dec, 2025 1 commit
  6. 23 Dec, 2025 1 commit
  7. 22 Dec, 2025 1 commit
  8. 18 Dec, 2025 1 commit