作为一个企业内部系统,在用户还没有登录的前提下,是不允许访问系统中任何页面内容的。
所以本节要实现的:
另外为了避免刷新页面后登录状态重置,还要保存一下用户的登录信息。
这需要用到浏览器的 localstorage 功能。
本文只是提供一种思路,具体,可以根据项目进行自行修改。
如何实现触发事件?
点击菜单项后会触发事件,用户可以通过相应的菜单项 key
进行不同的操作。
import { DownOutlined } from '@ant-design/icons';
import { Dropdown, message, Space } from 'antd';
// 注意此处
const onClick = ({ key }) => {
message.info(`Click on item ${key}`);
};
const items = [
{
label: '1st menu item',
key: '1',
},
{
label: '2nd menu item',
key: '2',
},
{
label: '3rd menu item',
key: '3',
},
];
const App = () => (
e.preventDefault()}>
Hover me, Click menu item
);
export default App;
实现代码
import { useNavigate } from "react-router-dom";
const navigate = useNavigate();
const onClick = ({ key }) => {
if(key.toString() === '4'){
navigate('/login');
}
};
登录框
普通的登录框,可以容纳更多的元素。
实现代码
import { LockOutlined, UserOutlined } from "@ant-design/icons";
import { Button, Form, Input, Space } from "antd";
import styles from "./index.module.css";
export default function Login() {
const onFinish = (values) => {
console.log("Received values of form: ");
console.log(values);
};
return (
);
}
页面展示
reactjs-localstorage react存储本地数据,下载地址
安装
npm install reactjs-localstorage
or
yarn add reactjs-localstorage
使用案例
import {reactLocalStorage} from 'reactjs-localstorage';
reactLocalStorage.set('var', true);
reactLocalStorage.get('var', true);
reactLocalStorage.setObject('var', {'test': 'test'});
reactLocalStorage.getObject('var');
reactLocalStorage.remove('var');
reactLocalStorage.clear();
jsonserver由于受限,所以,暂时使用get请求。但是真实环境,一定是后端判断是否可以登录。
实现代码
import {reactLocalStorage} from 'reactjs-localstorage'; //引入组件 'reactjs-localstorage'
const onFinish = async (values) => {
let userData = await fetchGetUsersLogin(values)
// 判断是否是可用用户
if(userData.length > 0){
reactLocalStorage.setObject('token', userData[0]);
navigate('/home');
} else {
message.error(`登录失败`);
}
};
页面展示
在实际中,后端返回的token往往是一大串大串的字符串,而不是真实用户数据。
全部代码
import { LockOutlined, UserOutlined } from "@ant-design/icons";
import { Button, Form, Input, Space ,message} from "antd";
import { useNavigate } from "react-router-dom";
import styles from "./index.module.css";
import { fetchGetUsersLogin } from "../../utils/api";
import {reactLocalStorage} from 'reactjs-localstorage';
export default function Login() {
const navigate = useNavigate();
const onFinish = async (values) => {
let userData = await fetchGetUsersLogin(values)
// 判断是否是可用用户
if(userData.length > 0){
delete userData[0].password
reactLocalStorage.setObject('token', userData[0]);
navigate('/home');
} else {
message.error(`登录失败`);
}
};
return (
);
}
此部分,需要修改之前的左侧导航组件:需要根据用户的权限,动态显示左侧导航内容。
详见左侧导航组件内容
修改之前组件,添加用户权限判断
import {reactLocalStorage} from 'reactjs-localstorage';
// 获取用户权限列表
const {role: {rights}} = reactLocalStorage.getObject('token')
const checkPagePermission = (item)=>{
return item.key !== "/login" && rights.includes(item.key) && item.pagepermisson === 1
}
全部代码如下:
import { useEffect, useState } from "react";
import { Layout, Menu } from "antd";
import { matchRoutes, useLocation, useNavigate } from "react-router-dom";
import { routers } from "../../router";
import styles from "./SideMenu.module.css";
import siteBaseConfig from "../../config";
import { fetchGetMenus } from "../../utils/api";
import { iconList } from "./iconList";
import {reactLocalStorage} from 'reactjs-localstorage';
const { Sider } = Layout;
export default function AppLayout() {
const location = useLocation();
const navigate = useNavigate();
const [isInit, setIsInit] = useState(false);
const [collapsed, setCollapsed] = useState(false);
// items 菜单内容 ItemType[]
const [items, setitems] = useState([]);
// defaultSelectedKeys 初始选中的菜单项 key 数组
const [defaultSelectedKeys, setDefaultSelectedKeys] = useState([]);
// defaultOpenKeys 初始展开的 SubMenu 菜单项 key 数组
const [defaultOpenKeys, setDefaultOpenKeys] = useState([]);
// submenu keys of first level
const [rootSubmenuKeys , setrootSubmenuKeys ] = useState([])
// openKeys 当前展开的 SubMenu 菜单项 key 数组
const [openKeys, setOpenKeys] = useState([]);
// 获取用户权限列表
const {role: {rights}} = reactLocalStorage.getObject('token')
const checkPagePermission = (item)=>{
return item.key !== "/login" && rights.includes(item.key) &&
item.pagepermisson === 1
}
useEffect(() => {
async function fetchData() {
const menusListData = await fetchGetMenus();
let tempItems = [],
rootSubmenuKeys = []; // submenu keys of first level
menusListData.forEach((item) => {
item.key !== "/login" && rootSubmenuKeys.push(item.key)
checkPagePermission(item) && tempItems.push({
label: item.title,
key: item.key,
icon: iconList[item.key],
children:
item.children &&
item.children.length > 0 &&
item.children.map((child) => {
if (child.pagepermisson === 1) {
return {
label: child.title,
key: child.key,
icon: iconList[item.key],
children:
child.children &&
child.children.length > 0 &&
child.children.map((sun) => {
if (child.pagepermisson === 1) {
return {
label: sun.title,
key: sun.key,
icon: iconList[item.key],
};
}
}),
};
}
}),
});
});
setitems(tempItems);
setrootSubmenuKeys(rootSubmenuKeys)
}
fetchData();
}, []);
useEffect(() => {
const routes = matchRoutes(routers, location.pathname); // 返回匹配到的路由数组对象,每一个对象都是一个路由对象
const pathArr = [];
if (routes !== null) {
routes.forEach((item) => {
const path = item.pathname;
if (path) {
pathArr.push(path);
}
});
}
setDefaultSelectedKeys(pathArr);
setDefaultOpenKeys(pathArr);
setIsInit(true);
}, [location.pathname]);
if (!isInit) {
return null;
}
const onClick = (e) => {
navigate(e.key);
};
const onOpenChange = (keys) => {
const latestOpenKey = keys.find((key) => openKeys.indexOf(key) === -1);
if (rootSubmenuKeys.indexOf(latestOpenKey) === -1) {
setOpenKeys(keys);
} else {
setOpenKeys(latestOpenKey ? [latestOpenKey] : []);
}
};
return (
<>
{siteBaseConfig.siteName}
>
);
}
页面展示 – 根据不同用户,显示不同左侧导航
问题所在
解决方案
优化用户列表,在真实环境中,是需要后端返回的。
import { reactLocalStorage } from "reactjs-localstorage";
// 获取用户权限列表
const { roleId, region,username } = reactLocalStorage.getObject("token");
const roleInterface = {
"1":"superadmin",
"2":"regionadmin",
"3":"regionediter",
}
// 获取用户数据处理
useEffect(() => {
const fetchGetUserListHandle = async () => {
const urseListData = await fetchGetUserList();
// 注意此处
setdataSource(roleInterface[roleId] === 'superadmin' ? urseListData: [
...urseListData.filter(item => item.username === username),
...urseListData.filter(item => item.region === region && roleInterface[item.roleId] === "regionediter"),
]);
};
fetchGetUserListHandle();
}, []);
问题解决
全部代码
import React, { useEffect, useRef, useState } from "react";
import { Space, Switch, Table, Modal, Tag, Button } from "antd";
import {
DeleteOutlined,
EditOutlined,
ExclamationCircleFilled,
} from "@ant-design/icons";
import AddUserModal from "./AddUserForm";
import UpdateUserModal from "./UpdateUserModal";
import {
fetchGetUserList,
fetchGetRegionList,
fetchGetRoles,
fetchAddUser,
fetchDeleteUser,
fetchPatchUser,
} from "../../utils/api";
import { reactLocalStorage } from "reactjs-localstorage";
const { confirm } = Modal;
export default function UserList() {
const [dataSource, setdataSource] = useState([]);
// 获取用户权限列表
const { roleId, region,username } = reactLocalStorage.getObject("token");
const roleInterface = {
"1":"superadmin",
"2":"regionadmin",
"3":"regionediter",
}
// 获取用户数据处理
useEffect(() => {
const fetchGetUserListHandle = async () => {
const urseListData = await fetchGetUserList();
// 注意此处
setdataSource(roleInterface[roleId] === 'superadmin' ? urseListData: [
...urseListData.filter(item => item.username === username),
...urseListData.filter(item => item.region === region && roleInterface[item.roleId] === "regionediter"),
]);
};
fetchGetUserListHandle();
}, []);
// 添加用户处理
const [open, setOpen] = useState(false);
const [regionList, setregionList] = useState([]);
const [rolesList, serolesList] = useState([]);
const AddUserFormData = useRef(null);
// 获取用户数据处理
useEffect(() => {
// 获取用户数据处理
const fetchGetRegionListHandle = async () => {
const urseListData = await fetchGetRegionList();
setregionList(urseListData);
};
fetchGetRegionListHandle();
// 获取用户数据处理
const fetchGetRolesListHandle = async () => {
const urseListData = await fetchGetRoles();
serolesList(urseListData);
};
fetchGetRolesListHandle();
}, []);
const onCreate = async (values) => {
console.log("Received values of form: ", values);
setOpen(false);
//post到后端,生成id,再设置 datasource, 方便后面的删除和更新
const data = await fetchAddUser({
...values,
roleState: true,
default: false,
});
setdataSource([
...dataSource,
{
...data,
role: rolesList.filter((item) => item.id === values.roleId)[0],
},
]);
};
// 删除弹框事件
const confirmHandel = (item) => {
confirm({
title: "您确定要删除吗?",
icon: ,
content: "此处删除会删除用户,请谨慎操作!",
okText: "确认",
cancelText: "取消",
onOk() {
console.log("OK");
deleteRolesMethod(item);
},
onCancel() {
console.log("Cancel");
},
});
};
// 删除事件
const deleteRolesMethod = async (item) => {
console.log(item);
setdataSource(dataSource.filter((data) => data.id != item.id));
const data = await fetchDeleteUser(item.id);
};
// 用户状态修改
const handelChange = async (item) => {
item.roleState = !item.roleState;
setdataSource([...dataSource]);
// 发送请求到后端
await fetchPatchUser(item.id, { roleState: item.roleState });
};
// 用户信息更改
const [openUpdateModal, setopenUpdateModal] = useState(false);
const UpdateUserFormData = useRef(null);
const [isRegionDisable, setisRegionDisable] = useState(false);
const [curentUserData, setcurentUserData] = useState(null);
const showUserModal = (item) => {
console.log(item);
setopenUpdateModal(true);
setTimeout(() => {
if (item.roleId === 1) {
// 禁用
setisRegionDisable(true);
} else {
// 取消禁用
setisRegionDisable(false);
}
UpdateUserFormData.current.setFieldsValue(item);
setcurentUserData(item);
}, 10);
};
const onUpdataUserConfirm = async (values) => {
setopenUpdateModal(false);
setdataSource(
dataSource.map((item) => {
if (item.id === curentUserData.id) {
return {
...item,
...values,
role: rolesList.filter((item) => item.id === values.roleId)[0],
};
}
return item;
})
);
setisRegionDisable(!isRegionDisable);
// 发送请求到后端
await fetchPatchUser(curentUserData.id, values);
};
const columns = [
{
title: "部门",
dataIndex: "region",
render: (region) => {
return region === "" ? "总部" : region;
},
filters: [
...regionList.map((item) => ({
text: item.title,
value: item.value,
})),
{ text: "超级管理员", value: "超级管理员" },
],
// 用户删选
onFilter: (value, record) => {
if (value === "超级管理员") {
return record.region === "";
} else {
return record.region === value;
}
},
},
{
title: "角色名称",
dataIndex: "role",
render: (role) => {
return {role?.roleName} ;
},
},
{
title: "用户名",
dataIndex: "username",
},
{
title: "用户可用状态",
dataIndex: "roleState",
render: (roleState, item) => {
// 注意这里
return (
handelChange(item)}
/>
);
},
},
{
title: "操作",
render: (item) => {
return (
}
shape="circle"
type="primary"
size="small"
onClick={() => showUserModal(item)}
>
}
shape="circle"
danger
size="small"
onClick={() => {
confirmHandel(item);
}}
>
);
},
},
];
return (
item.id}
pagination={{
pageSize: 5,
}}
>
{
setOpen(false);
}}
regionList={regionList}
rolesList={rolesList}
ref={AddUserFormData}
>
{
setopenUpdateModal(false);
}}
regionList={regionList}
rolesList={rolesList}
ref={UpdateUserFormData}
isRegionDisable={isRegionDisable}
>
);
}