Backend (controller/ratio_sync.go):
- Add built‑in official upstream to GetSyncableChannels (ID: -100, BaseURL: https://basellm.github.io)
- Support absolute endpoint URLs; otherwise join BaseURL + endpoint (defaults to /api/ratio_config)
- Harden HTTP client:
- IPv4‑first with IPv6 fallback for github.io
- Add ResponseHeaderTimeout
- 3 attempts with exponential backoff (200/400/800ms)
- Validate Content-Type and limit response body to 10MB (safe decode via io.LimitReader)
- Robust parsing: support type1 ratio_config map and type2 pricing list
- Use net.SplitHostPort for host parsing
- Use float tolerance in differences comparison to avoid false mismatches
- Remove unused code (tryDirect) and improve warnings
Frontend:
- UpstreamRatioSync.jsx: auto-assign official endpoint to /llm-metadata/api/newapi/ratio_config-v1-base.json
- ChannelSelectorModal.jsx:
- Pin the official source at the top of the list
- Show a green “官方” tag next to the status
- Refactor status renderer to accept the full record
Notes:
- Backward compatible; no API surface changes
- Official ratio_config reference: https://basellm.github.io/llm-metadata/api/newapi/ratio_config-v1-base.json
- Ran: bun run eslint:fix && bun run lint:fix
- Inserted AGPL license header via eslint-plugin-header
- Enforced no-multiple-empty-lines and other lint rules
- Formatted code using Prettier v3 (@so1ve/prettier-config)
- No functional changes; formatting-only baseline across JS/JSX files
Replace the fallback assignment of serverAddress in `web/src/pages/Home/index.jsx`
to use a template literal for `window.location.origin`.
- Aligns with the preferred style for constructing base URLs
- Keeps formatting consistent across the app
- No functional changes; behavior remains the same
- Lint passes with no new warnings or errors
Files affected:
- web/src/pages/Home/index.jsx
- Rename React components/pages/utilities that contain JSX to `.jsx` across `web/src`
- Update import paths and re-exports to match new `.jsx` extensions
- Fix Vite entry by switching `web/index.html` from `/src/index.js` to `/src/index.jsx`
- Verified remaining `.js` files are plain JS (hooks/helpers/constants) and do not require JSX
- No runtime behavior changes; extension and reference alignment only
Context: Resolves the Vite pre-transform error caused by the stale `/src/index.js` entry after migrating to `.jsx`.
Summary of changes
1. SetupWizard.jsx
• Center card (`min-h-screen flex items-center justify-center`) and remove top margin.
• Merge step indicator/content into single card; added `Divider` separator.
• Added sweep-shine animation to current step title via existing `shine-text` class.
• Simplified imports (removed Avatar / Typography) and deleted unused modal state.
2. Step components
• Stripped outer `Card` and header sections from `DatabaseStep.jsx`, `AdminStep.jsx`, `UsageModeStep.jsx`, `CompleteStep.jsx` to fit single-card layout.
• Removed unused imports and props.
3. Components cleanup
• Deleted obsolete files:
- `components/setup/components/SetupSteps.jsx`
- `components/setup/components/modals/UsageModeInfoModal.jsx`
• Updated `setup/index.jsx` exports accordingly.
4. Styling
• Ensured global sweep-shine effect already present in `index.css` is reused for step titles.
5. i18n
• Pruned unused translation keys related to removed components from `i18n/locales/en.json`.
6. Miscellaneous
• Removed redundant Avatar/Icon imports from multiple files.
• All linter checks pass with no new warnings.
This commit consolidates the initialization flow into a cleaner, centered single-card wizard, adds visual polish, and reduces dead code for easier maintenance.
- Add RightStatsCard and place it in RechargeCard header
- Shows current balance, historical spend, and request count
- Mobile: stacks under title; three metrics split equally (flex-1); vertical dividers hidden on small screens
- Remove extra margins; small card styling
- RechargeCard
- Replace redeem code Input icon with Semi UI IconGift
- Style “Payable amount” number in red and bold; keep same style in confirm modal
- Always render payment methods as Cards (remove Button variant) with adaptive grid
- Use brand color icons: SiAlipay (#1677FF), SiWechat (#07C160), SiStripe (#635BFF)
- Replace Stripe icon with SiStripe
- Integrate RightStatsCard props; adjust header to flex-col on mobile and flex-row on desktop
- Hide Banner close button when online top-up is disabled (closeIcon={null})
- InvitationCard
- Simplify to match RechargeCard’s minimalist slate style
- Use Card title for “Rewards” and place content directly in body
- Improve link input and copy button; use Badge dots for bullet points
- TopUp index
- Remove separate right-column stats card; pass userState and renderQuota to RechargeCard
- Cleanup
- Lint passes; no functional changes to APIs or business logic
- Add new Forbidden page at /forbidden (`web/src/pages/Forbidden/index.js`)
- Use Semi-UI Empty with IllustrationNoAccess (250x250)
- Update i18n description to: '您无权访问此页面,请联系管理员~'
- Align visual style with existing 404 page
- Introduce `AdminRoute` in `web/src/helpers/auth.js`
- Use `UserContext`/localStorage; redirect to `/forbidden` when `!user` or `user.role < 10`
- Protect console/admin routes with `AdminRoute` and register `/forbidden` in `web/src/App.js`
- Update `web/src/i18n/locales/en.json`
- Add English translation for the new forbidden message
- Remove legacy "没有权限" entry
- Lint passes; no runtime errors observed
Backend
• Add `model/model_meta.go` and `model/vendor_meta.go` defining Model & Vendor entities with CRUD helpers, soft-delete and time stamps
• Create corresponding controllers `controller/model_meta.go`, `controller/vendor_meta.go` and register routes in `router/api-router.go`
• Auto-migrate new tables in DB startup logic
Frontend
• Build complete “Model Management” module under `/console/models`
- New pages, tables, filters, actions, hooks (`useModelsData`) and dynamic vendor tabs
- Modals `EditModelModal.jsx` & unified `EditVendorModal.jsx`; latter now uses default confirm/cancel footer and mobile-friendly modal sizing (`full-width` / `small`) via `useIsMobile`
• Update sidebar (`SiderBar.js`) and routing (`App.js`) to surface the feature
• Add helper updates (`render.js`) incl. `stringToColor`, dynamic LobeHub icon retrieval, and tag color palettes
Table UX improvements
• Replace separate status column with inline Enable / Disable buttons in operation column (matching channel table style)
• Limit visible tags to max 3; overflow represented as “+x” tag with padded `Popover` showing remaining tags
• Color all tags deterministically using `stringToColor` for consistent theming
• Change vendor column tag color to white for better contrast
Misc
• Minor layout tweaks, compact-mode toggle relocation, lint fixes and TypeScript/ESLint clean-up
These changes collectively deliver end-to-end model & vendor administration while unifying visual language across management tables.
- Increase skeleton card count from 6 to 10 for better visual coverage
- Extend minimum skeleton display duration from 500ms to 1000ms for smoother UX
- Add circle shape to all pricing tags for consistent rounded design
- Apply circle styling to billing type, popularity, endpoint, and context tags
This commit improves the visual consistency and user experience of the pricing
card view by standardizing tag appearance and optimizing skeleton loading timing.
- Break down monolithic ModelPricing.js (685 lines) into focused components:
* ModelPricingHeader.jsx - top status card with pricing information
* ModelPricingTabs.jsx - model category navigation tabs
* ModelPricingFilters.jsx - search and action controls
* ModelPricingTable.jsx - data table with pricing details
* ModelPricingColumnDefs.js - table column definitions and renderers
- Create custom hook useModelPricingData.js for centralized state management:
* Consolidate all business logic and API calls
* Manage pricing calculations and data transformations
* Handle search, filtering, and UI interactions
- Follow project conventions matching other table components:
* Adopt same file structure as channels/, users/, tokens/ modules
* Maintain consistent naming patterns and component organization
* Preserve all original functionality including responsive design
- Update import paths:
* Remove obsolete ModelPricing.js file
* Update Pricing page to use new ModelPricingPage component
* Fix missing import references
Benefits:
- Improved maintainability with single-responsibility components
- Enhanced code reusability and testability
- Better team collaboration with modular structure
- Consistent codebase architecture across all table components
- Update license text from "Apache-2.0协议" to "AGPL v3.0协议"
- Update license link to point to official AGPL v3.0 license page
- Align About page license references with actual project license
## Overview
Refactored the monolithic dashboard page (~1200 lines) into a modular architecture following the project's global layout pattern. The main `Detail/index.js` is now simplified to match other page entry files like `Midjourney/index.js`.
## Changes Made
### 🏗️ Architecture Changes
- **Before**: Single large file `pages/Detail/index.js` containing all dashboard logic
- **After**: Modular structure with dedicated hooks, components, and helpers
### 📁 New Files Created
- `hooks/dashboard/useDashboardData.js` - Core data management and API calls
- `hooks/dashboard/useDashboardStats.js` - Statistics computation and memoization
- `hooks/dashboard/useDashboardCharts.js` - Chart specifications and data processing
- `constants/dashboard.constants.js` - UI config, time options, and chart defaults
- `helpers/dashboard.js` - Utility functions for data processing and UI helpers
- `components/dashboard/index.jsx` - Main dashboard component integrating all modules
- `components/dashboard/modals/SearchModal.jsx` - Search modal component
### 🔧 Updated Files
- `constants/index.js` - Added dashboard constants export
- `helpers/index.js` - Added dashboard helpers export
- `pages/Detail/index.js` - Simplified to minimal wrapper (~20 lines)
### 🐛 Bug Fixes
- Fixed SearchModal DatePicker onChange to properly convert Date objects to timestamp strings
- Added missing localStorage update for `data_export_default_time` persistence
- Corrected data flow between search confirmation and chart updates
- Ensured proper chart data refresh after search parameter changes
### ✨ Key Improvements
- **Separation of Concerns**: Data, stats, and charts logic isolated into dedicated hooks
- **Reusability**: Components and hooks can be easily reused across the application
- **Maintainability**: Smaller, focused files easier to understand and modify
- **Consistency**: Follows established project patterns for global folder organization
- **Performance**: Proper memoization and callback optimization maintained
### 🎯 Functional Verification
- ✅ All dashboard panels (model analysis, resource consumption, performance metrics) update correctly
- ✅ Search functionality works with proper parameter validation
- ✅ Chart data refreshes properly after search/filter operations
- ✅ User interface remains identical to original implementation
- ✅ All existing features preserved without regression
### 🔄 Data Flow
```
User Input → SearchModal → useDashboardData → API Call → useDashboardCharts → UI Update
```
## Breaking Changes
None. All existing functionality preserved.
## Migration Notes
The refactored dashboard maintains 100% API compatibility and identical user experience while providing a cleaner, more maintainable codebase structure.
- Create new ScrollableContainer component in @/components/common/ui
- Provides automatic scroll detection and fade indicator
- Supports customizable height, styling, and event callbacks
- Includes comprehensive PropTypes for type safety
- Optimized with useCallback for better performance
- Refactor Detail page to use ScrollableContainer
- Remove manual scroll detection functions (checkApiScrollable, checkCardScrollable)
- Remove scroll event handlers (handleApiScroll, handleCardScroll)
- Remove scroll-related refs and state variables
- Replace all card scroll containers with ScrollableContainer component
* API info card
* System announcements card
* FAQ card
* Uptime monitoring card (both single and multi-tab scenarios)
- Benefits:
- Improved code reusability and maintainability
- Reduced code duplication across components
- Consistent scroll behavior throughout the application
- Easier to maintain and extend scroll functionality
Breaking changes: None
Migration: Existing scroll behavior is preserved with no user-facing changes
Move EditChannel and EditTagModal from standalone pages to modal components
within the channels module structure for consistency with other table modules.
Changes:
- Move EditChannel.js → components/table/channels/modals/EditChannelModal.jsx
- Move EditTagModal.js → components/table/channels/modals/EditTagModal.jsx
- Update import paths in channels/index.jsx
- Remove standalone routes for EditChannel from App.js
- Delete original files from pages/Channel/
This change aligns the channels module with the established modular pattern
used by tokens, users, redemptions, and other table modules, centralizing
all channel management functionality within integrated modal components
instead of separate page routes.
BREAKING CHANGE: EditChannel standalone routes (/console/channel/edit/:id
and /console/channel/add) have been removed. All channel editing is now
handled through modal components within the main channels page.
BREAKING CHANGE: Removed standalone user edit routes (/console/user/edit, /console/user/edit/:id)
- Decompose 673-line monolithic UsersTable.js into 8 specialized components
- Extract column definitions to UsersColumnDefs.js with render functions
- Create dedicated UsersActions.jsx for action buttons
- Create UsersFilters.jsx for search and filtering logic
- Create UsersDescription.jsx for description area
- Extract all data management logic to useUsersData.js hook
- Move AddUser.js and EditUser.js to users/modals/ folder as modal components
- Create 4 new confirmation modal components (Promote, Demote, EnableDisable, Delete)
- Implement pure UsersTable.jsx component for table rendering only
- Create main container component users/index.jsx to compose all subcomponents
- Update import paths in pages/User/index.js to use new modular structure
- Remove obsolete EditUser imports and routes from App.js
- Delete original monolithic files: UsersTable.js, AddUser.js, EditUser.js
The new architecture follows the same modular pattern as tokens and redemptions modules:
- Consistent file organization across all table modules
- Better separation of concerns and maintainability
- Enhanced reusability and testability
- Unified modal management approach
All existing functionality preserved with improved code organization.
Refactor the monolithic RedemptionsTable component (614 lines) into a clean,
modular structure following the established tokens component pattern.
### Changes Made:
**New Components:**
- `RedemptionsColumnDefs.js` - Extract table column definitions and render logic
- `RedemptionsActions.jsx` - Extract action buttons (add, batch copy, clear invalid)
- `RedemptionsFilters.jsx` - Extract search and filter form components
- `RedemptionsDescription.jsx` - Extract description area component
- `redemptions/index.jsx` - Main container component managing state and composition
**New Hook:**
- `useRedemptionsData.js` - Extract all data management, CRUD operations, and business logic
**New Constants:**
- `redemption.constants.js` - Extract redemption status, actions, and form constants
**Architecture Changes:**
- Transform RedemptionsTable.jsx into pure table rendering component
- Move state management and component composition to index.jsx
- Implement consistent prop drilling pattern matching tokens module
- Add memoization for performance optimization
- Centralize translation function distribution
### Benefits:
- **Maintainability**: Each component has single responsibility
- **Reusability**: Components and hooks can be used elsewhere
- **Testability**: Individual modules can be unit tested
- **Team Collaboration**: Multiple developers can work on different modules
- **Consistency**: Follows established architectural patterns
### File Structure:
```
redemptions/
├── index.jsx # Main container (state + composition)
├── RedemptionsTable.jsx # Pure table component
├── RedemptionsActions.jsx # Action buttons
├── RedemptionsFilters.jsx # Search/filter form
├── RedemptionsDescription.jsx # Description area
└── RedemptionsColumnDefs.js # Column definitions
Refactor the monolithic TaskLogsTable component (802 lines) into a modular,
maintainable architecture following the established pattern from LogsTable
and MjLogsTable refactors.
## What Changed
### 🏗️ Architecture
- Split large single file into focused, single-responsibility components
- Introduced custom hook `useTaskLogsData` for centralized state management
- Created dedicated column definitions file for better organization
- Implemented modal components for user interactions
### 📁 New Structure
```
web/src/components/table/task-logs/
├── index.jsx # Main page component orchestrator
├── TaskLogsTable.jsx # Pure table rendering component
├── TaskLogsActions.jsx # Actions area (task records + compact mode)
├── TaskLogsFilters.jsx # Search form component
├── TaskLogsColumnDefs.js # Column definitions and renderers
└── modals/
├── ColumnSelectorModal.jsx # Column visibility settings
└── ContentModal.jsx # Content viewer for JSON data
web/src/hooks/task-logs/
└── useTaskLogsData.js # Custom hook for state & logic
```
### 🎯 Key Improvements
- **Maintainability**: Clear separation of concerns, easier to understand
- **Reusability**: Modular components can be reused independently
- **Performance**: Optimized with `useMemo` for column rendering
- **Testing**: Single-responsibility components easier to test
- **Developer Experience**: Better code organization and readability
### 🎨 Task-Specific Features Preserved
- All task type rendering with icons (MUSIC, LYRICS, video generation)
- Platform-specific rendering (Suno, Kling, Jimeng) with distinct colors
- Progress indicators for task completion status
- Video preview links for successful video generation tasks
- Admin-only columns for channel information
- Status rendering with appropriate colors and icons
### 🔧 Technical Details
- Centralized all business logic in `useTaskLogsData` custom hook
- Extracted comprehensive column definitions with Lucide React icons
- Split complex UI into focused components (table, actions, filters, modals)
- Maintained responsive design patterns for mobile compatibility
- Preserved admin permission handling for restricted features
- Optimized spacing and layout (reduced gap from 4 to 2 for better density)
### 🎮 Platform Support
- **Suno**: Music and lyrics generation with music icons
- **Kling**: Video generation with video icons
- **Jimeng**: Video generation with distinct purple styling
### 🐛 Fixes
- Improved component prop passing patterns
- Enhanced type safety through better state management
- Optimized rendering performance with proper memoization
- Streamlined export pattern using `export { default }`
## Breaking Changes
None - all existing imports and functionality preserved.
Eliminated the manual `formatPageText` function that previously rendered
pagination text (e.g. “第 {{start}} - {{end}} 条,共 {{total}} 条”) in each
Table. Pagination now relies on the default Semi UI text or the global
i18n configuration, reducing duplication and making future language
updates centralized.
Why
---
* Keeps table components cleaner and more maintainable.
* Ensures pagination text automatically respects the app-wide i18n
settings without per-component overrides.
Summary
Implement a dedicated, reusable scrolling mechanism for all console-table pages while keeping header and sidebar fixed, plus related layout improvements.
Key Changes
• Added `.table-scroll-card` utility class
– Provides flex column layout and internal vertical scrolling
– Desktop height: `calc(100vh - 110px)`; Mobile (<768 px) height: `calc(100vh - 77px)`
– Hides scrollbars cross-browser (`-ms-overflow-style`, `scrollbar-width`, `::-webkit-scrollbar`)
• Replaced global `.semi-card` scrolling rules with `.table-scroll-card` to avoid affecting non-table cards
• Updated table components (Channels, Tokens, Users, Logs, MjLogs, TaskLogs, Redemptions) to use the new class
• PageLayout
– Footer is now suppressed for all `/console` routes
– Confirmed only central content area scrolls; header & sidebar remain fixed
• Restored hidden scrollbar rules for `.semi-layout-content` and removed unnecessary global overrides
• Minor CSS cleanup & comment improvements for readability
Result
Console table pages now fill the viewport with smooth, internal scrolling and no visible scrollbars, while other cards and pages remain unaffected.
Backend
- setting/payment.go: introduce default `USDExchangeRate` (7.3)
- model/option.go:
• inject `USDExchangeRate` into `InitOptionMap`
• persist & sync value in `updateOptionMap`
- controller/misc.go: expose `usd_exchange_rate` via `/api/status`
Frontend
- OperationSetting.js & SettingsGeneral.js:
• extend state/inputs with `USDExchangeRate`
• add form field “美元汇率 (non-top-up rate, pricing only)”
- ModelPricing.js already consumes `status.usd_exchange_rate`; no change needed
API
- Administrators can update the rate via `PUT /api/option` (key: `USDExchangeRate`)
- All clients receive the latest rate through `GET /api/status`
This closes the end-to-end flow for displaying model prices in both USD and CNY based on a configurable exchange rate.