150 lines
5.6 KiB
JavaScript
150 lines
5.6 KiB
JavaScript
const express = require('express');
|
|
const router = express.Router();
|
|
const db = require('../db');
|
|
const { hashPassword, verifyPassword } = require('../utils/auth');
|
|
const { authenticate, requireAdmin } = require('../middleware/auth');
|
|
|
|
router.get('/', authenticate, requireAdmin, async (req, res) => {
|
|
try {
|
|
const usersResult = await db.query('SELECT id, username, name, email, phone, role, is_active, created_at, updated_at FROM users ORDER BY id');
|
|
const users = usersResult.rows;
|
|
res.json({ success: true, data: users, count: users.length });
|
|
} catch (error) {
|
|
console.error('获取用户列表失败:', error);
|
|
res.status(500).json({ success: false, message: '获取用户列表失败' });
|
|
}
|
|
});
|
|
|
|
router.post('/', authenticate, requireAdmin, async (req, res) => {
|
|
try {
|
|
const { username, name, email, phone, role, password } = req.body;
|
|
|
|
if (!username || !name || !password) {
|
|
return res.status(400).json({ success: false, message: '用户名、姓名和密码为必填项' });
|
|
}
|
|
|
|
const existingUser = await db.query('SELECT id FROM users WHERE username = $1', [username]);
|
|
if (existingUser.rows.length > 0) {
|
|
return res.status(400).json({ success: false, message: '用户名已存在' });
|
|
}
|
|
|
|
const passwordHash = hashPassword(password);
|
|
|
|
const result = await db.query(
|
|
'INSERT INTO users (username, password_hash, name, email, phone, role, created_at, updated_at) VALUES ($1, $2, $3, $4, $5, $6, NOW(), NOW()) RETURNING id',
|
|
[username, passwordHash, name, email || null, phone || null, role || 'employee']
|
|
);
|
|
|
|
const newUserResult = await db.query('SELECT id, username, name, email, phone, role, is_active, created_at, updated_at FROM users WHERE id = $1', [result.rows[0].id]);
|
|
const newUser = newUserResult.rows[0];
|
|
|
|
res.json({ success: true, data: newUser });
|
|
} catch (error) {
|
|
console.error('创建用户失败:', error);
|
|
res.status(500).json({ success: false, message: '创建用户失败' });
|
|
}
|
|
});
|
|
|
|
router.put('/:id', authenticate, requireAdmin, async (req, res) => {
|
|
try {
|
|
const { id } = req.params;
|
|
const { name, email, phone, role, password } = req.body;
|
|
|
|
if (password) {
|
|
const passwordHash = hashPassword(password);
|
|
await db.query(
|
|
'UPDATE users SET name = $1, email = $2, phone = $3, role = $4, password_hash = $5, updated_at = NOW() WHERE id = $6',
|
|
[name, email || null, phone || null, role, passwordHash, id]
|
|
);
|
|
} else {
|
|
await db.query(
|
|
'UPDATE users SET name = $1, email = $2, phone = $3, role = $4, updated_at = NOW() WHERE id = $5',
|
|
[name, email || null, phone || null, role, id]
|
|
);
|
|
}
|
|
|
|
const updatedUserResult = await db.query('SELECT id, username, name, email, phone, role, is_active, created_at, updated_at FROM users WHERE id = $1', [id]);
|
|
const updatedUser = updatedUserResult.rows[0];
|
|
|
|
if (!updatedUser) {
|
|
return res.status(404).json({ success: false, message: '用户不存在' });
|
|
}
|
|
|
|
res.json({ success: true, data: updatedUser });
|
|
} catch (error) {
|
|
console.error('更新用户信息失败:', error);
|
|
res.status(500).json({ success: false, message: '更新用户信息失败' });
|
|
}
|
|
});
|
|
|
|
router.put('/:id/password', authenticate, async (req, res) => {
|
|
try {
|
|
const { id } = req.params;
|
|
const { currentPassword, newPassword } = req.body;
|
|
|
|
if (!newPassword) {
|
|
return res.status(400).json({ success: false, message: '新密码不能为空' });
|
|
}
|
|
|
|
const userResult = await db.query('SELECT id, password_hash FROM users WHERE id = $1', [id]);
|
|
if (userResult.rows.length === 0) {
|
|
return res.status(404).json({ success: false, message: '用户不存在' });
|
|
}
|
|
|
|
const user = userResult.rows[0];
|
|
const isAdmin = req.user.role === 'admin';
|
|
const isSelf = req.user.id === parseInt(id);
|
|
|
|
if (isSelf && currentPassword) {
|
|
if (!verifyPassword(currentPassword, user.password_hash)) {
|
|
return res.status(400).json({ success: false, message: '当前密码错误' });
|
|
}
|
|
} else if (!isAdmin) {
|
|
return res.status(403).json({ success: false, message: '只能修改自己的密码' });
|
|
}
|
|
|
|
const newPasswordHash = hashPassword(newPassword);
|
|
|
|
await db.query(
|
|
'UPDATE users SET password_hash = $1, updated_at = NOW() WHERE id = $2',
|
|
[newPasswordHash, id]
|
|
);
|
|
|
|
res.json({ success: true, message: '密码更新成功' });
|
|
} catch (error) {
|
|
console.error('更新密码失败:', error);
|
|
res.status(500).json({ success: false, message: '更新密码失败' });
|
|
}
|
|
});
|
|
|
|
router.delete('/:id', authenticate, requireAdmin, async (req, res) => {
|
|
try {
|
|
const { id } = req.params;
|
|
|
|
if (parseInt(id) === req.user.id) {
|
|
return res.status(400).json({ success: false, message: '不能删除自己' });
|
|
}
|
|
|
|
const existingUser = await db.query('SELECT id, role FROM users WHERE id = $1', [id]);
|
|
if (existingUser.rows.length === 0) {
|
|
return res.status(404).json({ success: false, message: '用户不存在' });
|
|
}
|
|
|
|
if (existingUser.rows[0].role === 'admin') {
|
|
const adminCount = await db.query("SELECT COUNT(*) as cnt FROM users WHERE role = 'admin'");
|
|
if (parseInt(adminCount.rows[0].cnt) <= 1) {
|
|
return res.status(400).json({ success: false, message: '至少需要保留一个管理员账号' });
|
|
}
|
|
}
|
|
|
|
await db.query('DELETE FROM users WHERE id = $1', [id]);
|
|
|
|
res.json({ success: true, message: '用户删除成功' });
|
|
} catch (error) {
|
|
console.error('删除用户失败:', error);
|
|
res.status(500).json({ success: false, message: '删除用户失败' });
|
|
}
|
|
});
|
|
|
|
module.exports = router;
|