A1/A3/A5/A7/A8 完成员工头像前端、组织架构页与QA回填

这个提交包含在:
2026-03-29 11:29:44 +08:00
父节点 6f9e1d30a2
当前提交 c3873999c2
共修改 15 个文件,包含 971 行新增和 227 行删除
+104 -3
查看文件
@@ -1,6 +1,13 @@
import { apiRequestData } from "./http";
export type EmployeeStatus = "active" | "archived";
export type EmployeeContractType = "labor" | "nda" | "non_compete" | "internship";
export type EmployeeContractStatus = "active" | "expired" | "terminated";
export type EmployeeDepartmentSummary = {
id: string;
name: string;
};
export type EmployeeSummary = {
id: string;
@@ -12,6 +19,7 @@ export type EmployeeSummary = {
departmentId: string;
directManagerId: string | null;
title: string;
avatarUrl: string | null;
roleCodes: string[];
createdAt: string | null;
updatedAt: string | null;
@@ -61,7 +69,46 @@ export type EmployeeOrganizationNode = {
name: string;
title: string;
status: EmployeeStatus;
department: { id: string; name: string } | null;
avatarUrl: string | null;
department: EmployeeDepartmentSummary | null;
};
export type EmployeeContract = {
id: string;
employeeId: string;
contractNo: string;
contractType: EmployeeContractType;
startDate: string | null;
endDate: string | null;
terminatedDate: string | null;
attachmentPath: string | null;
status: EmployeeContractStatus;
createdAt: string | null;
createdBy: string | null;
updatedAt: string | null;
updatedBy: string | null;
};
export type OrganizationTreeNode = {
id: string;
employeeNo: string;
name: string;
title: string;
status: EmployeeStatus;
avatarUrl: string | null;
department: EmployeeDepartmentSummary | null;
externalManager: {
id: string;
employeeNo: string;
name: string;
department: EmployeeDepartmentSummary | null;
} | null;
children: OrganizationTreeNode[];
};
export type OrganizationDepartmentSection = {
department: EmployeeDepartmentSummary | null;
roots: OrganizationTreeNode[];
};
export type EmployeeProfile = {
@@ -83,10 +130,11 @@ export type EmployeeProfile = {
emergencyContactName: string | null;
emergencyContactPhone: string | null;
notes: string | null;
avatarUrl: string | null;
archivedAt: string | null;
roleCodes: string[];
department: { id: string; name: string } | null;
directManager: { id: string; employeeNo: string; name: string } | null;
department: EmployeeDepartmentSummary | null;
directManager: { id: string; employeeNo: string; name: string; avatarUrl: string | null } | null;
};
lifecycle: {
events: EmployeeLifecycleEvent[];
@@ -131,6 +179,16 @@ export async function fetchEmployeeProfile(employeeId: string) {
return apiRequestData<EmployeeProfile>(`/api/employees/${employeeId}/profile`);
}
export async function uploadEmployeeAvatar(employeeId: string, file: File) {
const formData = new FormData();
formData.append("file", file);
return apiRequestData<{ employeeId: string; avatarUrl: string | null }>(`/api/employees/${employeeId}/avatar`, {
method: "PUT",
body: formData,
});
}
export async function patchEmployeeProfile(
employeeId: string,
payload: Partial<{
@@ -202,6 +260,49 @@ export async function fetchEmployeeLifecycle(employeeId: string) {
return apiRequestData<EmployeeProfile["lifecycle"]>(`/api/employees/${employeeId}/lifecycle`);
}
export async function fetchEmployeeOrganization() {
return apiRequestData<{ items: OrganizationDepartmentSection[] }>("/api/employees/organization");
}
export async function fetchEmployeeContracts(employeeId: string) {
return apiRequestData<{ items: EmployeeContract[] }>(`/api/employees/${employeeId}/contracts`);
}
export async function createEmployeeContract(
employeeId: string,
payload: {
contractNo: string;
contractType: EmployeeContractType;
startDate: string;
endDate: string;
terminatedDate?: string | null;
attachmentPath?: string | null;
},
) {
return apiRequestData<EmployeeContract>(`/api/employees/${employeeId}/contracts`, {
method: "POST",
body: JSON.stringify(payload),
});
}
export async function patchEmployeeContract(
employeeId: string,
contractId: string,
payload: Partial<{
contractNo: string;
contractType: EmployeeContractType;
startDate: string;
endDate: string;
terminatedDate: string | null;
attachmentPath: string | null;
}>,
) {
return apiRequestData<EmployeeContract>(`/api/employees/${employeeId}/contracts/${contractId}`, {
method: "PATCH",
body: JSON.stringify(payload),
});
}
export async function completeEmployeeChecklistTask(employeeId: string, taskId: string) {
return apiRequestData<EmployeeProfile["lifecycle"]>(`/api/employees/${employeeId}/checklist-tasks/${taskId}/complete`, {
method: "POST",
+1
查看文件
@@ -21,6 +21,7 @@ export type PresenceEmployee = {
employeeNo: string;
name: string;
title: string;
avatarUrl: string | null;
employmentStatus: string;
department: { id: string; name: string } | null;
};