UML图

1561626104773-d6bd0964-326a-48a0-81ad-989de7a0ac53.png

权限类型

operator_rule 功能操作权限
menu_rule 菜单权限
page_item_rule 页面元素
file_rule 文件权限

表设计

ruleId 权限ID
operatorId 操作ID
menuId 菜单ID
pageItemId 页面元素ID
fileId 文件ID

权限表

  1. /** model/Permissions.js */
  2. const Sequelize = require('sequelize');
  3. const defaultInit = require('./config/default')
  4. const Model = Sequelize.Model;
  5. const { Op } = Sequelize;
  6. class Permissions extends Model { }
  7. /**
  8. * 权限表
  9. */
  10. module.exports = async (sequelize, force = false) => {
  11. Permissions.init({
  12. ruleName: {
  13. type: Sequelize.STRING,
  14. // 设置为 false 表示 not null
  15. allowNull: false,
  16. field: 'rule_name',
  17. },
  18. // attributes
  19. ruleId: {
  20. type: Sequelize.INTEGER,
  21. // 设置为 false 表示 not null
  22. allowNull: false,
  23. field: 'rule_id',
  24. unique: true,
  25. },
  26. ruleType: {
  27. type: Sequelize.STRING,
  28. // 设置为 false 表示 not null
  29. allowNull: false,
  30. field: 'rule_type',
  31. unique: true,
  32. },
  33. ...defaultInit
  34. }, {
  35. charset: 'utf8',
  36. sequelize,
  37. /** 表名称 */
  38. tableName: 'permissions',
  39. /** 模型名称 */
  40. modelName: 'permissions',
  41. // options
  42. // 此属性约定是否自动创建,createdAt与updatedAt
  43. timestamps: false
  44. });
  45. return Permissions.sync({ force: true }).then(async () => {
  46. return {
  47. getAll (params) {
  48. const where = {};
  49. if (params && params.ruleType) {
  50. where.ruleType = params.ruleType
  51. }
  52. return Permissions.findAll({ where: { isDelete: { [Op.ne]: 1 }, ...where } })
  53. },
  54. createOperatorRule ({
  55. ruleId,
  56. ruleName,
  57. createdBy
  58. }) {
  59. return Permissions.create({
  60. ruleId,
  61. ruleName,
  62. ruleType: 'operator_rule',
  63. createdBy: createdBy,
  64. createdAt: new Date()
  65. })
  66. },
  67. createMenuRule ({
  68. ruleId,
  69. ruleName,
  70. createdBy
  71. }) {
  72. return Permissions.create({
  73. ruleId,
  74. ruleName,
  75. ruleType: 'menu_rule',
  76. createdBy: createdBy,
  77. createdAt: new Date()
  78. })
  79. },
  80. createPageItemRule ({
  81. ruleId,
  82. ruleName,
  83. createdBy
  84. }) {
  85. return Permissions.create({
  86. ruleId,
  87. ruleName,
  88. ruleType: 'page_item_rule',
  89. createdBy: createdBy,
  90. createdAt: new Date()
  91. })
  92. },
  93. createFileRule ({
  94. ruleId,
  95. ruleName,
  96. createdBy
  97. }) {
  98. return Permissions.create({
  99. ruleId,
  100. ruleName,
  101. ruleType: 'file_rule',
  102. createdBy: createdBy,
  103. createdAt: new Date()
  104. })
  105. }
  106. }
  107. })
  108. }

