122 lines
2.7 KiB
JavaScript
122 lines
2.7 KiB
JavaScript
const { DataTypes } = require('sequelize');
|
|
const { sequelize } = require('../config/database');
|
|
const bcrypt = require('bcryptjs');
|
|
|
|
// 用户模型
|
|
const User = sequelize.define('User', {
|
|
id: {
|
|
type: DataTypes.BIGINT,
|
|
primaryKey: true,
|
|
autoIncrement: true
|
|
},
|
|
uuid: {
|
|
type: DataTypes.STRING(36),
|
|
allowNull: false,
|
|
unique: true,
|
|
defaultValue: DataTypes.UUIDV4
|
|
},
|
|
username: {
|
|
type: DataTypes.STRING(50),
|
|
allowNull: false,
|
|
unique: true,
|
|
validate: {
|
|
len: [2, 50]
|
|
}
|
|
},
|
|
password_hash: {
|
|
type: DataTypes.STRING(255),
|
|
allowNull: false
|
|
},
|
|
phone: {
|
|
type: DataTypes.STRING(20),
|
|
allowNull: false,
|
|
unique: true,
|
|
validate: {
|
|
is: /^1[3-9]\d{9}$/
|
|
}
|
|
},
|
|
email: {
|
|
type: DataTypes.STRING(100),
|
|
validate: {
|
|
isEmail: true
|
|
}
|
|
},
|
|
real_name: DataTypes.STRING(50),
|
|
avatar_url: DataTypes.STRING(255),
|
|
user_type: {
|
|
type: DataTypes.ENUM('client', 'supplier', 'driver', 'staff', 'admin'),
|
|
allowNull: false,
|
|
defaultValue: 'client'
|
|
},
|
|
status: {
|
|
type: DataTypes.ENUM('active', 'inactive', 'locked'),
|
|
defaultValue: 'active'
|
|
},
|
|
last_login_at: DataTypes.DATE,
|
|
login_count: {
|
|
type: DataTypes.INTEGER,
|
|
defaultValue: 0
|
|
}
|
|
}, {
|
|
tableName: 'users',
|
|
timestamps: true,
|
|
paranoid: true, // 软删除
|
|
indexes: [
|
|
{ fields: ['phone'] },
|
|
{ fields: ['user_type'] },
|
|
{ fields: ['status'] },
|
|
{ fields: ['username'] }
|
|
],
|
|
hooks: {
|
|
beforeCreate: async (user) => {
|
|
if (user.password_hash) {
|
|
user.password_hash = await bcrypt.hash(user.password_hash, 12);
|
|
}
|
|
},
|
|
beforeUpdate: async (user) => {
|
|
if (user.changed('password_hash')) {
|
|
user.password_hash = await bcrypt.hash(user.password_hash, 12);
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
// 实例方法:验证密码
|
|
User.prototype.validatePassword = async function(password) {
|
|
return await bcrypt.compare(password, this.password_hash);
|
|
};
|
|
|
|
// 实例方法:更新登录信息
|
|
User.prototype.updateLoginInfo = async function() {
|
|
this.last_login_at = new Date();
|
|
this.login_count += 1;
|
|
await this.save();
|
|
};
|
|
|
|
// 类方法:根据用户名或手机号查找用户
|
|
User.findByLoginIdentifier = async function(identifier) {
|
|
return await this.findOne({
|
|
where: {
|
|
[sequelize.Sequelize.Op.or]: [
|
|
{ username: identifier },
|
|
{ phone: identifier }
|
|
]
|
|
}
|
|
});
|
|
};
|
|
|
|
// 类方法:创建用户
|
|
User.createUser = async function(userData) {
|
|
const { username, password, phone, email, real_name, user_type = 'client' } = userData;
|
|
|
|
return await this.create({
|
|
username,
|
|
password_hash: password,
|
|
phone,
|
|
email,
|
|
real_name,
|
|
user_type
|
|
});
|
|
};
|
|
|
|
module.exports = User; |