R46 A1-A7:落地绩效考核模块首版

这个提交包含在:
2026-03-29 16:30:29 +08:00
父节点 48f395e18d
当前提交 659e3153a3
共修改 19 个文件,包含 2652 行新增和 15 行删除
+128
查看文件
@@ -0,0 +1,128 @@
import { apiRequestData } from "./http";
import type { EmployeeDepartmentSummary, EmployeeStatus } from "./employees";
export type PerformanceReviewCycleType = "monthly" | "quarterly" | "semi_annual" | "annual";
export type PerformanceReviewCycleStatus = "draft" | "active" | "completed";
export type PerformanceReviewDimensionType =
| "work_quality"
| "work_efficiency"
| "teamwork"
| "initiative"
| "professional_skill";
export type PerformanceEmployeeSummary = {
id: string;
employeeNo: string;
name: string;
title: string;
status: EmployeeStatus;
avatarUrl: string | null;
department: EmployeeDepartmentSummary | null;
};
export type PerformanceReviewCycle = {
id: string;
name: string;
cycleType: PerformanceReviewCycleType;
status: PerformanceReviewCycleStatus;
startDate: string | null;
endDate: string | null;
activatedAt: string | null;
completedAt: string | null;
createdAt: string | null;
createdBy: string | null;
updatedAt: string | null;
updatedBy: string | null;
};
export type PerformanceReviewDimension = {
dimensionType: PerformanceReviewDimensionType;
score: number;
};
export type PerformanceReview = {
id: string;
cycleId: string;
employeeId: string;
reviewerEmployeeId: string;
overallScore: number;
comment: string | null;
reviewer: {
id: string;
employeeNo: string;
name: string;
} | null;
dimensions: PerformanceReviewDimension[];
createdAt: string | null;
createdBy: string | null;
updatedAt: string | null;
updatedBy: string | null;
};
export type PerformanceCycleOverview = {
cycle: PerformanceReviewCycle;
items: Array<{
employee: PerformanceEmployeeSummary;
review: PerformanceReview | null;
}>;
};
export type PerformanceEmployeeReviewTimeline = {
employee: PerformanceEmployeeSummary;
viewerRole: "self" | "manager" | "admin";
items: Array<{
cycle: PerformanceReviewCycle;
review: PerformanceReview | null;
canEdit: boolean;
}>;
};
export type CreatePerformanceCyclePayload = {
name: string;
cycleType: PerformanceReviewCycleType;
startDate: string;
endDate: string;
};
export type PatchPerformanceCyclePayload = Partial<CreatePerformanceCyclePayload> & {
status?: PerformanceReviewCycleStatus;
};
export type UpsertPerformanceReviewPayload = {
overallScore: number;
comment?: string | null;
dimensions?: PerformanceReviewDimension[];
};
export async function fetchPerformanceCycles() {
return apiRequestData<{ items: PerformanceReviewCycle[] }>("/api/performance/cycles");
}
export async function createPerformanceCycle(payload: CreatePerformanceCyclePayload) {
return apiRequestData<PerformanceReviewCycle>("/api/performance/cycles", {
method: "POST",
body: JSON.stringify(payload),
});
}
export async function patchPerformanceCycle(cycleId: string, payload: PatchPerformanceCyclePayload) {
return apiRequestData<PerformanceReviewCycle>(`/api/performance/cycles/${cycleId}`, {
method: "PATCH",
body: JSON.stringify(payload),
});
}
export async function fetchPerformanceCycleOverview(cycleId: string) {
return apiRequestData<PerformanceCycleOverview>(`/api/performance/cycles/${cycleId}/reviews`);
}
export async function fetchEmployeePerformanceTimeline(employeeId: string) {
return apiRequestData<PerformanceEmployeeReviewTimeline>(`/api/performance/employees/${employeeId}/reviews`);
}
export async function upsertPerformanceReview(cycleId: string, employeeId: string, payload: UpsertPerformanceReviewPayload) {
return apiRequestData<PerformanceReview>(`/api/performance/cycles/${cycleId}/reviews/${employeeId}`, {
method: "PUT",
body: JSON.stringify(payload),
});
}