diff --git a/frontend-web/src/components/workspace/appearance-controls.tsx b/frontend-web/src/components/workspace/appearance-controls.tsx
index a8ff1097..77864f64 100644
--- a/frontend-web/src/components/workspace/appearance-controls.tsx
+++ b/frontend-web/src/components/workspace/appearance-controls.tsx
@@ -223,22 +223,19 @@ const LAYOUT_OPTIONS = [
* 界面模式(全量 / 简洁)下拉切换。换肤旁并排,图标 + 下拉:
* - 简洁模式 ChatPage 顶栏(全局顶栏被隐藏)。
* - 全量模式 Header 右上角。
- * 用户未显式设置过界面模式时(mode === undefined),当前态按调用方所在的实际界面
- * 兜底——`fallback` 指明这一回退值(Header 传 "full",ChatPage 传 "compact")。
+ * 当前态为有效界面模式(用户自选 > 管理员系统默认 > 内置简洁默认)——
+ * useLayoutMode 总会返回具体值,不再有 undefined 兜底。
*/
export function LayoutModeSwitcher({
tone,
- fallback = "compact",
navigateTo = "/page/workspace/chats/new",
}: {
tone: AppearanceControlTone;
- fallback?: "full" | "compact";
navigateTo?: string | null;
}) {
const [mode, setLayoutMode] = useLayoutMode();
const navigate = useNavigate();
- const current = mode ?? fallback;
- const TriggerIcon = current === "full" ? PanelLeftIcon : LayoutIcon;
+ const TriggerIcon = mode === "full" ? PanelLeftIcon : LayoutIcon;
if (env.FORCE_COLLAPSED_SIDEBAR || isHideChromeActive()) return null;
@@ -262,7 +259,7 @@ export function LayoutModeSwitcher({
{LAYOUT_OPTIONS.map((option) => {
const Icon = option.icon;
- const active = current === option.id;
+ const active = mode === option.id;
return (
void }) {
const globalDefault = appearance?.default_theme ?? "light";
const globalSkillView = appearance?.default_skill_view ?? "list";
const globalAgentView = appearance?.default_agent_view ?? "card";
- const globalLayoutMode = appearance?.default_layout_mode ?? "full";
+ const globalLayoutMode = appearance?.default_layout_mode ?? "compact";
const globalDefaultLabel = useMemo(() => {
const customTheme = (appearance?.custom_themes ?? []).find(
(preset) => preset.id === globalDefault,
@@ -201,7 +201,7 @@ export function AppearanceSettingsPage({ onClose }: { onClose?: () => void }) {
if (globalDefault === "lightyellow") return "浅黄色";
return "浅蓝";
}, [appearance?.custom_themes, globalDefault]);
- // 有效界面模式:用户自己选过则以其为准,否则跟随管理员系统默认(再否则会话级回退)。
+ // 有效界面模式:用户自己选过则以其为准,否则跟随管理员系统默认(再否则内置默认简洁模式)。
const [effectiveLayoutMode, setLayoutMode] = useLayoutMode();
const cleanupWords =
citationDisplay?.cleanup_words ?? settings.display.citationCleanupWords ?? [];
diff --git a/frontend-web/src/core/system-settings/hooks.ts b/frontend-web/src/core/system-settings/hooks.ts
index 5ec98457..8e51b828 100644
--- a/frontend-web/src/core/system-settings/hooks.ts
+++ b/frontend-web/src/core/system-settings/hooks.ts
@@ -164,19 +164,15 @@ export function useViewMode(
/**
* Effective interface layout mode (full chrome vs compact). A user's own choice
* (persisted in local settings) wins; otherwise the admin-configured system
- * default applies; otherwise `undefined` (callers fall back to the session-level
- * `sidebarEnabled` flag set by portal / yUserId login). `setMode` persists the
- * user's override locally.
+ * default applies; otherwise the built-in default is compact (简洁模式).
+ * `setMode` persists the user's override locally.
*/
-export function useLayoutMode(): [
- LayoutMode | undefined,
- (mode: LayoutMode) => void,
-] {
+export function useLayoutMode(): [LayoutMode, (mode: LayoutMode) => void] {
const [settings, setSettings] = useLocalSettings();
const { data: appearance } = useAppearanceSettings();
const userOverride = settings.display.layoutMode;
const adminDefault = appearance?.default_layout_mode;
- const mode = userOverride ?? adminDefault;
+ const mode: LayoutMode = userOverride ?? adminDefault ?? "compact";
const setMode = (next: LayoutMode) =>
setSettings("display", { layoutMode: next });
return [mode, setMode];
diff --git a/frontend-web/src/pages/ChatPage.tsx b/frontend-web/src/pages/ChatPage.tsx
index 6e17b22d..39a5ef93 100644
--- a/frontend-web/src/pages/ChatPage.tsx
+++ b/frontend-web/src/pages/ChatPage.tsx
@@ -37,7 +37,6 @@ import { UserIdentityBadge } from "@/components/workspace/user-identity-badge";
import { CompactModeGuide } from "@/components/workspace/compact-mode-guide";
import { Welcome } from "@/components/workspace/welcome";
import { CompactWelcome } from "@/components/workspace/compact-welcome";
-import { readSidebarEnabled } from "@/core/page-layout/sidebar-enabled";
import {
buildFullChatNavigationPath,
isChatsIframeWorkspacePath,
@@ -129,7 +128,7 @@ export default function ChatPage() {
const { open: historySidebarOpen, toggleSidebar: toggleHistorySidebar } =
useSidebar();
const { t } = useI18n();
- // 有效界面模式:用户自选 > 管理员系统默认 > (下方再回退会话级 sidebarEnabled)
+ // 有效界面模式:用户自选 > 管理员系统默认 > 内置默认「简洁模式」
const [effectiveLayoutMode] = useLayoutMode();
const [showFollowups, setShowFollowups] = useState(false);
const [hasStartedConversation, setHasStartedConversation] = useState(false);
@@ -662,16 +661,10 @@ export default function ChatPage() {
const isLandingState = isNewThread && !hasStartedConversation;
// 紧凑模式(正常 App,有外层页面侧栏)落地态:用 CM 参考图样式重画;
// 判定与 PageRoutes 的 compactWorkspaceSidebar(pageSidebarAllowed) 保持一致 ——
- // 优先看外观设置的「全量/简洁」,未设置过才回退到会话级 sidebarEnabled。否则用户显式
- // 选「全量」时 PageRoutes 已挂出顶栏+侧栏,这里却还按旧 sidebarEnabled 判定,导致深蓝
- // 主题底图(workspace-chat-bg)不生效。非紧凑(嵌入/standalone)保持原样。
- const layoutMode = effectiveLayoutMode;
+ // 用 useLayoutMode 的有效界面模式(用户自选 > 管理员系统默认 > 内置简洁默认),
+ // 与 PageRoutes 的 chrome 判定同源。非紧凑(嵌入/standalone)保持原样。
const chromeByPreference =
- fullChatMode || layoutMode === "full"
- ? true
- : layoutMode === "compact"
- ? false
- : readSidebarEnabled();
+ fullChatMode || effectiveLayoutMode === "full" ? true : false;
const compactChrome =
chromeByPreference && !isChatsIframeWorkspacePath(pathname);
const compactLanding = isLandingState && compactChrome;
diff --git a/frontend-web/src/pages/PageRoutes.tsx b/frontend-web/src/pages/PageRoutes.tsx
index 50bb0dc4..e29fa11c 100644
--- a/frontend-web/src/pages/PageRoutes.tsx
+++ b/frontend-web/src/pages/PageRoutes.tsx
@@ -5,7 +5,6 @@ import { PageSidebar } from "@/components/page-sidebar";
import { PageSidebarDark } from "@/components/page-sidebar-dark";
import { CompactToolbox } from "@/components/workspace/compact-toolbox";
import { isChatsIframeWorkspacePath } from "@/core/page-layout/chats-iframe-route";
-import { readSidebarEnabled } from "@/core/page-layout/sidebar-enabled";
import { isWujieEnv } from "@/core/embed/wujie";
import {
isEmbedActive,
@@ -34,7 +33,6 @@ import { RoundtableJobNotifier } from "@/roundtable-planning/components/Roundtab
function PageLayout() {
const [collapsed, setCollapsed] = useState(false);
const forceCollapsedSidebar = env.FORCE_COLLAPSED_SIDEBAR;
- const sidebarEnabled = useMemo(() => readSidebarEnabled(), []);
const location = useLocation();
const { theme } = useTheme();
const isDark = theme === "dark";
@@ -45,17 +43,11 @@ function PageLayout() {
const thirdLevel = useActiveThirdLevel();
const lightExpanded = lightNarrowSidebar && thirdLevel.length > 0;
// 界面模式(外观设置):用户显式选「全量/简洁」时以其为准;否则跟随管理员系统默认
- // (default_layout_mode);两者都没有才回退到会话级 sidebarEnabled(外部门户/yUserId
- // 登录时置位)这一旧默认。这样无论是否走门户登录,「全量↔简洁」都能真正控制顶栏+侧边栏。
+ // (default_layout_mode);两者都没有时使用内置默认「简洁模式」(useLayoutMode 兜底,
+ // 不再回退到会话级 sidebarEnabled 旧默认)。「全量↔简洁」始终能真正控制顶栏+侧边栏。
const [layoutMode] = useLayoutMode();
const chromeByPreference =
- forceCollapsedSidebar
- ? false
- : layoutMode === "full"
- ? true
- : layoutMode === "compact"
- ? false
- : sidebarEnabled;
+ forceCollapsedSidebar ? false : layoutMode === "compact" ? false : true;
// iframe 嵌入模式(外部系统 `&embed=1`,按标签页 sessionStorage):去掉全局导航栏 + 侧边栏,
// 只留问答/会商工作区本体。按 location 重算以跟随页内导航;非嵌入标签页恒为 false,不受影响。
const embedActive = useMemo(
diff --git a/frontend-web/src/strategy-components/Header.tsx b/frontend-web/src/strategy-components/Header.tsx
index a1dbde5c..baf95239 100644
--- a/frontend-web/src/strategy-components/Header.tsx
+++ b/frontend-web/src/strategy-components/Header.tsx
@@ -170,10 +170,7 @@ const Header = ({ collapsed }: HeaderProps) => {
-
+