可用版本

This commit is contained in:
戚辰先生 2024-11-30 18:13:37 +08:00
parent 5cc0deb917
commit 445766b458

View File

@ -1,331 +1,331 @@
import React, { useEffect, useState } from 'react';
import { Table, Button, Modal, Form, Input, Space, message, Switch, TreeSelect } from 'antd';
import { PlusOutlined, EditOutlined, DeleteOutlined, KeyOutlined, TeamOutlined } from '@ant-design/icons';
import type { UserResponse, Role } from './types';
import type { DepartmentDTO } from '../Department/types';
import { getUsers, createUser, updateUser, deleteUser, resetPassword } from './service';
import { useTableData } from '@/hooks/useTableData';
import type { FixedType, AlignType } from 'rc-table/lib/interface';
import React, {useEffect, useState} from 'react';
import {Table, Button, Modal, Form, Input, Space, message, Switch, TreeSelect} from 'antd';
import {PlusOutlined, EditOutlined, DeleteOutlined, KeyOutlined, TeamOutlined} from '@ant-design/icons';
import type {UserResponse, Role} from './types';
import type {DepartmentDTO} from '../Department/types';
import {getUsers, createUser, updateUser, deleteUser, resetPassword} from './service';
import {useTableData} from '@/hooks/useTableData';
import type {FixedType, AlignType} from 'rc-table/lib/interface';
const UserPage: React.FC = () => {
const {
list: users,
pagination,
loading,
loadData: fetchUsers,
onPageChange,
handleCreate,
handleUpdate,
handleDelete
} = useTableData({
service: {
list: getUsers,
create: createUser,
update: updateUser,
delete: deleteUser
},
defaultParams: {
sortField: 'createTime',
sortOrder: 'desc'
},
message: {
createSuccess: '用户创建成功',
updateSuccess: '用户更新成功',
deleteSuccess: '用户删除成功',
loadError: '获取用户列表失败'
}
});
const [departments, setDepartments] = useState<DepartmentDTO[]>([]);
const [modalVisible, setModalVisible] = useState(false);
const [resetPasswordModalVisible, setResetPasswordModalVisible] = useState(false);
const [editingUser, setEditingUser] = useState<UserResponse | null>(null);
const [form] = Form.useForm();
const [passwordForm] = Form.useForm();
const handleAdd = () => {
setEditingUser(null);
form.resetFields();
form.setFieldsValue({
enabled: true
const {
list: users,
pagination,
loading,
loadData: fetchUsers,
onPageChange,
handleCreate,
handleUpdate,
handleDelete
} = useTableData({
service: {
list: getUsers,
create: createUser,
update: updateUser,
delete: deleteUser
},
defaultParams: {
sortField: 'createTime',
sortOrder: 'desc'
},
message: {
createSuccess: '用户创建成功',
updateSuccess: '用户更新成功',
deleteSuccess: '用户删除成功',
loadError: '获取用户列表失败'
}
});
setModalVisible(true);
};
const handleEdit = (record: UserResponse) => {
setEditingUser(record);
form.setFieldsValue({
...record
});
setModalVisible(true);
};
const [departments, setDepartments] = useState<DepartmentDTO[]>([]);
const [modalVisible, setModalVisible] = useState(false);
const [resetPasswordModalVisible, setResetPasswordModalVisible] = useState(false);
const [editingUser, setEditingUser] = useState<UserResponse | null>(null);
const [form] = Form.useForm();
const [passwordForm] = Form.useForm();
const handleResetPassword = (record: UserResponse) => {
setEditingUser(record);
passwordForm.resetFields();
setResetPasswordModalVisible(true);
};
const handleResetPasswordSubmit = async () => {
try {
const values = await passwordForm.validateFields();
if (editingUser) {
await resetPassword(editingUser.id, values.password);
message.success('密码重置成功');
setResetPasswordModalVisible(false);
}
} catch (error) {
message.error('密码重置失败');
}
};
const handleSubmit = async () => {
try {
const values = await form.validateFields();
if (editingUser) {
await updateUser(editingUser.id, {
...values,
version: editingUser.version
const handleAdd = () => {
setEditingUser(null);
form.resetFields();
form.setFieldsValue({
enabled: true
});
message.success('更新成功');
} else {
await createUser(values);
message.success('创建成功');
}
setModalVisible(false);
fetchUsers();
} catch (error) {
message.error('操作失败');
}
};
setModalVisible(true);
};
const getTreeData = (deps: DepartmentDTO[]): any[] => {
return deps.map(dept => ({
title: dept.name,
value: dept.id,
children: dept.children && dept.children.length > 0 ? getTreeData(dept.children) : undefined
}));
};
const handleEdit = (record: UserResponse) => {
setEditingUser(record);
form.setFieldsValue({
...record
});
setModalVisible(true);
};
// const handleAssignRoles = (record: UserResponse) => {
// setSelectedUser(record);
// setRoleModalVisible(true);
// };
const handleResetPassword = (record: UserResponse) => {
setEditingUser(record);
passwordForm.resetFields();
setResetPasswordModalVisible(true);
};
const columns = [
{
title: 'ID',
dataIndex: 'id',
key: 'id',
width: 80,
fixed: 'left' as FixedType
},
{
title: '用户名',
dataIndex: 'username',
key: 'username',
width: 120,
},
{
title: '昵称',
dataIndex: 'nickname',
key: 'nickname',
width: 120,
},
{
title: '邮箱',
dataIndex: 'email',
key: 'email',
width: 200,
ellipsis: true,
},
{
title: '手机号',
dataIndex: 'phone',
key: 'phone',
width: 120,
},
{
title: '角色',
dataIndex: 'roles',
key: 'roles',
width: 150,
ellipsis: true,
render: (roles: Role[]) => roles?.map(role => role.name).join(', ') || '-'
},
{
title: '创建时间',
dataIndex: 'createTime',
key: 'createTime',
width: 180,
},
{
title: '更新时间',
dataIndex: 'updateTime',
key: 'updateTime',
width: 180,
},
{
title: '状态',
dataIndex: 'enabled',
key: 'enabled',
width: 80,
align: 'center' as AlignType,
render: (enabled: boolean) => (
<Switch checked={enabled} disabled size="small" />
),
},
{
title: '操作',
key: 'action',
width: 180,
fixed: 'right' as FixedType,
render: (_: any, record: UserResponse) => (
<Space size="small">
<Button
type="link"
size="small"
icon={<EditOutlined />}
onClick={() => handleEdit(record)}
>
</Button>
<Button
type="link"
size="small"
icon={<KeyOutlined />}
onClick={() => handleResetPassword(record)}
>
</Button>
<Button
type="link"
size="small"
danger
icon={<DeleteOutlined />}
onClick={() => handleDelete(record.id)}
disabled={record.username === 'admin'}
>
</Button>
</Space>
),
},
];
const handleResetPasswordSubmit = async () => {
try {
const values = await passwordForm.validateFields();
if (editingUser) {
await resetPassword(editingUser.id, values.password);
message.success('密码重置成功');
setResetPasswordModalVisible(false);
}
} catch (error) {
message.error('密码重置失败');
}
};
return (
<div style={{ padding: '24px' }}>
<div style={{ marginBottom: 16 }}>
<Button type="primary" icon={<PlusOutlined />} onClick={handleAdd}>
</Button>
</div>
const handleSubmit = async () => {
try {
const values = await form.validateFields();
if (editingUser) {
await updateUser(editingUser.id, {
...values,
version: editingUser.version
});
message.success('更新成功');
} else {
await createUser(values);
message.success('创建成功');
}
setModalVisible(false);
fetchUsers();
} catch (error) {
message.error('操作失败');
}
};
<Table
loading={loading}
columns={columns}
dataSource={users}
rowKey="id"
scroll={{ x: 1500 }}
pagination={{
...pagination,
showSizeChanger: true,
showQuickJumper: true,
showTotal: (total) => `${total} 条记录`,
onChange: onPageChange,
size: 'small'
}}
rowSelection={{
type: 'checkbox',
onChange: (selectedRowKeys, selectedRows) => {
console.log('selectedRowKeys:', selectedRowKeys);
console.log('selectedRows:', selectedRows);
},
getCheckboxProps: (record) => ({
disabled: record.username === 'admin',
}),
fixed: true,
}}
size="middle"
bordered
/>
const getTreeData = (deps: DepartmentDTO[]): any[] => {
return deps.map(dept => ({
title: dept.name,
value: dept.id,
children: dept.children && dept.children.length > 0 ? getTreeData(dept.children) : undefined
}));
};
<Modal
title={editingUser ? '编辑用户' : '新增用户'}
open={modalVisible}
onOk={handleSubmit}
onCancel={() => setModalVisible(false)}
width={600}
destroyOnClose
>
<Form
form={form}
layout="vertical"
>
<Form.Item
name="username"
label="用户名"
rules={[{ required: true, message: '请输入用户名' }]}
>
<Input placeholder="请输入用户名" disabled={!!editingUser} />
</Form.Item>
// const handleAssignRoles = (record: UserResponse) => {
// setSelectedUser(record);
// setRoleModalVisible(true);
// };
{!editingUser && (
<Form.Item
name="password"
label="密码"
rules={[
{ required: true, message: '请输入密码' },
{ min: 6, message: '密码长度不能小于6位' }
]}
>
<Input.Password placeholder="请输入密码" />
</Form.Item>
)}
const columns = [
{
title: 'ID',
dataIndex: 'id',
key: 'id',
width: 60,
fixed: 'left' as FixedType
},
{
title: '用户名',
dataIndex: 'username',
key: 'username',
width: 100,
},
{
title: '昵称',
dataIndex: 'nickname',
key: 'nickname',
width: 100,
},
{
title: '邮箱',
dataIndex: 'email',
key: 'email',
width: 180,
ellipsis: true,
},
{
title: '手机号',
dataIndex: 'phone',
key: 'phone',
width: 120,
},
{
title: '角色',
dataIndex: 'roles',
key: 'roles',
width: 120,
ellipsis: true,
render: (roles: Role[]) => roles?.map(role => role.name).join(', ') || '-'
},
{
title: '创建时间',
dataIndex: 'createTime',
key: 'createTime',
width: 150,
},
{
title: '更新时间',
dataIndex: 'updateTime',
key: 'updateTime',
width: 150,
},
{
title: '状态',
dataIndex: 'enabled',
key: 'enabled',
width: 60,
align: 'center' as AlignType,
render: (enabled: boolean) => (
<Switch checked={enabled} disabled size="small"/>
),
},
{
title: '操作',
key: 'action',
width: 240,
fixed: 'right' as FixedType,
render: (_: any, record: UserResponse) => (
<Space size={0}>
<Button
type="link"
size="small"
icon={<EditOutlined/>}
onClick={() => handleEdit(record)}
>
</Button>
<Button
type="link"
size="small"
icon={<KeyOutlined/>}
onClick={() => handleResetPassword(record)}
>
</Button>
<Button
type="link"
size="small"
danger
icon={<DeleteOutlined/>}
onClick={() => handleDelete(record.id)}
disabled={record.username === 'admin'}
>
</Button>
</Space>
),
},
];
<Form.Item
name="nickname"
label="昵称"
>
<Input placeholder="请输入昵称" />
</Form.Item>
<Form.Item
name="email"
label="邮箱"
rules={[{ type: 'email', message: '请输入正确的邮箱格式' }]}
>
<Input placeholder="请输入邮箱" />
</Form.Item>
<Form.Item
name="phone"
label="手机号"
>
<Input placeholder="请输入手机号" />
</Form.Item>
<Form.Item
name="deptId"
label="所属部门"
>
<TreeSelect
treeData={getTreeData(departments)}
placeholder="请选择所属部门"
allowClear
treeDefaultExpandAll
style={{ width: '100%' }}
return (
<div style={{padding: '24px'}}>
<div style={{marginBottom: 16}}>
<Button type="primary" icon={<PlusOutlined/>} onClick={handleAdd}>
</Button>
</div>
<Table
loading={loading}
columns={columns}
dataSource={users}
rowKey="id"
scroll={{x: 1500}}
pagination={{
...pagination,
showSizeChanger: true,
showQuickJumper: true,
showTotal: (total) => `${total} 条记录`,
onChange: onPageChange,
size: 'small'
}}
rowSelection={{
type: 'checkbox',
onChange: (selectedRowKeys, selectedRows) => {
console.log('selectedRowKeys:', selectedRowKeys);
console.log('selectedRows:', selectedRows);
},
getCheckboxProps: (record) => ({
disabled: record.username === 'admin',
}),
fixed: true,
}}
size="middle"
bordered
/>
</Form.Item>
<Form.Item
name="enabled"
label="状态"
valuePropName="checked"
initialValue={true}
>
<Switch />
</Form.Item>
</Form>
</Modal>
{/* RoleModal
<Modal
title={editingUser ? '编辑用户' : '新增用户'}
open={modalVisible}
onOk={handleSubmit}
onCancel={() => setModalVisible(false)}
width={600}
destroyOnClose
>
<Form
form={form}
layout="vertical"
>
<Form.Item
name="username"
label="用户名"
rules={[{required: true, message: '请输入用户名'}]}
>
<Input placeholder="请输入用户名" disabled={!!editingUser}/>
</Form.Item>
{!editingUser && (
<Form.Item
name="password"
label="密码"
rules={[
{required: true, message: '请输入密码'},
{min: 6, message: '密码长度不能小于6位'}
]}
>
<Input.Password placeholder="请输入密码"/>
</Form.Item>
)}
<Form.Item
name="nickname"
label="昵称"
>
<Input placeholder="请输入昵称"/>
</Form.Item>
<Form.Item
name="email"
label="邮箱"
rules={[{type: 'email', message: '请输入正确的邮箱格式'}]}
>
<Input placeholder="请输入邮箱"/>
</Form.Item>
<Form.Item
name="phone"
label="手机号"
>
<Input placeholder="请输入手机号"/>
</Form.Item>
<Form.Item
name="deptId"
label="所属部门"
>
<TreeSelect
treeData={getTreeData(departments)}
placeholder="请选择所属部门"
allowClear
treeDefaultExpandAll
style={{width: '100%'}}
/>
</Form.Item>
<Form.Item
name="enabled"
label="状态"
valuePropName="checked"
initialValue={true}
>
<Switch/>
</Form.Item>
</Form>
</Modal>
{/* RoleModal
{selectedUser && (
<RoleModal
userId={selectedUser.id}
@ -343,49 +343,49 @@ const UserPage: React.FC = () => {
)}
*/}
<Modal
title="重置密码"
open={resetPasswordModalVisible}
onOk={handleResetPasswordSubmit}
onCancel={() => setResetPasswordModalVisible(false)}
destroyOnClose
>
<Form
form={passwordForm}
layout="vertical"
>
<Form.Item
name="password"
label="新密码"
rules={[
{ required: true, message: '请输入新密码' },
{ min: 6, message: '密码长度不能小于6位' }
]}
>
<Input.Password placeholder="请输入新密码" />
</Form.Item>
<Form.Item
name="confirmPassword"
label="确认密码"
dependencies={['password']}
rules={[
{ required: true, message: '请确认新密码' },
({ getFieldValue }) => ({
validator(_, value) {
if (!value || getFieldValue('password') === value) {
return Promise.resolve();
}
return Promise.reject(new Error('两次输入的密码不一致'));
},
}),
]}
>
<Input.Password placeholder="请确认新密码" />
</Form.Item>
</Form>
</Modal>
</div>
);
<Modal
title="重置密码"
open={resetPasswordModalVisible}
onOk={handleResetPasswordSubmit}
onCancel={() => setResetPasswordModalVisible(false)}
destroyOnClose
>
<Form
form={passwordForm}
layout="vertical"
>
<Form.Item
name="password"
label="新密码"
rules={[
{required: true, message: '请输入新密码'},
{min: 6, message: '密码长度不能小于6位'}
]}
>
<Input.Password placeholder="请输入新密码"/>
</Form.Item>
<Form.Item
name="confirmPassword"
label="确认密码"
dependencies={['password']}
rules={[
{required: true, message: '请确认新密码'},
({getFieldValue}) => ({
validator(_, value) {
if (!value || getFieldValue('password') === value) {
return Promise.resolve();
}
return Promise.reject(new Error('两次输入的密码不一致'));
},
}),
]}
>
<Input.Password placeholder="请确认新密码"/>
</Form.Item>
</Form>
</Modal>
</div>
);
};
export default UserPage;