Commit Graph
673 Commits
Author SHA1 Message Date
erio 37292367c9 feat(payment): UI improvements for admin payment pages
- Plan table: group column shows GroupBadge with platform color instead
  of raw ID, column header changed to "分组"
- Plan dialog: group info preview uses GroupBadge, removes redundant
  platform/rate fields
- Action buttons: all payment admin tables (plans, orders, providers)
  now use vertically stacked icon+text buttons matching the app style
- Added i18n keys: payment.admin.group, common.view
2026-04-07 11:36:36 +08:00
erio 6c5a2452f2 refactor(payment): unify all JSON tags to snake_case
Backend request/response structs used camelCase JSON tags while the
rest of the codebase uses snake_case (from Ent ORM entities). This
caused field name mismatches — notably the admin refund deduct_balance
field was silently ignored.

Backend: changed all camelCase JSON tags in payment handler/service
structs to snake_case (CreateOrderRequest, CreateOrderResponse,
CreatePlanRequest, UpdatePlanRequest, CreateProviderInstanceRequest,
UpdateProviderInstanceRequest, AdminProcessRefundRequest, RefundResult).

Frontend: updated all API call payloads and response field accesses
to use snake_case, removed manual camelCase conversion in
buildPlanPayload, toggleForSale, provider dialog emit, etc.
2026-04-07 11:27:00 +08:00
erio 0cca4524c9 fix(payment): webhook GET support, Stripe as single method, QR page improvements
- EasyPay webhook: add GET route + read params from URL query (fix 404)
- Stripe: expose as single "stripe" method to users, sub-types (card/link/
  alipay/wxpay) passed to PaymentIntent internally via instance config
- QR code page: use order expiresAt for countdown, add cancel button
- InstanceSelection carries SupportedTypes for provider-specific routing
2026-04-07 10:38:21 +08:00
erio e1fe15010c fix: add payment fields to UpdateSettingsRequest, remove as any casts and dead code
- Add payment fields to UpdateSettingsRequest TypeScript interface
- Remove duplicate payment_enabled_types assignment in saveSettings
- Remove all (payload as any) casts for payment fields
- Remove unused parseTypes function from providerConfig.ts
2026-04-07 03:03:09 +08:00
erio 7eaccdf125 fix: supportedTypes emit type string -> string[] 2026-04-07 02:55:28 +08:00
erio 57cb01cd49 refactor(payment): use string[] for supported_types throughout frontend+backend API
- Backend API returns/accepts supported_types as string[] (converts to/from DB comma string)
- Frontend ProviderInstance.supported_types is string[], no more parseTypes
- Remove all split/join conversions for supported_types
- payment_enabled_types also uses string[] consistently
2026-04-07 02:54:03 +08:00
erio 18107819da fix: remove unused parseTypes import, fix string[] type mismatch 2026-04-07 02:45:16 +08:00
erio 957afed0f0 fix(payment): use string[] directly for payment_enabled_types, remove all split/join conversions 2026-04-07 02:43:00 +08:00
erio 862f1c846b fix: parseTypes handles array input defensively (prevents .split crash) 2026-04-07 02:34:58 +08:00
erio d02f8a3e2f fix(payment): structured error responses + disable provider card hint overlay
- Backend: PENDING_ORDERS error uses reason+metadata per CLAUDE.md spec
- Block disabling provider when it has pending orders
- ProviderCard: remove bottom hint area, use opacity + title tooltip instead
2026-04-07 01:49:45 +08:00
erio f3ea2f9f55 fix(payment): 0 means no limit, not a default value
- min/max/daily = 0 means no limit (no enforcement)
- Quick amounts: show all when no limit set
- Amount validation: skip check when limit is 0
- Placeholder: adaptive (shows range, ≥min, ≤max, or "输入金额")
2026-04-07 01:27:44 +08:00
erio 8648950f44 fix(payment): card/link are Stripe sub-methods, not top-level providers
- Remove card/link from global allPaymentTypes (they belong inside Stripe provider)
- Resolve i18n labels for Stripe sub-methods in provider dialog and card
2026-04-07 00:46:11 +08:00
erio f906b5f1f3 feat(payment): add Link payment method for Stripe
- Add TypeLink payment type
- Stripe provider now supports card/alipay/wxpay/link
- Add Link i18n labels and PaymentMethodSelector styles
2026-04-07 00:32:25 +08:00
erio 55b526582b feat(payment): Stripe multi-method support + card type + hide single-type selector
- Add TypeCard payment type for bank card payments
- Stripe provider now supports card/alipay/wxpay payment methods
- Map payment types to Stripe payment_method_types (card, alipay, wechat_pay)
- Hide supported types selector for single-type providers (alipay/wxpay official)
- Add card i18n labels and PaymentMethodSelector styles
2026-04-07 00:23:54 +08:00
erio ec88ca6c57 fix(payment): add placeholder hint on per-provider limit inputs 2026-04-07 00:01:45 +08:00
erio b1a8252f25 feat(payment): independent callback URLs + sensitive field visibility toggle
- Split callback URLs into two independent inputs (notify/return each with own base URL + fixed path)
- Add eye icon toggle for sensitive fields (PKey etc.) to reveal/hide values
- Bump version to 0.1.108.35
2026-04-06 23:58:16 +08:00
erio 5e723b2911 fix(payment): collapsible limits, reject <=0, hint uses global config
- Limits section collapsible (default collapsed, auto-expand if has values)
- Empty input = use global config; reject values <= 0
- Input min changed from 0 to 1, placeholder changed to empty
- Hint: "留空表示使用全局配置"
2026-04-06 23:30:57 +08:00
erio 438782d536 fix(payment): split callback URL into base URL + fixed path, wider dialog
- Callback URLs now split: editable base URL + read-only fixed path
- Base URL defaults to current domain, user can change it
- notifyUrl/returnUrl computed as baseUrl + fixed webhook path
- Edit loads existing base URL by extracting it from stored notifyUrl
- Dialog width set to wide for more space
- Strict validation: all required fields must be filled on both create/edit
2026-04-06 23:15:32 +08:00
erio 34bd16ea3c fix(payment): strict validation — all required fields must be filled on edit
- Edit mode: sensitive fields show ••••••••, must remain filled to save
- Non-sensitive fields pre-filled from backend on edit
- Empty defaults (notifyUrl/returnUrl) auto-filled if backend has no value
- Submit filters out ••••••••  to keep existing backend credentials
- All required fields validated regardless of create/edit mode
2026-04-06 23:02:34 +08:00
erio eff86c9a72 fix(payment): return decrypted non-sensitive config on provider list
- Backend: add ListProviderInstancesWithConfig that decrypts config
  and masks sensitive fields (keys, secrets) as "••••••••"
