feat(codex): 支持compact端点非流式请求,更新请求头与字段清理

- Codex适配器支持compact端点:非流式请求使用application/json Accept头,
  stream_policy根据compact上下文返回FORCE_NON_STREAM
- 更新Codex请求头格式:添加Version/Connection头,header key首字母大写
- 简化include列表处理:normalizer和request_patching统一强制为固定列表
- 清理Codex不支持的字段:truncation、context_management、user
- 默认instructions改为空字符串
- 前端用量页面:用户页面使用前端筛选后总数,避免不必要的后端分页请求
This commit is contained in:
fawney19
2026-03-01 18:20:42 +08:00
parent d4840df447
commit a137601728
9 changed files with 190 additions and 67 deletions

View File

@@ -172,7 +172,7 @@ export function useUsageData(options: UseUsageDataOptions) {
// 使用 mergeRecordStatus 保护已有的活跃状态,避免轮询更新被覆盖
const nextRecords = (userData.records || []) as UsageRecord[]
currentRecords.value = mergeRecordStatus(currentRecords.value, nextRecords)
totalRecords.value = currentRecords.value.length
totalRecords.value = userData.pagination?.total ?? currentRecords.value.length
// 从记录中提取筛选选项和 API 格式统计
const models = new Set<string>()

View File

@@ -67,7 +67,7 @@
:available-providers="availableProviders"
:current-page="currentPage"
:page-size="pageSize"
:total-records="totalRecords"
:total-records="effectiveTotalRecords"
:page-size-options="pageSizeOptions"
:auto-refresh="globalAutoRefresh"
@update:time-range="handleTimeRangeChange"
@@ -391,7 +391,7 @@ onUnmounted(() => {
stopGlobalAutoRefresh()
})
// 用户页面的前端分页
// 用户页面的前端分页(后端一次性返回所有记录,前端分页+筛选)
const paginatedRecords = computed(() => {
if (!isAdminPage.value) {
const start = (currentPage.value - 1) * pageSize.value
@@ -401,6 +401,14 @@ const paginatedRecords = computed(() => {
return currentRecords.value
})
// 用户页面使用前端筛选后的总数,管理员页面使用后端返回的总数
const effectiveTotalRecords = computed(() => {
if (!isAdminPage.value) {
return filteredRecords.value.length
}
return totalRecords.value
})
// 显示的记录
const displayRecords = computed(() => paginatedRecords.value)
@@ -419,20 +427,22 @@ onMounted(async () => {
const heatmapTask = loadHeatmapData().catch(err => {
log.error('加载热力图数据失败:', err)
})
const recordsTask = loadRecords(
{ page: currentPage.value, pageSize: pageSize.value },
getCurrentFilters()
)
const tasks: Promise<unknown>[] = [statsTask, heatmapTask, recordsTask]
const tasks: Promise<unknown>[] = [statsTask, heatmapTask]
if (isAdminPage.value) {
// 管理员页面stats 和 records 分开加载(后端分页)
tasks.push(loadRecords(
{ page: currentPage.value, pageSize: pageSize.value },
getCurrentFilters()
))
tasks.push(
usersApi.getAllUsers().then(users => {
availableUsers.value = users.map(u => ({ id: u.id, username: u.username, email: u.email }))
})
)
}
// 用户页面loadStats 已包含记录加载,不需要单独调用 loadRecords
await Promise.allSettled(tasks)
})
@@ -442,20 +452,29 @@ async function handleTimeRangeChange(value: DateRangeParams) {
timeRange.value = value
currentPage.value = 1 // 重置到第一页
await loadStats(timeRange.value)
await loadRecords({ page: 1, pageSize: pageSize.value }, getCurrentFilters())
if (isAdminPage.value) {
await loadRecords({ page: 1, pageSize: pageSize.value }, getCurrentFilters())
}
// 用户页面loadStats 已包含记录加载
}
// 处理分页变化
async function handlePageChange(page: number) {
currentPage.value = page
await loadRecords({ page, pageSize: pageSize.value }, getCurrentFilters())
if (isAdminPage.value) {
await loadRecords({ page, pageSize: pageSize.value }, getCurrentFilters())
}
// 用户页面使用前端分页,无需重新请求
}
// 处理每页大小变化
async function handlePageSizeChange(size: number) {
pageSize.value = size
currentPage.value = 1 // 重置到第一页
await loadRecords({ page: 1, pageSize: size }, getCurrentFilters())
if (isAdminPage.value) {
await loadRecords({ page: 1, pageSize: size }, getCurrentFilters())
}
// 用户页面使用前端分页,无需重新请求
}
// 获取当前筛选参数
@@ -475,7 +494,11 @@ async function handleFilterSearchChange(value: string) {
filterSearch.value = value
currentPage.value = 1
await loadRecords({ page: 1, pageSize: pageSize.value }, getCurrentFilters())
if (isAdminPage.value) {
await loadRecords({ page: 1, pageSize: pageSize.value }, getCurrentFilters())
}
// 用户页面search 需要重新从后端拉取数据(后端支持 search 参数)
// 但通过 filteredRecords 做前端过滤已覆盖,无需额外请求
}
async function handleFilterUserChange(value: string) {
@@ -526,7 +549,10 @@ async function handleFilterStatusChange(value: string) {
// 刷新数据
async function refreshData() {
await loadStats(timeRange.value)
await loadRecords({ page: currentPage.value, pageSize: pageSize.value }, getCurrentFilters())
if (isAdminPage.value) {
await loadRecords({ page: currentPage.value, pageSize: pageSize.value }, getCurrentFilters())
}
// 用户页面loadStats 已包含记录加载
}
// 显示请求详情