feat: 完成23项系统优化 - 花名册社保状态列/身份证复制/附件类型扩展, 用工办理姓名检索/直接提交/文书查看/批量证明, 风险中心跳转筛选+批量处理, 日历7/15/35天分组+逾期统计, 考勤单条编辑+按人导出, 工资条查看状态+工资流水导出, 辞职申请附件上传, 交接清单PDF下载, 操作完成下一步引导, 休假审批入口, 人效成本分部门

This commit is contained in:
freedakgmail
2026-08-04 22:55:03 +08:00
parent 338af5eee9
commit 5604d02de9
41 changed files with 2104 additions and 482 deletions
+60 -3
View File
@@ -1,4 +1,5 @@
import { useState, useMemo, useEffect } from 'react'
import { usePageSize } from '../hooks/usePageSize'
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
import { toast } from 'sonner'
import { AlertTriangle, Check, ChevronRight, ChevronLeft, Shield, Info, Calculator, FileText, Printer, Trash2, List, Download, Plus, Edit, Send, CheckCircle, XCircle, Play, Ban, CheckCheck } from 'lucide-react'
@@ -204,8 +205,8 @@ export default function Termination() {
const [filterStatus, setFilterStatus] = useState('')
const [filterDepartment, setFilterDepartment] = useState('')
const [searchTerm, setSearchTerm] = useState('')
const draftPageSize = usePageSize()
const [draftPage, setDraftPage] = useState(1)
const [draftPageSize, setDraftPageSize] = useState(20)
const { data: employees } = useQuery<any[]>({
queryKey: ['roster-for-termination'],
@@ -697,7 +698,7 @@ export default function Termination() {
{view === 'list' && (
<>
<PageGuide>
稿
稿
</PageGuide>
<div className="flex gap-2 flex-wrap items-center">
<Input
@@ -886,7 +887,7 @@ export default function Termination() {
pageSize={draftPageSize}
total={draftsTotal}
onPageChange={setDraftPage}
onPageSizeChange={(s) => { setDraftPageSize(s); setDraftPage(1) }}
onPageSizeChange={() => setDraftPage(1)}
/>
</Card>
</>
@@ -1017,6 +1018,62 @@ export default function Termination() {
</Button>
</div>
)}
{/* 下载离职证明 & 交接清单 */}
{draftDetail.status === 'COMPLETED' && (
<div className="border-t pt-3 flex gap-2 flex-wrap">
<Button
variant="secondary"
onClick={() => {
const doc = new jsPDF()
doc.setFontSize(18)
doc.text('解除/终止劳动合同证明书', 105, 25, { align: 'center' })
doc.setFontSize(11)
let y = 45
doc.text(`兹证明 ${draftDetail.employeeName}(身份证号:${draftDetail.idCardNumber || '—'}),`, 14, y); y += 8
doc.text(`原系我公司 ${draftDetail.department} 部门员工,`, 14, y); y += 8
doc.text(`${draftDetail.terminationDate}${REASONS.find(r => r.value === draftDetail.reason)?.label || draftDetail.reason} 原因,`, 14, y); y += 8
doc.text(`正式解除/终止劳动合同。`, 14, y); y += 8
doc.text(`经济补偿金已结清:¥${fmt(draftDetail.compensation)}`, 14, y); y += 8
doc.text(`社保截止月份:${draftDetail.socialInsEndMonth || '—'},公积金截止月份:${draftDetail.housingFundEndMonth || '—'}`, 14, y); y += 16
doc.text('特此证明。', 14, y); y += 24
doc.text('公司(盖章)', 140, y)
doc.text(new Date().toISOString().slice(0, 10), 140, y + 8)
doc.save(`离职证明-${draftDetail.employeeName}-${draftDetail.terminationDate}.pdf`)
}}
>
<Download className="w-4 h-4 mr-1" />
</Button>
{draftDetail.handoverItems && draftDetail.handoverItems.length > 0 && (
<Button
variant="secondary"
onClick={() => {
const doc = new jsPDF()
doc.setFontSize(16)
doc.text('工作交接清单', 105, 25, { align: 'center' })
doc.setFontSize(11)
let y = 40
doc.text(`员工姓名:${draftDetail.employeeName}`, 14, y); y += 8
doc.text(`部门:${draftDetail.department || '—'}`, 14, y); y += 8
doc.text(`离职日期:${draftDetail.terminationDate}`, 14, y); y += 12
doc.setFontSize(10)
draftDetail.handoverItems.forEach((item: any, i: number) => {
if (y > 270) { doc.addPage(); y = 20 }
doc.text(`${item.done ? '[√]' : '[ ]'} ${item.label}${item.remark ? '' + item.remark + '' : ''}`, 14, y); y += 7
})
y += 16
doc.text('交接人签字:____________', 14, y)
doc.text('接收人签字:____________', 100, y)
y += 12
doc.text('日期:____________', 14, y)
doc.save(`交接清单-${draftDetail.employeeName}-${draftDetail.terminationDate}.pdf`)
}}
>
<Download className="w-4 h-4 mr-1" />
</Button>
)}
</div>
)}
</div>
</Card>
)}