Merge pull request #854 from james-6-23/main

feat(admin): 支持定时测试自动恢复并统一账号恢复入口
This commit is contained in:
Wesley Liddick
2026-03-09 08:48:36 +08:00
committed by GitHub
23 changed files with 535 additions and 92 deletions

View File

@@ -263,7 +263,7 @@
<AccountTestModal :show="showTest" :account="testingAcc" @close="closeTestModal" />
<AccountStatsModal :show="showStats" :account="statsAcc" @close="closeStatsModal" />
<ScheduledTestsPanel :show="showSchedulePanel" :account-id="scheduleAcc?.id ?? null" :model-options="scheduleModelOptions" @close="closeSchedulePanel" />
<AccountActionMenu :show="menu.show" :account="menu.acc" :position="menu.pos" @close="menu.show = false" @test="handleTest" @stats="handleViewStats" @schedule="handleSchedule" @reauth="handleReAuth" @refresh-token="handleRefresh" @reset-status="handleResetStatus" @clear-rate-limit="handleClearRateLimit" @reset-quota="handleResetQuota" />
<AccountActionMenu :show="menu.show" :account="menu.acc" :position="menu.pos" @close="menu.show = false" @test="handleTest" @stats="handleViewStats" @schedule="handleSchedule" @reauth="handleReAuth" @refresh-token="handleRefresh" @recover-state="handleRecoverState" @reset-quota="handleResetQuota" />
<SyncFromCrsModal :show="showSync" @close="showSync = false" @synced="reload" />
<ImportDataModal :show="showImportData" @close="showImportData = false" @imported="handleDataImported" />
<BulkEditAccountModal :show="showBulkEdit" :account-ids="selIds" :selected-platforms="selPlatforms" :selected-types="selTypes" :proxies="proxies" :groups="groups" @close="showBulkEdit = false" @updated="handleBulkUpdated" />
@@ -572,16 +572,17 @@ const resetAutoRefreshCache = () => {
const isFirstLoad = ref(true)
const load = async () => {
const requestParams = params as any
hasPendingListSync.value = false
resetAutoRefreshCache()
pendingTodayStatsRefresh.value = false
if (isFirstLoad.value) {
;(params as any).lite = '1'
requestParams.lite = '1'
}
await baseLoad()
if (isFirstLoad.value) {
isFirstLoad.value = false
delete (params as any).lite
delete requestParams.lite
}
await refreshTodayStatsBatch()
}
@@ -1116,24 +1117,15 @@ const handleRefresh = async (a: Account) => {
console.error('Failed to refresh credentials:', error)
}
}
const handleResetStatus = async (a: Account) => {
const handleRecoverState = async (a: Account) => {
try {
const updated = await adminAPI.accounts.clearError(a.id)
const updated = await adminAPI.accounts.recoverState(a.id)
patchAccountInList(updated)
enterAutoRefreshSilentWindow()
appStore.showSuccess(t('common.success'))
} catch (error) {
console.error('Failed to reset status:', error)
}
}
const handleClearRateLimit = async (a: Account) => {
try {
const updated = await adminAPI.accounts.clearRateLimit(a.id)
patchAccountInList(updated)
enterAutoRefreshSilentWindow()
appStore.showSuccess(t('common.success'))
} catch (error) {
console.error('Failed to clear rate limit:', error)
appStore.showSuccess(t('admin.accounts.recoverStateSuccess'))
} catch (error: any) {
console.error('Failed to recover account state:', error)
appStore.showError(error?.message || t('admin.accounts.recoverStateFailed'))
}
}
const handleResetQuota = async (a: Account) => {
@@ -1163,17 +1155,11 @@ const handleToggleSchedulable = async (a: Account) => {
}
}
const handleShowTempUnsched = (a: Account) => { tempUnschedAcc.value = a; showTempUnsched.value = true }
const handleTempUnschedReset = async () => {
if(!tempUnschedAcc.value) return
try {
const updated = await adminAPI.accounts.clearError(tempUnschedAcc.value.id)
showTempUnsched.value = false
tempUnschedAcc.value = null
patchAccountInList(updated)
enterAutoRefreshSilentWindow()
} catch (error) {
console.error('Failed to reset temp unscheduled:', error)
}
const handleTempUnschedReset = async (updated: Account) => {
showTempUnsched.value = false
tempUnschedAcc.value = null
patchAccountInList(updated)
enterAutoRefreshSilentWindow()
}
const formatExpiresAt = (value: number | null) => {
if (!value) return '-'

View File

@@ -552,9 +552,10 @@ const loadDashboardSnapshot = async (includeStats: boolean) => {
appStore.showError(t('admin.dashboard.failedToLoad'))
console.error('Error loading dashboard snapshot:', error)
} finally {
if (currentSeq !== chartLoadSeq) return
loading.value = false
chartsLoading.value = false
if (currentSeq === chartLoadSeq) {
loading.value = false
chartsLoading.value = false
}
}
}
@@ -575,8 +576,9 @@ const loadUsersTrend = async () => {
console.error('Error loading users trend:', error)
userTrend.value = []
} finally {
if (currentSeq !== usersTrendLoadSeq) return
userTrendLoading.value = false
if (currentSeq === usersTrendLoadSeq) {
userTrendLoading.value = false
}
}
}