mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-02 09:20:22 +08:00
refactor: Antigravity/Codex 服务重构为插件化适配器架构
- 将 Antigravity 和 Codex 从独立模块迁移至 src/services/provider/adapters/ 插件体系 - 新增 provider_types 和 oauth_token 模块,移除 maintenance_scheduler 中的 OAuth 定时刷新 - 增强 admin API:扩展 keys 和 provider_query 端点,新增 dashboard 路由 - 大幅增强 ProviderDetailDrawer 组件,新增 AntigravityQuotaDialog - 改进 handler 基类(chat/cli)和错误分类器 - 优化 fetch_scheduler 和 upstream_fetcher - 前端 UI 组件清理和优化 - 更新测试以匹配新模块结构
This commit is contained in:
@@ -39,7 +39,6 @@
|
||||
<!-- 状态筛选 -->
|
||||
<Select
|
||||
v-model="filterStatus"
|
||||
v-model:open="filterStatusOpen"
|
||||
>
|
||||
<SelectTrigger class="w-20 sm:w-28 h-8 text-xs border-border/60">
|
||||
<SelectValue placeholder="全部状态" />
|
||||
@@ -58,7 +57,6 @@
|
||||
<!-- 余额类型筛选 -->
|
||||
<Select
|
||||
v-model="filterBalance"
|
||||
v-model:open="filterBalanceOpen"
|
||||
>
|
||||
<SelectTrigger class="w-20 sm:w-28 h-8 text-xs border-border/60">
|
||||
<SelectValue placeholder="全部类型" />
|
||||
@@ -759,9 +757,7 @@ const EXPIRY_SOON_DAYS = 7
|
||||
// 筛选相关
|
||||
const searchQuery = ref('')
|
||||
const filterStatus = ref<'all' | 'active' | 'inactive'>('all')
|
||||
const filterStatusOpen = ref(false)
|
||||
const filterBalance = ref<'all' | 'limited' | 'unlimited'>('all')
|
||||
const filterBalanceOpen = ref(false)
|
||||
|
||||
const statusFilters = [
|
||||
{ value: 'all' as const, label: '全部状态' },
|
||||
|
||||
@@ -93,7 +93,6 @@
|
||||
<div class="flex items-center gap-2">
|
||||
<!-- 状态筛选 -->
|
||||
<Select
|
||||
v-model:open="statusSelectOpen"
|
||||
v-model="filterStatus"
|
||||
>
|
||||
<SelectTrigger class="w-28 h-8 text-xs border-border/60">
|
||||
@@ -895,7 +894,6 @@ const total = ref(0)
|
||||
const currentPage = ref(1)
|
||||
const pageSize = ref(20)
|
||||
const filterStatus = ref('all')
|
||||
const statusSelectOpen = ref(false)
|
||||
const filterModel = ref('')
|
||||
const showDetail = ref(false)
|
||||
const selectedTask = ref<AsyncTaskDetail | null>(null)
|
||||
|
||||
@@ -33,7 +33,6 @@
|
||||
<!-- 事件类型筛选 -->
|
||||
<Select
|
||||
v-model="filters.eventType"
|
||||
v-model:open="eventTypeSelectOpen"
|
||||
@update:model-value="handleEventTypeChange"
|
||||
>
|
||||
<SelectTrigger class="w-24 sm:w-40 h-8 border-border/60">
|
||||
@@ -78,7 +77,6 @@
|
||||
<!-- 时间范围筛选 -->
|
||||
<Select
|
||||
v-model="filtersDaysString"
|
||||
v-model:open="daysSelectOpen"
|
||||
@update:model-value="handleDaysChange"
|
||||
>
|
||||
<SelectTrigger class="w-20 sm:w-28 h-8 border-border/60">
|
||||
@@ -468,9 +466,6 @@ const selectedLog = ref<AuditLog | null>(null)
|
||||
// 搜索查询
|
||||
const searchQuery = ref('')
|
||||
|
||||
// Select open state
|
||||
const eventTypeSelectOpen = ref(false)
|
||||
const daysSelectOpen = ref(false)
|
||||
|
||||
const filters = ref({
|
||||
username: '',
|
||||
|
||||
@@ -46,7 +46,6 @@ const clearingRowAffinityKey = ref<string | null>(null)
|
||||
const currentPage = ref(1)
|
||||
const pageSize = ref(20)
|
||||
const currentTime = ref(Math.floor(Date.now() / 1000))
|
||||
const analysisHoursSelectOpen = ref(false)
|
||||
|
||||
// ==================== 模型映射缓存 ====================
|
||||
|
||||
@@ -1060,7 +1059,6 @@ onBeforeUnmount(() => {
|
||||
<div class="flex flex-wrap items-center gap-2">
|
||||
<Select
|
||||
v-model="analysisHours"
|
||||
v-model:open="analysisHoursSelectOpen"
|
||||
>
|
||||
<SelectTrigger class="w-24 sm:w-28 h-8">
|
||||
<SelectValue placeholder="时间段" />
|
||||
|
||||
@@ -159,7 +159,6 @@
|
||||
</Label>
|
||||
<Select
|
||||
v-model="smtpEncryption"
|
||||
v-model:open="smtpEncryptionSelectOpen"
|
||||
>
|
||||
<SelectTrigger
|
||||
id="smtp-encryption"
|
||||
@@ -239,7 +238,6 @@
|
||||
</Label>
|
||||
<Select
|
||||
v-model="emailConfig.email_suffix_mode"
|
||||
v-model:open="emailSuffixModeSelectOpen"
|
||||
:disabled="!requireEmailVerification"
|
||||
>
|
||||
<SelectTrigger
|
||||
@@ -509,8 +507,6 @@ interface EmailConfig {
|
||||
|
||||
const smtpSaveLoading = ref(false)
|
||||
const emailVerificationSaveLoading = ref(false)
|
||||
const smtpEncryptionSelectOpen = ref(false)
|
||||
const emailSuffixModeSelectOpen = ref(false)
|
||||
const testSmtpLoading = ref(false)
|
||||
const smtpPasswordIsSet = ref(false)
|
||||
const requireEmailVerification = ref(false) // 是否开启了邮箱验证
|
||||
|
||||
@@ -565,6 +565,7 @@
|
||||
<ProviderFormDialog
|
||||
v-model="providerDialogOpen"
|
||||
:provider="providerToEdit"
|
||||
:max-priority="maxProviderPriority"
|
||||
@provider-created="handleProviderAdded"
|
||||
@provider-updated="handleProviderUpdated"
|
||||
/>
|
||||
@@ -672,6 +673,13 @@ const priorityModeConfig = computed(() => {
|
||||
}
|
||||
})
|
||||
|
||||
// 当前已有提供商的最大优先级
|
||||
const maxProviderPriority = computed(() => {
|
||||
if (providers.value.length === 0) return undefined
|
||||
const priorities = providers.value.map(p => p.provider_priority).filter(v => typeof v === 'number' && Number.isFinite(v))
|
||||
return priorities.length > 0 ? Math.max(...priorities) : undefined
|
||||
})
|
||||
|
||||
// 筛选后的提供商列表
|
||||
const filteredProviders = computed(() => {
|
||||
let result = [...providers.value]
|
||||
|
||||
@@ -234,7 +234,6 @@
|
||||
</Label>
|
||||
<Select
|
||||
v-model="systemConfig.request_record_level"
|
||||
v-model:open="logLevelSelectOpen"
|
||||
>
|
||||
<SelectTrigger
|
||||
id="request-log-level"
|
||||
@@ -539,7 +538,6 @@
|
||||
>
|
||||
<Clock class="w-4 h-4 text-muted-foreground" />
|
||||
<Select
|
||||
v-model:open="task.hourSelectOpen.value"
|
||||
:model-value="task.hour"
|
||||
@update:model-value="(val: string) => task.updateTime(val, task.minute)"
|
||||
>
|
||||
@@ -558,7 +556,6 @@
|
||||
</Select>
|
||||
<span class="text-sm text-muted-foreground">:</span>
|
||||
<Select
|
||||
v-model:open="task.minuteSelectOpen.value"
|
||||
:model-value="task.minute"
|
||||
@update:model-value="(val: string) => task.updateTime(task.hour, val)"
|
||||
>
|
||||
@@ -1050,7 +1047,6 @@ interface SystemConfig {
|
||||
const basicConfigLoading = ref(false)
|
||||
const logConfigLoading = ref(false)
|
||||
const cleanupConfigLoading = ref(false)
|
||||
const logLevelSelectOpen = ref(false)
|
||||
|
||||
// 导出/导入相关
|
||||
const exportLoading = ref(false)
|
||||
@@ -1382,8 +1378,6 @@ async function handleProviderCheckinToggle(enabled: boolean) {
|
||||
const previousCheckinTime = ref('')
|
||||
const checkinConfigLoading = ref(false)
|
||||
const quotaResetConfigLoading = ref(false)
|
||||
const checkinHourSelectOpen = ref(false)
|
||||
const checkinMinuteSelectOpen = ref(false)
|
||||
|
||||
// 解析签到时间的小时和分钟
|
||||
const checkinHour = computed(() => {
|
||||
@@ -1444,14 +1438,8 @@ async function handleOAuthTokenRefreshToggle(enabled: boolean) {
|
||||
}
|
||||
}
|
||||
|
||||
// OAuth Token 刷新(无时间配置,占位 ref)
|
||||
const oauthRefreshHourSelectOpen = ref(false)
|
||||
const oauthRefreshMinuteSelectOpen = ref(false)
|
||||
|
||||
// 用户配额重置时间相关
|
||||
const previousUserQuotaResetTime = ref('')
|
||||
const userQuotaResetHourSelectOpen = ref(false)
|
||||
const userQuotaResetMinuteSelectOpen = ref(false)
|
||||
const previousUserQuotaResetIntervalDays = ref(1)
|
||||
|
||||
const userQuotaResetHour = computed(() => {
|
||||
@@ -1493,8 +1481,6 @@ const scheduledTasks = computed(() => [
|
||||
hasTimeConfig: true,
|
||||
hour: checkinHour.value,
|
||||
minute: checkinMinute.value,
|
||||
hourSelectOpen: checkinHourSelectOpen,
|
||||
minuteSelectOpen: checkinMinuteSelectOpen,
|
||||
updateTime: updateCheckinTime,
|
||||
hasChanges: hasCheckinTimeChanged.value,
|
||||
loading: checkinConfigLoading.value,
|
||||
@@ -1510,8 +1496,6 @@ const scheduledTasks = computed(() => [
|
||||
hasTimeConfig: true,
|
||||
hour: userQuotaResetHour.value,
|
||||
minute: userQuotaResetMinute.value,
|
||||
hourSelectOpen: userQuotaResetHourSelectOpen,
|
||||
minuteSelectOpen: userQuotaResetMinuteSelectOpen,
|
||||
updateTime: updateUserQuotaResetTime,
|
||||
hasChanges: hasQuotaResetConfigChanged.value,
|
||||
loading: quotaResetConfigLoading.value,
|
||||
@@ -1527,8 +1511,6 @@ const scheduledTasks = computed(() => [
|
||||
hasTimeConfig: false,
|
||||
hour: '',
|
||||
minute: '',
|
||||
hourSelectOpen: oauthRefreshHourSelectOpen,
|
||||
minuteSelectOpen: oauthRefreshMinuteSelectOpen,
|
||||
updateTime: () => {},
|
||||
hasChanges: false,
|
||||
loading: false,
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
:allow-hourly="true"
|
||||
/>
|
||||
<Select
|
||||
v-model:open="userSelectOpen"
|
||||
v-model="selectedUserId"
|
||||
>
|
||||
<SelectTrigger class="h-8 text-xs w-52">
|
||||
@@ -32,7 +31,6 @@
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<Select
|
||||
v-model:open="compareUserSelectOpen"
|
||||
v-model="compareUserId"
|
||||
>
|
||||
<SelectTrigger class="h-8 text-xs w-52">
|
||||
@@ -164,8 +162,6 @@ const metric = ref<'requests' | 'tokens' | 'cost'>('requests')
|
||||
const users = ref<User[]>([])
|
||||
const selectedUserId = ref<string | null>(null)
|
||||
const compareUserId = ref<string>('__none__')
|
||||
const userSelectOpen = ref(false)
|
||||
const compareUserSelectOpen = ref(false)
|
||||
|
||||
const leaderboard = ref<LeaderboardItem[]>([])
|
||||
const leaderboardLoading = ref(false)
|
||||
|
||||
@@ -45,7 +45,6 @@
|
||||
</div>
|
||||
<Select
|
||||
v-model="filterRole"
|
||||
v-model:open="filterRoleOpenMobile"
|
||||
>
|
||||
<SelectTrigger class="w-24 h-8 text-xs border-border/60">
|
||||
<SelectValue placeholder="角色" />
|
||||
@@ -64,7 +63,6 @@
|
||||
</Select>
|
||||
<Select
|
||||
v-model="filterStatus"
|
||||
v-model:open="filterStatusOpenMobile"
|
||||
>
|
||||
<SelectTrigger class="w-20 h-8 text-xs border-border/60">
|
||||
<SelectValue placeholder="状态" />
|
||||
@@ -110,7 +108,6 @@
|
||||
<!-- 角色筛选 -->
|
||||
<Select
|
||||
v-model="filterRole"
|
||||
v-model:open="filterRoleOpen"
|
||||
>
|
||||
<SelectTrigger class="w-32 h-8 text-xs border-border/60">
|
||||
<SelectValue placeholder="全部角色" />
|
||||
@@ -131,7 +128,6 @@
|
||||
<!-- 状态筛选 -->
|
||||
<Select
|
||||
v-model="filterStatus"
|
||||
v-model:open="filterStatusOpen"
|
||||
>
|
||||
<SelectTrigger class="w-28 h-8 text-xs border-border/60">
|
||||
<SelectValue placeholder="全部状态" />
|
||||
@@ -799,10 +795,6 @@ const loadingStats = ref(false)
|
||||
const searchQuery = ref('')
|
||||
const filterRole = ref('all')
|
||||
const filterStatus = ref('all')
|
||||
const filterRoleOpen = ref(false)
|
||||
const filterStatusOpen = ref(false)
|
||||
const filterRoleOpenMobile = ref(false)
|
||||
const filterStatusOpenMobile = ref(false)
|
||||
|
||||
const currentPage = ref(1)
|
||||
const pageSize = ref(20)
|
||||
|
||||
@@ -379,7 +379,6 @@
|
||||
>类型</Label>
|
||||
<Select
|
||||
v-model="formData.type"
|
||||
v-model:open="typeSelectOpen"
|
||||
>
|
||||
<SelectTrigger
|
||||
id="type"
|
||||
@@ -597,7 +596,6 @@ const pageSize = ref(20)
|
||||
const dialogOpen = ref(false)
|
||||
const deleteDialogOpen = ref(false)
|
||||
const detailDialogOpen = ref(false)
|
||||
const typeSelectOpen = ref(false)
|
||||
const editingAnnouncement = ref<Announcement | null>(null)
|
||||
const deletingAnnouncement = ref<Announcement | null>(null)
|
||||
const viewingAnnouncement = ref<Announcement | null>(null)
|
||||
|
||||
Reference in New Issue
Block a user