feat: 系统设置增加默认主题模式配置
- 管理员可以设置网站默认使用深色/浅色/跟随系统模式 - 新增 defaultTheme 字段到 SiteSettings 表 - 前端 ThemeProvider 从数据库读取默认主题设置
This commit is contained in:
parent
aee826c688
commit
24af251fd3
@ -151,6 +151,7 @@ type SiteSettings = {
|
||||
usageTimeStart: string;
|
||||
usageTimeEnd: string;
|
||||
usageTimeMessage: string;
|
||||
defaultTheme: "light" | "dark" | "system";
|
||||
};
|
||||
|
||||
type NavLink = {
|
||||
@ -340,6 +341,7 @@ export function AdminSettingsClient() {
|
||||
usageTimeStart: "08:00",
|
||||
usageTimeEnd: "20:00",
|
||||
usageTimeMessage: "由壹点累了也是需要休息的",
|
||||
defaultTheme: "system",
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
@ -354,6 +356,7 @@ export function AdminSettingsClient() {
|
||||
usageTimeStart: siteSettingsData.usageTimeStart || "08:00",
|
||||
usageTimeEnd: siteSettingsData.usageTimeEnd || "20:00",
|
||||
usageTimeMessage: siteSettingsData.usageTimeMessage || "由壹点累了也是需要休息的",
|
||||
defaultTheme: siteSettingsData.defaultTheme || "system",
|
||||
});
|
||||
}
|
||||
}, [siteSettingsData]);
|
||||
@ -2281,6 +2284,25 @@ export function AdminSettingsClient() {
|
||||
placeholder="https://example.com/favicon.ico"
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="defaultTheme">默认主题模式</Label>
|
||||
<Select
|
||||
value={siteSettings.defaultTheme}
|
||||
onValueChange={(value: "light" | "dark" | "system") => setSiteSettings({ ...siteSettings, defaultTheme: value })}
|
||||
>
|
||||
<SelectTrigger id="defaultTheme">
|
||||
<SelectValue placeholder="选择默认主题" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="system">跟随系统</SelectItem>
|
||||
<SelectItem value="light">浅色模式</SelectItem>
|
||||
<SelectItem value="dark">深色模式</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<div className="text-xs text-muted-foreground">
|
||||
设置新用户首次访问时的默认主题模式
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center justify-between space-x-2 rounded-lg border p-4">
|
||||
<div className="space-y-0.5">
|
||||
<Label htmlFor="showAutoModel">显示"自动"模型选项</Label>
|
||||
|
||||
@ -26,6 +26,7 @@ export async function GET() {
|
||||
siteLogoDark: null,
|
||||
favicon: null,
|
||||
showAutoModel: true,
|
||||
defaultTheme: "system",
|
||||
usageTimeEnabled: false,
|
||||
usageTimeStart: "08:00",
|
||||
usageTimeEnd: "20:00",
|
||||
@ -58,6 +59,7 @@ const updateSchema = z.object({
|
||||
siteLogoDark: z.string().nullable().optional(),
|
||||
favicon: z.string().nullable().optional(),
|
||||
showAutoModel: z.boolean().optional(),
|
||||
defaultTheme: z.enum(["system", "light", "dark"]).optional(),
|
||||
usageTimeEnabled: z.boolean().optional(),
|
||||
usageTimeStart: z.string().length(5).optional(),
|
||||
usageTimeEnd: z.string().length(5).optional(),
|
||||
@ -106,6 +108,7 @@ export async function PUT(request: NextRequest) {
|
||||
siteLogoDark: data.siteLogoDark,
|
||||
favicon: data.favicon,
|
||||
showAutoModel: data.showAutoModel ?? true,
|
||||
defaultTheme: data.defaultTheme ?? "system",
|
||||
usageTimeEnabled: data.usageTimeEnabled ?? false,
|
||||
usageTimeStart: data.usageTimeStart ?? "08:00",
|
||||
usageTimeEnd: data.usageTimeEnd ?? "20:00",
|
||||
|
||||
@ -125,11 +125,15 @@ const CHUNK_ERROR_RECOVERY_SCRIPT = `\
|
||||
});
|
||||
})();`;
|
||||
|
||||
export default function RootLayout({
|
||||
export default async function RootLayout({
|
||||
children,
|
||||
}: Readonly<{
|
||||
children: React.ReactNode;
|
||||
}>) {
|
||||
// 获取网站设置中的默认主题
|
||||
const settings = await getSiteSettings();
|
||||
const defaultTheme = settings.defaultTheme || "system";
|
||||
|
||||
return (
|
||||
<html
|
||||
className={`${geist.variable} ${geistMono.variable}`}
|
||||
@ -158,7 +162,7 @@ export default function RootLayout({
|
||||
<FaviconUpdater />
|
||||
<ThemeProvider
|
||||
attribute="class"
|
||||
defaultTheme="dark"
|
||||
defaultTheme={defaultTheme}
|
||||
disableTransitionOnChange
|
||||
enableSystem
|
||||
>
|
||||
|
||||
@ -1510,9 +1510,9 @@ export async function getSubModelsByParentModelId(parentModelId: string) {
|
||||
export async function getSiteSettings() {
|
||||
try {
|
||||
const [settings] = await db.select().from(siteSettings).limit(1);
|
||||
return settings || { siteName: "AI Chatbot", siteLogo: null, siteLogoDark: null, favicon: null };
|
||||
return settings || { siteName: "AI Chatbot", siteLogo: null, siteLogoDark: null, favicon: null, defaultTheme: "system" };
|
||||
} catch (_error) {
|
||||
return { siteName: "AI Chatbot", siteLogo: null, siteLogoDark: null, favicon: null };
|
||||
return { siteName: "AI Chatbot", siteLogo: null, siteLogoDark: null, favicon: null, defaultTheme: "system" };
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -286,6 +286,7 @@ export const siteSettings = pgTable("SiteSettings", {
|
||||
siteLogoDark: text("siteLogoDark"), // 黑夜模式 LOGO
|
||||
favicon: text("favicon"),
|
||||
showAutoModel: boolean("showAutoModel").notNull().default(true), // 是否显示"自动"模型选项
|
||||
defaultTheme: varchar("defaultTheme", { length: 16 }).notNull().default("system"), // 默认主题:system | light | dark
|
||||
// 使用时间限制
|
||||
usageTimeEnabled: boolean("usageTimeEnabled").notNull().default(false), // 是否启用时间限制
|
||||
usageTimeStart: varchar("usageTimeStart", { length: 5 }).default("08:00"), // 开始时间(HH:mm)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user