refactor: 前端全面替换 any 为 unknown 并统一错误处理,后端用量记录补写请求头/体

- 前端 API 层、stores、conversation 解析器、组件全面替换 any 为 unknown/具体类型
- 错误处理统一使用 parseApiError/getErrorStatus 替代 err.response?.data?.detail 模式
- 后端 handler/TaskService/UsageLifecycle/StreamTracker 链路传递 request_headers/request_body
- streaming/pending 状态更新时可补写客户端和提供商的请求头及请求体
- 新增 TaskService 和 UsageService 相关测试
This commit is contained in:
fawney19
2026-02-22 00:43:41 +08:00
parent 98e60e8f74
commit cf2eee222e
121 changed files with 1652 additions and 1179 deletions
@@ -3,6 +3,7 @@ import type { ProviderWithEndpointsSummary } from '@/api/endpoints'
import { batchQueryBalance, getArchitectures, type ActionResultResponse, type ArchitectureInfo } from '@/api/providerOps'
import { formatBalanceExtraFromSchema, type CredentialsSchema } from '@/features/providers/auth-templates/schema-utils'
import type { BalanceExtraItem } from '@/features/providers/auth-templates'
import { log } from '@/utils/logger'
const MAX_BALANCE_RETRIES = 3
@@ -96,7 +97,7 @@ export function useProviderBalance() {
pendingTimers.add(timerId)
}
} catch (e) {
console.warn('[loadBalances] 加载余额数据失败:', e)
log.warn('[loadBalances] 加载余额数据失败', e)
}
}
@@ -127,7 +128,7 @@ export function useProviderBalance() {
pendingTimers.add(timerId)
}
} catch (e) {
console.warn('[retryPendingBalances] 重试加载余额失败:', e)
log.warn('[retryPendingBalances] 重试加载余额失败', e)
}
}
@@ -165,7 +166,7 @@ export function useProviderBalance() {
if (!result || (result.status !== 'success' && result.status !== 'auth_expired') || !result.data) {
return null
}
const data = result.data as Record<string, any>
const data = result.data as Record<string, unknown>
const extra = data.extra
if (!extra || extra.balance === undefined || extra.points === undefined) {
return null
@@ -216,7 +217,7 @@ export function useProviderBalance() {
if (!result || result.status !== 'success' || !result.data) {
return null
}
const data = result.data as Record<string, any>
const data = result.data as Record<string, unknown>
const extra = data.extra
if (!extra || extra.checkin_success === undefined) {
return null
@@ -236,7 +237,7 @@ export function useProviderBalance() {
if (result.status !== 'success' && result.status !== 'auth_expired') {
return null
}
const data = result.data as Record<string, any>
const data = result.data as Record<string, unknown>
const extra = data.extra
if (!extra || !extra.cookie_expired) {
return null
@@ -288,7 +289,7 @@ export function useProviderBalance() {
return []
}
const data = result.data as Record<string, any>
const data = result.data as Record<string, unknown>
const extra = data.extra
if (!extra) return []
@@ -4,6 +4,7 @@
* 缓存已移至后端(Redis),前端只保留并发请求去重,避免同时发多个相同请求。
*/
import { ref } from 'vue'
import { isAxiosError } from 'axios'
import { adminApi } from '@/api/admin'
import { parseUpstreamModelError } from '@/utils/errorParser'
import type { UpstreamModel } from '@/api/endpoints/types'
@@ -42,6 +43,7 @@ export function useUpstreamModelsCache() {
// 强制刷新时不复用进行中的请求
if (!forceRefresh && pendingRequests.has(requestKey)) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
return pendingRequests.get(requestKey)!
}
@@ -62,9 +64,9 @@ export function useUpstreamModelsCache() {
const rawError = response.data?.error || '获取上游模型失败'
return { models: [], error: parseUpstreamModelError(rawError) }
}
} catch (err: any) {
const rawError = err.response?.data?.detail || err.message || '获取上游模型失败'
return { models: [], error: parseUpstreamModelError(rawError) }
} catch (err: unknown) {
const rawError = isAxiosError(err) ? (err.response?.data?.detail ?? err.message) : (err instanceof Error ? err.message : String(err))
return { models: [], error: parseUpstreamModelError(rawError || '获取上游模型失败') }
} finally {
loadingMap.value.set(requestKey, false)
pendingRequests.delete(requestKey)