R39: 完成员工档案汇报链查询
这个提交包含在:
@@ -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: {
|
||||
|
||||
@@ -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>
|
||||
|
||||
在新工单中引用
屏蔽一个用户