feat(client): 用户管理页 + E2E 门禁(E15/E16/E18)
- 新增系统用户管理页(创建/禁用启用/重置密码/角色) - 引入 Playwright E2E:覆盖登录-报销-待办-票据-OCR-支付-登出 - 新增 ci-e2e 工作流(PR + nightly)
这个提交包含在:
@@ -0,0 +1,83 @@
|
||||
import { apiRequestData } from "./http";
|
||||
|
||||
export type UserStatus = "active" | "archived";
|
||||
|
||||
export type UserSummary = {
|
||||
id: string;
|
||||
employeeNo: string;
|
||||
name: string;
|
||||
phone: string;
|
||||
email: string;
|
||||
status: UserStatus;
|
||||
departmentId: string;
|
||||
title: string;
|
||||
roleCodes: string[];
|
||||
createdAt: string | null;
|
||||
updatedAt: string | null;
|
||||
};
|
||||
|
||||
export type UserListResponse = {
|
||||
page: number;
|
||||
pageSize: number;
|
||||
total: number;
|
||||
items: UserSummary[];
|
||||
};
|
||||
|
||||
export async function fetchUsers(params: {
|
||||
page: number;
|
||||
pageSize: number;
|
||||
status?: UserStatus;
|
||||
q?: string;
|
||||
}) {
|
||||
const search = new URLSearchParams();
|
||||
search.set("page", String(params.page));
|
||||
search.set("pageSize", String(params.pageSize));
|
||||
if (params.status) search.set("status", params.status);
|
||||
if (params.q) search.set("q", params.q);
|
||||
|
||||
return apiRequestData<UserListResponse>(`/api/users?${search.toString()}`);
|
||||
}
|
||||
|
||||
export async function createUser(payload: {
|
||||
employeeNo: string;
|
||||
name: string;
|
||||
phone: string;
|
||||
email: string;
|
||||
password: string;
|
||||
roles: string[];
|
||||
}) {
|
||||
return apiRequestData<UserSummary>("/api/users", {
|
||||
method: "POST",
|
||||
body: JSON.stringify(payload),
|
||||
});
|
||||
}
|
||||
|
||||
export async function disableUser(userId: string) {
|
||||
return apiRequestData<{ id: string; status: UserStatus }>(`/api/users/${userId}/disable`, {
|
||||
method: "POST",
|
||||
});
|
||||
}
|
||||
|
||||
export async function enableUser(userId: string) {
|
||||
return apiRequestData<{ id: string; status: UserStatus }>(`/api/users/${userId}/enable`, {
|
||||
method: "POST",
|
||||
});
|
||||
}
|
||||
|
||||
export async function resetUserPassword(userId: string) {
|
||||
return apiRequestData<{ id: string; oneTimePassword: string }>(
|
||||
`/api/users/${userId}/reset-password`,
|
||||
{
|
||||
method: "POST",
|
||||
body: JSON.stringify({}),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
export async function setUserRoles(userId: string, roles: string[]) {
|
||||
return apiRequestData<{ id: string; roleCodes: string[] }>(`/api/users/${userId}/roles`, {
|
||||
method: "POST",
|
||||
body: JSON.stringify({ roles }),
|
||||
});
|
||||
}
|
||||
|
||||
在新工单中引用
屏蔽一个用户