5-1 路由表
src/routes/roleAccess.ts
import Router from '@koa/router'import {addRoleAccessController,getRoleAccessController,getAccessByRolesController} from '../controller/roleAccess'const router = new Router({prefix: '/api/role_access'})/*** 添加菜单与角色关联* post /api/role_access'*/router.post('/:id', async ctx => {const { id } = ctx.paramsconst { access } = ctx.request.bodyctx.body = await addRoleAccessController(Number(id), access)})/*** 根据角色id获取关联菜单id* post /api/role_access'*/router.get('/:id', async ctx => {const { id } = ctx.paramsctx.body = await getRoleAccessController(Number(id))})router.post('/role/access', async ctx => {const { roles } = ctx.request.bodyconst ids = (roles as string[]).map(Number)ctx.body = await getAccessByRolesController(ids)// ctx.body = typeof roles})export default router
5-2 角色与菜单controller
src/controller/roleAccess.ts
import {createRoleAccess,destroyRoleAccessByRoleID,getRoleAccessByID,getAccessByRolesService} from '../services/roleAccess'import { SuccessResponse, createErrorResponse } from '../utils/Response';import errorInfo from '../constants/errorInfo'const {allocRoleAccessFailInfo,getRoleAccessFailInfo} = errorInfoexport const addRoleAccessController = async (id: number, access: number[]) => {// 先移除之前该角色关联记录await destroyRoleAccessByRoleID(id)try {// 批量插入记录await createRoleAccess(id, access)return new SuccessResponse(null, '权限分配成功')} catch (error) {console.error(error)return createErrorResponse(allocRoleAccessFailInfo)}}export const getRoleAccessController = async (id: number) => {try {// 批量插入记录const result = await getRoleAccessByID(id)return new SuccessResponse(result)} catch (error) {return createErrorResponse(getRoleAccessFailInfo)}}export const getAccessByRolesController = async (roles: number[]) => {try {// 批量插入记录const result = await getAccessByRolesService(roles)return new SuccessResponse(result)} catch (error) {return createErrorResponse(getRoleAccessFailInfo)}}
5-3 角色与菜单service
import { AccessModel, RoleAccessModel, RolesModel } from '../db/models'import Sequelize from 'sequelize'import { AccessRole } from './types'const Op = Sequelize.Op/*** 删除与该角色相关联记录* @param id 角色id*/export const destroyRoleAccessByRoleID = async (id: number) => {const result = await RoleAccessModel.destroy({where: {role_id: id}})return result}/*** 添加与该角色相关联记录* @param id 角色id* @param access 菜单id列表*/export const createRoleAccess = async (id: number, access: number[]) => {const records = access.map(aid => ({role_id: id,access_id: aid}))// 批量插入const result = await RoleAccessModel.bulkCreate(records)return result}/*** 获取与该角色相关联记录* @param id 角色id*/export const getRoleAccessByID = async (id: number) => {const result = await RoleAccessModel.findAll({attributes: ['id', 'role_id', 'access_id'],where: {role_id: id}})return result}export const getAccessByRolesService = async (roles: number[]) => {const { rows } = await AccessModel.findAndCountAll({// https://blog.csdn.net/Tirst_/article/details/109677451distinct: true, // 去重 解决findAndCountAll联表查询时 count数不准确问题解决order: [['sort_id', 'ASC']],include: [{model: RoleAccessModel,attributes: ['id'],where: {// [Op.or]: whereProps,role_id: {[Op.in]: roles}},include: [{model: RolesModel,attributes: ['id', 'name', 'description']}]}]})const access = rows.map(row => {const ac = row.toJSON() as AccessRoleac.roles = ac.RoleAccesses?.map(item => item.Role)delete ac.RoleAccessesreturn ac})return {access}}
service下类型文件
src/services/types.ts
import { UserModelProps } from '../db/models/user'import { AccessModelProps } from '../db/models/access';export interface UserWhereProps {username: string;password?: string;id?: number;}interface Role {id: number;name: string;description: string;}interface UserRole {id: number,Role: Role}// 根据用户id 获取用户以及角色信息export type UserInfo = UserModelProps & {UserRoles?: UserRole[];roles?: Role[];}// 根据角色id获取资源export type AccessRole = AccessModelProps & {RoleAccesses?: UserRole[];roles?: Role[];}
