fix: risk.service.ts priorityOrder 重复声明导致后端启动失败
用户手动修改 risk.service.ts 时在第 966 行重复声明了 priorityOrder(第 955 行已声明),导致 esbuild 报错 "The symbol priorityOrder has already been declared", 后端 502 Bad Gateway。删除重复声明。 Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,140 @@
|
||||
/**
|
||||
* 提成奖金路由
|
||||
* 管理按月提成奖金/扣款的 CRUD、批量导入、模板下载
|
||||
*/
|
||||
import { Router, Response, NextFunction } from 'express'
|
||||
import { authMiddleware, AuthRequest } from '../middleware/auth'
|
||||
import multer from 'multer'
|
||||
import * as XLSX from 'xlsx'
|
||||
import {
|
||||
listByMonth,
|
||||
summaryByMonth,
|
||||
create,
|
||||
update,
|
||||
remove,
|
||||
batchImport,
|
||||
} from '../services/commission-bonus.service'
|
||||
import { auditLog } from '../middleware/auditLog'
|
||||
|
||||
const router = Router()
|
||||
router.use(authMiddleware)
|
||||
|
||||
const upload = multer({ storage: multer.memoryStorage(), limits: { fileSize: 5 * 1024 * 1024 } })
|
||||
|
||||
/**
|
||||
* 按月查询提成奖金列表
|
||||
* GET /commission-bonus?month=YYYY-MM
|
||||
*/
|
||||
router.get('/', async (req: AuthRequest, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
const orgId = req.user!.orgId
|
||||
const month = (req.query.month as string) || new Date().toISOString().slice(0, 7)
|
||||
const [records, summary] = await Promise.all([
|
||||
listByMonth(orgId, month),
|
||||
summaryByMonth(orgId, month),
|
||||
])
|
||||
res.json({ success: true, data: { records, summary, month } })
|
||||
} catch (err) { next(err) }
|
||||
})
|
||||
|
||||
/**
|
||||
* 新增单条提成奖金
|
||||
* POST /commission-bonus body: { employeeId, month, amount, remark? }
|
||||
*/
|
||||
router.post('/', async (req: AuthRequest, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
const orgId = req.user!.orgId
|
||||
const { employeeId, month, amount, remark } = req.body
|
||||
if (!employeeId || !month || amount === undefined) {
|
||||
return res.status(400).json({ success: false, error: { code: 'BAD_REQUEST', message: '缺少 employeeId/month/amount' } })
|
||||
}
|
||||
const record = await create(orgId, req.user!.id, { employeeId, month, amount: Number(amount), remark })
|
||||
await auditLog(req, 'CREATE', 'COMMISSION_BONUS', record.id, { employeeId, month, amount })
|
||||
res.json({ success: true, data: record })
|
||||
} catch (err: any) {
|
||||
if (err.code === 'NOT_FOUND') return res.status(404).json({ success: false, error: { code: err.code, message: err.message } })
|
||||
next(err)
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* 更新单条
|
||||
* PUT /commission-bonus/:id body: { amount?, remark? }
|
||||
*/
|
||||
router.put('/:id', async (req: AuthRequest, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
const orgId = req.user!.orgId
|
||||
const { amount, remark } = req.body
|
||||
const record = await update(orgId, req.params.id, { amount: amount !== undefined ? Number(amount) : undefined, remark })
|
||||
await auditLog(req, 'UPDATE', 'COMMISSION_BONUS', req.params.id, { amount, remark })
|
||||
res.json({ success: true, data: record })
|
||||
} catch (err: any) {
|
||||
if (err.code === 'NOT_FOUND') return res.status(404).json({ success: false, error: { code: err.code, message: err.message } })
|
||||
next(err)
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* 删除单条
|
||||
* DELETE /commission-bonus/:id
|
||||
*/
|
||||
router.delete('/:id', async (req: AuthRequest, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
const orgId = req.user!.orgId
|
||||
await remove(orgId, req.params.id)
|
||||
await auditLog(req, 'DELETE', 'COMMISSION_BONUS', req.params.id)
|
||||
res.json({ success: true, data: { message: '已删除' } })
|
||||
} catch (err: any) {
|
||||
if (err.code === 'NOT_FOUND') return res.status(404).json({ success: false, error: { code: err.code, message: err.message } })
|
||||
next(err)
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* 批量导入 Excel
|
||||
* POST /commission-bonus/import multipart: file, month
|
||||
* Excel 列:员工姓名 | 证件号码 | 金额 | 备注
|
||||
*/
|
||||
router.post('/import', upload.single('file'), async (req: AuthRequest, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
const orgId = req.user!.orgId
|
||||
const month = req.body.month || new Date().toISOString().slice(0, 7)
|
||||
if (!req.file) {
|
||||
return res.status(400).json({ success: false, error: { code: 'BAD_REQUEST', message: '请上传 Excel 文件' } })
|
||||
}
|
||||
const wb = XLSX.read(req.file.buffer, { type: 'buffer' })
|
||||
const ws = wb.Sheets[wb.SheetNames[0]]
|
||||
const rows: any[] = XLSX.utils.sheet_to_json(ws, { defval: '' })
|
||||
|
||||
const parsed = rows.map((r) => ({
|
||||
employeeName: String(r['员工姓名'] || r['姓名'] || '').trim() || undefined,
|
||||
idCardNumber: String(r['证件号码'] || r['身份证号'] || '').trim() || undefined,
|
||||
amount: parseFloat(r['金额'] || r['提成奖金'] || '0') || 0,
|
||||
remark: String(r['备注'] || '').trim() || undefined,
|
||||
})).filter((r) => r.employeeName || r.idCardNumber)
|
||||
|
||||
const result = await batchImport(orgId, req.user!.id, month, parsed)
|
||||
await auditLog(req, 'IMPORT', 'COMMISSION_BONUS', undefined, { month, ...result })
|
||||
res.json({ success: true, data: result })
|
||||
} catch (err) { next(err) }
|
||||
})
|
||||
|
||||
/**
|
||||
* 下载导入模板
|
||||
* GET /commission-bonus/template
|
||||
*/
|
||||
router.get('/template', (req: AuthRequest, res: Response) => {
|
||||
const ws = XLSX.utils.aoa_to_sheet([
|
||||
['员工姓名', '证件号码', '金额', '备注'],
|
||||
['张三', '110101199001011234', '5000', '销售提成'],
|
||||
['李四', '', '-200', '迟到扣款'],
|
||||
])
|
||||
const wb = XLSX.utils.book_new()
|
||||
XLSX.utils.book_append_sheet(wb, ws, '提成奖金模板')
|
||||
const buf = XLSX.write(wb, { type: 'buffer', bookType: 'xlsx' })
|
||||
res.setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
|
||||
res.setHeader('Content-Disposition', 'attachment; filename="commission-bonus-template.xlsx"')
|
||||
res.send(buf)
|
||||
})
|
||||
|
||||
export default router
|
||||
Reference in New Issue
Block a user