Commit Graph

566 Commits

Author SHA1 Message Date
CaIon
812ab67780 refactor: replace iota with explicit values for log type constants 2025-10-15 19:54:13 +08:00
CaIon
b9c2089d37 fix 2025-10-15 19:46:06 +08:00
CaIon
31e09b960f refactor: aws 2025-10-15 16:44:33 +08:00
Xyfacai
c6175c0b46 fix: 修复视频任务不同分组可能导致补回额度计算错误 (#2030) 2025-10-13 15:17:06 +08:00
Xyfacai
b7a07e1ef7 refactor: Openai video model 移动到 dto 2025-10-13 11:45:45 +08:00
CaIon
250f10fa67 fix: mask sensitive information in error messages and refine task retrieval query 2025-10-12 12:25:11 +08:00
feitianbubu
d724f25db4 refactor: add openaiVideo and method 2025-10-11 17:05:36 +08:00
Seefs
5010f2d004 format: package name -> github.com/QuantumNous/new-api (#2017) 2025-10-11 15:30:09 +08:00
Seefs
a2d9634e70 fix: channel remark ignore issue 2025-10-10 15:40:00 +08:00
Apple\Apple
c7ab5c9a67 🔎 feat(topup): add order number search for billing history (admin and user)
Enable searching topup records by trade_no across both admin-wide and user-only views.

Frontend
- TopupHistoryModal.jsx:
  - Add search input with prefix icon (IconSearch) to filter by order number
  - Send `keyword` query param to backend; works with both endpoints:
    - Admin: GET /api/user/topup?p=1&page_size=10&keyword=...
    - User:  GET /api/user/topup/self?p=1&page_size=10&keyword=...
  - Keep endpoint auto-switching based on role (isAdmin)
  - Minor UI polish: outlined admin action button; keep Coins icon for amount

Backend
- model/topup.go:
  - Add SearchUserTopUps(userId, keyword, pageInfo)
  - Add SearchAllTopUps(keyword, pageInfo)
  - Both support pagination and `trade_no LIKE %keyword%` filtering (ordered by id desc)
- controller/topup.go:
  - GetUserTopUps / GetAllTopUps accept optional `keyword` and route to search functions when present

Routes
- No new endpoints; search is enabled via `keyword` on existing:
  - GET /api/user/topup
  - GET /api/user/topup/self

Affected files
- model/topup.go
- controller/topup.go
- web/src/components/topup/modals/TopupHistoryModal.jsx
2025-10-07 00:55:01 +08:00
Apple\Apple
01d18dcba8 feat(topup): Admin-wide topup listing and route reorganization
Allow administrators to view all platform topup orders and streamline admin-only routes.

Frontend
- TopupHistoryModal: dynamically switch endpoint by role
  - Admin → GET /api/user/topup (all orders)
  - Non-admin → GET /api/user/topup/self (own orders)
- Use shared utils `isAdmin()`; keep logic centralized and DRY
- Minor UI: set admin action button theme to outline for clarity

Backend
- model/topup.go: add GetAllTopUps(pageInfo) with pagination (ordered by id desc)
- controller/topup.go: add GetAllTopUps handler returning PageInfo response
- router/api-router.go:
  - Add admin route GET /api/user/topup (AdminAuth)
  - Move POST /api/user/topup/complete to adminRoute (keeps path stable, consolidates admin endpoints)

Security/Behavior
- Admin-only endpoints now reside under the admin route group with AdminAuth
- No behavior change for regular users; no schema changes

Affected files
- model/topup.go
- controller/topup.go
- router/api-router.go
- web/src/components/topup/modals/TopupHistoryModal.jsx
2025-10-07 00:46:47 +08:00
Apple\Apple
dec3a32397 feat: Add topup billing history with admin manual completion
Implement comprehensive topup billing system with user history viewing and admin management capabilities.

## Features Added

### Frontend
- Add topup history modal with paginated billing records
- Display order details: trade number, payment method, amount, money, status, create time
- Implement empty state with proper illustrations
- Add payment method column with localized display (Stripe, Alipay, WeChat)
- Add admin manual completion feature for pending orders
- Add Coins icon for recharge amount display
- Integrate "Bills" button in RechargeCard header
- Optimize code quality by using shared utility functions (isAdmin)
- Extract constants for status and payment method mappings
- Use React.useMemo for performance optimization

### Backend
- Create GET `/api/user/topup/self` endpoint for user topup history with pagination
- Create POST `/api/user/topup/complete` endpoint for admin manual order completion
- Add `payment_method` field to TopUp model for tracking payment types
- Implement `GetUserTopUps` method with proper pagination and ordering
- Implement `ManualCompleteTopUp` with transaction safety and row-level locking
- Add application-level mutex locks to prevent concurrent order processing
- Record payment method in Epay and Stripe payment flows
- Ensure idempotency and data consistency with proper error handling

### Internationalization
- Add i18n keys for Chinese (zh), English (en), and French (fr)
- Support for billing-related UI text and status messages

## Technical Improvements
- Use database transactions with FOR UPDATE row-level locking
- Implement sync.Map-based mutex for order-level concurrency control
- Proper error handling and user-friendly toast notifications
- Follow existing codebase patterns for empty states and modals
- Maintain code quality with extracted render functions and constants

## Files Changed
- Backend: controller/topup.go, controller/topup_stripe.go, model/topup.go, router/api-router.go
- Frontend: web/src/components/topup/modals/TopupHistoryModal.jsx (new), web/src/components/topup/RechargeCard.jsx, web/src/components/topup/index.jsx
- i18n: web/src/i18n/locales/{zh,en,fr}.json
2025-10-07 00:22:45 +08:00
Seefs
b65e271971 Merge branch 'main-upstream' into pr/custom-currency-1923
# Conflicts:
#	web/src/components/settings/personal/cards/AccountManagement.jsx
#	web/src/components/table/channels/modals/EditChannelModal.jsx
#	web/src/hooks/channels/useChannelsData.jsx
#	web/src/hooks/common/useSidebar.js
#	web/src/i18n/locales/fr.json
#	web/src/pages/Setting/Operation/SettingsGeneral.jsx
2025-10-02 20:30:48 +08:00
Seefs
f3477cb267 fix: blob type 2025-09-30 12:40:05 +08:00
Seefs
9e55266383 fix: personal setting 2025-09-30 12:26:24 +08:00
Seefs
e26c794742 Merge branch 'main-upstream' into feature/passkey
# Conflicts:
#	web/src/components/settings/PersonalSetting.jsx
#	web/src/i18n/locales/en.json
#	web/src/i18n/locales/zh.json
2025-09-30 12:15:20 +08:00
t0ng7u
8294a76bc2 💱 feat(settings): introduce site-wide quota display type (USD/CNY/TOKENS/CUSTOM)
Replace the legacy boolean “DisplayInCurrencyEnabled” with an injected, type-safe
configuration `general_setting.quota_display_type`, and wire it through the
backend and frontend.

Backend
- Add `QuotaDisplayType` to `operation_setting.GeneralSetting` with injected
  registration via `config.GlobalConfig.Register("general_setting", ...)`.
  Helpers: `IsCurrencyDisplay()`, `IsCNYDisplay()`, `GetQuotaDisplayType()`.
- Expose `quota_display_type` in `/api/status` and keep legacy
  `display_in_currency` for backward compatibility.
- Logger: update `LogQuota` and `FormatQuota` to support USD/CNY/TOKENS. When
  CNY is selected, convert using `operation_setting.USDExchangeRate`.
- Controllers:
  - `billing`: compute subscription/usage amounts based on the selected type
    (USD: divide by `QuotaPerUnit`; CNY: USD→CNY; TOKENS: keep raw tokens).
  - `topup` / `topup_stripe`: treat inputs as “amount” for USD/CNY and as
    token-count for TOKENS; adjust min topup and pay money accordingly.
  - `misc`: include `quota_display_type` in status payload.
- Compatibility: in `model/option.UpdateOption`, map updates to
  `DisplayInCurrencyEnabled` → `general_setting.quota_display_type`
  (true→USD, false→TOKENS). Keep exporting the legacy key in `OptionMap`.

Frontend
- Settings: replace the “display in currency” switch with a Select
  (`general_setting.quota_display_type`) offering USD / CNY / Tokens.
  Provide fallback mapping from legacy `DisplayInCurrencyEnabled`.
- Persist `quota_display_type` to localStorage (keep `display_in_currency`
  for legacy components).
- Rendering helpers: base all quota/price rendering on `quota_display_type`;
  use `usd_exchange_rate` for CNY symbol/values.
- Pricing page: default view currency follows site display type (USD/CNY),
  while TOKENS mode still allows per-view currency toggling when needed.

Notes
- No database migrations required.
- Legacy clients remain functional via compatibility fields.
2025-09-29 23:23:31 +08:00
Seefs
1599a8403f feat: passkey 2025-09-29 17:45:09 +08:00
CaIon
6ca88d1699 fix(models): increase varchar length for TaskID and Username fields #1905 2025-09-29 16:45:46 +08:00
Seefs
bd6f4dee73 feat: allow stripe promotion code 2025-09-27 15:43:12 +08:00
creamlike1024
d21886b9fb Merge branch 'alpha' into imageratio-and-audioratio-edit 2025-09-15 14:12:24 +08:00
CaIon
9e17df3f74 fix: update references from setting to system_setting for ServerAddress 2025-09-13 15:27:41 +08:00
CaIon
c47d9fb5b5 feat(payment): add payment settings configuration and update payment methods handling 2025-09-12 19:29:34 +08:00
CaIon
e53cbd96ad fix(channel): implement per-channel locking to ensure thread-safe updates in multi-key mode 2025-09-03 15:52:54 +08:00
t0ng7u
14af08750f feat(sync): multi-language sync wizard, backend locale support, and conflict modal UX improvements
Frontend (web)
- ModelsActions.jsx
  - Replace “Sync Official” with “Sync” and open a new two-step SyncWizard.
  - Pass selected locale through to preview, sync, and overwrite flows.
  - Keep conflict resolution flow; inject locale into overwrite submission.

- New: models/modals/SyncWizardModal.jsx
  - Two-step wizard: (1) method selection (config-sync disabled for now), (2) language selection (en/zh/ja).
  - Horizontal, centered Radio cards; returns { option, locale } via onConfirm.

- UpstreamConflictModal.jsx
  - Add search input (model fuzzy search) and native pagination.
  - Column header checkbox now only applies to rows in the current filtered result.
  - Fix “Cannot access ‘filteredDataSource’ before initialization”.
  - Refactor with useMemo/useCallback; extract helpers to remove duplicated logic:
    - getPresentRowsForField, getHeaderState, applyHeaderChange
  - Minor code cleanups and stability improvements.

- i18n (en.json)
  - Add strings for the sync wizard and related actions (Sync, Sync Wizard, Select method/source/language, etc.).
  - Adjust minor translations.

Hooks
- useModelsData.jsx
  - Extend previewUpstreamDiff, syncUpstream, applyUpstreamOverwrite to accept options with locale.
  - Send locale via query/body accordingly.

Backend (Go)
- controller/model_sync.go
  - Accept locale from query/body and resolve i18n upstream URLs.
  - Add SYNC_UPSTREAM_BASE for upstream base override (default: https://basellm.github.io/llm-metadata).
  - Make HTTP timeouts/retries/limits configurable:
    - SYNC_HTTP_TIMEOUT_SECONDS, SYNC_HTTP_RETRY, SYNC_HTTP_MAX_MB
  - Add ETag-based caching and support both envelope and pure array JSON formats.
  - Concurrently fetch vendors and models; improve error responses with locale and source URLs.
  - Include source meta (locale, models_url, vendors_url) in success payloads.

Notes
- No breaking changes expected.
- Lint passes for touched files.
2025-09-02 18:49:37 +08:00
t0ng7u
d15b31ab5c 🧹 refactor(db): remove legacy models/vendors index cleanup logic
- Delete dropIndexIfExists helper from `model/main.go`
- Remove all calls to dropIndexIfExists in `migrateDB` and `migrateDBFast`
- Drop related comments and MySQL-only DROP INDEX code paths
- Keep GORM AutoMigrate as the sole migration path for `Model` and `Vendor`

Why:
- Simplifies migrations and avoids destructive index drops at startup
- Prevents noisy MySQL 1091 errors and vendor-specific branches
- Aligns with composite unique indexes (uk_model_name_delete_at, uk_vendor_name_delete_at)

Impact:
- No expected runtime behavior change; schema remains managed by GORM
- Legacy single-column unique indexes (if any) will no longer be auto-dropped
- Safe across MySQL/PostgreSQL/SQLite; MySQL Chinese charset checks remain intact

Verification:
- Lint passed for `model/main.go`
- Confirmed no remaining `DROP INDEX` or `dropIndexIfExists` references
2025-09-02 02:24:17 +08:00
t0ng7u
54f118d9ba feat(models-sync): official upstream sync with conflict resolution UI, opt‑out flag, and backend resiliency
Backend
- Add endpoints:
  - GET /api/models/sync_upstream/preview — diff preview (filters out models with sync_official = 0)
  - POST /api/models/sync_upstream — apply sync (create missing; optionally overwrite selected fields)
- Respect opt‑out: skip models with sync_official = 0 in both preview and apply
- Return detailed stats: created_models, created_vendors, updated_models, skipped_models, plus created_list / updated_list
- Add model.Model.SyncOfficial (default 1); auto‑migrated by GORM
- Make HTTP fetching robust:
  - Shared http.Client (connection reuse) with 3x exponential backoff retry
  - 10MB response cap; keep existing IPv4‑first for *.github.io
- Vendor handling:
  - New ensureVendorID helper (cache lookup → DB lookup → create), reduces round‑trips
  - Transactional overwrite to avoid partial updates
- Small cleanups and clearer helpers (containsField, coalesce, chooseStatus)

Frontend
- ModelsActions: add “Sync official” button with Popover (p‑2) explaining community contribution; loading = syncing || previewing; preview → conflict modal → apply flow
- New UpstreamConflictModal:
  - Per‑field columns (description/icon/tags/vendor/name_rule/status) with column‑level checkbox to select all
  - Cell with Checkbox + Tag (“Click to view differences”) and Popover (p‑2) showing Local vs Official values
  - Auto‑hide columns with no conflicts; responsive width; use native Semi Modal footer
  - Full i18n coverage
- useModelsData: add syncing/previewing states; new methods previewUpstreamDiff, applyUpstreamOverwrite, syncUpstream; refresh vendors/models after apply
- EditModelModal: add “Participate in official sync” switch; persisted as sync_official
- ModelsColumnDefs: add “Participate in official sync” column

i18n
- Add missing English keys for the new UI and messages; fix quoting issues

Refs
- Upstream metadata: https://github.com/basellm/llm-metadata
2025-09-02 02:04:22 +08:00
Seefs
06785c019f feat: add channel remark #1710 2025-09-01 16:23:29 +08:00
IcedTangerine
5bb732394f Merge pull request #1672 from feitianbubu/pr/fix-mysql-default-false
fix: prevent loop auto-migrate with bool default false
2025-08-31 15:06:37 +08:00
creamlike1024
d2dcd8beb3 Merge branch 'alpha' of github.com:x-Ai/new-api into x-Ai-alpha 2025-08-31 14:03:17 +08:00
t0ng7u
6d7c00634c 🐛 fix(db): rename composite unique indexes to avoid drop/recreate on restart
- Model: rename `uk_model_name` -> `uk_model_name_delete_at`
  (composite on `model_name` + `deleted_at`)
- Vendor: rename `uk_vendor_name` -> `uk_vendor_name_delete_at`
  (composite on `name` + `deleted_at`)
- Keep legacy cleanup in `model/main.go` to drop old index names
  (`uk_model_name`, `model_name`, `uk_vendor_name`, `name`) for compatibility.

Result: idempotent GORM migrations and no unnecessary index churn on MySQL restarts.

Files:
- `model/model_meta.go`
- `model/vendor_meta.go`
2025-08-31 13:00:28 +08:00
F。
d0d6168e2f 顶栏和侧边栏管理
增加用户体验
2025-08-31 07:07:40 +08:00
creamlike1024
2875dbba10 feat: 图像倍率,音频倍率和音频补全倍率配置 2025-08-30 23:28:09 +08:00
t0ng7u
aee5b8caa7 feat(pricing): add default vendor icons with LobeHub color support
- Add defaultVendorIcons mapping for major AI vendors
- Update getOrCreateVendor to automatically set vendor icons
- Add getDefaultVendorIcon helper function
- Support LobeHub icons Color variants (e.g., Claude.Color, Gemini.Color)
- Fix issue where default vendors were created without icons

This ensures that when new models are encountered, their vendors
will be created with appropriate colored icons for better UI display.

Affected vendors include:
- OpenAI, Anthropic, Google, Moonshot, 智谱, 阿里巴巴
- DeepSeek, MiniMax, 百度, 讯飞, 腾讯, Cohere
- Cloudflare, 360, 零一万物, Jina, Mistral, xAI
- Meta, 字节跳动, 快手, 即梦, Vidu, Microsoft/Azure
2025-08-29 23:42:33 +08:00
IcedTangerine
4bf9ef5579 Merge pull request #1564 from feitianbubu/pr/init-default-vendor
feat: init default vendor
2025-08-29 19:48:20 +08:00
CaIon
9e4c4d3bd1 fix(channel): ensure thread-safe polling with channel-specific lock 2025-08-28 16:34:23 +08:00
feitianbubu
d47779b0a3 fix: prevent loop auto-migrate with bool default false 2025-08-27 12:33:56 +08:00
iszcz
d904f9b486 task_relay_info 2025-08-25 18:01:10 +08:00
CaIon
a69f166e9e feat: add SaveWithoutKey method to Channel and update status saving logic 2025-08-25 11:20:16 +08:00
Nekohy
82c032e8c3 fix: log name 2025-08-24 01:32:19 +08:00
Nekohy
2d1512096a feats:add custom headers override 2025-08-24 01:02:23 +08:00
CaIon
4e3f008ae9 fix: update token usage calculation 2025-08-16 19:11:15 +08:00
CaIon
07903b0a8a refactor: improve logging for channel operations with detailed context 2025-08-15 14:15:03 +08:00
CaIon
f6f9e73fa3 refactor: improve channel base URL handling and enhance RelayInfo logging 2025-08-14 22:15:18 +08:00
CaIon
c9e9a24e99 refactor: centralize logging and update resource initialization
This commit refactors the logging mechanism across the application by replacing direct logger calls with a centralized logging approach using the `common` package. Key changes include:

- Replaced instances of `logger.SysLog` and `logger.FatalLog` with `common.SysLog` and `common.FatalLog` for consistent logging practices.
- Updated resource initialization error handling to utilize the new logging structure, enhancing maintainability and readability.
- Minor adjustments to improve code clarity and organization throughout various modules.

This change aims to streamline logging and improve the overall architecture of the codebase.
2025-08-14 21:10:04 +08:00
CaIon
97ea8b6560 refactor: Introduce pre-consume quota and unify relay handlers
This commit introduces a major architectural refactoring to improve quota management, centralize logging, and streamline the relay handling logic.

Key changes:
- **Pre-consume Quota:** Implements a new mechanism to check and reserve user quota *before* making the request to the upstream provider. This ensures more accurate quota deduction and prevents users from exceeding their limits due to concurrent requests.

- **Unified Relay Handlers:** Refactors the relay logic to use generic handlers (e.g., `ChatHandler`, `ImageHandler`) instead of provider-specific implementations. This significantly reduces code duplication and simplifies adding new channels.

- **Centralized Logger:** A new dedicated `logger` package is introduced, and all system logging calls are migrated to use it, moving this responsibility out of the `common` package.

- **Code Reorganization:** DTOs are generalized (e.g., `dalle.go` -> `openai_image.go`) and utility code is moved to more appropriate packages (e.g., `common/http.go` -> `service/http.go`) for better code structure.
2025-08-14 20:05:06 +08:00
CaIon
219ed0d1cf fix(database): improve MySQL Chinese character support validation 2025-08-12 16:31:00 +08:00
CaIon
a423ee3dd1 feat(database): enhance MySQL support for Chinese characters
- Added a check for MySQL charset/collation to ensure compatibility with Chinese characters during database initialization.
- Updated SQLite busy timeout from 5000ms to 30000ms for improved performance.
- Removed commented-out PostgreSQL migration logic for clarity.
2025-08-12 14:12:11 +08:00
feitianbubu
5520bf4dbe feat: init default vendor 2025-08-11 16:47:12 +08:00
t0ng7u
ec006d3a67 🚀 perf: optimize model management APIs, unify pricing types as array, and remove redundancies
Backend
- Add GetBoundChannelsByModelsMap to batch-fetch bound channels via a single JOIN (Distinct), compatible with SQLite/MySQL/PostgreSQL
- Replace per-record enrichment with a single-pass enrichModels to avoid N+1 queries; compute unions for prefix/suffix/contains matches in memory
- Change Model.QuotaType to QuotaTypes []int and expose quota_types in responses
- Add GetModelQuotaTypes for cached O(1) lookups; exact models return a single-element array
- Sort quota_types for stable output order
- Remove unused code: GetModelByName, GetBoundChannels, GetBoundChannelsForModels, FindModelByNameWithRule, buildPrefixes, buildSuffixes
- Clean up redundant comments, keeping concise and readable code

Frontend
- Models table: switch to quota_types, render multiple billing modes ([0], [1], [0,1], future values supported)
- Pricing table: switch to quota_types; ratio display now checks quota_types.includes(0); array rendering for billing tags

Compatibility
- SQL uses standard JOIN/IN/Distinct; works across SQLite/MySQL/PostgreSQL
- Lint passes; no DB schema changes (quota_types is a JSON response field only)

Breaking Change
- API field renamed: quota_type -> quota_types (array). Update clients accordingly.
2025-08-11 14:40:01 +08:00