`image.png

5-1 路由表

src/routes/roleAccess.ts

  1. import Router from '@koa/router'
  2. import {
  3. addRoleAccessController,
  4. getRoleAccessController,
  5. getAccessByRolesController
  6. } from '../controller/roleAccess'
  7. const router = new Router({
  8. prefix: '/api/role_access'
  9. })
  10. /**
  11. * 添加菜单与角色关联
  12. * post /api/role_access'
  13. */
  14. router.post('/:id', async ctx => {
  15. const { id } = ctx.params
  16. const { access } = ctx.request.body
  17. ctx.body = await addRoleAccessController(Number(id), access)
  18. })
  19. /**
  20. * 根据角色id获取关联菜单id
  21. * post /api/role_access'
  22. */
  23. router.get('/:id', async ctx => {
  24. const { id } = ctx.params
  25. ctx.body = await getRoleAccessController(Number(id))
  26. })
  27. router.post('/role/access', async ctx => {
  28. const { roles } = ctx.request.body
  29. const ids = (roles as string[]).map(Number)
  30. ctx.body = await getAccessByRolesController(ids)
  31. // ctx.body = typeof roles
  32. })
  33. export default router

5-2 角色与菜单controller

src/controller/roleAccess.ts

  1. import {
  2. createRoleAccess,
  3. destroyRoleAccessByRoleID,
  4. getRoleAccessByID,
  5. getAccessByRolesService
  6. } from '../services/roleAccess'
  7. import { SuccessResponse, createErrorResponse } from '../utils/Response';
  8. import errorInfo from '../constants/errorInfo'
  9. const {
  10. allocRoleAccessFailInfo,
  11. getRoleAccessFailInfo
  12. } = errorInfo
  13. export const addRoleAccessController = async (id: number, access: number[]) => {
  14. // 先移除之前该角色关联记录
  15. await destroyRoleAccessByRoleID(id)
  16. try {
  17. // 批量插入记录
  18. await createRoleAccess(id, access)
  19. return new SuccessResponse(null, '权限分配成功')
  20. } catch (error) {
  21. console.error(error)
  22. return createErrorResponse(allocRoleAccessFailInfo)
  23. }
  24. }
  25. export const getRoleAccessController = async (id: number) => {
  26. try {
  27. // 批量插入记录
  28. const result = await getRoleAccessByID(id)
  29. return new SuccessResponse(result)
  30. } catch (error) {
  31. return createErrorResponse(getRoleAccessFailInfo)
  32. }
  33. }
  34. export const getAccessByRolesController = async (roles: number[]) => {
  35. try {
  36. // 批量插入记录
  37. const result = await getAccessByRolesService(roles)
  38. return new SuccessResponse(result)
  39. } catch (error) {
  40. return createErrorResponse(getRoleAccessFailInfo)
  41. }
  42. }

5-3 角色与菜单service

  1. import { AccessModel, RoleAccessModel, RolesModel } from '../db/models'
  2. import Sequelize from 'sequelize'
  3. import { AccessRole } from './types'
  4. const Op = Sequelize.Op
  5. /**
  6. * 删除与该角色相关联记录
  7. * @param id 角色id
  8. */
  9. export const destroyRoleAccessByRoleID = async (id: number) => {
  10. const result = await RoleAccessModel.destroy({
  11. where: {
  12. role_id: id
  13. }
  14. })
  15. return result
  16. }
  17. /**
  18. * 添加与该角色相关联记录
  19. * @param id 角色id
  20. * @param access 菜单id列表
  21. */
  22. export const createRoleAccess = async (id: number, access: number[]) => {
  23. const records = access.map(aid => ({
  24. role_id: id,
  25. access_id: aid
  26. }))
  27. // 批量插入
  28. const result = await RoleAccessModel.bulkCreate(records)
  29. return result
  30. }
  31. /**
  32. * 获取与该角色相关联记录
  33. * @param id 角色id
  34. */
  35. export const getRoleAccessByID = async (id: number) => {
  36. const result = await RoleAccessModel.findAll({
  37. attributes: ['id', 'role_id', 'access_id'],
  38. where: {
  39. role_id: id
  40. }
  41. })
  42. return result
  43. }
  44. export const getAccessByRolesService = async (roles: number[]) => {
  45. const { rows } = await AccessModel.findAndCountAll({
  46. // https://blog.csdn.net/Tirst_/article/details/109677451
  47. distinct: true, // 去重 解决findAndCountAll联表查询时 count数不准确问题解决
  48. order: [
  49. ['sort_id', 'ASC']
  50. ],
  51. include: [
  52. {
  53. model: RoleAccessModel,
  54. attributes: ['id'],
  55. where: {
  56. // [Op.or]: whereProps,
  57. role_id: {
  58. [Op.in]: roles
  59. }
  60. },
  61. include: [
  62. {
  63. model: RolesModel,
  64. attributes: ['id', 'name', 'description']
  65. }
  66. ]
  67. }
  68. ]
  69. })
  70. const access = rows.map(row => {
  71. const ac = row.toJSON() as AccessRole
  72. ac.roles = ac.RoleAccesses?.map(item => item.Role)
  73. delete ac.RoleAccesses
  74. return ac
  75. })
  76. return {
  77. access
  78. }
  79. }

service下类型文件

src/services/types.ts

  1. import { UserModelProps } from '../db/models/user'
  2. import { AccessModelProps } from '../db/models/access';
  3. export interface UserWhereProps {
  4. username: string;
  5. password?: string;
  6. id?: number;
  7. }
  8. interface Role {
  9. id: number;
  10. name: string;
  11. description: string;
  12. }
  13. interface UserRole {
  14. id: number,
  15. Role: Role
  16. }
  17. // 根据用户id 获取用户以及角色信息
  18. export type UserInfo = UserModelProps & {
  19. UserRoles?: UserRole[];
  20. roles?: Role[];
  21. }
  22. // 根据角色id获取资源
  23. export type AccessRole = AccessModelProps & {
  24. RoleAccesses?: UserRole[];
  25. roles?: Role[];
  26. }

目前最新源码

https://gitee.com/brolly/vue3-admin-server