1
This commit is contained in:
parent
f03bcbdc80
commit
6b34ae7f72
66
frontend/src/components/ui/layout.tsx
Normal file
66
frontend/src/components/ui/layout.tsx
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
import * as React from "react";
|
||||||
|
import { cn } from "@/lib/utils";
|
||||||
|
|
||||||
|
const Layout = React.forwardRef<
|
||||||
|
HTMLDivElement,
|
||||||
|
React.HTMLAttributes<HTMLDivElement>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<div
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"flex h-screen overflow-hidden",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
));
|
||||||
|
Layout.displayName = "Layout";
|
||||||
|
|
||||||
|
const LayoutContent = React.forwardRef<
|
||||||
|
HTMLDivElement,
|
||||||
|
React.HTMLAttributes<HTMLDivElement>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<div
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"flex flex-1 flex-col overflow-hidden",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
));
|
||||||
|
LayoutContent.displayName = "LayoutContent";
|
||||||
|
|
||||||
|
const Header = React.forwardRef<
|
||||||
|
HTMLDivElement,
|
||||||
|
React.HTMLAttributes<HTMLDivElement>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<div
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"flex h-16 items-center border-b bg-background px-6",
|
||||||
|
"z-40",
|
||||||
|
"shadow-sm",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
));
|
||||||
|
Header.displayName = "Header";
|
||||||
|
|
||||||
|
const Main = React.forwardRef<
|
||||||
|
HTMLDivElement,
|
||||||
|
React.HTMLAttributes<HTMLDivElement>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<div
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"flex-1 overflow-auto p-6",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
));
|
||||||
|
Main.displayName = "Main";
|
||||||
|
|
||||||
|
export { Layout, LayoutContent, Header, Main };
|
||||||
@ -1,5 +1,5 @@
|
|||||||
import React, {useEffect, useState, useCallback} from 'react';
|
import React, {useEffect, useState, useCallback} from 'react';
|
||||||
import {Layout, Dropdown, Modal, message, Spin, Space, Tooltip} from 'antd';
|
import {Dropdown, Modal, message, Spin, Space, Tooltip} from 'antd';
|
||||||
import {useNavigate, useLocation, Outlet} from 'react-router-dom';
|
import {useNavigate, useLocation, Outlet} from 'react-router-dom';
|
||||||
import {useDispatch, useSelector} from 'react-redux';
|
import {useDispatch, useSelector} from 'react-redux';
|
||||||
import {
|
import {
|
||||||
@ -17,8 +17,8 @@ import type {RootState} from '../store';
|
|||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import 'dayjs/locale/zh-cn';
|
import 'dayjs/locale/zh-cn';
|
||||||
import { AppMenu } from '@/components/AppMenu';
|
import { AppMenu } from '@/components/AppMenu';
|
||||||
|
import { Layout, LayoutContent, Header, Main } from '@/components/ui/layout';
|
||||||
|
|
||||||
const {Header, Content} = Layout;
|
|
||||||
const {confirm} = Modal;
|
const {confirm} = Modal;
|
||||||
|
|
||||||
// 设置中文语言
|
// 设置中文语言
|
||||||
@ -153,91 +153,46 @@ const BasicLayout: React.FC = () => {
|
|||||||
|
|
||||||
if (loading) {
|
if (loading) {
|
||||||
return (
|
return (
|
||||||
<div style={{
|
<div className="flex h-screen w-screen flex-col items-center justify-center bg-slate-50">
|
||||||
height: '100vh',
|
|
||||||
width: '100vw',
|
|
||||||
display: 'flex',
|
|
||||||
flexDirection: 'column',
|
|
||||||
justifyContent: 'center',
|
|
||||||
alignItems: 'center',
|
|
||||||
background: '#f0f2f5'
|
|
||||||
}}>
|
|
||||||
<Spin size="large"/>
|
<Spin size="large"/>
|
||||||
<div style={{
|
<div className="mt-6 text-center text-slate-500">
|
||||||
marginTop: 24,
|
<p className="text-base">正在为您准备系统资源</p>
|
||||||
fontSize: 16,
|
<p className="text-sm">请稍候,马上就好...</p>
|
||||||
color: 'rgba(0, 0, 0, 0.45)',
|
|
||||||
textAlign: 'center'
|
|
||||||
}}>
|
|
||||||
<p>正在为您准备系统资源</p>
|
|
||||||
<p style={{fontSize: 14}}>请稍候,马上就好...</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Layout style={{
|
<Layout>
|
||||||
height: '100vh',
|
|
||||||
display: 'flex',
|
|
||||||
flexDirection: 'row',
|
|
||||||
overflow: 'hidden'
|
|
||||||
}}>
|
|
||||||
<AppMenu openKeys={openKeys} onOpenChange={handleOpenChange} />
|
<AppMenu openKeys={openKeys} onOpenChange={handleOpenChange} />
|
||||||
<Layout style={{flex: 1, overflow: 'hidden', display: 'flex', flexDirection: 'column'}}>
|
<LayoutContent>
|
||||||
<Header style={{
|
<Header className="justify-end">
|
||||||
padding: '0 24px',
|
|
||||||
background: '#fff',
|
|
||||||
display: 'flex',
|
|
||||||
justifyContent: 'flex-end',
|
|
||||||
alignItems: 'center',
|
|
||||||
boxShadow: '0 1px 4px rgba(0,21,41,.08)',
|
|
||||||
height: 64,
|
|
||||||
flexShrink: 0
|
|
||||||
}}>
|
|
||||||
<Space size={24}>
|
<Space size={24}>
|
||||||
<Space size={16}>
|
<Space size={16}>
|
||||||
<span style={{
|
<span className="inline-flex items-center text-sm text-slate-600">
|
||||||
display: 'inline-flex',
|
<ClockCircleOutlined className="mr-2" />
|
||||||
alignItems: 'center',
|
|
||||||
color: 'rgba(0, 0, 0, 0.65)',
|
|
||||||
fontSize: 14
|
|
||||||
}}>
|
|
||||||
<ClockCircleOutlined style={{marginRight: 8}}/>
|
|
||||||
{currentTime.format('YYYY年MM月DD日 HH:mm:ss')} 星期{currentTime.format('dd')}
|
{currentTime.format('YYYY年MM月DD日 HH:mm:ss')} 星期{currentTime.format('dd')}
|
||||||
</span>
|
</span>
|
||||||
<Tooltip title={`${weather.city}`}>
|
<Tooltip title={`${weather.city}`}>
|
||||||
<span style={{
|
<span className="inline-flex items-center text-sm text-slate-600">
|
||||||
display: 'inline-flex',
|
<CloudOutlined className="mr-2" />
|
||||||
alignItems: 'center',
|
|
||||||
color: 'rgba(0, 0, 0, 0.65)',
|
|
||||||
fontSize: 14
|
|
||||||
}}>
|
|
||||||
<CloudOutlined style={{marginRight: 8}}/>
|
|
||||||
{weather.weather} {weather.temp}℃
|
{weather.weather} {weather.temp}℃
|
||||||
</span>
|
</span>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</Space>
|
</Space>
|
||||||
<Dropdown menu={{items: userMenuItems}} trigger={['hover']}>
|
<Dropdown menu={{items: userMenuItems}} trigger={['hover']}>
|
||||||
<Space style={{cursor: 'pointer'}}>
|
<Space className="cursor-pointer">
|
||||||
<UserOutlined/>
|
<UserOutlined/>
|
||||||
<span>{userInfo?.nickname || userInfo?.username}</span>
|
<span>{userInfo?.nickname || userInfo?.username}</span>
|
||||||
</Space>
|
</Space>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
</Space>
|
</Space>
|
||||||
</Header>
|
</Header>
|
||||||
<Content style={{
|
<Main className="bg-white">
|
||||||
margin: '24px 16px',
|
|
||||||
padding: 24,
|
|
||||||
background: '#fff',
|
|
||||||
flex: 1,
|
|
||||||
overflow: 'auto',
|
|
||||||
display: 'flex',
|
|
||||||
flexDirection: 'column'
|
|
||||||
}}>
|
|
||||||
<Outlet/>
|
<Outlet/>
|
||||||
</Content>
|
</Main>
|
||||||
</Layout>
|
</LayoutContent>
|
||||||
</Layout>
|
</Layout>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user