Compare commits
No commits in common. '7488c21ed5a641e9a375e050fa13b588d6906a40' and 'f2504b390fb977e5398a6b07f913176203566be8' have entirely different histories.
7488c21ed5
...
f2504b390f
File diff suppressed because it is too large
Load Diff
@ -1,63 +0,0 @@ |
||||
import { Controller, Get, Post, Body, Patch, Param, Delete, Query } from '@nestjs/common'; |
||||
import { AuthRoleService } from './auth-role.service'; |
||||
import { CreateAuthRoleDto } from './dto/create-auth-role.dto'; |
||||
import { UpdateAuthRoleDto } from './dto/update-auth-role.dto'; |
||||
import { ApiOperation, ApiProduces, ApiTags } from '@nestjs/swagger'; |
||||
import { PacInfo } from '@common/decorator/pac-info/pac-info.decorator'; |
||||
import { PacInfoType } from '@utils/myType'; |
||||
import { query } from 'express'; |
||||
import { GetPacAuthRoleAllDto } from '@app/auth-role/dto/get-auth-role.dto'; |
||||
|
||||
@ApiTags('角色服务') |
||||
@Controller('authRole') |
||||
export class AuthRoleController { |
||||
constructor(private readonly authRoleService: AuthRoleService) {} |
||||
|
||||
@ApiOperation({ |
||||
summary: '添加角色', |
||||
description: '增加一个角色,菜单和数据权限', |
||||
}) |
||||
@ApiProduces('application/json') |
||||
@Post() |
||||
create(@Body() createAuthRoleDto: CreateAuthRoleDto, @PacInfo() pacInfo: PacInfoType) { |
||||
return this.authRoleService.create(createAuthRoleDto, pacInfo); |
||||
} |
||||
|
||||
@ApiOperation({ |
||||
summary: '获取角色列表', |
||||
description: '查询角色分页或者列表', |
||||
}) |
||||
@ApiProduces('application/json') |
||||
@Get() |
||||
findAll(@Query() getPacAuthRoleAllDto: GetPacAuthRoleAllDto) { |
||||
return this.authRoleService.findAll(getPacAuthRoleAllDto); |
||||
} |
||||
@ApiOperation({ |
||||
summary: '获取角色详细信息', |
||||
description: '查询角色详细信息,目录菜单列表,数据权限范围', |
||||
}) |
||||
@ApiProduces('application/json') |
||||
@Get(':id') |
||||
findOne(@Param('id') id: string) { |
||||
return this.authRoleService.findOne(id); |
||||
} |
||||
|
||||
@ApiOperation({ |
||||
summary: '更新角色信息', |
||||
description: '更新角色信息', |
||||
}) |
||||
@ApiProduces('application/json') |
||||
@Patch(':id') |
||||
update(@Param('id') id: string, @Body() updateAuthRoleDto: UpdateAuthRoleDto, @PacInfo() pacInfo: PacInfoType) { |
||||
return this.authRoleService.update(id, updateAuthRoleDto, pacInfo); |
||||
} |
||||
@ApiOperation({ |
||||
summary: '删除目标角色', |
||||
description: '删除目标角色信息', |
||||
}) |
||||
@ApiProduces('application/json') |
||||
@Delete(':id') |
||||
remove(@Param('id') id: string, @PacInfo() pacInfo: PacInfoType) { |
||||
return this.authRoleService.remove(id, pacInfo); |
||||
} |
||||
} |
@ -1,9 +0,0 @@ |
||||
import { Module } from '@nestjs/common'; |
||||
import { AuthRoleService } from './auth-role.service'; |
||||
import { AuthRoleController } from './auth-role.controller'; |
||||
|
||||
@Module({ |
||||
controllers: [AuthRoleController], |
||||
providers: [AuthRoleService], |
||||
}) |
||||
export class AuthRoleModule {} |
@ -1,517 +0,0 @@ |
||||
import { HttpException, HttpStatus, Injectable } from '@nestjs/common'; |
||||
import { CreateAuthRoleDto } from './dto/create-auth-role.dto'; |
||||
import { UpdateAuthRoleDto } from './dto/update-auth-role.dto'; |
||||
import { LoggerService } from '@service/logger/logger.service'; |
||||
import { MysqlService } from '@common/service/mysql/mysql.service'; |
||||
import { RedisService } from '@common/service/redis/redis.service'; |
||||
import { Snowflake } from '@service/snowflake/snowflake.service'; |
||||
import { ConfigService } from '@nestjs/config'; |
||||
import { PacInfoType } from '@utils/myType'; |
||||
import { isExistKey, isTrueEnum } from '@utils/boolean.enum'; |
||||
import { pacAuthDept, pacAuthLinkRoleDept, pacAuthLinkRoleMenu, pacAuthRole, pacAuthUser, pacCoreDict, pacCoreMenu } from '@entities/schema'; |
||||
import { and, asc, desc, eq, isNull, like, or, sql } from 'drizzle-orm'; |
||||
import { GetPacAuthRoleAllDto } from '@app/auth-role/dto/get-auth-role.dto'; |
||||
import { likeQuery } from '@utils/likeQuery'; |
||||
import { alias } from 'drizzle-orm/mysql-core'; |
||||
|
||||
@Injectable() |
||||
export class AuthRoleService { |
||||
// 基本分页信息
|
||||
private readonly rolePageType = { |
||||
roleId: pacAuthRole.roleId, |
||||
pid: pacAuthRole.pid, |
||||
roleName: pacAuthRole.roleName, |
||||
roleKey: pacAuthRole.roleKey, |
||||
roleDesc: pacAuthRole.roleDesc, |
||||
roleType: pacAuthRole.roleType, |
||||
roleTypeName: pacCoreDict.dictName, |
||||
roleTypeKey: pacCoreDict.dictKey, |
||||
deptScope: pacAuthRole.deptScope, |
||||
haveChildren: pacAuthRole.haveChildren, |
||||
root: pacAuthRole.root, |
||||
orderNum: pacAuthRole.orderNum, |
||||
status: pacAuthRole.status, |
||||
createby: pacAuthRole.createby, |
||||
createName: pacAuthUser.nickname, |
||||
createtime: pacAuthRole.createtime, |
||||
updateby: pacAuthRole.updateby, |
||||
updatetime: pacAuthRole.updatetime, |
||||
}; |
||||
|
||||
// 角色详细信息
|
||||
private readonly roleMoreType = { |
||||
roleId: pacAuthRole.roleId, |
||||
pid: pacAuthRole.pid, |
||||
roleName: pacAuthRole.roleName, |
||||
roleKey: pacAuthRole.roleKey, |
||||
roleDesc: pacAuthRole.roleDesc, |
||||
roleType: pacAuthRole.roleType, |
||||
roleTypeName: pacCoreDict.dictName, |
||||
roleTypeKey: pacCoreDict.dictKey, |
||||
deptScope: pacAuthRole.deptScope, |
||||
root: pacAuthRole.root, |
||||
orderNum: pacAuthRole.orderNum, |
||||
status: pacAuthRole.status, |
||||
createby: pacAuthRole.createby, |
||||
createName: pacAuthUser.nickname, |
||||
createtime: pacAuthRole.createtime, |
||||
updateby: pacAuthRole.updateby, |
||||
updateName: pacAuthUser.nickname, |
||||
updatetime: pacAuthRole.updatetime, |
||||
}; |
||||
|
||||
// 角色列表/数信息
|
||||
private readonly roleListType = { |
||||
roleId: pacAuthRole.roleId, |
||||
pid: pacAuthRole.pid, |
||||
roleName: pacAuthRole.roleName, |
||||
roleKey: pacAuthRole.roleKey, |
||||
roleType: pacAuthRole.roleType, |
||||
roleTypeName: pacCoreDict.dictName, |
||||
deptScope: pacAuthRole.deptScope, |
||||
orderNum: pacAuthRole.orderNum, |
||||
}; |
||||
constructor( |
||||
private readonly logger: LoggerService, |
||||
private readonly mysqlService: MysqlService, |
||||
private readonly redisService: RedisService, |
||||
private readonly snowflake: Snowflake, |
||||
private readonly config: ConfigService, |
||||
) {} |
||||
|
||||
/** Service |
||||
* NAME: create |
||||
* DESC: 创建角色信息 |
||||
* DATE: 2024-06-25 15:53:04 - |
||||
* */ |
||||
public async create(createAuthRoleDto: CreateAuthRoleDto, pacInfo: PacInfoType) { |
||||
// ! 判断是否是root账户,非root账户无法设置为root
|
||||
if (this.config.get<number>('masterId') !== pacInfo.userId && isTrueEnum(createAuthRoleDto.root)) { |
||||
throw new HttpException('没有权限创建原始角色!', HttpStatus.UNAUTHORIZED); |
||||
} |
||||
|
||||
// ! 加目标锁
|
||||
const lock = await this.redisService.distributedLock('DICT' + createAuthRoleDto.roleKey, createAuthRoleDto.roleKey); |
||||
|
||||
// ? 存在正在进行写入的角色
|
||||
if (!lock) throw new HttpException('服务繁忙,角色标识重复!', HttpStatus.CONFLICT); |
||||
|
||||
// @ 核心内容
|
||||
try { |
||||
// ! 查重
|
||||
const result = await this.getRoleForRoleKey(createAuthRoleDto.roleKey); |
||||
|
||||
// ? 是否存在重复的角色
|
||||
if (result.length > 0) throw new HttpException('角色标识重复!', HttpStatus.CONFLICT); |
||||
|
||||
// ! 添加角色数据
|
||||
const newRoleResult = await this.addRoleData(createAuthRoleDto, pacInfo.userId).catch((e) => { |
||||
this.logger.error(e.message + e.track.toString()); |
||||
throw new HttpException('角色写入错误!', HttpStatus.INTERNAL_SERVER_ERROR); |
||||
}); |
||||
|
||||
// ! 增加关联菜单
|
||||
await this.createMenuLink(newRoleResult.roleId, createAuthRoleDto.menuList, pacInfo.userId as any).catch((e) => { |
||||
this.logger.error(e.message + e.track.toString()); |
||||
throw new HttpException('添加菜单关系出现错误,角色写入错误!', HttpStatus.INTERNAL_SERVER_ERROR); |
||||
}); |
||||
|
||||
// ! 增加关联部门
|
||||
if (createAuthRoleDto.deptScope == 5) { |
||||
await this.createDeptLink(newRoleResult.roleId, createAuthRoleDto.deptList, pacInfo.userId as any).catch((e) => { |
||||
this.logger.error(e.message + e.track.toString()); |
||||
throw new HttpException('添加部门数据范围关系出现错误,角色写入错误!', HttpStatus.INTERNAL_SERVER_ERROR); |
||||
}); |
||||
} |
||||
|
||||
// ! 解锁
|
||||
lock(); |
||||
|
||||
// !更新父节点的子节点数量
|
||||
await this.haveChildrenSelfIncreasing(createAuthRoleDto.pid); |
||||
|
||||
// ! 返回结果
|
||||
return newRoleResult; |
||||
} catch (e) { |
||||
// ! 解锁
|
||||
lock(); |
||||
|
||||
// ! 抛出错误
|
||||
throw e; |
||||
} |
||||
} |
||||
|
||||
/** Service |
||||
* NAME: findAll |
||||
* DESC: 获取角色信息列表/分页 |
||||
* DATE: 2024-06-26 13:53:03 - |
||||
* */ |
||||
public async findAll(getPacAuthRoleAllDto: GetPacAuthRoleAllDto) { |
||||
if (isTrueEnum(getPacAuthRoleAllDto['isList'])) { |
||||
return await this.getRoleList(getPacAuthRoleAllDto); |
||||
} else { |
||||
return await this.getRolePage(getPacAuthRoleAllDto); |
||||
} |
||||
} |
||||
|
||||
/** Service |
||||
* NAME: findOne |
||||
* DESC: 获取角色详细信息 |
||||
* DATE: 2024-06-26 16:15:21 - |
||||
* */ |
||||
findOne(id: string) { |
||||
return this.getRoleMore(id); |
||||
} |
||||
|
||||
public async update(roleId: string, updateAuthRoleDto: UpdateAuthRoleDto, pacInfo: PacInfoType) { |
||||
// ! 查找角色信息
|
||||
const roleData = await this.getRoleForRoleId(roleId); |
||||
|
||||
// ? 当不存在角色信息
|
||||
if (roleData.length == 0) { |
||||
throw new HttpException('未找到目标角色信息,无法修改!', HttpStatus.BAD_REQUEST); |
||||
} |
||||
|
||||
// ! 判断是否是root账户,非root账户无法设置为root
|
||||
if (this.config.get('masterId') !== pacInfo.userId && isTrueEnum(roleData[0].root)) { |
||||
throw new HttpException('没有权限创建原始角色!', HttpStatus.UNAUTHORIZED); |
||||
} |
||||
|
||||
// ! 加目标锁
|
||||
const lock = await this.redisService.distributedLock('DICT' + updateAuthRoleDto.roleKey, updateAuthRoleDto.roleKey); |
||||
|
||||
// ? 存在正在进行写入的角色
|
||||
if (!lock) throw new HttpException('服务繁忙,角色标识重复!', HttpStatus.CONFLICT); |
||||
|
||||
// @ 核心内容
|
||||
try { |
||||
// ! 查重
|
||||
const checkRepeat = await this.getRoleForRoleKey(updateAuthRoleDto.roleKey); |
||||
|
||||
// ? 是否存在重复的角色
|
||||
if (checkRepeat.length > 0 && checkRepeat[0].roleId != roleId) throw new HttpException('角色标识重复!', HttpStatus.CONFLICT); |
||||
|
||||
// ! 修改角色数据
|
||||
const result = await this.updateRole(roleId, updateAuthRoleDto, pacInfo.userId as any).catch((e) => { |
||||
this.logger.error(e.message + e.track.toString()); |
||||
throw new HttpException('角色写入错误!', HttpStatus.INTERNAL_SERVER_ERROR); |
||||
}); |
||||
|
||||
// ! 增加关联菜单
|
||||
await this.createMenuLink(roleData[0].roleId, updateAuthRoleDto.menuList, pacInfo.userId as any).catch((e) => { |
||||
this.logger.error(e.message + e.track.toString()); |
||||
throw new HttpException('添加菜单关系出现错误,角色写入错误!', HttpStatus.INTERNAL_SERVER_ERROR); |
||||
}); |
||||
|
||||
// ! 增加关联部门
|
||||
await this.createDeptLink(roleData[0].roleId, updateAuthRoleDto.deptList, pacInfo.userId as any).catch((e) => { |
||||
this.logger.error(e.message + e.track); |
||||
throw new HttpException('添加部门数据范围关系出现错误,角色写入错误!', HttpStatus.INTERNAL_SERVER_ERROR); |
||||
}); |
||||
|
||||
// ! 解锁
|
||||
lock(); |
||||
|
||||
// ! 返回结果
|
||||
return result; |
||||
} catch (e) { |
||||
// ! 解锁
|
||||
lock(); |
||||
|
||||
// ! 抛出错误
|
||||
throw e; |
||||
} |
||||
} |
||||
|
||||
/** Service |
||||
* NAME: remove |
||||
* DESC: 删除角色信息 |
||||
* DATE: 2024-06-26 16:16:55 - |
||||
* */ |
||||
public async remove(roleId: string, pacInfo: PacInfoType) { |
||||
return await this.deleteRole(roleId, pacInfo.userId as any); |
||||
} |
||||
|
||||
// DB 通过roleKey查找角色信息
|
||||
private getRoleForRoleKey(key: string) { |
||||
return this.mysqlService.db |
||||
.select() |
||||
.from(pacAuthRole) |
||||
.where(and(isNull(pacAuthRole.deleteby), eq(pacAuthRole.roleKey, key))); |
||||
} |
||||
|
||||
// DB 添加角色信息
|
||||
private async addRoleData(createAuthRoleDto: CreateAuthRoleDto, userId) { |
||||
// ! 生成雪花id,用于角色主键
|
||||
const id = await this.snowflake.generate(); |
||||
|
||||
// ! 定义写入的角色数据
|
||||
const newRoleData: typeof pacAuthRole.$inferInsert = { |
||||
roleId: id as any, |
||||
pid: createAuthRoleDto.pid, |
||||
roleName: createAuthRoleDto.roleName, |
||||
roleKey: createAuthRoleDto.roleKey, |
||||
roleDesc: createAuthRoleDto.roleDesc, |
||||
roleType: createAuthRoleDto.roleType, |
||||
deptScope: createAuthRoleDto.deptScope, |
||||
root: isTrueEnum(createAuthRoleDto.root) ? 1 : 0, |
||||
orderNum: createAuthRoleDto.orderNum, |
||||
createby: userId, |
||||
createtime: sql`now()` as any, |
||||
}; |
||||
const result = await this.mysqlService.db.insert(pacAuthRole).values(newRoleData); |
||||
return { |
||||
...result[0], |
||||
roleId: id.toString(), |
||||
}; |
||||
} |
||||
|
||||
// DB 更新父级子元素数量
|
||||
private async haveChildrenSelfIncreasing(roleId: string, isAdd = true) { |
||||
return this.mysqlService.db |
||||
.update(pacAuthRole) |
||||
.set({ |
||||
haveChildren: isAdd ? sql`${pacAuthRole.haveChildren} + 1` : sql`${pacAuthRole.haveChildren} - 1`, |
||||
}) |
||||
.where(eq(pacAuthRole.roleId as any, roleId)); |
||||
} |
||||
|
||||
// DB 建立菜单角色关联
|
||||
private async createMenuLink(roleId: string, menuIdList: string[], userId: string) { |
||||
const newMenuIdList = Array.from(new Set(menuIdList)); |
||||
await this.mysqlService.db.delete(pacAuthLinkRoleMenu).where(eq(pacAuthLinkRoleMenu.roleId as any, roleId)); |
||||
if (menuIdList.length > 0) { |
||||
await this.mysqlService.db.insert(pacAuthLinkRoleMenu).values( |
||||
newMenuIdList.map((i) => ({ |
||||
roleId, |
||||
menuId: i, |
||||
createby: userId, |
||||
createtime: sql`now()` as any, |
||||
})), |
||||
); |
||||
} |
||||
} |
||||
|
||||
// DB 建立部门角色关联
|
||||
private async createDeptLink(roleId: string, deptIdList: string[], userId: string) { |
||||
const newDeptIdList = Array.from(new Set(deptIdList)); |
||||
await this.mysqlService.db.delete(pacAuthLinkRoleDept).where(eq(pacAuthLinkRoleDept.roleId as any, roleId)); |
||||
if (deptIdList.length > 0) { |
||||
await this.mysqlService.db.insert(pacAuthLinkRoleDept).values( |
||||
newDeptIdList.map((i) => ({ |
||||
roleId, |
||||
deptId: i, |
||||
createby: userId, |
||||
createtime: sql`now()` as any, |
||||
})), |
||||
); |
||||
} |
||||
} |
||||
|
||||
// DB 查角色-基本查询结构
|
||||
private getRoleData(data, selectData = undefined) { |
||||
// ! 定义基础查询函数
|
||||
// 启用动态查询模式 $dynamic
|
||||
const query = this.mysqlService.db |
||||
.select(selectData) |
||||
.from(pacAuthRole) |
||||
.orderBy( |
||||
isTrueEnum(data.isAsc) ? asc(pacAuthRole.orderNum) : desc(pacAuthRole.orderNum), |
||||
isTrueEnum(data.isAsc) ? asc(pacAuthRole.roleId) : desc(pacAuthRole.roleId), |
||||
) |
||||
.leftJoin(pacCoreDict, eq(pacAuthRole.roleType, pacCoreDict.dictId)) |
||||
.$dynamic(); |
||||
|
||||
// 查询条件集合
|
||||
const wl = []; |
||||
|
||||
// ? 未删除
|
||||
wl.push(isNull(pacAuthRole.deleteby)); |
||||
|
||||
// ? 模糊查询
|
||||
wl.push( |
||||
or( |
||||
like(pacAuthRole.roleName, likeQuery(data.roleInfo)), |
||||
like(pacAuthRole.roleKey, likeQuery(data.roleInfo)), |
||||
like(pacAuthRole.roleDesc, likeQuery(data.roleInfo)), |
||||
).if(isExistKey(data, 'roleInfo')), |
||||
); |
||||
|
||||
// ? 是否查pac的数据
|
||||
wl.push(eq(pacAuthRole.root, isTrueEnum(data['root']) ? 0 : 1).if(isExistKey(data, 'root') && isTrueEnum(data['root']))); |
||||
|
||||
// ? 按照层级查
|
||||
wl.push(eq(pacAuthRole.pid, data.hierarchy).if(isExistKey(data, 'hierarchy'))); |
||||
|
||||
// ? 是否查角色类型
|
||||
wl.push(eq(pacAuthRole.roleType, data.roleType).if(isExistKey(data, 'roleType'))); |
||||
|
||||
// ? 是否查字典状态
|
||||
wl.push(eq(pacAuthRole.status, data.status).if(isExistKey(data, 'status'))); |
||||
|
||||
query.where(and(...wl)); |
||||
return query; |
||||
} |
||||
|
||||
// DB 查角色分页
|
||||
private async getRolePage(getPacAuthRoleAllDto: GetPacAuthRoleAllDto) { |
||||
const offset = (getPacAuthRoleAllDto.pageNumber - 1) * getPacAuthRoleAllDto.pageSize; |
||||
|
||||
// ! 使用基础查询构建查询总记录数
|
||||
const totalCountQuery = this.getRoleData(getPacAuthRoleAllDto, { |
||||
totalCount: sql`COUNT(*)`, |
||||
}); |
||||
|
||||
// ! 使用基础查询构建分页查询
|
||||
// 重命名表
|
||||
const userTable1 = alias(pacAuthUser, 'userTable1'); |
||||
const paginatedQuery = this.getRoleData(getPacAuthRoleAllDto, { |
||||
...this.rolePageType, |
||||
updateName: userTable1.nickname, |
||||
}) |
||||
.leftJoin(pacAuthUser, eq(pacAuthRole.createby, pacAuthUser.userId)) |
||||
.leftJoin(userTable1, eq(pacAuthRole.updateby, pacAuthUser.userId)) |
||||
.limit(getPacAuthRoleAllDto.pageSize) |
||||
.offset(offset); |
||||
|
||||
return { |
||||
total: (await totalCountQuery)[0].totalCount, |
||||
rowData: await paginatedQuery, |
||||
searchData: getPacAuthRoleAllDto, |
||||
}; |
||||
} |
||||
|
||||
// DB 查角色列表
|
||||
private getRoleList(getPacAuthRoleAllDto: GetPacAuthRoleAllDto) { |
||||
return this.getRoleData(getPacAuthRoleAllDto, this.roleListType); |
||||
} |
||||
|
||||
// DB 查角色树
|
||||
getRoleTree() {} |
||||
|
||||
// DB 查角色详细信息
|
||||
private async getRoleMore(roleId: string) { |
||||
// ! 定义2次连表查询的用户表
|
||||
const userTable1 = alias(pacAuthUser, 'userTable1'); |
||||
|
||||
// ! 查询目标角色信息
|
||||
const roleRerult = await this.mysqlService.db |
||||
.select({ |
||||
...this.rolePageType, |
||||
updateName: userTable1.nickname, |
||||
}) |
||||
.from(pacAuthRole) |
||||
.leftJoin(pacCoreDict, eq(pacAuthRole.roleType, pacCoreDict.dictId)) |
||||
.leftJoin(pacAuthUser, eq(pacAuthRole.createby, pacAuthUser.userId)) |
||||
.leftJoin(userTable1, eq(pacAuthRole.updateby, pacAuthUser.userId)) |
||||
.where(and(isNull(pacAuthRole.deleteby), eq(pacAuthRole.roleId, roleId))); |
||||
|
||||
// ! 如果不存在角色信息直接报错
|
||||
if (roleRerult.length === 0) { |
||||
throw new HttpException('未找到目标角色详细信息!', HttpStatus.BAD_REQUEST); |
||||
} |
||||
|
||||
// ! 获取角色关联的菜单信息
|
||||
const menuList = await this.mysqlService.db |
||||
.select({ |
||||
menuId: pacCoreMenu.menuId, |
||||
menuName: pacCoreMenu.menuName, |
||||
}) |
||||
.from(pacCoreMenu) |
||||
.leftJoin(pacAuthLinkRoleMenu, eq(pacAuthLinkRoleMenu.menuId, pacCoreMenu.menuId)) |
||||
.where(and(isNull(pacCoreMenu.deleteby), eq(pacAuthLinkRoleMenu.roleId, roleId))); |
||||
|
||||
// ! 获取角色数据权限的部门范围
|
||||
let deptList = []; |
||||
|
||||
// ! 只有自定义数据范围才会选部门
|
||||
if (roleRerult[0].deptScope == 5) { |
||||
deptList = await this.mysqlService.db |
||||
.select({ |
||||
deptId: pacAuthDept.deptId, |
||||
deptName: pacAuthDept.deptName, |
||||
}) |
||||
.from(pacAuthDept) |
||||
.leftJoin(pacAuthLinkRoleDept, eq(pacAuthLinkRoleDept.deptId, pacAuthDept.deptId)) |
||||
.where(and(isNull(pacAuthDept.deleteby), eq(pacAuthLinkRoleDept.roleId, roleId))); |
||||
} |
||||
|
||||
// ! 返回重构的数据结构
|
||||
return { |
||||
...roleRerult[0], |
||||
menuList, |
||||
deptList, |
||||
}; |
||||
} |
||||
|
||||
// 根据ID查角色基本信息
|
||||
private getRoleForRoleId(roleId: string) { |
||||
return this.mysqlService.db |
||||
.select() |
||||
.from(pacAuthRole) |
||||
.where(and(isNull(pacAuthRole.deleteby), eq(pacAuthRole.roleId, roleId))); |
||||
} |
||||
|
||||
// DB 删除角色信息
|
||||
private async deleteRole(roleId: string, userId: string) { |
||||
// ! 查找角色信息
|
||||
const roleData = await this.getRoleForRoleId(roleId); |
||||
|
||||
// ? 当不存在角色信息
|
||||
if (roleData.length == 0) { |
||||
throw new HttpException('未找到目标角色信息,无法删除!', HttpStatus.BAD_REQUEST); |
||||
} |
||||
|
||||
// ! 判断是否是root账户,非root账户无法设置为root
|
||||
if (this.config.get('masterId') !== userId && isTrueEnum(roleData[0].root)) { |
||||
throw new HttpException('没有权限创建原始角色!', HttpStatus.UNAUTHORIZED); |
||||
} |
||||
|
||||
// ? 判断是否存在子项
|
||||
if (roleData[0].haveChildren != 0) { |
||||
throw new HttpException('该角色存在子项!', HttpStatus.BAD_REQUEST); |
||||
} |
||||
|
||||
// ! 清角色菜单关联表
|
||||
await this.mysqlService.db.delete(pacAuthLinkRoleMenu).where(eq(pacAuthLinkRoleMenu.roleId as any, roleId)); |
||||
|
||||
// ? 判断是否是自定义数据范围,清角色部门关联表
|
||||
if (roleData[0].deptScope == 5) { |
||||
await this.mysqlService.db.delete(pacAuthLinkRoleDept).where(eq(pacAuthLinkRoleDept.roleId as any, roleId)); |
||||
} |
||||
|
||||
// ! 判断父节点是否存在
|
||||
if (roleData[0].pid != 0) { |
||||
// ! 减少父级子节点数量
|
||||
await this.haveChildrenSelfIncreasing(roleData[0].pid, false); |
||||
} |
||||
|
||||
// ! 删除角色数据
|
||||
return await this.mysqlService.db |
||||
.update(pacAuthRole) |
||||
.set({ |
||||
deletetime: sql`now()`, |
||||
deleteby: userId, |
||||
}) |
||||
.where(eq(pacAuthRole.roleId, roleId)); |
||||
} |
||||
|
||||
// DB 更新角色信息
|
||||
private async updateRole(roleId: string, updateAuthRoleDto: UpdateAuthRoleDto, userId: string) { |
||||
return this.mysqlService.db |
||||
.update(pacAuthRole) |
||||
.set({ |
||||
roleName: updateAuthRoleDto.roleName, |
||||
roleKey: updateAuthRoleDto.roleKey, |
||||
roleDesc: updateAuthRoleDto.roleDesc, |
||||
roleType: updateAuthRoleDto.roleType, |
||||
deptScope: updateAuthRoleDto.deptScope, |
||||
orderNum: updateAuthRoleDto.orderNum, |
||||
status: updateAuthRoleDto.status, |
||||
root: isTrueEnum(updateAuthRoleDto.root) ? 1 : 0, |
||||
updateby: userId, |
||||
updatetime: sql`now()`, |
||||
}) |
||||
.where(eq(pacAuthRole.roleId, roleId)); |
||||
} |
||||
} |
@ -1,154 +0,0 @@ |
||||
import { ApiProperty } from '@nestjs/swagger'; |
||||
import Trim from '@common/decorator/trim/trim.decorator'; |
||||
import { ArrayMinSize, IsEnum, IsInt, IsOptional, IsString, Length, Max, MaxLength, Min, MinLength } from 'class-validator'; |
||||
import { BooleanEnum } from '@utils/boolean.enum'; |
||||
import ChangeCase, { |
||||
CaseType |
||||
} from "@common/decorator/change-case/change-case.decorator"; |
||||
|
||||
export class CreateAuthRoleDto { |
||||
@ApiProperty({ |
||||
description: '角色父ID', |
||||
type: String, |
||||
example: '0', |
||||
required: false, |
||||
minLength: 1, |
||||
maxLength: 32, |
||||
}) |
||||
@Trim() |
||||
@IsString({ message: '角色关联属性应为字符串格式!' }) |
||||
@IsOptional() |
||||
readonly pid?: string = '0'; |
||||
|
||||
@ApiProperty({ |
||||
description: '角色名称', |
||||
type: String, |
||||
example: '管理员', |
||||
required: true, |
||||
minLength: 1, |
||||
maxLength: 32, |
||||
}) |
||||
@Trim() |
||||
@IsString({ message: '角色名称应为字符串格式!' }) |
||||
@Length(1, 32, { message: '角色名称长度控制在1到32位之间!' }) |
||||
readonly roleName: string; |
||||
|
||||
@ApiProperty({ |
||||
description: '角色标志', |
||||
type: String, |
||||
example: 'Country', |
||||
required: true, |
||||
minLength: 1, |
||||
maxLength: 32, |
||||
}) |
||||
@Trim() |
||||
@ChangeCase(CaseType.constant) |
||||
@IsString({ message: '角色标志应为字符串格式!' }) |
||||
@Length(1, 32, { message: '请将角色标志长度控制在1到32位之间!' }) |
||||
readonly roleKey: string; |
||||
|
||||
@ApiProperty({ |
||||
description: '角色类型,来自于字典', |
||||
type: String, |
||||
example: '0', |
||||
required: false, |
||||
minLength: 19, |
||||
maxLength: 19, |
||||
}) |
||||
@Trim() |
||||
@IsString({ message: '角色类型格式不正确!' }) |
||||
@Length(19, 19, { message: '角色类型格式不正确!' }) |
||||
@IsOptional() |
||||
readonly roleType: string; |
||||
|
||||
@ApiProperty({ |
||||
description: '角色描述', |
||||
type: String, |
||||
example: '0', |
||||
required: false, |
||||
minLength: 1, |
||||
maxLength: 255, |
||||
}) |
||||
@Trim() |
||||
@IsString({ message: '角色描述应为字符串格式!' }) |
||||
@Length(1, 255, { message: '请将角色描述长度控制在1到255位之间!' }) |
||||
@IsOptional() |
||||
readonly roleDesc?: string; |
||||
|
||||
@ApiProperty({ |
||||
description: '数据权限范围', |
||||
type: Number, |
||||
example: 10, |
||||
required: false, |
||||
minimum: -1000, |
||||
maximum: 1000, |
||||
}) |
||||
@IsOptional() |
||||
@IsInt({ |
||||
message: '数据权限范围必须是整数!', |
||||
}) |
||||
@Min(0, { |
||||
message: '数据权限范围不能小于0!', |
||||
}) |
||||
@Max(5, { |
||||
message: '数据权限范围不能超过5', |
||||
}) |
||||
readonly deptScope?: number = 0; |
||||
|
||||
@ApiProperty({ |
||||
description: '数据范围组织部门Id列表', |
||||
type: [String], |
||||
example: ['a'], |
||||
required: false, |
||||
minItems: 1, |
||||
}) |
||||
@IsString({ each: true, message: '部门id格式错误' }) |
||||
@ArrayMinSize(0, { message: '至少需要选择一个部门作为数据范围' }) |
||||
@Length(19, 19, { each: true, message: '部门id格式错误' }) |
||||
@IsOptional() |
||||
readonly deptList?: string[]; |
||||
|
||||
@ApiProperty({ |
||||
description: '菜单列表', |
||||
type: [String], |
||||
example: ['a'], |
||||
required: false, |
||||
minItems: 1, |
||||
}) |
||||
@IsString({ each: true, message: '菜单id格式错误' }) |
||||
@ArrayMinSize(1, { message: '至少需要选择一个菜单作为权限' }) |
||||
@Length(19, 19, { each: true, message: '菜单id格式错误' }) |
||||
readonly menuList?: string[]; |
||||
|
||||
@ApiProperty({ |
||||
description: '是否属于PAC', |
||||
type: BooleanEnum, |
||||
enum: BooleanEnum, |
||||
example: false, |
||||
required: false, |
||||
}) |
||||
@Trim() |
||||
@IsEnum(BooleanEnum, { message: 'root参数格式错误' }) |
||||
@IsOptional() |
||||
readonly root?: BooleanEnum = BooleanEnum.FALSE; |
||||
|
||||
@ApiProperty({ |
||||
description: '排序', |
||||
type: Number, |
||||
example: 10, |
||||
required: false, |
||||
minimum: -1000, |
||||
maximum: 1000, |
||||
}) |
||||
@IsOptional() |
||||
@IsInt({ |
||||
message: '排序必须是整数!', |
||||
}) |
||||
@Min(-1000, { |
||||
message: '排序不能小于-1000!', |
||||
}) |
||||
@Max(1000, { |
||||
message: '排序不能超过1000', |
||||
}) |
||||
readonly orderNum?: number = 0; |
||||
} |
@ -1,114 +0,0 @@ |
||||
// | ------------------------------------------------------------
|
||||
// | @版本: version 0.1
|
||||
// | @创建人: 【Nie-x7129】
|
||||
// | @E-mail: x71291@outlook.com
|
||||
// | @所在项目: pac-auth
|
||||
// | @文件描述: get-auth-role.dto.ts -
|
||||
// | @创建时间: 2024-06-25 17:22
|
||||
// | @更新时间: 2024-06-25 17:22
|
||||
// | @修改记录:
|
||||
// | -*-*-*- (时间--修改人--修改说明) -*-*-*-
|
||||
// | =
|
||||
// | ------------------------------------------------------------
|
||||
|
||||
import { GetDto } from '@dto/get.dto'; |
||||
import { ApiProperty } from '@nestjs/swagger'; |
||||
import Trim from '@common/decorator/trim/trim.decorator'; |
||||
import { IsEnum, IsInt, IsOptional, IsString, Length, Max, Min } from 'class-validator'; |
||||
import { BooleanEnum } from '@utils/boolean.enum'; |
||||
import Int from '@common/decorator/int/int.descrator'; |
||||
import ChangeCase, { CaseType } from '@common/decorator/change-case/change-case.decorator'; |
||||
|
||||
export class GetPacAuthRoleAllDto extends GetDto { |
||||
@ApiProperty({ |
||||
description: '角色', |
||||
type: String, |
||||
example: '管理员', |
||||
required: false, |
||||
minLength: 1, |
||||
maxLength: 128, |
||||
}) |
||||
@Trim() |
||||
@IsString({ message: '字典信息应为字符串格式!' }) |
||||
@Length(0, 128, { message: '请将字典信息长度控制在1到128位之间!' }) |
||||
@IsOptional() |
||||
readonly roleInfo?: string; |
||||
|
||||
@ApiProperty({ |
||||
description: '角色类型,来自于字典', |
||||
type: String, |
||||
example: '0', |
||||
required: false, |
||||
minLength: 19, |
||||
maxLength: 19, |
||||
}) |
||||
@Trim() |
||||
@IsString({ message: '角色类型格式不正确!' }) |
||||
@Length(19, 19, { message: '角色类型格式不正确!' }) |
||||
@IsOptional() |
||||
readonly roleType: string; |
||||
|
||||
@ApiProperty({ |
||||
description: '是否属于PAC', |
||||
type: BooleanEnum, |
||||
enum: BooleanEnum, |
||||
example: 0, |
||||
required: false, |
||||
}) |
||||
@Trim() |
||||
@IsEnum(BooleanEnum, { message: 'root参数格式错误' }) |
||||
@IsOptional() |
||||
readonly root: BooleanEnum; |
||||
|
||||
@ApiProperty({ |
||||
description: '字典状态', |
||||
type: Number, |
||||
example: 0, |
||||
required: false, |
||||
minimum: -100, |
||||
maximum: 100, |
||||
}) |
||||
@Trim() |
||||
@Int() |
||||
@IsInt({ |
||||
message: '字典状态必须是整数!', |
||||
}) |
||||
@Min(-100, { |
||||
message: '字典状态需要大于-100!', |
||||
}) |
||||
@Max(100, { |
||||
message: '字典状态不能超过100', |
||||
}) |
||||
@IsOptional() |
||||
readonly status?: string; |
||||
|
||||
@ApiProperty({ |
||||
description: '字典层级id', |
||||
type: Number, |
||||
example: 0, |
||||
required: false, |
||||
minimum: 0, |
||||
maximum: 100, |
||||
}) |
||||
@Trim() |
||||
@IsString({ message: '字典层级id应为字符串格式!' }) |
||||
@Length(1, 20, { message: '字典层级id格式错误!' }) |
||||
@IsOptional() |
||||
readonly hierarchy?: string; |
||||
} |
||||
|
||||
export class PacAuthRoleTargetListDto { |
||||
@ApiProperty({ |
||||
description: '是否查找树结构', |
||||
type: BooleanEnum, |
||||
enum: BooleanEnum, |
||||
example: 0, |
||||
required: false, |
||||
}) |
||||
@Trim() |
||||
@IsEnum(BooleanEnum, { |
||||
message: '查找树结构数据错误', |
||||
}) |
||||
@IsOptional() |
||||
readonly isTree: BooleanEnum; |
||||
} |
@ -1,25 +0,0 @@ |
||||
import { ApiProperty, PartialType } from '@nestjs/swagger'; |
||||
import { CreateAuthRoleDto } from './create-auth-role.dto'; |
||||
import { IsInt, IsOptional, Max, Min } from 'class-validator'; |
||||
|
||||
export class UpdateAuthRoleDto extends PartialType(CreateAuthRoleDto) { |
||||
@ApiProperty({ |
||||
description: '状态', |
||||
type: Number, |
||||
example: 10, |
||||
required: false, |
||||
minimum: -100, |
||||
maximum: 100, |
||||
}) |
||||
@IsOptional() |
||||
@IsInt({ |
||||
message: '状态必须是整数!', |
||||
}) |
||||
@Min(-1000, { |
||||
message: '状态不能小于-100!', |
||||
}) |
||||
@Max(1000, { |
||||
message: '状态不能超过100', |
||||
}) |
||||
readonly status: number; |
||||
} |
@ -1,3 +1,2 @@ |
||||
import { relations } from "drizzle-orm/relations"; |
||||
import { } from "./schema"; |
||||
|
||||
import { relations } from 'drizzle-orm/relations'; |
||||
import {} from './schema'; |
||||
|
Loading…
Reference in new issue