feat: 20260805 系统优化 - 身份证复制fallback/薪税日期筛选/社保版本修复/证据链导出/违纪证明/医疗期政策/绩效类型评级/合同作废/帮助更新

This commit is contained in:
freedakgmail
2026-08-05 20:26:16 +08:00
parent a5901d648e
commit c355a7d208
24 changed files with 1185 additions and 257 deletions
+25 -5
View File
@@ -11,7 +11,7 @@ import { AlertTriangle, Check } from "lucide-react"
export default function PerformanceInfo({ employeeId, records }: { employeeId: string; records: any[] }) {
const queryClient = useQueryClient()
const [showForm, setShowForm] = useState(false)
const [form, setForm] = useState({ period: '', score: 80, grade: 'B', result: 'QUALIFIED', summary: '', improvementPlan: '', employeeAck: false, ackDate: '', reviewer: '' })
const [form, setForm] = useState({ period: '', periodType: 'MONTHLY' as 'MONTHLY' | 'QUARTERLY' | 'YEARLY', score: 80, grade: 'B', result: 'QUALIFIED', summary: '', improvementPlan: '', employeeAck: false, ackDate: '', reviewer: '' })
const createMutation = useMutation({
mutationFn: (data: any) => rosterApi.performance(employeeId, data),
@@ -25,6 +25,19 @@ export default function PerformanceInfo({ employeeId, records }: { employeeId: s
const resultMap: Record<string, string> = { EXCELLENT: '优秀', QUALIFIED: '合格', NEED_IMPROVE: '需改进', UNQUALIFIED: '不胜任' }
// 根据得分自动计算等级和结果
const scoreToGrade = (score: number): { grade: string; result: string } => {
if (score >= 90) return { grade: 'A', result: 'EXCELLENT' }
if (score >= 80) return { grade: 'B', result: 'QUALIFIED' }
if (score >= 60) return { grade: 'C', result: 'NEED_IMPROVE' }
return { grade: 'D', result: 'UNQUALIFIED' }
}
const handleScoreChange = (score: number) => {
const { grade, result } = scoreToGrade(score)
setForm({ ...form, score, grade, result })
}
return (
<div className="space-y-3">
<div className="flex justify-between items-center">
@@ -35,14 +48,21 @@ export default function PerformanceInfo({ employeeId, records }: { employeeId: s
{showForm && (
<Card>
<div className="grid md:grid-cols-2 gap-4">
<div><Label></Label><Input value={form.period} onChange={(e) => setForm({ ...form, period: e.target.value })} placeholder="如 2026-07 或 2026-Q3" /></div>
<div><Label></Label><Input type="number" value={form.score} onChange={(e) => setForm({ ...form, score: Number(e.target.value) })} /></div>
<div><Label></Label>
<div><Label></Label>
<Select value={form.periodType} onChange={(e) => setForm({ ...form, periodType: e.target.value as any })}>
<option value="MONTHLY"></option>
<option value="QUARTERLY"></option>
<option value="YEARLY"></option>
</Select>
</div>
<div><Label></Label><Input value={form.period} onChange={(e) => setForm({ ...form, period: e.target.value })} placeholder={form.periodType === 'MONTHLY' ? '如 2026-07' : form.periodType === 'QUARTERLY' ? '如 2026-Q3' : '如 2026'} /></div>
<div><Label></Label><Input type="number" value={form.score} onChange={(e) => handleScoreChange(Number(e.target.value))} /></div>
<div><Label></Label>
<Select value={form.grade} onChange={(e) => setForm({ ...form, grade: e.target.value })}>
<option value="A">A</option><option value="B">B</option><option value="C">C</option><option value="D">D</option>
</Select>
</div>
<div><Label></Label>
<div><Label></Label>
<Select value={form.result} onChange={(e) => setForm({ ...form, result: e.target.value })}>
{Object.entries(resultMap).map(([k, v]) => <option key={k} value={k}>{v}</option>)}
</Select>