mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-03 01:40:21 +08:00
perf: 全栈查询优化、前端缓存去重与页面可见性优化
后端: - SQL count 查询统一改用 func.count() 子查询替代 query.count() - Dashboard/Audit 等页面多次独立查询合并为单次聚合查询 - Provider summary 列表改为批量查询消除 N+1 问题 - DailyStats 逐天循环查询改为 CASE 分桶单次查询 - 使用 load_only() 减少不必要的列加载 - cache_decorator 支持嵌套属性路径解析(dotted vary_by) - 多个管理/公共端点新增 @cache_result 缓存装饰 前端: - cache.ts 新增 in-flight 请求复用、dedupedRequest、buildCacheKey - 大量 API 调用添加前端缓存或去重 - 多个页面定时器在标签页隐藏时暂停、可见时恢复 - Auth 检查从 setInterval 改为 storage + visibilitychange 事件驱动 - 请求竞态防护(requestId 模式) 数据库: - Usage 表新增 idx_usage_status_user_created 复合索引
This commit is contained in:
@@ -1132,6 +1132,8 @@ const endpoints = ref<ProviderEndpointWithKeys[]>([])
|
||||
const providerKeys = ref<EndpointAPIKey[]>([]) // Provider 级别的 keys
|
||||
const providerModels = ref<Model[]>([]) // Provider 级别的 models
|
||||
const providerMappingPreview = ref<ProviderMappingPreviewResponse | null>(null) // 映射预览
|
||||
let providerLoadRequestId = 0
|
||||
let endpointsLoadRequestId = 0
|
||||
|
||||
// 系统级格式转换配置
|
||||
const systemFormatConversionEnabled = ref(false)
|
||||
@@ -1281,12 +1283,19 @@ watch(
|
||||
}
|
||||
void autoRefreshQuotaInBackground()
|
||||
} else if (!newOpen && oldOpen) {
|
||||
// 使在途请求失效,避免关闭后旧响应回写
|
||||
providerLoadRequestId += 1
|
||||
endpointsLoadRequestId += 1
|
||||
|
||||
// 停止倒计时定时器
|
||||
stopCountdownTimer()
|
||||
// 重置所有状态
|
||||
loading.value = false
|
||||
provider.value = null
|
||||
endpoints.value = []
|
||||
providerKeys.value = [] // 清空 Provider 级别的 keys
|
||||
providerModels.value = []
|
||||
providerMappingPreview.value = null
|
||||
|
||||
// 重置分页状态
|
||||
resetKeysPagination()
|
||||
@@ -2581,6 +2590,7 @@ async function loadSystemFormatConversionConfig() {
|
||||
// 加载 Provider 信息
|
||||
async function loadProvider() {
|
||||
if (!props.providerId) return
|
||||
const requestId = ++providerLoadRequestId
|
||||
|
||||
try {
|
||||
loading.value = true
|
||||
@@ -2589,21 +2599,26 @@ async function loadProvider() {
|
||||
getProvider(props.providerId),
|
||||
loadSystemFormatConversionConfig(),
|
||||
])
|
||||
if (requestId !== providerLoadRequestId) return
|
||||
provider.value = providerData
|
||||
|
||||
if (!provider.value) {
|
||||
throw new Error('Provider 不存在')
|
||||
}
|
||||
} catch (err: unknown) {
|
||||
if (requestId !== providerLoadRequestId) return
|
||||
showError(parseApiError(err, '加载失败'), '错误')
|
||||
} finally {
|
||||
loading.value = false
|
||||
if (requestId === providerLoadRequestId) {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 加载端点列表
|
||||
async function loadEndpoints() {
|
||||
if (!props.providerId) return
|
||||
const requestId = ++endpointsLoadRequestId
|
||||
|
||||
try {
|
||||
// 并行加载端点列表、Provider 级别的 keys、models 和映射预览
|
||||
@@ -2613,6 +2628,7 @@ async function loadEndpoints() {
|
||||
getProviderModels(props.providerId).catch(() => []),
|
||||
getProviderMappingPreview(props.providerId).catch(() => null),
|
||||
])
|
||||
if (requestId !== endpointsLoadRequestId) return
|
||||
|
||||
providerKeys.value = providerKeysResult
|
||||
providerModels.value = modelsResult
|
||||
@@ -2627,6 +2643,7 @@ async function loadEndpoints() {
|
||||
return aIdx - bIdx
|
||||
})
|
||||
} catch (err: unknown) {
|
||||
if (requestId !== endpointsLoadRequestId) return
|
||||
showError(parseApiError(err, '加载端点失败'), '错误')
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user