mirror of
https://gitee.com/wanwujie/sub2api
synced 2026-04-18 13:54:46 +08:00
feat: add independent load_factor field for scheduling load calculation
This commit is contained in:
@@ -469,7 +469,7 @@
|
||||
</div>
|
||||
|
||||
<!-- Concurrency & Priority -->
|
||||
<div class="grid grid-cols-2 gap-4 border-t border-gray-200 pt-4 dark:border-dark-600 lg:grid-cols-3">
|
||||
<div class="grid grid-cols-2 gap-4 border-t border-gray-200 pt-4 dark:border-dark-600 lg:grid-cols-4">
|
||||
<div>
|
||||
<div class="mb-3 flex items-center justify-between">
|
||||
<label
|
||||
@@ -498,6 +498,35 @@
|
||||
aria-labelledby="bulk-edit-concurrency-label"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<div class="mb-3 flex items-center justify-between">
|
||||
<label
|
||||
id="bulk-edit-load-factor-label"
|
||||
class="input-label mb-0"
|
||||
for="bulk-edit-load-factor-enabled"
|
||||
>
|
||||
{{ t('admin.accounts.loadFactor') }}
|
||||
</label>
|
||||
<input
|
||||
v-model="enableLoadFactor"
|
||||
id="bulk-edit-load-factor-enabled"
|
||||
type="checkbox"
|
||||
aria-controls="bulk-edit-load-factor"
|
||||
class="rounded border-gray-300 text-primary-600 focus:ring-primary-500"
|
||||
/>
|
||||
</div>
|
||||
<input
|
||||
v-model.number="loadFactor"
|
||||
id="bulk-edit-load-factor"
|
||||
type="number"
|
||||
min="1"
|
||||
:disabled="!enableLoadFactor"
|
||||
class="input"
|
||||
:class="!enableLoadFactor && 'cursor-not-allowed opacity-50'"
|
||||
aria-labelledby="bulk-edit-load-factor-label"
|
||||
/>
|
||||
<p class="input-hint">{{ t('admin.accounts.loadFactorHint') }}</p>
|
||||
</div>
|
||||
<div>
|
||||
<div class="mb-3 flex items-center justify-between">
|
||||
<label
|
||||
@@ -869,6 +898,7 @@ const enableCustomErrorCodes = ref(false)
|
||||
const enableInterceptWarmup = ref(false)
|
||||
const enableProxy = ref(false)
|
||||
const enableConcurrency = ref(false)
|
||||
const enableLoadFactor = ref(false)
|
||||
const enablePriority = ref(false)
|
||||
const enableRateMultiplier = ref(false)
|
||||
const enableStatus = ref(false)
|
||||
@@ -889,6 +919,7 @@ const customErrorCodeInput = ref<number | null>(null)
|
||||
const interceptWarmupRequests = ref(false)
|
||||
const proxyId = ref<number | null>(null)
|
||||
const concurrency = ref(1)
|
||||
const loadFactor = ref<number | null>(null)
|
||||
const priority = ref(1)
|
||||
const rateMultiplier = ref(1)
|
||||
const status = ref<'active' | 'inactive'>('active')
|
||||
@@ -1195,6 +1226,10 @@ const buildUpdatePayload = (): Record<string, unknown> | null => {
|
||||
updates.concurrency = concurrency.value
|
||||
}
|
||||
|
||||
if (enableLoadFactor.value) {
|
||||
updates.load_factor = loadFactor.value
|
||||
}
|
||||
|
||||
if (enablePriority.value) {
|
||||
updates.priority = priority.value
|
||||
}
|
||||
@@ -1340,6 +1375,7 @@ const handleSubmit = async () => {
|
||||
enableInterceptWarmup.value ||
|
||||
enableProxy.value ||
|
||||
enableConcurrency.value ||
|
||||
enableLoadFactor.value ||
|
||||
enablePriority.value ||
|
||||
enableRateMultiplier.value ||
|
||||
enableStatus.value ||
|
||||
@@ -1430,6 +1466,7 @@ watch(
|
||||
enableInterceptWarmup.value = false
|
||||
enableProxy.value = false
|
||||
enableConcurrency.value = false
|
||||
enableLoadFactor.value = false
|
||||
enablePriority.value = false
|
||||
enableRateMultiplier.value = false
|
||||
enableStatus.value = false
|
||||
@@ -1446,6 +1483,7 @@ watch(
|
||||
interceptWarmupRequests.value = false
|
||||
proxyId.value = null
|
||||
concurrency.value = 1
|
||||
loadFactor.value = null
|
||||
priority.value = 1
|
||||
rateMultiplier.value = 1
|
||||
status.value = 'active'
|
||||
|
||||
@@ -1749,11 +1749,17 @@
|
||||
<ProxySelector v-model="form.proxy_id" :proxies="proxies" />
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-2 gap-4 lg:grid-cols-3">
|
||||
<div class="grid grid-cols-2 gap-4 lg:grid-cols-4">
|
||||
<div>
|
||||
<label class="input-label">{{ t('admin.accounts.concurrency') }}</label>
|
||||
<input v-model.number="form.concurrency" type="number" min="1" class="input" />
|
||||
</div>
|
||||
<div>
|
||||
<label class="input-label">{{ t('admin.accounts.loadFactor') }}</label>
|
||||
<input v-model.number="form.load_factor" type="number" min="1"
|
||||
class="input" :placeholder="String(form.concurrency || 1)" />
|
||||
<p class="input-hint">{{ t('admin.accounts.loadFactorHint') }}</p>
|
||||
</div>
|
||||
<div>
|
||||
<label class="input-label">{{ t('admin.accounts.priority') }}</label>
|
||||
<input
|
||||
@@ -2633,6 +2639,7 @@ const form = reactive({
|
||||
credentials: {} as Record<string, unknown>,
|
||||
proxy_id: null as number | null,
|
||||
concurrency: 10,
|
||||
load_factor: null as number | null,
|
||||
priority: 1,
|
||||
rate_multiplier: 1,
|
||||
group_ids: [] as number[],
|
||||
@@ -3112,6 +3119,7 @@ const resetForm = () => {
|
||||
form.credentials = {}
|
||||
form.proxy_id = null
|
||||
form.concurrency = 10
|
||||
form.load_factor = null
|
||||
form.priority = 1
|
||||
form.rate_multiplier = 1
|
||||
form.group_ids = []
|
||||
@@ -3483,6 +3491,7 @@ const handleImportAccessToken = async (accessTokenInput: string) => {
|
||||
extra: soraExtra,
|
||||
proxy_id: form.proxy_id,
|
||||
concurrency: form.concurrency,
|
||||
load_factor: form.load_factor || undefined,
|
||||
priority: form.priority,
|
||||
rate_multiplier: form.rate_multiplier,
|
||||
group_ids: form.group_ids,
|
||||
@@ -3542,6 +3551,7 @@ const createAccountAndFinish = async (
|
||||
extra,
|
||||
proxy_id: form.proxy_id,
|
||||
concurrency: form.concurrency,
|
||||
load_factor: form.load_factor || undefined,
|
||||
priority: form.priority,
|
||||
rate_multiplier: form.rate_multiplier,
|
||||
group_ids: form.group_ids,
|
||||
@@ -3597,6 +3607,7 @@ const handleOpenAIExchange = async (authCode: string) => {
|
||||
extra,
|
||||
proxy_id: form.proxy_id,
|
||||
concurrency: form.concurrency,
|
||||
load_factor: form.load_factor || undefined,
|
||||
priority: form.priority,
|
||||
rate_multiplier: form.rate_multiplier,
|
||||
group_ids: form.group_ids,
|
||||
@@ -3626,6 +3637,7 @@ const handleOpenAIExchange = async (authCode: string) => {
|
||||
extra: soraExtra,
|
||||
proxy_id: form.proxy_id,
|
||||
concurrency: form.concurrency,
|
||||
load_factor: form.load_factor || undefined,
|
||||
priority: form.priority,
|
||||
rate_multiplier: form.rate_multiplier,
|
||||
group_ids: form.group_ids,
|
||||
@@ -3703,6 +3715,7 @@ const handleOpenAIValidateRT = async (refreshTokenInput: string) => {
|
||||
extra,
|
||||
proxy_id: form.proxy_id,
|
||||
concurrency: form.concurrency,
|
||||
load_factor: form.load_factor || undefined,
|
||||
priority: form.priority,
|
||||
rate_multiplier: form.rate_multiplier,
|
||||
group_ids: form.group_ids,
|
||||
@@ -3730,6 +3743,7 @@ const handleOpenAIValidateRT = async (refreshTokenInput: string) => {
|
||||
extra: soraExtra,
|
||||
proxy_id: form.proxy_id,
|
||||
concurrency: form.concurrency,
|
||||
load_factor: form.load_factor || undefined,
|
||||
priority: form.priority,
|
||||
rate_multiplier: form.rate_multiplier,
|
||||
group_ids: form.group_ids,
|
||||
@@ -3818,6 +3832,7 @@ const handleSoraValidateST = async (sessionTokenInput: string) => {
|
||||
extra: soraExtra,
|
||||
proxy_id: form.proxy_id,
|
||||
concurrency: form.concurrency,
|
||||
load_factor: form.load_factor || undefined,
|
||||
priority: form.priority,
|
||||
rate_multiplier: form.rate_multiplier,
|
||||
group_ids: form.group_ids,
|
||||
@@ -3906,6 +3921,7 @@ const handleAntigravityValidateRT = async (refreshTokenInput: string) => {
|
||||
extra: {},
|
||||
proxy_id: form.proxy_id,
|
||||
concurrency: form.concurrency,
|
||||
load_factor: form.load_factor || undefined,
|
||||
priority: form.priority,
|
||||
rate_multiplier: form.rate_multiplier,
|
||||
group_ids: form.group_ids,
|
||||
@@ -4064,8 +4080,11 @@ const handleAnthropicExchange = async (authCode: string) => {
|
||||
}
|
||||
|
||||
// Add RPM limit settings
|
||||
if (rpmLimitEnabled.value && baseRpm.value != null && baseRpm.value > 0) {
|
||||
extra.base_rpm = baseRpm.value
|
||||
if (rpmLimitEnabled.value) {
|
||||
const DEFAULT_BASE_RPM = 15
|
||||
extra.base_rpm = (baseRpm.value != null && baseRpm.value > 0)
|
||||
? baseRpm.value
|
||||
: DEFAULT_BASE_RPM
|
||||
extra.rpm_strategy = rpmStrategy.value
|
||||
if (rpmStickyBuffer.value != null && rpmStickyBuffer.value > 0) {
|
||||
extra.rpm_sticky_buffer = rpmStickyBuffer.value
|
||||
@@ -4176,8 +4195,11 @@ const handleCookieAuth = async (sessionKey: string) => {
|
||||
}
|
||||
|
||||
// Add RPM limit settings
|
||||
if (rpmLimitEnabled.value && baseRpm.value != null && baseRpm.value > 0) {
|
||||
extra.base_rpm = baseRpm.value
|
||||
if (rpmLimitEnabled.value) {
|
||||
const DEFAULT_BASE_RPM = 15
|
||||
extra.base_rpm = (baseRpm.value != null && baseRpm.value > 0)
|
||||
? baseRpm.value
|
||||
: DEFAULT_BASE_RPM
|
||||
extra.rpm_strategy = rpmStrategy.value
|
||||
if (rpmStickyBuffer.value != null && rpmStickyBuffer.value > 0) {
|
||||
extra.rpm_sticky_buffer = rpmStickyBuffer.value
|
||||
@@ -4223,6 +4245,7 @@ const handleCookieAuth = async (sessionKey: string) => {
|
||||
extra,
|
||||
proxy_id: form.proxy_id,
|
||||
concurrency: form.concurrency,
|
||||
load_factor: form.load_factor || undefined,
|
||||
priority: form.priority,
|
||||
rate_multiplier: form.rate_multiplier,
|
||||
group_ids: form.group_ids,
|
||||
|
||||
@@ -650,11 +650,17 @@
|
||||
<ProxySelector v-model="form.proxy_id" :proxies="proxies" />
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-2 gap-4 lg:grid-cols-3">
|
||||
<div class="grid grid-cols-2 gap-4 lg:grid-cols-4">
|
||||
<div>
|
||||
<label class="input-label">{{ t('admin.accounts.concurrency') }}</label>
|
||||
<input v-model.number="form.concurrency" type="number" min="1" class="input" />
|
||||
</div>
|
||||
<div>
|
||||
<label class="input-label">{{ t('admin.accounts.loadFactor') }}</label>
|
||||
<input v-model.number="form.load_factor" type="number" min="1"
|
||||
class="input" :placeholder="String(form.concurrency || 1)" />
|
||||
<p class="input-hint">{{ t('admin.accounts.loadFactorHint') }}</p>
|
||||
</div>
|
||||
<div>
|
||||
<label class="input-label">{{ t('admin.accounts.priority') }}</label>
|
||||
<input
|
||||
@@ -1465,6 +1471,7 @@ const form = reactive({
|
||||
notes: '',
|
||||
proxy_id: null as number | null,
|
||||
concurrency: 1,
|
||||
load_factor: null as number | null,
|
||||
priority: 1,
|
||||
rate_multiplier: 1,
|
||||
status: 'active' as 'active' | 'inactive',
|
||||
@@ -1498,6 +1505,7 @@ watch(
|
||||
form.notes = newAccount.notes || ''
|
||||
form.proxy_id = newAccount.proxy_id
|
||||
form.concurrency = newAccount.concurrency
|
||||
form.load_factor = newAccount.load_factor ?? null
|
||||
form.priority = newAccount.priority
|
||||
form.rate_multiplier = newAccount.rate_multiplier ?? 1
|
||||
form.status = newAccount.status as 'active' | 'inactive'
|
||||
@@ -2049,6 +2057,10 @@ const handleSubmit = async () => {
|
||||
if (form.expires_at === null) {
|
||||
updatePayload.expires_at = 0
|
||||
}
|
||||
// load_factor: 空值/0/NaN 时发送 0(后端约定 0 = 清除)
|
||||
if (!form.load_factor || form.load_factor <= 0) {
|
||||
updatePayload.load_factor = 0
|
||||
}
|
||||
updatePayload.auto_pause_on_expired = autoPauseOnExpired.value
|
||||
|
||||
// For apikey type, handle credentials update
|
||||
@@ -2188,8 +2200,11 @@ const handleSubmit = async () => {
|
||||
}
|
||||
|
||||
// RPM limit settings
|
||||
if (rpmLimitEnabled.value && baseRpm.value != null && baseRpm.value > 0) {
|
||||
newExtra.base_rpm = baseRpm.value
|
||||
if (rpmLimitEnabled.value) {
|
||||
const DEFAULT_BASE_RPM = 15
|
||||
newExtra.base_rpm = (baseRpm.value != null && baseRpm.value > 0)
|
||||
? baseRpm.value
|
||||
: DEFAULT_BASE_RPM
|
||||
newExtra.rpm_strategy = rpmStrategy.value
|
||||
if (rpmStickyBuffer.value != null && rpmStickyBuffer.value > 0) {
|
||||
newExtra.rpm_sticky_buffer = rpmStickyBuffer.value
|
||||
|
||||
Reference in New Issue
Block a user