R47 A1-A8:完成薪资管理模块

这个提交包含在:
2026-03-29 19:05:55 +08:00
父节点 c0384b5bbf
当前提交 7ba72ca87d
共修改 25 个文件,包含 3598 行新增和 4 行删除
+37
查看文件
@@ -16,6 +16,10 @@ 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"],
@@ -31,6 +35,7 @@ export function PeopleStatsPage() {
}
const stats = statsQuery.data;
const salarySummary = stats.salarySummary;
return (
<div className="space-y-6">
@@ -83,6 +88,38 @@ export function PeopleStatsPage() {
{stats.certificateSummary.dateFrom} 至 {stats.certificateSummary.dateTo}
</div>
</section>
{salarySummary ? (
<section className="card-std p-5">
<div className="text-sm text-zinc-500">当月薪资总支出</div>
<div className="mt-2 text-3xl font-semibold text-zinc-900">{moneyText(salarySummary.currentMonth?.totalNetAmount)}</div>
<div className="mt-2 text-xs text-zinc-500">
{salarySummary.currentMonth ? `${salarySummary.currentMonth.month} · 已发放 ${salarySummary.currentMonth.issuedCount} 人` : "当月暂无已发放工资条"}
</div>
</section>
) : null}
{salarySummary ? (
<section className="card-std p-5">
<div className="text-sm text-zinc-500">当月人均薪资</div>
<div className="mt-2 text-3xl font-semibold text-zinc-900">{moneyText(salarySummary.currentMonth?.averageNetAmount)}</div>
<div className="mt-2 text-xs text-zinc-500">仅统计 issued 工资条实发金额</div>
</section>
) : null}
{salarySummary ? (
<section className="card-std p-5">
<div className="text-sm text-zinc-500">上月薪资总支出</div>
<div className="mt-2 text-3xl font-semibold text-zinc-900">{moneyText(salarySummary.previousMonth?.totalNetAmount)}</div>
<div className="mt-2 text-xs text-zinc-500">
{salarySummary.previousMonth ? `${salarySummary.previousMonth.month} · 已发放 ${salarySummary.previousMonth.issuedCount} 人` : "上月暂无已发放工资条"}
</div>
</section>
) : null}
{salarySummary ? (
<section className="card-std p-5">
<div className="text-sm text-zinc-500">上月人均薪资</div>
<div className="mt-2 text-3xl font-semibold text-zinc-900">{moneyText(salarySummary.previousMonth?.averageNetAmount)}</div>
<div className="mt-2 text-xs text-zinc-500">非 system.users 不展示任何薪资汇总</div>
</section>
) : null}
<section className="card-std p-5">
<div className="text-sm text-zinc-500">当前 / 最近周期平均分</div>
<div className="mt-2 text-3xl font-semibold text-zinc-900">