目录
一. 简述
上一篇文章我们实现登录页面和管理页面的 Layout
骨架,并对接登录和登出接口。这篇文章我们将实现用户管理的模块和相应的接口。最后效果如下:
二. 模块规划
在开发之前我们需要对 xxl-job
管理系统的用户模块进行规划。
2.1. 页面规划
一般我们都是从前端页面需要使用什么组件;后端接口需要哪些?
前端使用的组件:表格、分页、下拉框、输入框和按钮,就是一个很普通的 CRUD
管理页面,比较简单;接口也是围绕这些功能的:分页查询接口、创建用户接口、编辑用户接口和删除接口。
2.2. 模型实体定义
接着我们需要定义下前后端交互会使用的到的请求和响应实体的定义。
首先是用户分页查询接口的请求和响应:
// UserPageQueryProp 用户分页查询请求参数定义
export interface UserPageQueryProp {
page: number; // 页码
size: number; // 页大小
role: number; // 角色 ID
username?: string; // 用户名称
}
// UserTableProp 用户分页查询返回参数定义
export interface UserTableProp {
id: number; // 用户ID
username: string; // 用户名称
role: number; // 角色
permission: string; // 权限
}
这里需要注意的是虽然我们表格中只有用户名和角色名两个显示属性,但是考虑到在编辑的时候需要根据角色显示权限信息,这里在分页查询中返回用户的权限数据。但是如果在一些复杂的分页表格中,不建议这样操作!
接着是用户创建和编辑的请求的定义:
// UserTableProp 用户创建表单属性
export interface UserCreateFormProp {
username: string; // 用户名称
password: string; // 密码
role: number; // 角色
permission: string[]; // 权限
}
// UserUpdateFormProp 用户创建表单属性
export interface UserUpdateFormProp extends UserCreateFormProp{
id: number; // 用户ID
}
三. 模块实现
从这个模块我们可以分为两个大部分和三个小组件组成。
其中功能部分我们可以使用 antd
的Space
中嵌套表单组件实现;表格可以使用 Table
组件(这个组件自带分页功能)实现;最后创建和编辑按钮我们使用 Modal
组件中嵌套 Form
表单组件实现就可以了。下面我们按功能一个个实现这个用户模块。
这里我们在使用
TS
这个Buff
的使用,大部分使用需要申明类型,尤其在使用不熟悉的UI
组件库的时候,大家需要多读文章,多看组件定义文件或者源码。
3.1. 用户分页搜索
上面我们分析我们要使用组件,这里就不赘述了,直接上代码:
import {
Button, Divider, Input, Select, Space, Table, Tag} from "antd";
import React, {
useEffect, useState} from "react";
import {
User} from "@/types";
import {
ColumnsType} from "antd/es/table";
import {
useRequest} from "ahooks";
import UserApi from "@/api/user.ts";
import {
ClearOutlined, PlusOutlined, SearchOutlined} from "@ant-design/icons";
const UserPage = () => {
// 定义列信息
const columns: ColumnsType<User.UserTableProp> = [
{
title: '账号',
key: 'username',
dataIndex: 'username',
align: 'center'
},
{
title: '角色',
key: 'role',
dataIndex: 'role',
align: 'center',
render: (_, record) => record.role == 1 ? <Tag color="#f50">管理员</Tag> : <Tag color="#2db7f5">普通用户</Tag>
},
{
title: '操作',
key: 'active',
align: 'center',
width: 200,
render: (_, record) => <Space>
<Button type="primary" onClick={
() => openEdit(record.id)}>编辑</Button>
<Button type="primary" danger onClick={
() => deleteUser(record.id)}>删除</Button>
</Space>,
},
]
// 总条数
const [total, setTotal] = useState<number>(0);
const [selectedRowKeys, setSelectedRowKeys] = useState<number[]>([]);
// 用户数据
const [datasource, setDatasource] = useState<User.UserTableProp[]>([]);
// 分页查询属性
const [pageQuery, setPageQuery] = useState<User.UserPageQueryProp>(defaultUserPageQuery());
return <div>
<Space>
<Button type="primary" icon={
<PlusOutlined />}>增加用户</Button>
<Divider type="vertical"/>
<div>角色:</div>
<Select
onChange={
e => setPageQuery({
...pageQuery, role: e})