权限操作关联表

  1. /** model/PermissionsRelative.js */
  2. const Sequelize = require('sequelize');
  3. const defaultInit = require('./config/default')
  4. const Model = Sequelize.Model;
  5. const { Op } = Sequelize;
  6. class PermissionsRelative extends Model { }
  7. /**
  8. * 权限表与操作表的关联表
  9. */
  10. module.exports = async (sequelize, force = false) => {
  11. PermissionsRelative.init({
  12. // attributes
  13. ruleId: {
  14. type: Sequelize.INTEGER,
  15. // 设置为 false 表示 not null
  16. allowNull: false,
  17. field: 'rule_id',
  18. },
  19. operatorCode: { // 功能操作编码
  20. type: Sequelize.STRING,
  21. // 设置为 false 表示 not null
  22. allowNull: false,
  23. field: 'operator_code',
  24. },
  25. ...defaultInit
  26. }, {
  27. charset: 'utf8',
  28. sequelize,
  29. /** 表名称 */
  30. tableName: 'PermissionsRelative_operator_relation',
  31. /** 模型名称 */
  32. modelName: 'PermissionsRelative_operator_relation',
  33. // options
  34. // 此属性约定是否自动创建,createdAt与updatedAt
  35. timestamps: false
  36. });
  37. return PermissionsRelative.sync({ force: true }).then(async () => {
  38. return {
  39. getAll (params) {
  40. const where = {};
  41. if (params && params.ids) {
  42. where.ruleId = { [Op.in]: params.ids }
  43. }
  44. if (params && params.ruleType) {
  45. where.ruleType = params.ruleType
  46. }
  47. return PermissionsRelative.findAll({ where: { isDelete: { [Op.ne]: 1 }, ...where } })
  48. },
  49. create ({
  50. id,
  51. code,
  52. createdBy
  53. }) {
  54. return PermissionsRelative.create({
  55. ruleId: id,
  56. operatorCode: code,
  57. createdBy: createdBy,
  58. createdAt: new Date()
  59. })
  60. }
  61. }
  62. })
  63. }

