/** * 员工端 — 培训/绩效/违纪记录查看与签收 */ import { useState } from 'react' import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query' import { GraduationCap, TrendingUp, AlertTriangle, CheckCircle, Clock, XCircle, ArrowLeft } from 'lucide-react' import { portalApi } from '../../lib/api-services' import Button from '../../components/ui/Button' type Tab = 'training' | 'performance' | 'disciplinary' const TABS: { key: Tab; label: string; icon: any }[] = [ { key: 'training', label: '培训记录', icon: GraduationCap }, { key: 'performance', label: '绩效考核', icon: TrendingUp }, { key: 'disciplinary', label: '违纪记录', icon: AlertTriangle }, ] const ACK_LABELS: Record = { PENDING: '待签收', SIGNED: '已签收', REFUSED: '拒绝签收' } const ACK_COLORS: Record = { PENDING: 'text-amber-600', SIGNED: 'text-green-600', REFUSED: 'text-red-600' } const RESULT_LABELS: Record = { EXCELLENT: '优秀', QUALIFIED: '合格', NEED_IMPROVE: '需改进', UNQUALIFIED: '不胜任' } const TYPE_LABELS: Record = { LATE: '迟到', ABSENT: '旷工', INSUBORDINATION: '不服从管理', MISCONDUCT: '违纪', VIOLATE_POLICY: '违反规章制度', OTHER: '其他' } const SEVERITY_LABELS: Record = { WARNING: '警告', SERIOUS: '严重', SEVERE: '极其严重' } const ACTION_LABELS: Record = { ORAL_WARNING: '口头警告', WRITTEN_WARNING: '书面警告', DEDUCTION: '扣款', DEMOTION: '降职', TERMINATION: '解除劳动合同' } function fmtDate(d: string | Date | null): string { if (!d) return '-' return new Date(d).toLocaleDateString('zh-CN') } export default function MyRecords() { const [tab, setTab] = useState('training') return (
{TABS.map(t => { const Icon = t.icon const active = tab === t.key return ( ) })}
{tab === 'training' && } {tab === 'performance' && } {tab === 'disciplinary' && }
) } function TrainingTab() { const queryClient = useQueryClient() const { data: records, isLoading } = useQuery({ queryKey: ['portal-training'], queryFn: () => portalApi.myTraining(), }) const signMut = useMutation({ mutationFn: (id: string) => portalApi.signTraining(id), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['portal-training'] }) }, }) const refuseMut = useMutation({ mutationFn: (id: string) => portalApi.refuseTraining(id), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['portal-training'] }) }, }) if (isLoading) return
加载中...
return (
{(records || []).length === 0 ? (
暂无培训记录
) : (records || []).map((r: any) => (
{r.topic}
{ACK_LABELS[r.ackStatus] || r.ackStatus}
培训日期:{fmtDate(r.trainingDate)}
讲师:{r.trainer || '-'}
时长:{r.duration}小时
{r.content &&
{r.content}
} {r.remark &&
备注:{r.remark}
} {r.ackStatus === 'PENDING' && (
)} {r.ackDate &&
签收时间:{fmtDate(r.ackDate)}
}
))}
) } function PerformanceTab() { const queryClient = useQueryClient() const { data: records, isLoading } = useQuery({ queryKey: ['portal-performance'], queryFn: () => portalApi.myPerformance(), }) const signMut = useMutation({ mutationFn: (id: string) => portalApi.signPerformance(id), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['portal-performance'] }) }, }) if (isLoading) return
加载中...
return (
{(records || []).length === 0 ? (
暂无绩效记录
) : (records || []).map((r: any) => (
{r.period} 绩效考核
{r.employeeAck ? '已签字' : '待签字'}
得分:{r.score}
等级:{r.grade}
结果:{RESULT_LABELS[r.result] || r.result}
{r.summary &&
评语:{r.summary}
} {r.improvementPlan &&
改进计划:{r.improvementPlan}
} {r.reviewer &&
考评人:{r.reviewer}
} {!r.employeeAck && (
)} {r.ackDate &&
签字时间:{fmtDate(r.ackDate)}
}
))}
) } function DisciplinaryTab() { const queryClient = useQueryClient() const { data: records, isLoading } = useQuery({ queryKey: ['portal-disciplinary'], queryFn: () => portalApi.myDisciplinary(), }) const signMut = useMutation({ mutationFn: (id: string) => portalApi.signDisciplinary(id), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['portal-disciplinary'] }) }, }) if (isLoading) return
加载中...
return (
{(records || []).length === 0 ? (
暂无违纪记录
) : (records || []).map((r: any) => (
{TYPE_LABELS[r.violationType] || r.violationType}
{r.employeeAck ? '已签字' : '待签字'}
违纪日期:{fmtDate(r.violationDate)}
严重程度:{SEVERITY_LABELS[r.severity] || r.severity}
处理:{ACTION_LABELS[r.action] || r.action}
{r.description}
{r.actionDetail &&
处理详情:{r.actionDetail}
} {r.witness &&
见证人:{r.witness}
} {!r.employeeAck && (
)} {r.ackDate &&
签字时间:{fmtDate(r.ackDate)}
}
))}
) }