import { Reducer } from 'redux'; // eslint-disable-next-line eslint-comments/disable-enable-pair /* eslint-disable promise/catch-or-return */ import { message } from 'antd'; import defaultSettings, { DefaultSettings } from '../../config/defaultSettings'; import themeColorClient from '../components/SettingDrawer/themeColorClient'; import { getCurrentUserSetting, saveCurrentUserSetting } from '@/services/user'; import { Effect } from 'dva'; export interface UserSetting extends DefaultSettings { settingId?: number; userId?: number; } export interface SettingModelType { namespace: 'settings'; state: UserSetting; effects: { getSettings: Effect; }; reducers: { getSetting: Reducer; changeSetting: Reducer; }; } const updateTheme = (newPrimaryColor?: string) => { if (newPrimaryColor) { const timeOut = 0; const hideMessage = message.loading('正在切换主题!', timeOut); themeColorClient.changeColor(newPrimaryColor).finally(() => hideMessage()); } }; const updateColorWeak: (colorWeak: boolean) => void = colorWeak => { const root = document.getElementById('root'); if (root) { root.className = colorWeak ? 'colorWeak' : ''; } }; const SettingModel: SettingModelType = { namespace: 'settings', state: defaultSettings, effects: { *saveSettings({ payload }, { call, put }) { const { navTheme, primaryColor, layout, contentWidth, fixedHeader, autoHideHeader, fixSiderbar, userId, settingId, } = payload; yield call(saveCurrentUserSetting, { userId, settingId, appStyle: navTheme === 'light' ? 0 : 1, appTheme: primaryColor, navigatorStyle: layout === 'sidemenu' ? 0 : 1, contentWidth: navTheme === 'Fluid' ? 0 : 1, fixedHead: fixedHeader ? 1 : 0, fixedSide: fixSiderbar ? 1 : 0, hideHead: autoHideHeader ? 1 : 0, }); }, *getSettings({ payload }, { call, put }) { const { data, code } = yield call(getCurrentUserSetting, payload); let settings = defaultSettings; console.log(data); if (code === 'sys.success' && data) { const { appStyle, appTheme, navigatorStyle, contentWidth, fixedHead, fixedSide, hideHead, } = data; settings = { ...settings, ...data, navTheme: appStyle === 0 ? 'light' : 'dark', primaryColor: appTheme, layout: navigatorStyle === 0 ? 'sidemenu' : 'topmenu', contentWidth: contentWidth === 0 ? 'Fluid' : 'Fixed', fixedHeader: fixedHead === 1, autoHideHeader: hideHead === 1, fixSiderbar: fixedSide === 1, }; } yield put({ type: 'saveSettings', payload: settings, }); }, }, reducers: { saveSettings(state = defaultSettings, { payload }) { const setting: Partial = {}; const urlParams = new URL(window.location.href); Object.keys(state).forEach(key => { if (urlParams.searchParams.has(key)) { const value = urlParams.searchParams.get(key); setting[key] = value === '1' ? true : value; } }); const { primaryColor, colorWeak } = setting; if (primaryColor && state.primaryColor !== primaryColor) { updateTheme(primaryColor); } updateColorWeak(!!colorWeak); return { ...state, ...setting, ...payload, }; }, changeSetting(state = defaultSettings, { payload }) { const urlParams = new URL(window.location.href); Object.keys(defaultSettings).forEach(key => { if (urlParams.searchParams.has(key)) { urlParams.searchParams.delete(key); } }); Object.keys(payload).forEach(key => { if (key === 'collapse') { return; } let value = payload[key]; if (value === true) { value = 1; } if (defaultSettings[key] !== value) { urlParams.searchParams.set(key, value); } }); const { primaryColor, colorWeak, contentWidth } = payload; if (primaryColor && state.primaryColor !== primaryColor) { updateTheme(primaryColor); } if (state.contentWidth !== contentWidth && window.dispatchEvent) { window.dispatchEvent(new Event('resize')); } updateColorWeak(!!colorWeak); window.history.replaceState(null, 'setting', urlParams.href); return { ...state, ...payload, }; }, }, }; export default SettingModel;