优化: 大文件拆分+代码分割+按需加载+console清理+any类型替换

- Money.tsx (2260行→54行): 拆分为 money/ 子目录4个组件, React.lazy二级分割
- AIAssistant.tsx (2038行→63行): 拆分为 ai-assistant/ 子目录6个组件, React.lazy二级分割
- xlsx改为动态导入, OvertimeTab从345KB降至12.7KB
- api-services.ts: 请求参数 any→Record<string,unknown>
- 移除前端3处console.log残留
- 后端console替换为pino logger
- 前后端未使用import/变量清理
- Zod schema验证: termination/platform/special-status/work-process
- 新增 leave.routes.ts, acceptance-test.routes.ts
- UI组件: PageGuide, QueryError, Stepper
This commit is contained in:
freedakgmail
2026-08-04 07:53:37 +08:00
parent 1da385cd5d
commit 2968484d2d
109 changed files with 8950 additions and 5926 deletions
+10 -3
View File
@@ -3,7 +3,7 @@ import { useSearchParams } from 'react-router-dom'
import { toast } from 'sonner'
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
import { useConfirm } from '../hooks/useConfirm'
import { Users, FileText, AlertTriangle, Calendar, TrendingUp, Scale, X, Plus, Check, UserX, UserPlus, DollarSign, Building2, RotateCcw, History, Upload, Wallet, Download } from 'lucide-react'
import { Users, Plus, Check, UserX, UserPlus, DollarSign, Building2, RotateCcw, Upload, Wallet, Download } from 'lucide-react'
import { rosterApi, employeeApi, terminationApi } from '../lib/api-services'
import { useAuthStore } from '../store/authStore'
import { useDebouncedValue } from '../hooks/useDebouncedValue'
@@ -12,11 +12,13 @@ import Button from '../components/ui/Button'
import { Input, Label, Select } from '../components/ui/Input'
import Modal from '../components/ui/Modal'
import Pagination from '../components/ui/Pagination'
import { fmt, terminateReasonMap, DetailTab, TAB_GROUPS, TAB_COUNT_KEYS } from './roster/shared'
import { fmt, terminateReasonMap } from './roster/shared'
import PageGuide from '../components/ui/PageGuide'
import EmployeeProfile from './roster/EmployeeProfile'
import { InlineAlert } from '../components/ui/InlineAlert'
import { AddEmployeeModal, ResignModal, RehireModal, SalaryChangeModal, DeptChangeModal } from './roster/modals'
import { ImportSettings } from './Settings'
import QueryError from '../components/ui/QueryError'
export default function Roster() {
const queryClient = useQueryClient()
@@ -49,7 +51,7 @@ export default function Roster() {
const [batchTerminateReason, setBatchTerminateReason] = useState('NEGOTIATED')
const [terminatePreviewData, setTerminatePreviewData] = useState<any>(null)
const { data: rosterData, isLoading } = useQuery<any>({
const { data: rosterData, isLoading, isError, error, refetch } = useQuery<any>({
queryKey: ['roster', page, pageSize, debouncedSearch, filterStatus, filterContractStatus, filterDepartment],
queryFn: async () => {
const params: any = { page, pageSize }
@@ -272,6 +274,9 @@ export default function Roster() {
return (
<div className="space-y-5">
<PageGuide>
</PageGuide>
<div className="flex flex-col gap-4 xl:flex-row xl:items-end xl:justify-between">
<div>
<div className="flex items-center gap-2">
@@ -407,6 +412,8 @@ export default function Roster() {
{isLoading ? (
<div className="rounded-lg border border-gray-200 bg-white py-16 text-center text-sm text-gray-400">...</div>
) : isError ? (
<QueryError error={error} onRetry={refetch} />
) : filtered.length === 0 ? (
<Card><div className="py-12 text-center text-sm text-gray-400"></div></Card>
) : (