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'; // eslint-disable-next-line no-restricted-globals 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') || sessionStorage.getItem('client'); const client = value && value !== 'undefined' ? value : 'city'; return client; }; const getUrlToken = () => { const value = params.getParams('token'); const token = value && value !== 'undefined' ? value : null; return token; }; const client = getClient(); const token = getUrlToken(); if (sessionStorage.getItem('client') !== client) { sessionStorage.setItem('client', client); } let config = window.globalConfig || {}; // eslint-disable-next-line no-undef, no-restricted-globals createStoreage.remove(`__PANDA_STORE__${location.hostname}`); window.globalConfig = {}; // eslint-disable-next-line no-underscore-dangle 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 => { // eslint-disable-next-line prettier/prettier, no-undef 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 => { // eslint-disable-next-line no-use-before-define initGlobalConfig(gateWayConfig); }) .catch(err => { // eslint-disable-next-line no-use-before-define initGlobalConfig(); }); }; const initGlobalConfig = (gateWayConfig = {}) => { appService .queryConfig({ client: client || 'city', ignoreSite: true, }) .then(res => { if (res) { const { data } = res; if (!data.client) { data.client = client; } if (data.pwdRegex) { localStorage.setItem('password_pwdRegex', data.pwdRegex); } else { localStorage.removeItem('password_pwdRegex'); } if (data.pwdRegexTip) { localStorage.setItem('password_pwdRegexTip', data.pwdRegexTip); } else { localStorage.removeItem('password_pwdRegexTip'); } if (data.webState === '1' || data.webState === '3') { data.isIntegration = '1'; } 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 }); }); } // eslint-disable-next-line no-new // 增加免登判定 if (!token && 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)) && // // eslint-disable-next-line no-use-before-define // 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 () { const 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) { ConfigProvider.config({ rootPrefixCls: customPrefixCls, }); message.config({ rootPrefixCls: `${finalConfig.prefixCls}-message`, }); notification.config({ rootPrefixCls: `${finalConfig.prefixCls}-notification`, }); } return React.createElement( Provider, { store, }, React.createElement( ConnectedRouter, { 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;