R47 A1-A8:完成薪资管理模块
这个提交包含在:
@@ -36,6 +36,7 @@ import { hasPermission } from "../auth/permissions";
|
||||
import { EmployeeAvatar } from "../components/common/EmployeeAvatar";
|
||||
import { PageHeader } from "../components/common/PageHeader";
|
||||
import { EmployeePerformancePanel } from "../components/people/EmployeePerformancePanel";
|
||||
import { EmployeeSalaryPanel } from "../components/people/EmployeeSalaryPanel";
|
||||
import { StatusBadge } from "../components/common/StatusBadge";
|
||||
import { Button } from "../components/ui/button";
|
||||
import { Input } from "../components/ui/input";
|
||||
@@ -47,7 +48,7 @@ import { mapApiErrorMessage } from "../api/errorMessages";
|
||||
import { isApiError } from "../api/types";
|
||||
import { downloadBlob } from "../lib/download";
|
||||
|
||||
type ProfileTab = "profile" | "contracts" | "trainingCertificates" | "performance";
|
||||
type ProfileTab = "profile" | "contracts" | "trainingCertificates" | "performance" | "salary";
|
||||
|
||||
type ContractFormState = {
|
||||
contractNo: string;
|
||||
@@ -122,7 +123,7 @@ function buildEmptyCertificateForm(): CertificateFormState {
|
||||
}
|
||||
|
||||
function parseProfileTab(value: string | null): ProfileTab {
|
||||
if (value === "contracts" || value === "trainingCertificates" || value === "performance") {
|
||||
if (value === "contracts" || value === "trainingCertificates" || value === "performance" || value === "salary") {
|
||||
return value;
|
||||
}
|
||||
return "profile";
|
||||
@@ -482,6 +483,7 @@ export function EmployeeProfilePage() {
|
||||
const performanceOnlyMode = activeTab === "performance" && profilePermissionDenied && Boolean(performanceQuery.data);
|
||||
const showPerformanceTab =
|
||||
canManageEmployeeProfile || canEditSelfProfile || performanceOnlyMode || performanceQuery.data?.viewerRole === "manager";
|
||||
const showSalaryTab = canManageEmployeeProfile || canEditSelfProfile;
|
||||
|
||||
const performanceContent =
|
||||
performanceQuery.isLoading ? (
|
||||
@@ -498,6 +500,7 @@ export function EmployeeProfilePage() {
|
||||
]}
|
||||
/>
|
||||
);
|
||||
const salaryContent = <EmployeeSalaryPanel employeeId={employeeId} canManage={canManageEmployeeProfile} isSelf={canEditSelfProfile} />;
|
||||
|
||||
if (profileQuery.isLoading || (activeTab === "performance" && profilePermissionDenied && performanceQuery.isLoading)) {
|
||||
return <div className="card-std p-6 text-sm text-zinc-500">加载员工档案中...</div>;
|
||||
@@ -686,6 +689,7 @@ export function EmployeeProfilePage() {
|
||||
{canManageEmployeeProfile ? <TabsTrigger value="contracts">合同</TabsTrigger> : null}
|
||||
{canManageEmployeeProfile ? <TabsTrigger value="trainingCertificates">培训与证书</TabsTrigger> : null}
|
||||
{showPerformanceTab ? <TabsTrigger value="performance">绩效</TabsTrigger> : null}
|
||||
{showSalaryTab ? <TabsTrigger value="salary">薪资</TabsTrigger> : null}
|
||||
</TabsList>
|
||||
|
||||
<TabsContent value="profile" className="space-y-6">
|
||||
@@ -1420,6 +1424,12 @@ export function EmployeeProfilePage() {
|
||||
{performanceContent}
|
||||
</TabsContent>
|
||||
) : null}
|
||||
|
||||
{showSalaryTab ? (
|
||||
<TabsContent value="salary" className="space-y-6">
|
||||
{salaryContent}
|
||||
</TabsContent>
|
||||
) : null}
|
||||
</Tabs>
|
||||
</div>
|
||||
);
|
||||
|
||||
在新工单中引用
屏蔽一个用户