imeeting/frontend/src/pages/Roles.tsx

162 lines
4.8 KiB
TypeScript
Raw Normal View History

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>
);
}