merge upstream/main

This commit is contained in:
LLLLLLiulei
2026-02-06 11:33:45 +08:00
89 changed files with 10119 additions and 343 deletions

View File

@@ -16,6 +16,16 @@
@sync="showSync = true"
@create="showCreate = true"
>
<template #before>
<button
@click="showErrorPassthrough = true"
class="btn btn-secondary"
:title="t('admin.errorPassthrough.title')"
>
<Icon name="shield" size="md" class="mr-1.5" />
<span class="hidden md:inline">{{ t('admin.errorPassthrough.title') }}</span>
</button>
</template>
<template #after>
<!-- Auto Refresh Dropdown -->
<div class="relative" ref="autoRefreshDropdownRef">
@@ -245,6 +255,7 @@
<span>{{ t('admin.accounts.dataExportIncludeProxies') }}</span>
</label>
</ConfirmDialog>
<ErrorPassthroughRulesModal :show="showErrorPassthrough" @close="showErrorPassthrough = false" />
</AppLayout>
</template>
@@ -277,6 +288,7 @@ import AccountGroupsCell from '@/components/account/AccountGroupsCell.vue'
import AccountCapacityCell from '@/components/account/AccountCapacityCell.vue'
import PlatformTypeBadge from '@/components/common/PlatformTypeBadge.vue'
import Icon from '@/components/icons/Icon.vue'
import ErrorPassthroughRulesModal from '@/components/admin/ErrorPassthroughRulesModal.vue'
import { formatDateTime, formatRelativeTime } from '@/utils/format'
import type { Account, Proxy, AdminGroup } from '@/types'
@@ -299,6 +311,7 @@ const showDeleteDialog = ref(false)
const showReAuth = ref(false)
const showTest = ref(false)
const showStats = ref(false)
const showErrorPassthrough = ref(false)
const edAcc = ref<Account | null>(null)
const tempUnschedAcc = ref<Account | null>(null)
const deletingAcc = ref<Account | null>(null)
@@ -441,7 +454,8 @@ const isAnyModalOpen = computed(() => {
showDeleteDialog.value ||
showReAuth.value ||
showTest.value ||
showStats.value
showStats.value ||
showErrorPassthrough.value
)
})

View File

@@ -73,6 +73,7 @@
:platform="row.group.platform"
:subscription-type="row.group.subscription_type"
:rate-multiplier="row.group.rate_multiplier"
:user-rate-multiplier="userGroupRates[row.group.id]"
/>
<span v-else class="text-sm text-gray-400 dark:text-dark-500">{{
t('keys.noGroup')
@@ -272,6 +273,7 @@
:platform="(option as unknown as GroupOption).platform"
:subscription-type="(option as unknown as GroupOption).subscriptionType"
:rate-multiplier="(option as unknown as GroupOption).rate"
:user-rate-multiplier="(option as unknown as GroupOption).userRate"
/>
<span v-else class="text-gray-400">{{ t('keys.selectGroup') }}</span>
</template>
@@ -281,6 +283,7 @@
:platform="(option as unknown as GroupOption).platform"
:subscription-type="(option as unknown as GroupOption).subscriptionType"
:rate-multiplier="(option as unknown as GroupOption).rate"
:user-rate-multiplier="(option as unknown as GroupOption).userRate"
:description="(option as unknown as GroupOption).description"
:selected="selected"
/>
@@ -667,6 +670,7 @@
:platform="option.platform"
:subscription-type="option.subscriptionType"
:rate-multiplier="option.rate"
:user-rate-multiplier="option.userRate"
:description="option.description"
:selected="
selectedKeyForGroup?.group_id === option.value ||
@@ -718,6 +722,7 @@ interface GroupOption {
label: string
description: string | null
rate: number
userRate: number | null
subscriptionType: SubscriptionType
platform: GroupPlatform
}
@@ -742,6 +747,7 @@ const groups = ref<Group[]>([])
const loading = ref(false)
const submitting = ref(false)
const usageStats = ref<Record<string, BatchApiKeyUsageStats>>({})
const userGroupRates = ref<Record<number, number>>({})
const pagination = ref({
page: 1,
@@ -825,6 +831,7 @@ const groupOptions = computed(() =>
label: group.name,
description: group.description,
rate: group.rate_multiplier,
userRate: userGroupRates.value[group.id] ?? null,
subscriptionType: group.subscription_type,
platform: group.platform
}))
@@ -899,6 +906,14 @@ const loadGroups = async () => {
}
}
const loadUserGroupRates = async () => {
try {
userGroupRates.value = await userGroupsAPI.getUserGroupRates()
} catch (error) {
console.error('Failed to load user group rates:', error)
}
}
const loadPublicSettings = async () => {
try {
publicSettings.value = await authAPI.getPublicSettings()
@@ -1268,6 +1283,7 @@ const closeCcsClientSelect = () => {
onMounted(() => {
loadApiKeys()
loadGroups()
loadUserGroupRates()
loadPublicSettings()
document.addEventListener('click', closeGroupSelector)
})