Files
yunhaifinance/backend/routes/users.js
T

154 lines
5.9 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];
console.log('用户 ' + username + ' 创建成功,操作者: ' + req.user.username);
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: '用户不存在' });
}
console.log('用户 ID ' + id + ' 已更新,操作者: ' + req.user.username);
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]
);
console.log('用户 ID ' + id + ' 密码已更新,操作者: ' + req.user.username);
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]);
console.log('用户 ID ' + id + ' 已删除,操作者: ' + req.user.username);
res.json({ success: true, message: '用户删除成功' });
} catch (error) {
console.error('删除用户失败:', error);
res.status(500).json({ success: false, message: '删除用户失败' });
}
});
module.exports = router;