update
This commit is contained in:
@@ -143,14 +143,12 @@ const saveLayout = () => {
|
||||
|
||||
const resetToDefault = () => {
|
||||
if (confirm(t('layoutConfigurator.confirmReset', '确定要恢复默认布局吗?当前更改将丢失。'))) {
|
||||
// 重新调用 store 的初始化方法来获取默认布局
|
||||
layoutStore.initializeLayout();
|
||||
// 重新加载到本地副本
|
||||
if (layoutStore.layoutTree) {
|
||||
localLayoutTree.value = JSON.parse(JSON.stringify(layoutStore.layoutTree));
|
||||
// 调用 store 中获取系统默认布局的方法
|
||||
const defaultLayout = layoutStore.getSystemDefaultLayout();
|
||||
// 直接将获取到的默认布局(深拷贝)赋值给本地副本
|
||||
localLayoutTree.value = JSON.parse(JSON.stringify(defaultLayout));
|
||||
hasChanges.value = true; // 标记为有更改,因为是重置操作
|
||||
console.log('[LayoutConfigurator] 已重置为默认布局。');
|
||||
}
|
||||
console.log('[LayoutConfigurator] 已重置为系统默认布局。');
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -41,17 +41,24 @@ const i18n = createI18n<[MessageSchema], 'en' | 'zh'>({
|
||||
* @param lang 要设置的语言代码 ('en', 'zh', etc.)
|
||||
*/
|
||||
export const setLocale = (lang: 'en' | 'zh') => {
|
||||
console.log(`[i18n] Attempting to set locale to: ${lang}`); // <-- 添加日志
|
||||
const globalComposer = i18n.global as unknown as Composer; // 强制类型断言
|
||||
if (globalComposer.availableLocales.includes(lang)) {
|
||||
const currentLocale = globalComposer.locale.value; // <-- 获取当前 locale
|
||||
if (currentLocale !== lang) { // <-- 仅在 locale 实际改变时更新
|
||||
globalComposer.locale.value = lang; // 访问 .value 属性
|
||||
console.log(`[i18n] Successfully updated global locale from "${currentLocale}" to "${lang}".`); // <-- 修改日志
|
||||
try {
|
||||
localStorage.setItem(localStorageKey, lang); // 持久化到 localStorage
|
||||
console.log(`[i18n] Locale set to "${lang}" and saved to localStorage.`); // 添加日志
|
||||
console.log(`[i18n] Locale "${lang}" saved to localStorage.`); // <-- 修改日志
|
||||
} catch (e) {
|
||||
console.error('[i18n] Failed to save locale to localStorage:', e);
|
||||
}
|
||||
} else {
|
||||
console.warn(`[i18n] Locale "${lang}" is not available.`);
|
||||
console.log(`[i18n] Locale is already "${lang}". No update needed.`); // <-- 添加日志
|
||||
}
|
||||
} else {
|
||||
console.warn(`[i18n] Locale "${lang}" is not available. Available locales: ${globalComposer.availableLocales.join(', ')}`); // <-- 修改日志
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -251,6 +251,12 @@ export const useLayoutStore = defineStore('layout', () => {
|
||||
}
|
||||
}
|
||||
|
||||
// 新增 Action: 获取系统内置的默认布局
|
||||
function getSystemDefaultLayout(): LayoutNode {
|
||||
console.log('[Layout Store] Getting system default layout.');
|
||||
return getDefaultLayout(); // 直接调用内部函数
|
||||
}
|
||||
|
||||
// 新增 Action: 将当前布局树持久化到后端和 localStorage
|
||||
async function persistLayoutTree() {
|
||||
if (!layoutTree.value) {
|
||||
@@ -328,5 +334,7 @@ export const useLayoutStore = defineStore('layout', () => {
|
||||
isHeaderVisible,
|
||||
loadHeaderVisibility,
|
||||
toggleHeaderVisibility,
|
||||
// 新增:暴露获取默认布局的方法
|
||||
getSystemDefaultLayout,
|
||||
};
|
||||
});
|
||||
|
||||
@@ -43,7 +43,8 @@ export const useSettingsStore = defineStore('settings', () => {
|
||||
console.log('[SettingsStore] 加载通用设置...');
|
||||
const response = await apiClient.get<Record<string, string>>('/settings'); // 使用 apiClient
|
||||
settings.value = response.data; // Store fetched general settings
|
||||
console.log('[SettingsStore] 通用设置已加载:', settings.value);
|
||||
// --- 更详细的日志 ---
|
||||
console.log('[SettingsStore] Fetched settings from backend:', JSON.stringify(settings.value));
|
||||
|
||||
// --- 设置默认值 (如果后端未返回) ---
|
||||
if (settings.value.showPopupFileEditor === undefined) {
|
||||
@@ -77,30 +78,34 @@ export const useSettingsStore = defineStore('settings', () => {
|
||||
|
||||
// --- 语言设置 ---
|
||||
const langFromSettings = settings.value.language;
|
||||
console.log(`[SettingsStore] Language from fetched settings: ${langFromSettings}`); // <-- 添加日志
|
||||
if (langFromSettings === 'en' || langFromSettings === 'zh') {
|
||||
fetchedLang = langFromSettings;
|
||||
} else {
|
||||
const navigatorLang = navigator.language?.split('-')[0];
|
||||
fetchedLang = navigatorLang === 'zh' ? 'zh' : defaultLng;
|
||||
console.warn(`[SettingsStore] 语言设置无效 ('${langFromSettings}'), 回退到 '${fetchedLang}'.`);
|
||||
console.warn(`[SettingsStore] Invalid language setting ('${langFromSettings}') received from backend or missing. Falling back to '${fetchedLang}'.`); // <-- 修改日志
|
||||
// Optionally save the fallback language back
|
||||
// await updateSetting('language', fetchedLang);
|
||||
}
|
||||
|
||||
if (fetchedLang) {
|
||||
console.log(`[SettingsStore] 设置语言: ${fetchedLang}`);
|
||||
console.log(`[SettingsStore] Determined language: ${fetchedLang}. Calling setLocale...`); // <-- 添加日志
|
||||
setLocale(fetchedLang);
|
||||
} else {
|
||||
console.error('[SettingsStore] 无法确定有效语言。');
|
||||
// This case should theoretically not happen with the fallback logic above
|
||||
console.error('[SettingsStore] Could not determine a valid language. This should not happen.');
|
||||
console.log(`[SettingsStore] Falling back to default: ${defaultLng}. Calling setLocale...`); // <-- 添加日志
|
||||
setLocale(defaultLng);
|
||||
}
|
||||
|
||||
} catch (err: any) {
|
||||
console.error('加载通用设置失败:', err);
|
||||
error.value = err.response?.data?.message || err.message || '加载设置失败';
|
||||
console.error('Error loading general settings:', err); // <-- 修改日志
|
||||
error.value = err.response?.data?.message || err.message || 'Failed to load settings';
|
||||
// 出错时(例如未登录),根据浏览器语言设置回退语言
|
||||
const navigatorLang = navigator.language?.split('-')[0];
|
||||
const fallbackLang = navigatorLang === 'zh' ? 'zh' : defaultLng;
|
||||
console.log(`[SettingsStore] Error loading settings. Falling back to language: ${fallbackLang}. Calling setLocale...`); // <-- 添加日志
|
||||
setLocale(fallbackLang);
|
||||
} finally {
|
||||
isLoading.value = false;
|
||||
@@ -134,6 +139,7 @@ export const useSettingsStore = defineStore('settings', () => {
|
||||
|
||||
// If updating language, also update i18n
|
||||
if (key === 'language' && (value === 'en' || value === 'zh')) {
|
||||
console.log(`[SettingsStore] updateSetting: Language updated to ${value}. Calling setLocale...`); // <-- 添加日志
|
||||
setLocale(value);
|
||||
}
|
||||
} catch (err: any) {
|
||||
@@ -180,6 +186,7 @@ export const useSettingsStore = defineStore('settings', () => {
|
||||
|
||||
// If language is updated, apply it
|
||||
if (languageUpdate) {
|
||||
console.log(`[SettingsStore] updateMultipleSettings: Language updated to ${languageUpdate}. Calling setLocale...`); // <-- 添加日志
|
||||
setLocale(languageUpdate);
|
||||
}
|
||||
} catch (err: any) {
|
||||
|
||||
@@ -251,15 +251,16 @@ const appearanceStore = useAppearanceStore(); // 实例化外观 store
|
||||
const { t } = useI18n();
|
||||
|
||||
// --- Reactive state from store ---
|
||||
// 使用 storeToRefs 获取响应式 getter
|
||||
const { settings, isLoading: settingsLoading, error: settingsError, showPopupFileEditorBoolean, shareFileEditorTabsBoolean, autoCopyOnSelectBoolean, dockerDefaultExpandBoolean } = storeToRefs(settingsStore); // +++ 添加 dockerDefaultExpandBoolean +++
|
||||
// 使用 storeToRefs 获取响应式 getter,包括 language
|
||||
const { settings, isLoading: settingsLoading, error: settingsError, showPopupFileEditorBoolean, shareFileEditorTabsBoolean, autoCopyOnSelectBoolean, dockerDefaultExpandBoolean, language: storeLanguage } = storeToRefs(settingsStore); // +++ 添加 dockerDefaultExpandBoolean 和 language getter +++
|
||||
|
||||
// --- Local state for forms ---
|
||||
const ipWhitelistInput = ref('');
|
||||
const selectedLanguage = ref<'en' | 'zh'>('en'); // Default to 'en', will be updated by watcher
|
||||
// 使用 store 的 language getter 初始化 selectedLanguage
|
||||
const selectedLanguage = ref<'en' | 'zh'>(storeLanguage.value);
|
||||
const blacklistSettingsForm = reactive({ // Renamed to avoid conflict with store state name
|
||||
maxLoginAttempts: '5',
|
||||
loginBanDuration: '300',
|
||||
maxLoginAttempts: '5', // 初始值将在 watcher 中被 store 值覆盖
|
||||
loginBanDuration: '300', // 初始值将在 watcher 中被 store 值覆盖
|
||||
});
|
||||
const popupEditorEnabled = ref(true); // 本地状态,用于 v-model
|
||||
|
||||
@@ -297,11 +298,11 @@ watch(settings, (newSettings, oldSettings) => {
|
||||
const isInitialLoad = !oldSettings;
|
||||
|
||||
ipWhitelistInput.value = newSettings.ipWhitelist || '';
|
||||
selectedLanguage.value = newSettings.language || 'en';
|
||||
// selectedLanguage.value = newSettings.language || 'en'; // <-- 移除这一行,selectedLanguage 现在由 v-model 更新
|
||||
blacklistSettingsForm.maxLoginAttempts = newSettings.maxLoginAttempts || '5';
|
||||
blacklistSettingsForm.loginBanDuration = newSettings.loginBanDuration || '300';
|
||||
|
||||
// 始终将本地布尔状态与 store 的布尔 getter 同步
|
||||
// 始终将本地布尔状态与 store 的布尔 getter 同步 (除了 language)
|
||||
popupEditorEnabled.value = showPopupFileEditorBoolean.value;
|
||||
shareTabsEnabled.value = shareFileEditorTabsBoolean.value;
|
||||
autoCopyEnabled.value = autoCopyOnSelectBoolean.value; // 同步选中即复制状态
|
||||
|
||||
Reference in New Issue
Block a user