完成部门部分

main
expressgy 3 months ago
parent dc4391a79f
commit dcbe19c36e
  1. 2
      src/application/app.module.ts
  2. 108
      src/application/auth-dept/auth-dept.controller.ts
  3. 9
      src/application/auth-dept/auth-dept.module.ts
  4. 560
      src/application/auth-dept/auth-dept.service.ts
  5. 107
      src/application/auth-dept/dto/create-auth-dept.dto.ts
  6. 85
      src/application/auth-dept/dto/get-auth-dept.dto.ts
  7. 25
      src/application/auth-dept/dto/update-auth-dept.dto.ts
  8. 13
      src/application/auth-role/auth-role.controller.ts
  9. 4
      src/application/auth-role/auth-role.module.ts
  10. 47
      src/application/auth-role/auth-role.service.ts
  11. 4
      src/application/auth-role/dto/create-auth-role.dto.ts
  12. 30
      src/application/auth-role/dto/get-auth-role.dto.ts
  13. 4
      src/application/core-dict/dto/create-core-dict.dto.ts
  14. 1
      src/application/core-dict/dto/get-core-dict.dto.ts
  15. 4
      src/application/core-menu/dto/create-core-menu.dto.ts
  16. 4
      src/application/core-menu/dto/get-core-menu.dto.ts
  17. 4
      src/application/core-service/dto/create-core-service.dto.ts
  18. 29
      src/dto/AttLinkUser.dto.ts
  19. 47
      src/dto/GetUserForAtt.dto.ts
  20. 5
      src/entities/relations.ts

