+
0) {
confirmMessage += `\n\n⚠️ 注意:此账号有 ${boundKeysCount} 个 API Key 绑定。`
@@ -2147,49 +2303,112 @@ const deleteAccount = async (account) => {
if (!confirmed) return
- try {
- let endpoint
- if (account.platform === 'claude') {
- endpoint = `/admin/claude-accounts/${account.id}`
- } else if (account.platform === 'claude-console') {
- endpoint = `/admin/claude-console-accounts/${account.id}`
- } else if (account.platform === 'bedrock') {
- endpoint = `/admin/bedrock-accounts/${account.id}`
- } else if (account.platform === 'openai') {
- endpoint = `/admin/openai-accounts/${account.id}`
- } else if (account.platform === 'azure_openai') {
- endpoint = `/admin/azure-openai-accounts/${account.id}`
- } else if (account.platform === 'openai-responses') {
- endpoint = `/admin/openai-responses-accounts/${account.id}`
- } else if (account.platform === 'ccr') {
- endpoint = `/admin/ccr-accounts/${account.id}`
- } else {
- endpoint = `/admin/gemini-accounts/${account.id}`
+ const result = await performAccountDeletion(account)
+
+ if (result.success) {
+ const data = result.data
+ let toastMessage = '账户已成功删除'
+ if (data?.unboundKeys > 0) {
+ toastMessage += `,${data.unboundKeys} 个 API Key 已切换为共享池模式`
}
+ showToast(toastMessage, 'success')
- const data = await apiClient.delete(endpoint)
+ selectedAccounts.value = selectedAccounts.value.filter((id) => id !== account.id)
+ updateSelectAllState()
- if (data.success) {
- // 根据解绑结果显示不同的消息
- let toastMessage = '账户已成功删除'
- if (data.unboundKeys > 0) {
- toastMessage += `,${data.unboundKeys} 个 API Key 已切换为共享池模式`
- }
- showToast(toastMessage, 'success')
-
- // 清空相关缓存
- groupMembersLoaded.value = false
- apiKeysLoaded.value = false // 重新加载API Keys以反映解绑变化
- loadAccounts()
- loadApiKeys(true) // 强制重新加载API Keys
- } else {
- showToast(data.message || '删除失败', 'error')
- }
- } catch (error) {
- showToast('删除失败', 'error')
+ groupMembersLoaded.value = false
+ apiKeysLoaded.value = false
+ loadAccounts()
+ loadApiKeys(true)
+ } else {
+ showToast(result.message || '删除失败', 'error')
}
}
+// 批量删除账户
+const batchDeleteAccounts = async () => {
+ if (selectedAccounts.value.length === 0) {
+ showToast('请先选择要删除的账户', 'warning')
+ return
+ }
+
+ const accountsMap = new Map(accounts.value.map((item) => [item.id, item]))
+ const targets = selectedAccounts.value
+ .map((id) => accountsMap.get(id))
+ .filter((account) => !!account)
+
+ if (targets.length === 0) {
+ showToast('选中的账户已不存在', 'warning')
+ selectedAccounts.value = []
+ updateSelectAllState()
+ return
+ }
+
+ let confirmMessage = `确定要删除选中的 ${targets.length} 个账户吗?此操作不可恢复。`
+ const boundInfo = targets
+ .map((account) => ({ account, boundKeys: getBoundApiKeysForAccount(account) }))
+ .filter((item) => item.boundKeys.length > 0)
+
+ if (boundInfo.length > 0) {
+ confirmMessage += '\n\n⚠️ 以下账户存在绑定的 API Key,将自动解绑:'
+ boundInfo.forEach(({ account, boundKeys }) => {
+ const displayName = account.name || account.email || account.accountName || account.id
+ confirmMessage += `\n- ${displayName}: ${boundKeys.length} 个`
+ })
+ confirmMessage += '\n删除后,这些 API Key 将切换为共享池模式。'
+ }
+
+ confirmMessage += '\n\n请再次确认是否继续。'
+
+ const confirmed = await showConfirm('批量删除账户', confirmMessage, '删除', '取消')
+ if (!confirmed) return
+
+ let successCount = 0
+ let failedCount = 0
+ let totalUnboundKeys = 0
+ const failedDetails = []
+
+ for (const account of targets) {
+ const result = await performAccountDeletion(account)
+ if (result.success) {
+ successCount += 1
+ totalUnboundKeys += result.data?.unboundKeys || 0
+ } else {
+ failedCount += 1
+ failedDetails.push({
+ name: account.name || account.email || account.accountName || account.id,
+ message: result.message || '删除失败'
+ })
+ }
+ }
+
+ if (successCount > 0) {
+ let toastMessage = `成功删除 ${successCount} 个账户`
+ if (totalUnboundKeys > 0) {
+ toastMessage += `,${totalUnboundKeys} 个 API Key 已切换为共享池模式`
+ }
+ showToast(toastMessage, failedCount > 0 ? 'warning' : 'success')
+
+ selectedAccounts.value = []
+ selectAllChecked.value = false
+ isIndeterminate.value = false
+
+ groupMembersLoaded.value = false
+ apiKeysLoaded.value = false
+ await loadAccounts(true)
+ }
+
+ if (failedCount > 0) {
+ const detailMessage = failedDetails.map((item) => `${item.name}: ${item.message}`).join('\n')
+ showToast(
+ `有 ${failedCount} 个账户删除失败:\n${detailMessage}`,
+ successCount > 0 ? 'warning' : 'error'
+ )
+ }
+
+ updateSelectAllState()
+}
+
// 重置账户状态
const resetAccountStatus = async (account) => {
if (account.isResetting) return
@@ -2747,10 +2966,12 @@ const calculateDailyCost = (account) => {
watch(searchKeyword, () => {
currentPage.value = 1
+ updateSelectAllState()
})
watch(pageSize, (newSize) => {
localStorage.setItem(PAGE_SIZE_STORAGE_KEY, newSize.toString())
+ updateSelectAllState()
})
watch(
@@ -2759,6 +2980,7 @@ watch(
if (currentPage.value > totalPages.value) {
currentPage.value = totalPages.value || 1
}
+ updateSelectAllState()
}
)
@@ -2777,6 +2999,18 @@ watch(accountSortBy, (newVal) => {
}
})
+watch(currentPage, () => {
+ updateSelectAllState()
+})
+
+watch(paginatedAccounts, () => {
+ updateSelectAllState()
+})
+
+watch(accounts, () => {
+ cleanupSelectedAccounts()
+})
+
onMounted(() => {
// 首次加载时强制刷新所有数据
loadAccounts(true)