162 lines
4.8 KiB
TypeScript
162 lines
4.8 KiB
TypeScript
|
|
import { Button, Form, Input, Modal, Popconfirm, Space, Table, Tag, Select } from "antd";
|
|||
|
|
import { useEffect, useMemo, useState } from "react";
|
|||
|
|
import { createRole, deleteRole, listRoles, updateRole } from "../api";
|
|||
|
|
import type { SysRole } from "../types";
|
|||
|
|
import { usePermission } from "../hooks/usePermission";
|
|||
|
|
|
|||
|
|
export default function Roles() {
|
|||
|
|
const [loading, setLoading] = useState(false);
|
|||
|
|
const [data, setData] = useState<SysRole[]>([]);
|
|||
|
|
const [query, setQuery] = useState({ roleCode: "", roleName: "" });
|
|||
|
|
const [pagination, setPagination] = useState({ current: 1, pageSize: 10 });
|
|||
|
|
const [open, setOpen] = useState(false);
|
|||
|
|
const [editing, setEditing] = useState<SysRole | null>(null);
|
|||
|
|
const [form] = Form.useForm();
|
|||
|
|
const { can } = usePermission();
|
|||
|
|
|
|||
|
|
const load = async () => {
|
|||
|
|
setLoading(true);
|
|||
|
|
try {
|
|||
|
|
const list = await listRoles();
|
|||
|
|
setData(list || []);
|
|||
|
|
} finally {
|
|||
|
|
setLoading(false);
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
useEffect(() => {
|
|||
|
|
load();
|
|||
|
|
}, []);
|
|||
|
|
|
|||
|
|
const filtered = useMemo(() => {
|
|||
|
|
return data.filter((r) => {
|
|||
|
|
const hitCode = query.roleCode ? r.roleCode?.includes(query.roleCode) : true;
|
|||
|
|
const hitName = query.roleName ? r.roleName?.includes(query.roleName) : true;
|
|||
|
|
return hitCode && hitName;
|
|||
|
|
});
|
|||
|
|
}, [data, query]);
|
|||
|
|
|
|||
|
|
const pageData = useMemo(() => {
|
|||
|
|
const start = (pagination.current - 1) * pagination.pageSize;
|
|||
|
|
return filtered.slice(start, start + pagination.pageSize);
|
|||
|
|
}, [filtered, pagination]);
|
|||
|
|
|
|||
|
|
const openCreate = () => {
|
|||
|
|
setEditing(null);
|
|||
|
|
form.resetFields();
|
|||
|
|
setOpen(true);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
const openEdit = (record: SysRole) => {
|
|||
|
|
setEditing(record);
|
|||
|
|
form.setFieldsValue(record);
|
|||
|
|
setOpen(true);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
const submit = async () => {
|
|||
|
|
const values = await form.validateFields();
|
|||
|
|
const payload: Partial<SysRole> = {
|
|||
|
|
roleCode: values.roleCode,
|
|||
|
|
roleName: values.roleName,
|
|||
|
|
remark: values.remark,
|
|||
|
|
status: values.status
|
|||
|
|
};
|
|||
|
|
if (editing) {
|
|||
|
|
await updateRole(editing.roleId, payload);
|
|||
|
|
} else {
|
|||
|
|
await createRole(payload);
|
|||
|
|
}
|
|||
|
|
setOpen(false);
|
|||
|
|
load();
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
const remove = async (id: number) => {
|
|||
|
|
await deleteRole(id);
|
|||
|
|
load();
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
return (
|
|||
|
|
<div>
|
|||
|
|
<Space style={{ marginBottom: 16 }}>
|
|||
|
|
<Input
|
|||
|
|
placeholder="角色编码"
|
|||
|
|
value={query.roleCode}
|
|||
|
|
onChange={(e) => setQuery({ ...query, roleCode: e.target.value })}
|
|||
|
|
/>
|
|||
|
|
<Input
|
|||
|
|
placeholder="角色名称"
|
|||
|
|
value={query.roleName}
|
|||
|
|
onChange={(e) => setQuery({ ...query, roleName: e.target.value })}
|
|||
|
|
/>
|
|||
|
|
{can("sys_role:create") && (
|
|||
|
|
<Button type="primary" onClick={openCreate}>新增</Button>
|
|||
|
|
)}
|
|||
|
|
</Space>
|
|||
|
|
|
|||
|
|
<Table
|
|||
|
|
rowKey="roleId"
|
|||
|
|
loading={loading}
|
|||
|
|
dataSource={pageData}
|
|||
|
|
pagination={{
|
|||
|
|
current: pagination.current,
|
|||
|
|
pageSize: pagination.pageSize,
|
|||
|
|
total: filtered.length,
|
|||
|
|
onChange: (current, pageSize) => setPagination({ current, pageSize })
|
|||
|
|
}}
|
|||
|
|
columns={[
|
|||
|
|
{ title: "ID", dataIndex: "roleId" },
|
|||
|
|
{ title: "编码", dataIndex: "roleCode" },
|
|||
|
|
{ title: "名称", dataIndex: "roleName" },
|
|||
|
|
{ title: "备注", dataIndex: "remark" },
|
|||
|
|
{
|
|||
|
|
title: "状态",
|
|||
|
|
dataIndex: "status",
|
|||
|
|
render: (v) => (v === 1 ? <Tag color="green">启用</Tag> : <Tag color="red">禁用</Tag>)
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
title: "操作",
|
|||
|
|
render: (_, record) => (
|
|||
|
|
<Space>
|
|||
|
|
{can("sys_role:update") && <Button onClick={() => openEdit(record)}>编辑</Button>}
|
|||
|
|
{can("sys_role:delete") && (
|
|||
|
|
<Popconfirm title="确认删除?" onConfirm={() => remove(record.roleId)}>
|
|||
|
|
<Button danger>删除</Button>
|
|||
|
|
</Popconfirm>
|
|||
|
|
)}
|
|||
|
|
</Space>
|
|||
|
|
)
|
|||
|
|
}
|
|||
|
|
]}
|
|||
|
|
/>
|
|||
|
|
|
|||
|
|
<Modal
|
|||
|
|
title={editing ? "编辑角色" : "新增角色"}
|
|||
|
|
open={open}
|
|||
|
|
onOk={submit}
|
|||
|
|
onCancel={() => setOpen(false)}
|
|||
|
|
destroyOnClose
|
|||
|
|
>
|
|||
|
|
<Form form={form} layout="vertical">
|
|||
|
|
<Form.Item label="角色编码" name="roleCode" rules={[{ required: true }]}>
|
|||
|
|
<Input disabled={!!editing} />
|
|||
|
|
</Form.Item>
|
|||
|
|
<Form.Item label="角色名称" name="roleName" rules={[{ required: true }]}>
|
|||
|
|
<Input />
|
|||
|
|
</Form.Item>
|
|||
|
|
<Form.Item label="备注" name="remark">
|
|||
|
|
<Input.TextArea rows={3} />
|
|||
|
|
</Form.Item>
|
|||
|
|
<Form.Item label="状态" name="status" initialValue={1}>
|
|||
|
|
<Select
|
|||
|
|
options={[
|
|||
|
|
{ value: 1, label: "启用" },
|
|||
|
|
{ value: 0, label: "禁用" }
|
|||
|
|
]}
|
|||
|
|
/>
|
|||
|
|
</Form.Item>
|
|||
|
|
</Form>
|
|||
|
|
</Modal>
|
|||
|
|
</div>
|
|||
|
|
);
|
|||
|
|
}
|