恢复到没有加载效果的 除了效果别的还都是新的
This commit is contained in:
parent
02b1425689
commit
b07d192d20
@ -20,9 +20,9 @@ export default defineConfig({
|
||||
hash: true,
|
||||
mock: false,
|
||||
antd: {},
|
||||
// dva: {
|
||||
// hmr: true
|
||||
// },
|
||||
dva: {
|
||||
hmr: true
|
||||
},
|
||||
history: {
|
||||
type: REACT_APP_ENV === 'dev' ? "hash" : "memory",
|
||||
// type: "hash"
|
||||
@ -36,7 +36,7 @@ export default defineConfig({
|
||||
baseNavigator: true,
|
||||
},
|
||||
dynamicImport: {
|
||||
loading: '@/components/SmartLoading/index',
|
||||
loading: '@/components/PageLoading/index',
|
||||
},
|
||||
targets: {
|
||||
ie: 11,
|
||||
|
||||
17
src/app.ts
17
src/app.ts
@ -7,7 +7,6 @@
|
||||
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||
*/
|
||||
import globalState from './globalState';
|
||||
import { routePreloader } from './utils/routePreloader';
|
||||
|
||||
// import { getMicroAppRouteComponent } from 'umi';
|
||||
|
||||
@ -30,22 +29,6 @@ export const qiankun = {
|
||||
}
|
||||
|
||||
|
||||
// 应用启动时的初始化配置
|
||||
export async function getInitialState() {
|
||||
// 预加载关键路由以优化首屏加载
|
||||
setTimeout(() => {
|
||||
routePreloader.preloadCriticalRoutes().then(() => {
|
||||
console.log('关键路由预加载完成');
|
||||
}).catch(error => {
|
||||
console.warn('关键路由预加载失败:', error);
|
||||
});
|
||||
}, 1000); // 延迟1秒后开始预加载,避免影响首屏渲染
|
||||
|
||||
return {
|
||||
preloadEnabled: true,
|
||||
};
|
||||
}
|
||||
|
||||
// export const patchRoutes = ({ routes }: any) => {
|
||||
// console.info('routes', routes);
|
||||
// routes[0].routes[1].routes[0].routes.forEach((item: any, index: number) => {
|
||||
|
||||
@ -1,7 +0,0 @@
|
||||
.page-loading-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
width: 100%;
|
||||
}
|
||||
@ -1,13 +1,5 @@
|
||||
// import { PageLoading } from '@ant-design/pro-layout';
|
||||
|
||||
// // loading components from code split
|
||||
// // https://umijs.org/plugin/umi-plugin-react.html#dynamicimport
|
||||
// export default PageLoading;
|
||||
import React from 'react';
|
||||
import SkeletonLoading from '../SkeletonLoading';
|
||||
|
||||
const PageLoading: React.FC = () => {
|
||||
return <SkeletonLoading type="page" />;
|
||||
};
|
||||
import { PageLoading } from '@ant-design/pro-layout';
|
||||
|
||||
// loading components from code split
|
||||
// https://umijs.org/plugin/umi-plugin-react.html#dynamicimport
|
||||
export default PageLoading;
|
||||
@ -3,7 +3,13 @@
|
||||
// 默认不播放动画,只有带animate类时才播放
|
||||
&.animate {
|
||||
animation: pageEnter 0.5s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
will-change: opacity, transform;
|
||||
// 移除will-change避免HMR时样式冲突
|
||||
// will-change: opacity, transform;
|
||||
}
|
||||
|
||||
// 动画结束后重置will-change,避免持续占用GPU资源
|
||||
&.animate:not(:hover):not(:focus) {
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
}
|
||||
|
||||
@ -11,12 +17,12 @@
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(30px) scale(0.96);
|
||||
filter: blur(4px);
|
||||
// filter: blur(4px); // 注释掉filter属性,可能导致HMR问题
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0) scale(1);
|
||||
filter: blur(0);
|
||||
// filter: blur(0); // 注释掉filter属性
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -41,7 +41,7 @@ const PageTransition: React.FC<PageTransitionProps> = ({
|
||||
);
|
||||
};
|
||||
|
||||
// 简化版本 - 仅使用CSS动画
|
||||
// 简化版本 - 禁用所有动画
|
||||
export const SimplePageTransition: React.FC<{
|
||||
children: React.ReactNode;
|
||||
className?: string;
|
||||
@ -50,20 +50,25 @@ export const SimplePageTransition: React.FC<{
|
||||
}> = ({
|
||||
children,
|
||||
className = '',
|
||||
enableAnimation = true,
|
||||
enableAnimation = false, // 强制禁用动画
|
||||
onAnimationEnd,
|
||||
}) => {
|
||||
// 立即执行回调,不等待动画
|
||||
const handleAnimationEnd = () => {
|
||||
if (enableAnimation && onAnimationEnd) {
|
||||
if (onAnimationEnd) {
|
||||
onAnimationEnd();
|
||||
}
|
||||
};
|
||||
|
||||
// 立即执行动画结束回调
|
||||
React.useEffect(() => {
|
||||
if (onAnimationEnd) {
|
||||
onAnimationEnd();
|
||||
}
|
||||
}, [onAnimationEnd]);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`simple-page-transition ${enableAnimation ? 'animate' : ''} ${className}`}
|
||||
onAnimationEnd={handleAnimationEnd}
|
||||
>
|
||||
<div className={`simple-page-transition ${className}`}>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
// @import '~antd/es/style/themes/default.less';
|
||||
@import '~antd/dist/antd.less';
|
||||
@import '~antd/es/style/themes/default.less';
|
||||
|
||||
html,
|
||||
body,
|
||||
@ -25,51 +24,6 @@ body {
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
// 骨架屏优化样式
|
||||
.ant-skeleton {
|
||||
.ant-skeleton-content {
|
||||
|
||||
.ant-skeleton-title,
|
||||
.ant-skeleton-paragraph>li {
|
||||
background: linear-gradient(90deg, #f2f2f2 25%, #e6e6e6 50%, #f2f2f2 75%);
|
||||
background-size: 200% 100%;
|
||||
animation: loading 1.4s ease-in-out infinite;
|
||||
}
|
||||
}
|
||||
|
||||
.ant-skeleton-avatar {
|
||||
background: linear-gradient(90deg, #f2f2f2 25%, #e6e6e6 50%, #f2f2f2 75%);
|
||||
background-size: 200% 100%;
|
||||
animation: loading 1.4s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.ant-skeleton-input,
|
||||
.ant-skeleton-button {
|
||||
background: linear-gradient(90deg, #f2f2f2 25%, #e6e6e6 50%, #f2f2f2 75%);
|
||||
background-size: 200% 100%;
|
||||
animation: loading 1.4s ease-in-out infinite;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes loading {
|
||||
0% {
|
||||
background-position: 200% 0;
|
||||
}
|
||||
|
||||
100% {
|
||||
background-position: -200% 0;
|
||||
}
|
||||
}
|
||||
|
||||
// 页面切换动画优化
|
||||
.ant-layout-content {
|
||||
transition: opacity 0.2s ease-in-out;
|
||||
|
||||
&.loading {
|
||||
opacity: 0.7;
|
||||
}
|
||||
}
|
||||
|
||||
ul,
|
||||
ol {
|
||||
list-style: none;
|
||||
@ -102,17 +56,3 @@ ol {
|
||||
min-height: 100vh;
|
||||
}
|
||||
}
|
||||
|
||||
// 页面过渡优化
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
// 增强页面切换体验
|
||||
.ant-tabs-content-holder {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.ant-tabs-tabpane {
|
||||
outline: none;
|
||||
}
|
||||
@ -1,5 +1,4 @@
|
||||
@import '~antd/es/style/themes/default.less';
|
||||
@import '../components/PageTransition/index.less';
|
||||
|
||||
.ant-pro-global-header {
|
||||
box-shadow: none !important;
|
||||
|
||||
@ -28,9 +28,6 @@ import * as Icon from '@ant-design/icons'
|
||||
import IconFont from '@/components/IconFont';
|
||||
import type { CurrentUser } from '@/models/user'
|
||||
import session from '@/utils/session';
|
||||
import { SimplePageTransition } from '@/components/PageTransition';
|
||||
import TabVirtualizer from '@/components/TabVirtualizer';
|
||||
import { tabPerformanceManager, DEFAULT_CONFIG } from '@/utils/tabPerformanceManager';
|
||||
import upMenu from '../assets/tab/upMenu.png'
|
||||
import { getFieldEnum, getFieldEnumTravel, getFieldEnumTree, getFieldGetFieEnumList, getTravelFieldEnumTree, handleGetFieldEnumTreeTravel, handleGetNestingFIELDENUMList } from "@/services/options";
|
||||
import { handleGetServerpartTree } from '@/pages/basicManage/serverpartAssets/service';
|
||||
@ -95,10 +92,7 @@ const BasicLayout: React.FC<BasicLayoutProps> = (props) => {
|
||||
|
||||
|
||||
const [activeKey, setActiveKey] = useState<string>(location?.pathname || '/')
|
||||
const [animatedPages, setAnimatedPages] = useState<Set<string>>(new Set());
|
||||
const [reloadingTabs, setReloadingTabs] = useState<Set<string>>(new Set());
|
||||
const menuDataRef = useRef<MenuDataItem[]>([]);
|
||||
const checkTimerRef = useRef<NodeJS.Timeout | null>(null);
|
||||
const { formatMessage } = useIntl();
|
||||
|
||||
useEffect(() => {
|
||||
@ -146,57 +140,13 @@ const BasicLayout: React.FC<BasicLayoutProps> = (props) => {
|
||||
// 改变panes
|
||||
const handleTabsPanes = (payload: any): void => {
|
||||
if (dispatch) {
|
||||
// 检查是否为新页面(从未打开过的页面才需要动画)
|
||||
const isNewPage = !tabsPanes.some(tab => tab.path === payload.path);
|
||||
if (isNewPage) {
|
||||
// 标记新页面需要播放动画
|
||||
setAnimatedPages(prev => new Set(prev).add(payload.path));
|
||||
}
|
||||
|
||||
// 更新访问时间
|
||||
const updatedPayload = {
|
||||
...payload,
|
||||
lastAccessTime: Date.now(),
|
||||
isLoaded: true,
|
||||
isLoading: false,
|
||||
};
|
||||
|
||||
dispatch({
|
||||
type: 'global/changeTabsRoutes',
|
||||
payload: { data: updatedPayload, action: 'add' },
|
||||
payload: { data: payload, action: 'add' },
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// 处理标签页重新加载
|
||||
const handleTabReload = (tabPath: string): void => {
|
||||
if (dispatch) {
|
||||
// 标记为加载中
|
||||
setReloadingTabs(prev => new Set(prev).add(tabPath));
|
||||
|
||||
// 重新加载时也要播放动画
|
||||
setAnimatedPages(prev => new Set(prev).add(tabPath));
|
||||
|
||||
dispatch({
|
||||
type: 'global/reloadTab',
|
||||
payload: { tabPath },
|
||||
});
|
||||
|
||||
// 模拟加载过程
|
||||
setTimeout(() => {
|
||||
setReloadingTabs(prev => {
|
||||
const newSet = new Set(prev);
|
||||
newSet.delete(tabPath);
|
||||
return newSet;
|
||||
});
|
||||
|
||||
// 切换到该标签页
|
||||
history.push(tabPath);
|
||||
setActiveKey(tabPath);
|
||||
}, 800); // 800ms的加载时间
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// 关闭当前标签
|
||||
const handleEdit = (targetKey: string | React.MouseEvent<Element, MouseEvent> | React.KeyboardEvent<Element>, action: "add" | "remove"): void => {
|
||||
@ -210,13 +160,6 @@ const BasicLayout: React.FC<BasicLayoutProps> = (props) => {
|
||||
history.push(nextkey || '/')
|
||||
setActiveKey(nextkey)
|
||||
|
||||
// 从动画记录中移除关闭的页面
|
||||
setAnimatedPages(prev => {
|
||||
const newSet = new Set(prev);
|
||||
newSet.delete(targetKey as string);
|
||||
return newSet;
|
||||
});
|
||||
|
||||
// 缓存路由栈数据
|
||||
dispatch({
|
||||
type: 'global/changeTabsRoutes',
|
||||
@ -927,31 +870,6 @@ const BasicLayout: React.FC<BasicLayoutProps> = (props) => {
|
||||
})
|
||||
}
|
||||
|
||||
// 启动标签页性能管理
|
||||
useEffect(() => {
|
||||
// 启动定时检查
|
||||
checkTimerRef.current = setInterval(() => {
|
||||
if (dispatch && tabsPanes.length > 0) {
|
||||
const tabsToUnload = tabPerformanceManager.getTabsToUnload(tabsPanes, activeKey);
|
||||
if (tabsToUnload.length > 0) {
|
||||
// 批量卸载标签页
|
||||
tabsToUnload.forEach(tabPath => {
|
||||
dispatch({
|
||||
type: 'global/unloadTab',
|
||||
payload: { tabPath },
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}, DEFAULT_CONFIG.checkIntervalMinutes * 60 * 1000);
|
||||
|
||||
return () => {
|
||||
if (checkTimerRef.current) {
|
||||
clearInterval(checkTimerRef.current);
|
||||
}
|
||||
};
|
||||
}, [dispatch, tabsPanes, activeKey]);
|
||||
|
||||
// 显示就调用
|
||||
useEffect(() => {
|
||||
handleGetAllFieldEnum()
|
||||
@ -1064,14 +982,6 @@ const BasicLayout: React.FC<BasicLayoutProps> = (props) => {
|
||||
onChange={(value) => {
|
||||
history.push(value)
|
||||
setActiveKey(value)
|
||||
|
||||
// 更新标签页访问时间
|
||||
if (dispatch) {
|
||||
dispatch({
|
||||
type: 'global/updateTabAccessTime',
|
||||
payload: { tabPath: value },
|
||||
});
|
||||
}
|
||||
}}
|
||||
activeKey={activeKey}
|
||||
onEdit={handleEdit}
|
||||
@ -1096,13 +1006,6 @@ const BasicLayout: React.FC<BasicLayoutProps> = (props) => {
|
||||
break;
|
||||
}
|
||||
|
||||
// 从动画记录中移除关闭的页面
|
||||
setAnimatedPages(prev => {
|
||||
const newSet = new Set(prev);
|
||||
closeTabKeys.forEach(key => newSet.delete(key));
|
||||
return newSet;
|
||||
});
|
||||
|
||||
dispatch({
|
||||
type: 'global/changeTabsRoutes',
|
||||
payload: { data: closeTabKeys, action: 'remove' },
|
||||
@ -1132,53 +1035,17 @@ const BasicLayout: React.FC<BasicLayoutProps> = (props) => {
|
||||
}
|
||||
moreIcon={<DoubleRightOutlined style={{ color: "#7b828c" }} />}
|
||||
>
|
||||
{tabsPanes && tabsPanes.map((item: tabsRoute) => {
|
||||
const shouldAnimate = animatedPages.has(item.path);
|
||||
const isActive = activeKey === item.path;
|
||||
const isLoaded = item.isLoaded !== false; // 默认为已加载状态
|
||||
const isLoading = reloadingTabs.has(item.path) || item.isLoading === true;
|
||||
|
||||
return (
|
||||
{tabsPanes && tabsPanes.map((item: tabsRoute) =>
|
||||
<TabPane
|
||||
tab={item.title}
|
||||
key={item?.path}
|
||||
style={{ padding: 24, paddingTop: 0 }}
|
||||
>
|
||||
{/* 如果页面未加载或正在加载,显示TabVirtualizer */}
|
||||
{(!isLoaded || isLoading) ? (
|
||||
<TabVirtualizer
|
||||
tabKey={item.path}
|
||||
isActive={isActive}
|
||||
isLoaded={isLoaded}
|
||||
isLoading={isLoading}
|
||||
lastAccessTime={item.lastAccessTime}
|
||||
onReload={handleTabReload}
|
||||
>
|
||||
{/* 空内容,TabVirtualizer会处理显示 */}
|
||||
</TabVirtualizer>
|
||||
) : (
|
||||
/* 页面已加载,直接显示内容,根据需要播放动画 */
|
||||
<SimplePageTransition
|
||||
enableAnimation={shouldAnimate}
|
||||
onAnimationEnd={() => {
|
||||
// 动画播放完成后,移除动画标记
|
||||
setAnimatedPages(prev => {
|
||||
const newSet = new Set(prev);
|
||||
newSet.delete(item.path);
|
||||
return newSet;
|
||||
});
|
||||
}}
|
||||
>
|
||||
<Suspense fallback={null}>
|
||||
tab={item.title} key={item?.path}
|
||||
style={{ padding: 24, paddingTop: 0 }}>
|
||||
<Suspense fallback={<div>Loading...</div>}>
|
||||
<Authorized authority={authorized!.authority} noMatch={noMatch}>
|
||||
{item.children}
|
||||
</Authorized>
|
||||
</Suspense>
|
||||
</SimplePageTransition>
|
||||
)}
|
||||
</TabPane>
|
||||
);
|
||||
})}
|
||||
</TabPane>)
|
||||
}
|
||||
</Tabs>
|
||||
{/* 不要标签栏,删除tabs的代码,使用下方的代码就可以 */}
|
||||
{/* <Authorized authority={authorized!.authority} noMatch={noMatch}>
|
||||
|
||||
@ -15,101 +15,68 @@ type SecurityLayoutProps = {
|
||||
|
||||
type SecurityLayoutState = {
|
||||
isReady: boolean;
|
||||
shouldShowLoading: boolean;
|
||||
initialLoadComplete: boolean;
|
||||
};
|
||||
|
||||
class SecurityLayout extends React.Component<SecurityLayoutProps, SecurityLayoutState> {
|
||||
state: SecurityLayoutState = {
|
||||
isReady: false,
|
||||
shouldShowLoading: false,
|
||||
initialLoadComplete: false,
|
||||
|
||||
};
|
||||
|
||||
private loadingTimer?: NodeJS.Timeout;
|
||||
|
||||
componentDidMount() {
|
||||
const { location } = history;
|
||||
|
||||
const { location } = history
|
||||
|
||||
const { dispatch } = this.props;
|
||||
|
||||
// 检查是否有缓存的用户信息,避免不必要的加载状态
|
||||
const cachedUser = session.get("currentUser");
|
||||
|
||||
// 设置防闪烁定时器,只有加载时间超过300ms才显示loading
|
||||
this.loadingTimer = setTimeout(() => {
|
||||
if (!this.state.isReady && !this.state.initialLoadComplete) {
|
||||
this.setState({
|
||||
shouldShowLoading: true,
|
||||
});
|
||||
}
|
||||
}, 300);
|
||||
|
||||
if (dispatch) {
|
||||
|
||||
dispatch({
|
||||
type: 'user/fetch',
|
||||
callback: (user) => {
|
||||
// 清除定时器
|
||||
if (this.loadingTimer) {
|
||||
clearTimeout(this.loadingTimer);
|
||||
}
|
||||
type: 'user/fetch', callback: (user) => {
|
||||
|
||||
if (user.code && location.pathname !== '/user/login') {
|
||||
history.push('/user/login');
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
console.log('secur')
|
||||
dispatch({
|
||||
type: 'global/getMenuData',
|
||||
payload: user.ID,
|
||||
callback: (menu) => {
|
||||
type: 'global/getMenuData', payload: user.ID, callback: (menu) => {
|
||||
if (menu) {
|
||||
|
||||
this.setState({
|
||||
isReady: true,
|
||||
shouldShowLoading: false,
|
||||
initialLoadComplete: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
} else {
|
||||
// 清除定时器
|
||||
if (this.loadingTimer) {
|
||||
clearTimeout(this.loadingTimer);
|
||||
}
|
||||
|
||||
this.setState({
|
||||
isReady: true,
|
||||
shouldShowLoading: false,
|
||||
initialLoadComplete: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
if (this.loadingTimer) {
|
||||
clearTimeout(this.loadingTimer);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const { isReady, shouldShowLoading, initialLoadComplete } = this.state;
|
||||
const { children, currentUser } = this.props;
|
||||
const { isReady } = this.state;
|
||||
const { children, loading, currentUser } = this.props;
|
||||
// const { location } = history;
|
||||
|
||||
// 用户认证规则
|
||||
|
||||
// You can replace it to your authentication rule (such as check token exists)
|
||||
// You can replace it with your own login authentication rules (such as judging whether the token exists)
|
||||
const isLogin = currentUser && currentUser.ID;
|
||||
|
||||
// 如果初始化未完成且需要显示加载状态,才显示骨架屏
|
||||
if (!isReady && shouldShowLoading) {
|
||||
|
||||
if ((!isLogin && loading) || !isReady) {
|
||||
return <PageLoading />;
|
||||
}
|
||||
|
||||
// 如果还在初始化过程中,但不需要显示loading,返回null(避免闪烁)
|
||||
if (!isReady && !shouldShowLoading) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// if (!isLogin && location.pathname !== '/user/login') {
|
||||
// history.push('/user/login');
|
||||
// }
|
||||
return children;
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,9 +20,6 @@ export type tabsRoute = {
|
||||
path: string;
|
||||
key: string;
|
||||
children: any;
|
||||
lastAccessTime?: number; // 最后访问时间
|
||||
isLoaded?: boolean; // 是否已加载
|
||||
isLoading?: boolean; // 是否正在加载
|
||||
}
|
||||
|
||||
export type GlobalModelState = {
|
||||
@ -42,9 +39,6 @@ export type GlobalModelType = {
|
||||
changeNoticeReadState: Effect;
|
||||
changeTabsRoutes: Effect;
|
||||
getMenuData: Effect;
|
||||
updateTabAccessTime: Effect;
|
||||
unloadTab: Effect;
|
||||
reloadTab: Effect;
|
||||
};
|
||||
reducers: {
|
||||
changeLayoutCollapsed: Reducer<GlobalModelState>;
|
||||
@ -185,26 +179,10 @@ const GlobalModel: GlobalModelType = {
|
||||
const index = state.global.tabsRoutes.findIndex(n => n.path === data.path)
|
||||
|
||||
if (index === -1) { // 没缓存 则添加
|
||||
return [...state.global.tabsRoutes, {
|
||||
...data,
|
||||
index: state.global.tabsRoutes.length,
|
||||
lastAccessTime: data.lastAccessTime || Date.now(),
|
||||
isLoaded: data.isLoaded !== false,
|
||||
isLoading: data.isLoading || false,
|
||||
}]
|
||||
return [...state.global.tabsRoutes, { ...data, index: state.global.tabsRoutes.length }]
|
||||
}
|
||||
// 否则更新现有标签页信息
|
||||
return state.global.tabsRoutes.map(tab =>
|
||||
tab.path === data.path
|
||||
? {
|
||||
...tab,
|
||||
...data,
|
||||
lastAccessTime: data.lastAccessTime || Date.now(),
|
||||
isLoaded: data.isLoaded !== false,
|
||||
isLoading: data.isLoading || false,
|
||||
}
|
||||
: tab
|
||||
);
|
||||
// 否则不操作
|
||||
return [...state.global.tabsRoutes]
|
||||
}
|
||||
if (payload.action === 'removeAll') {
|
||||
return []
|
||||
@ -221,57 +199,8 @@ const GlobalModel: GlobalModelType = {
|
||||
type: 'saveTabsRoutes',
|
||||
payload: tabsRoutes,
|
||||
});
|
||||
},
|
||||
|
||||
// 更新标签页访问时间
|
||||
* updateTabAccessTime({ payload }, { put, select }) {
|
||||
const { tabPath } = payload;
|
||||
const tabsRoutes: tabsRoute[] = yield select((state: ConnectState) =>
|
||||
state.global.tabsRoutes.map(tab =>
|
||||
tab.path === tabPath
|
||||
? { ...tab, lastAccessTime: Date.now(), isLoaded: true, isLoading: false }
|
||||
: tab
|
||||
)
|
||||
);
|
||||
|
||||
yield put({
|
||||
type: 'saveTabsRoutes',
|
||||
payload: tabsRoutes,
|
||||
});
|
||||
},
|
||||
|
||||
// 卸载标签页
|
||||
* unloadTab({ payload }, { put, select }) {
|
||||
const { tabPath } = payload;
|
||||
const tabsRoutes: tabsRoute[] = yield select((state: ConnectState) =>
|
||||
state.global.tabsRoutes.map(tab =>
|
||||
tab.path === tabPath
|
||||
? { ...tab, isLoaded: false, isLoading: false }
|
||||
: tab
|
||||
)
|
||||
);
|
||||
|
||||
yield put({
|
||||
type: 'saveTabsRoutes',
|
||||
payload: tabsRoutes,
|
||||
});
|
||||
},
|
||||
|
||||
// 重新加载标签页
|
||||
* reloadTab({ payload }, { put, select }) {
|
||||
const { tabPath } = payload;
|
||||
const tabsRoutes: tabsRoute[] = yield select((state: ConnectState) =>
|
||||
state.global.tabsRoutes.map(tab =>
|
||||
tab.path === tabPath
|
||||
? { ...tab, isLoaded: true, isLoading: false, lastAccessTime: Date.now() }
|
||||
: tab
|
||||
)
|
||||
);
|
||||
|
||||
yield put({
|
||||
type: 'saveTabsRoutes',
|
||||
payload: tabsRoutes,
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user