diff --git a/middleware/employees.js b/middleware/employees.js new file mode 100644 index 0000000..53a271c --- /dev/null +++ b/middleware/employees.js @@ -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 } diff --git a/middleware/users.js b/middleware/users.js new file mode 100644 index 0000000..c0b5ad1 --- /dev/null +++ b/middleware/users.js @@ -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 }