feat: UserManage 完整用户 CRUD,创建/编辑/停用,角色下拉用拼音值
This commit is contained in:
@@ -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>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user