- Frontend: pre-fill non-sensitive config values when editing provider
  (PID, API base URL, notify URL, return URL, channel IDs etc.)
- Sensitive fields left empty for user to re-enter if needed
2026-04-06 22:54:17 +08:00
erio 9bc8a4b4df fix(payment): reduce provider dialog width to default 2026-04-06 22:37:55 +08:00
erio c891439d2a refactor(payment): extract provider management into components + add limits UI
Components extracted from SettingsView:
- providerConfig.ts: shared constants, types, helpers
- PaymentProviderList.vue: provider card list with header
- ProviderCard.vue: single provider card with inline toggles
- ToggleSwitch.vue: reusable toggle switch component
- PaymentProviderDialog.vue: create/edit dialog with config + limits

Other changes:
- Add per-payment-type limits config UI (singleMin, singleMax, dailyLimit)
- Remove generic cid from EasyPay config (keep cidAlipay/cidWxpay only)
- Backend: remove paymentMode constants, determine mode by PaymentType
- Backend: add validateProviderRequest for create
- Add limits field to ProviderInstance type
- SettingsView reduced by ~200 lines of provider management code
2026-04-06 22:34:06 +08:00
erio bfcc487a6b feat(payment): add EasyPay dual-mode support (redirect + API)
- Backend: EasyPay provider supports paymentMode config (redirect/api)
  - redirect: builds submit.php signed URL, browser redirects to hosted page
  - api: calls mapi.php, returns payurl/qrcode (existing behavior)
- Add TypeEasyPay payment type constant
- Fix notify/return URL fallback to instance config
- Handle empty TradeNo for redirect mode (SetNillable)
- Frontend: add paymentMode dropdown in EasyPay provider config
- Auto-update supported_types when paymentMode changes
- Add easypay icon/color in PaymentMethodSelector
- Add i18n for easypay, paymentMode labels
- Rename "启用的支付方式" to "服务商"
- Migration 098: clean easypay from ENABLED_PAYMENT_TYPES
2026-04-06 20:57:45 +08:00
erio d8f2fd3c94 fix(frontend): unify purchase icon with subscriptions (CreditCardIcon)
Use the same CreditCardIcon for both "我的订阅" and "充值/订阅" sidebar
items. Remove unused RechargeSubscriptionIcon.
2026-04-06 19:57:42 +08:00
erio 335aaa733b fix(frontend): fix purchase page icon and title i18n
- Replace fill-based 1024x1024 icon with stroke-based Heroicons banknotes
  icon (24x24) matching sidebar style
