import { Router, Response, NextFunction } from 'express' import prisma from '../lib/prisma' import { authMiddleware, AuthRequest } from '../middleware/auth' import { z } from 'zod' const router = Router() router.use(authMiddleware) // 获取社保配置 router.get('/config', async (req: AuthRequest, res: Response, next: NextFunction) => { try { let config = await prisma.socialInsuranceConfig.findUnique({ where: { orgId: req.user!.orgId }, }) if (!config) { config = await prisma.socialInsuranceConfig.create({ data: { orgId: req.user!.orgId }, }) } res.json({ success: true, data: config }) } catch (err) { next(err) } }) // 更新社保配置 const configSchema = z.object({ city: z.string().optional(), pensionOrg: z.number().optional(), pensionEmp: z.number().optional(), medicalOrg: z.number().optional(), medicalEmp: z.number().optional(), unemploymentOrg: z.number().optional(), unemploymentEmp: z.number().optional(), injuryOrg: z.number().optional(), maternityOrg: z.number().optional(), housingOrg: z.number().optional(), housingEmp: z.number().optional(), baseMin: z.number().optional(), baseMax: z.number().optional(), }) router.put('/config', async (req: AuthRequest, res: Response, next: NextFunction) => { try { const data = configSchema.parse(req.body) const config = await prisma.socialInsuranceConfig.upsert({ where: { orgId: req.user!.orgId }, update: data, create: { orgId: req.user!.orgId, ...data }, }) res.json({ success: true, data: config }) } catch (err) { next(err) } }) // 社保计算 const calcSchema = z.object({ base: z.number().positive(), }) router.post('/calculate', async (req: AuthRequest, res: Response, next: NextFunction) => { try { const { base } = calcSchema.parse(req.body) let config = await prisma.socialInsuranceConfig.findUnique({ where: { orgId: req.user!.orgId }, }) if (!config) { config = await prisma.socialInsuranceConfig.create({ data: { orgId: req.user!.orgId } }) } const actualBase = Math.min(Math.max(base, config.baseMin), config.baseMax) const pensionOrg = actualBase * config.pensionOrg / 100 const pensionEmp = actualBase * config.pensionEmp / 100 const medicalOrg = actualBase * config.medicalOrg / 100 const medicalEmp = actualBase * config.medicalEmp / 100 const unemploymentOrg = actualBase * config.unemploymentOrg / 100 const unemploymentEmp = actualBase * config.unemploymentEmp / 100 const injuryOrg = actualBase * config.injuryOrg / 100 const maternityOrg = actualBase * config.maternityOrg / 100 const housingOrg = actualBase * config.housingOrg / 100 const housingEmp = actualBase * config.housingEmp / 100 const totalOrg = pensionOrg + medicalOrg + unemploymentOrg + injuryOrg + maternityOrg + housingOrg const totalEmp = pensionEmp + medicalEmp + unemploymentEmp + housingEmp const total = totalOrg + totalEmp res.json({ success: true, data: { actualBase, originalBase: base, capped: base > config.baseMax, floored: base < config.baseMin, items: [ { name: '养老保险', orgRate: config.pensionOrg, empRate: config.pensionEmp, orgAmount: pensionOrg, empAmount: pensionEmp }, { name: '医疗保险', orgRate: config.medicalOrg, empRate: config.medicalEmp, orgAmount: medicalOrg, empAmount: medicalEmp }, { name: '失业保险', orgRate: config.unemploymentOrg, empRate: config.unemploymentEmp, orgAmount: unemploymentOrg, empAmount: unemploymentEmp }, { name: '工伤保险', orgRate: config.injuryOrg, empRate: 0, orgAmount: injuryOrg, empAmount: 0 }, { name: '生育保险', orgRate: config.maternityOrg, empRate: 0, orgAmount: maternityOrg, empAmount: 0 }, { name: '住房公积金', orgRate: config.housingOrg, empRate: config.housingEmp, orgAmount: housingOrg, empAmount: housingEmp }, ], totalOrg, totalEmp, total, }, }) } catch (err) { next(err) } }) export default router