1. 16 Jun, 2025 1 commit
  2. 15 Jun, 2025 4 commits
    • feat(channel-ui): support multi-JSON batch creation for Vertex AI & multi-to-single mode · 52008cbb
      WHY
      • Backend (558e67d9) now accepts structured request `{ mode, channel }`, including new `multi_to_single`.
      • Need front-end to upload multiple service-account JSON files and generate correct `channel.key`.
      • Improve UX: avoid red “uploadFail” state and offer drag-and-drop UI.
      
      WHAT
      1. EditChannel.js
         • Added Upload drag-area with IconBolt; `uploadTrigger="custom"`.
         • `handleJsonFileUpload` reads file, pushes content to `jsonFiles`, returns `{ shouldUpload:false, status:'success' }`.
         • New states: `batch`, `mergeToSingle`, `jsonFiles`.
         • Dynamic mode resolver: `single` | `batch` | `multi_to_single`.
         • Builds `channel.key` as JSON-object whose keys are the raw credential texts.
         • UI:
           – “Batch create” checkbox (new build only).
           – Nested “Merge to single channel (multi-key mode)” checkbox enabled when batch=true.
           – Real-time file count display.
      
      2. Upload UX
         • Drag-and-drop, accepts `.json,application/json`.
         • Custom texts: “Click or drop files here” / “JSON credentials only”.
         • Eliminated mandatory `action` warning (`action="#"`).
      
      3. Misc
         • Included IconBolt import.
         • Safeguard toggles reset logic to prevent stale state.
      
      RESULT
      Front-end now fully aligns with enhanced AddChannel API:
      • Supports Vertex AI multi JSON batch creation.
      • Supports new `multi_to_single` flow.
      • Clean user feedback with successful file status.
      Apple\Apple committed
    • fix(playground): send selected group in API payload · e3b7523c
      Previously, the Playground UI allowed users to pick a group, but the request body sent to `/pg/chat/completions` did not include this information, so the backend always fell back to the user’s default group.
      
      Changes introduced
      • web/src/helpers/api.js – added `group: inputs.group` to the `payload` built in `buildApiPayload`.
      
      Outcome
      • Selected group is now transmitted to the backend, enabling proper channel routing and pricing logic based on group ratios.
      • Resolves the issue where group selection appeared ineffective in the Playground.
      Apple\Apple committed
  3. 14 Jun, 2025 11 commits
  4. 13 Jun, 2025 13 commits
    • 🎛️ feat(dashboard): add per-panel enable switches & conditional backend payload · 882cdbd3
      Backend:
      • ConsoleSetting
        - Introduce `ApiInfoEnabled`, `UptimeKumaEnabled`, `AnnouncementsEnabled`, `FAQEnabled` (default true).
      • misc.GetStatus
        - Refactor to build response map dynamically.
        - Return the four *_enabled flags.
        - Only append `api_info`, `announcements`, `faq` when their respective flags are true.
      
      Frontend:
      • Detail page
        - Remove all `self_use_mode_enabled` checks.
        - Render API, Announcement, FAQ and Uptime panels based on the new *_enabled flags.
      • Dashboard → Settings
        - Added `Switch` controls in:
          · SettingsAPIInfo.js
          · SettingsAnnouncements.js
          · SettingsFAQ.js
          · SettingsUptimeKuma.js
        - Each switch persists its state via `/api/option` to the corresponding
          `console_setting.<panel>_enabled` key and reflects current status on load.
        - DashboardSetting.js now initialises and refreshes the four *_enabled keys so
          child components receive accurate panel states.
      
      Fixes:
      • Switches previously defaulted to “on” because *_enabled keys were missing.
        They are now included, ensuring correct visual state when panels are disabled.
      
      No breaking changes; existing functionality remains untouched aside from the
      new per-panel visibility control.
      Apple\Apple committed
    • feat: Add `controller/console_migrate.go` providing… · bccb87fe
       feat: Add `controller/console_migrate.go` providing `/api/option/migrate_console_setting` endpoint for one-off data migration.
      Apple\Apple committed
    • 🧹 refactor: drop obsolete ValidateApiInfo API & update callers · ce0ff679
      Backend
      • Removed the exported function `ValidateApiInfo` from `setting/console_setting/validation.go`; it was only a legacy wrapper and is no longer required.
      • Updated `controller/option.go` to call `ValidateConsoleSettings(value, "ApiInfo")` directly when validating `console_setting.api_info`.
      • Confirmed there are no remaining references to `ValidateApiInfo` in the codebase.
      
      This commit eliminates the last piece of compatibility code related to the old validation interface, keeping the API surface clean and consistent.
      Apple\Apple committed
    • refactor(console_setting): migrate console settings to model_setting auto-injection · 9d384f97
      Backend
      - Introduce `setting/console_setting` package that defines `ConsoleSetting` struct with JSON tags and validation rules.
      - Register the new module with `config.GlobalConfig` to enable automatic injection/export of configuration values.
      - Remove legacy `setting/console.go` and the manual `OptionMap` hooks; clean up `model/option.go`.
      - Add `controller/console_migrate.go` providing `/api/option/migrate_console_setting` endpoint for one-off data migration.
      - Update controllers (`misc`, `option`, `uptime_kuma`) and router to consume namespaced keys `console_setting.*`.
      
      Frontend
      - Refactor dashboard pages (`SettingsAPIInfo`, `SettingsAnnouncements`, `SettingsFAQ`, `SettingsUptimeKuma`) and detail page to read/write the new keys.
      - Simplify `DashboardSetting.js` state to only include namespaced options.
      
      BREAKING CHANGE: All console-related option keys are now stored under `console_setting.*`. Run the migration endpoint once after deployment to preserve existing data.
      Apple\Apple committed
    • 🎫 feat: Enhance redemption code expiry handling & improve UI responsiveness · f5e3617c
      Backend
      • Introduced `validateExpiredTime` helper in `controller/redemption.go`; reused in both Add & Update endpoints to enforce “expiry time must not be earlier than now”, eliminating duplicated checks
      • Removed `RedemptionCodeStatusExpired` constant and all related references – expiry is now determined exclusively by the `expired_time` field for simpler, safer state management
      • Simplified `DeleteInvalidRedemptions`: deletes codes that are `used` / `disabled` or `enabled` but already expired, without relying on extra status codes
      • Controller no longer mutates `status` when listing or fetching redemption codes; clients derive expiry status from timestamp
      
      Frontend
      • Added reusable `isExpired` helper in `RedemptionsTable.js`; leveraged for:
        – status rendering (orange “Expired” tag)
        – action-menu enable/disable logic
        – row styling
      • Removed duplicated inline expiry logic, improving readability and performance
      • Adjusted toolbar layout: on small screens the “Clear invalid codes” button now wraps onto its own line, while “Add” & “Copy” remain grouped
      
      Result
      The codebase is now more maintainable, secure, and performant with no redundant constants, centralized validation, and cleaner UI behaviour across devices.
      Apple\Apple committed
    • 🎨 feat(ui): enhance table headers with descriptive titles and semantic icons · 8c5f46ce
      - Add informative header section to TokensTable with Key icon and description
      - Replace generic eye icon with semantic Ticket icon in RedemptionsTable header
      - Import additional UI components (Divider, Typography) for better layout structure
      - Improve user experience with contextual information about token and redemption functionality
      - Maintain consistent styling and layout between both table components
      
      The changes provide users with clear understanding of each table's purpose:
      - Tokens: "令牌用于API访问认证,可以设置额度限制和模型权限" with Key icon
      - Redemptions: "兑换码可以批量生成和分发,适合用于推广活动或批量充值" with Ticket icon
      Apple\Apple committed
    • feat(ui): add incremental-add feedback & translations for model lists (#1218) · f4874c2c
      Front-end enhancements around “Add custom models”:
      
      • EditChannel.js / EditTagModal.js
        – Skip models that already exist instead of blocking the action.
        – Collect actually inserted items and display:
            • Success toast: “Added N models: model1, model2 …”
            • Info toast when no new model detected.
        – Keeps UX smooth while preserving deduplication logic.
      
      • i18n
        – en.json: added keys
            • "已新增 {{count}} 个模型:{{list}}"
            • "未发现新增模型"
        – Fixed a broken JSON string containing smart quotes to maintain valid syntax.
      
      Result:
      Users can bulk-paste model names; duplicates are silently ignored and the UI clearly lists what was incrementally appended. All messages are fully internationalised.
      
      Closes #1218
      Apple\Apple committed
    • 🐛 fix(ability): keep case-sensitive (group, model) keys during deduplication · 0c34eb43
      The previous patch lower-cased `group` and `model` when building the
      temporary `abilitySet` used to prevent duplicate inserts.
      This merged models that differ only by letter case, e.g.
      `GPT-3.5-turbo` vs `gpt-3.5-turbo`, causing them to disappear from the
      user’s available-models list and pricing page.
      
      Change:
      • ability.go – removed all `strings.ToLower` calls when composing the
        deduplication key (`group|model`), so duplicates are checked in a
        case-sensitive manner while preserving the original data.
      
      Result:
      • `GPT-3.5-turbo` and `gpt-3.5-turbo` are now treated as distinct
        models throughout the system.
      Apple\Apple committed
    • 🐛 fix(ability): prevent duplicate (group, model) pairs when saving channels · 21523833
      When importing large model lists (≈700+) an attempt to save a channel
      could fail with:
      
          Error 1062 (23000): Duplicate entry 'default-DeepSeek-1' for key 'abilities.PRIMARY'
      
      Root cause: AddAbilities / UpdateAbilities inserted the same
      (group, model) pair multiple times if the input list contained
      duplicates or case-variants (e.g. `default` vs `Default`).
      
      Changes:
      • ability.go
        – AddAbilities: introduced `abilitySet` to deduplicate by
          lower-cased `group|model` key before batch-inserting.
        – UpdateAbilities: applied the same deduplication logic when
          rebuilding abilities inside a transaction.
      
      Notes:
      • The lower-casing is only for set comparison; the original
        `group` and `model` values are preserved when persisting to DB,
        so case sensitivity of stored data is unchanged.
      • Batch chunking logic (lo.Chunk) and performance characteristics
        remain unaffected.
      
      Fixes #1215
      Apple\Apple committed
    • 🐛 fix(setup): enforce username length ≤ 12 during initial system setup · bbeaa6a2
      The User model applies `validate:"max=12"` to the `Username` field, but the
      initial setup flow did not validate this constraint. This allowed creation
      of a root user with an overly long username (e.g. "Uselessly1344"), which
      later caused every update request to fail with:
      
        Field validation for 'Username' failed on the 'max' tag
      
      This patch adds an explicit length check in `controller/setup.go` to reject
      usernames longer than 12 characters during setup, keeping validation rules
      consistent across the entire application.
      
      Refs: #1214
      Apple\Apple committed
  5. 12 Jun, 2025 11 commits