Commit Graph

52 Commits

Author SHA1 Message Date
shaw
70e9329e64 feat(proxy): 统一代理配置并支持 SOCKS5H 协议
- 新增 proxyutil 包,统一 HTTP/HTTPS/SOCKS5/SOCKS5H 代理配置逻辑
- SOCKS5H 支持服务端 DNS 解析,避免本地 DNS 泄露
- 移除 ProxyStrict 宽松模式,代理失败直接返回错误不回退直连
- 前端代理管理页面支持 SOCKS5H 协议的添加/编辑/批量导入
- 补充 IPv6 地址和特殊字符密码的边界测试
2026-01-04 11:43:58 +08:00
shaw
106e59b753 Merge PR #122: feat: 用户自定义属性系统 + Wechat 字段迁移 2026-01-01 20:25:50 +08:00
Edric Li
404bf0f8d2 refactor: migrate wechat to user attributes and enhance users list
Migrate the hardcoded wechat field to the new extensible user
attributes system and improve the users management UI.

Migration:
- Add migration 019 to move wechat data to user_attribute_values
- Remove wechat field from User entity, DTOs, and API contracts
- Clean up wechat-related code from backend and frontend

UsersView enhancements:
- Add text labels to action buttons (Filter Settings, Column Settings,
  Attributes Config) for better UX
- Change status column to show colored dot + Chinese text instead of
  English text
- Add dynamic attribute columns support with batch loading
- Add column visibility settings with localStorage persistence
- Add filter settings modal for search and filter preferences
- Update i18n translations

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 18:59:38 +08:00
Edric Li
3c3fed886f feat(backend): add user custom attributes system
Add a flexible user attribute system that allows admins to define
custom fields for users (text, textarea, number, email, url, date,
select, multi_select types).

- Add Ent schemas for UserAttributeDefinition and UserAttributeValue
- Add service layer with validation logic
- Add repository layer with batch operations support
- Add admin API endpoints for CRUD and reorder operations
- Add batch API for loading attribute values for multiple users
- Add database migration (018_user_attributes.sql)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 18:58:34 +08:00
IanShaw027
c63192fcb5 fix(test): 修复 CI 测试和 lint 错误
- 为所有 mock 实现添加 GetByIDs 方法以满足 AccountRepository 接口
- 重构 account_handler.go 中的类型断言,使用类型安全的变量
- 修复 gofmt 格式问题
2026-01-01 15:16:12 +08:00
IanShaw027
48764e15a5 test(gemini): 添加 Drive API 和 OAuth 服务单元测试
- 新增 drive_client_test.go:Drive API 客户端单元测试
- 新增 gemini_oauth_service_test.go:OAuth 服务单元测试
- 重构 account_handler.go:改进 RefreshTier API 实现
- 优化 drive_client.go:增强错误处理和重试逻辑
- 完善 repository 和 service 层:支持批量 tier 刷新
- 更新迁移文件编号:017 -> 024(避免冲突)
2026-01-01 15:07:16 +08:00
IanShaw027
34bbfb5dd2 fix(lint): 修复 golangci-lint 检查错误
- 修复未检查的错误返回值 (errcheck)
- 移除未使用的 httpClient 字段 (unused)
- 修复低效赋值问题 (ineffassign)
- 使用 switch 替代 if-else 链 (staticcheck QF1003)
- 修复错误字符串首字母大写问题 (staticcheck ST1005)
- 运行 gofmt 格式化代码
2026-01-01 14:07:37 +08:00
ianshaw
7df914af06 feat(gemini): 添加 Google One 存储空间推断 Tier 功能
## 功能概述
通过 Google Drive API 获取存储空间配额来推断 Google One 订阅等级,并优化统一的配额显示系统。

## 后端改动
- 新增 Drive API 客户端 (drive_client.go)
  - 支持代理和指数退避重试
  - 处理 403/429 错误
- 添加 Tier 推断逻辑 (inferGoogleOneTier)
  - 支持 6 种 tier 类型:AI_PREMIUM, GOOGLE_ONE_STANDARD, GOOGLE_ONE_BASIC, FREE, GOOGLE_ONE_UNKNOWN, GOOGLE_ONE_UNLIMITED
