文件
hyb-oa/client/src/api/portal.ts
T
wangsli 5d8cdf12b4
ci-e2e / e2e (push) Canceled after 0s
ci-minimal / check-minimal (push) Canceled after 0s
fix: 隔离门户待办身份并取消旧请求(09-11-reimbursement-payment-handoffs)
2026-09-11 20:21:46 +08:00

128 行
3.9 KiB
TypeScript

import { apiRequestData } from "./http";
export type PortalRecentActivity = {
id: string;
type:
| "reimbursement.submit"
| "reimbursement.approve"
| "reimbursement.reject"
| "leave.submit"
| "leave.approve"
| "leave.reject"
| "attendance.clock_in"
| "attendance.clock_out"
| "attendance.supplement"
| "asset.assign"
| "asset.return";
actorName: string;
summary: string;
createdAt: string;
href: string;
};
export type PortalTeamStatusItem = {
employeeId: string;
name: string;
avatarUrl: string | null;
presenceStatus: string | null;
attendanceClockIn: string | null;
attendanceClockOut: string | null;
onLeave: boolean;
leaveType: string | null;
};
export type PortalHomePayload = {
workspace: {
id: string | null;
persisted: boolean;
profile: "small_team_internal";
};
greeting: { name: string };
cards: Array<{ key: string; title: string; value: string | number; href: string; severity?: "normal" | "warning" | "high" }>;
pendingTasks: { count: number; href: string };
myApplications: Array<{ domain: string; count: number; href: string }>;
riskSummary: { openCount: number; href: string } | null;
announcements: Array<{ id: string; title: string; summary: string; href: string | null }>;
quickLinks: Array<{ key: string; title: string; href: string }>;
todayPresence: { date: string; status: string | null; label: string; note: string | null; href: string } | null;
teamPresence:
| ({ date: string; href: string } & {
office: number;
remote: number;
out: number;
travel: number;
leave: number;
unspecified: number;
total: number;
})
| null;
weeklyReport: { weekStart: string; status: "draft" | "submitted"; needsHelp: boolean; href: string } | null;
weeklySummary: { weekStart: string; submittedCount: number; missingCount: number; needsHelpCount: number; href: string } | null;
todoSummary: { openCount: number; highPriorityCount: number; href: string } | null;
projectSummary:
| {
myCount: number;
overdueMilestonesCount: number;
highPriorityTaskCount: number;
openRiskCount: number;
followUpDueTodayCount: number;
closurePendingProjectCount: number;
href: string;
}
| null;
peopleLifecycle: { onboardingCount: number; offboardingCount: number; assetReturnPendingCount: number; href: string } | null;
roleCapabilities?: {
canSubmitApplications: boolean;
canApproveTasks: boolean;
canUseFinance: boolean;
canManageSystem: boolean;
canViewTeam: boolean;
isAdminOnly: boolean;
};
businessHandoffs?: {
total: number;
items: Array<{
key: string;
kind: "reimbursement_edit" | "reimbursement_batch" | "payment_review" | "payment_execute";
reference: string | null;
title: string;
nextStep: string;
ownerLabel: string;
href: string;
mobileHref: string;
}>;
};
financeSummary?: {
pendingBatchCount: number;
failedItemCount: number;
riskCount: number;
paymentBatchEnabled?: boolean;
href: string;
} | null;
adoptionSummary:
| {
activeEmployeeCount: number;
login7dCount: number;
weeklySubmittedCount: number;
weeklyMissingCount: number;
presenceUpdatedCount: number;
presenceMissingCount: number;
announcementCount: number;
login7dRate: number;
weeklySubmissionRate: number;
presenceCoverageRate: number;
hints: string[];
}
| null;
recentActivities: PortalRecentActivity[];
teamStatusBoard: PortalTeamStatusItem[];
};
export async function fetchPortalHome(signal?: AbortSignal) {
return apiRequestData<PortalHomePayload>("/api/portal/home", { signal });
}
export async function fetchPortalTeamStatus() {
return apiRequestData<PortalTeamStatusItem[]>("/api/portal/team-status");
}