mirror of
https://github.com/Wei-Shaw/sub2api.git
synced 2026-10-29 16:20:27 +00:00
fix: 长上下文默认保持开启,并与 OpenAI 账号开关取交集
迁移默认 false 会让存量分组静默丢掉 ≥200k 阶梯与渠道多档价。 OpenAI 路径传入 Group 后,账号级 openai_long_context_billing_enabled 被顶掉。 - 列默认 TRUE,并对存量行回填 - 分组价卡不再手填 token 区间,勾选走官方/预设阶梯 - 分组开关与账号开关 AND;价卡 JSON 损坏时打 warn
This commit is contained in:
@@ -134,8 +134,8 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Token intervals -->
|
||||
<div class="mt-3">
|
||||
<!-- Token intervals (channel-only; group long-context uses official presets) -->
|
||||
<div v-if="!hideTokenIntervals" class="mt-3">
|
||||
<div class="flex items-center justify-between">
|
||||
<label class="text-xs font-medium text-gray-500 dark:text-gray-400">
|
||||
{{ t('admin.channels.form.intervals') }}
|
||||
@@ -245,10 +245,13 @@ import channelsAPI from '@/api/admin/channels'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const props = defineProps<{
|
||||
const props = withDefaults(defineProps<{
|
||||
entry: PricingFormEntry
|
||||
platform?: string
|
||||
}>()
|
||||
hideTokenIntervals?: boolean
|
||||
}>(), {
|
||||
hideTokenIntervals: false,
|
||||
})
|
||||
|
||||
const emit = defineEmits<{
|
||||
update: [entry: PricingFormEntry]
|
||||
|
||||
@@ -1007,9 +1007,9 @@ export default {
|
||||
},
|
||||
modelPricing: {
|
||||
title: 'Per-model group pricing',
|
||||
description: 'Overrides channel and built-in prices for matching models. Use per-request tiers such as realtime, tts, and stt for audio.',
|
||||
description: 'Overrides channel and built-in prices for matching models. Long-context tiers come from official presets — do not enter custom intervals. Use per-request tiers such as realtime, tts, and stt for audio.',
|
||||
longContext: 'Enable long-context tier pricing',
|
||||
longContextHint: 'When disabled, token models always use the lowest configured tier.',
|
||||
longContextHint: 'When checked, official/preset long-context tiers apply. When unchecked, token models stay on the first-tier base rate.',
|
||||
add: 'Add model price'
|
||||
},
|
||||
voicePricing: {
|
||||
|
||||
@@ -1004,9 +1004,9 @@ export default {
|
||||
},
|
||||
modelPricing: {
|
||||
title: '分组逐模型定价',
|
||||
description: '匹配模型后覆盖渠道和内置价格。音频可用按次层级配置 realtime、tts、stt。',
|
||||
description: '匹配模型后覆盖渠道和内置价格。长上下文阶梯沿用官方/预设价卡,无需再手填区间。音频可用按次层级配置 realtime、tts、stt。',
|
||||
longContext: '启用长上下文阶梯定价',
|
||||
longContextHint: '关闭时,Token 模型始终只使用配置的最低档。',
|
||||
longContextHint: '勾选后按官方/预设阶梯计费;关闭则始终按第一档基础价。',
|
||||
add: '添加模型价格'
|
||||
},
|
||||
voicePricing: {
|
||||
|
||||
@@ -1499,7 +1499,7 @@
|
||||
<span><span class="block text-sm text-gray-700 dark:text-gray-300">{{ t("admin.groups.modelPricing.longContext") }}</span><span class="block text-xs text-gray-500">{{ t("admin.groups.modelPricing.longContextHint") }}</span></span>
|
||||
</label>
|
||||
<div class="mt-3 space-y-2">
|
||||
<PricingEntryCard v-for="(entry, index) in createForm.model_pricing" :key="index" :entry="entry" :platform="createForm.platform" @update="createForm.model_pricing[index] = $event" @remove="createForm.model_pricing.splice(index, 1)" />
|
||||
<PricingEntryCard v-for="(entry, index) in createForm.model_pricing" :key="index" :entry="entry" :platform="createForm.platform" hide-token-intervals @update="createForm.model_pricing[index] = $event" @remove="createForm.model_pricing.splice(index, 1)" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -3221,7 +3221,7 @@
|
||||
<span><span class="block text-sm text-gray-700 dark:text-gray-300">{{ t("admin.groups.modelPricing.longContext") }}</span><span class="block text-xs text-gray-500">{{ t("admin.groups.modelPricing.longContextHint") }}</span></span>
|
||||
</label>
|
||||
<div class="mt-3 space-y-2">
|
||||
<PricingEntryCard v-for="(entry, index) in editForm.model_pricing" :key="index" :entry="entry" :platform="editForm.platform" @update="editForm.model_pricing[index] = $event" @remove="editForm.model_pricing.splice(index, 1)" />
|
||||
<PricingEntryCard v-for="(entry, index) in editForm.model_pricing" :key="index" :entry="entry" :platform="editForm.platform" hide-token-intervals @update="editForm.model_pricing[index] = $event" @remove="editForm.model_pricing.splice(index, 1)" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -4527,7 +4527,10 @@ const groupPricingToAPI = (
|
||||
image_input_price: mTokToPerToken(entry.image_input_price),
|
||||
image_output_price: mTokToPerToken(entry.image_output_price),
|
||||
per_request_price: toNullableNumber(entry.per_request_price),
|
||||
intervals: formIntervalsToAPI(entry.intervals || []),
|
||||
intervals:
|
||||
entry.billing_mode === "token"
|
||||
? []
|
||||
: formIntervalsToAPI(entry.intervals || []),
|
||||
}));
|
||||
|
||||
const { t } = useI18n();
|
||||
@@ -5013,7 +5016,7 @@ const createForm = reactive({
|
||||
daily_limit_usd: null as number | null,
|
||||
weekly_limit_usd: null as number | null,
|
||||
monthly_limit_usd: null as number | null,
|
||||
long_context_pricing_enabled: false,
|
||||
long_context_pricing_enabled: true,
|
||||
model_pricing: [] as PricingFormEntry[],
|
||||
// 图片生成计费配置
|
||||
allow_image_generation: false,
|
||||
@@ -5374,7 +5377,7 @@ const editForm = reactive({
|
||||
daily_limit_usd: null as number | null,
|
||||
weekly_limit_usd: null as number | null,
|
||||
monthly_limit_usd: null as number | null,
|
||||
long_context_pricing_enabled: false,
|
||||
long_context_pricing_enabled: true,
|
||||
model_pricing: [] as PricingFormEntry[],
|
||||
// 图片生成计费配置
|
||||
allow_image_generation: false,
|
||||
@@ -5848,7 +5851,7 @@ const closeCreateModal = () => {
|
||||
createForm.video_price_720p = null;
|
||||
createForm.video_price_1080p = null;
|
||||
createForm.video_model_prices = createVideoModelPricesForm();
|
||||
createForm.long_context_pricing_enabled = false;
|
||||
createForm.long_context_pricing_enabled = true;
|
||||
createForm.model_pricing = [];
|
||||
createForm.web_search_price_per_call = null;
|
||||
createForm.search_price_per_1k = null;
|
||||
@@ -6076,7 +6079,7 @@ const handleEdit = async (group: AdminGroup) => {
|
||||
editForm.weekly_limit_usd = group.weekly_limit_usd;
|
||||
editForm.monthly_limit_usd = group.monthly_limit_usd;
|
||||
editForm.long_context_pricing_enabled =
|
||||
group.long_context_pricing_enabled ?? false;
|
||||
group.long_context_pricing_enabled ?? true;
|
||||
editForm.model_pricing = groupPricingFromAPI(group.model_pricing);
|
||||
editForm.allow_image_generation = group.allow_image_generation ?? false;
|
||||
editForm.allow_batch_image_generation =
|
||||
@@ -6182,7 +6185,7 @@ const closeEditModal = () => {
|
||||
editForm.video_price_720p = null;
|
||||
editForm.video_price_1080p = null;
|
||||
editForm.video_model_prices = createVideoModelPricesForm();
|
||||
editForm.long_context_pricing_enabled = false;
|
||||
editForm.long_context_pricing_enabled = true;
|
||||
editForm.model_pricing = [];
|
||||
editForm.web_search_price_per_call = null;
|
||||
editForm.search_price_per_1k = null;
|
||||
|
||||
Reference in New Issue
Block a user