功能操作表

  1. /** model/FunctionOperator.js */
  2. const Sequelize = require('sequelize');
  3. const defaultInit = require('./config/default')
  4. const Model = Sequelize.Model;
  5. const { Op } = Sequelize;
  6. class FunctionOperator extends Model { }
  7. /**
  8. * 功能操作表
  9. *
  10. * 查询路径的规则,表示在开始位置命中,或在中间位置命中
  11. * `${operatorId}-%` || `%-${operatorId}-%`
  12. */
  13. const rules = {
  14. operatorName: 'root',
  15. operatorCode: 'root',
  16. parentCode: '-',
  17. treePath: '-',
  18. children: [
  19. {
  20. operatorName: '应用管理 all',
  21. operatorCode: 'application',
  22. children: [
  23. {
  24. operatorName: '应用管理 查看',
  25. operatorCode: 'applicationSelect',
  26. },
  27. {
  28. operatorName: '应用管理 新增',
  29. operatorCode: 'applicationCreate',
  30. },
  31. {
  32. operatorName: '应用管理 编辑',
  33. operatorCode: 'applicationUpdate',
  34. },
  35. {
  36. operatorName: '应用管理 删除',
  37. operatorCode: 'applicationDelete',
  38. }
  39. ]
  40. },
  41. {
  42. operatorName: '页面管理 all',
  43. operatorCode: 'pages',
  44. children: [
  45. {
  46. operatorName: '页面管理 查看',
  47. operatorCode: 'pagesSelect',
  48. },
  49. {
  50. operatorName: '页面管理 新增',
  51. operatorCode: 'pagesCreate',
  52. },
  53. {
  54. operatorName: '页面管理 编辑',
  55. operatorCode: 'pagesUpdate',
  56. },
  57. {
  58. operatorName: '页面管理 删除',
  59. operatorCode: 'pagesDelete',
  60. }
  61. ]
  62. },
  63. {
  64. operatorName: '发布 all',
  65. operatorCode: 'yidaWebPublish',
  66. children: [
  67. {
  68. operatorName: '日常发布',
  69. operatorCode: 'yidaWebPublishDev',
  70. },
  71. {
  72. operatorName: '预发发布',
  73. operatorCode: 'yidaWebPublishStaging',
  74. },
  75. {
  76. operatorName: '线上发布',
  77. operatorCode: 'yidaWebPublishProd',
  78. },
  79. ]
  80. },
  81. ]
  82. }
  83. module.exports = async (sequelize, force = false) => {
  84. FunctionOperator.init({
  85. // attributes
  86. operatorName: { // 功能操作名称
  87. type: Sequelize.STRING,
  88. // 设置为 false 表示 not null
  89. allowNull: false,
  90. field: 'operator_name',
  91. unique: true,
  92. },
  93. operatorCode: { // 功能操作编码
  94. type: Sequelize.STRING,
  95. // 设置为 false 表示 not null
  96. allowNull: false,
  97. field: 'operator_code',
  98. unique: true,
  99. },
  100. parentCode: {
  101. type: Sequelize.STRING,
  102. // 设置为 false 表示 not null
  103. allowNull: false,
  104. field: 'parent_code',
  105. },
  106. treePath: {
  107. type: Sequelize.STRING,
  108. // 设置为 false 表示 not null
  109. allowNull: false,
  110. field: 'tree_path',
  111. },
  112. filterPath: { // 拦截Url前缀
  113. type: Sequelize.STRING,
  114. // 设置为 false 表示 not null
  115. field: 'filter_path',
  116. },
  117. method: { // 拦截 url 请求类型
  118. type: Sequelize.STRING,
  119. // 设置为 false 表示 not null
  120. field: 'filter_path',
  121. },
  122. ...defaultInit
  123. }, {
  124. charset: 'utf8',
  125. sequelize,
  126. /** 表名称 */
  127. tableName: 'function_operator',
  128. /** 模型名称 */
  129. modelName: 'function_operator',
  130. // options
  131. // 此属性约定是否自动创建,createdAt与updatedAt
  132. timestamps: false
  133. });
  134. return FunctionOperator.sync({ force: true }).then(async () => {
  135. const data = await FunctionOperator.findAll({});
  136. const list = [];
  137. if (data.length === 0) { // 初始化数据
  138. const root = rules;
  139. root.createdAt = new Date();
  140. root.createdBy = '__system',
  141. list.push(root);
  142. const loop = (arr, parentCode, treePath) => {
  143. arr.forEach((item) => {
  144. item.createdAt = root.createdAt;
  145. item.createdBy = root.createdBy;
  146. item.parentCode = parentCode
  147. item.treePath = treePath + `-${item.operatorCode}`
  148. list.push(item)
  149. if (item.children) {
  150. loop(
  151. item.children,
  152. item.operatorCode,
  153. item.treePath
  154. )
  155. }
  156. delete item.children
  157. })
  158. }
  159. loop(root.children, root.operatorCode, root.operatorCode)
  160. delete root.children;
  161. await FunctionOperator.bulkCreate(list)
  162. }
  163. return {
  164. destroy (operatorCodes) {
  165. return FunctionOperator
  166. .destroy({ where: { operatorCode: { [Op.in]: operatorCodes } } })
  167. .then(res => {
  168. if (Array.isArray(res) && res.length) {
  169. return true
  170. }
  171. return false
  172. });
  173. },
  174. delete (operatorCodes) {
  175. const deletedAt = new Date()
  176. return FunctionOperator
  177. .update({
  178. deletedAt: deletedAt,
  179. isDelete: 1
  180. }, { where: { operatorCode: { [Op.in]: operatorCodes } }, })
  181. .then(res => {
  182. if (Array.isArray(res) && res.length) {
  183. return true
  184. }
  185. return false
  186. })
  187. },
  188. getAll: () => {
  189. return FunctionOperator.findAll({ where: { isDelete: { [Op.ne]: 1 } } })
  190. },
  191. update: ({
  192. updatedAt,
  193. updatedBy,
  194. operatorName,
  195. filterPath,
  196. method,
  197. }, operatorCode) => {
  198. return FunctionOperator.update({
  199. updatedAt,
  200. updatedBy,
  201. operatorName,
  202. filterPath,
  203. method,
  204. },
  205. { where: { operatorCode: operatorCode } })
  206. .then(res => {
  207. if (Array.isArray(res) && res.length) {
  208. return true
  209. }
  210. return false
  211. })
  212. },
  213. create: ({
  214. createdBy,
  215. createdAt,
  216. operatorName,
  217. operatorCode,
  218. filterPath,
  219. parentCode,
  220. treePath,
  221. method
  222. }) => {
  223. return FunctionOperator.create({
  224. createdBy,
  225. createdAt,
  226. operatorName,
  227. operatorCode,
  228. filterPath,
  229. parentCode,
  230. treePath,
  231. method
  232. })
  233. }
  234. }
  235. })
  236. }