- Change titleKey from purchase.title to nav.buySubscription for consistency
2026-04-06 17:40:05 +08:00
erio a6cd294ab6 feat(frontend): enrich payment settings with provider management inline
- Move payment config out of orders submenu (now 3 items: dashboard, orders, plans)
- Embed provider management directly in SettingsView Payment tab
- Add missing fields: product name prefix/suffix with preview, load balance strategy
- Add full provider CRUD dialog (EasyPay/Alipay/Wxpay/Stripe config fields)
2026-04-06 14:51:14 +08:00
erio f2b3cf628e feat(frontend): collapsible payment submenu in sidebar
Group the 4 payment admin pages under a single "订单管理" parent menu
item that expands/collapses to show sub-items with indented tree line.
2026-04-06 14:40:37 +08:00
erio 94585c3c21 refactor(frontend): split payment admin into 4 independent pages
Replace the single AdminOrdersView with 4-tab layout with separate pages:
- /admin/orders/dashboard — payment dashboard with 7/30/90 day switcher
- /admin/orders — pure order list (removed channels/plans tabs)
- /admin/orders/config — payment config + provider management
- /admin/orders/plans — subscription plans (group dropdown) + user subscriptions

Delete AdminProvidersView (merged into config page).
Update sidebar to show 4 menu items instead of 1.
2026-04-06 14:26:28 +08:00
erio acf79ff832 fix: resolve frontend TypeScript build errors
- Remove unused ReceiptIcon/SoraIcon and sora_client_enabled references
- Fix AdminOrdersView pagination response property (data → items)
- Fix PaymentView null safety for amount (use validAmount computed)
- Add missing @stripe/stripe-js dependency
2026-04-06 02:39:07 +08:00
erio 3703b5c08b refactor: migrate legacy purchase subscription to custom menu item
- Restore MigrateLegacyPurchaseURL auto-call on startup: converts old
  purchase_subscription_url into a custom menu item (id: migrated_purchase_subscription)
  and clears the legacy settings
- Delete PurchaseRouter.vue and PurchaseSubscriptionView.vue (replaced
  by existing CustomPageView.vue via custom menu system)
- /purchase route now exclusively serves the new built-in payment system
- Remove purchase_subscription_enabled from sidebar, router, settings UI,
  TypeScript types, and i18n keys
- Legacy purchase URL users will see their link as a custom menu entry
  after upgrade, editable in admin custom menu settings
2026-04-06 02:09:26 +08:00
erio 4a703cb084 fix: backward compatibility for legacy purchase subscription system
- Add PurchaseRouter.vue to dynamically render PaymentView or
  PurchaseSubscriptionView based on payment_enabled vs
  purchase_subscription_enabled settings
- Fix route guard to allow access when either payment system is enabled
- Split sidebar menu: /purchase shows for both systems, /orders only
  for built-in payment
- Remove auto-migration that forcibly disabled legacy purchase system
  on first startup (MigrateLegacyPurchaseURL)
- Add payment_enabled to PublicSettings API response so frontend can
  check both systems from a single endpoint
- Restore legacy purchase link config UI controls in admin Payment tab
- Split payment settings save to use dedicated PUT /admin/payment/config
  API instead of mixing into general settings endpoint
- Add admin payment config API functions (getConfig/updateConfig)
2026-04-06 01:51:12 +08:00
erio c69929bbb7 Merge feature/payment into release/custom-0.1.108
集成支付系统(EasyPay、Alipay、WxPay、Stripe),包含完整的订单管理、
Webhook 回调、管理后台仪表盘和用户充值/订阅流程。
2026-04-06 00:53:57 +08:00
erio db6413039a Merge tag 'v0.1.108' into release/custom-0.1.108
彻底移除 Sora 平台功能,精简代码库约 24000 行;修复渠道平台定价隔离问题。

- 完全移除 Sora 平台:删除所有 Sora 相关的后端服务、前端组件、数据库 Schema 和 ent 代码
- 移除 Sora 相关的 S3 存储、媒体管理、配额管理、生成服务等模块
- 清理前端 Sora 视图、组件、composables、API 调用和国际化文本
- 移除 Sora OAuth 选项,简化 OpenAI OAuth 流程
- 更新 antigravity User-Agent 版本号至 1.21.9

