优化: 大文件拆分+代码分割+按需加载+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
+34
View File
@@ -0,0 +1,34 @@
import { z } from 'zod'
export const createOrgSchema = z.object({
name: z.string().min(2, '企业名称至少2个字').max(50, '企业名称最多50个字'),
plan: z.enum(['FREE', 'PRO', 'ENTERPRISE']).default('FREE'),
maxEmployees: z.number().int().min(1).max(100000).default(20),
city: z.string().max(50).optional(),
contactName: z.string().max(30).optional(),
contactPhone: z.string().regex(/^1[3-9]\d{9}$/).optional(),
adminName: z.string().max(30).optional(),
adminPhone: z.string().regex(/^1[3-9]\d{9}$/, '手机号格式不正确'),
adminPassword: z.string().min(8, '密码至少8位').max(32, '密码最多32位'),
})
export const updateOrgSchema = z.object({
name: z.string().min(2).max(50).optional(),
plan: z.enum(['FREE', 'PRO', 'ENTERPRISE']).optional(),
maxEmployees: z.number().int().min(1).max(100000).optional(),
city: z.string().max(50).optional().nullable(),
contactName: z.string().max(30).optional().nullable(),
contactPhone: z.string().regex(/^1[3-9]\d{9}$/).optional().nullable(),
})
export const updateOrgAdminSchema = z.object({
adminName: z.string().max(30).optional(),
adminPhone: z.string().regex(/^1[3-9]\d{9}$/).optional(),
adminPassword: z.string().min(8, '密码至少8位').max(32).optional(),
})
export const createPlatformAdminSchema = z.object({
name: z.string().min(1, '姓名不能为空').max(30),
phone: z.string().regex(/^1[3-9]\d{9}$/, '手机号格式不正确'),
password: z.string().min(8, '密码至少8位').max(32, '密码最多32位'),
})
@@ -0,0 +1,40 @@
import { z } from 'zod'
export const createSpecialStatusSchema = z.object({
employeeId: z.string().min(1, '员工ID不能为空'),
type: z.enum([
'PREGNANCY', 'WORK_INJURY', 'MEDICAL_PERIOD', 'OTHER',
], { errorMap: () => ({ message: '无效的特殊状态类型' }) }),
status: z.enum(['ACTIVE', 'PENDING', 'RESOLVED']).default('ACTIVE'),
startDate: z.string().optional().nullable(),
endDate: z.string().optional().nullable(),
expectedDueDate: z.string().optional().nullable(),
injuryDate: z.string().optional().nullable(),
injuryDescription: z.string().max(500).optional().nullable(),
certificationDate: z.string().optional().nullable(),
certificationNo: z.string().max(50).optional().nullable(),
disabilityLevel: z.string().max(20).optional().nullable(),
assessmentDate: z.string().optional().nullable(),
medicalMonths: z.number().int().min(1).max(36).optional().nullable(),
description: z.string().max(500).optional().nullable(),
attachments: z.array(z.any()).optional().nullable(),
reminderDate: z.string().optional().nullable(),
})
export const updateSpecialStatusSchema = z.object({
type: z.enum(['PREGNANCY', 'WORK_INJURY', 'MEDICAL_PERIOD', 'OTHER']).optional(),
status: z.enum(['ACTIVE', 'PENDING', 'RESOLVED']).optional(),
startDate: z.string().optional().nullable(),
endDate: z.string().optional().nullable(),
expectedDueDate: z.string().optional().nullable(),
injuryDate: z.string().optional().nullable(),
injuryDescription: z.string().max(500).optional().nullable(),
certificationDate: z.string().optional().nullable(),
certificationNo: z.string().max(50).optional().nullable(),
disabilityLevel: z.string().max(20).optional().nullable(),
assessmentDate: z.string().optional().nullable(),
medicalMonths: z.number().int().min(1).max(36).optional().nullable(),
description: z.string().max(500).optional().nullable(),
attachments: z.array(z.any()).optional().nullable(),
reminderDate: z.string().optional().nullable(),
})
+42
View File
@@ -13,3 +13,45 @@ export const terminationQuerySchema = z.object({
page: z.coerce.number().min(1).default(1),
pageSize: z.coerce.number().min(1).max(50).default(20),
})
export const resignationSchema = z.object({
employeeId: z.string().min(1, '员工ID不能为空'),
terminationDate: z.string().min(1, '离职日期不能为空'),
resignationReason: z.string().max(200).optional(),
remark: z.string().max(500).optional(),
})
export const batchTerminatePreviewSchema = z.object({
items: z.array(z.object({
employeeId: z.string().min(1),
reason: z.string().min(1, '解聘原因不能为空'),
terminationDate: z.string().min(1, '解聘日期不能为空'),
})).min(1, '至少选择一名员工'),
})
export const batchTerminateSchema = z.object({
items: z.array(z.object({
employeeId: z.string().min(1),
reason: z.string().min(1, '解聘原因不能为空'),
terminationDate: z.string().min(1, '解聘日期不能为空'),
compensation: z.number().min(0).optional(),
})).min(1, '至少选择一名员工'),
})
export const createTerminationDraftSchema = z.object({
employeeId: z.string().min(1, '员工ID不能为空'),
type: z.enum(['TERMINATION', 'RESIGNATION']).optional(),
reason: z.string().max(200).optional(),
terminationDate: z.string().optional(),
compensation: z.number().min(0).optional(),
handoverItems: z.array(z.any()).optional(),
remark: z.string().max(500).optional(),
})
export const updateTerminationDraftSchema = z.object({
reason: z.string().max(200).optional(),
terminationDate: z.string().optional(),
compensation: z.number().min(0).optional(),
handoverItems: z.array(z.any()).optional(),
remark: z.string().max(500).optional(),
})
@@ -0,0 +1,21 @@
import { z } from 'zod'
export const createWorkProcessSchema = z.object({
type: z.enum([
'HIRE', 'ONBOARD', 'CUSTOM_CONTRACT', 'INFO_SUBMIT', 'CONFIRM',
'CHANGE', 'RENEW', 'SUSPEND', 'INCOME_CERT', 'TERMINATE',
'RESCIND', 'LEAVING_CERT', 'FLEXIBLE',
]),
title: z.string().max(100).optional(),
employeeId: z.string().optional().nullable(),
formData: z.record(z.any()).optional(),
status: z.enum(['DRAFT', 'COMPLETED']).default('DRAFT'),
remark: z.string().max(500).optional().nullable(),
})
export const updateWorkProcessSchema = z.object({
title: z.string().max(100).optional(),
employeeId: z.string().optional().nullable(),
formData: z.record(z.any()).optional(),
remark: z.string().max(500).optional().nullable(),
})