fix: 全面优化安全、性能和代码质量
P0: 环境变量校验/事务保护/RBAC权限 P1: 花名册分页/密码重置验证码/ErrorBoundary/N+1查询优化 P2: 导出限制/自定义错误类/body大小限制/代码去重 P3: 自定义确认弹窗替换window.confirm
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { useState, useRef } from 'react'
|
||||
import { toast } from 'sonner'
|
||||
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
|
||||
import { useConfirm } from '../hooks/useConfirm'
|
||||
import { Users, FileText, AlertTriangle, Calendar, GraduationCap, TrendingUp, Scale, X, Plus, Paperclip, Trash2, Printer, Calculator, Shield, Info, Check, Eye, Download, UserX, UserPlus, Briefcase, FileSignature, DollarSign, Building2, RotateCcw } from 'lucide-react'
|
||||
import { QRCodeSVG } from 'qrcode.react'
|
||||
import api from '../lib/api'
|
||||
@@ -27,6 +28,7 @@ type DetailTab = 'basic' | 'contract' | 'payslip' | 'overtime' | 'disciplinary'
|
||||
|
||||
export default function Roster() {
|
||||
const queryClient = useQueryClient()
|
||||
const confirm = useConfirm()
|
||||
const [selectedId, setSelectedId] = useState<string | null>(null)
|
||||
const [search, setSearch] = useState('')
|
||||
const debouncedSearch = useDebouncedValue(search, 300)
|
||||
@@ -476,9 +478,12 @@ export default function Roster() {
|
||||
title="撤回"
|
||||
aria-label={`撤回${e.name}的${e.latestTerminationType === 'RESIGNATION' ? '离职' : '解聘'}记录`}
|
||||
className="rounded-md p-1.5 text-gray-400 transition hover:bg-danger/10 hover:text-danger"
|
||||
onClick={(ev) => {
|
||||
onClick={async (ev) => {
|
||||
ev.stopPropagation()
|
||||
if (e.latestTerminationId && window.confirm(`确认撤回${e.latestTerminationType === 'RESIGNATION' ? '离职' : '解聘'}记录?`)) {
|
||||
if (e.latestTerminationId && await confirm({
|
||||
title: '撤回确认',
|
||||
message: `确认撤回${e.latestTerminationType === 'RESIGNATION' ? '离职' : '解聘'}记录?`,
|
||||
})) {
|
||||
revokeMutation.mutate(e.latestTerminationId)
|
||||
}
|
||||
}}
|
||||
|
||||
Reference in New Issue
Block a user