import { createSlice, createAsyncThunk, PayloadAction } from '@reduxjs/toolkit'; import { fetchI18nMessages, I18nMessages } from '../API/i18n/i18nActions'; import { getLanguageList, changeLanguage, LanguageItem } from '../API/language'; import { fetchSoftwareInfo } from '../API/softwareInfo'; export interface I18nState { messages: I18nMessages; currentLocale: string; supportedLocales: string[]; loading: boolean; error: string | null; // 语言管理相关状态 availableLanguages: LanguageItem[]; selectedLanguage: string; currentSystemLocale: string; // 当前系统语言,如 "zh" languagesLoading: boolean; savingLanguage: boolean; languageError: string | null; } const initialState: I18nState = { messages: {}, currentLocale: 'en_US', supportedLocales: ['en_US', 'zh_CN'], loading: false, error: null, // 语言管理初始状态 availableLanguages: [], selectedLanguage: '', currentSystemLocale: '', languagesLoading: false, savingLanguage: false, languageError: null, }; // 异步thunk:加载多语言资源 export const loadI18nMessages = createAsyncThunk( 'i18n/loadMessages', async (locale: string) => { const messages = await fetchI18nMessages(locale); return { locale, messages }; } ); // 异步thunk:加载可用语言列表 export const loadAvailableLanguages = createAsyncThunk( 'i18n/loadAvailableLanguages', async () => { // 同时获取语言列表和软件信息 const [languageResponse, softwareInfo] = await Promise.all([ getLanguageList(), fetchSoftwareInfo(), ]); if (languageResponse.data.code === '0x000000') { // 从 softwareInfo 获取当前系统语言 const currentSystemLocale = softwareInfo.current_locale; return { languages: languageResponse.data.data, currentSystemLocale, }; } throw new Error(languageResponse.data.description || '加载语言列表失败'); } ); // 异步thunk:更新系统语言 export const updateSystemLanguage = createAsyncThunk( 'i18n/updateSystemLanguage', async (language: string) => { const response = await changeLanguage(language); if (response.data.code === '0x000000') { return language; } throw new Error(response.data.description || '修改语言失败'); } ); const i18nSlice = createSlice({ name: 'i18n', initialState, reducers: { setCurrentLocale: (state, action: PayloadAction) => { state.currentLocale = action.payload; }, clearError: (state) => { state.error = null; }, // 设置选中的语言 setSelectedLanguage: (state, action: PayloadAction) => { state.selectedLanguage = action.payload; }, // 清除语言错误 clearLanguageError: (state) => { state.languageError = null; }, }, extraReducers: (builder) => { builder // 加载多语言资源 .addCase(loadI18nMessages.pending, (state) => { state.loading = true; state.error = null; }) .addCase(loadI18nMessages.fulfilled, (state, action) => { state.loading = false; state.messages = action.payload.messages; state.currentLocale = action.payload.locale; }) .addCase(loadI18nMessages.rejected, (state, action) => { state.loading = false; state.error = action.error.message || 'Failed to load i18n messages'; }) // 加载可用语言列表 .addCase(loadAvailableLanguages.pending, (state) => { state.languagesLoading = true; state.languageError = null; }) .addCase(loadAvailableLanguages.fulfilled, (state, action) => { state.languagesLoading = false; state.availableLanguages = action.payload.languages; state.currentSystemLocale = action.payload.currentSystemLocale; // 默认选中当前系统语言 if (!state.selectedLanguage) { state.selectedLanguage = action.payload.currentSystemLocale; } }) .addCase(loadAvailableLanguages.rejected, (state, action) => { state.languagesLoading = false; state.languageError = action.error.message || '加载语言列表失败'; }) // 更新系统语言 .addCase(updateSystemLanguage.pending, (state) => { state.savingLanguage = true; state.languageError = null; }) .addCase(updateSystemLanguage.fulfilled, (state, action) => { state.savingLanguage = false; state.currentLocale = action.payload; }) .addCase(updateSystemLanguage.rejected, (state, action) => { state.savingLanguage = false; state.languageError = action.error.message || '修改语言失败'; }); }, }); export const { setCurrentLocale, clearError, setSelectedLanguage, clearLanguageError, } = i18nSlice.actions; export default i18nSlice.reducer;