R44 A2-A8 完成员工高级筛选批量操作与统计页
这个提交包含在:
+101
-3
@@ -1,6 +1,7 @@
|
||||
import { apiRequestData } from "./http";
|
||||
|
||||
export type EmployeeStatus = "active" | "archived";
|
||||
export type EmployeeEmploymentStatus = "onboarding" | "probation" | "active" | "offboarding" | "inactive";
|
||||
export type EmployeeContractType = "labor" | "nda" | "non_compete" | "internship";
|
||||
export type EmployeeContractStatus = "active" | "expired" | "terminated";
|
||||
|
||||
@@ -17,8 +18,12 @@ export type EmployeeSummary = {
|
||||
email: string;
|
||||
status: EmployeeStatus;
|
||||
departmentId: string;
|
||||
department: EmployeeDepartmentSummary | null;
|
||||
directManagerId: string | null;
|
||||
directManager: { id: string; employeeNo: string; name: string } | null;
|
||||
title: string;
|
||||
employmentStatus: EmployeeEmploymentStatus | null;
|
||||
hireDate: string | null;
|
||||
avatarUrl: string | null;
|
||||
roleCodes: string[];
|
||||
createdAt: string | null;
|
||||
@@ -119,7 +124,7 @@ export type EmployeeProfile = {
|
||||
phone: string;
|
||||
email: string;
|
||||
status: EmployeeStatus;
|
||||
employmentStatus: "onboarding" | "probation" | "active" | "offboarding" | "inactive";
|
||||
employmentStatus: EmployeeEmploymentStatus;
|
||||
departmentId: string;
|
||||
title: string;
|
||||
directManagerId: string | null;
|
||||
@@ -158,19 +163,80 @@ export type EmployeeProfile = {
|
||||
};
|
||||
};
|
||||
|
||||
export async function fetchEmployees(params: {
|
||||
export type FetchEmployeesParams = {
|
||||
page: number;
|
||||
pageSize: number;
|
||||
status?: EmployeeStatus;
|
||||
departmentId?: string;
|
||||
q?: string;
|
||||
}) {
|
||||
title?: string;
|
||||
managerId?: string;
|
||||
hireDateFrom?: string;
|
||||
hireDateTo?: string;
|
||||
employmentStatus?: EmployeeEmploymentStatus;
|
||||
};
|
||||
|
||||
export type BatchOperationResult = {
|
||||
summary: {
|
||||
total: number;
|
||||
updated: number;
|
||||
};
|
||||
employeeIds: string[];
|
||||
};
|
||||
|
||||
export type EmployeeStatsResponse = {
|
||||
asOfDate: string;
|
||||
employmentStatusSummary: {
|
||||
total: number;
|
||||
items: Array<{
|
||||
status: EmployeeEmploymentStatus;
|
||||
count: number;
|
||||
}>;
|
||||
};
|
||||
departmentHeadcount: Array<{
|
||||
departmentId: string;
|
||||
departmentName: string;
|
||||
count: number;
|
||||
}>;
|
||||
recentMovements: {
|
||||
dateFrom: string;
|
||||
dateTo: string;
|
||||
hires: number;
|
||||
departures: number;
|
||||
};
|
||||
expiringContracts: {
|
||||
dateFrom: string;
|
||||
dateTo: string;
|
||||
count: number;
|
||||
};
|
||||
};
|
||||
|
||||
export type BatchTransferDepartmentPayload = {
|
||||
employeeIds: string[];
|
||||
departmentId: string;
|
||||
};
|
||||
|
||||
export type BatchToggleUsersPayload = {
|
||||
employeeIds: string[];
|
||||
};
|
||||
|
||||
export type BatchSetManagerPayload = {
|
||||
employeeIds: string[];
|
||||
managerId: string;
|
||||
};
|
||||
|
||||
export async function fetchEmployees(params: FetchEmployeesParams) {
|
||||
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.departmentId) search.set("departmentId", params.departmentId);
|
||||
if (params.q) search.set("q", params.q);
|
||||
if (params.title) search.set("title", params.title);
|
||||
if (params.managerId) search.set("managerId", params.managerId);
|
||||
if (params.hireDateFrom) search.set("hireDateFrom", params.hireDateFrom);
|
||||
if (params.hireDateTo) search.set("hireDateTo", params.hireDateTo);
|
||||
if (params.employmentStatus) search.set("employmentStatus", params.employmentStatus);
|
||||
|
||||
return apiRequestData<EmployeeListResponse>(`/api/employees?${search.toString()}`);
|
||||
}
|
||||
@@ -264,6 +330,10 @@ export async function fetchEmployeeOrganization() {
|
||||
return apiRequestData<{ items: OrganizationDepartmentSection[] }>("/api/employees/organization");
|
||||
}
|
||||
|
||||
export async function fetchEmployeeStats() {
|
||||
return apiRequestData<EmployeeStatsResponse>("/api/employees/stats");
|
||||
}
|
||||
|
||||
export async function fetchEmployeeContracts(employeeId: string) {
|
||||
return apiRequestData<{ items: EmployeeContract[] }>(`/api/employees/${employeeId}/contracts`);
|
||||
}
|
||||
@@ -316,3 +386,31 @@ export async function skipEmployeeChecklistTask(employeeId: string, taskId: stri
|
||||
body: JSON.stringify({}),
|
||||
});
|
||||
}
|
||||
|
||||
export async function batchTransferEmployeesDepartment(payload: BatchTransferDepartmentPayload) {
|
||||
return apiRequestData<BatchOperationResult>("/api/users/batch/transfer-department", {
|
||||
method: "POST",
|
||||
body: JSON.stringify(payload),
|
||||
});
|
||||
}
|
||||
|
||||
export async function batchEnableUsers(payload: BatchToggleUsersPayload) {
|
||||
return apiRequestData<BatchOperationResult>("/api/users/batch/enable", {
|
||||
method: "POST",
|
||||
body: JSON.stringify(payload),
|
||||
});
|
||||
}
|
||||
|
||||
export async function batchDisableUsers(payload: BatchToggleUsersPayload) {
|
||||
return apiRequestData<BatchOperationResult>("/api/users/batch/disable", {
|
||||
method: "POST",
|
||||
body: JSON.stringify(payload),
|
||||
});
|
||||
}
|
||||
|
||||
export async function batchSetEmployeesManager(payload: BatchSetManagerPayload) {
|
||||
return apiRequestData<BatchOperationResult>("/api/users/batch/set-manager", {
|
||||
method: "POST",
|
||||
body: JSON.stringify(payload),
|
||||
});
|
||||
}
|
||||
|
||||
在新工单中引用
屏蔽一个用户