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:
fawney19
2026-03-03 22:04:40 +08:00
parent 0a60492146
commit 97b0146ce9
66 changed files with 2306 additions and 657 deletions
@@ -47,6 +47,7 @@ const clearingRowAffinityKey = ref<string | null>(null)
const currentPage = ref(1)
const pageSize = ref(20)
const currentTime = ref(Math.floor(Date.now() / 1000))
const isPageVisible = ref(typeof document === 'undefined' ? true : !document.hidden)
// ==================== 模型映射缓存 ====================
@@ -236,6 +237,7 @@ function handlePageChange() {
// ==================== 定时器管理 ====================
function startCountdown() {
if (!isPageVisible.value) return
if (countdownTimer) clearInterval(countdownTimer)
countdownTimer = setInterval(() => {
@@ -260,6 +262,16 @@ function stopCountdown() {
}
}
function handleVisibilityChange() {
isPageVisible.value = !document.hidden
if (!isPageVisible.value) {
stopCountdown()
return
}
currentTime.value = Math.floor(Date.now() / 1000)
startCountdown()
}
// ==================== 模型映射缓存方法 ====================
async function fetchModelMappingStats() {
@@ -431,6 +443,7 @@ watch(tableKeyword, (value) => {
})
onMounted(() => {
document.addEventListener('visibilitychange', handleVisibilityChange)
fetchCacheStats()
fetchCacheConfig()
fetchAffinityList()
@@ -441,6 +454,7 @@ onMounted(() => {
})
onBeforeUnmount(() => {
document.removeEventListener('visibilitychange', handleVisibilityChange)
if (searchDebounceTimer) clearTimeout(searchDebounceTimer)
stopCountdown()
})