feat: UserManage 完整用户 CRUD,创建/编辑/停用,角色下拉用拼音值

This commit is contained in:
simonkoson
2026-05-21 19:47:54 +08:00
parent e0ccfb20e7
commit f0f9dc493e
+179 -9
View File
@@ -1,16 +1,186 @@
import { Card } from 'antd'
import { TeamOutlined } from '@ant-design/icons'
import { useState, useEffect } from 'react'
import { Table, Button, Modal, Form, Input, Select, Switch, message, Space } from 'antd'
import { UserAddOutlined, EditOutlined, StopOutlined } from '@ant-design/icons'
import { listUsers, createUser, updateUser, deactivateUser } from '../../services/userService'
const roleOptions = [
{ value: 'zhipianren', label: '制片人' },
{ value: 'zebian', label: '责编' },
{ value: 'biandao', label: '编导' },
]
function UserManage() {
const [users, setUsers] = useState([])
const [loading, setLoading] = useState(false)
const [modalVisible, setModalVisible] = useState(false)
const [editingUser, setEditingUser] = useState(null)
const [form] = Form.useForm()
useEffect(() => {
loadUsers()
}, [])
const loadUsers = () => {
setLoading(true)
listUsers().then(data => {
setUsers(data || [])
setLoading(false)
}).catch(() => {
message.error('加载用户列表失败')
setLoading(false)
})
}
const handleCreate = () => {
setEditingUser(null)
form.resetFields()
setModalVisible(true)
}
const handleEdit = (record) => {
setEditingUser(record)
form.setFieldsValue({
display_name: record.display_name,
role: record.role,
profile_text: record.profile_text,
is_active: record.is_active,
})
setModalVisible(true)
}
const handleDeactivate = (record) => {
Modal.confirm({
title: '停用用户',
content: `确认停用用户「${record.display_name}」(${record.username})?停用后可重新启用。`,
okText: '确认停用',
cancelText: '取消',
onOk: () => deactivateUser(record.id).then(() => {
message.success('已停用')
loadUsers()
}).catch(err => {
message.error(err.response?.data?.detail || '停用失败')
}),
})
}
const handleSubmit = () => {
form.validateFields().then(values => {
if (editingUser) {
updateUser(editingUser.id, values).then(() => {
message.success('更新成功')
setModalVisible(false)
loadUsers()
}).catch(err => {
message.error(err.response?.data?.detail || '更新失败')
})
} else {
createUser(values).then(() => {
message.success('创建成功')
setModalVisible(false)
loadUsers()
}).catch(err => {
message.error(err.response?.data?.detail || '创建失败')
})
}
})
}
const columns = [
{
title: '用户名',
dataIndex: 'username',
key: 'username',
},
{
title: '显示名',
dataIndex: 'display_name',
key: 'display_name',
},
{
title: '角色',
dataIndex: 'role',
key: 'role',
render: role => roleOptions.find(o => o.value === role)?.label || role,
},
{
title: '状态',
dataIndex: 'is_active',
key: 'is_active',
render: (active, record) => (
<Switch
checked={active}
onChange={() => handleDeactivate(record)}
checkedChildren="在职"
unCheckedChildren="已停"
/>
),
},
{
title: '操作',
key: 'action',
render: (_, record) => (
<Space>
<Button size="small" icon={<EditOutlined />} onClick={() => handleEdit(record)}>
编辑
</Button>
{record.is_active && (
<Button size="small" danger icon={<StopOutlined />} onClick={() => handleDeactivate(record)}>
停用
</Button>
)}
</Space>
),
},
]
return (
<Card style={{ borderRadius: 16 }}>
<div style={{ textAlign: 'center', padding: '48px 0', color: '#999' }}>
<TeamOutlined style={{ fontSize: 48, marginBottom: 16 }} />
<h3 style={{ color: '#666' }}>用户管理</h3>
<p>Phase 2 实施</p>
<small>管理员创建账号 / 角色分配 zhipianren 可见</small>
<div style={{ padding: '0 0 24px' }}>
<div style={{ marginBottom: 16, display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
<h2 style={{ margin: 0, fontSize: 20, fontWeight: 600 }}>用户管理</h2>
<Button type="primary" icon={<UserAddOutlined />} onClick={handleCreate}>
新建用户
</Button>
</div>
<Table
columns={columns}
dataSource={users}
rowKey="id"
loading={loading}
pagination={{ pageSize: 20 }}
/>
<Modal
title={editingUser ? '编辑用户' : '新建用户'}
open={modalVisible}
onOk={handleSubmit}
onCancel={() => setModalVisible(false)}
okText="保存"
cancelText="取消"
>
<Form form={form} layout="vertical" style={{ marginTop: 16 }}>
{!editingUser && (
<Form.Item name="username" label="用户名" rules={[{ required: true, message: '请输入用户名' }]}>
<Input placeholder="登录用户名" />
</Form.Item>
)}
<Form.Item name="display_name" label="显示名" rules={[{ required: true, message: '请输入显示名' }]}>
<Input placeholder="界面显示名称" />
</Form.Item>
{!editingUser && (
<Form.Item name="password" label="密码" rules={[{ required: true, message: '请输入密码' }]}>
<Input.Password placeholder="初始密码" />
</Form.Item>
)}
<Form.Item name="role" label="角色" rules={[{ required: true, message: '请选择角色' }]}>
<Select placeholder="选择角色" options={roleOptions} />
</Form.Item>
<Form.Item name="profile_text" label="个人简介">
<Input.TextArea rows={3} placeholder="可选" />
</Form.Item>
</Form>
</Modal>
</div>
</Card>
)
}