import { Link } from "react-router-dom"; import { useQuery } from "@tanstack/react-query"; import { fetchEmployeeStats, type EmployeeEmploymentStatus } from "../api/employees"; import { PageHeader } from "../components/common/PageHeader"; import { Button } from "../components/ui/button"; const EMPLOYMENT_STATUS_LABELS: Record = { onboarding: "待入职", probation: "试用期", active: "在职", offboarding: "离职办理中", inactive: "已离职", }; function employmentStatusLabel(status: EmployeeEmploymentStatus) { return EMPLOYMENT_STATUS_LABELS[status] ?? status; } function moneyText(value: number | null | undefined) { return value == null ? "-" : value.toFixed(2); } export function PeopleStatsPage() { const statsQuery = useQuery({ queryKey: ["employee-stats"], queryFn: fetchEmployeeStats, }); if (statsQuery.isLoading) { return
加载员工统计中...
; } if (statsQuery.isError || !statsQuery.data) { return
加载员工统计失败
; } const stats = statsQuery.data; const salarySummary = stats.salarySummary; return (
返回人员管理 } />
在职人数
{stats.employmentStatusSummary.total}
按 active 账号员工汇总
近 30 天入职
{stats.recentMovements.hires}
{stats.recentMovements.dateFrom} 至 {stats.recentMovements.dateTo}
近 30 天离职
{stats.recentMovements.departures}
{stats.recentMovements.dateFrom} 至 {stats.recentMovements.dateTo}
30 天内合同到期
{stats.expiringContracts.count}
{stats.expiringContracts.dateFrom} 至 {stats.expiringContracts.dateTo}
持有效证书人数
{stats.certificateSummary.validHolderCount}
按 active 员工去重统计有效证书持有人
30 天内证书到期
{stats.certificateSummary.expiringSoonCount}
{stats.certificateSummary.dateFrom} 至 {stats.certificateSummary.dateTo}
{salarySummary ? (
当月薪资总支出
{moneyText(salarySummary.currentMonth?.totalNetAmount)}
{salarySummary.currentMonth ? `${salarySummary.currentMonth.month} · 已发放 ${salarySummary.currentMonth.issuedCount} 人` : "当月暂无已发放工资条"}
) : null} {salarySummary ? (
当月人均薪资
{moneyText(salarySummary.currentMonth?.averageNetAmount)}
仅统计 issued 工资条实发金额
) : null} {salarySummary ? (
上月薪资总支出
{moneyText(salarySummary.previousMonth?.totalNetAmount)}
{salarySummary.previousMonth ? `${salarySummary.previousMonth.month} · 已发放 ${salarySummary.previousMonth.issuedCount} 人` : "上月暂无已发放工资条"}
) : null} {salarySummary ? (
上月人均薪资
{moneyText(salarySummary.previousMonth?.averageNetAmount)}
非 system.users 不展示任何薪资汇总
) : null}
当前 / 最近周期平均分
{stats.performanceSummary.averageScore == null ? "-" : stats.performanceSummary.averageScore.toFixed(1)}
{stats.performanceSummary.cycle ? `${stats.performanceSummary.cycle.name} · ${stats.performanceSummary.cycle.startDate} 至 ${stats.performanceSummary.cycle.endDate}` : "暂无可展示的绩效周期"}
当前 / 最近周期已评分人数
{stats.performanceSummary.reviewedCount}
只统计当前 active 或最近 completed 周期

雇用状态分布

按当前 active 账号员工的 employment status 聚合。

{stats.employmentStatusSummary.items.length ? ( stats.employmentStatusSummary.items.map((item) => (
{employmentStatusLabel(item.status)}
{item.count}
)) ) : (
暂无雇用状态统计。
)}

部门人数分布

按当前 active 账号员工的部门归属统计。

{stats.departmentHeadcount.length ? ( stats.departmentHeadcount.map((item) => (
{item.departmentName}
{item.count}
)) ) : (
暂无部门人数统计。
)}

绩效评分分布

按当前 active 周期或最近 completed 周期的总分分布汇总。

{stats.performanceSummary.cycle && stats.performanceSummary.distribution.length ? ( stats.performanceSummary.distribution.map((item) => (
{item.score.toFixed(1)} 分
{item.count}
)) ) : (
暂无绩效周期统计。
)}
); } export default PeopleStatsPage;