0、前言
使用umi3和antd pro5从零实现全栈中后台管理系统
0-1、涉及技术栈
前端: TS 、 React、React Hooks、 umi3、antd-pro5
后端: express、mongodb、jwt
**
0-2、实现的功能
- 后端用户鉴权
- 前端权限管理
- 用户密码加密
- 封装一套通用弹窗表单组件,实现新建、修改、详情功能
- 用户登录注册(首次需要后端自己添加一条用户登录信息)
- 后端通过expressJWT实现接口鉴权与添加白名单
- 后端日志功能
- 后端封装方法统一处理返回信息
- 实现列表的筛选、排序、删除、批量删除
- 实现新建、修改、查看详情
1、初始化前端项目
yarn create umi myapp
npm i
npm run dev
1、设置config下的proxy代理
dev: {
'/api/': {
target: "http://localhost:3000",
changeOrigin: true,
pathRewrite: {
'^': '' },
},
},
2、登录
修改src/service/login.ts 接口改为/api/user/login
export async function fakeAccountLogin(params: LoginParamsType) {
return request<API.LoginStateType>('/api/user/login', {
method: 'POST',
data: params,
});
}
存储token pages/user/login/index.tsx
localStorage.setItem('token' , msg.token)
使用token services/user.ts
export async function queryCurrent() {
return request<API.CurrentUser>('/api/currentUser', headers: {
Authorization : 'Bearer ' + `${
localStorage.getItem('token')
}`
}
}
每次请求都带上token src/app.tsx
export const request: RequestConfig = {
errorHandler,
headers: {
Authorization : 'Bearer ' + `${
localStorage.getItem('token')}`
}
};
退出 RightContent/AvatarDropdown.tsx
localStorage.removeItem('token')
3、pro5参考文档
https://procomponents.ant.design/components/form#proform-1
4、实现一个用户管理
5、列表页
pages/ListTableList/index.tsx
import {
PlusOutlined } from '@ant-design/icons';
import {
Button, Divider, message, Avatar } from 'antd';
import React, {
useState, useRef } from 'react';
import {
PageContainer, FooterToolbar } from '@ant-design/pro-layout';
import ProTable, {
ProColumns, ActionType } from '@ant-design/pro-table';
import HandleForm from './components/HandleForm';
import {
TableListItem } from './data.d';
import {
queryRule, updateRule, addRule, removeRule } from './service';
import moment from 'moment';
/**
* 操作提交
* @param fields
*/
const handleSubmit = async (_id?: string, fields?: TableListItem) => {
let title = _id ? '修改' : '新增';
const hide = message.loading(`正在${
title}`);
try {
if (_id) {
await updateRule({
_id,
...fields,
});
} else {
await addRule({
...fields });
}
hide();
message.success(`${
title}成功`);
return true;
} catch (error) {
hide();
message.error(`${
title}失败`);
return false;
}
};
/**
* 删除节点
* @param selectedRows
*/
const handleRemove = async (selectedRows: string[], _id: string) => {
// console.log(selectedRows,_id,'selectedRows>>>>')
const hide = message.loading('正在删除');
// return
try {
await removeRule({
_id: _id ? _id : selectedRows,
});
hide();
message.success('删除成功');
return true;
} catch (error) {
hide();
message.error('删除失败');
return false;
}
};
const TableList: React.FC<{
}> = () => {
const [modalVisible, handleModalVisible] = useState<boolean>(false);
const [currentInfo, handleSaveCurrentInfo] = useState<TableListItem | null>(null);
const [isDetail, setDetail] = useState<boolean>(false);
const actionRef = useRef<ActionType>();
const [selectedRowsState, setSelectedRows] = useState<any>([]);
const columns: ProColumns<TableListItem>[] = [
{
title: '用户名',
dataIndex: 'username',
},
{
title: '密码',
dataIndex: 'password',
hideInDescriptions: true, //详情页不显示
hideInTable: true,
},
{
title: '角色',
dataIndex: 'access',
search: false,
filters: [
{
text: '普通用户', value: 'user' },
{
text: '管理员', value: 'admin' },
],
valueEnum: {
user: {
text: '普通用户' },
admin: {
text: '管理员' },
},
},</