页面加载的平滑效果添加

This commit is contained in:
ylj20011123 2025-09-08 10:22:36 +08:00
parent 1f62f3878b
commit 09478a1b58
5 changed files with 211 additions and 44 deletions

View File

@ -0,0 +1,58 @@
// 简化版页面过渡动画
.simple-page-transition {
animation: pageEnter 0.5s cubic-bezier(0.4, 0, 0.2, 1);
will-change: opacity, transform;
}
@keyframes pageEnter {
from {
opacity: 0;
transform: translateY(30px) scale(0.96);
filter: blur(4px);
}
to {
opacity: 1;
transform: translateY(0) scale(1);
filter: blur(0);
}
}
// 复杂版页面过渡动画
.page-transition {
position: relative;
height: 100%;
.transition-content {
height: 100%;
&.fadeIn {
animation: fadeIn 0.3s ease-in-out forwards;
}
&.fadeOut {
animation: fadeOut 0.3s ease-in-out forwards;
}
}
}
@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes fadeOut {
from {
opacity: 1;
transform: translateY(0);
}
to {
opacity: 0;
transform: translateY(-10px);
}
}

View File

@ -0,0 +1,56 @@
import React, { useEffect, useState } from 'react';
import { CSSTransition, TransitionGroup } from 'react-transition-group';
import { useLocation } from 'umi';
import './index.less';
export interface PageTransitionProps {
children: React.ReactNode;
type?: 'fade' | 'slide' | 'scale';
duration?: number;
className?: string;
}
const PageTransition: React.FC<PageTransitionProps> = ({
children,
type = 'fade',
duration = 300,
className = '',
}) => {
const location = useLocation();
const [displayLocation, setDisplayLocation] = useState(location);
const [transitionStage, setTransitionStage] = useState('fadeIn');
useEffect(() => {
if (location !== displayLocation) setTransitionStage('fadeOut');
}, [location, displayLocation]);
return (
<div className={`page-transition ${type}-transition ${className}`}>
<div
className={`transition-content ${transitionStage}`}
onAnimationEnd={() => {
if (transitionStage === 'fadeOut') {
setDisplayLocation(location);
setTransitionStage('fadeIn');
}
}}
>
{children}
</div>
</div>
);
};
// 简化版本 - 仅使用CSS动画
export const SimplePageTransition: React.FC<{ children: React.ReactNode; className?: string }> = ({
children,
className = '',
}) => {
return (
<div className={`simple-page-transition ${className}`}>
{children}
</div>
);
};
export default PageTransition;

View File

