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
+8 -5
View File
@@ -498,6 +498,8 @@ import RefreshButton from '@/components/ui/refresh-button.vue'
import { Plus, Key, Copy, Trash2, Loader2, Activity, CheckCircle, Power, Check } from 'lucide-vue-next'
import { useToast } from '@/composables/useToast'
import { log } from '@/utils/logger'
import { parseApiError } from '@/utils/errorParser'
import { getErrorStatus } from '@/types/api-error'
import { computed } from 'vue'
const { success, error: showError } = useToast()
@@ -548,14 +550,15 @@ async function loadApiKeys() {
loading.value = true
try {
apiKeys.value = await meApi.getApiKeys()
} catch (error: any) {
} catch (error: unknown) {
log.error('加载 API 密钥失败:', error)
if (!error.response) {
const status = getErrorStatus(error)
if (status === undefined) {
showError('无法连接到服务器,请检查后端服务是否运行')
} else if (error.response.status === 401) {
} else if (status === 401) {
showError('认证失败,请重新登录')
} else {
showError(`加载 API 密钥失败:${ error.response?.data?.detail || error.message}`)
showError(parseApiError(error, '加载 API 密钥失败'))
}
} finally {
loading.value = false
@@ -596,7 +599,7 @@ async function deleteApiKey() {
deleting.value = true
try {
await meApi.deleteApiKey(keyToDelete.value.id)
apiKeys.value = apiKeys.value.filter(k => k.id !== keyToDelete.value!.id)
apiKeys.value = apiKeys.value.filter(k => k.id !== keyToDelete.value?.id)
showDeleteDialog.value = false
success('API 密钥已删除')
} catch (error) {