const { DataTypes } = require('sequelize'); const bcrypt = require('bcryptjs'); module.exports = (sequelize) => { const Employee = sequelize.define('Employee', { id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true }, employeeNumber: { type: DataTypes.STRING(20), allowNull: false, unique: true, comment: '员工编号' }, name: { type: DataTypes.STRING(50), allowNull: false, comment: '员工姓名' }, phone: { type: DataTypes.STRING(20), allowNull: false, comment: '联系电话' }, email: { type: DataTypes.STRING(100), allowNull: true, comment: '邮箱' }, password: { type: DataTypes.STRING(255), allowNull: false, comment: '密码' }, isLoanSpecialist: { type: DataTypes.BOOLEAN, defaultValue: false, comment: '是否为贷款专员' }, department: { type: DataTypes.STRING(50), allowNull: true, comment: '部门' }, position: { type: DataTypes.STRING(50), allowNull: true, comment: '职位' }, status: { type: DataTypes.ENUM('active', 'inactive', 'locked'), defaultValue: 'active', comment: '账号状态' }, lastLogin: { type: DataTypes.DATE, allowNull: true, comment: '最后登录时间' }, loginAttempts: { type: DataTypes.INTEGER, defaultValue: 0, comment: '登录尝试次数' }, lockedUntil: { type: DataTypes.DATE, allowNull: true, comment: '锁定到期时间' } }, { tableName: 'bank_employees', timestamps: true, createdAt: 'created_at', updatedAt: 'updated_at', paranoid: true, deletedAt: 'deleted_at', comment: '银行员工表', hooks: { beforeSave: async (employee) => { if (employee.changed('password')) { const salt = await bcrypt.genSalt(10); employee.password = await bcrypt.hash(employee.password, salt); } } } }); // 实例方法:验证密码 Employee.prototype.validPassword = async function(password) { try { return await bcrypt.compare(password, this.password); } catch (error) { console.error('密码验证错误:', error); return false; } }; // 实例方法:检查账号是否被锁定 Employee.prototype.isLocked = function() { return !!(this.lockedUntil && this.lockedUntil > Date.now()); }; // 实例方法:增加登录尝试次数 Employee.prototype.incLoginAttempts = async function() { // 如果已经锁定且锁定时间已过,则重置 if (this.lockedUntil && this.lockedUntil < Date.now()) { return this.update({ loginAttempts: 1, lockedUntil: null }); } const updates = { loginAttempts: this.loginAttempts + 1 }; // 如果达到最大尝试次数,则锁定账号 if (this.loginAttempts + 1 >= 5 && !this.isLocked()) { updates.lockedUntil = new Date(Date.now() + 30 * 60 * 1000); // 锁定30分钟 } return this.update(updates); }; // 实例方法:重置登录尝试次数 Employee.prototype.resetLoginAttempts = async function() { return this.update({ loginAttempts: 0, lockedUntil: null }); }; return Employee; };