Commit fb5e1a80 authored by yzl's avatar yzl

- 优化进入子应用过渡效果

- 增加进入子应用前的进度条
parent 20787d5e
Pipeline #57560 passed with stages
...@@ -15,5 +15,5 @@ import 'antd/dist/antd.less'; ...@@ -15,5 +15,5 @@ import 'antd/dist/antd.less';
// const namespace = `__PANDA_STORE__${location.hostname}`; // const namespace = `__PANDA_STORE__${location.hostname}`;
// window.createStoreage = new Storeage(namespace); // window.createStoreage = new Storeage(namespace);
;(() => { ;(() => {
render(); render({loading: true });
})(); })();
\ No newline at end of file
import { Spin } from 'antd';
export default (props) => {
const { loading } = props;
const style = {
position: 'absolute',
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)',
}
return (
<Spin spinning={loading} size="large" style={style} tip="子应用正在加载..." />
);
}
...@@ -3,24 +3,29 @@ import React from 'react'; ...@@ -3,24 +3,29 @@ import React from 'react';
import { Helmet } from 'react-helmet'; import { Helmet } from 'react-helmet';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { Router, Switch } from '@wisdom-utils/runtime'; import { Router, Switch } from '@wisdom-utils/runtime';
import { helpers } from '@wisdom-utils/utils'; import { helpers, event } from '@wisdom-utils/utils';
import defaultSetting from '@wisdom-utils/components/lib/AppLayout/layouts/defaultSettings'; import defaultSetting from '@wisdom-utils/components/lib/AppLayout/layouts/defaultSettings';
// eslint-disable-next-line import/extensions // eslint-disable-next-line import/extensions
import { dyRoutes } from '../../routes/config'; import { dyRoutes } from '../../routes/config';
const pkg = require('../../../package.json'); const pkg = require('../../../package.json');
const { renderRoutes } = helpers; const { renderRoutes } = helpers;
const config = require('../../../config/config'); const config = require('../../../config/config');
function App(props) { function App(props) {
event.emit('loading' , props.loading);
const metaSecurity = /https/.test(window.location.protocol) ? ( const metaSecurity = /https/.test(window.location.protocol) ? (
<meta httpEquiv="Content-Security-Policy" content="upgrade-insecure-requests" /> <meta httpEquiv='Content-Security-Policy' content='upgrade-insecure-requests' />
) : null; ) : null;
return ( return (
<> <>
<Helmet title={`${(props.global && props.global.title) || defaultSetting.title}`}> <Helmet title={`${(props.global && props.global.title) || defaultSetting.title}`}>
<title>{`${(props.global && props.global.title) || defaultSetting.title}`}</title> <title>{`${(props.global && props.global.title) || defaultSetting.title}`}</title>
<link rel="shortcut icon" href={`${window.location.origin}/web4/${props.global && props.global.shortcutIcon}`} /> <link rel='shortcut icon'
href={`${window.location.origin}/web4/${props.global && props.global.shortcutIcon}`} />
{metaSecurity} {metaSecurity}
<meta name="description" content={`${(props.global && props.global.title) || defaultSetting.title}`} /> <meta name='description' content={`${(props.global && props.global.title) || defaultSetting.title}`} />
</Helmet> </Helmet>
<Router basename={config.base || pkg.name.toLocaleLowerCase() || ''}> <Router basename={config.base || pkg.name.toLocaleLowerCase() || ''}>
<Switch> <Switch>
...@@ -32,7 +37,7 @@ function App(props) { ...@@ -32,7 +37,7 @@ function App(props) {
(props.global && props.global.theme) || 'dark', (props.global && props.global.theme) || 'dark',
).routes, ).routes,
)} )}
</Switch> </Switch>
</Router> </Router>
</> </>
...@@ -41,7 +46,7 @@ function App(props) { ...@@ -41,7 +46,7 @@ function App(props) {
const mapStateToProps = state => ({ const mapStateToProps = state => ({
global: state.getIn(['global', 'globalConfig']), global: state.getIn(['global', 'globalConfig']),
menu: state.getIn(['global', 'menu']) menu: state.getIn(['global', 'menu']),
}); });
export default connect( export default connect(
mapStateToProps, mapStateToProps,
......
This diff is collapsed.
...@@ -62,25 +62,32 @@ export const initMicroApps = () => { ...@@ -62,25 +62,32 @@ export const initMicroApps = () => {
micorConfig.dev : micorConfig.dev :
products; products;
registerMicroApps( const apps = entrys.map(item => {
entrys.map(item => { return {
item.loader = loader; ...item,
item.props = { props: {
emitter: window.share.event, emitter: window.share.event,
baseRoot: item.name, baseRoot: item.name,
event: event, event: event,
store: microStore, store: microStore,
// eslint- // eslint-
// disable-next-line no-undef // disable-next-line no-undef
globalConfig: /civweb4/.test(item.name) ? Object.assign({}, config, { globalConfig: /civweb4/.test(item.name) ? Object.assign({}, config, {
homepage: config.homepage ? config.homepage.replace(/civweb\//, '') : config.homepage homepage: config.homepage ? config.homepage.replace(/civweb\//, '') : config.homepage
}) : config, }) : config,
//createStoreage.get('globalConfig'), //createStoreage.get('globalConfig'),
XMLHttpRequest: window.XMLHttpRequest, XMLHttpRequest: window.XMLHttpRequest,
// offGlobalStateChange: actions.offGlobalStateChange // offGlobalStateChange: actions.offGlobalStateChange
}; }
return item; }
}), { })
const microApps = apps.map((app => ({
...app,
loader,
})))
registerMicroApps(microApps, {
beforeLoad: [ beforeLoad: [
app => { app => {
store.dispatch(actionCreators.updateMicroMounted(true)); store.dispatch(actionCreators.updateMicroMounted(true));
...@@ -208,17 +215,20 @@ export const initMicroApps = () => { ...@@ -208,17 +215,20 @@ export const initMicroApps = () => {
}; };
export const defaultApp = () => { export const defaultApp = () => {
const globalStore = store.getState().toJS();
const globalStore = store.getState().toJS();
// eslint-disable-next-line no-undef // eslint-disable-next-line no-undef
const config = window.globalConfig; const config = window.globalConfig;
// const flatMenu = globalStore.global.flatMenu; // const flatMenu = globalStore.global.flatMenu;
// const current = flatMenu.find(item => item.name === '首页'); // const current = flatMenu.find(item => item.name === '首页');
// config.homepage = current.path; // config.homepage = current.path;
if (config && config.token) { if (config && config.token) {
let url = !config.home ? let url = !config.home ?
((config.homepage === '' || _.isNull(config.homepage)) ? `/civbase/civweb4`: (`/civbase/${config.homepage.replace(/^\//, '')}`)) : `/civbase/${config.homepage.replace(/^\//, '')}`; ((config.homepage === '' || _.isNull(config.homepage)) ? `/civbase/civweb4`: (`/civbase/${config.homepage.replace(/^\//, '')}`)) : `/civbase/${config.homepage.replace(/^\//, '')}`;
setDefaultMountApp(url); setDefaultMountApp(url);
window.history.pushState(null, '', url);
event.emit('visible', false);
} }
}; };
......
// 云平台引导页 // 云平台引导页
import React, { useCallback, useEffect, useMemo, useState } from 'react'; import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { Space, Spin } from 'antd'; import { Space, Spin, Progress } from 'antd';
import classNames from 'classnames'; import classNames from 'classnames';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { useIntl } from '@wisdom-utils/components'; import { useIntl } from '@wisdom-utils/components';
...@@ -16,44 +16,25 @@ import usingIcon from '@/assets/bootPage/using-icon.png'; ...@@ -16,44 +16,25 @@ import usingIcon from '@/assets/bootPage/using-icon.png';
import { appService } from '@/api'; import { appService } from '@/api';
const industries = [ const industries = [
{ name: '供水', type: '供水', subTitle: 'WATER SUPPLY' }, { name: '供水', type: '供水', subTitle: 'WATER SUPPLY' , color: 'rgb(16,104,239)'},
{ name: '农饮水', type: '农饮水', subTitle: 'RURAL POTABLE WATER' }, { name: '农饮水', type: '农饮水', subTitle: 'RURAL POTABLE WATER' , color: 'rgb(4,142,101)'},
{ name: '排水', type: '排水', subTitle: 'DRAINAGE' }, { name: '排水', type: '排水', subTitle: 'DRAINAGE' , color: 'rgb(234,117,28)'},
{ name: '水利', type: '水利', subTitle: 'WATER CONSERVANCY' }, { name: '水利', type: '水利', subTitle: 'WATER CONSERVANCY' , color: 'rgb(0,144,158)'},
{ name: '能源', type: '能源', subTitle: 'ENERGY SOURCES' }, { name: '能源', type: '能源', subTitle: 'ENERGY SOURCES', color: 'rgb(16,104,239)' },
{ name: '高品质水', type: '高品质水', subTitle: 'HIGH QUALITY WATER' }, { name: '高品质水', type: '高品质水', subTitle: 'HIGH QUALITY WATER' , color: 'rgb(16,104,239)'},
// { name: '水资源', type: '水资源', subTitle: 'WATER RESOURCES' }, // { name: '水资源', type: '水资源', subTitle: 'WATER RESOURCES' },
{ name: '熊猫智能实验室', type: '实验室', subTitle: 'PANDA AI. LAB' }, { name: '熊猫智能实验室', type: '实验室', subTitle: 'PANDA AI. LAB', color: 'rgb(16,104,239)' },
{ name: '水务大数据', type: '大数据', subTitle: 'WATER BIG DATA' }, { name: '水务大数据', type: '大数据', subTitle: 'WATER BIG DATA' , color: 'rgb(85,77,210)'},
{ name: '熊猫新产品', type: '熊猫新产品', subTitle: "PANDA'S NEW PRODUCT" }, { name: '熊猫新产品', type: '熊猫新产品', subTitle: "PANDA'S NEW PRODUCT" , color: 'rgb(12,103,205)'},
{ name: '项目案例', type: '项目案例', subTitle: 'PROJECT CASE' }, { name: '项目案例', type: '项目案例', subTitle: 'PROJECT CASE' , color: 'rgb(107,36,155)'},
]; ];
const renderIndustries = (config, callback) =>
industries.map(item => {
if (
config &&
config.userInfo &&
config.userInfo.Industries &&
config.userInfo.Industries instanceof Array &&
config.userInfo.Industries.indexOf(item.type) > -1
) {
return (
<li className={styles.bootPageLi} key={item.type} onClick={event => callback(event, item.type)}>
<div className={styles.bootPageList}>
<div className={styles.listMain}>
<img src={require(`@/assets/bootPage/${item.type}.png`)} alt="" />
<span className={styles.bootPageName}>{item.name}</span>
<span className={styles.bootPageNameEng}>{item.subTitle}</span>
</div>
</div>
</li>
);
}
});
// let loginAction = null; // let loginAction = null;
const BootPage = props => { const BootPage = props => {
const [loadding, setLoadding] = useState(false); const {visible} = props;
const [percentNum, setPercentNum] = useState(10);
const [currentType, setCurrentType] = useState('');
// const [loadding, setLoadding] = useState(false);
const [hasRole, setHasRole] = useState(false); const [hasRole, setHasRole] = useState(false);
const [scale, setScale] = useState(1); const [scale, setScale] = useState(1);
const [loginAction, setAction] = useState(() => new LoginAction(props)); const [loginAction, setAction] = useState(() => new LoginAction(props));
...@@ -62,8 +43,11 @@ const BootPage = props => { ...@@ -62,8 +43,11 @@ const BootPage = props => {
{ title: defaultSetting.title, id: '', pageName: '行业切换' }, { title: defaultSetting.title, id: '', pageName: '行业切换' },
props.global.title || defaultSetting.title, props.global.title || defaultSetting.title,
); );
const handlePage = useCallback( const handlePage = useCallback(
(event, type) => { (event, type) => {
setPercentNum(Math.ceil(Math.random()*50));
event.persist(); event.persist();
event.preventDefault(); event.preventDefault();
...@@ -73,7 +57,7 @@ const BootPage = props => { ...@@ -73,7 +57,7 @@ const BootPage = props => {
return; return;
} }
setLoadding(true); // setLoadding(true);
const config = props.global; const config = props.global;
// const loginAction = new LoginAction(props); // const loginAction = new LoginAction(props);
config.uiwidgets = []; config.uiwidgets = [];
...@@ -82,9 +66,56 @@ const BootPage = props => { ...@@ -82,9 +66,56 @@ const BootPage = props => {
props.instance && props.instance.updateConfig(config); props.instance && props.instance.updateConfig(config);
// props.instance && props.instance.getUserInfoAndConfig('', true, type); // props.instance && props.instance.getUserInfoAndConfig('', true, type);
loginAction && loginAction.getUserInfoAndConfig('', true, type); loginAction && loginAction.getUserInfoAndConfig('', true, type);
},
setCurrentType(type);
},
[loginAction, props.global.token, props.instance], [loginAction, props.global.token, props.instance],
); );
const renderIndustries = (config, callback) =>
industries.map(item => {
if (
config &&
config.userInfo &&
config.userInfo.Industries &&
config.userInfo.Industries instanceof Array &&
config.userInfo.Industries.indexOf(item.type) > -1
) {
return (
<li className={styles.bootPageLi} key={item.type} onClick={event => callback(event, item.type)}>
<div className={styles.bootPageList}>
<div className={styles.listMain}>
<img src={require(`@/assets/bootPage/${item.type}.png`)} alt="" />
<span className={styles.bootPageName}>{item.name}</span>
<span className={styles.bootPageNameEng}>{item.subTitle}</span>
</div>
</div>
{
currentType === item.type && <Progress
style={{width: '98%'}}
strokeColor={item.color}
percent={percentNum}
status="active"
format={percent => <span style={{color: '#fff'}}>{percent}%</span>}
className={styles.bootProgress}
/>
}
</li>
);
}
});
useEffect(() => {
if(visible){
setCurrentType('');
setPercentNum(10);
}
} , [visible])
useEffect(() => { useEffect(() => {
// eslint-disable-next-line no-use-before-define // eslint-disable-next-line no-use-before-define
handleResize(); handleResize();
...@@ -100,11 +131,16 @@ const BootPage = props => { ...@@ -100,11 +131,16 @@ const BootPage = props => {
window.addEventListener('resize', handleResize); window.addEventListener('resize', handleResize);
const handleToggleIndustry = event => { const handleToggleIndustry = event => {
setLoadding(false);
props.history.push(`/?client=${props.global.client}`); // props.history.push(`/?client=${props.global.client}`);
defaultApp(); defaultApp();
// window.share.event.emit('triggerMicro', props.global); // window.share.event.emit('triggerMicro', props.global);
props.updateCurrentIndex(0); props.updateCurrentIndex(0);
setPercentNum(100);
// setLoadding(false);
}; };
loginAction.events.on('toggleIndustry', handleToggleIndustry); loginAction.events.on('toggleIndustry', handleToggleIndustry);
return () => { return () => {
...@@ -114,7 +150,7 @@ const BootPage = props => { ...@@ -114,7 +150,7 @@ const BootPage = props => {
}, [loginAction.events, props]); }, [loginAction.events, props]);
const [IndustryNum, setIndustryNum] = useState(0); const [IndustryNum, setIndustryNum] = useState(0);
const renderIndustr = useMemo(() => renderIndustries(props.global, handlePage), [handlePage, props.global.token]); const renderIndustr = useMemo(() => renderIndustries(props.global, handlePage), [handlePage, props.global.token, currentType, percentNum]);
useEffect(() => { useEffect(() => {
const NewIndustryNum = const NewIndustryNum =
props.global && props.global.userInfo && props.global.userInfo.Industries props.global && props.global.userInfo && props.global.userInfo.Industries
...@@ -172,9 +208,9 @@ const BootPage = props => { ...@@ -172,9 +208,9 @@ const BootPage = props => {
{renderIndustr} {renderIndustr}
</ul> </ul>
</section> </section>
<Space className={styles.abs}> {/*<Space className={styles.abs}>*/}
<Spin spinning={loadding} size="large" /> {/* <Spin spinning={loadding} size="large" />*/}
</Space> {/*</Space>*/}
</div> </div>
{hasRole ? ( {hasRole ? (
<div className={styles.cloudMonitorBtns}> <div className={styles.cloudMonitorBtns}>
......
...@@ -61,6 +61,7 @@ ...@@ -61,6 +61,7 @@
transition: all .5s ease-out; transition: all .5s ease-out;
padding-top: 10px; padding-top: 10px;
.bootPageLi { .bootPageLi {
position: relative;
width: 298px; width: 298px;
height: 268.8px; height: 268.8px;
margin: 10px; margin: 10px;
...@@ -166,7 +167,12 @@ ...@@ -166,7 +167,12 @@
.@{ant-prefix}-spin-nested-loading, .@{ant-prefix}-spin-nested-loading,
.@{ant-prefix}-spin-container { .@{ant-prefix}-spin-container {
height: 100%; height: 100%;
} }
}
.bootProgress {
position: absolute;
bottom: -5px;
} }
} }
......
...@@ -81,7 +81,7 @@ export const AppInitState = () => { ...@@ -81,7 +81,7 @@ export const AppInitState = () => {
let config = window.globalConfig || {}; let config = window.globalConfig || {};
createStoreage.remove(`__PANDA_STORE__${location.hostname}`); createStoreage.remove(`__PANDA_STORE__${location.hostname}`);
window.globalConfig = {}; window.globalConfig = {};
window.__INITIAL_STATE__ = {}; window.__INITIAL_STATE__ = {};
...@@ -233,11 +233,11 @@ export const AppInitState = () => { ...@@ -233,11 +233,11 @@ export const AppInitState = () => {
store.subscribe((function() { store.subscribe((function() {
let preVariableTheme = store.getState().toJS().global?.globalConfig?.variableTheme; let preVariableTheme = store.getState().toJS().global?.globalConfig?.variableTheme;
return function() { return function() {
// if (!preVariableTheme) // if (!preVariableTheme)
const variableTheme = store.getState().toJS().global?.globalConfig?.variableTheme; const variableTheme = store.getState().toJS().global?.globalConfig?.variableTheme;
if(!hasThemeChanged(preVariableTheme, variableTheme)) return false if(!hasThemeChanged(preVariableTheme, variableTheme)) return false
const { const {
primaryColor: prePrimaryColor, primaryColor: prePrimaryColor,
navTheme: preNavTheme, navTheme: preNavTheme,
headerPrimaryColor: preHeaderPrimaryColor, headerPrimaryColor: preHeaderPrimaryColor,
} = (preVariableTheme || {}); } = (preVariableTheme || {});
...@@ -265,7 +265,8 @@ export const AppInitState = () => { ...@@ -265,7 +265,8 @@ export const AppInitState = () => {
initAppTheme(); initAppTheme();
} }
const RootContainer = () => { const RootContainer = (props) => {
const { loading } = props;
useEffect(() => { useEffect(() => {
AppInitState(); AppInitState();
...@@ -275,43 +276,46 @@ const RootContainer = () => { ...@@ -275,43 +276,46 @@ const RootContainer = () => {
...{ ...{
prefixCls: customPrefixCls, prefixCls: customPrefixCls,
theme: { theme: {
"root-entry-name": "default", 'root-entry-name': 'default',
...getThemeVariables({}), ...getThemeVariables({}),
primaryColor: defaultSetting.primaryColor, primaryColor: defaultSetting.primaryColor,
}, },
} },
} };
if(finalConfig.prefixCls) { if (finalConfig.prefixCls) {
Modal.config({ Modal.config({
rootPrefixCls: customPrefixCls rootPrefixCls: customPrefixCls,
}); });
message.config({ message.config({
rootPrefixCls: `${finalConfig.prefixCls}-message` rootPrefixCls: `${finalConfig.prefixCls}-message`,
}); });
notification.config({ notification.config({
rootPrefixCls: `${finalConfig.prefixCls}-notification` rootPrefixCls: `${finalConfig.prefixCls}-notification`,
}); });
} }
return React.createElement(Provider, { return React.createElement(Provider, {
store: store store: store,
}, React.createElement(ConnectedRouter, { }, React.createElement(ConnectedRouter, {
history: history history: history,
}, React.createElement(LocaleContainer, { }, React.createElement(LocaleContainer, {
prefixCls: customPrefixCls prefixCls: customPrefixCls,
}, React.createElement(ConfigProvider, { }, React.createElement(ConfigProvider, {
prefixCls: customPrefixCls prefixCls: customPrefixCls,
}, React.createElement(Container, null, React.createElement(App)))))) }, React.createElement(Container, null, React.createElement(App , {
} loading,
}))))));
};
export const render = ({ loading }) => {
export const render = () => {
// eslint-disable-next-line react-hooks/rules-of-hooks // eslint-disable-next-line react-hooks/rules-of-hooks
ReactDOM.render(<RootContainer/>, MOUNT_NODE); ReactDOM.render(<RootContainer loading={loading} />, MOUNT_NODE);
}; };
// updateTheme('#ff9600'); // updateTheme('#ff9600');
const loader = (appContent, loading) => render({ appContent, loading }); const loader = (loading) => render({ loading });
export default loader; export default loader;
...@@ -41,10 +41,10 @@ export const dyRoutes = (routes, layout, theme) => { ...@@ -41,10 +41,10 @@ export const dyRoutes = (routes, layout, theme) => {
}, },
], ],
}, },
{ // {
path: '/industry', // path: '/industry',
component: BootPage, // component: BootPage,
}, // },
{ {
path: '/cloud/analysis/using', path: '/cloud/analysis/using',
component: UsingAnalysis, component: UsingAnalysis,
...@@ -64,7 +64,7 @@ export const dyRoutes = (routes, layout, theme) => { ...@@ -64,7 +64,7 @@ export const dyRoutes = (routes, layout, theme) => {
component: CommonMenu, component: CommonMenu,
// name: '菜单收藏' // name: '菜单收藏'
}, },
{ {
// 历史消息箱 // 历史消息箱
path: '/system/notifications', path: '/system/notifications',
component: Notifications, component: Notifications,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment