feat: 完成TikTok短剧管理后台基础功能开发
本次提交搭建了完整的后台管理系统,包含: 1. 登录认证与权限校验体系 2. 工作台、短剧、用户、角色、人员、日志等全业务模块 3. 响应式布局与通用样式组件 4. 菜单动态过滤与路由权限控制 5. 移除了README中冗余的权限管理菜单项
This commit is contained in:
117
src/Role/index.tsx
Normal file
117
src/Role/index.tsx
Normal file
@@ -0,0 +1,117 @@
|
||||
import { useState } from 'react';
|
||||
import { Button, Card, Form, Input, Message, Modal, Space, Table, Tag } from '@arco-design/web-react';
|
||||
import { IconPlus } from '@arco-design/web-react/icon';
|
||||
import type { Permission, Role } from '../api/types';
|
||||
import { api } from '../api/client';
|
||||
import { usePageData } from '../hooks/usePageData';
|
||||
import { PermissionTreePicker } from './PermissionTreePicker';
|
||||
import './index.css';
|
||||
|
||||
function RolesPage() {
|
||||
const { data, loading, reload } = usePageData<Role>('/api/admin/v1/roles');
|
||||
const permissions = usePageData<Permission>('/api/admin/v1/permissions');
|
||||
const [createForm] = Form.useForm();
|
||||
const [createVisible, setCreateVisible] = useState(false);
|
||||
const [creatingRole, setCreatingRole] = useState(false);
|
||||
const [createPermissionIds, setCreatePermissionIds] = useState<number[]>([]);
|
||||
const [assignmentVisible, setAssignmentVisible] = useState(false);
|
||||
const [selectedRole, setSelectedRole] = useState<Role | null>(null);
|
||||
const [selectedPermissionIds, setSelectedPermissionIds] = useState<number[]>([]);
|
||||
const [savingPermissions, setSavingPermissions] = useState(false);
|
||||
|
||||
const openCreateRole = () => {
|
||||
createForm.resetFields();
|
||||
setCreatePermissionIds([]);
|
||||
setCreateVisible(true);
|
||||
};
|
||||
|
||||
const createRole = async (values: { code: string; name: string; description?: string }) => {
|
||||
setCreatingRole(true);
|
||||
try {
|
||||
await api.post('/api/admin/v1/roles', {
|
||||
...values,
|
||||
permissionIds: createPermissionIds,
|
||||
});
|
||||
Message.success('角色创建成功');
|
||||
setCreateVisible(false);
|
||||
await reload();
|
||||
} finally {
|
||||
setCreatingRole(false);
|
||||
}
|
||||
};
|
||||
|
||||
const openAssignPermissions = (role: Role) => {
|
||||
setSelectedRole(role);
|
||||
setSelectedPermissionIds(role.permissions.map((permission) => permission.id));
|
||||
setAssignmentVisible(true);
|
||||
};
|
||||
|
||||
const saveRolePermissions = async () => {
|
||||
if (!selectedRole) {
|
||||
return;
|
||||
}
|
||||
setSavingPermissions(true);
|
||||
try {
|
||||
await api.patch(`/api/admin/v1/roles/${selectedRole.id}/permissions`, {
|
||||
permissionIds: selectedPermissionIds,
|
||||
});
|
||||
Message.success('角色权限已更新');
|
||||
setAssignmentVisible(false);
|
||||
await reload();
|
||||
} finally {
|
||||
setSavingPermissions(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Card className="section-card" title="角色管理" extra={<Button type="primary" icon={<IconPlus />} onClick={openCreateRole}>新增角色</Button>}>
|
||||
<Table rowKey="id" loading={loading} data={data.list} pagination={{ total: data.pagination.total, pageSize: data.pagination.pageSize }} columns={[
|
||||
{ title: 'ID', dataIndex: 'id', width: 80 },
|
||||
{ title: '编码', dataIndex: 'code' },
|
||||
{ title: '名称', dataIndex: 'name' },
|
||||
{ title: '权限列表', render: (_, record: Role) => <Space wrap>{record.permissions.map((item) => <Tag key={item.id}>{item.name}</Tag>)}</Space> },
|
||||
{ title: '操作', width: 140, render: (_, record: Role) => <Button size="small" onClick={() => openAssignPermissions(record)}>分配权限</Button> },
|
||||
]} />
|
||||
<Modal title="新增角色" visible={createVisible} onCancel={() => setCreateVisible(false)} footer={null}>
|
||||
<Form form={createForm} layout="vertical" onSubmit={createRole}>
|
||||
<Form.Item label="角色编码" field="code" rules={[{ required: true }]}>
|
||||
<Input placeholder="请输入角色编码,例如 drama_operator" />
|
||||
</Form.Item>
|
||||
<div className="form-help">角色的唯一标识,创建后不可修改</div>
|
||||
<Form.Item label="角色名称" field="name" rules={[{ required: true }]}>
|
||||
<Input placeholder="请输入角色名称" />
|
||||
</Form.Item>
|
||||
<Form.Item label="角色描述" field="description">
|
||||
<Input.TextArea placeholder="请输入角色描述" autoSize={{ minRows: 2, maxRows: 4 }} />
|
||||
</Form.Item>
|
||||
<div className="form-label">权限设置</div>
|
||||
<PermissionTreePicker
|
||||
permissions={permissions.data.list}
|
||||
value={createPermissionIds}
|
||||
onChange={setCreatePermissionIds}
|
||||
/>
|
||||
<div className="form-help">为角色分配系统权限,决定拥有此角色的用户可以进行的操作</div>
|
||||
<div className="modal-actions">
|
||||
<Button onClick={() => setCreateVisible(false)}>取消</Button>
|
||||
<Button type="primary" htmlType="submit" loading={creatingRole}>创建</Button>
|
||||
</div>
|
||||
</Form>
|
||||
</Modal>
|
||||
<Modal
|
||||
title={`分配权限${selectedRole ? ` - ${selectedRole.name}` : ''}`}
|
||||
visible={assignmentVisible}
|
||||
confirmLoading={savingPermissions}
|
||||
onOk={saveRolePermissions}
|
||||
onCancel={() => setAssignmentVisible(false)}
|
||||
>
|
||||
<PermissionTreePicker
|
||||
permissions={permissions.data.list}
|
||||
value={selectedPermissionIds}
|
||||
onChange={setSelectedPermissionIds}
|
||||
/>
|
||||
</Modal>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
export default RolesPage;
|
||||
Reference in New Issue
Block a user