@ -33,12 +33,15 @@ ol {
.ant-table { .ant-table {
width: 100%; width: 100%;
overflow-x: auto; overflow-x: auto;
&-thead > tr,
&-tbody > tr { &-thead>tr,
> th, &-tbody>tr {
> td {
>th,
>td {
white-space: pre; white-space: pre;
> span {
>span {
display: block; display: block;
} }
} }
@ -47,8 +50,23 @@ ol {
} }
// Compatible with IE11 // Compatible with IE11
@media screen and(-ms-high-contrast: active), (-ms-high-contrast: none) { @media screen and(-ms-high-contrast: active),
body .ant-design-pro > .ant-layout { (-ms-high-contrast: none) {
body .ant-design-pro>.ant-layout {
min-height: 100vh; min-height: 100vh;
} }
} }
// 页面过渡优化
* {
box-sizing: border-box;
}
// 增强页面切换体验
.ant-tabs-content-holder {
overflow: hidden;
}
.ant-tabs-tabpane {
outline: none;
}

View File

@ -1,45 +1,56 @@
@import '~antd/es/style/themes/default.less'; @import '~antd/es/style/themes/default.less';
@import '../components/PageTransition/index.less';
.ant-pro-global-header { .ant-pro-global-header {
box-shadow: none !important; box-shadow: none !important;
} }
.ant-pro-basicLayout-content { .ant-pro-basicLayout-content {
margin: 0 !important; margin: 0 !important;
} }
.ant-menu-inline-collapsed .ant-pro-menu-item .ant-pro-menu-item-title {
.ant-menu-inline-collapsed .ant-pro-menu-item .ant-pro-menu-item-title {
opacity: 0; opacity: 0;
} }
.ant-pro-sider-logo img { .ant-pro-sider-logo img {
height: 21px !important; height: 21px !important;
} }
.main-tab >.ant-tabs-nav {
.main-tab>.ant-tabs-nav {
margin-bottom: 0 !important; margin-bottom: 0 !important;
padding: 2px 15px 0 16px; padding: 2px 15px 0 16px;
background-color: #fff; background-color: #fff;
} }
.main-tab > .ant-tabs-nav .ant-tabs-tab {
.main-tab>.ant-tabs-nav .ant-tabs-tab {
background-color: #fafafa; background-color: #fafafa;
border-color: #f0f0f0; border-color: #f0f0f0;
border-bottom: 0; border-bottom: 0;
} }
.main-tab > .ant-tabs-nav .ant-tabs-tab button svg {
.main-tab>.ant-tabs-nav .ant-tabs-tab button svg {
// color: #fff; // color: #fff;
transition: all 0.3s; transition: all 0.3s;
} }
.main-tab > .ant-tabs-nav .ant-tabs-tab:hover {
background-color:#fafafa; .main-tab>.ant-tabs-nav .ant-tabs-tab:hover {
background-color: #fafafa;
border-color: #f0f0f0; border-color: #f0f0f0;
} }
.main-tab > .ant-tabs-nav .ant-tabs-tab:hover button svg {
.main-tab>.ant-tabs-nav .ant-tabs-tab:hover button svg {
color: @link-color; color: @link-color;
} }
.main-tab.ant-tabs-top > .ant-tabs-nav .ant-tabs-tab-active {
.main-tab.ant-tabs-top>.ant-tabs-nav .ant-tabs-tab-active {
background-color: #f6f9fb; background-color: #f6f9fb;
border-color: #f0f0f0; border-color: #f0f0f0;
box-shadow: 2px 0 6px 0 #e7e7e7; box-shadow: 2px 0 6px 0 #e7e7e7;
border-top-color: #3591fe; border-top-color: #3591fe;
} }
.main-tab.ant-tabs-top > .ant-tabs-nav .ant-tabs-tab-active::before {
.main-tab.ant-tabs-top>.ant-tabs-nav .ant-tabs-tab-active::before {
content: ''; content: '';
position: absolute; position: absolute;
display: block; display: block;
@ -49,17 +60,21 @@
width: 100%; width: 100%;
height: 1px; height: 1px;
} }
.main-tab > .ant-tabs-nav .ant-tabs-tab-active button svg {
.main-tab>.ant-tabs-nav .ant-tabs-tab-active button svg {
color: @icon-color; color: @icon-color;
} }
.main-tab > .ant-tabs-content-holder {
.main-tab>.ant-tabs-content-holder {
height: calc(100vh - 86px); height: calc(100vh - 86px);
padding-top: 16px; padding-top: 16px;
overflow-y: auto; overflow-y: auto;
} }
.main-tab > .ant-tabs-nav .ant-tabs-nav-wrap {
.main-tab>.ant-tabs-nav .ant-tabs-nav-wrap {
bottom: 1px; bottom: 1px;
} }
.tab-extra { .tab-extra {
width: 13px; width: 13px;
height: 15px; height: 15px;
@ -68,10 +83,12 @@
// background-repeat: no-repeat; // background-repeat: no-repeat;
} }
.ant-dropdown-open svg { .ant-dropdown-open svg {
color: @primary-color; color: @primary-color;
// background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA0AAAAPCAYAAAA/I0V3AAAAAXNSR0IArs4c6QAAAMZJREFUOE+9kb0KwkAQhGdUEBtfxpxtWisLS7GxE4Too3gH1hZKSgsrW1vj09iIkGQkghJ/kLPJlrs7u8M3NDYX/ixWKHIKlaX0dch6Q97L5aM0i2wN1hq+n6A8rRBEYPOMQM3XnoCcHasJoaWPsBAInN7pmYVGoFYAfgFJIY6TOTdP5MZpICkm0Hy3KuBKcphE3Bazl5yMVQ9QMWiVhBeAg2TG/aP3Ea5xCiHtALQBnEH2k4iHl3C/UQucupBikMNTxOP7zg3x4U00HiX/gwAAAABJRU5ErkJggg=='); // background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA0AAAAPCAYAAAA/I0V3AAAAAXNSR0IArs4c6QAAAMZJREFUOE+9kb0KwkAQhGdUEBtfxpxtWisLS7GxE4Too3gH1hZKSgsrW1vj09iIkGQkghJ/kLPJlrs7u8M3NDYX/ixWKHIKlaX0dch6Q97L5aM0i2wN1hq+n6A8rRBEYPOMQM3XnoCcHasJoaWPsBAInN7pmYVGoFYAfgFJIY6TOTdP5MZpICkm0Hy3KuBKcphE3Bazl5yMVQ9QMWiVhBeAg2TG/aP3Ea5xCiHtALQBnEH2k4iHl3C/UQucupBikMNTxOP7zg3x4U00HiX/gwAAAABJRU5ErkJggg==');
} }
.tab-extra:hover { .tab-extra:hover {
// background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA0AAAAPCAYAAAA/I0V3AAAAAXNSR0IArs4c6QAAAMZJREFUOE+9kb0KwkAQhGdUEBtfxpxtWisLS7GxE4Too3gH1hZKSgsrW1vj09iIkGQkghJ/kLPJlrs7u8M3NDYX/ixWKHIKlaX0dch6Q97L5aM0i2wN1hq+n6A8rRBEYPOMQM3XnoCcHasJoaWPsBAInN7pmYVGoFYAfgFJIY6TOTdP5MZpICkm0Hy3KuBKcphE3Bazl5yMVQ9QMWiVhBeAg2TG/aP3Ea5xCiHtALQBnEH2k4iHl3C/UQucupBikMNTxOP7zg3x4U00HiX/gwAAAABJRU5ErkJggg=='); // background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA0AAAAPCAYAAAA/I0V3AAAAAXNSR0IArs4c6QAAAMZJREFUOE+9kb0KwkAQhGdUEBtfxpxtWisLS7GxE4Too3gH1hZKSgsrW1vj09iIkGQkghJ/kLPJlrs7u8M3NDYX/ixWKHIKlaX0dch6Q97L5aM0i2wN1hq+n6A8rRBEYPOMQM3XnoCcHasJoaWPsBAInN7pmYVGoFYAfgFJIY6TOTdP5MZpICkm0Hy3KuBKcphE3Bazl5yMVQ9QMWiVhBeAg2TG/aP3Ea5xCiHtALQBnEH2k4iHl3C/UQucupBikMNTxOP7zg3x4U00HiX/gwAAAABJRU5ErkJggg==');
} }
@ -83,9 +100,11 @@
body *::-webkit-scrollbar { body *::-webkit-scrollbar {
/* 滚动条整体样式 */ /* 滚动条整体样式 */
width : 8px; /* 高宽分别对应横竖滚动条的尺寸 */ width: 8px;
/* 高宽分别对应横竖滚动条的尺寸 */
height: 8px; height: 8px;
} }
body *::-webkit-scrollbar-thumb { body *::-webkit-scrollbar-thumb {
/* 滚动条里面小方块 */ /* 滚动条里面小方块 */
background-color: #d1cfcf; background-color: #d1cfcf;
@ -101,6 +120,7 @@ body *::-webkit-scrollbar-thumb {
// ); // );
border-radius: 10px; border-radius: 10px;
} }
body *::-webkit-scrollbar-track { body *::-webkit-scrollbar-track {
/* 滚动条里面轨道 */ /* 滚动条里面轨道 */
background: #ededed; background: #ededed;
@ -109,59 +129,71 @@ body *::-webkit-scrollbar-track {
} }
// 列表页左侧多选树 // 列表页左侧多选树
.pageTable-leftnav .ant-tree-list-holder{ .pageTable-leftnav .ant-tree-list-holder {
height: calc(100vh - 257px); height: calc(100vh - 257px);
padding-right: 0; padding-right: 0;
padding-bottom: 0; padding-bottom: 0;
overflow-y: auto; overflow-y: auto;
} }
.leftHeight .ant-tree-list-holder{
height: 100%!important; .leftHeight .ant-tree-list-holder {
height: 100% !important;
} }
.leftHeight .ant-tree-list{
height: 560px .leftHeight .ant-tree-list {
height: 560px
} }
.pageTable-leftnavs .ant-tree-list-holder{
height: 580px; .pageTable-leftnavs .ant-tree-list-holder {
padding-right: 0; height: 580px;
padding-bottom: 0; padding-right: 0;
overflow-y: auto; padding-bottom: 0;
overflow-y: auto;
} }
.pageTable-leftnav .ant-pro-card-header.ant-pro-card-header-border { .pageTable-leftnav .ant-pro-card-header.ant-pro-card-header-border {
padding-top: 29px; padding-top: 29px;
} }
.pageTable-leftnav .ant-pro-card-title { .pageTable-leftnav .ant-pro-card-title {
font-size: 14px; font-size: 14px;
} }
.pageTable-leftnav .ant-pro-card-split-vertical{ .pageTable-leftnav .ant-pro-card-split-vertical {
transition: width 0.3s; transition: width 0.3s;
} }
.pageTable-leftnav .ant-tree .ant-tree-treenode { .pageTable-leftnav .ant-tree .ant-tree-treenode {
padding-bottom: 16px; padding-bottom: 16px;
} }
.pageTable-leftnavs .ant-tree .ant-tree-treenode { .pageTable-leftnavs .ant-tree .ant-tree-treenode {
padding-bottom: 16px; padding-bottom: 16px;
} }
.ant-table-tbody > tr.tablerow-no-border > td{
.ant-table-tbody>tr.tablerow-no-border>td {
border-bottom: 0; border-bottom: 0;
} }
// prolist 卡片类型 // prolist 卡片类型
.ant-pro-list .ant-pro-card-header { .ant-pro-list .ant-pro-card-header {
padding: 0 !important; padding: 0 !important;
} }
.ant-pro-list .ant-pro-card.ant-pro-card-border.ant-pro-card-hoverable>.ant-pro-card-body {
.ant-pro-list .ant-pro-card.ant-pro-card-border.ant-pro-card-hoverable>.ant-pro-card-body {
margin: 0 !important; margin: 0 !important;
padding: 20px 0 0 0 !important; padding: 20px 0 0 0 !important;
} }
.ant-pro-list .ant-pro-card.ant-pro-card-border> ul.ant-pro-card-actions { .ant-pro-list .ant-pro-card.ant-pro-card-border>ul.ant-pro-card-actions {
margin-top: 20px; margin-top: 20px;
} }
.ant-pro-list .ant-pro-card.ant-pro-card-border> ul.ant-pro-card-actions >li{ .ant-pro-list .ant-pro-card.ant-pro-card-border>ul.ant-pro-card-actions>li {
margin:0; margin: 0;
} }
.ant-pro-list .ant-pro-card.ant-pro-card-border.ant-pro-card-hoverable> ul.ant-pro-card-actions > li, .ant-pro-list .ant-pro-card .ant-pro-card-actions .ant-space-item {
.ant-pro-list .ant-pro-card.ant-pro-card-border.ant-pro-card-hoverable>ul.ant-pro-card-actions>li,
.ant-pro-list .ant-pro-card .ant-pro-card-actions .ant-space-item {
margin: 10px 0 0 0 !important; margin: 10px 0 0 0 !important;
} }

View File

@ -28,6 +28,7 @@ import * as Icon from '@ant-design/icons'
import IconFont from '@/components/IconFont'; import IconFont from '@/components/IconFont';
import type { CurrentUser } from '@/models/user' import type { CurrentUser } from '@/models/user'
import session from '@/utils/session'; import session from '@/utils/session';
import { SimplePageTransition } from '@/components/PageTransition';
import upMenu from '../assets/tab/upMenu.png' import upMenu from '../assets/tab/upMenu.png'
import { getFieldEnum, getFieldEnumTravel, getFieldEnumTree, getFieldGetFieEnumList, getTravelFieldEnumTree, handleGetFieldEnumTreeTravel, handleGetNestingFIELDENUMList } from "@/services/options"; import { getFieldEnum, getFieldEnumTravel, getFieldEnumTree, getFieldGetFieEnumList, getTravelFieldEnumTree, handleGetFieldEnumTreeTravel, handleGetNestingFIELDENUMList } from "@/services/options";
import { handleGetServerpartTree } from '@/pages/basicManage/serverpartAssets/service'; import { handleGetServerpartTree } from '@/pages/basicManage/serverpartAssets/service';
@ -1039,11 +1040,13 @@ const BasicLayout: React.FC<BasicLayoutProps> = (props) => {
<TabPane <TabPane
tab={item.title} key={item?.path} tab={item.title} key={item?.path}
style={{ padding: 24, paddingTop: 0 }}> style={{ padding: 24, paddingTop: 0 }}>
<Suspense fallback={<div>Loading...</div>}> <SimplePageTransition>
<Authorized authority={authorized!.authority} noMatch={noMatch}> <Suspense fallback={<div>Loading...</div>}>
{item.children} <Authorized authority={authorized!.authority} noMatch={noMatch}>
</Authorized> {item.children}
</Suspense> </Authorized>
</Suspense>
</SimplePageTransition>
</TabPane>) </TabPane>)
} }
</Tabs> </Tabs>