- 18 Apr, 2026 1 commit
-
-
erio authored
The native Alipay provider previously tried to embed the payment page URL into a QR code on the client — the URL is not a scannable payload so the QR never worked. Merchants also hit a H5 detection mismatch whenever the backend UA sniffer missed iPadOS 13+ or embedded browsers, and the popup window was too small for Alipay's standard checkout layout (QR + account-login panel on the right), forcing the user to scroll horizontally and vertically. Changes: Backend - alipay.go: drop QR-on-URL path. Use redirect-only flow — alipay.trade.page.pay for PC (returns a gateway URL the browser opens in a new window) and alipay.trade.wap.pay for H5 (returns a URL the browser jumps to). Both flows produce pages on openapi.alipaydev.com / excashier.alipay.com; the client never renders a QR itself. - payment_handler.go: add optional is_mobile bool to CreateOrderRequest so the frontend can declare the device explicitly. Server still falls back to UA sniffing when absent. Frontend - types/payment.ts, PaymentView.vue: declare is_mobile in CreateOrderRequest and pass the computed isMobileDevice() value. - providerConfig.ts: replace the two fixed POPUP_WINDOW_FEATURES constants with getPaymentPopupFeatures(), which prefers 1250×900 (Alipay's checkout footprint), clamps to window.screen.avail* and centers the popup so it never overflows on smaller laptops. - PaymentQRDialog.vue, PaymentStatusPanel.vue, StripePaymentInline.vue, PaymentView.vue: use the new helper at all popup call sites.
-
- 17 Apr, 2026 12 commits
-
-
erio authored
明文 JSON 已经是新写入的默认格式;保留 AES 密文读取仅为兼容迁移期间的旧 记录,一旦所有部署通过管理后台重存过一次即可删除。标记为 deprecated 并加 TODO,几个版本后统一清理掉:payment.Encrypt / payment.Decrypt、两处 decryptConfig 的 AES 分支、PaymentConfigService.encryptionKey 和 DefaultLoadBalancer.encryptionKey 字段。
-
erio authored
图片生成 API 返回的 base64 内联图响应经常超过 8MB 单次读取上限,被 ReadUpstreamResponseBody 拦截成 502 upstream_error。 单张 4K PNG base64 最坏约 67MB,多张候选图或 imageSize=4K 的 image_generation 一次请求能轻松到 30MB+。把默认上限提到 128MB 能覆盖 2-3 张 4K 图,相对 请求体上限 256MB 仍有缓冲;同时抽出 config.DefaultUpstreamResponseReadMaxBytes 共享常量,viper 默认值和 service 层兜底共用,消除两处同步魔法数字。 仍可通过 gateway.upstream_response_read_max_bytes 配置项覆盖。
-
erio authored
分组倍率和用户专属倍率在保存时没有校验,0 会触发计费层的 `<=0 → 1.0` 防御条款,结果订阅/余额分组按标准价扣费;完全是沉默地绕过了业务规则。 - 保存校验(admin_service):CreateGroup / UpdateGroup / BatchSetGroupRateMultipliers / UpdateUser.SyncUserGroupRates 全部要求 > 0 - 计算层(billing_service):三处 `<=0 → 1.0` 改为 `<0 → 0`;负数按 0 结算, 避免配置异常被静默按 1x 收费 - 前端:分组倍率 / 用户专属倍率输入 min 统一到 0.001 - 删除未使用的 IsFreeSubscription 方法 测试:新增 billing_service_rate_multiplier_test.go 端到端验证;更新原有锁定 旧 `<=0 → 1.0` 行为的测试。
-
erio authored
Chrome's password manager matched the apikey-type account's Base URL + API Key inputs as a login form and autofilled the last saved password by domain, so editing a Gemini account could overwrite its apikey with a Claude key that shared the same Base URL. Add autocomplete="new-password" plus data-*-ignore attributes for 1Password / LastPass / Bitwarden to opt the field out of every major password manager's autofill.
-
erio authored
Subscription-mode billing was consuming quota at TotalCost (raw) instead of ActualCost (TotalCost * RateMultiplier), so per-group rate multipliers — including free subscriptions (multiplier = 0) — were silently ignored. Switch the three subscription cost writes in buildUsageBillingCommand, finalizePostUsageBilling, and the legacy postUsageBilling fallback to ActualCost, and add a table-driven test covering 2x / 0.5x / free multipliers plus a balance-mode regression check.
-
erio authored
Without TOTP_ENCRYPTION_KEY, saved payment configs were lost on restart because the AES round-trip failed silently. Write new records as plaintext JSON; read path tries JSON first, falls back to legacy AES decrypt when a key is present, and treats unreadable values as empty so admins can re-enter them via the UI.
-
github-actions[bot] authored
-
Wesley Liddick authored
fix:修复上游账号为OpenAI API key时Claude Code调用缓存率低的问题
-
Wesley Liddick authored
refactor: extract ReadUpstreamResponseBody to deduplicate response read + too-large handling
-
Wesley Liddick authored
fix: fix outbox watermark context expiry and add in-batch group rebuild dedup
-
shaw authored
-
shaw authored
-
- 16 Apr, 2026 7 commits
-
-
Elysia authored
Each retry in the SetOutboxWatermark loop now gets its own 5s context. Previously a shared context could already be expired when the second or third attempt ran, making the retries pointless. Co-Authored-By:Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
-
Elysia authored
Fixes #1691 - pollOutbox() reused a 10s context for SetOutboxWatermark after event processing could take much longer, causing "outbox watermark write failed: context deadline exceeded". The watermark never advanced so the same 200 events were reprocessed every poll cycle, spiking CPU. Now uses an independent 5s context with up to 3 retries (200ms apart). - When multiple Codex accounts sharing the same 21-22 groups are all rate-limited in quick succession, each account_changed event triggered redundant bucket rebuild attempts for the same groups. Introduce batchSeenKey{groupID, platform} and thread a seen map through the handler chain; rebuildBucketsForPlatform skips (group, platform) pairs already rebuilt within the same poll batch (~80% fewer rebuild calls in the 5-accounts-same-groups scenario). Co-Authored-By:Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
-
Wesley Liddick authored
fix: preserve openai ws flags in scheduler cache
-
shaw authored
-
shaw authored
-
KnowSky404 authored
-
KnowSky404 authored
-
- 15 Apr, 2026 15 commits
-
-
erio authored
refactor: extract ReadUpstreamResponseBody to deduplicate upstream response read + too-large error handling Consolidates 9 call sites of resolveUpstreamResponseReadLimit + readUpstreamResponseBodyLimited + ErrUpstreamResponseBodyTooLarge error handling into a single ReadUpstreamResponseBody function with TooLargeWriter callback for API-format-specific error responses (Anthropic, OpenAI, countTokens).
-
fjl5 authored
-
github-actions[bot] authored
-
Wesley Liddick authored
修复 OpenAI 账号限流回流误判:7d 窗口可用时不因 5h 窗口为 0 回写 429
-
Wesley Liddick authored
feat(usage): add account cost display to admin dashboard and usage pages
-
Wesley Liddick authored
fix(ui): allow closing test dialog during active SSE stream
-
Wesley Liddick authored
feat(payment): balance recharge multiplier and fee rate
-
erio authored
-
erio authored
- Cost cell: change gray "A $xxx" to orange "成本 $xxx" with i18n - Remove standalone account_cost column from column settings (redundant)
-
erio authored
- UserBreakdownItem: add AccountCost field + SQL aggregation - UserBreakdownSubTable: add orange account cost column - Admin usage table: add account_cost column (after cost, default visible) - Column settings: add account_cost toggle option
-
Wesley Liddick authored
-
erio authored
-
erio authored
- Fix mock for GetModelStatsWithFilters: add account_cost column - Add assertion: GetStatsWithFilters always returns TotalAccountCost - New test: GetModelStatsAccountCostColumn verifies scan of AccountCost - New test: GetGroupStatsAccountCostColumn verifies scan of AccountCost - New test: GetStatsWithFiltersAlwaysReturnsAccountCost (no AccountID filter) - Integration test: add TotalAccountCost/TodayAccountCost assertions - Fix gofmt alignment in usage_log_types.go
-
erio authored
- Add account_cost column to dashboard aggregation tables (migration 107) - DashboardStats: add TotalAccountCost/TodayAccountCost fields - ModelStat/GroupStat: add AccountCost field with SQL aggregation - GetStatsWithFilters: always return TotalAccountCost (remove accountID filter) - Dashboard Token cards: show user(green)/cost(orange)/standard(gray) - Usage stats card: show account cost and standard below main value - Model/Group distribution tables: add orange cost column
-
erio authored
Replace dead EventSource variable with AbortController to enable cancelling fetch streams. Remove close-button disable during connecting status so users can dismiss the dialog at any time.
-
- 14 Apr, 2026 5 commits
-
-
erio authored
-
erio authored
Product name (e.g. "快代码科技工作室 100 元") should show the user's original recharge amount (limitAmount), not the fee-inclusive pay amount. The gateway receives payAmount separately for actual charging.
-
erio authored
-
erio authored
- Fix gofmt alignment in setting_handler.go, settings.go, payment_config_service.go - Add payment_balance_recharge_multiplier and payment_recharge_fee_rate to API contract test expected JSON
-
erio authored
- Show base amount (充值金额) as first line - Show fee amount with percentage when fee_rate > 0 - Show pay_amount (实付金额) in bold primary color - Show credited amount (到账金额) when different from pay_amount - Compute baseAmount and feeAmount from backend order data
-