import { eq } from "drizzle-orm"; import { getDatabase } from "@/modules/core/server/db"; import { systemSettings } from "@/modules/core/server/schema"; import type { SystemSettings } from "@/modules/core/types"; const GLOBAL_SETTINGS_ID = "global"; type SystemSettingsRow = typeof systemSettings.$inferSelect; export type SystemSettingsUpdate = { registrationEnabled?: boolean; oidcEnabled?: boolean; oidcIssuerUrl?: string; oidcClientId?: string; oidcClientSecret?: string; oidcScopes?: string; oidcRedirectUri?: string; oidcAvatarClaim?: string; oidcAutoProvision?: boolean; }; function toSystemSettings(row: SystemSettingsRow): SystemSettings { return { id: row.id, registrationEnabled: row.registrationEnabled, oidcEnabled: row.oidcEnabled, oidcIssuerUrl: row.oidcIssuerUrl, oidcClientId: row.oidcClientId, oidcHasClientSecret: row.oidcClientSecret.length > 0, oidcScopes: row.oidcScopes, oidcRedirectUri: row.oidcRedirectUri, oidcAvatarClaim: row.oidcAvatarClaim, oidcAutoProvision: row.oidcAutoProvision, updatedAt: row.updatedAt.toISOString(), }; } async function ensureSystemSettingsRow(): Promise { const database = getDatabase(); const existingRows = await database .select() .from(systemSettings) .where(eq(systemSettings.id, GLOBAL_SETTINGS_ID)) .limit(1); const existing = existingRows[0]; if (existing) { return existing; } const createdRows = await database .insert(systemSettings) .values({ id: GLOBAL_SETTINGS_ID }) .onConflictDoNothing() .returning(); const created = createdRows[0]; if (created) { return created; } const fallbackRows = await database .select() .from(systemSettings) .where(eq(systemSettings.id, GLOBAL_SETTINGS_ID)) .limit(1); const fallback = fallbackRows[0]; if (!fallback) { throw new Error("系统配置初始化失败"); } return fallback; } export async function ensureSystemSettings(): Promise { await ensureSystemSettingsRow(); } export async function getSystemSettings(): Promise { const row = await ensureSystemSettingsRow(); return toSystemSettings(row); } export async function updateSystemSettings(input: SystemSettingsUpdate): Promise { const database = getDatabase(); await ensureSystemSettingsRow(); const updateValues: SystemSettingsUpdate & { updatedAt: Date } = { updatedAt: new Date(), }; if (input.registrationEnabled !== undefined) { updateValues.registrationEnabled = input.registrationEnabled; } if (input.oidcEnabled !== undefined) { updateValues.oidcEnabled = input.oidcEnabled; } if (input.oidcIssuerUrl !== undefined) { updateValues.oidcIssuerUrl = input.oidcIssuerUrl; } if (input.oidcClientId !== undefined) { updateValues.oidcClientId = input.oidcClientId; } if (input.oidcClientSecret !== undefined && input.oidcClientSecret.length > 0) { updateValues.oidcClientSecret = input.oidcClientSecret; } if (input.oidcScopes !== undefined) { updateValues.oidcScopes = input.oidcScopes; } if (input.oidcRedirectUri !== undefined) { updateValues.oidcRedirectUri = input.oidcRedirectUri; } if (input.oidcAvatarClaim !== undefined) { updateValues.oidcAvatarClaim = input.oidcAvatarClaim; } if (input.oidcAutoProvision !== undefined) { updateValues.oidcAutoProvision = input.oidcAutoProvision; } const rows = await database .update(systemSettings) .set(updateValues) .where(eq(systemSettings.id, GLOBAL_SETTINGS_ID)) .returning(); const row = rows[0]; if (!row) { throw new Error("系统配置不存在"); } return toSystemSettings(row); }