权限菜单关联表

权限页面元素关联表

权限文件关联表

查询设计

  1. 查询用户有哪些角色,查询出 roles (角色List)
  2. 利用 roles 查询出当前用户的所有权限 rules (权限List)
  3. 根据具体场景,利用 rules 去查对应 “权限类型”(【菜单,页面元素,文件,功能操作】)的对应权限

题目一:单独的功能权限设计

一、当前我有一个应用表,页面表,要设计出,控制应用表的,查看,编辑,新增,删除,发布的权限。
应用表 : appId,appName
页面表:appId,pageId,pageName

首先,先有应用 【查看,编辑,新增,删除,发布日常,发布线上】六个权限。

根据 应用表 和 功能操作表 设计出一张 “应用功能操作权限表”,
应用功能操作权限表:appId,operatorId,operatorName

用户查询角色,角色查询权限,权限根据“权限类型”去查相关操作(operatorList)。

再去查 “应用功能操作权限表” 看当前应用有没有操作权限。

题目二: 新增功能操作

一、新增一个“功能操作”时,要关联 “权限操作关联表”数据,并新增“权限表”一条数据。
插入一条“功能操作”的数据,插入一条“权限操作关联”的数据,插入一条“权限表”的数据

index.js 入口文件

  1. // 应用管理
  2. const ApplicationInit = require('./application');
  3. // 页面管理
  4. const PagesInit = require('./page');
  5. // 发布管理
  6. const ApplicationVersionInit = require('./applicationVersion');
  7. // 全局 数据源 管理
  8. const ApplicationDataSource = require('./applicationDataSource');
  9. // 权限表
  10. const Permissions = require('./permissions');
  11. const PermissionsRelation = require('./permissionsRelation')
  12. // 功能表
  13. const FunctionOperator = require('./functionOperation');
  14. // page历史记录表
  15. const pagesSave = require('./pageSave')
  16. module.exports = async (sequelize) => {
  17. const model = {}
  18. const force = false;
  19. model.pagesSave = await pagesSave(sequelize, force)
  20. model.permissions = await Permissions(sequelize, force)
  21. model.PermissionsRelation = await PermissionsRelation(sequelize, force)
  22. model.functionOperator = await FunctionOperator(sequelize, force)
  23. model.applicationDataSource = await ApplicationDataSource(sequelize, force);
  24. model.application = await ApplicationInit(sequelize, force);
  25. model.pages = await PagesInit(sequelize, force);
  26. model.applicationVersion = await ApplicationVersionInit(sequelize, force);
  27. return model
  28. }

defaultInit

  1. /** model/config/default.js */
  2. const Sequelize = require('sequelize');
  3. module.exports = {
  4. createdBy: {
  5. type: Sequelize.STRING,
  6. allowNull: false,
  7. field: 'created_by',
  8. },
  9. updatedBy: {
  10. type: Sequelize.STRING,
  11. field: 'updated_by'
  12. },
  13. deletedBy: {
  14. type: Sequelize.STRING,
  15. field: 'deleted_by'
  16. },
  17. createdAt: {
  18. type: Sequelize.DATE,
  19. allowNull: false,
  20. field: 'created_at'
  21. // allowNull defaults to true
  22. },
  23. updatedAt: {
  24. type: Sequelize.DATE,
  25. field: 'updated_at'
  26. // allowNull defaults to true
  27. },
  28. /** 删除时间 */
  29. deletedAt: {
  30. type: Sequelize.DATE,
  31. field: 'deleted_at'
  32. },
  33. /** 伪删除字段 伪删除字段 1 表示删除 */
  34. isDelete: {
  35. type: Sequelize.TINYINT,
  36. field: 'is_delete',
  37. defaultValue: 0
  38. }
  39. }