添加银行政府后端接口

This commit is contained in:
2025-09-25 15:53:44 +08:00
parent b17bdcc24c
commit 5b6b7e0a96
60 changed files with 5345 additions and 1920 deletions

View File

@@ -1,77 +1,73 @@
/**
* 员工控制器
* @file employeeController.js
* @description 处理员工相关的请求
*/
const { Employee, Department, Position } = require('../models');
const { Employee, User } = require('../models');
const { validationResult } = require('express-validator');
const { Op } = require('sequelize');
const bcrypt = require('bcryptjs');
/**
* 获取员工列表
* @param {Object} req 请求对象
* @param {Object} res 响应对象
*/
exports.getEmployees = async (req, res) => {
const getEmployees = async (req, res) => {
try {
const {
page = 1,
limit = 10,
search = '',
department = '',
position = '',
pageSize = 10,
searchField = 'name',
searchValue = '',
status = '',
sortBy = 'created_at',
sortOrder = 'DESC'
isLoanSpecialist = ''
} = req.query;
const offset = (page - 1) * limit;
const whereClause = {};
// 搜索条件
if (search) {
whereClause[Op.or] = [
{ name: { [Op.like]: `%${search}%` } },
{ employee_id: { [Op.like]: `%${search}%` } },
{ phone: { [Op.like]: `%${search}%` } },
{ email: { [Op.like]: `%${search}%` } }
];
// 构建查询条件
const where = {};
if (searchValue) {
if (searchField === 'name') {
where.name = { [require('sequelize').Op.like]: `%${searchValue}%` };
} else if (searchField === 'phone') {
where.phone = { [require('sequelize').Op.like]: `%${searchValue}%` };
} else if (searchField === 'employeeNumber') {
where.employeeNumber = { [require('sequelize').Op.like]: `%${searchValue}%` };
}
}
// 部门筛选
if (department) {
whereClause.department_id = department;
}
// 职位筛选
if (position) {
whereClause.position_id = position;
}
// 状态筛选
if (status) {
whereClause.status = status;
where.status = status;
}
const { count, rows: employees } = await Employee.findAndCountAll({
where: whereClause,
include: [
{
model: Department,
as: 'department',
attributes: ['id', 'name']
},
{
model: Position,
as: 'position',
attributes: ['id', 'name', 'level']
}
],
order: [[sortBy, sortOrder.toUpperCase()]],
limit: parseInt(limit),
offset: parseInt(offset)
if (isLoanSpecialist !== '') {
where.isLoanSpecialist = isLoanSpecialist === 'true';
}
// 分页参数
const offset = (parseInt(page) - 1) * parseInt(pageSize);
const limit = parseInt(pageSize);
// 查询数据
const { count, rows } = await Employee.findAndCountAll({
where,
limit,
offset,
order: [['createdAt', 'DESC']],
attributes: {
exclude: ['password'] // 不返回密码
}
});
// 格式化数据
const employees = rows.map(employee => ({
id: employee.id,
employeeNumber: employee.employeeNumber,
name: employee.name,
phone: employee.phone,
email: employee.email,
isLoanSpecialist: employee.isLoanSpecialist,
department: employee.department,
position: employee.position,
status: employee.status,
lastLogin: employee.lastLogin,
createdAt: employee.createdAt,
updatedAt: employee.updatedAt
}));
res.json({
success: true,
message: '获取员工列表成功',
@@ -79,113 +75,32 @@ exports.getEmployees = async (req, res) => {
employees,
pagination: {
current: parseInt(page),
pageSize: parseInt(limit),
pageSize: parseInt(pageSize),
total: count,
pages: Math.ceil(count / limit)
pages: Math.ceil(count / parseInt(pageSize))
}
}
});
} catch (error) {
console.error('获取员工列表错误:', error);
console.error('获取员工列表失败:', error);
res.status(500).json({
success: false,
message: '服务器内部错误',
error: error.message
});
}
};
/**
* 创建员工
* @param {Object} req 请求对象
* @param {Object} res 响应对象
*/
exports.createEmployee = async (req, res) => {
try {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({
success: false,
message: '输入数据验证失败',
errors: errors.array()
});
}
const {
name,
employee_id,
department_id,
position_id,
phone,
email,
hire_date,
salary,
status = 'active'
} = req.body;
// 检查员工编号是否已存在
const existingEmployee = await Employee.findOne({
where: { employee_id }
});
if (existingEmployee) {
return res.status(400).json({
success: false,
message: '员工编号已存在'
});
}
const employee = await Employee.create({
name,
employee_id,
department_id,
position_id,
phone,
email,
hire_date,
salary: salary * 100, // 转换为分
status
});
res.status(201).json({
success: true,
message: '创建员工成功',
data: employee
});
} catch (error) {
console.error('创建员工错误:', error);
res.status(500).json({
success: false,
message: '服务器内部错误',
error: error.message
message: '获取员工列表失败'
});
}
};
/**
* 获取员工详情
* @param {Object} req 请求对象
* @param {Object} res 响应对象
*/
exports.getEmployeeById = async (req, res) => {
const getEmployeeById = async (req, res) => {
try {
const { id } = req.params;
const employee = await Employee.findByPk(id, {
include: [
{
model: Department,
as: 'department',
attributes: ['id', 'name', 'description']
},
{
model: Position,
as: 'position',
attributes: ['id', 'name', 'level', 'description']
}
]
attributes: {
exclude: ['password'] // 不返回密码
}
});
if (!employee) {
@@ -200,43 +115,128 @@ exports.getEmployeeById = async (req, res) => {
message: '获取员工详情成功',
data: employee
});
} catch (error) {
console.error('获取员工详情错误:', error);
console.error('获取员工详情失败:', error);
res.status(500).json({
success: false,
message: '服务器内部错误',
error: error.message
message: '获取员工详情失败'
});
}
};
/**
* 更新员工
* @param {Object} req 请求对象
* @param {Object} res 响应对象
* 创建员工
*/
exports.updateEmployee = async (req, res) => {
const createEmployee = async (req, res) => {
try {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({
success: false,
message: '输入数据验证失败',
message: '请求参数错误',
errors: errors.array()
});
}
const {
employeeNumber,
name,
phone,
email,
password,
isLoanSpecialist,
department,
position
} = req.body;
// 检查员工编号是否已存在
const existingEmployee = await Employee.findOne({
where: { employeeNumber }
});
if (existingEmployee) {
return res.status(400).json({
success: false,
message: '员工编号已存在'
});
}
// 检查手机号是否已存在
const existingPhone = await Employee.findOne({
where: { phone }
});
if (existingPhone) {
return res.status(400).json({
success: false,
message: '手机号已存在'
});
}
// 创建员工
const employee = await Employee.create({
employeeNumber,
name,
phone,
email,
password: password || '123456', // 默认密码
isLoanSpecialist: isLoanSpecialist || false,
department,
position,
status: 'active'
});
res.status(201).json({
success: true,
message: '创建员工成功',
data: {
id: employee.id,
employeeNumber: employee.employeeNumber,
name: employee.name,
phone: employee.phone,
email: employee.email,
isLoanSpecialist: employee.isLoanSpecialist,
department: employee.department,
position: employee.position,
status: employee.status,
createdAt: employee.createdAt
}
});
} catch (error) {
console.error('创建员工失败:', error);
res.status(500).json({
success: false,
message: '创建员工失败'
});
}
};
/**
* 更新员工信息
*/
const updateEmployee = async (req, res) => {
try {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({
success: false,
message: '请求参数错误',
errors: errors.array()
});
}
const { id } = req.params;
const updateData = req.body;
// 如果更新薪资,转换为分
if (updateData.salary) {
updateData.salary = updateData.salary * 100;
}
const {
name,
phone,
email,
isLoanSpecialist,
department,
position,
status
} = req.body;
const employee = await Employee.findByPk(id);
if (!employee) {
return res.status(404).json({
success: false,
@@ -244,35 +244,101 @@ exports.updateEmployee = async (req, res) => {
});
}
await employee.update(updateData);
// 检查手机号是否被其他员工使用
if (phone && phone !== employee.phone) {
const existingPhone = await Employee.findOne({
where: {
phone,
id: { [require('sequelize').Op.ne]: id }
}
});
if (existingPhone) {
return res.status(400).json({
success: false,
message: '手机号已被其他员工使用'
});
}
}
// 更新员工信息
await employee.update({
name,
phone,
email,
isLoanSpecialist,
department,
position,
status
});
res.json({
success: true,
message: '更新员工成功',
data: employee
message: '更新员工信息成功',
data: {
id: employee.id,
employeeNumber: employee.employeeNumber,
name: employee.name,
phone: employee.phone,
email: employee.email,
isLoanSpecialist: employee.isLoanSpecialist,
department: employee.department,
position: employee.position,
status: employee.status,
updatedAt: employee.updatedAt
}
});
} catch (error) {
console.error('更新员工错误:', error);
console.error('更新员工信息失败:', error);
res.status(500).json({
success: false,
message: '服务器内部错误',
error: error.message
message: '更新员工信息失败'
});
}
};
/**
* 重设密码
*/
const resetPassword = async (req, res) => {
try {
const { id } = req.params;
const { newPassword } = req.body;
const employee = await Employee.findByPk(id);
if (!employee) {
return res.status(404).json({
success: false,
message: '员工不存在'
});
}
// 更新密码
await employee.update({
password: newPassword || '123456' // 默认密码
});
res.json({
success: true,
message: '重设密码成功'
});
} catch (error) {
console.error('重设密码失败:', error);
res.status(500).json({
success: false,
message: '重设密码失败'
});
}
};
/**
* 删除员工
* @param {Object} req 请求对象
* @param {Object} res 响应对象
*/
exports.deleteEmployee = async (req, res) => {
const deleteEmployee = async (req, res) => {
try {
const { id } = req.params;
const employee = await Employee.findByPk(id);
if (!employee) {
return res.status(404).json({
success: false,
@@ -280,87 +346,105 @@ exports.deleteEmployee = async (req, res) => {
});
}
// 软删除
await employee.destroy();
res.json({
success: true,
message: '删除员工成功'
});
} catch (error) {
console.error('删除员工错误:', error);
console.error('删除员工失败:', error);
res.status(500).json({
success: false,
message: '服务器内部错误',
error: error.message
message: '删除员工失败'
});
}
};
/**
* 获取员工统计
* @param {Object} req 请求对象
* @param {Object} res 响应对象
* 批量更新员工状态
*/
exports.getEmployeeStats = async (req, res) => {
const batchUpdateStatus = async (req, res) => {
try {
const { ids, status } = req.body;
if (!ids || !Array.isArray(ids) || ids.length === 0) {
return res.status(400).json({
success: false,
message: '请选择要更新的员工'
});
}
if (!status) {
return res.status(400).json({
success: false,
message: '请选择要更新的状态'
});
}
await Employee.update(
{
status
},
{
where: {
id: { [require('sequelize').Op.in]: ids }
}
}
);
res.json({
success: true,
message: '批量更新状态成功'
});
} catch (error) {
console.error('批量更新状态失败:', error);
res.status(500).json({
success: false,
message: '批量更新状态失败'
});
}
};
/**
* 获取员工统计信息
*/
const getEmployeeStats = async (req, res) => {
try {
const totalEmployees = await Employee.count();
const activeEmployees = await Employee.count({ where: { status: 'active' } });
const inactiveEmployees = await Employee.count({ where: { status: 'inactive' } });
const departmentStats = await Employee.findAll({
attributes: [
'department_id',
[Employee.sequelize.fn('COUNT', Employee.sequelize.col('id')), 'count']
],
include: [{
model: Department,
as: 'department',
attributes: ['name']
}],
group: ['department_id', 'department.id'],
raw: false
});
const positionStats = await Employee.findAll({
attributes: [
'position_id',
[Employee.sequelize.fn('COUNT', Employee.sequelize.col('id')), 'count']
],
include: [{
model: Position,
as: 'position',
attributes: ['name', 'level']
}],
group: ['position_id', 'position.id'],
raw: false
});
const lockedEmployees = await Employee.count({ where: { status: 'locked' } });
const loanSpecialists = await Employee.count({ where: { isLoanSpecialist: true } });
res.json({
success: true,
message: '获取员工统计成功',
data: {
total: totalEmployees,
active: activeEmployees,
inactive: inactiveEmployees,
departmentStats: departmentStats.map(item => ({
department: item.department.name,
count: parseInt(item.dataValues.count)
})),
positionStats: positionStats.map(item => ({
position: item.position.name,
level: item.position.level,
count: parseInt(item.dataValues.count)
}))
totalEmployees,
activeEmployees,
inactiveEmployees,
lockedEmployees,
loanSpecialists
}
});
} catch (error) {
console.error('获取员工统计错误:', error);
console.error('获取员工统计失败:', error);
res.status(500).json({
success: false,
message: '服务器内部错误',
error: error.message
message: '获取员工统计失败'
});
}
};
module.exports = {
getEmployees,
getEmployeeById,
createEmployee,
updateEmployee,
resetPassword,
deleteEmployee,
batchUpdateStatus,
getEmployeeStats
};