129 lines
4.8 KiB
TypeScript
Raw Normal View History

import { PlusOutlined } from '@ant-design/icons';
import { ActionType, ModalForm, ProColumns, ProFormSelect, ProFormText, ProTable } from '@ant-design/pro-components';
import { Button, message, Popconfirm, Switch } from 'antd';
import { useRef, useState } from 'react';
import { listUsers, createUser, updateUser, deleteUser, updateUserStatus, listRoles } from '@/services/api';
import type { User } from '@/types/api';
const UsersPage: React.FC = () => {
const actionRef = useRef<ActionType>();
const [createOpen, setCreateOpen] = useState(false);
const [editOpen, setEditOpen] = useState(false);
const [currentRow, setCurrentRow] = useState<User | null>(null);
const [roleOptions, setRoleOptions] = useState<{ label: string; value: string }[]>([]);
const fetchRoles = async () => {
const res = await listRoles({ page: 1, pageSize: 100 });
if (res?.code === 0) {
setRoleOptions(
res.data?.list?.map((r) => ({ label: r.roleName, value: r.roleId })) || [],
);
}
};
const columns: ProColumns<User>[] = [
{ title: '用户名', dataIndex: 'username' },
{ title: '真实姓名', dataIndex: 'realName' },
{ title: '手机号', dataIndex: 'phone', search: false },
{ title: '邮箱', dataIndex: 'email', search: false },
{ title: '角色', dataIndex: 'roleName', search: false },
{
title: '状态',
dataIndex: 'status',
search: false,
render: (_, record) => (
<Switch
checked={record.status === 1}
onChange={async (checked) => {
const res = await updateUserStatus(record.userId, checked ? 1 : 0);
if (res?.code === 0) { message.success('状态更新成功'); actionRef.current?.reload(); }
}}
/>
),
},
{ title: '最后登录', dataIndex: 'lastLoginTime', valueType: 'dateTime', search: false },
{
title: '操作',
valueType: 'option',
render: (_, record) => [
<a key="edit" onClick={() => { setCurrentRow(record); setEditOpen(true); fetchRoles(); }}></a>,
<Popconfirm
key="del"
title="确认删除?"
onConfirm={async () => {
const res = await deleteUser(record.userId);
if (res?.code === 0) { message.success('删除成功'); actionRef.current?.reload(); }
}}
>
<a style={{ color: 'var(--ant-color-error)' }}></a>
</Popconfirm>,
],
},
];
return (
<>
<ProTable<User>
headerTitle="用户管理"
actionRef={actionRef}
rowKey="userId"
columns={columns}
request={async (params) => {
const res = await listUsers({
page: params.current,
pageSize: params.pageSize,
username: params.username,
realName: params.realName,
});
return { data: res?.data?.list || [], total: res?.data?.total || 0, success: res?.code === 0 };
}}
toolBarRender={() => [
<Button key="add" type="primary" icon={<PlusOutlined />} onClick={() => { setCreateOpen(true); fetchRoles(); }}>
</Button>,
]}
/>
<ModalForm
title="新增用户"
open={createOpen}
onOpenChange={setCreateOpen}
onFinish={async (values) => {
const res = await createUser(values);
if (res?.code === 0) { message.success('创建成功'); actionRef.current?.reload(); return true; }
message.error(res?.msg || '创建失败');
return false;
}}
>
<ProFormText name="username" label="用户名" rules={[{ required: true }]} />
<ProFormText.Password name="password" label="密码" rules={[{ required: true, min: 6, message: '密码至少6位' }]} />
<ProFormText name="realName" label="真实姓名" rules={[{ required: true }]} />
<ProFormText name="phone" label="手机号" />
<ProFormText name="email" label="邮箱" />
2026-06-18 17:37:11 +09:00
<ProFormSelect name="roleId" label="角色" options={roleOptions} />
</ModalForm>
<ModalForm
title="编辑用户"
open={editOpen}
onOpenChange={setEditOpen}
initialValues={currentRow ?? undefined}
onFinish={async (values) => {
if (!currentRow) return false;
const res = await updateUser(currentRow.userId, values);
if (res?.code === 0) { message.success('更新成功'); actionRef.current?.reload(); return true; }
message.error(res?.msg || '更新失败');
return false;
}}
>
<ProFormText name="realName" label="真实姓名" />
<ProFormText name="phone" label="手机号" />
<ProFormText name="email" label="邮箱" />
<ProFormSelect name="roleId" label="角色" options={roleOptions} />
</ModalForm>
</>
);
};
export default UsersPage;