Commit Graph
238 Commits
Author SHA1 Message Date
shaw d92edc01be Merge origin/main into feat/channel-monitor-v2-ops-ui
Resolves three conflicts, all of the "both branches appended to the same
block" shape. Every one is resolved as a union of both sides; nothing from
either parent is dropped.

- handler/admin/setting_handler_update.go: keep ChannelMonitorHideThroughput
  (V2) alongside GrokDefaultTextModel / GrokCrossClientModelMapEnabled /
  GrokDefaultBaseURLMode (#5408). UpdateSettings writes every key on each
  save, so dropping either side would reset those settings to zero values.
- service/domain_constants.go: keep SettingKeyChannelMonitorHideThroughput
  and the three SettingKeyGrok* constants.
- repository/migrations_runner.go: keep the 195 checksum rule (V2) and the
  218/219/220 rules (#5408).
2026-08-09 12:11:35 +08:00
IanShaw027 b7863650ec fix(usage): prefer explicit video billing mode over image_count
Reuse shared getDisplayBillingMode so user usage rows with billing_mode=video
are not mislabeled as image when image_count is non-zero.
2026-08-08 09:45:12 +08:00
IanShaw027 59b5ac5458 feat(channel-monitor-v2): 渠道监控展示首次聚合进度
在用户端监控页显示 bootstrap 进度横幅与百分比,完成后自动消失;
bootstrap 期间加快轮询,空态文案与进度联动。
2026-08-07 11:53:25 +08:00
IanShaw027 242f2b78c2 feat(channel-monitor-v2): 统一展示成功率、首 Token、每秒 Token 与缓存率
矩阵摘要列补齐每秒 Token(TPM÷60)与缓存率;KPI/模型表/用户榜同步为
成功率·首 Token·每秒 Token·缓存率,吞吐相关列仍受 hide_throughput 控制。
2026-08-07 11:10:55 +08:00
IanShaw027 d8c5024cee feat(channel-monitor-v2): 实现用户端 Ops 风格被动监控界面
提供筛选/矩阵/趋势/排行等组件与 en/zh 文案,按 mode 切换 V1/V2 壳层,
并统一 useI18n 避免语言包未挂载时键路径裸露。
2026-08-07 11:05:32 +08:00
Wesley Liddick 1702ee1362 Merge pull request #5078 from wucm667/fix/issue-5072-subscription-expiry-label
fix(frontend): correct subscription expiry labels
2026-07-31 11:44:07 +08:00
wucm667 fb40211305 fix(frontend): correct subscription expiry labels 2026-07-30 12:47:05 +08:00
BayinForge 0ee9ea5765 fix(payment): keep subscription plan titles readable 2026-07-29 21:23:16 +08:00
Zhixuan Jiang cc62979aa7 feat: add passkey authentication 2026-07-26 09:50:28 -04:00
shaw 5374ce2a0f Merge remote-tracking branch 'origin/main' into feature/openai-live-gateway 2026-07-25 15:16:05 +08:00
song e6eb23eaac feat(openai): add Live gateway support 2026-07-25 12:50:46 +08:00
wucm667 30d146e8b5 fix(frontend): adapt affiliate copy controls for mobile 2026-07-25 04:27:19 +08:00
wjx2951874 7914433011 feat(payment): add mobile Alipay precreate deep link 2026-07-22 19:18:04 +08:00
Wesley Liddick a978d56c7b Merge pull request #4661 from J606y/fix/mobile-adaptation
fix(mobile): 修复 iOS 页面自动缩放并完善运维监控及全站移动端适配
2026-07-21 14:43:30 +08:00
J606yandClaude Fable 5 64ab08e4aa fix(mobile): 修复全站排查发现的移动端布局问题
全站排查各页面移动端表现,修复以下确认会溢出/挤压的布局:

- 分组用户倍率/RPM 上限弹窗:7 列宽表滚动容器补横向滚动(min-w-max)
- 设置页联盟自定义用户表:容器 overflow-hidden 改为 overflow-x-auto
- 模型/分组/端点分布、消费排行、用户仪表盘 5 处甜甜圈图例表:
  移动端纵向堆叠(flex-col sm:flex-row),图例表全宽并支持横向滚动
- 安装向导:步骤指示器移动端只显示序号圆点(hidden sm:inline)避免
  硬溢出,表单两列栅格移动端折叠为单列
- 设置页:支付商品名三列、Beta 策略与帮助图片两列输入行移动端折叠
- 分组创建/编辑弹窗:三个 time 输入的三列行移动端折叠(时间控件有
  固有宽度,窄屏弹窗内会硬溢出)
- 密钥页分组选择浮层:min-w-[380px] 改为视口限宽 + JS 夹取 left,
  对齐 AccountGroupsCell 的定位收敛做法

桌面端布局均保持不变。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-20 22:10:19 +08:00
superman2003 a6ecc202f0 fix(frontend): 用户侧套餐有效期单位不再把「月/周」显示成「天」
管理端表单保存的有效期单位是复数(days/weeks/months),数据库默认值
与历史数据是单数(day)。用户侧套餐卡片与订单确认面板此前只匹配单数
'month'(以及计费根本不支持的 'year'),管理端存的 'months' 永远落进
默认分支:「1 个月」的套餐被显示成「1天」(#4607),'weeks' 则会把
周数错标成天数。

后端计费 psComputeValidityDays 对 week/weeks、month/months 单复数均
按 ×7/×30 天换算,实扣是对的——这是纯显示缺陷,但直接造成「显示 1 天、
实付 1 个月」的定价误解。

修复:抽出与计费语义一一对应的 planValiditySuffix 辅助函数(单复数
归一化;month→「月/N个月」、week→「N周」、其余含未知单位一律按天,
与后端兜底一致),SubscriptionPlanCard 与 PaymentView 两处共用;
补充 zh/en 的 weeks 文案与单元/组件测试。
2026-07-20 18:40:42 +08:00
Wesley Liddick 2e5973b165 Merge pull request #4575 from Astrenix/feat/batch-image-guide-i18n
feat(frontend): 批量生图页面完整迁移至 vue-i18n
2026-07-20 15:32:21 +08:00
Wesley Liddick 2ee66c401d Merge pull request #4574 from Astrenix/fix/i18n-hardcoded-strings
fix(frontend): 补齐零星硬编码 UI 文案的国际化
2026-07-20 15:29:05 +08:00
cugxuan 3379603022 feat(subscription): show expiry times to minute 2026-07-19 22:43:35 +08:00
AstrenixandClaude Fable 5 7bbe170405 feat(frontend): migrate batch image page to vue-i18n
BatchImageGuideView carried ~140 user-visible strings outside vue-i18n:
hardcoded Chinese template strings (buttons, placeholders, tooltips,
table headers, dialog titles, empty states) plus an inline bilingual
batchImageText dictionary switched by isZhLocale() in script.

Move all of it into a new batchImage locale namespace (180 leaf keys
per language, zh/en verified key-aligned) registered in both locale
indexes, reusing 15 existing common.*/pagination.* keys. Column and
filter-option definitions become computed so language switches take
effect immediately; countable strings use vue-i18n plurals and the
three rich-text counters keep their inner bold spans via <i18n-t>
slots.

The Codex agent-instruction prompt template intentionally stays as a
plain string: it is an AI-facing prompt document containing literal
JSON braces that conflict with vue-i18n message syntax.

Verified: eslint, vue-tsc --noEmit, vite build, and the full vitest
suite (175 files / 1219 tests) all pass.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 03:12:39 +08:00
AstrenixandClaude Fable 5 3401a971a8 fix(frontend): localize stray hardcoded UI strings
Move the last few user-visible hardcoded strings into vue-i18n:

- AppHeader: "Toggle Menu" / "User Menu" aria-labels (screen readers
  read these in English regardless of locale)
- CustomPageView: "Page not found" error body
- PaymentProviderDialog: display-name example placeholder hardcoded in
  Chinese for all locales

Adds common.toggleMenu / common.userMenu / common.pageNotFound and
admin.settings.payment.customMethodDisplayNamePlaceholder to both zh
and en locales, and registers the new placeholder key in the
PaymentProviderDialog spec's i18n mock.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 02:55:50 +08:00
wucm667 08e994ad86 fix(frontend): lazy-load Stripe payment dependency 2026-07-16 23:21:58 +08:00
bestony 2157ee344b feat(keys): add optional ID column on /keys page
Expose API key ID in the keys table column settings so users can show
or hide it. Hidden by default; bump column-settings version so existing
preferences also keep ID hidden until toggled on.
2026-07-14 19:18:53 +08:00
yan9651688 3605a316af Keep usage ranges consistent across API and dashboards
Expose the active weekly subscription window through /v1/usage, calculate offsets with the same normalized page size used by queries, and keep user-facing date ranges on the browser's local calendar date.

Constraint: Preserve existing response fields and avoid new dependencies
Rejected: Keep duplicate inline date formatters | a shared local-date utility prevents the same UTC regression in both views
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Keep Offset and Limit based on the same normalized page size
Tested: go test ./internal/pkg/pagination ./internal/handler; go vet ./internal/pkg/pagination ./internal/handler; frontend 923 tests; pnpm typecheck; pnpm lint:check; pnpm build
Not-tested: Live API request against a deployed subscription
Related: #4121
2026-07-13 11:35:46 +08:00
shaw 1a3cc2a787 refactor: 重新设计用量页布局并新增延迟健康列
- /admin/usage 明细区收进单卡片:三个下划线 tab(用量明细/错误请求/用户排行) + 自适应筛选栏 + 内容
- 用户 Token 排行收编为第三个 tab:去掉独立邮箱搜索,懒挂载,点击行下钻回用量明细并回显用户
- 首Token/耗时合并为延迟列(首字/总耗时):阈值 10s/30s/60s 与 1min/3min/5min 四档配色,色条上下两段短渐变过渡(from-40% to-60%),管理端与用户端 /usage 共用
- 时长格式 ≥1min 简化为 Xm Ys、≥1h 为 Xh Ym
- UsageFilters/UsageTable/OpsErrorLogTable 增加 flat 嵌入模式(默认关闭不影响其他使用方)
2026-07-09 21:09:40 +08:00
shaw 49fb18e073 Merge origin/main into worktree/brave-valley-9578
Resolve conflict in api_key_repo.go: keep both ListAllByUserID (this PR)
and attachLastUsedIPs/latestUsageLogIPs (main), and have ListAllByUserID
attach last-used IPs so the current_concurrency sort path keeps the
last_used_ip column populated.
2026-07-09 17:17:16 +08:00
Wesley Liddick 9ba0fb3084 Merge pull request #3775 from heathermhuang/codex/grok-media-pricing-labels
fix: add Grok video pricing controls
2026-07-09 15:03:38 +08:00
Wesley Liddick a57157b9fa Merge pull request #3822 from wucm667/feat/api-key-last-used-ip
feat(api-key): 展示 API Key 最近使用 IP
2026-07-09 14:38:01 +08:00
superman2003andCursor 29a5fcd25e fix(gateway,frontend): 修复鉴权绕过与前端支付/会话缺陷
后端:
- Gemini /v1beta 鉴权中间件补齐主中间件的授权校验: API Key 的 IP 白/黑名单、
  专属分组授权、运行时过期/配额二次检查, 修复经 Gemini 端点绕过 IP ACL、
  越权访问专属分组、以及状态未刷新时的配额/有效期绕过窗口。
- 粘性会话等待计划分支改走 newSelectionResult 以 hydrate 账号凭证, 修复调度
  快照中账号凭证被剥离导致等待路径转发鉴权失败。
- SSE 流式转发客户端断开时不再 break 跳过当前事件 usage 合并, 修复少计费。
- Forward 对 nil gin.Context 的防御补齐; 上游错误体读取失败时记录日志避免静默。

前端:
- logout 将本地会话清理移入 finally, 服务端吊销失败也保证本地登出。
- Stripe 弹窗轮询改用正确的 auth_token 键并加防重入; 收到 INIT 后清除兜底
  超时定时器, onUnmounted 清理 message 监听器。
- token 刷新请求补充 30s 超时, 避免挂起导致请求队列与 loading 永久卡死。
- 路由守卫在公共设置未加载时先 await fetchPublicSettings, 避免 payment/
  risk_control 被误判为未启用而错误拦截。
- 支付状态轮询回调补充防重入与终态守卫。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-09 09:06:56 +08:00
Bestony@Homelab 5debe1db33 feat(keys): sort by current concurrency 2026-07-08 15:51:22 +08:00
wucm667 e0d149d511 feat(api-key): show last used IP 2026-07-08 15:26:54 +08:00
Heatherm Huang 4d702e3234 fix: split Grok image and video pricing 2026-07-08 13:50:49 +08:00
Turtle_Li 3c43fdec11 docs: add batch image PR readiness notes 2026-07-07 03:31:39 +08:00
Turtle_Li 1b07fe821a merge: sync batch image branch with origin main 2026-07-07 03:27:11 +08:00
Wesley Liddick d1d3400b69 Merge pull request #3645 from bestony/worktree/lucky-harbor-dbe4
feat(keys): add api key concurrency stats
2026-07-06 16:45:15 +08:00
Turtle_Li 0b729496ee fix: center batch image empty state 2026-07-06 15:39:57 +08:00
Albert Coady 27cb485d55 fix: share built-in payment method matching 2026-07-06 15:00:29 +08:00
Albert Coady 0dc6e56aae fix: harden easypay custom method validation 2026-07-06 15:00:29 +08:00
Albert Coady bf76168ba5 feat: add custom easypay payment methods 2026-07-06 15:00:29 +08:00
shaw d56e94b875 feat(payment): 订阅 CNY 换算改为独立汇率配置的显式 opt-in
- 新增 SUBSCRIPTION_USD_TO_CNY_RATE 配置(1 USD = X CNY,默认 0=关闭),
  替代复用 balance_recharge_multiplier 的隐式换算,促销倍率与订阅定价解耦
- 未配置汇率时订阅保持 price 直付的存量行为,存量部署升级零影响
- 前端确认页/原价/手续费/方式限额与后端换算条件严格镜像(rate>0 且币种为 CNY)
- 管理后台新增汇率配置输入(zh/en 文案),checkout-info 透出 subscription_usd_to_cny_rate
- 单测锁定:汇率未配置时不换算、换算使用汇率而非余额倍率、余额订单不受影响、返利仍按 USD price
2026-07-06 14:34:17 +08:00
Turtle_Li 9703ca9d33 merge: sync batch image foundation with upstream main 2026-07-06 13:40:09 +08:00
Turtle_Li d8e96f0f97 fix: bound batch image settlement retries 2026-07-06 13:33:53 +08:00
Turtle_Li 8fab636998 feat: complete batch image workflow 2026-07-06 12:22:04 +08:00
wucm667 b408edf97b fix(payment): convert subscription CNY pay amount 2026-07-06 10:56:43 +08:00
wucm667 aee9a7ba98 fix(usage): add UTF-8 BOM to CSV export 2026-07-05 08:36:15 +08:00
DaydreamCoding ebbdc70311 feat(usage): 错误请求对齐用量明细(UI/排序/筛选/列设置)
错误请求列表(/admin/usage 错误 tab、Ops 弹窗、用户端 /usage 错误 tab)
对齐用量明细的交互与信息密度。Squash of:

- feat(usage): 错误请求全面对齐用量明细(UI/列序/排序/筛选/列设置/新列)
- refactor(usage): 错误表提取共享徽章工具与 IP 批量工具条,后端排序解析归并 SetSort
- feat(usage): /admin/usage 错误请求新增分类过滤
- fix(ops): 错误列表 phase=upstream 过滤生效,守卫豁免改为显式 opt-in
- fix(ops): 错误列表用户列回退显示已删除 KEY 所有者
- fix(usage): 错误请求状态码排序对齐展示/过滤,筛选项改固定常用码
2026-07-03 23:02:27 +08:00
Wesley Liddick a32196eedd Merge pull request #3615 from DaydreamCoding/feat/usage-ip-geolocation
feat(usage): add IP geolocation lookup to usage tables
2026-07-02 16:42:06 +08:00
shaw 11a3da65c0 fix(group): harden peak-rate config handling and label peak windows with server timezone
Follow-up fixes to #3569 based on code audit:

- Expose server_timezone / server_utc_offset in public settings (and the
  __APP_CONFIG__ injection payload) and label every peak-window display
  with the server UTC offset, so users don't misread the billing window
  as browser-local time
- Unify CreateGroup/UpdateGroup peak-config sanitization via a single
  NormalizePeakRateConfig chokepoint: non-subscription groups always get
  peak fields cleared; unparseable window strings and negative
  multipliers are scrubbed when peak is disabled
- Replace hot-path time.Parse in PeakMultiplierAt with a manual HH:MM
  parser (accept set verified byte-for-byte identical to
  time.Parse("15:04") by exhaustive fuzzing) and reuse it in validation
- Revert the zero-behavior CalculateCost indirection churn in
  billing_service/gateway_service introduced by #3569
- Remove dead GetGroupPlatformMap and the duplicate deref helper in the
  admin handler package
- Share frontend peak formatting via utils/peak-rate.ts, unify the ×N
  label format, and move hardcoded Chinese tooltips to i18n keys
2026-07-02 16:11:07 +08:00
Bestony@Homelab 089a7b7fae feat(keys): add api key concurrency stats 2026-07-02 15:58:29 +08:00
DaydreamCoding 0ff93aca7a feat: add usage IP geolocation lookup 2026-07-01 21:49:49 +08:00