完成顶栏,导航菜单分权展示
parent
62155de02d
commit
4cb396ee81
|
@ -2,6 +2,7 @@
|
|||
export interface Token {
|
||||
accessToken: string;
|
||||
refreshToken: string;
|
||||
clientSecret: string;
|
||||
}
|
||||
|
||||
export interface Staff {
|
||||
|
|
|
@ -8,12 +8,13 @@ const tokenSlice = createSlice({
|
|||
initialState: {
|
||||
accessToken: '',
|
||||
refreshToken: '',
|
||||
clientSecret: ''
|
||||
},
|
||||
reducers: {
|
||||
setToken: (state, action: PayloadAction<Token>) => {
|
||||
state.accessToken = action.payload.accessToken
|
||||
state.refreshToken = action.payload.refreshToken
|
||||
console.log('action: '+action)
|
||||
state.clientSecret = action.payload.clientSecret
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
@ -1,15 +1,94 @@
|
|||
import React, {FC, useEffect} from 'react';
|
||||
import React, {useState, useEffect} from 'react';
|
||||
import {UploadOutlined, UserOutlined, VideoCameraOutlined} from '@ant-design/icons';
|
||||
import {Layout, Menu, theme, Typography } from 'antd';
|
||||
import {useAppSelector} from "../models/hooks";
|
||||
import {getToken, store} from "../models/store";
|
||||
import {Layout, Menu, theme, Typography, Button, Dropdown, MenuProps} from 'antd';
|
||||
import {useAppDispatch, useAppSelector} from "../models/hooks";
|
||||
import {getToken, setToken, store} from "../models/store";
|
||||
import {Link, Outlet, useNavigate} from "react-router-dom";
|
||||
import Icon from '@ant-design/icons';
|
||||
import {Logo} from "../assets/icons";
|
||||
import axiosInstance from "../utils/axiosInstance";
|
||||
import {Department, Staff} from "../models/Staff";
|
||||
|
||||
const { Title } = Typography;
|
||||
const {Title} = Typography;
|
||||
const {Header, Content, Footer, Sider} = Layout;
|
||||
|
||||
|
||||
|
||||
function HeaderBar(props: any) {
|
||||
const {
|
||||
token: {colorBgContainer, colorPrimary},
|
||||
} = theme.useToken();
|
||||
|
||||
const dispatch = useAppDispatch()
|
||||
const navigate = useNavigate()
|
||||
|
||||
|
||||
const onClick: MenuProps['onClick'] = ({key}) => {
|
||||
switch (key) {
|
||||
case 'password':
|
||||
break
|
||||
case 'logout':
|
||||
dispatch(setToken({
|
||||
accessToken: '',
|
||||
refreshToken: '',
|
||||
clientSecret: ''
|
||||
}))
|
||||
navigate("/login")
|
||||
break
|
||||
}
|
||||
};
|
||||
const items: MenuProps['items'] = [
|
||||
{
|
||||
key: 'password',
|
||||
label: (
|
||||
<span>修改密码</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
key: 'logout',
|
||||
label: (
|
||||
<span>退出登录</span>
|
||||
),
|
||||
}
|
||||
];
|
||||
|
||||
const departmentToString = (staff:Staff) => {
|
||||
let result = staff.managingDepartment===null?'':staff.managingDepartment.departmentName+'主管'
|
||||
for(const department of staff.staffDepartments)
|
||||
{
|
||||
result+=' '+department.departmentName
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
return (
|
||||
<Header style={{
|
||||
height: '48px',
|
||||
padding: 0,
|
||||
background: colorBgContainer,
|
||||
display: 'flex',
|
||||
flexDirection: 'row-reverse',
|
||||
alignItems: 'center'
|
||||
}}>
|
||||
<Dropdown menu={{items, onClick}} placement="bottomRight" arrow>
|
||||
<Button type="text" style={{
|
||||
marginRight: '12px', height: '100%',
|
||||
display: 'flex', justifyContent: 'center', alignItems: 'center'
|
||||
}}>
|
||||
<span style={{marginRight: '12px'}}>{departmentToString(props.staff)}</span>
|
||||
<span style={{fontWeight: "bold", marginRight: '12px'}}>{props.staff.staffName}</span>
|
||||
<div style={{
|
||||
width: '24px', height: '24px', backgroundColor: colorPrimary, borderRadius: '12px',
|
||||
display: 'flex', justifyContent: 'center', alignItems: 'center'
|
||||
}}>
|
||||
<span style={{color: 'white'}}>{props.staff.staffName[0]}</span>
|
||||
</div>
|
||||
</Button>
|
||||
</Dropdown>
|
||||
</Header>
|
||||
)
|
||||
}
|
||||
|
||||
function HomeView() {
|
||||
const token = useAppSelector(getToken);
|
||||
const navigate = useNavigate();
|
||||
|
@ -23,35 +102,122 @@ function HomeView() {
|
|||
key: "/reimbursement/mine",
|
||||
//icon: React.createElement(UserOutlined),
|
||||
label: <Link to="/reimbursement/mine">我的报销</Link>,
|
||||
},{
|
||||
}, {
|
||||
key: "/invoice/management",
|
||||
//icon: React.createElement(UserOutlined),
|
||||
label: <Link to="/reimbursement/mine">发票管理</Link>,
|
||||
},{
|
||||
}, {
|
||||
key: "/reimbursement/management",
|
||||
//icon: React.createElement(UserOutlined),
|
||||
label: <Link to="/reimbursement/mine">报销审批</Link>,
|
||||
},{
|
||||
}, {
|
||||
key: "/stat",
|
||||
//icon: React.createElement(UserOutlined),
|
||||
label: <Link to="/reimbursement/mine">财务统计</Link>,
|
||||
}]
|
||||
|
||||
const {
|
||||
token: { colorBgContainer, colorPrimary },
|
||||
token: {colorBgContainer, colorPrimary},
|
||||
} = theme.useToken();
|
||||
|
||||
|
||||
const [staff, setStaff] = useState({
|
||||
staffName: "王司徒",
|
||||
managingDepartment: {
|
||||
departmentId: 3,
|
||||
departmentName: "投影立体角部"
|
||||
},
|
||||
staffDepartments: []
|
||||
})
|
||||
|
||||
const [menuItems, setMenuItems] = useState(
|
||||
[{
|
||||
key: "/invoice/mine",
|
||||
//icon: React.createElement(UserOutlined),
|
||||
label: <Link to="/invoice/mine">我的发票</Link>
|
||||
}, {
|
||||
key: "/reimbursement/mine",
|
||||
//icon: React.createElement(UserOutlined),
|
||||
label: <Link to="/reimbursement/mine">我的报销</Link>,
|
||||
}]
|
||||
)
|
||||
|
||||
const getStaffInfo = () => {
|
||||
axiosInstance({
|
||||
url: 'staff',
|
||||
method: 'get'
|
||||
}).then(response => {
|
||||
console.log(response.data)
|
||||
setStaff( response.data)
|
||||
}).catch(function (error) {
|
||||
console.log(error)
|
||||
})
|
||||
}
|
||||
useEffect(() => {
|
||||
if (token.accessToken === '') {
|
||||
console.log("redirect")
|
||||
navigate("/login")
|
||||
}
|
||||
getStaffInfo()
|
||||
if(staff.managingDepartment)
|
||||
{
|
||||
if(staff.managingDepartment.departmentName==='财务部')
|
||||
{
|
||||
setMenuItems([{
|
||||
key: "/invoice/mine",
|
||||
//icon: React.createElement(UserOutlined),
|
||||
label: <Link to="/invoice/mine">我的发票</Link>
|
||||
}, {
|
||||
key: "/reimbursement/mine",
|
||||
//icon: React.createElement(UserOutlined),
|
||||
label: <Link to="/reimbursement/mine">我的报销</Link>,
|
||||
}, {
|
||||
key: "/invoice/management",
|
||||
//icon: React.createElement(UserOutlined),
|
||||
label: <Link to="/reimbursement/mine">发票管理</Link>,
|
||||
}, {
|
||||
key: "/reimbursement/management",
|
||||
//icon: React.createElement(UserOutlined),
|
||||
label: <Link to="/reimbursement/mine">报销审批</Link>,
|
||||
}, {
|
||||
key: "/stat",
|
||||
//icon: React.createElement(UserOutlined),
|
||||
label: <Link to="/reimbursement/mine">财务统计</Link>,
|
||||
}])
|
||||
}
|
||||
else{
|
||||
setMenuItems([{
|
||||
key: "/invoice/mine",
|
||||
//icon: React.createElement(UserOutlined),
|
||||
label: <Link to="/invoice/mine">我的发票</Link>
|
||||
}, {
|
||||
key: "/reimbursement/mine",
|
||||
//icon: React.createElement(UserOutlined),
|
||||
label: <Link to="/reimbursement/mine">我的报销</Link>,
|
||||
}, {
|
||||
key: "/reimbursement/management",
|
||||
//icon: React.createElement(UserOutlined),
|
||||
label: <Link to="/reimbursement/mine">报销审批</Link>,
|
||||
}])
|
||||
}
|
||||
}
|
||||
else {
|
||||
setMenuItems([{
|
||||
key: "/invoice/mine",
|
||||
//icon: React.createElement(UserOutlined),
|
||||
label: <Link to="/invoice/mine">我的发票</Link>
|
||||
}, {
|
||||
key: "/reimbursement/mine",
|
||||
//icon: React.createElement(UserOutlined),
|
||||
label: <Link to="/reimbursement/mine">我的报销</Link>,
|
||||
}])
|
||||
}
|
||||
}, []);
|
||||
return (
|
||||
<Layout style={{height: '100%'}}>
|
||||
<Sider
|
||||
width={208}
|
||||
style={{ background: colorBgContainer }}
|
||||
style={{background: colorBgContainer}}
|
||||
breakpoint="lg"
|
||||
collapsedWidth="0"
|
||||
onBreakpoint={(broken) => {
|
||||
|
@ -61,20 +227,31 @@ function HomeView() {
|
|||
console.log(collapsed, type);
|
||||
}}
|
||||
>
|
||||
<div style={{height: '32px',margin: '17px 0 17px 0', display: 'flex', justifyContent: 'center', alignItems: 'center'}}>
|
||||
<div style={{
|
||||
height: '32px',
|
||||
margin: '17px 0 17px 0',
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center'
|
||||
}}>
|
||||
<Icon component={Logo}/>
|
||||
<span style={{color: colorPrimary, fontSize: '16px', fontWeight: 'bold', marginLeft: '4px'}}>智能财务报销系统</span>
|
||||
<span style={{
|
||||
color: colorPrimary,
|
||||
fontSize: '16px',
|
||||
fontWeight: 'bold',
|
||||
marginLeft: '4px'
|
||||
}}>智能财务报销系统</span>
|
||||
</div>
|
||||
<Menu
|
||||
mode="inline"
|
||||
defaultSelectedKeys={['/invoice/mine']}
|
||||
items={items}
|
||||
items={menuItems}
|
||||
/>
|
||||
</Sider>
|
||||
<Layout>
|
||||
<Header style={{height: '48px', padding: 0, background: colorBgContainer }}/>
|
||||
<HeaderBar staff={staff}/>
|
||||
<Content style={{margin: '24px 16px 0'}}>
|
||||
<Outlet />
|
||||
<Outlet/>
|
||||
</Content>
|
||||
<Footer style={{textAlign: 'center'}}></Footer>
|
||||
</Layout>
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import {Card, Dropdown, List,Menu,Input,Button,Radio,Divider} from "antd";
|
||||
import type { MenuProps } from 'antd';
|
||||
import { Icon } from '@ant-design/compatible'
|
||||
import { DownOutlined,UploadOutlined } from '@ant-design/icons';
|
||||
import React, {ReactElement, JSXElementConstructor, ReactFragment, ReactPortal,useState } from "react";
|
||||
import {Invoice,InvoiceSearchOption} from "../../../models/Staff"
|
||||
|
@ -33,7 +32,20 @@ class InvoiceSearch extends React.Component<any, any> {
|
|||
//const dispatch = useAppDispatch();
|
||||
//const navigate = useNavigate();
|
||||
console.log(baseUrl + 'common/invoice/list?'+this.state.invoiceSearchOption.toString())
|
||||
axiosInstance.get(baseUrl + 'common/invoice/list?'+this.state.invoiceSearchOption.toString()).then(function (response) {
|
||||
let params = this.state.invoiceSearchOption
|
||||
if(params.invoiceNo==="") params.invoiceNo=null
|
||||
if(params.invoiceCode==="") params.invoiceCode=null
|
||||
axiosInstance({
|
||||
url: 'common/invoice/list',
|
||||
method: 'get',
|
||||
params: params
|
||||
}).then(response => {
|
||||
console.log(response.data)
|
||||
handleSearchData(response.data.records)
|
||||
}).catch(function (error) {
|
||||
console.log(error)
|
||||
})
|
||||
/* axiosInstance.get(baseUrl + 'common/invoice/list?'+this.state.invoiceSearchOption.toString()).then(function (response) {
|
||||
console.log(response.data)
|
||||
//console.log(this.state)
|
||||
handleSearchData(response.data.records)
|
||||
|
@ -43,7 +55,7 @@ class InvoiceSearch extends React.Component<any, any> {
|
|||
}).catch(function (error) {
|
||||
console.log(error);
|
||||
//showAlert.value = true
|
||||
});
|
||||
});*/
|
||||
//console.log(value)
|
||||
//this.props.handleSearchData(value)
|
||||
}
|
||||
|
|
|
@ -22,10 +22,11 @@ function LoginView() {
|
|||
console.log(response.data)
|
||||
dispatch(setToken({
|
||||
accessToken: response.data.accessToken,
|
||||
refreshToken: response.data.refreshToken
|
||||
refreshToken: response.data.refreshToken,
|
||||
clientSecret: response.data.clientSecret
|
||||
}))
|
||||
//models.commit('setStaff', response.data.data)
|
||||
navigate('/')
|
||||
navigate('/invoice/mine')
|
||||
}).catch(function (error) {
|
||||
console.log(error);
|
||||
//showAlert.value = true
|
||||
|
|
Loading…
Reference in New Issue