feat: 系统优化Phase2 - 面包屑导航/侧边栏间距/制度公示阅读签收/模板变量中文化/通知类型补全
- 面包屑导航组件,集成至TopNav header - 侧边栏菜单分组间距增大,分组间分隔线 - 制度公示员工阅读签收:PolicyReadRecord模型、portal路由、管理端阅读统计 - 修复Policies.tsx民主程序推进bug(字段名/API路径/参数) - 用工文本模板变量名英文转中文显示 - 通知类型TYPE_LABELS补全(RISK_ALERT/SOCIAL_INS/OVERTIME_ALERT/PAYSLIP_READY) - 通知示例数据补充 - h2标题统一为text-sm font-medium - 新增run.md
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
import { Router, Response, NextFunction } from 'express'
|
||||
import prisma from '../lib/prisma'
|
||||
import { authMiddleware, AuthRequest } from '../middleware/auth'
|
||||
|
||||
const router = Router()
|
||||
router.use(authMiddleware)
|
||||
|
||||
/**
|
||||
* 查询审计日志
|
||||
* 支持按操作类型、实体类型、时间范围筛选
|
||||
*/
|
||||
router.get('/', async (req: AuthRequest, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
const page = parseInt(req.query.page as string) || 1
|
||||
const pageSize = parseInt(req.query.pageSize as string) || 20
|
||||
const action = req.query.action as string | undefined
|
||||
const entity = req.query.entity as string | undefined
|
||||
const userId = req.query.userId as string | undefined
|
||||
const dateFrom = req.query.dateFrom as string | undefined
|
||||
const dateTo = req.query.dateTo as string | undefined
|
||||
|
||||
const where: any = { orgId: req.user!.orgId }
|
||||
if (action) where.action = { contains: action, mode: 'insensitive' }
|
||||
if (entity) where.entity = entity
|
||||
if (userId) where.userId = userId
|
||||
if (dateFrom || dateTo) {
|
||||
where.createdAt = {}
|
||||
if (dateFrom) where.createdAt.gte = new Date(dateFrom)
|
||||
if (dateTo) where.createdAt.lte = new Date(`${dateTo}T23:59:59`)
|
||||
}
|
||||
|
||||
const [logs, total] = await Promise.all([
|
||||
prisma.auditLog.findMany({
|
||||
where,
|
||||
orderBy: { createdAt: 'desc' },
|
||||
skip: (page - 1) * pageSize,
|
||||
take: pageSize,
|
||||
}),
|
||||
prisma.auditLog.count({ where }),
|
||||
])
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
data: { items: logs, total, page, pageSize, totalPages: Math.ceil(total / pageSize) },
|
||||
})
|
||||
} catch (err) {
|
||||
next(err)
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* 获取审计日志统计(按操作类型分组)
|
||||
*/
|
||||
router.get('/stats', async (req: AuthRequest, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
const dateFrom = req.query.dateFrom as string | undefined
|
||||
const dateTo = req.query.dateTo as string | undefined
|
||||
|
||||
const where: any = { orgId: req.user!.orgId }
|
||||
if (dateFrom || dateTo) {
|
||||
where.createdAt = {}
|
||||
if (dateFrom) where.createdAt.gte = new Date(dateFrom)
|
||||
if (dateTo) where.createdAt.lte = new Date(`${dateTo}T23:59:59`)
|
||||
}
|
||||
|
||||
const stats = await prisma.auditLog.groupBy({
|
||||
by: ['action'],
|
||||
where,
|
||||
_count: { action: true },
|
||||
orderBy: { _count: { action: 'desc' } },
|
||||
take: 20,
|
||||
})
|
||||
|
||||
res.json({ success: true, data: stats })
|
||||
} catch (err) {
|
||||
next(err)
|
||||
}
|
||||
})
|
||||
|
||||
export default router
|
||||
Reference in New Issue
Block a user