- 修复 antigravity 分组错误匹配其他平台(anthropic/gemini)定价和模型映射的问题
- 修复渠道未映射模型时 BillingModel 被错误还原导致零计费的问题

# Conflicts:
#	backend/cmd/server/VERSION
#	backend/cmd/server/wire_gen.go
#	backend/ent/group.go
#	backend/ent/mutation.go
#	backend/ent/runtime/runtime.go
#	backend/ent/schema/group.go
#	backend/internal/handler/admin/channel_handler.go
#	backend/internal/handler/admin/channel_handler_test.go
#	backend/internal/handler/gateway_handler.go
#	backend/internal/pkg/antigravity/stream_transformer.go
#	backend/internal/server/api_contract_test.go
#	backend/internal/service/billing_service.go
#	backend/internal/service/channel_service.go
#	backend/internal/service/channel_service_test.go
#	backend/internal/service/gateway_service.go
#	backend/internal/service/openai_account_scheduler.go
#	backend/internal/service/openai_gateway_chat_completions.go
#	backend/internal/service/openai_gateway_service.go
#	backend/internal/service/openai_oauth_service.go
2026-04-05 23:11:04 +08:00
erio 5cde1bcc59 fix: code quality audit — critical bugs + convention compliance
Critical:
- Refund idempotency keys now include UnixNano timestamp (alipay/wxpay)
- PaymentView passes qr/pay_url params to QR code page
- Fix dead code branch in order result handling

Quality:
- Currency symbol $ → ¥ in admin stats and refund dialog
- StripePaymentView setTimeout cleanup on unmount
- Webhook body size limited to 1MB (io.LimitReader)
- SubscriptionPlan features type documented
2026-04-05 22:17:56 +08:00
shaw a07296770c fix: remove remaining Sora references from frontend
The previous Sora removal missed several frontend references, causing
TypeScript build errors for sora_client_enabled and a missing SoraView.vue
import. Clean up all remaining Sora code from types, router, sidebar,
settings, store, and accounts API.
2026-04-05 21:26:47 +08:00
erio ff86154a03 refactor: remove unused OpenAIOAuthOptions after Sora platform removal
The options parameter only served to switch between 'openai' and 'sora'
platforms. With Sora removed, the parameter is unnecessary.
2026-04-05 17:19:27 +08:00
erio fcee67e317 fix: remove remaining unused Sora variables causing TypeScript build failure
- Remove unused accessTokenInput ref from OAuthAuthorizationFlow
- Remove unused parsedSessionToken* computed and handleValidateSessionToken
- Prefix unused options parameter in useOpenAIOAuth
2026-04-05 17:19:27 +08:00
erio 155900e62f fix: remove unused Sora references causing TypeScript build failure
- Remove handleImportAccessToken event binding from CreateAccountModal
- Remove unused imports/variables from OAuthAuthorizationFlow (useAppStore,
  parsedAccessToken*, handleImportAccessToken)
- Remove unused oauthPlatform variable from useOpenAIOAuth composable
2026-04-05 17:19:27 +08:00
erio 62e80c602d revert: completely remove all Sora functionality 2026-04-05 17:11:01 +08:00
erio b1ef9f91f2 feat: add admin payment reusable components
- AdminOrderTable: reusable order table with search, filters, pagination
- AdminOrderDetail: order detail dialog with field grid and actions
- PaymentMethodChart: horizontal bar chart for payment distribution
- TopUsersLeaderboard: ranked top users table
2026-04-05 15:06:05 +08:00
erio 64c4495ae5 feat: integrate payment system (EasyPay, Alipay, WxPay, Stripe)
Replace iframe-based external payment with native implementation:

Backend (Go):
- 5 new Ent schemas: PaymentOrder, PaymentAuditLog, PaymentChannel,
  SubscriptionPlan, PaymentProviderInstance
- 5 SQL migrations (090-094)
- Payment provider interface + registry + load balancer
- 4 provider implementations (EasyPay, Alipay, WxPay, Stripe)
- PaymentService (order lifecycle, fulfillment, refund 3-phase)
- PaymentConfigService (settings, instance/channel/plan CRUD)
- 31 API endpoints (9 user + 4 webhook + 18 admin)
- Wire DI integration

Frontend (Vue3):
- Payment types, API modules, store, router changes
- Sidebar: payment_enabled controls visibility, new menu items
- User pages: PaymentView (replace iframe), QR payment, Stripe,
  result page, order list
- Admin pages: Order management (4 tabs), provider instance mgmt
- Settings: new payment tab, removed old purchase iframe config
- i18n: full payment namespace (en + zh)