@ -15,6 +15,7 @@ import { GlobalModule } from '@app/global.module';
import { CoreEnvModule } from './core-env/core-env.module'; import { CoreEnvModule } from './core-env/core-env.module';
import { CoreMenuModule } from './core-menu/core-menu.module'; import { CoreMenuModule } from './core-menu/core-menu.module';
import { AuthRoleModule } from './auth-role/auth-role.module'; import { AuthRoleModule } from './auth-role/auth-role.module';
import { AuthDeptModule } from './auth-dept/auth-dept.module';
@Module({ @Module({
imports: [ imports: [
@ -29,6 +30,7 @@ import { AuthRoleModule } from './auth-role/auth-role.module';
CoreEnvModule, CoreEnvModule,
CoreMenuModule, CoreMenuModule,
AuthRoleModule, AuthRoleModule,
AuthDeptModule,
], ],
controllers: [AppController], controllers: [AppController],
providers: [ providers: [

@ -0,0 +1,108 @@
import { Controller, Get, Post, Body, Patch, Param, Delete, Query } from '@nestjs/common';
import { AuthDeptService } from './auth-dept.service';
import { CreateAuthDeptDto } from './dto/create-auth-dept.dto';
import { UpdateAuthDeptDto } from './dto/update-auth-dept.dto';
import { ApiOperation, ApiProduces, ApiTags } from '@nestjs/swagger';
import { PacInfo } from '@common/decorator/pac-info/pac-info.decorator';
import { PacInfoType } from '@utils/myType';
import { GetAuthDeptDto } from '@app/auth-dept/dto/get-auth-dept.dto';
import {
GetUserForAttDto
} from "@dto/GetUserForAtt.dto";
import {DeptLinkUserDto} from "@dto/AttLinkUser.dto";
@ApiTags('部门服务')
@Controller('authDept')
export class AuthDeptController {
constructor(private readonly authDeptService: AuthDeptService) {}
@ApiOperation({
summary: '添加部门',
description: '部门',
})
@ApiProduces('application/json')
@Post()
create(@Body() createAuthDeptDto: CreateAuthDeptDto, @PacInfo() pacInfo: PacInfoType) {
return this.authDeptService.create(createAuthDeptDto, pacInfo);
}
@ApiOperation({
summary: '获取部门列表',
description: '查询部门分页或者列表',
})
@ApiProduces('application/json')
@Get()
findAll(@Query() getAuthDeptDto: GetAuthDeptDto) {
return this.authDeptService.findAll(getAuthDeptDto);
}
@ApiOperation({
summary: '获取部门详细信息',
description: '查询部门详细信息,目录菜单列表,数据权限范围',
})
@ApiProduces('application/json')
@Get(':id')
findOne(@Param('id') id: string) {
return this.authDeptService.findOne(id);
}
@ApiOperation({
summary: '获取部门树',
description: '查询部门基本信息,树结构',
})
@ApiProduces('application/json')
@Get('/tree/:pid')
findTree(@Param('pid') pid: string) {
return this.authDeptService.findTree(pid);
}
@ApiOperation({
summary: '更新部门信息',
description: '更新部门信息',
})
@ApiProduces('application/json')
@Patch(':id')
update(@Param('id') id: string, @Body() updateAuthDeptDto: UpdateAuthDeptDto, @PacInfo() pacInfo: PacInfoType) {
return this.authDeptService.update(id, updateAuthDeptDto, pacInfo);
}
@ApiOperation({
summary: '删除目标部门',
description: '删除目标部门信息',
})
@ApiProduces('application/json')
@Delete(':id')
remove(@Param('id') id: string, @PacInfo() pacInfo: PacInfoType) {
return this.authDeptService.remove(id, pacInfo);
}
@ApiOperation({
summary: '获取部门下的用户分页',
description: '获取部门下的用户分页',
})
@ApiProduces('application/json')
@Get('/user/:pid')
findUser(@Param('pid') pid: string,@Query() getUserForAttDto: GetUserForAttDto) {
return this.authDeptService.findUser(pid, getUserForAttDto);
}
@ApiOperation({
summary: '给部门绑定账户',
description: '给部门关联上账户,最大200个',
})
@ApiProduces('application/json')
@Post('/user')
linkUser(@Body() deptLinkUserDto: DeptLinkUserDto, @PacInfo() pacInfo: PacInfoType) {
return this.authDeptService.linkUser(deptLinkUserDto, pacInfo);
}
@ApiOperation({
summary: '给部门解绑账户',
description: '给部门取消关联上账户,最大200个',
})
@ApiProduces('application/json')
@Delete('/user')
unlinkUser(@Body() deptLinkUserDto: DeptLinkUserDto) {
return this.authDeptService.unlinkUser(deptLinkUserDto);
}
}

@ -0,0 +1,9 @@
import { Module } from '@nestjs/common';
import { AuthDeptService } from './auth-dept.service';
import { AuthDeptController } from './auth-dept.controller';
@Module({
controllers: [AuthDeptController],
providers: [AuthDeptService],
})
export class AuthDeptModule {}

@ -0,0 +1,560 @@
import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
import { CreateAuthDeptDto } from './dto/create-auth-dept.dto';
import { UpdateAuthDeptDto } from './dto/update-auth-dept.dto';
import { GetAuthDeptDto } from '@app/auth-dept/dto/get-auth-dept.dto';
import { PacInfoType } from '@utils/myType';
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 { pacAuthDept, pacAuthLinkUserDept, pacAuthRole, pacAuthUser, pacCoreDict } from '@entities/schema';
import { and, asc, count, desc, eq, inArray, isNull, like, or, SQL, sql } from 'drizzle-orm';
import { isExistKey, isTrueEnum } from '@utils/boolean.enum';
import { likeQuery } from '@utils/likeQuery';
import { alias, QueryBuilder } from 'drizzle-orm/mysql-core';
import { customDrizzleRowWithRecursive } from '@utils/customDrizzleRowWithRecursive';
import { GetUserForAttDto } from '@dto/GetUserForAtt.dto';
import {
DeptLinkUserDto
} from "@dto/AttLinkUser.dto";
@Injectable()
export class AuthDeptService {
// 分页数据格式
private readonly deptPageType = {
deptId: pacAuthDept.deptId,
pid: pacAuthDept.pid,
grade: pacAuthDept.grade,
deptName: pacAuthDept.deptName,
deptDesc: pacAuthDept.deptDesc,
deptType: pacAuthDept.deptType,
deptTypeKey: pacCoreDict.dictKey,
deptTypeName: pacCoreDict.dictName,
deptLeader: pacAuthDept.deptLeader,
deptLeaderName: pacAuthUser.nickname,
defaultRole: pacAuthDept.defaultRole,
defaultRoleKey: pacAuthRole.roleKey,
defaultRoleName: pacAuthRole.roleName,
haveChildren: pacAuthDept.haveChildren,
orderNum: pacAuthDept.orderNum,
status: pacAuthDept.status,
createby: pacAuthDept.createby,
createtime: pacAuthDept.createtime,
updateby: pacAuthDept.updateby,
updatetime: pacAuthDept.updatetime,
};
// 列表数据格式
private readonly deptListType = {
deptId: pacAuthDept.deptId,
pid: pacAuthDept.pid,
grade: pacAuthDept.grade,
deptName: pacAuthDept.deptName,
deptType: pacAuthDept.deptType,
deptTypeKey: pacCoreDict.dictKey,
deptTypeName: pacCoreDict.dictName,
deptLeader: pacAuthDept.deptLeader,
deptLeaderName: pacAuthUser.nickname,
haveChildren: pacAuthDept.haveChildren,
orderNum: pacAuthDept.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(createAuthDeptDto: CreateAuthDeptDto, pacInfo: PacInfoType) {
// ! 加目标锁,同级,而不是全局
const lock = await this.redisService.distributedLock('DEPT' + createAuthDeptDto.pid + '-' + createAuthDeptDto.deptName, createAuthDeptDto.deptName);
// ? 存在正在进行写入的部门
if (!lock) throw new HttpException('服务繁忙,部门名称重复!', HttpStatus.CONFLICT);
// @ 核心逻辑
try {
// ! 同级查重
const result = await this.checkRepeatForDeptName(createAuthDeptDto.deptName, createAuthDeptDto.pid);
// ? 是否存在重复的部门
if (result.length > 0) throw new HttpException('部门标识重复!', HttpStatus.CONFLICT);
// ! 获取上级信息
let pGrade = 0;
if (createAuthDeptDto.pid != 0 as any) {
const pDept = await this.getDeptForDeptId(createAuthDeptDto.pid);
if (pDept.length == 0) throw new HttpException('上级部门不存在!', HttpStatus.BAD_REQUEST);
pGrade = pDept[0].grade;
}
// ! 添加部门数据
const newPacCoreDict = await this.addDeptData(createAuthDeptDto, pGrade + 1, pacInfo.userId);
// ! 解锁
lock();
// !更新父节点的子节点数量
await this.haveChildrenSelfIncreasing(createAuthDeptDto.pid);
// ! 返回结果
return newPacCoreDict;
} catch (e) {
// ! 解锁
lock();
// ! 抛出错误
throw e;
}
}
/** Service
* NAME: findAll
* DESC: 获取部门分页/
* DATE: 2024-06-25 15:53:04 -
* */
public async findAll(getAuthDeptDto: GetAuthDeptDto) {
if (isTrueEnum(getAuthDeptDto['isList'])) {
return await this.getList(getAuthDeptDto);
} else {
return await this.getPage(getAuthDeptDto);
}
}
/** Service
* NAME: findOne
* DESC: 获取部门详细信息
* DATE: 2024-06-28 11:30:43 -
* */
public findOne(id: string) {
return this.getMore(id);
}
/** Service
* NAME: findTree
* DESC: 获取部门树
* DATE: 2024-06-28 11:30:47 -
* */
public async findTree(pid: string) {
const [result] = await this.getRoleTree(pid ? pid : '0');
return result;
}
/** Service
* NAME: update
* DESC: 更新部门信息
* DATE: 2024-06-28 11:30:50 -
* */
public async update(id: string, updateAuthDeptDto: UpdateAuthDeptDto, pacInfo: PacInfoType) {
return this.updateDept(id, updateAuthDeptDto, pacInfo.userId);
}
/** Service
* NAME: remove
* DESC: 删除部门信息
* DATE: 2024-06-28 11:30:54 -
* */
public async remove(id: string, pacInfo: PacInfoType) {
return await this.deleteDept(id, pacInfo.userId);
}
/** Service
* NAME: findUser
* DESC: 查找部门下的用户分页
* DATE: 2024-06-28 17:17:16 -
* */
public async findUser(id: string, getUserForAttDto: GetUserForAttDto) {
return this.getDeptUser(id, getUserForAttDto);
}
/** Service
* NAME: linkUser
* DESC: 关联账户给部门
* DATE: 2024-06-28 17:17:16 -
* */
public async linkUser(deptLinkUserDto: DeptLinkUserDto, pacInfo: PacInfoType) {
return this.linkUserForDept(deptLinkUserDto, pacInfo);
}
/** Service
* NAME: unlinkUser
* DESC: 取消关联账户给部门
* DATE: 2024-06-27 15:38:54 -
* */
public async unlinkUser(deptLinkUserDto: DeptLinkUserDto) {
return this.unlinkUserForDept(deptLinkUserDto);
}
// DB 同级查重
private checkRepeatForDeptName(deptName: string, pid: string) {
return this.mysqlService.db
.select()
.from(pacAuthDept)
.where(and(isNull(pacAuthDept.deleteby), eq(pacAuthDept.pid, pid), eq(pacAuthDept.deptName, deptName)));
}
// DB 根据id查部门信息
private getDeptForDeptId(deptId: string) {
return this.mysqlService.db
.select()
.from(pacAuthDept)
.where(and(isNull(pacAuthDept.deleteby), eq(pacAuthDept.deptId, deptId)));
}
// DB 更新父级子元素数量
private async haveChildrenSelfIncreasing(id: string, isAdd = true) {
return this.mysqlService.db
.update(pacAuthDept)
.set({
haveChildren: isAdd ? sql`${pacAuthDept.haveChildren} + 1` : sql`${pacAuthDept.haveChildren} - 1`,
})
.where(eq(pacAuthDept.deptId as any, id));
}
// DB 添加部门数据
private async addDeptData(createAuthDeptDto: CreateAuthDeptDto, grade, userId) {
// ! 生成雪花id,用于部门主键
const id = await this.snowflake.generate();
// ! 定义写入的部门数据
const newDeptData: typeof pacAuthDept.$inferInsert = {
pid: createAuthDeptDto.pid,
deptId: id as any,
grade: grade,
deptName: createAuthDeptDto.deptName,
deptDesc: createAuthDeptDto.deptDesc,
deptType: createAuthDeptDto.deptType,
deptLeader: createAuthDeptDto.deptLeader,
defaultRole: createAuthDeptDto.defaultRole,
orderNum: createAuthDeptDto.orderNum,
createby: userId,
createtime: sql`now()` as any,
};
return await this.mysqlService.db.insert(pacAuthDept).values(newDeptData);
}
// DB 差距查询构建器
private queryBuilder(getAuthDeptDto: GetAuthDeptDto, selectData = undefined) {
// ! 定义基础查询函数
// 启用动态查询模式 $dynamic
const query = this.mysqlService.db
.select(selectData)
.from(pacAuthDept)
.orderBy(
isTrueEnum(getAuthDeptDto.isAsc) ? asc(pacAuthDept.orderNum) : desc(pacAuthDept.orderNum),
isTrueEnum(getAuthDeptDto.isAsc) ? asc(pacAuthDept.deptId) : desc(pacAuthDept.deptId),
)
.leftJoin(pacCoreDict, eq(pacAuthDept.deptType, pacCoreDict.dictId))
.leftJoin(pacAuthUser, eq(pacAuthDept.deptLeader, pacAuthUser.userId))
.$dynamic();
// 查询条件集合
const wl = [];
// ? 未删除
wl.push(isNull(pacAuthDept.deleteby));
// ? 模糊查询
wl.push(
or(like(pacAuthDept.deptName, likeQuery(getAuthDeptDto.deptInfo)), like(pacAuthDept.deptDesc, likeQuery(getAuthDeptDto.deptInfo))).if(
isExistKey(getAuthDeptDto, 'deptInfo'),
),
);
// ? 按照层级查
wl.push(eq(pacAuthDept.pid, getAuthDeptDto.hierarchy).if(isExistKey(getAuthDeptDto, 'hierarchy')));
// ? 是否查部门类型
wl.push(eq(pacAuthDept.deptType, getAuthDeptDto.deptType).if(isExistKey(getAuthDeptDto, 'deptType')));
// ? 是否查字典状态
wl.push(eq(pacAuthDept.status, getAuthDeptDto.status as any).if(isExistKey(getAuthDeptDto, 'status')));
query.where(and(...wl));
return query;
}
// DB 查分页
private async getPage(getAuthDeptDto: GetAuthDeptDto) {
const offset = (getAuthDeptDto.pageNumber - 1) * getAuthDeptDto.pageSize;
// ! 使用基础查询构建查询总记录数
const totalCountQuery = this.queryBuilder(getAuthDeptDto, {
totalCount: sql`COUNT(*)`,
});
// ! 使用基础查询构建分页查询
// 重命名表
const userTable1 = alias(pacAuthUser, 'userTable1');
const userTable2 = alias(pacAuthUser, 'userTable2');
const paginatedQuery = this.queryBuilder(getAuthDeptDto, {
...this.deptPageType,
updateName: userTable1.nickname,
createName: userTable2.nickname,
})
.leftJoin(pacAuthRole, eq(pacAuthDept.defaultRole, pacAuthRole.roleId))
.leftJoin(userTable2, eq(pacAuthDept.createby, userTable2.userId))
.leftJoin(userTable1, eq(pacAuthDept.updateby, userTable1.userId))
.limit(getAuthDeptDto.pageSize)
.offset(offset);
return {
total: (await totalCountQuery)[0].totalCount,
rowData: await paginatedQuery,
searchData: getAuthDeptDto,
};
}
// DB 查列表
private async getList(getAuthDeptDto: GetAuthDeptDto) {
return this.queryBuilder(getAuthDeptDto, this.deptListType);
}
// DB 查树
private getRoleTree(pid: string = '0') {
console.log(pid);
// ! 基础层级
const baseQueryBuilder = new QueryBuilder();
const baseQuery = baseQueryBuilder
.select({
...this.deptListType,
level: sql`0`.as('level'),
})
.from(pacAuthDept)
.leftJoin(pacCoreDict, eq(pacAuthDept.deptType, pacCoreDict.dictId))
.leftJoin(pacAuthUser, eq(pacAuthDept.deptLeader, pacAuthUser.userId))
.where(and(isNull(pacAuthDept.deleteby), eq(pacAuthDept.pid, pid)));
// ! 递归层级
const recursiveQueryBuilder = new QueryBuilder();
const recursiveQuery = recursiveQueryBuilder
.select({
...this.deptListType,
level: sql`deptHierarchy.level + 1`.as('level'),
})
.from(pacAuthDept)
.leftJoin(pacCoreDict, eq(pacAuthDept.deptType, pacCoreDict.dictId))
.leftJoin(pacAuthUser, eq(pacAuthDept.deptLeader, pacAuthUser.userId))
.where(isNull(pacAuthDept.deleteby))
.innerJoin(sql`deptHierarchy`, sql`deptHierarchy.deptId = ${pacAuthDept.pid}`);
const rowName: SQL = customDrizzleRowWithRecursive(this.deptListType);
// ! 执行原始SQL查询
return this.mysqlService.db.execute(
sql`WITH RECURSIVE deptHierarchy(${rowName}) AS(${baseQuery} UNION ALL ${recursiveQuery}) SELECT * FROM deptHierarchy`,
);
}
// DB 查详情
private async getMore(id: string) {
const userTable1 = alias(pacAuthUser, 'userTable1');
const userTable2 = alias(pacAuthUser, 'userTable2');
const result = await this.mysqlService.db
.select({ ...this.deptPageType, updateName: userTable1.nickname, createName: userTable2.nickname })
.from(pacAuthDept)
.leftJoin(pacCoreDict, eq(pacAuthDept.deptType, pacCoreDict.dictId))
.leftJoin(pacAuthUser, eq(pacAuthDept.deptLeader, pacAuthUser.userId))
.leftJoin(pacAuthRole, eq(pacAuthDept.defaultRole, pacAuthRole.roleId))
.leftJoin(userTable2, eq(pacAuthDept.createby, userTable2.userId))
.leftJoin(userTable1, eq(pacAuthDept.updateby, userTable1.userId))
.where(and(isNull(pacAuthDept.deleteby), eq(pacAuthDept.deptId, id)));
if (result.length === 0) {
throw new HttpException('未找到目标部门信息!', HttpStatus.BAD_REQUEST);
}
const [{ userCount }] = await this.mysqlService.db
.select({ userCount: count(pacAuthUser.userId) })
.from(pacAuthUser)
.leftJoin(pacAuthLinkUserDept, eq(pacAuthLinkUserDept.userId, pacAuthUser.userId))
.where(and(isNull(pacAuthUser.deleteby), eq(pacAuthLinkUserDept.deptId, id)));
return {
...result[0],
userCount,
};
}
// DB 删除
private async deleteDept(id: string, userId) {
// ! 查找部门信息
const deptData = await this.mysqlService.db
.select()
.from(pacAuthDept)
.where(and(isNull(pacAuthDept.deleteby), eq(pacAuthDept.deptId, id)));
if (deptData.length === 0) throw new HttpException('未找到目标部门信息,无法删除!', HttpStatus.BAD_REQUEST);
// ? 判断是否存在子项
if (deptData[0].haveChildren != 0) throw new HttpException('该部门存在子项!', HttpStatus.BAD_REQUEST);
// ! 判断父节点是否存在
if (deptData[0].pid != 0) {
// ! 减少父级子节点数量
await this.haveChildrenSelfIncreasing(deptData[0].pid, false);
}
// ! 删除部门数据
return await this.mysqlService.db
.update(pacAuthDept)
.set({
deletetime: sql`now()`,
deleteby: userId,
})
.where(eq(pacAuthDept.deptId, id));
}
// DB 修改
private updateDept(id, updateAuthDeptDto: UpdateAuthDeptDto, userId) {
return this.mysqlService.db
.update(pacAuthDept)
.set({
deptName: updateAuthDeptDto.deptName,
deptDesc: updateAuthDeptDto.deptDesc,
deptType: updateAuthDeptDto.deptType,
deptLeader: updateAuthDeptDto.deptLeader,
defaultRole: updateAuthDeptDto.defaultRole,
orderNum: updateAuthDeptDto.orderNum,
status: updateAuthDeptDto.status,
updateby: userId,
updatetime: sql`now()`,
})
.where(eq(pacAuthDept.deptId, id));
}
// DB 查找部门下的账户查询构建
private getDeptUserQuery(roleId: string, getUserForRoleDto: GetUserForAttDto, selectData = null) {
const query = this.mysqlService.db
.select(selectData)
.from(pacAuthUser)
.orderBy(isTrueEnum(getUserForRoleDto.isAsc) ? asc(pacAuthUser.userId) : desc(pacAuthUser.userId))
.leftJoin(pacCoreDict, eq(pacAuthUser.userType, pacCoreDict.dictId))
.leftJoin(pacAuthLinkUserDept, eq(pacAuthLinkUserDept.userId, pacAuthUser.userId))
.$dynamic();
const wl = [];
// ? 未删除
wl.push(isNull(pacAuthUser.deleteby));
// ? 模糊查询
wl.push(
or(
like(pacAuthUser.nickname, likeQuery(getUserForRoleDto.userInfo)),
like(pacAuthUser.userDesc, likeQuery(getUserForRoleDto.userInfo)),
like(pacAuthUser.userEmail, likeQuery(getUserForRoleDto.userInfo)),
like(pacAuthUser.userPhone, likeQuery(getUserForRoleDto.userInfo)),
like(pacAuthUser.username, likeQuery(getUserForRoleDto.userInfo)),
).if(isExistKey(getUserForRoleDto, 'userInfo')),
);
// ? 目标roleId
wl.push(eq(pacAuthLinkUserDept.deptId, roleId));
// ? 用户类型
wl.push(eq(pacAuthUser.userType, getUserForRoleDto.userType).if(isExistKey(getUserForRoleDto, 'userType')));
query.where(and(...wl));
return query;
}
// DB 查找部门下的账户
private async getDeptUser(deptId: string, getUserForAttDto: GetUserForAttDto) {
console.log(getUserForAttDto);
const offset = (getUserForAttDto.pageNumber - 1) * getUserForAttDto.pageSize;
// ! 使用基础查询构建查询总记录数
const totalCountQuery = this.getDeptUserQuery(deptId, getUserForAttDto, {
totalCount: sql`COUNT(*)`,
});
// ! 使用基础查询构建分页查询
// 重命名表
const userTable1 = alias(pacAuthUser, 'userTable1');
const userTable2 = alias(pacAuthUser, 'userTable2');
const paginatedQuery = this.getDeptUserQuery(deptId, getUserForAttDto, {
userId: pacAuthUser.userId,
username: pacAuthUser.username,
nickname: pacAuthUser.nickname,
userType: pacAuthUser.userType,
userTypeName: pacCoreDict.dictName,
userTypeKey: pacCoreDict.dictKey,
userEmail: pacAuthUser.userEmail,
avatar: pacAuthUser.avatar,
userPhone: pacAuthUser.userPhone,
userDesc: pacAuthUser.userDesc,
haveChildren: pacAuthUser.haveChildren,
createby: pacAuthUser.createby,
createName: userTable2.nickname,
createtime: pacAuthUser.createtime,
updateName: userTable1.nickname,
})
.leftJoin(userTable2, eq(pacAuthUser.createby, userTable2.userId))
.leftJoin(userTable1, eq(pacAuthUser.updateby, userTable1.userId))
.limit(getUserForAttDto.pageSize)
.offset(offset);
return {
total: (await totalCountQuery)[0].totalCount,
rowData: await paginatedQuery,
searchData: getUserForAttDto,
};
}
// DB 查找部门账户关联数据
private async getDeptLinkUser(deptId: string, userIdList: string[]) {
return this.mysqlService.db
.select({
id: pacAuthLinkUserDept.userId,
index: pacAuthLinkUserDept.index,
})
.from(pacAuthLinkUserDept)
.where(and(eq(pacAuthLinkUserDept.deptId, deptId), inArray(pacAuthLinkUserDept.userId, userIdList)));
}
// DB 给部门关联上账户
private async linkUserForDept(deptLinkUserDto: DeptLinkUserDto, pacInfo: PacInfoType) {
// ! 去重账户ID
const deduplicateUserId = Array.from(new Set(deptLinkUserDto.userIdList));
// ! 查找部门是否存在这些账户
const existUser = await this.getDeptLinkUser(deptLinkUserDto.deptId, deduplicateUserId);
// ! 获取已存在的账户Id
const existUserIdList = existUser.map((user) => user.id);
// ! 过滤已经存在的账户
const userIdList = deptLinkUserDto.userIdList.filter((i) => !existUserIdList.includes(i));
return await this.mysqlService.db.insert(pacAuthLinkUserDept).values(
userIdList.map((i) => ({
deptId: deptLinkUserDto.deptId,
userId: i,
createby: pacInfo.userId,
createtime: sql`now()` as any,
})),
);
}
// DB 取消部门关联的账户
private async unlinkUserForDept(deptLinkUserDto: DeptLinkUserDto) {
// ! 去重账户ID
const deduplicateUserId = Array.from(new Set(deptLinkUserDto.userIdList));
// ! 查找部门是否存在这些账户
const existUser = await this.getDeptLinkUser(deptLinkUserDto.deptId, deduplicateUserId);
// ! 获取已存在的账户Id
const existUserIndexList = existUser.map((user) => user.index);
return await this.mysqlService.db.delete(pacAuthLinkUserDept).where(inArray(pacAuthLinkUserDept.index, existUserIndexList));
}
}

@ -0,0 +1,107 @@
import { ApiProperty } from '@nestjs/swagger';
import Trim from '@common/decorator/trim/trim.decorator';
import { IsInt, IsOptional, IsString, Length, Max, Min } from 'class-validator';
export class CreateAuthDeptDto {
@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位之间!' })
deptName: string;
@ApiProperty({
description: '部门描述',
type: String,
example: '0',
required: false,
minLength: 1,
maxLength: 255,
})
@Trim()
@IsString({ message: '部门描述应为字符串格式!' })
@Length(1, 255, { message: '请将部门描述长度控制在1到255位之间!' })
@IsOptional()
deptDesc: string;
@ApiProperty({
description: '部门类型,来自于字典',
type: String,
example: '0',
required: false,
minLength: 19,
maxLength: 19,
})
@Trim()
@IsString({ message: '部门类型格式不正确!' })
@Length(19, 19, { message: '部门类型格式不正确!' })
@IsOptional()
deptType: string;
@ApiProperty({
description: '部门负责人,来自于用户',
type: String,
example: '0',
required: false,
minLength: 19,
maxLength: 19,
})
@Trim()
@IsString({ message: '部门负责人格式不正确!' })
@Length(1, 19, { message: '部门负责人格式不正确!' })
@IsOptional()
deptLeader: string;
@ApiProperty({
description: '部门默认角色,来自于角色',
type: String,
example: '0',
required: false,
minLength: 19,
maxLength: 19,
})
@Trim()
@IsString({ message: '部门默认角色格式不正确!' })
@Length(19, 19, { message: '部门默认角色格式不正确!' })
@IsOptional()
defaultRole: string;
@ApiProperty({
description: '排序',
type: Number,
example: 10,
required: false,
minimum: -1000,
maximum: 1000,
})
@IsOptional()
@IsInt({
message: '排序必须是整数!',
})
@Min(-1000, {
message: '排序不能小于-1000!',
})
@Max(1000, {
message: '排序不能超过1000',
})
orderNum: number;
}

@ -0,0 +1,85 @@
// | ------------------------------------------------------------
// | @版本: version 0.1
// | @创建人: 【Nie-x7129】
// | @E-mail: x71291@outlook.com
// | @所在项目: pac-auth
// | @文件描述: get-auth-dept.dto.ts -
// | @创建时间: 2024-06-28 11:20
// | @更新时间: 2024-06-28 11:20
// | @修改记录:
// | -*-*-*- (时间--修改人--修改说明) -*-*-*-
// | =
// | ------------------------------------------------------------
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';
export class GetAuthDeptDto extends GetDto {
@ApiProperty({
description: '角色',
type: String,
example: '管理员',
required: false,
minLength: 1,
maxLength: 128,
})
@Trim()
@IsString({ message: '角色信息应为字符串格式!' })
@Length(0, 128, { message: '请将角色信息长度控制在1到128位之间!' })
@IsOptional()
readonly deptInfo?: string;
@ApiProperty({
description: '角色类型,来自于字典',
type: String,
example: '0',
required: false,
minLength: 19,
maxLength: 19,
})
@Trim()
@IsString({ message: '角色类型格式不正确!' })
@Length(19, 19, { message: '角色类型格式不正确!' })
@IsOptional()
readonly deptType: string;
@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;
}

@ -0,0 +1,25 @@
import { ApiProperty, PartialType } from '@nestjs/swagger';
import { CreateAuthDeptDto } from './create-auth-dept.dto';
import { IsInt, IsOptional, Max, Min } from 'class-validator';
export class UpdateAuthDeptDto extends PartialType(CreateAuthDeptDto) {
@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;
}

@ -6,13 +6,9 @@ import { ApiOperation, ApiProduces, ApiTags } from '@nestjs/swagger';
import { PacInfo } from '@common/decorator/pac-info/pac-info.decorator'; import { PacInfo } from '@common/decorator/pac-info/pac-info.decorator';
import { PacInfoType } from '@utils/myType'; import { PacInfoType } from '@utils/myType';
import { query } from 'express'; import { query } from 'express';
import { import { GetPacAuthRoleAllDto } from '@app/auth-role/dto/get-auth-role.dto';
GetPacAuthRoleAllDto, import {GetUserForAttDto} from "@dto/GetUserForAtt.dto";
GetUserForRoleDto import { RoleLinkUserDto } from '@dto/AttLinkUser.dto';
} from "@app/auth-role/dto/get-auth-role.dto";
import {
RoleLinkUserDto
} from "@app/auth-role/dto/roleLinkUser.dto";
@ApiTags('角色服务') @ApiTags('角色服务')
@Controller('authRole') @Controller('authRole')
@ -85,7 +81,7 @@ export class AuthRoleController {
}) })
@ApiProduces('application/json') @ApiProduces('application/json')
@Get('/user/:roleId') @Get('/user/:roleId')
findUserByRoleId(@Param('roleId') roleId: string, @Query() getUserForRoleDto: GetUserForRoleDto) { findUserByRoleId(@Param('roleId') roleId: string, @Query() getUserForRoleDto: GetUserForAttDto) {
return this.authRoleService.findUserByRoleId(roleId, getUserForRoleDto); return this.authRoleService.findUserByRoleId(roleId, getUserForRoleDto);
} }
@ -106,7 +102,6 @@ export class AuthRoleController {
@ApiProduces('application/json') @ApiProduces('application/json')
@Delete('/user') @Delete('/user')
unlinkUser(@Body() roleLinkUserDto: RoleLinkUserDto) { unlinkUser(@Body() roleLinkUserDto: RoleLinkUserDto) {
console.log(roleLinkUserDto);
return this.authRoleService.unlinkUser(roleLinkUserDto); return this.authRoleService.unlinkUser(roleLinkUserDto);
} }
} }

@ -3,7 +3,7 @@ import { AuthRoleService } from './auth-role.service';
import { AuthRoleController } from './auth-role.controller'; import { AuthRoleController } from './auth-role.controller';
@Module({ @Module({
controllers: [AuthRoleController], controllers: [AuthRoleController],
providers: [AuthRoleService], providers: [AuthRoleService],
}) })
export class AuthRoleModule {} export class AuthRoleModule {}

@ -19,11 +19,12 @@ import {
pacCoreMenu, pacCoreMenu,
} from '@entities/schema'; } from '@entities/schema';
import { and, asc, desc, eq, inArray, isNull, like, or, SQL, sql } from 'drizzle-orm'; import { and, asc, desc, eq, inArray, isNull, like, or, SQL, sql } from 'drizzle-orm';
import { GetPacAuthRoleAllDto, GetUserForRoleDto } from '@app/auth-role/dto/get-auth-role.dto'; import { GetPacAuthRoleAllDto } from '@app/auth-role/dto/get-auth-role.dto';
import { GetUserForAttDto } from '@dto/GetUserForAtt.dto';
import { likeQuery } from '@utils/likeQuery'; import { likeQuery } from '@utils/likeQuery';
import { alias, QueryBuilder } from 'drizzle-orm/mysql-core'; import { alias, QueryBuilder } from 'drizzle-orm/mysql-core';
import { customDrizzleRowWithRecursive } from '@utils/customDrizzleRowWithRecursive'; import { customDrizzleRowWithRecursive } from '@utils/customDrizzleRowWithRecursive';
import { RoleLinkUserDto } from '@app/auth-role/dto/roleLinkUser.dto'; import {RoleLinkUserDto} from "@dto/AttLinkUser.dto";
@Injectable() @Injectable()
export class AuthRoleService { export class AuthRoleService {
@ -80,7 +81,7 @@ export class AuthRoleService {
} }
// ! 加目标锁 // ! 加目标锁
const lock = await this.redisService.distributedLock('DICT' + createAuthRoleDto.roleKey, createAuthRoleDto.roleKey); const lock = await this.redisService.distributedLock('ROLE' + createAuthRoleDto.roleKey, createAuthRoleDto.roleKey);
// ? 存在正在进行写入的角色 // ? 存在正在进行写入的角色
if (!lock) throw new HttpException('服务繁忙,角色标识重复!', HttpStatus.CONFLICT); if (!lock) throw new HttpException('服务繁忙,角色标识重复!', HttpStatus.CONFLICT);
@ -158,7 +159,7 @@ export class AuthRoleService {
* DATE: 2024-06-27 14:23:36 - * DATE: 2024-06-27 14:23:36 -
* */ * */
public async findTree(pid: string) { public async findTree(pid: string) {
const [result] = await this.getRoleTree(pid); const [result] = await this.getRoleTree(pid ? pid : '0');
return result; return result;
} }
@ -167,7 +168,7 @@ export class AuthRoleService {
* DESC: 获取角色下的关联账户 * DESC: 获取角色下的关联账户
* DATE: 2024-06-27 14:49:42 - * DATE: 2024-06-27 14:49:42 -
* */ * */
public async findUserByRoleId(roleId: string, getUserForRoleDto: GetUserForRoleDto) { public async findUserByRoleId(roleId: string, getUserForRoleDto: GetUserForAttDto) {
return await this.getRoleUser(roleId, getUserForRoleDto); return await this.getRoleUser(roleId, getUserForRoleDto);
} }
@ -186,7 +187,7 @@ export class AuthRoleService {
} }
// ! 加目标锁 // ! 加目标锁
const lock = await this.redisService.distributedLock('DICT' + updateAuthRoleDto.roleKey, updateAuthRoleDto.roleKey); const lock = await this.redisService.distributedLock('ROLE' + updateAuthRoleDto.roleKey, updateAuthRoleDto.roleKey);
// ? 存在正在进行写入的角色 // ? 存在正在进行写入的角色
if (!lock) throw new HttpException('服务繁忙,角色标识重复!', HttpStatus.CONFLICT); if (!lock) throw new HttpException('服务繁忙,角色标识重复!', HttpStatus.CONFLICT);
@ -396,7 +397,7 @@ export class AuthRoleService {
updateName: userTable1.nickname, updateName: userTable1.nickname,
}) })
.leftJoin(pacAuthUser, eq(pacAuthRole.createby, pacAuthUser.userId)) .leftJoin(pacAuthUser, eq(pacAuthRole.createby, pacAuthUser.userId))
.leftJoin(userTable1, eq(pacAuthRole.updateby, pacAuthUser.userId)) .leftJoin(userTable1, eq(pacAuthRole.updateby, userTable1.userId))
.limit(getPacAuthRoleAllDto.pageSize) .limit(getPacAuthRoleAllDto.pageSize)
.offset(offset); .offset(offset);
@ -459,7 +460,7 @@ export class AuthRoleService {
.from(pacAuthRole) .from(pacAuthRole)
.leftJoin(pacCoreDict, eq(pacAuthRole.roleType, pacCoreDict.dictId)) .leftJoin(pacCoreDict, eq(pacAuthRole.roleType, pacCoreDict.dictId))
.leftJoin(pacAuthUser, eq(pacAuthRole.createby, pacAuthUser.userId)) .leftJoin(pacAuthUser, eq(pacAuthRole.createby, pacAuthUser.userId))
.leftJoin(userTable1, eq(pacAuthRole.updateby, pacAuthUser.userId)) .leftJoin(userTable1, eq(pacAuthRole.updateby, userTable1.userId))
.where(and(isNull(pacAuthRole.deleteby), eq(pacAuthRole.roleId, roleId))); .where(and(isNull(pacAuthRole.deleteby), eq(pacAuthRole.roleId, roleId)));
// ! 如果不存在角色信息直接报错 // ! 如果不存在角色信息直接报错
@ -572,11 +573,11 @@ export class AuthRoleService {
} }
// DB 查找角色下的账户查询构建 // DB 查找角色下的账户查询构建
private getRoleUserQuery(roleId: string, getUserForRoleDto: GetUserForRoleDto, selectData = null) { private getRoleUserQuery(roleId: string, getUserForAttDto: GetUserForAttDto, selectData = null) {
const query = this.mysqlService.db const query = this.mysqlService.db
.select(selectData) .select(selectData)
.from(pacAuthUser) .from(pacAuthUser)
.orderBy(isTrueEnum(getUserForRoleDto.isAsc) ? asc(pacAuthUser.userId) : desc(pacAuthUser.userId)) .orderBy(isTrueEnum(getUserForAttDto.isAsc) ? asc(pacAuthUser.userId) : desc(pacAuthUser.userId))
.leftJoin(pacCoreDict, eq(pacAuthUser.userType, pacCoreDict.dictId)) .leftJoin(pacCoreDict, eq(pacAuthUser.userType, pacCoreDict.dictId))
.leftJoin(pacAuthLinkUserRole, eq(pacAuthLinkUserRole.userId, pacAuthUser.userId)) .leftJoin(pacAuthLinkUserRole, eq(pacAuthLinkUserRole.userId, pacAuthUser.userId))
.$dynamic(); .$dynamic();
@ -588,29 +589,29 @@ export class AuthRoleService {
// ? 模糊查询 // ? 模糊查询
wl.push( wl.push(
or( or(
like(pacAuthUser.nickname, likeQuery(getUserForRoleDto.userInfo)), like(pacAuthUser.nickname, likeQuery(getUserForAttDto.userInfo)),
like(pacAuthUser.userDesc, likeQuery(getUserForRoleDto.userInfo)), like(pacAuthUser.userDesc, likeQuery(getUserForAttDto.userInfo)),
like(pacAuthUser.userEmail, likeQuery(getUserForRoleDto.userInfo)), like(pacAuthUser.userEmail, likeQuery(getUserForAttDto.userInfo)),
like(pacAuthUser.userPhone, likeQuery(getUserForRoleDto.userInfo)), like(pacAuthUser.userPhone, likeQuery(getUserForAttDto.userInfo)),
like(pacAuthUser.username, likeQuery(getUserForRoleDto.userInfo)), like(pacAuthUser.username, likeQuery(getUserForAttDto.userInfo)),
).if(isExistKey(getUserForRoleDto, 'userInfo')), ).if(isExistKey(getUserForAttDto, 'userInfo')),
); );
// ? 目标roleId // ? 目标roleId
wl.push(eq(pacAuthLinkUserRole.roleId, roleId)); wl.push(eq(pacAuthLinkUserRole.roleId, roleId));
// ? 用户类型 // ? 用户类型
wl.push(eq(pacAuthUser.userType, getUserForRoleDto.userType).if(isExistKey(getUserForRoleDto, 'userType'))); wl.push(eq(pacAuthUser.userType, getUserForAttDto.userType).if(isExistKey(getUserForAttDto, 'userType')));
query.where(and(...wl)); query.where(and(...wl));
return query; return query;
} }
// DB 查找角色下的账户 // DB 查找角色下的账户
private async getRoleUser(roleId: string, getUserForRoleDto: GetUserForRoleDto) { private async getRoleUser(roleId: string, getUserForAttDto: GetUserForAttDto) {
const offset = (getUserForRoleDto.pageNumber - 1) * getUserForRoleDto.pageSize; const offset = (getUserForAttDto.pageNumber - 1) * getUserForAttDto.pageSize;
// ! 使用基础查询构建查询总记录数 // ! 使用基础查询构建查询总记录数
const totalCountQuery = this.getRoleData(getUserForRoleDto, { const totalCountQuery = this.getRoleUserQuery(roleId, getUserForAttDto, {
totalCount: sql`COUNT(*)`, totalCount: sql`COUNT(*)`,
}); });
@ -618,7 +619,7 @@ export class AuthRoleService {
// 重命名表 // 重命名表
const userTable1 = alias(pacAuthUser, 'userTable1'); const userTable1 = alias(pacAuthUser, 'userTable1');
const userTable2 = alias(pacAuthUser, 'userTable2'); const userTable2 = alias(pacAuthUser, 'userTable2');
const paginatedQuery = this.getRoleUserQuery(roleId, getUserForRoleDto, { const paginatedQuery = this.getRoleUserQuery(roleId, getUserForAttDto, {
userId: pacAuthUser.userId, userId: pacAuthUser.userId,
username: pacAuthUser.username, username: pacAuthUser.username,
nickname: pacAuthUser.nickname, nickname: pacAuthUser.nickname,
@ -637,13 +638,13 @@ export class AuthRoleService {
}) })
.leftJoin(userTable2, eq(pacAuthUser.createby, userTable2.userId)) .leftJoin(userTable2, eq(pacAuthUser.createby, userTable2.userId))
.leftJoin(userTable1, eq(pacAuthUser.updateby, userTable1.userId)) .leftJoin(userTable1, eq(pacAuthUser.updateby, userTable1.userId))
.limit(getUserForRoleDto.pageSize) .limit(getUserForAttDto.pageSize)
.offset(offset); .offset(offset);
return { return {
total: (await totalCountQuery)[0].totalCount, total: (await totalCountQuery)[0].totalCount,
rowData: await paginatedQuery, rowData: await paginatedQuery,
searchData: getUserForRoleDto, searchData: getUserForAttDto,
}; };
} }

@ -2,9 +2,7 @@ import { ApiProperty } from '@nestjs/swagger';
import Trim from '@common/decorator/trim/trim.decorator'; import Trim from '@common/decorator/trim/trim.decorator';
import { ArrayMinSize, IsEnum, IsInt, IsOptional, IsString, Length, Max, MaxLength, Min, MinLength } from 'class-validator'; import { ArrayMinSize, IsEnum, IsInt, IsOptional, IsString, Length, Max, MaxLength, Min, MinLength } from 'class-validator';
import { BooleanEnum } from '@utils/boolean.enum'; import { BooleanEnum } from '@utils/boolean.enum';
import ChangeCase, { import ChangeCase, { CaseType } from '@common/decorator/change-case/change-case.decorator';
CaseType
} from "@common/decorator/change-case/change-case.decorator";
export class CreateAuthRoleDto { export class CreateAuthRoleDto {
@ApiProperty({ @ApiProperty({

@ -96,33 +96,3 @@ export class GetPacAuthRoleAllDto extends GetDto {
@IsOptional() @IsOptional()
readonly hierarchy?: string; readonly hierarchy?: string;
} }
export class GetUserForRoleDto extends GetDto {
@ApiProperty({
description: '用户信息',
type: String,
example: '哈哈',
required: false,
minLength: 1,
maxLength: 128,
})
@Trim()
@IsString({ message: '用户信息应为字符串格式!' })
@Length(0, 128, { message: '请将用户信息长度控制在1到128位之间!' })
@IsOptional()
readonly userInfo?: string;
@ApiProperty({
description: '用户类型,来自于字典',
type: String,
example: '0',
required: false,
minLength: 19,
maxLength: 19,
})
@Trim()
@IsString({ message: '用户类型格式不正确!' })
@Length(19, 19, { message: '用户类型格式不正确!' })
@IsOptional()
readonly userType: string;
}

@ -2,9 +2,7 @@ import { ApiProperty } from '@nestjs/swagger';
import { IsEnum, IsInt, IsOptional, IsString, Length, Max, Min } from 'class-validator'; import { IsEnum, IsInt, IsOptional, IsString, Length, Max, Min } from 'class-validator';
import Trim from '@common/decorator/trim/trim.decorator'; import Trim from '@common/decorator/trim/trim.decorator';
import { BooleanEnum } from '@utils/boolean.enum'; import { BooleanEnum } from '@utils/boolean.enum';
import ChangeCase, { import ChangeCase, { CaseType } from '@common/decorator/change-case/change-case.decorator';
CaseType
} from "@common/decorator/change-case/change-case.decorator";
export class CreateCoreDictDto { export class CreateCoreDictDto {
@ApiProperty({ @ApiProperty({

@ -34,7 +34,6 @@ export class GetPacCoreDictAllDto extends GetDto {
@IsOptional() @IsOptional()
readonly dictInfo?: string; readonly dictInfo?: string;
@ApiProperty({ @ApiProperty({
description: '字典类型', description: '字典类型',
type: String, type: String,

@ -2,9 +2,7 @@ import { ApiProperty } from '@nestjs/swagger';
import Trim from '@common/decorator/trim/trim.decorator'; import Trim from '@common/decorator/trim/trim.decorator';
import { IsEnum, IsInt, IsOptional, IsString, Length, Max, Min } from 'class-validator'; import { IsEnum, IsInt, IsOptional, IsString, Length, Max, Min } from 'class-validator';
import { BooleanEnum } from '@utils/boolean.enum'; import { BooleanEnum } from '@utils/boolean.enum';
import ChangeCase, { import ChangeCase, { CaseType } from '@common/decorator/change-case/change-case.decorator';
CaseType
} from "@common/decorator/change-case/change-case.decorator";
export class CreateCoreMenuDto { export class CreateCoreMenuDto {
@ApiProperty({ @ApiProperty({

@ -17,9 +17,7 @@ import Trim from '@common/decorator/trim/trim.decorator';
import { IsEnum, IsInt, IsOptional, IsString, Length, Max, Min } from 'class-validator'; import { IsEnum, IsInt, IsOptional, IsString, Length, Max, Min } from 'class-validator';
import { BooleanEnum } from '@utils/boolean.enum'; import { BooleanEnum } from '@utils/boolean.enum';
import Int from '@common/decorator/int/int.descrator'; import Int from '@common/decorator/int/int.descrator';
import ChangeCase, { import ChangeCase, { CaseType } from '@common/decorator/change-case/change-case.decorator';
CaseType
} from "@common/decorator/change-case/change-case.decorator";
export class GetPacCoreMenuAllDto extends GetDto { export class GetPacCoreMenuAllDto extends GetDto {
@ApiProperty({ @ApiProperty({

@ -1,9 +1,7 @@
import { IsOptional, IsString, Length } from 'class-validator'; import { IsOptional, IsString, Length } from 'class-validator';
import { ApiProperty } from '@nestjs/swagger'; import { ApiProperty } from '@nestjs/swagger';
import Trim from '@common/decorator/trim/trim.decorator'; import Trim from '@common/decorator/trim/trim.decorator';
import ChangeCase, { import ChangeCase, { CaseType } from '@common/decorator/change-case/change-case.decorator';
CaseType
} from "@common/decorator/change-case/change-case.decorator";
export class CreateCoreServiceDto { export class CreateCoreServiceDto {
@ApiProperty({ @ApiProperty({

@ -42,3 +42,32 @@ export class RoleLinkUserDto {
@Length(19, 19, { each: true, message: '账户Id格式错误' }) @Length(19, 19, { each: true, message: '账户Id格式错误' })
readonly userIdList?: string[]; readonly userIdList?: string[];
} }
export class DeptLinkUserDto {
@ApiProperty({
description: '角色ID',
type: String,
example: '0',
required: true,
minLength: 19,
maxLength: 19,
})
@Trim()
@IsString({ message: '角色属性格式不正确!' })
@Length(19, 19, { message: '角色属性格式不正确!' })
readonly deptId: string;
@ApiProperty({
description: '账户Id列表',
type: [String],
example: ['a'],
required: true,
minItems: 1,
})
@IsString({ each: true, message: '账户Id格式错误' })
@ArrayMinSize(1, { message: '至少需要选择一个需要绑定的账户' })
@ArrayMaxSize(200, { message: '需要绑定的账户账户超过限制' })
@Length(19, 19, { each: true, message: '账户Id格式错误' })
readonly userIdList?: string[];
}

@ -0,0 +1,47 @@
// | ------------------------------------------------------------
// | @版本: version 0.1
// | @创建人: 【Nie-x7129】
// | @E-mail: x71291@outlook.com
// | @所在项目: pac-auth
// | @文件描述: GetUserForAtt.dto.ts -
// | @创建时间: 2024-06-28 16:55
// | @更新时间: 2024-06-28 16:55
// | @修改记录:
// | -*-*-*- (时间--修改人--修改说明) -*-*-*-
// | =
// | ------------------------------------------------------------
import { GetDto } from '@dto/get.dto';
import { ApiProperty } from '@nestjs/swagger';
import Trim from '@common/decorator/trim/trim.decorator';
import { IsOptional, IsString, Length } from 'class-validator';
export class GetUserForAttDto extends GetDto {
@ApiProperty({
description: '用户信息',
type: String,
example: '哈哈',
required: false,
minLength: 1,
maxLength: 128,
})
@Trim()
@IsString({ message: '用户信息应为字符串格式!' })
@Length(0, 128, { message: '请将用户信息长度控制在1到128位之间!' })
@IsOptional()
readonly userInfo?: string;
@ApiProperty({
description: '用户类型,来自于字典',
type: String,
example: '0',
required: false,
minLength: 19,
maxLength: 19,
})
@Trim()
@IsString({ message: '用户类型格式不正确!' })
@Length(19, 19, { message: '用户类型格式不正确!' })
@IsOptional()
readonly userType: string;
}

@ -1,3 +1,2 @@
import { relations } from "drizzle-orm/relations"; import { relations } from 'drizzle-orm/relations';
import { } from "./schema"; import {} from './schema';

Loading…
Cancel
Save