c1d6dd3b29
- 目录重命名: backend/wdkj-server/ → server/, frontend/ai-dimension/ → client/ - 删除 20+ 冗余文件(WDKJ 旧脚本、Windows 脚本、过时文档、设计稿) - 更新 package.json 元数据(移除 wdkj 命名) - 完善三级 .gitignore(根 + server + client) - 重写 README.md 和 CHANGELOG.md - 工具脚本移至 scripts/
131 lines
2.7 KiB
JavaScript
Executable File
131 lines
2.7 KiB
JavaScript
Executable File
const mongoose = require('mongoose')
|
|
const { Schema } = mongoose
|
|
const bcrypt = require('bcryptjs')
|
|
|
|
/**
|
|
* 管理员模型
|
|
*/
|
|
const AdminSchema = new Schema({
|
|
// 登录信息
|
|
username: {
|
|
type: String,
|
|
required: true,
|
|
unique: true,
|
|
trim: true,
|
|
lowercase: true,
|
|
minlength: 3,
|
|
maxlength: 30
|
|
},
|
|
password: {
|
|
type: String,
|
|
required: true,
|
|
minlength: 6
|
|
},
|
|
email: {
|
|
type: String,
|
|
trim: true,
|
|
lowercase: true
|
|
},
|
|
|
|
// 基本信息
|
|
realName: String,
|
|
phone: String,
|
|
avatar: String,
|
|
|
|
// 角色
|
|
role: {
|
|
type: String,
|
|
enum: ['super_admin', 'content_manager', 'shop_manager', 'viewer'],
|
|
default: 'viewer'
|
|
},
|
|
|
|
// 权限
|
|
permissions: [{
|
|
type: String
|
|
}],
|
|
|
|
// 状态
|
|
status: {
|
|
type: String,
|
|
enum: ['active', 'inactive', 'suspended'],
|
|
default: 'active'
|
|
},
|
|
|
|
// 登录信息
|
|
lastLogin: Date,
|
|
lastLoginIp: String,
|
|
loginCount: {
|
|
type: Number,
|
|
default: 0
|
|
},
|
|
|
|
// 时间戳
|
|
createdAt: {
|
|
type: Date,
|
|
default: Date.now
|
|
},
|
|
updatedAt: {
|
|
type: Date,
|
|
default: Date.now
|
|
}
|
|
}, {
|
|
timestamps: true,
|
|
toJSON: { virtuals: true },
|
|
toObject: { virtuals: true }
|
|
})
|
|
|
|
// 索引(username 已通过 unique: true 自动创建索引)
|
|
AdminSchema.index({ role: 1 })
|
|
|
|
// 中间件:保存前加密密码
|
|
AdminSchema.pre('save', async function(next) {
|
|
if (!this.isModified('password')) {
|
|
return next()
|
|
}
|
|
|
|
try {
|
|
const salt = await bcrypt.genSalt(10)
|
|
this.password = await bcrypt.hash(this.password, salt)
|
|
next()
|
|
} catch (error) {
|
|
next(error)
|
|
}
|
|
})
|
|
|
|
// 实例方法:验证密码
|
|
AdminSchema.methods.validatePassword = async function(password) {
|
|
return bcrypt.compare(password, this.password)
|
|
}
|
|
|
|
// 实例方法:检查权限
|
|
AdminSchema.methods.hasPermission = function(permission) {
|
|
if (this.permissions.includes('*')) return true
|
|
return this.permissions.includes(permission)
|
|
}
|
|
|
|
// 静态方法:根据角色获取权限
|
|
AdminSchema.statics.getPermissionsByRole = function(role) {
|
|
const permissionMap = {
|
|
super_admin: ['*'],
|
|
content_manager: [
|
|
'knowledge:read', 'knowledge:write', 'knowledge:delete',
|
|
'gallery:read', 'gallery:approve', 'gallery:delete',
|
|
'users:read'
|
|
],
|
|
shop_manager: [
|
|
'shop:read', 'shop:write', 'shop:delete',
|
|
'orders:read', 'orders:process', 'orders:refund',
|
|
'users:read'
|
|
],
|
|
viewer: [
|
|
'dashboard:read',
|
|
'analytics:read',
|
|
'users:read'
|
|
]
|
|
}
|
|
|
|
return permissionMap[role] || []
|
|
}
|
|
|
|
module.exports = mongoose.model('Admin', AdminSchema)
|