Docs:
- PAYMENT_FRONTEND_MIGRATION_PLAN.md
- PAYMENT_BACKEND_MIGRATION_PLAN.md
- PAYMENT_IMPLEMENTATION_ROADMAP.md
2026-04-05 15:06:05 +08:00
erio 066b18b405 refactor: remove unused OpenAIOAuthOptions after Sora platform removal
The options parameter only served to switch between 'openai' and 'sora'
platforms. With Sora removed, the parameter is unnecessary.
2026-04-05 13:41:51 +08:00
erio 031ca66c7e fix: remove remaining unused Sora variables causing TypeScript build failure
- Remove unused accessTokenInput ref from OAuthAuthorizationFlow
- Remove unused parsedSessionToken* computed and handleValidateSessionToken
- Prefix unused options parameter in useOpenAIOAuth
2026-04-05 04:11:30 +08:00
erio 99e5a09d89 fix: remove unused Sora references causing TypeScript build failure
- Remove handleImportAccessToken event binding from CreateAccountModal
- Remove unused imports/variables from OAuthAuthorizationFlow (useAppStore,
  parsedAccessToken*, handleImportAccessToken)
- Remove unused oauthPlatform variable from useOpenAIOAuth composable
2026-04-05 04:04:47 +08:00
erio dece8987e9 revert: completely remove all Sora functionality
Remove ALL Sora code — client, gateway, generation, S3 storage, accounts,
media, SDK, quota, scheduling, billing, OAuth, settings, and frontend UI.

Backend: 60+ files deleted/cleaned, including service layer (scheduling,
billing, token provider), handler layer (client/gateway handlers, DTOs),
repository layer (sora repos), config, wire DI, routes, domain constants.

Frontend: 14 files deleted + 29 files cleaned, including components, views,
API clients, composables, i18n keys, types, router entries.

Cloudflare challenge detection migrated from soraerror to httputil package.
Migration files retained (046/047/063/070) to preserve DB migration history.

136 files changed, ~24,300 lines removed. All tests pass.
2026-04-04 23:50:00 +08:00
erio 53afb8c540 fix: restore upstream Sora frontend components and remove leftover i18n affinity keys 2026-04-04 17:08:43 +08:00
erio c790b808dd revert: remove affinity scheduling, Claude Max cache simulation, Sora async tasks, and GDrive remnants
Remove 4 features from the release branch to keep it focused on channel management + upstream:

1. Affinity scheduling: gateway affinity flow, Redis Lua scripts, account methods,
   handler endpoints, frontend components (AffinityBadge, AffinityConfigCard)

2. Claude Max cache simulation: billing policy, tokenizer, response helpers,
   Group.SimulateClaudeMaxEnabled field, ent schema changes, frontend toggles

3. Sora async tasks: task service/worker/repo, videos handler, object storage
   abstraction, frontend components (SoraGeneratePage, SoraProgressCard, etc.),
   S3 storage admin settings

4. Google Drive remnants: gdrive constant cleanup (base revert was already done)

All tests pass. Channel management code preserved intact.
2026-04-04 16:34:17 +08:00
erio 71f61bbc47 fix: resolve 5 audit findings in channel/credits/scheduling
P0-1: Credits degraded response retry + fail-open
- Add isAntigravityDegradedResponse() to detect transient API failures
- Retry up to 3 times with exponential backoff (500ms/1s/2s)
- Invalidate singleflight cache between retries
- Fail-open after exhausting retries instead of 5h circuit break

P1-1: Fix channel restriction pre-check timing conflict
- Swap checkClaudeCodeRestriction before checkChannelPricingRestriction
- Ensures channel restriction is checked against final fallback groupID

P1-2: Add interval pricing validation (frontend + backend)
- Backend: ValidateIntervals() with boundary, price, overlap checks
- Frontend: validateIntervals() with Chinese error messages
- Rules: MinTokens>=0, MaxTokens>MinTokens, prices>=0, no overlap

P2: Fix cross-platform same-model pricing/mapping override
- Store cache keys using original platform instead of group platform
- Lookup across matching platforms (antigravity→anthropic→gemini)
- Prevents anthropic/gemini same-name models from overwriting each other
2026-04-04 11:25:01 +08:00
erio 6c718578a5 refactor(ui): extract formatCacheTokens and formatMultiplier to shared utils 2026-04-04 11:21:11 +08:00
erio 212eaa3a05 fix(ui): show token breakdown when image model uses token billing
Only display image count format when billing_mode is "image".
When channel has token pricing, show input/output/cache token details.
2026-04-04 11:19:55 +08:00