72 lines
2.3 KiB
JavaScript
72 lines
2.3 KiB
JavaScript
// middleware/users.js —— users 路由的纯业务规则中间件
|
||
// 与权限/认证无关,只是保护操作者自身不被误操作
|
||
const { pool } = require('../db')
|
||
|
||
/**
|
||
* 更新用户时的自保护:
|
||
* - 不能修改自己的部门
|
||
* - 不能禁用自己
|
||
*/
|
||
function protectSelfUpdate(req, res, next) {
|
||
if (Number(req.params.id) === req.user.id) {
|
||
if (req.body.department_id !== undefined && req.body.department_id !== req.user.department_id) {
|
||
return res.status(400).json({ code: 400, message: '不能修改自己的部门' })
|
||
}
|
||
if (req.body.is_active === 0) {
|
||
return res.status(400).json({ code: 400, message: '不能禁用自己' })
|
||
}
|
||
}
|
||
next()
|
||
}
|
||
|
||
/**
|
||
* 删除用户时的保护:
|
||
* - 不能删除自己
|
||
* - 不能删除比自己级别高的用户
|
||
* - 最高只能删除同级用户
|
||
* - 不能删除最后一个总经理
|
||
*/
|
||
async function protectUserDelete(req, res, next) {
|
||
const targetId = Number(req.params.id)
|
||
const operatorLevel = req.user.role_level || 4
|
||
|
||
// 不能删除自己
|
||
if (targetId === req.user.id) {
|
||
return res.status(400).json({ code: 400, message: '不能删除自己' })
|
||
}
|
||
|
||
try {
|
||
const [rows] = await pool.query('SELECT role_level, department_id FROM users WHERE id = ?', [targetId])
|
||
if (rows.length === 0) {
|
||
return res.status(404).json({ code: 404, message: '用户不存在' })
|
||
}
|
||
|
||
const targetLevel = rows[0].role_level || 4
|
||
|
||
// 不能删除比自己级别高的用户(数字越小级别越高)
|
||
if (targetLevel < operatorLevel) {
|
||
return res.status(403).json({ code: 403, message: '不能删除比自己级别高的用户' })
|
||
}
|
||
|
||
// 最高只能删除同级
|
||
// 这个逻辑已经在上面的检查中覆盖了(targetLevel >= operatorLevel 才能继续)
|
||
|
||
// 不能删除最后一个总经理
|
||
if (targetLevel === 1) {
|
||
const [[{ cnt }]] = await pool.query(
|
||
'SELECT COUNT(*) AS cnt FROM users WHERE role_level = 1'
|
||
)
|
||
if (cnt <= 1) {
|
||
return res.status(400).json({ code: 400, message: '不能删除最后一个总经理' })
|
||
}
|
||
}
|
||
|
||
next()
|
||
} catch (e) {
|
||
console.error('[protectUserDelete] error:', e)
|
||
return res.status(500).json({ code: 500, message: e.message })
|
||
}
|
||
}
|
||
|
||
module.exports = { protectSelfUpdate, protectUserDelete }
|