- 集成到 OAuth 流程
  - ExchangeCode: 授权时自动获取 tier
  - RefreshAccountToken: Token 刷新时更新 tier (24小时缓存)
- 新增管理 API 端点
  - POST /api/v1/admin/accounts/:id/refresh-tier (单个账号刷新)
  - POST /api/v1/admin/accounts/batch-refresh-tier (批量刷新)

## 前端改动
- 更新 AccountQuotaInfo.vue
  - 添加 Google One tier 标签映射
  - 添加 tier 颜色样式 (紫色/蓝色/绿色/灰色/琥珀色)
- 更新 AccountUsageCell.vue
  - 添加 Google One tier 显示逻辑
  - 根据 oauth_type 区分显示方式
- 添加国际化翻译 (en.ts, zh.ts)
  - aiPremium, standard, basic, free, personal, unlimited

## Tier 推断规则
- >= 2TB: AI Premium
- >= 200GB: Google One Standard
- >= 100GB: Google One Basic
- >= 15GB: Free
- > 100TB: Unlimited (G Suite legacy)
- 其他/失败: Unknown (显示为 Personal)

## 优雅降级
- Drive API 失败时使用 GOOGLE_ONE_UNKNOWN
- 不阻断 OAuth 流程
- 24小时缓存避免频繁调用

## 测试
-  后端编译成功
-  前端构建成功
-  所有代码符合现有规范
2025-12-31 21:45:24 -08:00
shaw
0b6371174e fix(settings): 保存 Turnstile 设置时验证参数有效性 2025-12-31 21:11:10 +08:00
song
5844ea7e6e fix(Antigravity): 修复账号测试连接认证错误
- 新增 AntigravityGatewayService.TestConnection 方法,支持 Claude/Gemini 双协议测试
- AccountTestService 改用 AntigravityGatewayService 进行测试连接
- GetAvailableModels 为 Antigravity 账号返回 Claude + Gemini 模型列表
2025-12-30 22:42:00 +08:00
song
1ad29032d3 feat(antigravity): 添加混合调度可选功能
- 后端:账户模型添加 IsMixedSchedulingEnabled() 方法,读取 extra.mixed_scheduling
- 后端:gateway_service 和 gemini_messages_compat_service 支持混合调度逻辑
- 后端:分组创建支持指定 platform 参数
- 前端:账户创建/编辑弹窗添加混合调度开关(仅 antigravity 账户显示)
- 前端:混合调度开关添加问号图标和 tooltip 说明
- 前端:GroupSelector 支持根据 mixedScheduling 属性过滤分组
- 前端:分组创建支持选择 platform
- 测试:e2e 测试添加 ENDPOINT_PREFIX 环境变量支持混合/隔离模式测试
- 测试:删除过时的 Claude signature 测试用例
2025-12-29 09:44:39 +08:00
song
6648e6506c feat: 添加 Antigravity (Cloud AI Companion) OAuth 授权支持 2025-12-28 15:54:42 +08:00
shaw
fbdff4f34f fix: 防止订阅过期时间超出 JSON 序列化范围
问题:当分配订阅天数过大时,expires_at 年份可能超过 9999,
导致 time.Time JSON 序列化失败(RFC 3339 要求年份 <= 9999),
使后台无法显示和删除异常数据。

