From 28759651137b6118ccca45544b3b7cb8aa608cf9 Mon Sep 17 00:00:00 2001 From: selfrelease Date: Sun, 16 Aug 2026 14:19:43 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E8=96=AA=E8=B5=84?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E4=BF=9D=E5=AD=98=E5=A4=B1=E8=B4=A5=20+=20?= =?UTF-8?q?=E5=BA=94=E5=8F=91=E8=AE=A1=E7=AE=97=E4=B8=A2=E5=A4=B1=E7=BB=86?= =?UTF-8?q?=E5=8C=96=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 两个问题: 1. 编辑保存 422 错误:updateEntrySchema 要求 min(0),但 bonus 可能为负数(如扣款),导致 Zod 验证失败。放宽为 z.number().optional() 2. 应发不随编辑变化:编辑条目时 inputs 只合并 5 个基本字段, 丢失了 positionSalary/performanceSalary 等细化字段, 导致 calcBatchEntry 计算的 totalPay 不包含细化薪资项。 修复:从 entry 中补全所有细化字段 Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- backend/src/routes/payroll2.routes.ts | 28 +++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/backend/src/routes/payroll2.routes.ts b/backend/src/routes/payroll2.routes.ts index be95b52..b3ae314 100644 --- a/backend/src/routes/payroll2.routes.ts +++ b/backend/src/routes/payroll2.routes.ts @@ -520,15 +520,15 @@ router.post('/batches', async (req: AuthRequest, res: Response, next: NextFuncti // 编辑批次条目(计算依据项 + 社保公积金手动覆盖) const updateEntrySchema = z.object({ - baseSalary: z.number().min(0).optional(), - overtimePay: z.number().min(0).optional(), - allowance: z.number().min(0).optional(), - deduction: z.number().min(0).optional(), - bonus: z.number().min(0).optional(), - socialEmp: z.number().min(0).optional(), - socialOrg: z.number().min(0).optional(), - housingEmp: z.number().min(0).optional(), - housingOrg: z.number().min(0).optional(), + baseSalary: z.number().optional(), + overtimePay: z.number().optional(), + allowance: z.number().optional(), + deduction: z.number().optional(), + bonus: z.number().optional(), + socialEmp: z.number().optional(), + socialOrg: z.number().optional(), + housingEmp: z.number().optional(), + housingOrg: z.number().optional(), }) router.put('/batches/:batchId/entries/:employeeId', async (req: AuthRequest, res: Response, next: NextFunction) => { @@ -546,13 +546,21 @@ router.put('/batches/:batchId/entries/:employeeId', async (req: AuthRequest, res }) if (!entry) return res.status(404).json({ success: false, error: { code: 'NOT_FOUND', message: '条目不存在' } }) - // 合并输入项 + // 合并输入项(包含细化薪资字段,避免编辑时丢失岗位工资/绩效工资等) const inputs = { baseSalary: data.baseSalary ?? entry.baseSalary, overtimePay: data.overtimePay ?? entry.overtimePay, allowance: data.allowance ?? entry.allowance, deduction: data.deduction ?? entry.deduction, bonus: data.bonus ?? entry.bonus, + positionSalary: entry.positionSalary || undefined, + performanceSalary: entry.performanceSalary || undefined, + senioritySalary: entry.senioritySalary || undefined, + transportAllowance: entry.transportAllowance || undefined, + mealAllowance: entry.mealAllowance || undefined, + housingAllowance: entry.housingAllowance || undefined, + communicationAllowance: entry.communicationAllowance || undefined, + otherDeduction: entry.otherDeduction || undefined, } // 构建社保覆盖参数(如果请求中包含社保字段)