diff --git a/frontend/src/api/usr.ts b/frontend/src/api/usr.ts index 91c3086..0918529 100644 --- a/frontend/src/api/usr.ts +++ b/frontend/src/api/usr.ts @@ -72,3 +72,22 @@ export interface PageVO { export function getUserList(params?: UserListQueryReq): Promise> { return request.get('/usr/users', { params }) } + +export interface UserUpdateReq { + userType: string + language: string + canEditDoc: boolean + isDisabled: boolean + employeeId: string | null + permGroupIds: string[] +} + +export interface UserUpdateResp { + userId: string + username: string + updatedAt: string +} + +export function updateUser(userId: string, req: UserUpdateReq): Promise { + return request.put(`/usr/users/${userId}`, req) +} diff --git a/frontend/src/pages/usr/UserFormDrawer.tsx b/frontend/src/pages/usr/UserFormDrawer.tsx index 9d2b503..f15736e 100644 --- a/frontend/src/pages/usr/UserFormDrawer.tsx +++ b/frontend/src/pages/usr/UserFormDrawer.tsx @@ -3,25 +3,50 @@ import { Drawer, Form, Input, Select, Checkbox, Button, message, Table } from 'antd' import type { ColumnsType } from 'antd/es/table' -import { getStaffs, getPermissionGroups, createUser, StaffVO, PermissionGroupVO, UserCreateReq } from '../../api/usr' +import { getStaffs, getPermissionGroups, createUser, updateUser, StaffVO, PermissionGroupVO, UserCreateReq, UserUpdateReq } from '../../api/usr' + +interface InitialData { + userType: string + language: string + canEditDoc: boolean + isDisabled: boolean + employeeId?: string | null +} interface Props { open: boolean onClose: () => void onSuccess: () => void + userId?: string + initialData?: InitialData } -export default function UserFormDrawer({ open, onClose, onSuccess }: Props) { +export default function UserFormDrawer({ open, onClose, onSuccess, userId, initialData }: Props) { const [form] = Form.useForm() const [staffs, setStaffs] = useState([]) const [permGroups, setPermGroups] = useState([]) const [selectedPermIds, setSelectedPermIds] = useState([]) const [submitting, setSubmitting] = useState(false) + const isEditMode = !!userId + useEffect(() => { if (open) { getStaffs().then(setStaffs).catch(() => {}) getPermissionGroups().then(setPermGroups).catch(() => {}) + if (isEditMode && initialData) { + form.setFieldsValue({ + userType: initialData.userType, + language: initialData.language, + canEditDoc: initialData.canEditDoc, + isDisabled: initialData.isDisabled, + employeeId: initialData.employeeId ?? null, + }) + setSelectedPermIds([]) + } else { + form.resetFields() + setSelectedPermIds([]) + } } }, [open]) @@ -49,17 +74,30 @@ export default function UserFormDrawer({ open, onClose, onSuccess }: Props) { try { const values = await form.validateFields() setSubmitting(true) - const req: UserCreateReq = { - userCode: values.userCode, - username: values.username, - userType: values.userType, - language: values.language, - canEditDoc: values.canEditDoc ?? false, - employeeId: values.employeeId ?? null, - permGroupIds: selectedPermIds + if (isEditMode) { + const req: UserUpdateReq = { + userType: values.userType, + language: values.language, + canEditDoc: values.canEditDoc ?? false, + isDisabled: values.isDisabled ?? false, + employeeId: values.employeeId ?? null, + permGroupIds: selectedPermIds + } + await updateUser(userId, req) + message.success('修改用户成功') + } else { + const req: UserCreateReq = { + userCode: values.userCode, + username: values.username, + userType: values.userType, + language: values.language, + canEditDoc: values.canEditDoc ?? false, + employeeId: values.employeeId ?? null, + permGroupIds: selectedPermIds + } + await createUser(req) + message.success('新增用户成功') } - await createUser(req) - message.success('新增用户成功') form.resetFields() setSelectedPermIds([]) onSuccess() @@ -74,7 +112,7 @@ export default function UserFormDrawer({ open, onClose, onSuccess }: Props) { return (
- - - - - - + {!isEditMode && ( + <> + + + + + + + + )} = [ - { title: '用户名', dataIndex: 'sUsername' }, - { title: '员工名', dataIndex: 'sStaffName' }, - { title: '用户号', dataIndex: 'sUserCode' }, - { title: '部门', dataIndex: 'sDepartment' }, - { title: '用户类型', dataIndex: 'sUserType' }, - { title: '语言', dataIndex: 'sLanguage' }, - { title: '作废', dataIndex: 'bIsDisabled', render: (v: number) => v ? '是' : '否' }, - { title: '登录日期', dataIndex: 'tLastLoginDate' }, - { title: '制单人', dataIndex: 'sCreatorUsername' }, - { title: '制单日期', dataIndex: 'tCreateDate' }, -] - // REQ-USR-003: 查询用户 +// REQ-USR-002: 修改用户 export default function UserListPage() { const [drawerOpen, setDrawerOpen] = useState(false) + const [editingUser, setEditingUser] = useState(null) const [data, setData] = useState | null>(null) const [queryField, setQueryField] = useState('username') const [matchType, setMatchType] = useState('contains') @@ -54,6 +43,32 @@ export default function UserListPage() { load() }, []) + const columns: ColumnsType = [ + { title: '用户名', dataIndex: 'sUsername' }, + { title: '员工名', dataIndex: 'sStaffName' }, + { title: '用户号', dataIndex: 'sUserCode' }, + { title: '部门', dataIndex: 'sDepartment' }, + { title: '用户类型', dataIndex: 'sUserType' }, + { title: '语言', dataIndex: 'sLanguage' }, + { title: '作废', dataIndex: 'bIsDisabled', render: (v: number) => v ? '是' : '否' }, + { title: '登录日期', dataIndex: 'tLastLoginDate' }, + { title: '制单人', dataIndex: 'sCreatorUsername' }, + { title: '制单日期', dataIndex: 'tCreateDate' }, + { + title: '操作', + key: 'action', + render: (_, record) => ( + setEditingUser(record)} + > + 修改 + + ) + }, + ] + return (
@@ -100,6 +115,19 @@ export default function UserListPage() { onClose={() => setDrawerOpen(false)} onSuccess={() => { setDrawerOpen(false); load(1) }} /> + setEditingUser(null)} + onSuccess={() => { setEditingUser(null); load(1) }} + />
) } diff --git a/frontend/src/test/UserListPage.test.tsx b/frontend/src/test/UserListPage.test.tsx index 17b0823..16206a6 100644 --- a/frontend/src/test/UserListPage.test.tsx +++ b/frontend/src/test/UserListPage.test.tsx @@ -11,7 +11,8 @@ vi.mock('../api/usr', () => ({ getStaffs: vi.fn().mockResolvedValue([]), getPermissionGroups: vi.fn().mockResolvedValue([]), createUser: vi.fn(), - getUserList: vi.fn().mockResolvedValue({ total: 0, page: 1, pageSize: 20, list: [] }) + getUserList: vi.fn().mockResolvedValue({ total: 0, page: 1, pageSize: 20, list: [] }), + updateUser: vi.fn().mockResolvedValue({ userId: 'u1', username: 'alice', updatedAt: '2026-05-08T10:00:00' }) })) vi.mock('../api/request', () => ({ @@ -85,4 +86,23 @@ describe('UserListPage', () => { await userEvent.click(screen.getByRole('button', { name: /搜\s*索|搜索/ })) await waitFor(() => expect(vi.mocked(getUserList)).toHaveBeenCalledTimes(2)) }) + + it('editMode_submit_callsUpdateUser', async () => { + const { getUserList, updateUser } = await import('../api/usr') + vi.mocked(getUserList).mockResolvedValue({ + total: 1, page: 1, pageSize: 20, + list: [{ + sId: 'u1', sUsername: 'alice', sUserCode: 'UC001', sUserType: '普通用户', + sLanguage: '中文', bIsDisabled: 0, tLastLoginDate: null, + sCreatorUsername: 'admin', tCreateDate: '2026-01-01T00:00:00', + sStaffName: null, sDepartment: null + }] + }) + renderPage('超级管理员') + await waitFor(() => expect(screen.getByText('alice')).toBeInTheDocument()) + await userEvent.click(screen.getByRole('button', { name: /修改/ })) + await waitFor(() => expect(screen.getByText('修改用户')).toBeInTheDocument()) + await userEvent.click(screen.getByRole('button', { name: /确\s*认/ })) + await waitFor(() => expect(vi.mocked(updateUser)).toHaveBeenCalledTimes(1)) + }) })