import React, { useEffect } from 'react'; import ReactDOM from 'react-dom'; import { ConfigProvider, message, Modal, notification, } from 'antd'; import { ConnectedRouter } from 'connected-react-router/immutable'; import Cookies from 'js-cookie'; import canUseDom from 'rc-util/lib/Dom/canUseDom'; import { updateCSS } from 'rc-util/lib/Dom/dynamicCSS'; import { Provider } from 'react-redux'; import { LocaleContainer } from '@wisdom-utils/components'; import { history } from '@wisdom-utils/runtime'; import { params, Storeage, } from '@wisdom-utils/utils/lib/helpers'; import { appService } from './api'; import Container from './components/Container'; import App from './containers/App'; import { actionCreators } from './containers/App/store'; import { defaultApp, initMicroApps, } from './micro'; import Login from './pages/user/login/login'; import store from './stores'; import { getToken } from './utils/utils'; const { getThemeVariables } = require('antd/dist/theme'); const defaultSetting = require('../config/defaultSetting'); const MOUNT_NODE = document.getElementById('root'); const customPrefixCls = 'panda-console-base'; const namespace = `__PANDA_STORE__${location.hostname}`; window.createStoreage = new Storeage(namespace); const dynamicStyleMark = `-panda-${Date.now()}-${Math.random()}`; function getStyle(prefixCls, theme) { const variables = {}; Object.keys(theme).forEach(item => { variables[item] = theme[item] }) const cssList = Object.keys(variables).map( key => `--${prefixCls}-${key}: ${variables[key]};`, ); return ` :root { ${cssList.join('\n')} } `.trim(); } const registerTheme = function(prefixCls, theme) { const style = getStyle(prefixCls, theme); if(canUseDom()) { updateCSS(style, `${dynamicStyleMark}-dynamic-theme`) } } export const AppInitState = () => { const getClient = () => { const value = params.getParams('client') || Cookies.get('client'); const client = value && value !== 'undefined' ? value : 'city'; return client; } const client = getClient(); let config = window.globalConfig || {}; createStoreage.remove(`__PANDA_STORE__${location.hostname}`); window.globalConfig = {}; window.__INITIAL_STATE__ = {}; if (!getToken() || config.token == null) { // eslint-disable-next-line no-undef createStoreage.remove(namespace); config = {}; } if (!params.getParams('client', window.location.search) && config) { // eslint-disable-next-line no-undef createStoreage.remove(namespace); } // eslint-disable-next-line no-undef if (!createStoreage.get('globalConfig')) { window.createStoreage = new Storeage(namespace); } if (!getToken()) { localStorage.removeItem('loginSite'); } const initGeteWay = () => { appService.getWateWayConfig({ignoreSite: true}).then(res => { const hasGateWay = !res || !res.data ? false : _.isString(res.data) ? JSON.parse(res.data) : typeof res.data === 'boolean' ? res.data : false; return { hasGateWay, apiGatewayDomain: `${window.location.origin}${hasGateWay ? '/PandaCore/GateWay' : ''}`, }; }).then(gateWayConfig => { initGlobalConfig(gateWayConfig); }).catch(err => { initGlobalConfig(); }); } const initGlobalConfig = (gateWayConfig = {}) => { appService.queryConfig({ client: client || 'city', ignoreSite: true, }).then(res => { if (res) { const { data } = res; if (!data.client) { data.client = client; } store.dispatch(actionCreators.getConfig(Object.assign({},data,{ token: '', access_token: '', userInfo: null, },gateWayConfig))); const products = (data.products || []).map(item => { if (item.PackageName === 'civweb4') { return 'web4_console' } return `${item.PackageName}-main`; }); if(products && products.length > 0) { Object.keys(products).forEach(item => { window[products[item]] && window[products[item]] && window[products[item]].unmount && window[products[item]].unmount({ store: store }); }); initMicroApps(); } // eslint-disable-next-line no-new if (getToken()) { // eslint-disable-next-line no-new const action = new Login({ global: Object.assign({}, data, { token: getToken(), }, gateWayConfig, ), // eslint-disable-next-line no-shadow updateConfig: data => store.dispatch(actionCreators.getConfig(data)), isInit: false, logout: () => store.dispatch(actionCreators.logout()), }, () => { (async () => { (await (getToken() && window.globalConfig && window.globalConfig.token)) && initMicroApps(loader, store); })(); }, true, ); action.events.on('loginSuccess', event =>{ window.history.pushState('', '', `/?client=${client}`); defaultApp(); }) } return window.globalConfig.variableTheme } }) .then(themeConfig => { ConfigProvider.config({ prefixCls: customPrefixCls, theme: { primaryColor: themeConfig.primaryColor } }); registerTheme(customPrefixCls, { 'header-bg-color': themeConfig.headerPrimaryColor, // 'linear-gradient(0deg, #0066d6, #39a9ff 100%)' }); }) .catch(error => { store.dispatch(actionCreators.getConfigError(error)); }); } const initLocale = () => { localStorage.setItem('umi_locale', 'zh-CN'); }; // 语音播报全局拦截 const initMessageVoice = () => { const rawSpeak = window.speechSynthesis.speak; window.speechSynthesis.speak = function(...args) { if ( window.globalConfig && // eslint-disable-next-line no-prototype-builtins window.globalConfig.hasOwnProperty('messageVoice') && window.globalConfig.messageVoice === false ) return; rawSpeak.apply(window.speechSynthesis, args); }; }; // 添加主题变更事件监听 const initAppTheme = () => { const hasThemeChanged = (preTheme, theme) => { if (!preTheme && !theme) return false if ( preTheme && theme && (!theme.primaryColor || theme.primaryColor === preTheme.primaryColor) && (!theme.navTheme || theme.navTheme === preTheme.navTheme) && (!theme.headerPrimaryColor || theme.headerPrimaryColor === preTheme.headerPrimaryColor) ) return false return true } store.subscribe((function() { let preVariableTheme = store.getState().toJS().global?.globalConfig?.variableTheme; return function() { // if (!preVariableTheme) const variableTheme = store.getState().toJS().global?.globalConfig?.variableTheme; if(!hasThemeChanged(preVariableTheme, variableTheme)) return false const { primaryColor: prePrimaryColor, navTheme: preNavTheme, headerPrimaryColor: preHeaderPrimaryColor, } = (preVariableTheme || {}); const { primaryColor, headerPrimaryColor } = variableTheme; if (primaryColor && primaryColor !== prePrimaryColor) { ConfigProvider.config({ prefixCls: customPrefixCls, theme: { primaryColor, } }); } if (headerPrimaryColor && headerPrimaryColor !== preHeaderPrimaryColor) { registerTheme(customPrefixCls, { 'header-bg-color': headerPrimaryColor, }); } } })()) }; initLocale(); initMessageVoice(); initGeteWay(); initAppTheme(); } const RootContainer = (props) => { const { loading } = props; useEffect(() => { AppInitState(); }, []); const finalConfig = { ...{ prefixCls: customPrefixCls, theme: { 'root-entry-name': 'default', ...getThemeVariables({}), primaryColor: defaultSetting.primaryColor, }, }, }; if (finalConfig.prefixCls) { Modal.config({ rootPrefixCls: customPrefixCls, }); message.config({ rootPrefixCls: `${finalConfig.prefixCls}-message`, }); notification.config({ rootPrefixCls: `${finalConfig.prefixCls}-notification`, }); } return React.createElement(Provider, { store: store, }, React.createElement(ConnectedRouter, { history: history, }, React.createElement(LocaleContainer, { prefixCls: customPrefixCls, }, React.createElement(ConfigProvider, { prefixCls: customPrefixCls, }, React.createElement(Container, null, React.createElement(App , { loading, })))))); }; export const render = ({ loading }) => { // eslint-disable-next-line react-hooks/rules-of-hooks ReactDOM.render(<RootContainer loading={loading} />, MOUNT_NODE); }; // updateTheme('#ff9600'); const loader = (loading) => render({ loading }); export default loader;