- Add docker-build target for building Docker images
- Add docker-push target for building and pushing images
- Dynamic tag format: {registry}:{timestamp}-{branch}
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1. Extract parseTokenKey helper function to eliminate code duplication
2. Add channelId validation to prevent invalid formats like sk-abc:def:ghi
3. Add database migration to drop deprecated bound_channel_id column
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add support for sk-{key}:{channelId} format to specify channel dynamically
- Remove BoundChannelId field and related code
- All users can now specify channels, not just admins
- Add model validation when channel is specified
- Remove bound channel UI from token management
Breaking change: tokens can no longer be bound to channels at creation time.
Use sk-{key}:{channelId} format instead.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add "by price" sub-mode for per-token pricing (auto-calculate ratios)
- Add color picker with preset colors in tag manager
- Display tags with colors in channel pricing view and selector
- Remove unused function, extract hardcoded color constants
- Fix pricing model filter (status==0 instead of status!=1)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This PR fixes three issues:
1. Token bound_channel_id not updating: Add bound field to Update() method
2. Channel pricing quota_type detection: Use QuotaTypeByCall constant instead of magic number 1
3. Log display for ratio-based pricing: Set ModelPrice=-1 for ratio-based pricing
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add a new /api/user/channels endpoint that returns only enabled channels
with non-sensitive fields (id, name, type, remark) for token channel binding.
Update EditTokenModal to use this endpoint and display remark instead of ID
in the channel dropdown.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Rename "输入倍率" to "模型倍率" for model_ratio field
- Rename "输出倍率" to "补全倍率" for completion_ratio field
- Update help text to reflect accurate pricing calculation
- Add search functionality for model filtering
- Improve table expansion behavior
- Fix channel data loading in ModelSettingsVisualEditor
- Conditionally show ratio/price fields based on quota type
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add bound_channel_id field to EditTokenModal for channel binding
- Load channels list for dropdown selection
- Add i18n translations for channel pricing features (zh-CN, en)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add view mode switch (global vs channel) to ModelSettingsVisualEditor
- Create ChannelPricingView component for channel-specific pricing
- Add pricing tag management tab to RatioSetting
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Integrate channel-specific pricing into the billing logic.
- First tries to get channel pricing using model.GetEffectivePricing
- If found, uses channel pricing (modelRatio, completionRatio, modelPrice, usePrice)
- If not found, falls back to global pricing from ratio_setting
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When a token has BoundChannelId set, the distributor now uses that channel
instead of the normal channel selection process. The bound channel is still
validated to ensure it is enabled and supports the requested model.
Changes:
- Add ContextKeyTokenBoundChannelId constant
- Set bound channel in context during token authentication
- Check and use bound channel in distributor before normal selection
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add BoundChannelId field to support binding a token to a specific channel.
When set, the token will always use the bound channel for requests.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add new route groups for channel pricing and pricing tag management
with AdminAuth middleware.
Routes added:
- /api/channel_pricing/*: CRUD operations for channel pricing
- /api/pricing_tag/*: CRUD operations for pricing tags
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- GetAllChannelPricing: get all channel pricings with pagination
- GetChannelPricingByModel: get pricings for a specific model
- CreateChannelPricing: create or update channel pricing
- BatchCreateChannelPricing: batch create/update pricings
- DeleteChannelPricing: delete channel pricing
- CopyGlobalPricing: copy global pricing from ratio_setting to channel
- GetChannelPricingWithTags: get pricings with tag details
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add the new pricing models to both migrateDB() and migrateDBFast()
functions to enable automatic table creation on database initialization.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The previous implementation only did INSERT without handling conflicts.
Now uses GORM's OnConflict clause to properly update existing records
when (model_name, channel_id) unique constraint is violated.
On conflict updates: quota_type, model_ratio, completion_ratio,
model_price, tag_ids, updated_time
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add new model to support per-channel pricing for models,
allowing the same model to have different prices across
different channels.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When a channel is created or updated, automatically sync its models to the
models table if they don't exist. Models created this way are marked with
SyncOfficial=0 to prevent official sync from overwriting them.