feat: 支持表格单元格快捷编辑
Some checks failed
CI 检查 / lint (pull_request) Has been cancelled
CI 检查 / typecheck (pull_request) Has been cancelled
CI 检查 / test (pull_request) Has been cancelled

This commit is contained in:
2026-07-21 14:17:08 +08:00
parent fe0b71a0a9
commit a585fd42d5
17 changed files with 2197 additions and 303 deletions

View File

@@ -10,6 +10,7 @@ import {
import dayjs from 'dayjs';
import api from '../../api';
import PermissionButton from '../../components/PermissionButton';
import EditableCell from '../../components/EditableCell';
import { message } from '../../ui/app-message';
import { userProfileResponseToFormValues, type UserProfileResponse } from './user-profile-form';
@@ -153,31 +154,94 @@ const UsersPage: React.FC = () => {
}
};
const saveCell = useCallback(
async (record: any, field: string, value: unknown) => {
await api.put(`/rbac/users/${record.id}`, { [field]: value });
message.success('已保存');
await fetchData();
},
[fetchData],
);
const columns = useMemo(
() => [
{ title: 'ID', dataIndex: 'id', width: 60 },
{ title: '用户名', dataIndex: 'username', width: 120 },
{ title: '名', dataIndex: 'name', width: 120 },
{
title: '用户名',
dataIndex: 'username',
width: 120,
render: (v: string, r: any) => (
<EditableCell
value={v}
required
permission="user:edit"
disabled={r.isArchived}
onSave={(next) => saveCell(r, 'username', next)}
>
{v}
</EditableCell>
),
},
{
title: '姓名',
dataIndex: 'name',
width: 120,
render: (v: string, r: any) => (
<EditableCell
value={v}
required
permission="user:edit"
disabled={r.isArchived}
onSave={(next) => saveCell(r, 'name', next)}
>
{v}
</EditableCell>
),
},
{
title: '角色',
dataIndex: 'roles',
width: 200,
render: (v: any[]) =>
v && v.length > 0 ? (
v.map((r: any) => (
<Tag key={r.id} color="blue">
{r.name}
</Tag>
))
) : (
<Tag color="default"></Tag>
),
render: (v: any[], record: any) => (
<EditableCell
value={v?.map((item) => item.id) || []}
editor="multi-select"
options={roles.map((item) => ({ value: item.id, label: item.name }))}
permission="user:edit"
disabled={record.isArchived}
onSave={(next) => saveCell(record, 'roleIds', next)}
>
{v && v.length > 0 ? (
v.map((r: any) => (
<Tag key={r.id} color="blue">
{r.name}
</Tag>
))
) : (
<Tag color="default"></Tag>
)}
</EditableCell>
),
},
{
title: '状态',
dataIndex: 'isActive',
width: 80,
render: (v: boolean) => <Tag color={v ? 'green' : 'default'}>{v ? '启用' : '禁用'}</Tag>,
render: (v: boolean, r: any) => (
<EditableCell
value={String(v)}
editor="select"
options={[
{ value: 'true', label: '启用' },
{ value: 'false', label: '禁用' },
]}
permission="user:edit"
disabled={r.isArchived}
onSave={(next) => saveCell(r, 'isActive', String(next) === 'true')}
>
<Tag color={v ? 'green' : 'default'}>{v ? '启用' : '禁用'}</Tag>
</EditableCell>
),
},
{
title: '最后登录',
@@ -244,7 +308,7 @@ const UsersPage: React.FC = () => {
),
},
],
[],
[roles, saveCell],
);
return (