i18nSlice.ts 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. import { createSlice, createAsyncThunk, PayloadAction } from '@reduxjs/toolkit';
  2. import { fetchI18nMessages, I18nMessages } from '../API/i18n/i18nActions';
  3. export interface I18nState {
  4. messages: I18nMessages;
  5. currentLocale: string;
  6. supportedLocales: string[];
  7. loading: boolean;
  8. error: string | null;
  9. }
  10. const initialState: I18nState = {
  11. messages: {},
  12. currentLocale: 'en',
  13. supportedLocales: ['en', 'zh'],
  14. loading: false,
  15. error: null,
  16. };
  17. // 异步thunk:加载多语言资源
  18. export const loadI18nMessages = createAsyncThunk(
  19. 'i18n/loadMessages',
  20. async (locale: string) => {
  21. const messages = await fetchI18nMessages(locale);
  22. return { locale, messages };
  23. }
  24. );
  25. const i18nSlice = createSlice({
  26. name: 'i18n',
  27. initialState,
  28. reducers: {
  29. setCurrentLocale: (state, action: PayloadAction<string>) => {
  30. state.currentLocale = action.payload;
  31. },
  32. clearError: (state) => {
  33. state.error = null;
  34. },
  35. },
  36. extraReducers: (builder) => {
  37. builder
  38. .addCase(loadI18nMessages.pending, (state) => {
  39. state.loading = true;
  40. state.error = null;
  41. })
  42. .addCase(loadI18nMessages.fulfilled, (state, action) => {
  43. state.loading = false;
  44. state.messages = action.payload.messages;
  45. state.currentLocale = action.payload.locale;
  46. })
  47. .addCase(loadI18nMessages.rejected, (state, action) => {
  48. state.loading = false;
  49. state.error = action.error.message || 'Failed to load i18n messages';
  50. });
  51. },
  52. });
  53. export const { setCurrentLocale, clearError } = i18nSlice.actions;
  54. export default i18nSlice.reducer;