文件
hyb-oa/client/src/api/presence.ts
T

159 行
4.7 KiB
TypeScript

import { apiRequestBlob, apiRequestData, type ApiBlobResponse } from "./http";
export type PresenceStatus = "office" | "remote" | "out" | "travel" | "leave";
export type PresenceTimeRange = "full_day" | "morning" | "afternoon";
export type PresenceSource = "manual" | "leave_sync" | "admin_override";
export type PresenceHistoryStatusFilter = PresenceStatus | "unspecified";
export type PresenceItem = {
id: string;
employeeId: string;
date: string;
status: PresenceStatus;
timeRange: PresenceTimeRange;
note: string | null;
source: PresenceSource;
updatedAt: string | null;
};
export type PresenceEmployee = {
id: string;
employeeNo: string;
name: string;
title: string;
avatarUrl: string | null;
employmentStatus: string;
department: { id: string; name: string } | null;
};
export type TeamPresenceItem = {
employee: PresenceEmployee;
presence: PresenceItem | null;
};
export type MyPresenceHistoryItem = {
date: string;
presence: PresenceItem | null;
};
export type TeamPresenceHistoryItem = {
date: string;
employee: PresenceEmployee;
presence: PresenceItem | null;
};
export type PresenceSummary = {
office: number;
remote: number;
out: number;
travel: number;
leave: number;
unspecified: number;
total: number;
};
export type MyPresenceHistoryResponse = {
dateFrom: string;
dateTo: string;
summary: PresenceSummary;
items: MyPresenceHistoryItem[];
};
export type TeamPresenceHistoryResponse = {
dateFrom: string;
dateTo: string;
summary: PresenceSummary;
items: TeamPresenceHistoryItem[];
};
export async function fetchMyPresence(date?: string) {
const suffix = date ? `?date=${encodeURIComponent(date)}` : "";
return apiRequestData<{ item: PresenceItem | null; date: string }>(`/api/presence/me${suffix}`);
}
export async function upsertMyPresence(payload: {
date?: string;
status: Extract<PresenceStatus, "office" | "remote" | "out" | "travel">;
timeRange?: PresenceTimeRange;
note?: string | null;
}) {
return apiRequestData<{ item: PresenceItem }>("/api/presence/me", {
method: "PUT",
body: JSON.stringify(payload),
});
}
export async function fetchTeamPresence(date?: string) {
const suffix = date ? `?date=${encodeURIComponent(date)}` : "";
return apiRequestData<{ date: string; summary: PresenceSummary; items: TeamPresenceItem[] }>(`/api/presence/team${suffix}`);
}
export async function fetchMyPresenceHistory(params: {
dateFrom?: string;
dateTo?: string;
}) {
const search = new URLSearchParams();
if (params.dateFrom) search.set("dateFrom", params.dateFrom);
if (params.dateTo) search.set("dateTo", params.dateTo);
const query = search.toString();
return apiRequestData<MyPresenceHistoryResponse>(`/api/presence/me/history${query ? `?${query}` : ""}`);
}
export async function fetchTeamPresenceHistory(params: {
dateFrom?: string;
dateTo?: string;
departmentId?: string;
employeeId?: string;
status?: PresenceHistoryStatusFilter;
}) {
const search = new URLSearchParams();
if (params.dateFrom) search.set("dateFrom", params.dateFrom);
if (params.dateTo) search.set("dateTo", params.dateTo);
if (params.departmentId) search.set("departmentId", params.departmentId);
if (params.employeeId) search.set("employeeId", params.employeeId);
if (params.status) search.set("status", params.status);
const query = search.toString();
return apiRequestData<TeamPresenceHistoryResponse>(`/api/presence/team/history${query ? `?${query}` : ""}`);
}
export async function fetchPresenceSummary(date?: string) {
const suffix = date ? `?date=${encodeURIComponent(date)}` : "";
return apiRequestData<{ date: string; summary: PresenceSummary }>(`/api/presence/summary${suffix}`);
}
export async function exportPresenceHistory(params: {
format: "csv" | "xlsx";
dateFrom?: string;
dateTo?: string;
departmentId?: string;
employeeId?: string;
status?: PresenceHistoryStatusFilter;
}): Promise<ApiBlobResponse> {
const search = new URLSearchParams();
search.set("format", params.format);
if (params.dateFrom) search.set("dateFrom", params.dateFrom);
if (params.dateTo) search.set("dateTo", params.dateTo);
if (params.departmentId) search.set("departmentId", params.departmentId);
if (params.employeeId) search.set("employeeId", params.employeeId);
if (params.status) search.set("status", params.status);
return apiRequestBlob(`/api/exports/presence-history?${search.toString()}`);
}
export async function patchTeamPresence(
employeeId: string,
payload: {
date: string;
status: Extract<PresenceStatus, "office" | "remote" | "out" | "travel">;
timeRange?: PresenceTimeRange;
note?: string | null;
},
) {
return apiRequestData<{ item: PresenceItem }>(`/api/presence/team/${employeeId}`, {
method: "PUT",
body: JSON.stringify(payload),
});
}