代码代码修改
This commit is contained in:
1 parent
a5d877207e
commit
0c5938a5a3
12 files changed
+784
-618
No files matched your search
@@ -0,0 +1,39 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect } from "react";
|
||||
|
||||
import { useLocalSettings } from "@/core/settings";
|
||||
|
||||
/**
|
||||
* 基准字号 = 16px,对应《深蓝色 UI 规范》§2.1.2 后台系统正文字号(16px Regular)。
|
||||
* 用户在「外观 → 字号」里选择的倍数作用于 <html> 根元素的 font-size;由于 Tailwind
|
||||
* 的字号 / 间距基于 rem,整套界面会随之按比例放大 / 缩小。`fontScale === 1` 即默认 16px。
|
||||
*/
|
||||
export const BASE_FONT_PX = 16;
|
||||
|
||||
export const FONT_SCALE_OPTIONS: { value: number; label: string; px: number }[] =
|
||||
[
|
||||
{ value: 0.875, label: "小", px: 14 },
|
||||
{ value: 1, label: "标准", px: 16 },
|
||||
{ value: 1.125, label: "大", px: 18 },
|
||||
{ value: 1.25, label: "特大", px: 20 },
|
||||
];
|
||||
|
||||
/**
|
||||
* 将用户选择的字号倍数应用到 <html> 根元素。挂在应用根部,保证刷新后即时生效、全局统一。
|
||||
* 不渲染任何 DOM。
|
||||
*/
|
||||
export function FontScaleApplier() {
|
||||
const [settings] = useLocalSettings();
|
||||
const { fontScale } = settings.display;
|
||||
|
||||
useEffect(() => {
|
||||
const scale =
|
||||
typeof fontScale === "number" && Number.isFinite(fontScale) && fontScale > 0
|
||||
? fontScale
|
||||
: 1;
|
||||
document.documentElement.style.fontSize = `${BASE_FONT_PX * scale}px`;
|
||||
}, [fontScale]);
|
||||
|
||||
return null;
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import { toast } from "sonner";
|
||||
|
||||
import { useTheme } from "@/contexts/ThemeContext";
|
||||
|
||||
import { FONT_SCALE_OPTIONS } from "@/components/font-scale";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
Select,
|
||||
@@ -21,12 +22,12 @@ import { getStoredAuth } from "@/core/auth";
|
||||
import { enUS, isLocale, zhCN, type Locale } from "@/core/i18n";
|
||||
import { useI18n } from "@/core/i18n/hooks";
|
||||
import { useLocalSettings } from "@/core/settings";
|
||||
import {
|
||||
useAppearanceSettings,
|
||||
useCitationDisplaySettings,
|
||||
useUpdateAppearanceSettings,
|
||||
useUpdateCitationDisplaySettings,
|
||||
} from "@/core/system-settings/hooks";
|
||||
import {
|
||||
useAppearanceSettings,
|
||||
useCitationDisplaySettings,
|
||||
useUpdateAppearanceSettings,
|
||||
useUpdateCitationDisplaySettings,
|
||||
} from "@/core/system-settings/hooks";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
import { SettingsSection } from "./settings-section";
|
||||
@@ -42,13 +43,13 @@ export function AppearanceSettingsPage() {
|
||||
const currentTheme = theme;
|
||||
const [settings, setSettings] = useLocalSettings();
|
||||
const isAdmin = getStoredAuth()?.system_role === "admin";
|
||||
const { data: appearance } = useAppearanceSettings();
|
||||
const updateAppearance = useUpdateAppearanceSettings();
|
||||
const { data: citationDisplay } = useCitationDisplaySettings();
|
||||
const updateCitationDisplay = useUpdateCitationDisplaySettings();
|
||||
const globalDefault = appearance?.default_theme ?? "light";
|
||||
const cleanupWords =
|
||||
citationDisplay?.cleanup_words ?? settings.display.citationCleanupWords ?? [];
|
||||
const { data: appearance } = useAppearanceSettings();
|
||||
const updateAppearance = useUpdateAppearanceSettings();
|
||||
const { data: citationDisplay } = useCitationDisplaySettings();
|
||||
const updateCitationDisplay = useUpdateCitationDisplaySettings();
|
||||
const globalDefault = appearance?.default_theme ?? "light";
|
||||
const cleanupWords =
|
||||
citationDisplay?.cleanup_words ?? settings.display.citationCleanupWords ?? [];
|
||||
|
||||
const handleSetGlobalDefault = async (value: "light" | "dark") => {
|
||||
if (value === globalDefault) return;
|
||||
@@ -147,6 +148,39 @@ export function AppearanceSettingsPage() {
|
||||
|
||||
<Separator />
|
||||
|
||||
<SettingsSection
|
||||
title="字号"
|
||||
description="调整界面整体字号,方便放大或缩小阅读。默认 16px(标准)。"
|
||||
>
|
||||
<div className="space-y-3">
|
||||
<Select
|
||||
value={String(settings.display.fontScale ?? 1)}
|
||||
onValueChange={(value) => {
|
||||
const scale = Number(value);
|
||||
if (Number.isFinite(scale) && scale > 0) {
|
||||
setSettings("display", { fontScale: scale });
|
||||
}
|
||||
}}
|
||||
>
|
||||
<SelectTrigger className="w-[220px]">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{FONT_SCALE_OPTIONS.map((item) => (
|
||||
<SelectItem key={item.value} value={String(item.value)}>
|
||||
{item.label}({item.px}px)
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<div className="text-muted-foreground rounded-lg border p-4 text-sm leading-relaxed">
|
||||
预览:多智能体圆桌研讨 · The quick brown fox · 0123456789
|
||||
</div>
|
||||
</div>
|
||||
</SettingsSection>
|
||||
|
||||
<Separator />
|
||||
|
||||
<SettingsSection
|
||||
title={t.settings.appearance.languageTitle}
|
||||
description={t.settings.appearance.languageDescription}
|
||||
@@ -217,16 +251,16 @@ export function AppearanceSettingsPage() {
|
||||
管理员配置。每行一个词或短句,参考文献卡片和详情弹框会自动移除这些广告词、导航词或免责声明。
|
||||
</p>
|
||||
</div>
|
||||
<Textarea
|
||||
value={cleanupWords.join("\n")}
|
||||
onChange={(event) => {
|
||||
const words = event.currentTarget.value
|
||||
.split(/\r?\n/)
|
||||
.map((item) => item.trim())
|
||||
.filter(Boolean);
|
||||
setSettings("display", { citationCleanupWords: words });
|
||||
updateCitationDisplay.mutate({ cleanup_words: words });
|
||||
}}
|
||||
<Textarea
|
||||
value={cleanupWords.join("\n")}
|
||||
onChange={(event) => {
|
||||
const words = event.currentTarget.value
|
||||
.split(/\r?\n/)
|
||||
.map((item) => item.trim())
|
||||
.filter(Boolean);
|
||||
setSettings("display", { citationCleanupWords: words });
|
||||
updateCitationDisplay.mutate({ cleanup_words: words });
|
||||
}}
|
||||
placeholder={"广告\n点击下载APP\n打开客户端\n免责声明\n责任编辑"}
|
||||
className="min-h-32 text-sm"
|
||||
/>
|
||||
|
||||
Reference in new issue
Block a user