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

View File

@@ -1,9 +1,11 @@
<template>
<div :class="wrapperClass">
<!-- eslint-disable vue/no-v-html -->
<pre><code
:class="`language-${language}`"
v-html="highlightedCode"
:class="`language-${language}`"
v-html="highlightedCode"
/></pre>
<!-- eslint-enable vue/no-v-html -->
</div>
</template>

View File

@@ -55,10 +55,12 @@
<div class="text-left text-xs font-medium text-muted-foreground mb-2">
更新内容
</div>
<!-- eslint-disable vue/no-v-html -->
<div
class="w-full max-h-48 overflow-y-auto rounded-lg bg-muted/50 p-3 text-left text-sm text-foreground/80 prose prose-sm dark:prose-invert prose-p:my-1 prose-ul:my-1 prose-li:my-0"
v-html="renderedReleaseNotes"
/>
<!-- eslint-enable vue/no-v-html -->
</div>
<!-- Description (fallback when no release notes) -->

View File

@@ -42,6 +42,7 @@ interface Props {
}
const props = withDefaults(defineProps<Props>(), {
subtitle: undefined,
loading: false
})
@@ -81,7 +82,7 @@ const chartOptions = computed(() => ({
plugins: {
tooltip: {
callbacks: {
label: (context: any) => {
label: (context: { parsed?: { y?: number }; dataset: { label?: string } }) => {
const value = context.parsed?.y ?? 0
return `${context.dataset.label}: ${formatCurrency(value)}`
}

View File

@@ -41,6 +41,7 @@ interface Props {
}
const props = withDefaults(defineProps<Props>(), {
subtitle: undefined,
loading: false
})

View File

@@ -42,6 +42,7 @@ interface Props {
}
const props = withDefaults(defineProps<Props>(), {
subtitle: undefined,
loading: false
})

View File

@@ -71,6 +71,7 @@ interface Props {
}
withDefaults(defineProps<Props>(), {
subtitle: undefined,
loading: false
})

View File

@@ -6,7 +6,7 @@ import { computed } from 'vue'
interface Props {
class?: string
src?: string
alt: string
alt?: string
}
const props = withDefaults(defineProps<Props>(), {

View File

@@ -76,6 +76,7 @@ const warnPasswordType = import.meta.env.DEV
return () => {
if (!warned) {
warned = true
// eslint-disable-next-line no-console
console.warn(
'[Input] type="password" 已被弃用,请使用 masked 属性代替。\n' +
'示例:<Input v-model="apiKey" masked />\n' +

View File

@@ -94,7 +94,8 @@ interface Emits {
const props = withDefaults(defineProps<Props>(), {
pageSize: 20,
pageSizeOptions: () => [10, 20, 50, 100],
showPageSizeSelector: true
showPageSizeSelector: true,
cacheKey: undefined
})
const emit = defineEmits<Emits>()

View File

@@ -9,6 +9,7 @@ const props = withDefaults(defineProps<{
sideOffset?: number
alignOffset?: number
}>(), {
class: undefined,
align: 'center',
side: 'bottom',
sideOffset: 4,

View File

@@ -15,8 +15,12 @@ interface Props {
}
const props = withDefaults(defineProps<Props>(), {
defaultValue: undefined,
modelValue: undefined,
open: undefined,
dir: undefined,
name: undefined,
autocomplete: undefined,
})
const emit = defineEmits<{