fix: 全面优化安全、性能和代码质量

P0: 环境变量校验/事务保护/RBAC权限
P1: 花名册分页/密码重置验证码/ErrorBoundary/N+1查询优化
P2: 导出限制/自定义错误类/body大小限制/代码去重
P3: 自定义确认弹窗替换window.confirm
This commit is contained in:
freedakgmail
2026-07-24 22:28:58 +08:00
parent 9ec21fedea
commit 5c12f28ac7
23 changed files with 634 additions and 366 deletions
+12 -10
View File
@@ -1,5 +1,6 @@
import { Router, Response } from 'express'
import { authMiddleware, AuthRequest } from '../middleware/auth'
import { requireAdmin } from '../middleware/rbac'
import prisma from '../lib/prisma'
import { decrypt } from '../lib/crypto'
import ExcelJS from 'exceljs'
@@ -21,22 +22,23 @@ function maskBankAccount(account: string | null): string | null {
}
// 导出全部数据(支持模块选择、格式选择、脱敏)
router.get('/all', authMiddleware, async (req: AuthRequest, res: Response, next) => {
router.get('/all', authMiddleware, requireAdmin, async (req: AuthRequest, res: Response, next) => {
try {
const orgId = req.user!.orgId
const format = (req.query.format as string) || 'json'
const mask = req.query.mask === 'true' || req.user!.role !== 'ADMIN'
const modules = (req.query.modules as string || 'employees,contracts,terminations,payrollBatches,payslips,socialRecords,housingRecords,riskItems').split(',')
const fetchMap: Record<string, () => Promise<any>> = {
employees: () => prisma.employee.findMany({ where: { orgId } }),
contracts: () => prisma.laborContract.findMany({ where: { orgId } }),
terminations: () => prisma.terminationRecord.findMany({ where: { orgId } }),
payrollBatches: () => prisma.payrollBatch.findMany({ where: { orgId } }),
payslips: () => prisma.payslip.findMany({ where: { orgId } }),
socialRecords: () => prisma.employeeSocialInsRecord.findMany({ where: { orgId } }),
housingRecords: () => prisma.employeeHousingFundRecord.findMany({ where: { orgId } }),
riskItems: () => prisma.riskItem.findMany({ where: { orgId } }),
const exportBatchSize = 500
const fetchMap: Record<string, () => Promise<any[]>> = {
employees: () => prisma.employee.findMany({ where: { orgId }, take: exportBatchSize }),
contracts: () => prisma.laborContract.findMany({ where: { orgId }, take: exportBatchSize }),
terminations: () => prisma.terminationRecord.findMany({ where: { orgId }, take: exportBatchSize }),
payrollBatches: () => prisma.payrollBatch.findMany({ where: { orgId }, take: exportBatchSize }),
payslips: () => prisma.payslip.findMany({ where: { orgId }, take: exportBatchSize }),
socialRecords: () => prisma.employeeSocialInsRecord.findMany({ where: { orgId }, take: exportBatchSize }),
housingRecords: () => prisma.employeeHousingFundRecord.findMany({ where: { orgId }, take: exportBatchSize }),
riskItems: () => prisma.riskItem.findMany({ where: { orgId }, take: exportBatchSize }),
}
const useGzip = req.query.gzip !== 'false'