refactor: 项目架构重构 - 目录标准化 + 清理冗余
- 目录重命名: backend/wdkj-server/ → server/, frontend/ai-dimension/ → client/ - 删除 20+ 冗余文件(WDKJ 旧脚本、Windows 脚本、过时文档、设计稿) - 更新 package.json 元数据(移除 wdkj 命名) - 完善三级 .gitignore(根 + server + client) - 重写 README.md 和 CHANGELOG.md - 工具脚本移至 scripts/
This commit is contained in:
Executable
+130
@@ -0,0 +1,130 @@
|
||||
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)
|
||||
Reference in New Issue
Block a user