1、安装express
# 安装 MySQL 驱动
npm install mysql2
# 安装 dotenv 管理环境变量
# npm install dotenv
# 安装数据库连接池管理
npm install mysql2-promise
# 安装 express
npm install -g express-generator
2、新建项目
express 项目名
3、创建env文件
# 数据库配置
DB_HOST=localhost
DB_PORT=3306
DB_USER=root
DB_PASSWORD=your_password
DB_DATABASE=your_database
DB_CONNECTION_LIMIT=10
# 可选:开发/生产环境
NODE_ENV=development
4、 创建数据库连接模块
// db/connection.js
const mysql = require('mysql2/promise');
require('dotenv').config();
class Database {
constructor() {
this.pool = null;
this.init();
}
init() {
try {
this.pool = mysql.createPool({
host: process.env.DB_HOST || 'localhost',
port: process.env.DB_PORT || 3306,
user: process.env.DB_USER || 'root',
password: process.env.DB_PASSWORD || '123456',
database: process.env.DB_DATABASE || 'test',
waitForConnections: true,
connectionLimit: process.env.DB_CONNECTION_LIMIT || 10,
queueLimit: 0,
enableKeepAlive: true,
keepAliveInitialDelay: 0
});
console.log('✅ MySQL 连接池创建成功',process.env.DB_PASSWORD );
} catch (error) {
console.error('❌ 创建数据库连接池失败:', error.message);
}
}
async getConnection() {
try {
const connection = await this.pool.getConnection();
console.log('🔗 获取数据库连接成功');
return connection;
} catch (error) {
console.error('❌ 获取数据库连接失败:', error.message);
throw error;
}
}
async execute(sql, params = []) {
let connection;
try {
connection = await this.getConnection();
const [results] = await connection.execute(sql, params);
return results;
} catch (error) {
console.error('❌ 执行SQL失败:', error.message);
console.error('SQL:', sql);
console.error('参数:', params);
throw error;
} finally {
if (connection) connection.release();
}
}
async query(sql, params = []) {
try {
const [results] = await this.pool.query(sql, params);
return results;
} catch (error) {
console.error('❌ 查询失败:', error.message);
console.error('SQL:', sql);
console.error('参数:', params);
throw error;
}
}
// 测试连接
async testConnection() {
try {
const result = await this.execute('SELECT 1 + 1 AS solution');
console.log('✅ 数据库连接测试成功:', result);
return true;
} catch (error) {
console.error('❌ 数据库连接测试失败:', error.message);
return false;
}
}
// 关闭连接池
async close() {
if (this.pool) {
await this.pool.end();
console.log('🔒 数据库连接池已关闭');
}
}
}
// 创建单例实例
const database = new Database();
module.exports = database;
5、创建模型/服务层
// models/userModel.js
const db = require('./connection');
class UserModel {
// 创建用户表
async createTable() {
const sql = `
CREATE TABLE IF NOT EXISTS users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL UNIQUE,
email VARCHAR(100) NOT NULL UNIQUE,
password VARCHAR(255) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
)
`;
await db.execute(sql);
console.log('✅ 用户表创建/检查完成');
}
// 创建用户
async createUser(userData) {
const sql = `
INSERT INTO users (username, email, password)
VALUES (?, ?, ?)
`;
const params = [userData.username, userData.email, userData.password];
const result = await db.execute(sql, params);
return { id: result.insertId, ...userData };
}
// 查询所有用户
async getAllUsers() {
const sql = `SELECT id, username, email, created_at FROM users`;
return await db.execute(sql);
}
// 根据ID查询用户
async getUserById(id) {
const sql = `SELECT id, username, email, created_at FROM users WHERE id = ?`;
const results = await db.execute(sql, [id]);
return results[0] || null;
}
// 根据用户名查询用户
async getUserByUsername(username) {
const sql = `SELECT * FROM users WHERE username = ?`;
const results = await db.execute(sql, [username]);
return results[0] || null;
}
// 更新用户
async updateUser(id, userData) {
const sql = `
UPDATE users
SET username = ?, email = ?, password = ?
WHERE id = ?
`;
const params = [userData.username, userData.email, userData.password, id];
const result = await db.execute(sql, params);
return result.affectedRows > 0;
}
// 删除用户
async deleteUser(id) {
const sql = `DELETE FROM users WHERE id = ?`;
const result = await db.execute(sql, [id]);
return result.affectedRows > 0;
}
// 分页查询用户
async getUsersPaginated(page = 1, limit = 10) {
const offset = (page - 1) * limit;
const sql = `
SELECT id, username, email, created_at
FROM users
LIMIT ? OFFSET ?
`;
return await db.execute(sql, [limit, offset]);
}
// 统计用户总数
async countUsers() {
const sql = `SELECT COUNT(*) as total FROM users`;
const result = await db.execute(sql);
return result[0].total;
}
// 通用查询方法
async query(sql, params = []) {
return await db.execute(sql, params);
}
// 创建带状态的用户表
async createTable() {
const sql = `
CREATE TABLE IF NOT EXISTS users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL UNIQUE,
email VARCHAR(100) NOT NULL UNIQUE,
password VARCHAR(255) NOT NULL,
status TINYINT DEFAULT 1 COMMENT '0:禁用 1:启用 2:锁定',
gender tiny DEFAULT 0 COMMENT '0:未知 1:男 2:女',
department_id INT DEFAULT 0,
role_id INT DEFAULT 3 COMMENT '角色ID',
phone VARCHAR(20),
avatar VARCHAR(255),
last_login_time TIMESTAMP NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_username (username),
INDEX idx_status (status),
INDEX idx_department (department_id)
)
`;
await db.execute(sql);
console.log('✅ 用户表创建/检查完成');
return true;
}
}
module.exports = new UserModel();
6、创建控制器
// controllers/userController.js
const db = require('./connection');
class UserController {
// ============ 用户列表相关 ============
// 获取用户列表(带分页和查询条件)
async getUserList(req, res) {
try {
console.log('📝 收到用户列表查询请求:', req.body);
const {
page = 1,
pageSize = 10,
username,
email,
role_id,
status,
department_id,
startTime,
endTime
} = req.body;
// 构建查询条件
let whereClause = 'WHERE 1=1';
const params = [];
if (username) {
whereClause += ' AND username LIKE ?';
params.push(`%${username}%`);
}
if (email) {
whereClause += ' AND email LIKE ?';
params.push(`%${email}%`);
}
if (status !== undefined && status !== '') {
whereClause += ' AND status = ?';
params.push(parseInt(status));
}
if (role_id) {
whereClause += ' AND role_id = ?';
params.push(parseInt(role_id));
}
if (department_id) {
whereClause += ' AND department_id = ?';
params.push(parseInt(department_id));
}
if (startTime) {
whereClause += ' AND created_at >= ?';
params.push(startTime);
}
if (endTime) {
whereClause += ' AND created_at <= ?';
params.push(endTime);
}
const offset = (page - 1) * pageSize;
console.log('📊 执行用户列表查询...');
// 查询数据
const sql = `
SELECT
u.*,
r.name as role_name,
d.name as department_name
FROM users u
LEFT JOIN roles r ON u.role_id = r.id
LEFT JOIN departments d ON u.department_id = d.id
${whereClause}
ORDER BY u.id DESC
LIMIT ? OFFSET ?
`;
const rows = await db.query(sql, [...params, parseInt(pageSize), offset]);
// 查询总数
const countSql = `
SELECT COUNT(*) as total
FROM users u
LEFT JOIN roles r ON u.role_id = r.id
LEFT JOIN departments d ON u.department_id = d.id
${whereClause}
`;
const countResult = await db.query(countSql, params);
const total = countResult[0]?.total || 0;
console.log(`✅ 用户列表查询成功: 找到 ${total} 条记录,返回 ${rows.length} 条`);
// 格式化数据
const formattedRows = rows.map(row => ({
...row,
created_at: row.created_at ? new Date(row.created_at).toLocaleString('zh-CN') : '',
last_login_time: row.last_login_time ? new Date(row.last_login_time).toLocaleString('zh-CN') : null
}));
res.json({
success: true,
data: {
list: formattedRows,
total,
page: parseInt(page),
pageSize: parseInt(pageSize)
},
message: 'success'
});
} catch (error) {
console.error('❌ 获取用户列表失败:', error);
res.status(500).json({
success: false,
message: '获取用户列表失败: ' + error.message
});
}
}
// 获取树形用户列表
async getUserTreeList(req, res) {
try {
console.log('📝 收到树形用户列表请求');
// 获取所有部门
const deptSql = 'SELECT id, name FROM departments ORDER BY parent_id, id';
const departments = await db.query(deptSql);
// 获取所有用户
const userSql = `
SELECT
u.id,
u.username,
u.email,
u.department_id,
u.status,
r.name as role_name
FROM users u
LEFT JOIN roles r ON u.role_id = r.id
WHERE u.status = 1
ORDER BY u.id
`;
const users = await db.query(userSql);
// 构建树形结构
const treeData = departments.map(dept => ({
id: `dept_${dept.id}`,
name: dept.name,
type: 'department',
children: 6
.filter(user => user.department_id === dept.id)
.map(user => ({
id: user.id,
name: user.username,
email: user.email,
role: user.role_name,
type: 'user'
}))
}));
// 添加未分配部门的用户
const unassignedUsers = users.filter(user => !user.department_id);
if (unassignedUsers.length > 0) {
treeData.push({
id: 'dept_0',
name: '未分配部门',
type: 'department',
children: unassignedUsers.map(user => ({
id: user.id,
name: user.username,
email: user.email,
role: user.role_name,
type: 'user'
}))
});
}
console.log(`✅ 树形用户列表查询成功: ${treeData.length} 个部门`);
res.json({
success: true,
data: treeData,
message: 'success'
});
} catch (error) {
console.error('❌ 获取树形用户列表失败:', error);
res.status(500).json({
success: false,
message: '获取树形用户列表失败: ' + error.message
});
}
}
// ============ 字典数据相关 ============
// 获取用户状态字典
async getUserStatus(req, res) {
try {
console.log('📝 收到状态字典请求');
// 从数据库查询状态字典
const sql = 'SELECT value, label FROM user_status ORDER BY value';
const statusList = await db.query(sql);
// 如果没有表或数据,返回默认数据
if (!statusList || statusList.length === 0) {
const defaultStatus = [
{ value: 0, label: '禁用' },
{ value: 1, label: '启用' },
{ value: 2, label: '锁定' }
];
return res.json({
success: true,
data: defaultStatus,
message: 'success'
});
}
console.log(`✅ 状态字典查询成功: ${statusList.length} 条`);
res.json({
success: true,
data: statusList,
message: 'success'
});
} catch (error) {
console.error('❌ 获取用户状态字典失败:', error);
// 返回默认数据作为降级方案
const defaultStatus = [
{ value: 0, label: '禁用' },
{ value: 1, label: '启用' },
{ value: 2, label: '锁定' }
];
res.json({
success: true,
data: defaultStatus,
message: 'success'
});
}
}
// 获取用户性别字典
async getUserGender(req, res) {
try {
console.log('📝 收到性别字典请求');
// 从数据库查询性别字典
const sql = 'SELECT value, label FROM user_gender ORDER BY value';
const genderList = await db.query(sql);
// 如果没有表或数据,返回默认数据
if (!genderList || genderList.length === 0) {
const defaultGender = [
{ value: 0, label: '未知' },
{ value: 1, label: '男' },
{ value: 2, label: '女' }
];
return res.json({
success: true,
data: defaultGender,
message: 'success'
});
}
console.log(`✅ 性别字典查询成功: ${genderList.length} 条`);
res.json({
success: true,
data: genderList,
message: 'success'
});
} catch (error) {
console.error('❌ 获取用户性别字典失败:', error);
// 返回默认数据
const defaultGender = [
{ value: 0, label: '未知' },
{ value: 1, label: '男' },
{ value: 2, label: '女' }
];
res.json({
success: true,
data: defaultGender,
message: 'success'
});
}
}
// 获取用户部门列表
async getUserDepartment(req, res) {
try {
console.log('📝 收到部门列表请求');
// 从数据库查询部门
const sql = 'SELECT id, name, parent_id as parentId FROM departments ORDER BY parent_id, id';
const departmentList = await db.query(sql);
// 如果没有表或数据,返回默认数据
if (!departmentList || departmentList.length === 0) {
const defaultDepartments = [
{ id: 1, name: '技术部', parentId: 0 },
{ id: 2, name: '市场部', parentId: 0 },
{ id: 3, name: '人事部', parentId: 0 },
{ id: 4, name: '前端开发组', parentId: 1 },
{ id: 5, name: '后端开发组', parentId: 1 }
];
return res.json({
success: true,
data: defaultDepartments,
message: 'success'
});
}
console.log(`✅ 部门列表查询成功: ${departmentList.length} 条`);
res.json({
success: true,
data: departmentList,
message: 'success'
});
} catch (error) {
console.error('❌ 获取用户部门列表失败:', error);
// 返回默认数据
const defaultDepartments = [
{ id: 1, name: '技术部', parentId: 0 },
{ id: 2, name: '市场部', parentId: 0 },
{ id: 3, name: '人事部', parentId: 0 }
];
res.json({
success: true,
data: defaultDepartments,
message: 'success'
});
}
}
// 获取用户角色字典
async getUserRole(req, res) {
try {
console.log('📝 收到角色字典请求');
// 从数据库查询角色
const sql = 'SELECT id, name, code FROM roles ORDER BY id';
const roleList = await db.query(sql);
// 如果没有表或数据,返回默认数据
if (!roleList || roleList.length === 0) {
const defaultRoles = [
{ id: 1, name: '超级管理员', code: 'super_admin' },
{ id: 2, name: '管理员', code: 'admin' },
{ id: 3, name: '普通用户', code: 'user' },
{ id: 4, name: '访客', code: 'guest' }
];
return res.json({
success: true,
data: defaultRoles,
message: 'success'
});
}
console.log(`✅ 角色字典查询成功: ${roleList.length} 条`);
res.json({
success: true,
data: roleList,
message: 'success'
});
} catch (error) {
console.error('❌ 获取用户角色字典失败:', error);
// 返回默认数据
const defaultRoles = [
{ id: 1, name: '超级管理员', code: 'super_admin' },
{ id: 2, name: '管理员', code: 'admin' },
{ id: 3, name: '普通用户', code: 'user' }
];
res.json({
success: true,
data: defaultRoles,
message: 'success'
});
}
}
// ============ 用户操作相关 ============
// 新增用户
async addUser(req, res) {
try {
console.log('📝 收到新增用户请求:', req.body);
const {
username,
email,
password,
phone,
role_id,
department_id,
gender = 0,
status = 1,
remark
} = req.body;
// 验证必填字段
if (!username || !email || !password) {
return res.status(400).json({
success: false,
message: '用户名、邮箱和密码是必填项'
});
}
// 检查用户名是否已存在
const checkSql = 'SELECT id FROM users WHERE username = ? OR email = ?';
const existing = await db.query(checkSql, [username, email]);
if (existing && existing.length > 0) {
return res.status(409).json({
success: false,
message: '用户名或邮箱已存在'
});
}
// 插入用户数据
const insertSql = `
INSERT INTO users
(username, email, password, phone, role_id, department_id, gender, status, remark)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
`;
const result = await db.query(insertSql, [
username,
email,
password,
phone || null,
role_id || null,
department_id || null,
gender,
status,
remark || null
]);
console.log(`✅ 用户创建成功,ID: ${result.insertId}`);
// 获取创建的用户信息
const userSql = 'SELECT * FROM users WHERE id = ?';
const user = await db.query(userSql, [result.insertId]);
res.json({
success: true,
data: user[0],
message: '用户添加成功'
});
} catch (error) {
console.error('❌ 新增用户失败:', error);
res.status(500).json({
success: false,
message: '新增用户失败: ' + error.message
});
}
}
// 批量添加用户
async batchAddUser(req, res) {
try {
console.log('📝 收到批量添加用户请求');
// 检查是否有文件
if (!req.file) {
return res.status(400).json({
success: false,
message: '请上传文件'
});
}
// 这里可以解析Excel或CSV文件
// 暂时模拟处理
const mockUsers = [
{ username: 'batch1', email: 'batch1@test.com', password: '123456', role_id: 3, department_id: 1 },
{ username: 'batch2', email: 'batch2@test.com', password: '123456', role_id: 3, department_id: 2 }
];
const results = [];
for (const userData of mockUsers) {
try {
const insertSql = `
INSERT INTO users
(username, email, password, role_id, department_id, status)
VALUES (?, ?, ?, ?, ?, 1)
`;
const result = await db.query(insertSql, [
userData.username,
userData.email,
userData.password,
userData.role_id,
userData.department_id
]);
results.push({
id: result.insertId,
username: userData.username,
success: true
});
} catch (error) {
results.push({
username: userData.username,
success: false,
error: error.message
});
}
}
const successCount = results.filter(r => r.success).length;
const failCount = results.filter(r => !r.success).length;
console.log(`✅ 批量导入完成: 成功 ${successCount} 条,失败 ${failCount} 条`);
res.json({
success: true,
data: results,
message: `批量导入完成,成功 ${successCount} 条,失败 ${failCount} 条`
});
} catch (error) {
console.error('❌ 批量添加用户失败:', error);
res.status(500).json({
success: false,
message: '批量添加用户失败: ' + error.message
});
}
}
// 编辑用户
async editUser(req, res) {
try {
console.log('📝 收到编辑用户请求:', req.body);
const { id, ...updateData } = req.body;
if (!id) {
return res.status(400).json({
success: false,
message: '用户ID是必填项'
});
}
// 检查用户是否存在
const checkSql = 'SELECT id FROM users WHERE id = ?';
const existing = await db.query(checkSql, [id]);
if (!existing || existing.length === 0) {
return res.status(404).json({
success: false,
message: '用户不存在'
});
}
// 构建更新字段
const fields = [];
const values = [];
Object.keys(updateData).forEach(key => {
if (updateData[key] !== undefined) {
fields.push(`${key} = ?`);
values.push(updateData[key]);
}
});
if (fields.length === 0) {
return res.status(400).json({
success: false,
message: '没有提供更新数据'
});
}
values.push(id);
const sql = `UPDATE users SET ${fields.join(', ')} WHERE id = ?`;
const result = await db.query(sql, values);
console.log(`✅ 用户更新成功,ID: ${id},影响行数: ${result.affectedRows}`);
res.json({
success: true,
message: '用户编辑成功'
});
} catch (error) {
console.error('❌ 编辑用户失败:', error);
res.status(500).json({
success: false,
message: '编辑用户失败: ' + error.message
});
}
}
// 删除用户(批量)
async deleteUser(req, res) {
try {
const { id: ids } = req.body;
console.log('📝 收到删除用户请求:', ids);
if (!ids || !Array.isArray(ids) || ids.length === 0) {
return res.status(400).json({
success: false,
message: '请提供要删除的用户ID数组'
});
}
// 检查要删除的用户是否存在
const placeholders = ids.map(() => '?').join(',');
const checkSql = `SELECT COUNT(*) as count FROM users WHERE id IN (${placeholders})`;
const checkResult = await db.query(checkSql, ids);
if (checkResult[0]?.count !== ids.length) {
return res.status(404).json({
success: false,
message: '部分用户不存在'
});
}
// 使用 IN 语句批量删除
const deleteSql = `DELETE FROM users WHERE id IN (${placeholders})`;
const result = await db.query(deleteSql, ids);
console.log(`✅ 删除成功,影响行数: ${result.affectedRows}`);
res.json({
success: true,
data: { deletedCount: result.affectedRows },
message: `删除完成,成功删除 ${result.affectedRows} 个用户`
});
} catch (error) {
console.error('❌ 删除用户失败:', error);
res.status(500).json({
success: false,
message: '删除用户失败: ' + error.message
});
}
}
// 切换用户状态
async changeUserStatus(req, res) {
try {
const { id, status } = req.body;
console.log(`📝 收到切换用户状态请求: id=${id}, status=${status}`);
if (!id || status === undefined) {
return res.status(400).json({
success: false,
message: '用户ID和状态都是必填项'
});
}
// 检查用户是否存在
const checkSql = 'SELECT id FROM users WHERE id = ?';
const existing = await db.query(checkSql, [id]);
if (!existing || existing.length === 0) {
return res.status(404).json({
success: false,
message: '用户不存在'
});
}
const sql = 'UPDATE users SET status = ? WHERE id = ?';
const result = await db.query(sql, [status, id]);
console.log(`✅ 用户状态更新成功,ID: ${id},新状态: ${status}`);
res.json({
success: true,
message: '用户状态更新成功'
});
} catch (error) {
console.error('❌ 切换用户状态失败:', error);
res.status(500).json({
success: false,
message: '切换用户状态失败: ' + error.message
});
}
}
// 重置用户密码
async resetUserPassWord(req, res) {
try {
const { id } = req.body;
console.log(`📝 收到重置用户密码请求: id=${id}`);
if (!id) {
return res.status(400).json({
success: false,
message: '用户ID是必填项'
});
}
// 检查用户是否存在
const checkSql = 'SELECT id FROM users WHERE id = ?';
const existing = await db.query(checkSql, [id]);
if (!existing || existing.length === 0) {
return res.status(404).json({
success: false,
message: '用户不存在'
});
}
// 重置密码为默认密码
const defaultPassword = '123456';
const sql = 'UPDATE users SET password = ? WHERE id = ?';
const result = await db.query(sql, [defaultPassword, id]);
console.log(`✅ 用户密码重置成功,ID: ${id}`);
res.json({
success: true,
message: '用户密码重置成功,新密码为:123456'
});
} catch (error) {
console.error('❌ 重置用户密码失败:', error);
res.status(500).json({
success: false,
message: '重置用户密码失败: ' + error.message
});
}
}
// 导出用户数据
async exportUserInfo(req, res) {
try {
console.log('📝 收到导出用户数据请求');
const queryParams = req.body || {};
// 构建查询条件
let whereClause = 'WHERE 1=1';
const params = [];
if (queryParams.username) {
whereClause += ' AND username LIKE ?';
params.push(`%${queryParams.username}%`);
}
if (queryParams.status !== undefined && queryParams.status !== '') {
whereClause += ' AND status = ?';
params.push(parseInt(queryParams.status));
}
// 获取所有用户数据
const sql = `
SELECT
u.*,
r.name as role_name,
d.name as department_name,
s.label as status_label,
g.label as gender_label
FROM users u
LEFT JOIN roles r ON u.role_id = r.id
LEFT JOIN departments d ON u.department_id = d.id
LEFT JOIN user_status s ON u.status = s.value
LEFT JOIN user_gender g ON u.gender = g.value
${whereClause}
ORDER BY u.id DESC
`;
const users = await db.query(sql, params);
console.log(`✅ 导出数据查询成功: ${users.length} 条`);
// 设置响应头
res.setHeader('Content-Type', 'application/json');
res.setHeader('Content-Disposition', 'attachment; filename=users_export.json');
// 发送数据
res.json({
success: true,
data: users,
message: '导出成功'
});
} catch (error) {
console.error('❌ 导出用户数据失败:', error);
res.status(500).json({
success: false,
message: '导出用户数据失败: ' + error.message
});
}
}
// ============ 原有的兼容方法 ============
// 创建用户(保持兼容)
async createUser(req, res) {
return this.addUser(req, res);
}
// 获取所有用户(保持兼容)
async getAllUsers(req, res) {
try {
const users = await db.query(`
SELECT
u.*,
r.name as role_name,
d.name as department_name
FROM users u
LEFT JOIN roles r ON u.role_id = r.id
LEFT JOIN departments d ON u.department_id = d.id
ORDER BY u.id DESC
`);
res.json({
success: true,
data: users
});
} catch (error) {
console.error('获取所有用户失败:', error);
res.status(500).json({
success: false,
message: '服务器内部错误'
});
}
}
// 获取单个用户(保持兼容)
async getUserById(req, res) {
try {
const userId = parseInt(req.params.id);
if (isNaN(userId)) {
return res.status(400).json({
success: false,
message: '无效的用户ID'
});
}
const user = await db.query(`
SELECT
u.*,
r.name as role_name,
d.name as department_name
FROM users u
LEFT JOIN roles r ON u.role_id = r.id
LEFT JOIN departments d ON u.department_id = d.id
WHERE u.id = ?
`, [userId]);
if (!user || user.length === 0) {
return res.status(404).json({
success: false,
message: '用户不存在'
});
}
res.json({
success: true,
data: user[0]
});
} catch (error) {
console.error('获取用户失败:', error);
res.status(500).json({
success: false,
message: '服务器内部错误'
});
}
}
// 更新用户(保持兼容)
async updateUser(req, res) {
try {
const userId = parseInt(req.params.id);
const { username, email, password } = req.body;
if (isNaN(userId)) {
return res.status(400).json({
success: false,
message: '无效的用户ID'
});
}
const updateData = {};
if (username !== undefined) updateData.username = username;
if (email !== undefined) updateData.email = email;
if (password !== undefined) updateData.password = password;
const fields = Object.keys(updateData).map(key => `${key} = ?`);
const values = Object.values(updateData);
if (fields.length === 0) {
return res.status(400).json({
success: false,
message: '没有提供更新数据'
});
}
values.push(userId);
const sql = `UPDATE users SET ${fields.join(', ')} WHERE id = ?`;
const result = await db.query(sql, values);
if (result.affectedRows === 0) {
return res.status(404).json({
success: false,
message: '用户不存在'
});
}
res.json({
success: true,
message: '用户更新成功'
});
} catch (error) {
console.error('更新用户失败:', error);
res.status(500).json({
success: false,
message: '服务器内部错误'
});
}
}
// 删除用户(单个,保持兼容)
async deleteUserSingle(req, res) {
try {
const userId = parseInt(req.params.id);
if (isNaN(userId)) {
return res.status(400).json({
success: false,
message: '无效的用户ID'
});
}
const result = await db.query('DELETE FROM users WHERE id = ?', [userId]);
if (result.affectedRows === 0) {
return res.status(404).json({
success: false,
message: '用户不存在'
});
}
res.json({
success: true,
message: '用户删除成功'
});
} catch (error) {
console.error('删除用户失败:', error);
res.status(500).json({
success: false,
message: '服务器内部错误'
});
}
}
}
// 创建实例并导出
const userController = new UserController();
module.exports = userController;
7、创建路由
// routes/users.js
const express = require('express');
const router = express.Router();
const userController = require('./userController');
const multer = require('multer');
// 配置multer用于文件上传
const storage = multer.memoryStorage();
const upload = multer({
storage: storage,
limits: {
fileSize: 5 * 1024 * 1024 // 限制5MB
}
});
// 1. 获取用户列表(POST方式,支持分页查询)
router.post('/list', userController.getUserList);
// 2. 获取树形用户列表
router.post('/tree/list', userController.getUserTreeList);
// 3. 新增用户
router.post('/add', userController.addUser);
// 4. 批量添加用户(文件上传)
router.post('/import', upload.single('file'), userController.batchAddUser);
// 5. 编辑用户
router.post('/edit', userController.editUser);
// 6. 删除用户(批量)
router.post('/delete', userController.deleteUser);
// 7. 切换用户状态
router.post('/change', userController.changeUserStatus);
// 8. 重置用户密码
router.post('/rest_password', userController.resetUserPassWord);
// 9. 导出用户数据
router.post('/export', userController.exportUserInfo);
// 10. 获取用户状态字典
router.get('/status', userController.getUserStatus);
// 11. 获取用户性别字典
router.get('/gender', userController.getUserGender);
// 12. 获取用户部门列表
router.get('/department', userController.getUserDepartment);
// 13. 获取用户角色字典
router.get('/role', userController.getUserRole);
// 14. 健康检查路由
router.get('/health', async (req, res) => {
const db = require('../db/connection');
const isConnected = await db.testConnection();
res.json({
success: isConnected,
database: isConnected ? 'connected' : 'disconnected',
timestamp: new Date().toISOString(),
service: 'User API'
});
});
// 15. 原有的RESTful风格接口(兼容性支持)
router.post('/users', userController.createUser); // 创建用户
router.get('/users', userController.getAllUsers); // 获取所有用户
router.get('/users/:id', userController.getUserById); // 获取单个用户
router.put('/users/:id', userController.updateUser); // 更新用户
router.delete('/users/:id', userController.deleteUserSingle); // 删除单个用户
module.exports = router;
8、修改app.js
// app.js - 添加数据库相关配置
require('dotenv').config(); // 在文件顶部添加
// 在路由之前添加数据库初始化
const db = require('./db/connection');
const userModel = require('./models/userModel');
// 初始化数据库表(可选)
async function initializeDatabase() {
try {
const isConnected = await db.testConnection();
if (isConnected) {
await userModel.createTable();
console.log('✅ 数据库初始化完成');
}
} catch (error) {
console.error('❌ 数据库初始化失败:', error);
}
}
// 启动时初始化
initializeDatabase();
9、初始化数据库
// scripts/init-tables.js
require('dotenv').config();
const db = require('./connection');
async function initTables() {
try {
console.log('🔄 开始初始化数据库表...');
// 1. 创建状态字典表
await db.query(`
CREATE TABLE IF NOT EXISTS user_status (
id INT AUTO_INCREMENT PRIMARY KEY,
value INT NOT NULL UNIQUE,
label VARCHAR(20) NOT NULL
)
`);
await db.query(`
INSERT IGNORE INTO user_status (value, label) VALUES
(0, '禁用'),
(1, '启用'),
(2, '锁定')
`);
console.log('✅ 状态字典表创建完成');
// 2. 创建性别字典表
await db.query(`
CREATE TABLE IF NOT EXISTS user_gender (
id INT AUTO_INCREMENT PRIMARY KEY,
value INT NOT NULL UNIQUE,
label VARCHAR(10) NOT NULL
)
`);
await db.query(`
INSERT IGNORE INTO user_gender (value, label) VALUES
(0, '未知'),
(1, '男'),
(2, '女')
`);
console.log('✅ 性别字典表创建完成');
// 3. 创建部门表
await db.query(`
CREATE TABLE IF NOT EXISTS departments (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(50) NOT NULL,
parent_id INT DEFAULT 0,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
`);
await db.query(`
INSERT IGNORE INTO departments (id, name, parent_id) VALUES
(1, '技术部', 0),
(2, '市场部', 0),
(3, '人事部', 0),
(4, '前端开发组', 1),
(5, '后端开发组', 1)
`);
console.log('✅ 部门表创建完成');
// 4. 创建角色表
await db.query(`
CREATE TABLE IF NOT EXISTS roles (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(50) NOT NULL,
code VARCHAR(50) NOT NULL UNIQUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
`);
await db.query(`
INSERT IGNORE INTO roles (id, name, code) VALUES
(1, '超级管理员', 'super_admin'),
(2, '管理员', 'admin'),
(3, '普通用户', 'user'),
(4, '访客', 'guest')
`);
console.log('✅ 角色表创建完成');
// 5. 创建用户表
await db.query(`
CREATE TABLE IF NOT EXISTS users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL UNIQUE,
email VARCHAR(100) NOT NULL UNIQUE,
password VARCHAR(255) NOT NULL,
phone VARCHAR(20) DEFAULT NULL,
status TINYINT DEFAULT 1 COMMENT '0:禁用 1:启用',
gender TINYINT DEFAULT 0 COMMENT '0:未知 1:男 2:女',
department_id INT DEFAULT NULL,
role_id INT DEFAULT NULL,
avatar VARCHAR(255) DEFAULT NULL,
remark TEXT DEFAULT NULL,
last_login_time TIMESTAMP NULL DEFAULT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
)
`);
console.log('✅ 用户表创建完成');
// 6. 插入测试用户数据
await db.query(`
INSERT IGNORE INTO users (username, email, password, phone, role_id, department_id, gender, status) VALUES
('admin', 'admin@example.com', '123456', '13800138000', 1, 1, 1, 1),
('test_user', 'test@example.com', '123456', '13800138001', 3, 4, 1, 1),
('zhangsan', 'zhangsan@example.com', '123456', '13800138002', 3, 5, 1, 1),
('lisi', 'lisi@example.com', '123456', '13800138003', 3, 2, 2, 0)
`);
console.log('✅ 测试用户数据插入完成');
console.log('\n🎉 所有表初始化完成!');
} catch (error) {
console.error('❌ 初始化失败:', error.message);
}
}
initTables();
10、 运行数据库初始化脚本并下载依赖
node scripts/init-tables.js
npm i
11、 启动项目
node ./bin/www