重构后端,使其更加权责分明
This commit is contained in:
35
middleware/employees.js
Normal file
35
middleware/employees.js
Normal file
@@ -0,0 +1,35 @@
|
||||
// middleware/employees.js —— 员工管理的业务规则中间件
|
||||
|
||||
/**
|
||||
* 允许在创建员工时一并创建系统用户账号(需 user:manage 权限)
|
||||
* 将用户创建参数挂到 req._createUser,由路由在写入 employee 后处理
|
||||
*/
|
||||
function allowUserCreation(req, res, next) {
|
||||
const { username, password, department_id } = req.body || {}
|
||||
|
||||
// 没传用户相关字段 → 只创建员工,跳过
|
||||
if (!username && !password) return next()
|
||||
|
||||
// 传了用户字段 → 必须有 user:manage 权限
|
||||
if (!req.user.permissions || !req.user.permissions.includes('user:manage')) {
|
||||
return res.status(403).json({ code: 403, message: '无权限创建用户账号' })
|
||||
}
|
||||
|
||||
// 校验必填字段
|
||||
if (!username || !password || !department_id) {
|
||||
return res.status(400).json({ code: 400, message: '用户名、密码、部门为必填' })
|
||||
}
|
||||
|
||||
if (typeof username !== 'string' || username.length < 3 || username.length > 50) {
|
||||
return res.status(400).json({ code: 400, message: '用户名长度需在 3-50 之间' })
|
||||
}
|
||||
if (typeof password !== 'string' || password.length < 6) {
|
||||
return res.status(400).json({ code: 400, message: '密码至少 6 位' })
|
||||
}
|
||||
|
||||
// 挂到 req,供路由在 INSERT employee 后使用
|
||||
req._createUser = { username, password, department_id }
|
||||
next()
|
||||
}
|
||||
|
||||
module.exports = { allowUserCreation }
|
||||
48
middleware/users.js
Normal file
48
middleware/users.js
Normal file
@@ -0,0 +1,48 @@
|
||||
// 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) {
|
||||
if (Number(req.params.id) === req.user.id) {
|
||||
return res.status(400).json({ code: 400, message: '不能删除自己' })
|
||||
}
|
||||
|
||||
const [rows] = await pool.query('SELECT department_id FROM users WHERE id = ?', [req.params.id])
|
||||
if (rows.length > 0) {
|
||||
const [adminDept] = await pool.query('SELECT id FROM departments WHERE name = ?', ['admin'])
|
||||
if (adminDept.length > 0 && rows[0].department_id === adminDept[0].id) {
|
||||
const [[{ cnt }]] = await pool.query(
|
||||
'SELECT COUNT(*) AS cnt FROM users WHERE department_id = ?',
|
||||
[adminDept[0].id]
|
||||
)
|
||||
if (cnt <= 1) {
|
||||
return res.status(400).json({ code: 400, message: '不能删除最后一个管理员' })
|
||||
}
|
||||
}
|
||||
}
|
||||
next()
|
||||
}
|
||||
|
||||
module.exports = { protectSelfUpdate, protectUserDelete }
|
||||
Reference in New Issue
Block a user