mirror of
https://github.com/Wei-Shaw/claude-relay-service.git
synced 2026-01-23 09:38:02 +00:00
fix: 修复API Keys页面的undefined错误
- 修复filteredAndSortedApiKeys未定义错误,改为使用sortedApiKeys - 添加缺失的分页相关变量定义(currentPage, pageSize, totalPages等) - 添加paginatedApiKeys计算属性实现分页功能 - 修复CreateApiKeyModal和EditApiKeyModal中localAccounts防御性编程 - 添加筛选条件变化时重置页码的逻辑 - 修复"Cannot read properties of undefined (reading 'length')"错误 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -699,7 +699,12 @@ onMounted(async () => {
|
|||||||
supportedClients.value = await clientsStore.loadSupportedClients()
|
supportedClients.value = await clientsStore.loadSupportedClients()
|
||||||
availableTags.value = await apiKeysStore.fetchTags()
|
availableTags.value = await apiKeysStore.fetchTags()
|
||||||
// 初始化账号数据
|
// 初始化账号数据
|
||||||
localAccounts.value = props.accounts
|
if (props.accounts) {
|
||||||
|
localAccounts.value = {
|
||||||
|
claude: props.accounts.claude || [],
|
||||||
|
gemini: props.accounts.gemini || []
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// 刷新账号列表
|
// 刷新账号列表
|
||||||
|
|||||||
@@ -709,7 +709,12 @@ onMounted(async () => {
|
|||||||
availableTags.value = await apiKeysStore.fetchTags()
|
availableTags.value = await apiKeysStore.fetchTags()
|
||||||
|
|
||||||
// 初始化账号数据
|
// 初始化账号数据
|
||||||
localAccounts.value = props.accounts
|
if (props.accounts) {
|
||||||
|
localAccounts.value = {
|
||||||
|
claude: props.accounts.claude || [],
|
||||||
|
gemini: props.accounts.gemini || []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
form.name = props.apiKey.name
|
form.name = props.apiKey.name
|
||||||
form.tokenLimit = props.apiKey.tokenLimit || ''
|
form.tokenLimit = props.apiKey.tokenLimit || ''
|
||||||
|
|||||||
@@ -174,7 +174,7 @@
|
|||||||
</thead>
|
</thead>
|
||||||
<tbody class="divide-y divide-gray-200/50">
|
<tbody class="divide-y divide-gray-200/50">
|
||||||
<template
|
<template
|
||||||
v-for="key in sortedApiKeys"
|
v-for="key in paginatedApiKeys"
|
||||||
:key="key.id"
|
:key="key.id"
|
||||||
>
|
>
|
||||||
<!-- API Key 主行 -->
|
<!-- API Key 主行 -->
|
||||||
@@ -615,7 +615,7 @@
|
|||||||
class="md:hidden space-y-3"
|
class="md:hidden space-y-3"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
v-for="key in sortedApiKeys"
|
v-for="key in paginatedApiKeys"
|
||||||
:key="key.id"
|
:key="key.id"
|
||||||
class="card p-4 hover:shadow-lg transition-shadow"
|
class="card p-4 hover:shadow-lg transition-shadow"
|
||||||
>
|
>
|
||||||
@@ -816,12 +816,12 @@
|
|||||||
|
|
||||||
<!-- 分页组件 -->
|
<!-- 分页组件 -->
|
||||||
<div
|
<div
|
||||||
v-if="filteredAndSortedApiKeys.length > 0"
|
v-if="sortedApiKeys.length > 0"
|
||||||
class="mt-4 sm:mt-6 flex flex-col sm:flex-row justify-between items-center gap-4"
|
class="mt-4 sm:mt-6 flex flex-col sm:flex-row justify-between items-center gap-4"
|
||||||
>
|
>
|
||||||
<div class="flex flex-col sm:flex-row items-center gap-3 w-full sm:w-auto">
|
<div class="flex flex-col sm:flex-row items-center gap-3 w-full sm:w-auto">
|
||||||
<span class="text-xs sm:text-sm text-gray-600">
|
<span class="text-xs sm:text-sm text-gray-600">
|
||||||
共 {{ filteredAndSortedApiKeys.length }} 条记录
|
共 {{ sortedApiKeys.length }} 条记录
|
||||||
</span>
|
</span>
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<span class="text-xs sm:text-sm text-gray-600">每页显示</span>
|
<span class="text-xs sm:text-sm text-gray-600">每页显示</span>
|
||||||
@@ -956,7 +956,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, computed, onMounted } from 'vue'
|
import { ref, computed, onMounted, watch } from 'vue'
|
||||||
import { showToast } from '@/utils/toast'
|
import { showToast } from '@/utils/toast'
|
||||||
import { apiClient } from '@/config/api'
|
import { apiClient } from '@/config/api'
|
||||||
import { useClientsStore } from '@/stores/clients'
|
import { useClientsStore } from '@/stores/clients'
|
||||||
@@ -994,6 +994,11 @@ const availableTags = ref([])
|
|||||||
// 移动端展开状态
|
// 移动端展开状态
|
||||||
const expandedKeys = ref([])
|
const expandedKeys = ref([])
|
||||||
|
|
||||||
|
// 分页相关
|
||||||
|
const currentPage = ref(1)
|
||||||
|
const pageSize = ref(10)
|
||||||
|
const pageSizeOptions = [10, 20, 50, 100]
|
||||||
|
|
||||||
// 模态框状态
|
// 模态框状态
|
||||||
const showCreateApiKeyModal = ref(false)
|
const showCreateApiKeyModal = ref(false)
|
||||||
const showEditApiKeyModal = ref(false)
|
const showEditApiKeyModal = ref(false)
|
||||||
@@ -1045,35 +1050,48 @@ const filteredAndSortedApiKeys = computed(() => {
|
|||||||
|
|
||||||
// 计算总页数
|
// 计算总页数
|
||||||
const totalPages = computed(() => {
|
const totalPages = computed(() => {
|
||||||
return Math.ceil(filteredAndSortedApiKeys.value.length / pageSize.value)
|
const total = sortedApiKeys.value.length
|
||||||
|
return Math.ceil(total / pageSize.value) || 0
|
||||||
})
|
})
|
||||||
|
|
||||||
// 计算当前页显示的API Keys
|
// 计算显示的页码数组
|
||||||
const sortedApiKeys = computed(() => {
|
|
||||||
const start = (currentPage.value - 1) * pageSize.value
|
|
||||||
const end = start + pageSize.value
|
|
||||||
return filteredAndSortedApiKeys.value.slice(start, end)
|
|
||||||
})
|
|
||||||
|
|
||||||
// 计算要显示的页码
|
|
||||||
const pageNumbers = computed(() => {
|
const pageNumbers = computed(() => {
|
||||||
const pages = []
|
const pages = []
|
||||||
const maxPagesToShow = 5
|
const current = currentPage.value
|
||||||
let startPage = Math.max(1, currentPage.value - Math.floor(maxPagesToShow / 2))
|
const total = totalPages.value
|
||||||
let endPage = Math.min(totalPages.value, startPage + maxPagesToShow - 1)
|
|
||||||
|
|
||||||
// 调整起始页
|
if (total <= 7) {
|
||||||
if (endPage - startPage < maxPagesToShow - 1) {
|
// 如果总页数小于等于7,显示所有页码
|
||||||
startPage = Math.max(1, endPage - maxPagesToShow + 1)
|
for (let i = 1; i <= total; i++) {
|
||||||
|
pages.push(i)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 如果总页数大于7,显示部分页码
|
||||||
|
let start = Math.max(1, current - 2)
|
||||||
|
let end = Math.min(total, current + 2)
|
||||||
|
|
||||||
|
// 调整起始和结束页码
|
||||||
|
if (current <= 3) {
|
||||||
|
end = 5
|
||||||
|
} else if (current >= total - 2) {
|
||||||
|
start = total - 4
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let i = startPage; i <= endPage; i++) {
|
for (let i = start; i <= end; i++) {
|
||||||
pages.push(i)
|
pages.push(i)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return pages
|
return pages
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 获取分页后的数据
|
||||||
|
const paginatedApiKeys = computed(() => {
|
||||||
|
const start = (currentPage.value - 1) * pageSize.value
|
||||||
|
const end = start + pageSize.value
|
||||||
|
return sortedApiKeys.value.slice(start, end)
|
||||||
|
})
|
||||||
|
|
||||||
// 加载账户列表
|
// 加载账户列表
|
||||||
const loadAccounts = async () => {
|
const loadAccounts = async () => {
|
||||||
try {
|
try {
|
||||||
@@ -1588,6 +1606,11 @@ const showApiKey = async (apiKey) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 监听筛选条件变化,重置页码
|
||||||
|
watch([selectedTagFilter, apiKeyStatsTimeRange], () => {
|
||||||
|
currentPage.value = 1
|
||||||
|
})
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
// 并行加载所有需要的数据
|
// 并行加载所有需要的数据
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
|
|||||||
Reference in New Issue
Block a user