R39: 完成员工档案汇报链查询

这个提交包含在:
2026-03-28 17:42:09 +08:00
父节点 f33431fdb8
当前提交 1cac1447b1
共修改 6 个文件,包含 347 行新增和 9 行删除
+13
查看文件
@@ -55,6 +55,15 @@ export type EmployeeChecklistTask = {
createdAt: string | null;
};
export type EmployeeOrganizationNode = {
id: string;
employeeNo: string;
name: string;
title: string;
status: EmployeeStatus;
department: { id: string; name: string } | null;
};
export type EmployeeProfile = {
employee: {
id: string;
@@ -95,6 +104,10 @@ export type EmployeeProfile = {
status: string;
location: string | null;
}>;
organization: {
reportingChain: EmployeeOrganizationNode[];
directReports: EmployeeOrganizationNode[];
};
};
export async function fetchEmployees(params: {
+59 -8
查看文件
@@ -106,6 +106,20 @@ export function EmployeeProfilePage() {
return <div className="card-std p-6 text-sm text-zinc-500">加载员工档案中...</div>;
}
const reportingChain = profile.organization.reportingChain.length
? profile.organization.reportingChain
: [
{
id: profile.employee.id,
employeeNo: profile.employee.employeeNo,
name: profile.employee.name,
title: profile.employee.title,
status: profile.employee.status,
department: profile.employee.department,
},
];
const directReports = profile.organization.directReports;
return (
<div className="space-y-6">
<PageHeader
@@ -172,16 +186,53 @@ export function EmployeeProfilePage() {
</div>
</div>
<div className="card-std p-6 space-y-4">
<h3 className="text-base font-semibold text-zinc-900">离职阻塞项</h3>
<div className="rounded-lg border border-zinc-200 p-3 text-sm">
资产未归还:<span className="font-medium text-zinc-900">{profile.lifecycle.blockers.openAssetCount}</span>
<div className="space-y-6">
<div className="card-std p-6 space-y-4">
<h3 className="text-base font-semibold text-zinc-900">离职阻塞项</h3>
<div className="rounded-lg border border-zinc-200 p-3 text-sm">
资产未归还:<span className="font-medium text-zinc-900">{profile.lifecycle.blockers.openAssetCount}</span>
</div>
<div className="rounded-lg border border-zinc-200 p-3 text-sm">
待办审批任务:<span className="font-medium text-zinc-900">{profile.lifecycle.blockers.pendingWorkflowTaskCount}</span>
</div>
<div className="rounded-lg border border-zinc-200 p-3 text-sm">
可完成离职:<span className="font-medium text-zinc-900">{profile.lifecycle.blockers.canCompleteOffboarding ? "是" : "否"}</span>
</div>
</div>
<div className="rounded-lg border border-zinc-200 p-3 text-sm">
待办审批任务:<span className="font-medium text-zinc-900">{profile.lifecycle.blockers.pendingWorkflowTaskCount}</span>
<div className="card-std p-6">
<h3 className="text-base font-semibold text-zinc-900">汇报链</h3>
<div className="mt-4 space-y-3">
{reportingChain.map((item, index) => (
<div key={item.id} className="rounded-lg border border-zinc-200 p-3 text-sm">
<div className="flex items-center justify-between gap-3">
<div className="font-medium text-zinc-900">{item.name}</div>
<StatusBadge status={item.status} />
</div>
<div className="mt-1 text-zinc-500">
{item.employeeNo} · {item.title} · {item.department?.name ?? "-"}
</div>
{index === reportingChain.length - 1 ? <div className="mt-1 text-xs text-zinc-500">当前员工</div> : null}
</div>
))}
</div>
</div>
<div className="rounded-lg border border-zinc-200 p-3 text-sm">
可完成离职:<span className="font-medium text-zinc-900">{profile.lifecycle.blockers.canCompleteOffboarding ? "是" : "否"}</span>
<div className="card-std p-6">
<h3 className="text-base font-semibold text-zinc-900">直属下级</h3>
<div className="mt-4 space-y-3">
{directReports.length ? directReports.map((item) => (
<div key={item.id} className="rounded-lg border border-zinc-200 p-3 text-sm">
<div className="flex items-center justify-between gap-3">
<div className="font-medium text-zinc-900">{item.name}</div>
<StatusBadge status={item.status} />
</div>
<div className="mt-1 text-zinc-500">
{item.employeeNo} · {item.title} · {item.department?.name ?? "-"}
</div>
</div>
)) : <div className="text-sm text-zinc-500">暂无直属下级</div>}
</div>
</div>
</div>
</div>