修复:
- handler 层添加 validity_days 最大值验证(max=36500,即100年)
- service 层添加 MaxValidityDays 和 MaxExpiresAt 双重保护
- 启动时自动修复已存在的异常数据(expires_at > 2099年)
2025-12-28 11:45:41 +08:00
IanShaw
254f12543c feat(frontend): 前端界面优化与使用统计功能增强 (#46)
* 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 方法调用
2025-12-27 10:50:25 +08:00
IanShaw027
9db52838b5 fix(backend): 适配重构后的架构修复 Gemini OAuth 集成
## 主要修改

1. **移除 model 包引用**
   - 删除所有 `internal/model` 包的 import
   - 使用 service 包中的类型定义(Account, Platform常量等)

2. **修复类型转换**
   - JSONB → map[string]any
   - 添加 mergeJSONB 辅助函数
   - 添加 Account.IsGemini() 方法

3. **更新中间件调用**
   - GetUserFromContext → GetAuthSubjectFromContext
   - 适配新的并发控制签名(传递 ID 和 Concurrency 而不是完整对象)

4. **修复 handler 层**
   - 更新 gemini_v1beta_handler.go
   - 修正 billing 检查和 usage 记录

## 影响范围
- backend/internal/service/gemini_*.go
- backend/internal/service/account_test_service.go
- backend/internal/service/crs_sync_service.go
- backend/internal/handler/gemini_v1beta_handler.go
- backend/internal/handler/gateway_handler.go
- backend/internal/handler/admin/account_handler.go
2025-12-26 22:07:55 +08:00
IanShaw027
bfcd9501c2 merge: 合并 upstream/main 解决 PR #37 冲突
- 删除 backend/internal/model/account.go 符合重构方向
- 合并最新的项目结构重构
- 包含 SSE 格式解析修复
- 更新依赖和配置文件
2025-12-26 21:56:08 +08:00
shaw
739d0ee61e fix: admin handlers 添加 DTO 转换修复 JSON 序列化
修复 PR #36 合并后部分 admin handler 直接返回 service 层对象导致
JSON 字段名为 PascalCase 而非期望的 snake_case 问题。

修复内容:
- account_handler: Refresh 接口添加 dto.AccountFromService
- openai_oauth_handler: RefreshAccountToken/CreateAccountFromOAuth 添加 dto 转换
- subscription_handler: BulkAssign 添加 dto.BulkAssignResultFromService
- usage_handler: List 接口添加 dto.UsageLogFromService 转换
- 新增 dto.BulkAssignResult 类型和对应的 mapper 函数
2025-12-26 21:22:48 +08:00
Forest
e5a77853b0 refactor: 调整项目结构为单向依赖 2025-12-26 16:45:40 +08:00
ianshaw
632318ad33 feat(backend): 添加 OAuth 能力查询接口,改进 OAuth 客户端选择逻辑
Handler 改进:
- 添加 GET /api/v1/admin/gemini/oauth/capabilities 接口
- 简化 GenerateAuthURL,redirect_uri 由服务层决定

Repository 改进:
- ExchangeCode/RefreshToken 根据 oauthType 选择正确的 OAuth 客户端
- Code Assist 始终使用内置客户端,AI Studio 使用用户配置的客户端
2025-12-26 00:11:03 -08:00
ianshaw
6682d06c99 fix(backend): 修复 golangci-lint 报告的格式和代码规范问题
- gofmt: 修复 account_handler.go, models.go, gemini_messages_compat_service.go 的格式
- staticcheck ST1005: 将 error strings 改为小写开头
2025-12-26 00:11:03 -08:00
ianshaw
46cb82bac0 feat(backend): 添加 Gemini V1beta Handler 和路由
- 新增 gemini_v1beta_handler.go: 代理原生 Google API 格式
- 更新 gemini_oauth_handler.go: 移除 redirectUri,新增 oauthType
- 更新 account_handler.go: 账户 Handler 增强
- 更新 router.go: 注册 v1beta 路由
- 更新 config.go: Gemini OAuth 通过环境变量配置
- 更新 wire_gen.go: 依赖注入
2025-12-26 00:11:03 -08:00
ianshaw
03a8ae62e5 feat(backend): 完善 Gemini OAuth Token 处理
- 修复 account_handler 中 token 字段类型转换(int64 转 string)
- 增强 Account.GetCredential 支持多种数值类型(float64, int, json.Number 等)
- 添加 Account.IsGemini() 方法用于平台判断
- 优化 refresh_token 和 scope 的空值处理
2025-12-26 00:09:46 -08:00
ianshaw
e36fb98fb9 feat(handler): 添加 Gemini OAuth Handler 和完善依赖注入
- 新增 Gemini OAuth 授权处理器
- 扩展账号和网关处理器支持 Gemini
- 注册 Gemini 相关路由
- 更新 Wire 依赖注入配置(所有层)
- 更新 Docker Compose 配置
2025-12-26 00:09:46 -08:00
Forest
eeaff85e47 refactor: 自定义业务错误 2025-12-25 21:06:40 +08:00
ianshaw
62ed5422dd feat(account): 优化批量更新实现,使用统一 SQL 合并 JSONB 字段
- 新增 BulkUpdate 仓储方法,使用单条 SQL 更新所有账户
- credentials/extra 使用 COALESCE(...) || ? 合并,只更新传入的 key
- name/proxy_id/concurrency/priority/status 只在提供时更新
- 分组绑定仍逐账号处理(需要独立操作)
- 前端优化:Base URL 留空则不修改,按勾选字段更新
- 完善 i18n 文案:说明留空不修改、批量更新行为
2025-12-24 17:16:19 -08:00
ianshaw
2e76302af7 feat(account): 添加批量编辑账户凭据功能并优化 CRS 同步
- 新增批量更新账户凭据接口(account_uuid/org_uuid/intercept_warmup_requests)
- 新增前端批量编辑模态框组件
- 优化 CRS 同步逻辑,改进 extra 字段处理
- 优化 CRS 同步 UI,添加更详细的结果展示
- 完善国际化文案(中英文)
2025-12-24 16:56:48 -08:00
ianshaw
6553828008 feat(account): 添加从 CRS 同步账户功能
- 添加账户同步 API 接口 (account_handler.go)
- 实现 CRS 同步服务 (crs_sync_service.go)
- 添加前端同步对话框组件 (SyncFromCrsModal.vue)
- 更新账户管理界面支持同步操作
- 添加账户仓库批量创建方法
- 添加中英文国际化翻译
- 更新依赖注入配置
2025-12-24 08:48:58 -08:00
shaw
876e85e7ad Merge branch 'feat/rename-go-module' 2025-12-24 21:34:37 +08:00
shaw
2e7818d688 feat(settings): 添加文档链接配置功能
- 后台系统设置新增文档链接(doc_url)配置项
- 首页顶部导航栏显示文档链接图标(条件渲染)
- Footer区域添加文档链接和GitHub链接
- 支持中英文国际化
2025-12-24 21:30:19 +08:00
Forest
836c4dda2b refactor: 重命名 go module 2025-12-24 21:07:21 +08:00
shaw
aaadd6ed04 fix(dashboard): 修复性能指标 RPM/TPM 显示为0的问题
- 修复 Admin Dashboard Handler 遗漏返回 rpm/tpm 字段
- 将性能统计时间窗口从1分钟改为5分钟平均值,数据更稳定
2025-12-24 19:58:33 +08:00
shaw
0abe322cca feat(accounts): 账户列表显示实时并发数
- 在账户列表 API 返回中添加 current_concurrency 字段
- 合并平台和类型列为 PlatformTypeBadge 组件,节省表格空间
- 新增并发状态列,显示 当前/最大 并发数,支持颜色编码
2025-12-24 15:44:45 +08:00
Forest
bbf4024dc7 refactor(usage): 移动 usage 查询到 services 2025-12-24 08:41:31 +08:00
dexcoder6
50dba656fd feat: 添加用户余额充值/退款功能 (#17)
## 功能特性

### 前端
- 在用户列表操作列添加充值和退款按钮
- 实现充值/退款对话框,支持输入金额和备注
- 从编辑用户表单中移除余额字段,防止直接修改
- 添加余额不足验证,实时显示操作后余额
- 优化备注提示词,提供多种场景示例

### 后端
- 为 redeem_codes 表添加 notes 字段(迁移文件)
- 在 UpdateUserBalance 接口添加 notes 参数支持
- 添加余额验证:金额必须大于0,操作后余额不能为负
- UpdateUser 接口移除 balance 字段处理,防止误操作
- 完整的审计日志和缓存管理

## 安全保护

- 前端:余额不足时禁用提交按钮,实时提示
- 后端:双重验证(输入金额 > 0 + 结果余额 >= 0)
- 权限:仅管理员可访问(AdminAuth 中间件)
- 审计:所有操作记录到 redeem_codes 表

## 修改文件

后端:
- backend/migrations/004_add_redeem_code_notes.sql
- backend/internal/model/redeem_code.go
- backend/internal/service/admin_service.go
- backend/internal/handler/admin/user_handler.go

前端:
- frontend/src/views/admin/UsersView.vue
- frontend/src/api/admin/users.ts
- frontend/src/i18n/locales/zh.ts
- frontend/src/i18n/locales/en.ts

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-23 16:29:57 +08:00
shaw
e53b34f321 Merge PR #15: feat: 增强用户管理功能,添加用户名、微信号和备注字段 2025-12-23 14:03:07 +08:00
shaw
7b9c3f165e feat: 账号管理新增使用统计功能
- 新增账号统计弹窗,展示30天使用数据
- 显示总费用、请求数、日均费用、日均请求等汇总指标
- 显示今日概览、最高费用日、最高请求日
- 包含费用与请求趋势图(双Y轴)
- 复用模型分布图组件展示模型使用分布
- 显示实际扣费和标准计费(标准计费以较淡颜色显示)
2025-12-23 13:42:33 +08:00
dexcoder6
0b8e84f942 feat: 增强用户管理功能,添加用户名、微信号和备注字段
- 新增User模型字段:username(用户名)、wechat(微信号)、notes(备注)
- 扩展用户搜索功能,支持通过用户名和微信号搜索
- 添加用户个人资料更新功能,用户可自行编辑用户名和微信号
- 管理员用户列表新增用户名、微信号、备注显示列
- 备注字段仅对管理员可见,增强数据安全性
- 完善中英文国际化翻译
- 修复国际化文件中重复属性的TypeScript错误

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-23 11:26:22 +08:00
shaw
6c469b42ed feat: 新增支持codex转发 2025-12-22 22:58:31 +08:00
Forest
1e1f3c0c74 ci(backend): 添加 gofmt 配置 2025-12-20 16:19:40 +08:00
Forest
1fab9204eb ci(backend): 添加 unused 配置 2025-12-20 16:12:44 +08:00
NepetaLemon
c6b3de1199 ci(backend): 添加 github actions (#10)
## 变更内容

### CI/CD
- 添加 GitHub Actions 工作流(test + golangci-lint)
- 添加 golangci-lint 配置,启用 errcheck/govet/staticcheck/unused/depguard
- 通过 depguard 强制 service 层不能直接导入 repository

### 错误处理修复
- 修复 CSV 写入、SSE 流式输出、随机数生成等未处理的错误
- GenerateRedeemCode() 现在返回 error

### 资源泄露修复
- 统一使用 defer func() { _ = xxx.Close() }() 模式

### 代码清理
- 移除未使用的常量
- 简化 nil map 检查
- 统一代码格式
2025-12-20 02:29:52 -05:00
shaw
587012396b feat: 支持创建管理员APIKEY 2025-12-20 15:11:43 +08:00
Forest
cceada7dae refactor(backend): service http ports 2025-12-20 11:57:02 +08:00
shaw
420bedd615 Merge PR #8: refactor(backend): 添加 service 缓存端口 2025-12-20 11:05:01 +08:00
shaw
0484c59ead feat: /admin/usage页面增加模型分布情况显示 2025-12-20 10:06:55 +08:00
Forest
7bbf621490 refactor(backend): 添加 service 缓存端口 2025-12-19 23:44:18 +08:00
Forest
e99b344b2b refactor(backend): 引入端口接口模式 2025-12-19 21:26:19 +08:00
shaw
d1f0902ec0 feat(account): 支持账号级别拦截预热请求
- 新增 intercept_warmup_requests 配置项,存储在 credentials 字段
- 启用后,标题生成、Warmup 等预热请求返回 mock 响应,不消耗上游 token
- 前端支持所有账号类型(OAuth、Setup Token、API Key)的开关配置
- 修复 OAuth 凭证刷新时丢失非 token 配置的问题
2025-12-19 16:39:25 +08:00
shaw
ee86dbca9d feat(account): 账号测试支持选择模型
- 新增 GET /api/v1/admin/accounts/:id/models 接口获取账号可用模型
- 账号测试弹窗新增模型选择下拉框
- 测试时支持传入 model_id 参数,不传则默认使用 Sonnet
- API Key 账号支持根据 model_mapping 映射测试模型
- 将模型常量提取到 claude 包统一管理
2025-12-19 16:00:09 +08:00
shaw
2e59998c51 fix: 代理表单字段保存时自动去除前后空格
前后端同时处理,防止因意外空格导致代理连接失败
2025-12-19 10:39:30 +08:00