完成顶栏,导航菜单分权展示

main
wuyize 2022-12-27 14:12:36 +08:00
parent 62155de02d
commit 4cb396ee81
5 changed files with 213 additions and 21 deletions

View File

@ -2,6 +2,7 @@
export interface Token { export interface Token {
accessToken: string; accessToken: string;
refreshToken: string; refreshToken: string;
clientSecret: string;
} }
export interface Staff { export interface Staff {

View File

@ -8,12 +8,13 @@ const tokenSlice = createSlice({
initialState: { initialState: {
accessToken: '', accessToken: '',
refreshToken: '', refreshToken: '',
clientSecret: ''
}, },
reducers: { reducers: {
setToken: (state, action: PayloadAction<Token>) => { setToken: (state, action: PayloadAction<Token>) => {
state.accessToken = action.payload.accessToken state.accessToken = action.payload.accessToken
state.refreshToken = action.payload.refreshToken state.refreshToken = action.payload.refreshToken
console.log('action: '+action) state.clientSecret = action.payload.clientSecret
}, },
}, },
}); });

View File

@ -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 {UploadOutlined, UserOutlined, VideoCameraOutlined} from '@ant-design/icons';
import {Layout, Menu, theme, Typography } from 'antd'; import {Layout, Menu, theme, Typography, Button, Dropdown, MenuProps} from 'antd';
import {useAppSelector} from "../models/hooks"; import {useAppDispatch, useAppSelector} from "../models/hooks";
import {getToken, store} from "../models/store"; import {getToken, setToken, store} from "../models/store";
import {Link, Outlet, useNavigate} from "react-router-dom"; import {Link, Outlet, useNavigate} from "react-router-dom";
import Icon from '@ant-design/icons'; import Icon from '@ant-design/icons';
import {Logo} from "../assets/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; 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() { function HomeView() {
const token = useAppSelector(getToken); const token = useAppSelector(getToken);
const navigate = useNavigate(); const navigate = useNavigate();
@ -23,35 +102,122 @@ function HomeView() {
key: "/reimbursement/mine", key: "/reimbursement/mine",
//icon: React.createElement(UserOutlined), //icon: React.createElement(UserOutlined),
label: <Link to="/reimbursement/mine"></Link>, label: <Link to="/reimbursement/mine"></Link>,
},{ }, {
key: "/invoice/management", key: "/invoice/management",
//icon: React.createElement(UserOutlined), //icon: React.createElement(UserOutlined),
label: <Link to="/reimbursement/mine"></Link>, label: <Link to="/reimbursement/mine"></Link>,
},{ }, {
key: "/reimbursement/management", key: "/reimbursement/management",
//icon: React.createElement(UserOutlined), //icon: React.createElement(UserOutlined),
label: <Link to="/reimbursement/mine"></Link>, label: <Link to="/reimbursement/mine"></Link>,
},{ }, {
key: "/stat", key: "/stat",
//icon: React.createElement(UserOutlined), //icon: React.createElement(UserOutlined),
label: <Link to="/reimbursement/mine"></Link>, label: <Link to="/reimbursement/mine"></Link>,
}] }]
const { const {
token: { colorBgContainer, colorPrimary }, token: {colorBgContainer, colorPrimary},
} = theme.useToken(); } = 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(() => { useEffect(() => {
if (token.accessToken === '') { if (token.accessToken === '') {
console.log("redirect") console.log("redirect")
navigate("/login") 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 ( return (
<Layout style={{height: '100%'}}> <Layout style={{height: '100%'}}>
<Sider <Sider
width={208} width={208}
style={{ background: colorBgContainer }} style={{background: colorBgContainer}}
breakpoint="lg" breakpoint="lg"
collapsedWidth="0" collapsedWidth="0"
onBreakpoint={(broken) => { onBreakpoint={(broken) => {
@ -61,20 +227,31 @@ function HomeView() {
console.log(collapsed, type); 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}/> <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> </div>
<Menu <Menu
mode="inline" mode="inline"
defaultSelectedKeys={['/invoice/mine']} defaultSelectedKeys={['/invoice/mine']}
items={items} items={menuItems}
/> />
</Sider> </Sider>
<Layout> <Layout>
<Header style={{height: '48px', padding: 0, background: colorBgContainer }}/> <HeaderBar staff={staff}/>
<Content style={{margin: '24px 16px 0'}}> <Content style={{margin: '24px 16px 0'}}>
<Outlet /> <Outlet/>
</Content> </Content>
<Footer style={{textAlign: 'center'}}></Footer> <Footer style={{textAlign: 'center'}}></Footer>
</Layout> </Layout>

View File

@ -1,6 +1,5 @@
import {Card, Dropdown, List,Menu,Input,Button,Radio,Divider} from "antd"; import {Card, Dropdown, List,Menu,Input,Button,Radio,Divider} from "antd";
import type { MenuProps } from 'antd'; import type { MenuProps } from 'antd';
import { Icon } from '@ant-design/compatible'
import { DownOutlined,UploadOutlined } from '@ant-design/icons'; import { DownOutlined,UploadOutlined } from '@ant-design/icons';
import React, {ReactElement, JSXElementConstructor, ReactFragment, ReactPortal,useState } from "react"; import React, {ReactElement, JSXElementConstructor, ReactFragment, ReactPortal,useState } from "react";
import {Invoice,InvoiceSearchOption} from "../../../models/Staff" import {Invoice,InvoiceSearchOption} from "../../../models/Staff"
@ -33,7 +32,20 @@ class InvoiceSearch extends React.Component<any, any> {
//const dispatch = useAppDispatch(); //const dispatch = useAppDispatch();
//const navigate = useNavigate(); //const navigate = useNavigate();
console.log(baseUrl + 'common/invoice/list?'+this.state.invoiceSearchOption.toString()) 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(response.data)
//console.log(this.state) //console.log(this.state)
handleSearchData(response.data.records) handleSearchData(response.data.records)
@ -43,7 +55,7 @@ class InvoiceSearch extends React.Component<any, any> {
}).catch(function (error) { }).catch(function (error) {
console.log(error); console.log(error);
//showAlert.value = true //showAlert.value = true
}); });*/
//console.log(value) //console.log(value)
//this.props.handleSearchData(value) //this.props.handleSearchData(value)
} }

View File

@ -22,10 +22,11 @@ function LoginView() {
console.log(response.data) console.log(response.data)
dispatch(setToken({ dispatch(setToken({
accessToken: response.data.accessToken, accessToken: response.data.accessToken,
refreshToken: response.data.refreshToken refreshToken: response.data.refreshToken,
clientSecret: response.data.clientSecret
})) }))
//models.commit('setStaff', response.data.data) //models.commit('setStaff', response.data.data)
navigate('/') navigate('/invoice/mine')
}).catch(function (error) { }).catch(function (error) {
console.log(error); console.log(error);
//showAlert.value = true //showAlert.value = true