UML图
权限类型
operator_rule 功能操作权限
menu_rule 菜单权限
page_item_rule 页面元素
file_rule 文件权限
表设计
ruleId 权限ID
operatorId 操作ID
menuId 菜单ID
pageItemId 页面元素ID
fileId 文件ID
权限表
/** model/Permissions.js */
const Sequelize = require('sequelize');
const defaultInit = require('./config/default')
const Model = Sequelize.Model;
const { Op } = Sequelize;
class Permissions extends Model { }
/**
* 权限表
*/
module.exports = async (sequelize, force = false) => {
Permissions.init({
ruleName: {
type: Sequelize.STRING,
// 设置为 false 表示 not null
allowNull: false,
field: 'rule_name',
},
// attributes
ruleId: {
type: Sequelize.INTEGER,
// 设置为 false 表示 not null
allowNull: false,
field: 'rule_id',
unique: true,
},
ruleType: {
type: Sequelize.STRING,
// 设置为 false 表示 not null
allowNull: false,
field: 'rule_type',
unique: true,
},
...defaultInit
}, {
charset: 'utf8',
sequelize,
/** 表名称 */
tableName: 'permissions',
/** 模型名称 */
modelName: 'permissions',
// options
// 此属性约定是否自动创建,createdAt与updatedAt
timestamps: false
});
return Permissions.sync({ force: true }).then(async () => {
return {
getAll (params) {
const where = {};
if (params && params.ruleType) {
where.ruleType = params.ruleType
}
return Permissions.findAll({ where: { isDelete: { [Op.ne]: 1 }, ...where } })
},
createOperatorRule ({
ruleId,
ruleName,
createdBy
}) {
return Permissions.create({
ruleId,
ruleName,
ruleType: 'operator_rule',
createdBy: createdBy,
createdAt: new Date()
})
},
createMenuRule ({
ruleId,
ruleName,
createdBy
}) {
return Permissions.create({
ruleId,
ruleName,
ruleType: 'menu_rule',
createdBy: createdBy,
createdAt: new Date()
})
},
createPageItemRule ({
ruleId,
ruleName,
createdBy
}) {
return Permissions.create({
ruleId,
ruleName,
ruleType: 'page_item_rule',
createdBy: createdBy,
createdAt: new Date()
})
},
createFileRule ({
ruleId,
ruleName,
createdBy
}) {
return Permissions.create({
ruleId,
ruleName,
ruleType: 'file_rule',
createdBy: createdBy,
createdAt: new Date()
})
}
}
})
}
权限操作关联表
/** model/PermissionsRelative.js */
const Sequelize = require('sequelize');
const defaultInit = require('./config/default')
const Model = Sequelize.Model;
const { Op } = Sequelize;
class PermissionsRelative extends Model { }
/**
* 权限表与操作表的关联表
*/
module.exports = async (sequelize, force = false) => {
PermissionsRelative.init({
// attributes
ruleId: {
type: Sequelize.INTEGER,
// 设置为 false 表示 not null
allowNull: false,
field: 'rule_id',
},
operatorCode: { // 功能操作编码
type: Sequelize.STRING,
// 设置为 false 表示 not null
allowNull: false,
field: 'operator_code',
},
...defaultInit
}, {
charset: 'utf8',
sequelize,
/** 表名称 */
tableName: 'PermissionsRelative_operator_relation',
/** 模型名称 */
modelName: 'PermissionsRelative_operator_relation',
// options
// 此属性约定是否自动创建,createdAt与updatedAt
timestamps: false
});
return PermissionsRelative.sync({ force: true }).then(async () => {
return {
getAll (params) {
const where = {};
if (params && params.ids) {
where.ruleId = { [Op.in]: params.ids }
}
if (params && params.ruleType) {
where.ruleType = params.ruleType
}
return PermissionsRelative.findAll({ where: { isDelete: { [Op.ne]: 1 }, ...where } })
},
create ({
id,
code,
createdBy
}) {
return PermissionsRelative.create({
ruleId: id,
operatorCode: code,
createdBy: createdBy,
createdAt: new Date()
})
}
}
})
}
功能操作表
/** model/FunctionOperator.js */
const Sequelize = require('sequelize');
const defaultInit = require('./config/default')
const Model = Sequelize.Model;
const { Op } = Sequelize;
class FunctionOperator extends Model { }
/**
* 功能操作表
*
* 查询路径的规则,表示在开始位置命中,或在中间位置命中
* `${operatorId}-%` || `%-${operatorId}-%`
*/
const rules = {
operatorName: 'root',
operatorCode: 'root',
parentCode: '-',
treePath: '-',
children: [
{
operatorName: '应用管理 all',
operatorCode: 'application',
children: [
{
operatorName: '应用管理 查看',
operatorCode: 'applicationSelect',
},
{
operatorName: '应用管理 新增',
operatorCode: 'applicationCreate',
},
{
operatorName: '应用管理 编辑',
operatorCode: 'applicationUpdate',
},
{
operatorName: '应用管理 删除',
operatorCode: 'applicationDelete',
}
]
},
{
operatorName: '页面管理 all',
operatorCode: 'pages',
children: [
{
operatorName: '页面管理 查看',
operatorCode: 'pagesSelect',
},
{
operatorName: '页面管理 新增',
operatorCode: 'pagesCreate',
},
{
operatorName: '页面管理 编辑',
operatorCode: 'pagesUpdate',
},
{
operatorName: '页面管理 删除',
operatorCode: 'pagesDelete',
}
]
},
{
operatorName: '发布 all',
operatorCode: 'yidaWebPublish',
children: [
{
operatorName: '日常发布',
operatorCode: 'yidaWebPublishDev',
},
{
operatorName: '预发发布',
operatorCode: 'yidaWebPublishStaging',
},
{
operatorName: '线上发布',
operatorCode: 'yidaWebPublishProd',
},
]
},
]
}
module.exports = async (sequelize, force = false) => {
FunctionOperator.init({
// attributes
operatorName: { // 功能操作名称
type: Sequelize.STRING,
// 设置为 false 表示 not null
allowNull: false,
field: 'operator_name',
unique: true,
},
operatorCode: { // 功能操作编码
type: Sequelize.STRING,
// 设置为 false 表示 not null
allowNull: false,
field: 'operator_code',
unique: true,
},
parentCode: {
type: Sequelize.STRING,
// 设置为 false 表示 not null
allowNull: false,
field: 'parent_code',
},
treePath: {
type: Sequelize.STRING,
// 设置为 false 表示 not null
allowNull: false,
field: 'tree_path',
},
filterPath: { // 拦截Url前缀
type: Sequelize.STRING,
// 设置为 false 表示 not null
field: 'filter_path',
},
method: { // 拦截 url 请求类型
type: Sequelize.STRING,
// 设置为 false 表示 not null
field: 'filter_path',
},
...defaultInit
}, {
charset: 'utf8',
sequelize,
/** 表名称 */
tableName: 'function_operator',
/** 模型名称 */
modelName: 'function_operator',
// options
// 此属性约定是否自动创建,createdAt与updatedAt
timestamps: false
});
return FunctionOperator.sync({ force: true }).then(async () => {
const data = await FunctionOperator.findAll({});
const list = [];
if (data.length === 0) { // 初始化数据
const root = rules;
root.createdAt = new Date();
root.createdBy = '__system',
list.push(root);
const loop = (arr, parentCode, treePath) => {
arr.forEach((item) => {
item.createdAt = root.createdAt;
item.createdBy = root.createdBy;
item.parentCode = parentCode
item.treePath = treePath + `-${item.operatorCode}`
list.push(item)
if (item.children) {
loop(
item.children,
item.operatorCode,
item.treePath
)
}
delete item.children
})
}
loop(root.children, root.operatorCode, root.operatorCode)
delete root.children;
await FunctionOperator.bulkCreate(list)
}
return {
destroy (operatorCodes) {
return FunctionOperator
.destroy({ where: { operatorCode: { [Op.in]: operatorCodes } } })
.then(res => {
if (Array.isArray(res) && res.length) {
return true
}
return false
});
},
delete (operatorCodes) {
const deletedAt = new Date()
return FunctionOperator
.update({
deletedAt: deletedAt,
isDelete: 1
}, { where: { operatorCode: { [Op.in]: operatorCodes } }, })
.then(res => {
if (Array.isArray(res) && res.length) {
return true
}
return false
})
},
getAll: () => {
return FunctionOperator.findAll({ where: { isDelete: { [Op.ne]: 1 } } })
},
update: ({
updatedAt,
updatedBy,
operatorName,
filterPath,
method,
}, operatorCode) => {
return FunctionOperator.update({
updatedAt,
updatedBy,
operatorName,
filterPath,
method,
},
{ where: { operatorCode: operatorCode } })
.then(res => {
if (Array.isArray(res) && res.length) {
return true
}
return false
})
},
create: ({
createdBy,
createdAt,
operatorName,
operatorCode,
filterPath,
parentCode,
treePath,
method
}) => {
return FunctionOperator.create({
createdBy,
createdAt,
operatorName,
operatorCode,
filterPath,
parentCode,
treePath,
method
})
}
}
})
}
权限菜单关联表
权限页面元素关联表
权限文件关联表
查询设计
- 查询用户有哪些角色,查询出 roles (角色List)
- 利用 roles 查询出当前用户的所有权限 rules (权限List)
- 根据具体场景,利用 rules 去查对应 “权限类型”(【菜单,页面元素,文件,功能操作】)的对应权限
题目一:单独的功能权限设计
一、当前我有一个应用表,页面表,要设计出,控制应用表的,查看,编辑,新增,删除,发布的权限。
应用表 : appId,appName
页面表:appId,pageId,pageName
首先,先有应用 【查看,编辑,新增,删除,发布日常,发布线上】六个权限。
根据 应用表 和 功能操作表 设计出一张 “应用功能操作权限表”,
应用功能操作权限表:appId,operatorId,operatorName
用户查询角色,角色查询权限,权限根据“权限类型”去查相关操作(operatorList)。
再去查 “应用功能操作权限表” 看当前应用有没有操作权限。
题目二: 新增功能操作
一、新增一个“功能操作
”时,要关联 “权限操作关联表
”数据,并新增“权限表
”一条数据。
插入一条“功能操作”的数据,插入一条“权限操作关联”的数据,插入一条“权限表”的数据
index.js 入口文件
// 应用管理
const ApplicationInit = require('./application');
// 页面管理
const PagesInit = require('./page');
// 发布管理
const ApplicationVersionInit = require('./applicationVersion');
// 全局 数据源 管理
const ApplicationDataSource = require('./applicationDataSource');
// 权限表
const Permissions = require('./permissions');
const PermissionsRelation = require('./permissionsRelation')
// 功能表
const FunctionOperator = require('./functionOperation');
// page历史记录表
const pagesSave = require('./pageSave')
module.exports = async (sequelize) => {
const model = {}
const force = false;
model.pagesSave = await pagesSave(sequelize, force)
model.permissions = await Permissions(sequelize, force)
model.PermissionsRelation = await PermissionsRelation(sequelize, force)
model.functionOperator = await FunctionOperator(sequelize, force)
model.applicationDataSource = await ApplicationDataSource(sequelize, force);
model.application = await ApplicationInit(sequelize, force);
model.pages = await PagesInit(sequelize, force);
model.applicationVersion = await ApplicationVersionInit(sequelize, force);
return model
}
defaultInit
/** model/config/default.js */
const Sequelize = require('sequelize');
module.exports = {
createdBy: {
type: Sequelize.STRING,
allowNull: false,
field: 'created_by',
},
updatedBy: {
type: Sequelize.STRING,
field: 'updated_by'
},
deletedBy: {
type: Sequelize.STRING,
field: 'deleted_by'
},
createdAt: {
type: Sequelize.DATE,
allowNull: false,
field: 'created_at'
// allowNull defaults to true
},
updatedAt: {
type: Sequelize.DATE,
field: 'updated_at'
// allowNull defaults to true
},
/** 删除时间 */
deletedAt: {
type: Sequelize.DATE,
field: 'deleted_at'
},
/** 伪删除字段 伪删除字段 1 表示删除 */
isDelete: {
type: Sequelize.TINYINT,
field: 'is_delete',
defaultValue: 0
}
}