feat(ai): 统一 AI 配置入口到 /admin/ai-settings
## 新增 - 创建 /admin/ai-settings 统一配置页(AiProviderSettingsCard + AiUsageDashboard) - admin 侧边栏新增"AI 配置"菜单项(权限 AI_CONFIGURE,图标 Sparkles) - 新增 deleteAiProvider 数据访问层(事务删除 + 自动转移默认) - 新增 deleteAiProviderAction Server Action(Zod 校验 + 权限校验) - AiProviderSettingsCard 新增删除按钮(AlertDialog 确认 + destructive 变体) - 新增 i18n 翻译键(delete/deleteConfirm/deleteSuccess 等,zh-CN + en) ## 移除 - 从 /settings 移除 AI 标签页(原 VALID_TABS 含 "ai",现仅 4 标签页) - 从考试页面移除 AI 配置弹窗(Dialog + AiProviderSettingsCard 内嵌) - 从 ai-provider-selector.tsx 移除配置弹窗(managePanel/manageOpen props) - 移除 settings-view.tsx 中 canConfigureAi 逻辑和未使用 import ## 变更 - 考试页面"管理"按钮改为 Link 跳转到 /admin/ai-settings - ai-provider-selector.tsx"管理"按钮改为 Link 跳转到 /admin/ai-settings - exam-form.tsx 移除 providerDialogOpen/providerDialogKey 状态 - 修正架构文档 004 中 Action 命名(getAiProvidersAction → getAiProviderSummaries 等) ## 架构文档同步 - 004 更新 settings 模块章节(V3 标记/修正 Action 名称/新增 deleteAiProvider) - 005 新增 deleteAiProviderAction 节点 + /admin/ai-settings 路由
This commit is contained in:
@@ -12,6 +12,7 @@ import { encryptAiApiKey, getAiErrorMessage, testAiProviderById, testAiProviderC
|
||||
import {
|
||||
countDefaultAiProviders,
|
||||
createAiProvider,
|
||||
deleteAiProvider as deleteAiProviderRecord,
|
||||
getAiProviderForUpdate,
|
||||
getAiProviderSummaries as fetchAiProviderSummaries,
|
||||
updateAiProvider,
|
||||
@@ -181,3 +182,31 @@ export async function testAiProviderAction(
|
||||
return { success: false, message: getAiErrorMessage(error) }
|
||||
}
|
||||
}
|
||||
|
||||
const DeleteAiProviderSchema = z.object({
|
||||
id: z.string().min(1),
|
||||
})
|
||||
|
||||
/**
|
||||
* 删除 AI Provider
|
||||
*
|
||||
* 如果删除的是默认 Provider,自动将最新的一条记录设为默认(若存在)。
|
||||
*/
|
||||
export async function deleteAiProviderAction(
|
||||
input: z.infer<typeof DeleteAiProviderSchema>
|
||||
): Promise<ActionState<null>> {
|
||||
try {
|
||||
await ensureUser()
|
||||
const parsed = DeleteAiProviderSchema.safeParse(input)
|
||||
if (!parsed.success) {
|
||||
return { success: false, message: "Invalid provider id" }
|
||||
}
|
||||
await deleteAiProviderRecord(parsed.data.id)
|
||||
revalidatePath("/admin/ai-settings")
|
||||
revalidatePath("/settings")
|
||||
return { success: true, message: "AI provider deleted", data: null }
|
||||
} catch (error) {
|
||||
if (error instanceof PermissionDeniedError) return { success: false, message: error.message }
|
||||
return { success: false, message: "Failed to delete AI provider" }
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user