用户操作
一、新增用户
- 新增组件 src\pages\user\components\AddUser.tsx
import React, { useEffect } from "react";
import { Form, Input, message, Modal } from "antd";
import { doAddUser } from "../../../api/user";
interface IProps {
open: boolean;
onCancel(refresh?: boolean): void;
}
function AddUser({ open, onCancel }: IProps) {
const [form] = Form.useForm();
useEffect(() => {
if (open) {
form.resetFields();
}
}, [open]);
const addUser = async (u: User) => {
const res = await doAddUser(u);
if (res.success) {
message.success("添加成功");
onCancel(true);
} else {
message.error(res.errorMessage);
}
};
return (
<Modal
title="新增用户"
open={open}
onCancel={() => {
onCancel();
}}
onOk={() => {
form.submit();
}}
>
<Form
labelCol={{ span: 5 }}
wrapperCol={{ span: 16 }}
form={form}
onFinish={addUser}
>
<Form.Item
label="用户名"
name={"username"}
rules={[
{
required: true,
type: "string",
message: "用户名不可以为空",
},
]}
>
<Input />
</Form.Item>
<Form.Item
label="邮箱"
name={"email"}
rules={[
{
required: true,
type: "email",
message: "邮箱格式不合法",
},
]}
>
<Input />
</Form.Item>
<Form.Item
label="密码"
name={"password"}
rules={[
{
required: true,
type: "string",
min: 6,
message: "密码至少要6位",
},
]}
>
<Input />
</Form.Item>
</Form>
</Modal>
);
}
export default AddUser;
- User 引入组件
import AddUser from "./components/AddUser";
const Index = () => {
const [open, setOpen] = useState(false);
const onCancel = async (status?: boolean) => {
setOpen(false);
if (status) {
getListByPage();
}
};
const addUserWrapper = <AddUser open={open} onCancel={onCancel} />;
return (
<div className={styles.userContainer}>
<Button
type="primary"
onClick={() => {
setOpen(true);
}}
>
新增
</Button>
<Table
rowKey={"id"}
dataSource={list}
columns={columns}
scroll={{ x: 1500, y: 500 }}
pagination={pagination}
onChange={changePage}
/>
{/* 新增用户 */}
{addUserWrapper}
</div>
);
};
二、删除用户
- src\pages\user\components\DeleteUser.tsx
import React from "react";
import { Button, message, Popconfirm } from "antd";
import { deleteUserById } from "../../../api/user";
interface Props {
id: number;
onDelete(id: number): void;
}
const DeleteUser = ({ id, onDelete }: Props) => {
const delUser = async () => {
const res = await deleteUserById(id);
if (res.success) {
onDelete(id);
} else {
message.error(res.errorMessage);
}
};
return (
<>
<Popconfirm title="删除用户" onConfirm={delUser}>
<Button type="primary" danger>
删除
</Button>
</Popconfirm>
</>
);
};
export default DeleteUser;
- User 引入
import DeleteUser from "./components/DeleteUser";
const Index = () => {
const deleteUser = async (id: number) => {
message.success(id);
await getListByPage();
};
const columns: ColumnsType<User> = [
{
title: "操作",
key: "operation",
fixed: "right",
width: 200,
align: "center",
render(value, record, index) {
return (
<Space>
<Button type="primary">编辑</Button>
<DeleteUser id={record.id} onDelete={deleteUser} />
</Space>
);
},
},
];
};
三、编辑用户
- src\pages\user\components\EditUser.tsx
import React, { useEffect } from "react";
import { Form, Input, message, Modal } from "antd";
import { updateUser } from "../../../api/user";
interface IProps {
user: User;
open: boolean;
onCancel(refresh?: boolean): void;
}
export default function EditUser({ user, open, onCancel }: IProps) {
const [form] = Form.useForm();
useEffect(() => {
if (open) {
form.resetFields();
}
}, [open]);
const saveUser = async (u: User) => {
const res = await updateUser(user.id, u);
if (res.success) {
message.success("更新成功");
onCancel(true);
} else {
message.error(res.errorMessage);
}
};
return (
<Modal
title="编辑用户"
open={open}
onCancel={() => {
onCancel();
}}
onOk={() => {
form.submit();
}}
>
<Form
labelCol={{ span: 5 }}
wrapperCol={{ span: 16 }}
form={form}
initialValues={{
...user,
password: "",
}}
onFinish={saveUser}
>
<Form.Item label="id" name={"id"} hidden>
<Input />
</Form.Item>
<Form.Item label="用户名" name={"username"}>
<Input />
</Form.Item>
<Form.Item label="邮箱" name={"email"}>
<Input />
</Form.Item>
<Form.Item label="密码" name={"password"}>
<Input />
</Form.Item>
</Form>
</Modal>
);
}
- User 页面
import EditUser from "./components/EditUser";
const Index = () => {
const [currentUser, setCurrentUser] = useState<User>({} as User);
const [editWrapper, setEditWrapper] = useState(false);
const cancelEditUser = async (status?: boolean) => {
setEditWrapper(false);
if (status) {
getListByPage();
}
};
const editUserWrapper = (
<EditUser user={currentUser} open={editWrapper} onCancel={cancelEditUser} />
);
const columns: ColumnsType<User> = [
{
title: "操作",
key: "operation",
fixed: "right",
width: 200,
align: "center",
render(value, record, index) {
return (
<Space>
<Button
type="primary"
onClick={() => {
setCurrentUser(record);
setEditWrapper(true);
}}
>
编辑
</Button>
<DeleteUser id={record.id} onDelete={deleteUser} />
</Space>
);
},
},
];
return (
<div className={styles.userContainer}>
{/* 新增用户 */}
{addUserWrapper}
{/* 编辑用户 */}
{editUserWrapper}
</div>
);
};
- 完成的 User 页面
import React, { useRef, useState, useEffect } from "react";
import { Table, Button, Space, Input, message } from "antd";
import type { InputRef } from "antd";
import { SearchOutlined, SyncOutlined } from "@ant-design/icons";
import type {
ColumnsType,
ColumnType,
TablePaginationConfig,
} from "antd/es/table";
import type { FilterConfirmProps } from "antd/es/table/interface";
import Highlighter from "react-highlight-words";
import AddUser from "./components/AddUser";
import DeleteUser from "./components/DeleteUser";
import EditUser from "./components/EditUser";
import { getUserList } from "../../api/user";
import styles from "./user.module.scss";
type DataIndex = keyof User;
const Index = () => {
const [searchText, setSearchText] = useState("");
const [searchedColumn, setSearchedColumn] = useState("");
const searchInput = useRef<InputRef>(null);
const [list, setList] = useState<User[]>([]);
const [pagination, setPagination] = useState<TablePaginationConfig>({
position: ["bottomCenter"],
showSizeChanger: true,
});
const [open, setOpen] = useState(false);
const [currentUser, setCurrentUser] = useState<User>({} as User);
const [editWrapper, setEditWrapper] = useState(false);
useEffect(() => {
getListByPage();
}, []);
const getListByPage = async (current: number = 1) => {
const res = await getUserList(current);
setList(res.data.list);
setPagination({
...pagination,
...res.data,
});
};
const onCancel = async (status?: boolean) => {
setOpen(false);
if (status) {
getListByPage();
}
};
const addUserWrapper = <AddUser open={open} onCancel={onCancel} />;
const deleteUser = async (id: number) => {
message.success(id);
await getListByPage();
};
const cancelEditUser = async (status?: boolean) => {
setEditWrapper(false);
if (status) {
getListByPage();
}
};
const editUserWrapper = (
<EditUser user={currentUser} open={editWrapper} onCancel={cancelEditUser} />
);
const changePage = (p: TablePaginationConfig) => {
console.log(p.current);
getListByPage(p.current);
};
const handleSearch = (
selectedKeys: string[],
confirm: (param?: FilterConfirmProps) => void,
dataIndex: DataIndex
) => {
confirm();
setSearchText(selectedKeys[0]);
setSearchedColumn(dataIndex);
};
const handleReset = (clearFilters: () => void) => {
clearFilters();
setSearchText("");
};
const getColumnSearchProps = (dataIndex: DataIndex): ColumnType<User> => ({
filterDropdown: ({
setSelectedKeys,
selectedKeys,
confirm,
clearFilters,
close,
}) => (
<div style={{ padding: 8 }} onKeyDown={(e) => e.stopPropagation()}>
<Input
ref={searchInput}
placeholder={`Search ${dataIndex}`}
value={selectedKeys[0]}
onChange={(e) =>
setSelectedKeys(e.target.value ? [e.target.value] : [])
}
onPressEnter={() =>
handleSearch(selectedKeys as string[], confirm, dataIndex)
}
style={{ marginBottom: 8, display: "block" }}
/>
<Space>
<Button
type="primary"
size="small"
onClick={() =>
handleSearch(selectedKeys as string[], confirm, dataIndex)
}
icon={<SearchOutlined />}
>
搜索
</Button>
<Button
type="primary"
size="small"
onClick={() => {
clearFilters && handleReset(clearFilters);
confirm({ closeDropdown: true });
close();
}}
icon={<SyncOutlined />}
>
还原
</Button>
</Space>
</div>
),
filterIcon: (filtered: boolean) => (
<SearchOutlined style={{ color: filtered ? "#1890ff" : undefined }} />
),
onFilter: (value, record) =>
record[dataIndex]
.toString()
.toLowerCase()
.includes((value as string).toLowerCase()),
onFilterDropdownOpenChange: (visible) => {
if (visible) {
setTimeout(() => searchInput.current?.select(), 100);
}
},
render: (text) =>
searchedColumn === dataIndex ? (
<Highlighter
highlightStyle={{ backgroundColor: "#ffc069", padding: 0 }}
searchWords={[searchText]}
autoEscape
textToHighlight={text ? text.toString() : ""}
/>
) : (
text
),
});
const columns: ColumnsType<User> = [
{
title: "ID",
width: 100,
dataIndex: "id",
key: "id",
align: "center",
fixed: "left",
},
{
title: "姓名",
dataIndex: "username",
key: "username",
...getColumnSearchProps("username"),
},
{
title: "email",
dataIndex: "email",
key: "email",
},
{
title: "操作",
key: "operation",
fixed: "right",
width: 200,
align: "center",
render(value, record, index) {
return (
<Space>
<Button
type="primary"
onClick={() => {
console.log(1111111, record);
setCurrentUser(record);
setEditWrapper(true);
}}
>
编辑
</Button>
<DeleteUser id={record.id} onDelete={deleteUser} />
</Space>
);
},
},
];
return (
<div className={styles.userContainer}>
<Button
type="primary"
onClick={() => {
setOpen(true);
}}
>
新增
</Button>
<Table
rowKey={"id"}
dataSource={list}
columns={columns}
scroll={{ x: 1500, y: 500 }}
pagination={pagination}
onChange={changePage}
/>
{/* 新增用户 */}
{addUserWrapper}
{/* 编辑用户 */}
{editUserWrapper}
</div>
);
};
export default Index;