修改serviceKey和root字段,增加root权限控制原始数据

main
expressgy 3 months ago
parent f9102f8761
commit f2504b390f
  1. 1386
      docs/pacAuth_database_0.2.ndm2
  2. 18
      src/application/core-dict/core-dict.controller.ts
  3. 95
      src/application/core-dict/core-dict.service.ts
  4. 6
      src/application/core-dict/dto/create-core-dict.dto.ts
  5. 36
      src/application/core-dict/dto/get-core-dict.dto.ts
  6. 14
      src/application/core-env/core-env.controller.ts
  7. 89
      src/application/core-env/core-env.service.ts
  8. 7
      src/application/core-env/dto/create-core-env.dto.ts
  9. 20
      src/application/core-env/dto/get-core-env.dto.ts
  10. 12
      src/application/core-menu/core-menu.service.ts
  11. 6
      src/application/core-menu/dto/create-core-menu.dto.ts
  12. 3
      src/application/core-menu/dto/get-core-menu.dto.ts
  13. 20
      src/application/core-service/core-service.controller.spec.ts
  14. 5
      src/application/core-service/core-service.controller.ts
  15. 18
      src/application/core-service/core-service.service.spec.ts
  16. 77
      src/application/core-service/core-service.service.ts
  17. 36
      src/application/core-service/dto/serviceKey.dto.ts
  18. 1
      src/application/core-service/entities/core-service.entity.ts
  19. 2
      src/common/http-except/http-except.filter.ts
  20. 1
      src/common/interceptor/log-request-info/log-request-info.interceptor.ts
  21. 5
      src/entities/relations.ts
  22. 74
      src/entities/schema.ts
  23. 2
      src/service/logger/logger.service.ts

File diff suppressed because it is too large Load Diff

@ -5,7 +5,7 @@ import { UpdateCoreDictDto } from './dto/update-core-dict.dto';
import { ApiOperation, ApiProduces, ApiTags } from '@nestjs/swagger';
import { PacInfo } from '@common/decorator/pac-info/pac-info.decorator';
import { PacInfoType } from '@utils/myType';
import { GetPacCoreDictAllDto, PacCoreDictIdDto, PacCoreDictKeyDto, PacCoreDictTargetListDto } from '@app/core-dict/dto/get-core-dict.dto';
import { GetPacCoreDictAllDto, PacCoreDictTargetListDto } from '@app/core-dict/dto/get-core-dict.dto';
@ApiTags('字典服务')
@Controller('coredict')
@ -38,8 +38,8 @@ export class CoreDictController {
})
@ApiProduces('application/json')
@Get('/details/:dictId')
findOne(@Param() pacCoreDictIdDto: PacCoreDictIdDto) {
return this.coreDictService.findOne(pacCoreDictIdDto);
findOne(@Param('dictId') dictId: string) {
return this.coreDictService.findOne(dictId);
}
@ApiOperation({
@ -48,8 +48,8 @@ export class CoreDictController {
})
@ApiProduces('application/json')
@Get('/list/:dictKey')
findTargetList(@Param() pacCoreDictKeyDto: PacCoreDictKeyDto, @Query() pacCoreDictTreeDto: PacCoreDictTargetListDto) {
return this.coreDictService.findTargetList(pacCoreDictKeyDto, pacCoreDictTreeDto);
findTargetList(@Param('dictKey') dictKey: string, @Query() pacCoreDictTreeDto: PacCoreDictTargetListDto) {
return this.coreDictService.findTargetList(dictKey, pacCoreDictTreeDto);
}
@ApiOperation({
@ -58,8 +58,8 @@ export class CoreDictController {
})
@ApiProduces('application/json')
@Patch(':dictId')
update(@Param() pacCoreDictIdDto: PacCoreDictIdDto, @Body() updateCoreDictDto: UpdateCoreDictDto, @PacInfo() pacInfo: PacInfoType) {
return this.coreDictService.update(pacCoreDictIdDto, updateCoreDictDto, pacInfo);
update(@Param('dictId') dictId: string, @Body() updateCoreDictDto: UpdateCoreDictDto, @PacInfo() pacInfo: PacInfoType) {
return this.coreDictService.update(dictId, updateCoreDictDto, pacInfo);
}
@ApiOperation({
@ -68,7 +68,7 @@ export class CoreDictController {
})
@ApiProduces('application/json')
@Delete(':dictId')
remove(@Param() pacCoreDictIdDto: PacCoreDictIdDto, @PacInfo() pacInfo: PacInfoType) {
return this.coreDictService.remove(pacCoreDictIdDto, pacInfo);
remove(@Param('dictId') dictId: string, @PacInfo() pacInfo: PacInfoType) {
return this.coreDictService.remove(dictId, pacInfo);
}
}

@ -7,7 +7,7 @@ import { RedisService } from '@common/service/redis/redis.service';
import { pacAuthUser, pacCoreDict, pacCoreService } from '@entities/schema';
import { and, asc, desc, eq, isNull, like, or, SQL, sql } from 'drizzle-orm';
import { Snowflake } from '@service/snowflake/snowflake.service';
import { GetPacCoreDictAllDto, PacCoreDictIdDto, PacCoreDictKeyDto, PacCoreDictTargetListDto } from '@app/core-dict/dto/get-core-dict.dto';
import { GetPacCoreDictAllDto, PacCoreDictTargetListDto } from '@app/core-dict/dto/get-core-dict.dto';
import { ConfigService } from '@nestjs/config';
import { likeQuery } from '@utils/likeQuery';
import { QueryBuilder } from 'drizzle-orm/mysql-core';
@ -26,10 +26,10 @@ export class CoreDictService {
dictName: pacCoreDict.dictName,
dictIcon: pacCoreDict.dictIcon,
dictType: pacCoreDict.dictType,
ownOfPac: pacCoreDict.ownOfPac,
root: pacCoreDict.root,
orderNum: pacCoreDict.orderNum,
status: pacCoreDict.status,
serviceOf: pacCoreDict.serviceOf,
serviceKey: pacCoreDict.serviceKey,
serviceName: pacCoreService.serviceName,
haveChildren: pacCoreDict.haveChildren,
createby: pacCoreDict.createby,
@ -64,7 +64,12 @@ export class CoreDictService {
* DESC: 创建字典内容
* DATE: 2024-05-31 19:12:47 -
* */
public async create(createCoreDictDto: CreateCoreDictDto, userInfo) {
public async create(createCoreDictDto: CreateCoreDictDto, pacInfo: PacInfoType) {
// ! 判断是否是root账户,非root账户无法设置为root
if (this.config.get<number>('masterId') !== pacInfo.userId && isTrueEnum(createCoreDictDto.root)) {
throw new HttpException('没有权限创建原始字典!', HttpStatus.UNAUTHORIZED);
}
// ! 加目标锁
const lock = await this.redisService.distributedLock('DICT' + createCoreDictDto.dictKey, createCoreDictDto.dictKey);
@ -80,7 +85,7 @@ export class CoreDictService {
if (result.length > 0) throw new HttpException('字典标识重复!', HttpStatus.CONFLICT);
// ! 添加字典数据
const newPacCoreDict = await this.addDictData(createCoreDictDto, userInfo.userId);
const newPacCoreDict = await this.addDictData(createCoreDictDto, pacInfo.userId);
// ! 解锁
lock();
@ -120,8 +125,10 @@ export class CoreDictService {
* DESC: 查找字典项详细信息
* DATE: 2024-06-04 19:21:40 -
* */
public async findOne(pacCoreDictIdDto: PacCoreDictIdDto) {
return (await this.getMore(pacCoreDictIdDto.dictId))[0];
public async findOne(dictId: string) {
const result = await this.getMore(dictId);
if (result.length == 0) throw new HttpException('未找到目标字典详细信息!', HttpStatus.BAD_REQUEST);
return result[0];
}
/** Service
@ -129,8 +136,8 @@ export class CoreDictService {
* DESC: 查找字典下的列表或树
* DATE: 2024-06-04 19:21:40 -
* */
public async findTargetList(pacCoreDictKeyDto: PacCoreDictKeyDto, pacCoreDictTargetListDto: PacCoreDictTargetListDto) {
const [result] = await this.getTargetDictList(pacCoreDictKeyDto, pacCoreDictTargetListDto);
public async findTargetList(dictKey: string, pacCoreDictTargetListDto: PacCoreDictTargetListDto) {
const [result] = await this.getTargetDictList(dictKey, pacCoreDictTargetListDto);
return result;
}
@ -139,7 +146,21 @@ export class CoreDictService {
* DESC: 更新字典
* DATE: 2024-06-04 23:24:18 -
* */
public async update(pacCoreDictIdDto: PacCoreDictIdDto, updateCoreDictDto: UpdateCoreDictDto, pacInfo: PacInfoType) {
public async update(dictId: string, updateCoreDictDto: UpdateCoreDictDto, pacInfo: PacInfoType) {
// ! 判断是否是root账户,非root账户无法设置为root
if (this.config.get<number>('masterId') !== pacInfo.userId && updateCoreDictDto.root !== undefined) {
throw new HttpException('没有权限修改原始字典!', HttpStatus.UNAUTHORIZED);
}
// ! 产看目标字典是否存在
const oldDict = await this.getMore(dictId);
if (oldDict.length == 0) throw new HttpException('未找到目标字典,无法修改!', HttpStatus.BAD_REQUEST);
// ! root数据,非root用户不允许修改
if (oldDict[0].root && this.config.get<number>('masterId') !== pacInfo.userId) {
throw new HttpException('原始字典,权限不足无法修改!', HttpStatus.BAD_REQUEST);
}
// ! 上锁
const lock = await this.redisService.distributedLock('DICT' + updateCoreDictDto.dictKey, updateCoreDictDto.dictKey);
@ -152,12 +173,12 @@ export class CoreDictService {
const checkRepeat = await this.getDictDataForDictKey(updateCoreDictDto.dictKey);
// ? 判断是否存在重名的字典,但是不包括自己
if (checkRepeat.length > 0 && checkRepeat[0].dictId != pacCoreDictIdDto.dictId) {
if (checkRepeat.length > 0 && checkRepeat[0].dictId != dictId) {
throw new HttpException('服务繁忙,字典标识重复!', HttpStatus.CONFLICT);
}
// ! 更新数据
const result = await this.updateDictData(pacCoreDictIdDto, updateCoreDictDto, pacInfo);
const result = await this.updateDictData(dictId, updateCoreDictDto, pacInfo);
// ! 解锁
lock();
@ -178,18 +199,23 @@ export class CoreDictService {
* DESC: 删除字典
* DATE: 2024-06-04 22:01:11 -
* */
public async remove(pacCoreDictIdDto: PacCoreDictIdDto, pacInfo: PacInfoType) {
public async remove(dictId: string, pacInfo: PacInfoType) {
// ! 查看目标字典项
const result = await this.getMore(pacCoreDictIdDto.dictId);
const result = await this.getMore(dictId);
// ? 判断是否存在
if (result.length > 0) {
// ! root数据,非root用户不允许删除
if (result[0].root && this.config.get<number>('masterId') !== pacInfo.userId) {
throw new HttpException('原始字典,权限不足无法删除!', HttpStatus.BAD_REQUEST);
}
// ! 存在目标字典项
// ? 判断是否存在子项
if (result[0].haveChildren == 0) {
// ! 删除字典
await this.deleteDictItem(pacCoreDictIdDto, pacInfo);
await this.deleteDictItem(dictId, pacInfo);
} else {
throw new HttpException('该字典存在子项!', HttpStatus.BAD_REQUEST);
}
@ -216,9 +242,6 @@ export class CoreDictService {
// ! 生成雪花id,用于字典主键
const id = await this.snowflake.generate();
// ? 判断身份是否是pac,如果是pac才能写入是pac的数据
const isPac = this.config.get<number>('masterId') == userId && isTrueEnum(createCoreDictDto.ownOfPac);
// ! 定义写入的字典数据
const newDictData: typeof pacCoreDict.$inferInsert = {
pid: createCoreDictDto.pid,
@ -228,9 +251,9 @@ export class CoreDictService {
dictName: createCoreDictDto.dictName,
dictIcon: createCoreDictDto.dictIcon,
dictType: createCoreDictDto.dictType,
ownOfPac: isPac ? 0 : 1,
root: isTrueEnum(createCoreDictDto) ? 1 : 0,
orderNum: createCoreDictDto.orderNum,
serviceOf: createCoreDictDto.serviceOf,
serviceKey: createCoreDictDto.serviceKey,
createby: userId,
createtime: sql`now()` as any,
};
@ -276,13 +299,13 @@ export class CoreDictService {
);
// ? 是否查pac的数据
wl.push(eq(pacCoreDict.ownOfPac, isTrueEnum(data['ownOfPac']) ? 0 : 1).if(isExistKey(data, 'ownOfPac') && isTrueEnum(data['ownOfPac'])));
wl.push(eq(pacCoreDict.root, isTrueEnum(data['root']) ? 0 : 1).if(isExistKey(data, 'root') && isTrueEnum(data['root'])));
// ? 按照层级查
wl.push(eq(pacCoreDict.pid, data.hierarchy).if(isExistKey(data, 'hierarchy')));
// ? 是否存在目标service
wl.push(eq(pacCoreDict.serviceOf, data.serviceOf).if(isExistKey(data, 'serviceOf')));
wl.push(eq(pacCoreDict.serviceKey, data.serviceKey).if(isExistKey(data, 'serviceKey')));
// ? 是否查字典类型
wl.push(eq(pacCoreDict.dictType, data.dictType).if(isExistKey(data, 'dictType')));
@ -311,7 +334,7 @@ export class CoreDictService {
// 使用基础查询构建分页查询
const paginatedQuery = this.getDict(getCoreDictAllDto, this.dictMoreDataType)
.leftJoin(pacAuthUser, eq(pacCoreDict.createby, pacAuthUser.userId))
.leftJoin(pacCoreService, eq(pacCoreService.serviceKey, pacCoreDict.serviceOf))
.leftJoin(pacCoreService, eq(pacCoreService.serviceKey, pacCoreDict.serviceKey))
.limit(getCoreDictAllDto.pageSize)
.offset(offset);
@ -328,12 +351,12 @@ export class CoreDictService {
.select(this.dictMoreDataType)
.from(pacCoreDict)
.leftJoin(pacAuthUser, eq(pacCoreDict.createby, pacAuthUser.userId))
.leftJoin(pacCoreService, eq(pacCoreService.serviceKey, pacCoreDict.serviceOf))
.leftJoin(pacCoreService, eq(pacCoreService.serviceKey, pacCoreDict.serviceKey))
.where(and(eq(pacCoreDict.dictId, dictId), isNull(pacCoreDict.deleteby)));
}
// DB 通过Key查找目标字典的信息?树结构
private getTargetDictList(pacCoreDictKeyDto: PacCoreDictKeyDto, pacCoreDictTargetListDto: PacCoreDictTargetListDto) {
// DB 通过Key查找目标字典的信息?树结构 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
private getTargetDictList(dictKey: string, pacCoreDictTargetListDto: PacCoreDictTargetListDto) {
if (isExistKey(pacCoreDictTargetListDto, 'isTree') && isTrueEnum(pacCoreDictTargetListDto['isTree'])) {
// ! 基础层级
const baseQueryBuilder = new QueryBuilder();
@ -343,7 +366,7 @@ export class CoreDictService {
level: sql`0`.as('level'),
})
.from(pacCoreDict)
.where(and(isNull(pacCoreDict.deleteby), eq(pacCoreDict.dictKey, pacCoreDictKeyDto.dictKey)));
.where(and(isNull(pacCoreDict.deleteby), eq(pacCoreDict.dictKey, dictKey)));
// ! 递归层级
const recursiveQueryBuilder = new QueryBuilder();
@ -368,26 +391,24 @@ export class CoreDictService {
.select(this.dictMoreDataType)
.from(pacCoreDict)
.leftJoin(pacAuthUser, eq(pacCoreDict.createby, pacAuthUser.userId))
.leftJoin(pacCoreService, eq(pacCoreService.serviceKey, pacCoreDict.serviceOf))
.where(and(eq(pacCoreDict.dictKey, pacCoreDictKeyDto.dictKey), isNull(pacCoreDict.deleteby)));
.leftJoin(pacCoreService, eq(pacCoreService.serviceKey, pacCoreDict.serviceKey))
.where(and(eq(pacCoreDict.dictKey, dictKey), isNull(pacCoreDict.deleteby)));
}
}
// DB 通过ID删除字典项
private deleteDictItem(pacCoreDictIdDto: PacCoreDictIdDto, pacInfo: PacInfoType) {
private deleteDictItem(dictId: string, pacInfo: PacInfoType) {
return this.mysqlService.db
.update(pacCoreDict)
.set({
deletetime: sql`now()`,
deleteby: pacInfo.userId,
})
.where(eq(pacCoreDict.dictId, pacCoreDictIdDto.dictId));
.where(eq(pacCoreDict.dictId, dictId));
}
// DB 更新字典
private updateDictData(pacCoreDictIdDto: PacCoreDictIdDto, updateCoreDictDto: UpdateCoreDictDto, pacInfo: PacInfoType) {
// ? 判断身份是否是pac,如果是pac才能写入是pac的数据
const isPac = this.config.get<number>('masterId') == pacInfo.userId && isTrueEnum(updateCoreDictDto.ownOfPac);
private updateDictData(dictId: string, updateCoreDictDto: UpdateCoreDictDto, pacInfo: PacInfoType) {
return this.mysqlService.db
.update(pacCoreDict)
.set({
@ -398,11 +419,11 @@ export class CoreDictService {
dictType: updateCoreDictDto.dictType,
orderNum: updateCoreDictDto.orderNum,
status: updateCoreDictDto.status,
ownOfPac: isPac ? 0 : 1,
serviceOf: updateCoreDictDto.serviceOf,
root: isTrueEnum(updateCoreDictDto.root) ? 1 : 0,
serviceKey: updateCoreDictDto.serviceKey,
updateby: pacInfo.userId,
updatetime: sql`now()`,
})
.where(eq(pacCoreDict.dictId, pacCoreDictIdDto.dictId));
.where(eq(pacCoreDict.dictId, dictId));
}
}

@ -1,5 +1,5 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsBoolean, 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 { BooleanEnum } from '@utils/boolean.enum';
@ -97,7 +97,7 @@ export class CreateCoreDictDto {
@Trim()
@IsEnum(BooleanEnum, { message: 'ownOfPac参数格式错误' })
@IsOptional()
readonly ownOfPac?: BooleanEnum = BooleanEnum.FALSE;
readonly root?: BooleanEnum = BooleanEnum.FALSE;
@ApiProperty({
description: '排序',
@ -131,5 +131,5 @@ export class CreateCoreDictDto {
@IsString({ message: '服务标识应为字符串格式!' })
@Length(2, 16, { message: '请将服务标识长度控制在2到16位之间!' })
@IsOptional()
readonly serviceOf: string;
readonly serviceKey: string;
}

@ -16,8 +16,7 @@ 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 {Type} from "class-transformer";
import Int from "@common/decorator/int/int.descrator";
import Int from '@common/decorator/int/int.descrator';
export class GetPacCoreDictAllDto extends GetDto {
@ApiProperty({
@ -55,7 +54,7 @@ export class GetPacCoreDictAllDto extends GetDto {
@Trim()
@IsEnum(BooleanEnum, { message: 'ownOfPac参数格式错误' })
@IsOptional()
readonly ownOfPac: BooleanEnum;
readonly root: BooleanEnum;
@ApiProperty({
description: '服务的唯一标识',
@ -69,7 +68,7 @@ export class GetPacCoreDictAllDto extends GetDto {
@IsString({ message: '服务标识应为字符串格式!' })
@Length(2, 16, { message: '请将服务标识长度控制在2到16位之间!' })
@IsOptional()
readonly serviceOf: string;
readonly serviceKey: string;
@ApiProperty({
description: '字典状态',
@ -108,35 +107,6 @@ export class GetPacCoreDictAllDto extends GetDto {
readonly hierarchy?: string;
}
export class PacCoreDictIdDto {
@ApiProperty({
description: '字典ID',
type: String,
example: '1123817263136',
required: true,
minLength: 19,
maxLength: 19,
})
@IsString()
@Length(19, 19, { message: '字典ID格式错误!' })
readonly dictId: string;
}
export class PacCoreDictKeyDto {
@ApiProperty({
description: '字典标志',
type: String,
example: 'Country',
required: true,
minLength: 1,
maxLength: 32,
})
@Trim()
@IsString({ message: '字典标志应为字符串格式!' })
@Length(1, 32, { message: '请将字典标志长度控制在1到32位之间!' })
readonly dictKey: string;
}
export class PacCoreDictTargetListDto {
@ApiProperty({
description: '是否查找树结构',

@ -5,7 +5,7 @@ import { UpdateCoreEnvDto } from './dto/update-core-env.dto';
import { ApiOperation, ApiProduces, ApiTags } from '@nestjs/swagger';
import { PacInfo } from '@common/decorator/pac-info/pac-info.decorator';
import { PacInfoType } from '@utils/myType';
import { CoreEnvIdDTO, CoreEnvKeyDTO, CoreEnvTargetListDTO, GetCoreEnvDTO } from '@app/core-env/dto/get-core-env.dto';
import { CoreEnvKeyDTO, CoreEnvTargetListDTO, GetCoreEnvDTO } from '@app/core-env/dto/get-core-env.dto';
@ApiTags('环境变量服务')
@Controller('coreenv')
@ -38,8 +38,8 @@ export class CoreEnvController {
})
@ApiProduces('application/json')
@Get('/details/:envId')
findOne(@Param() coreEnvIdDTO: CoreEnvIdDTO) {
return this.coreEnvService.findOne(coreEnvIdDTO);
findOne(@Param('envId') envId: string) {
return this.coreEnvService.findOne(envId);
}
@ApiOperation({
@ -58,8 +58,8 @@ export class CoreEnvController {
})
@ApiProduces('application/json')
@Patch(':envId')
update(@Param() coreEnvIdDTO: CoreEnvIdDTO, @Body() updateCoreEnvDto: UpdateCoreEnvDto, @PacInfo() pacInfo: PacInfoType) {
return this.coreEnvService.update(coreEnvIdDTO, updateCoreEnvDto, pacInfo);
update(@Param('envId') envId: string, @Body() updateCoreEnvDto: UpdateCoreEnvDto, @PacInfo() pacInfo: PacInfoType) {
return this.coreEnvService.update(envId, updateCoreEnvDto, pacInfo);
}
@ApiOperation({
@ -68,7 +68,7 @@ export class CoreEnvController {
})
@ApiProduces('application/json')
@Delete(':envId')
remove(@Param() coreEnvIdDTO: CoreEnvIdDTO, @PacInfo() pacInfo: PacInfoType) {
return this.coreEnvService.remove(coreEnvIdDTO, pacInfo);
remove(@Param('envId') envId: string, @PacInfo() pacInfo: PacInfoType) {
return this.coreEnvService.remove(envId, pacInfo);
}
}

@ -9,7 +9,7 @@ import { ConfigService } from '@nestjs/config';
import { pacAuthUser, pacCoreDict, pacCoreEnv, pacCoreService } from '@entities/schema';
import { and, asc, desc, eq, isNull, like, or, sql } from 'drizzle-orm';
import { isExistKey, isTrueEnum } from '@utils/boolean.enum';
import { CoreEnvIdDTO, CoreEnvKeyDTO, CoreEnvTargetListDTO, GetCoreEnvDTO } from '@app/core-env/dto/get-core-env.dto';
import { CoreEnvKeyDTO, CoreEnvTargetListDTO, GetCoreEnvDTO } from '@app/core-env/dto/get-core-env.dto';
import { likeQuery } from '@utils/likeQuery';
import { QueryBuilder } from 'drizzle-orm/mysql-core';
import { customDrizzleRowWithRecursive } from '@utils/customDrizzleRowWithRecursive';
@ -28,10 +28,10 @@ export class CoreEnvService {
envDictName: pacCoreDict.dictName,
valIsDict: pacCoreEnv.valIsDict,
haveChildren: pacCoreEnv.haveChildren,
ownOfPac: pacCoreEnv.ownOfPac,
root: pacCoreEnv.root,
orderNum: pacCoreEnv.orderNum,
status: pacCoreEnv.status,
serviceOf: pacCoreEnv.serviceOf,
serviceKey: pacCoreEnv.serviceKey,
};
// # 环境变量列表信息
@ -46,10 +46,10 @@ export class CoreEnvService {
valIsDict: pacCoreEnv.valIsDict,
envDesc: pacCoreEnv.envDesc,
haveChildren: pacCoreEnv.haveChildren,
ownOfPac: pacCoreEnv.ownOfPac,
root: pacCoreEnv.root,
orderNum: pacCoreEnv.orderNum,
status: pacCoreEnv.status,
serviceOf: pacCoreEnv.serviceOf,
serviceKey: pacCoreEnv.serviceKey,
serviceName: pacCoreService.serviceName,
createby: pacCoreEnv.createby,
createName: pacAuthUser.nickname,
@ -70,7 +70,12 @@ export class CoreEnvService {
* DESC: 创建环境变量内容
* DATE: 2024-06-05 11:48:04 -
* */
public async create(createCoreEnvDto: CreateCoreEnvDto, userInfo) {
public async create(createCoreEnvDto: CreateCoreEnvDto, pacInfo: PacInfoType) {
// ! 判断是否是root账户,非root账户无法设置为root
if (this.config.get<number>('masterId') !== pacInfo.userId && isTrueEnum(createCoreEnvDto.root)) {
throw new HttpException('没有权限创建原始变量!', HttpStatus.UNAUTHORIZED);
}
// ! 加目标锁
const lock = await this.redisService.distributedLock('ENV' + createCoreEnvDto.envKey, createCoreEnvDto.envKey);
@ -86,7 +91,7 @@ export class CoreEnvService {
if (result.length > 0) throw new HttpException('环境变量标识重复!', HttpStatus.CONFLICT);
// ! 添加环境变量数据
const newPacCoreEnv = await this.addEnvData(createCoreEnvDto, userInfo);
const newPacCoreEnv = await this.addEnvData(createCoreEnvDto, pacInfo);
// ! 解锁
lock();
@ -126,8 +131,8 @@ export class CoreEnvService {
* DESC: 查找环境变量项详细信息
* DATE: 2024-06-05 14:58:44 -
* */
public async findOne(coreEnvIdDTO: CoreEnvIdDTO) {
return (await this.getMore(coreEnvIdDTO.envId))[0];
public async findOne(envId: string) {
return (await this.getMore(envId))[0];
}
/** Service
@ -140,7 +145,23 @@ export class CoreEnvService {
return result;
}
public async update(coreEnvIdDTO: CoreEnvIdDTO, updateCoreEnvDto: UpdateCoreEnvDto, pacInfo: PacInfoType) {
public async update(envId: string, updateCoreEnvDto: UpdateCoreEnvDto, pacInfo: PacInfoType) {
// ! 判断是否是root账户,非root账户无法设置为root
if (this.config.get<number>('masterId') !== pacInfo.userId && updateCoreEnvDto.root !== undefined) {
throw new HttpException('没有权限修改原始字典!', HttpStatus.UNAUTHORIZED);
}
// ! 查变量是否存在
const oldEnv = await this.getMore(envId);
if (oldEnv.length == 0) {
throw new HttpException('未找到目标变量,无法修改!', HttpStatus.BAD_REQUEST);
}
// ! root数据,非root用户不允许修改
if (oldEnv[0].root && this.config.get<number>('masterId') !== pacInfo.userId) {
throw new HttpException('原始变量,权限不足无法修改!', HttpStatus.BAD_REQUEST);
}
// ! 上锁
const lock = await this.redisService.distributedLock('ENV' + updateCoreEnvDto.envKey, updateCoreEnvDto.envKey);
@ -153,12 +174,12 @@ export class CoreEnvService {
const checkRepeat = await this.getEnvForEnvKey(updateCoreEnvDto.envKey);
// ? 判断是否存在重名的环境变量,但是不包括自己
if (checkRepeat.length > 0 && checkRepeat[0].envId != coreEnvIdDTO.envId) {
if (checkRepeat.length > 0 && checkRepeat[0].envId != envId) {
throw new HttpException('环境变量标识重复!', HttpStatus.CONFLICT);
}
// ! 更新数据
const result = await this.updateEnvData(coreEnvIdDTO, updateCoreEnvDto, pacInfo);
const result = await this.updateEnvData(envId, updateCoreEnvDto, pacInfo);
// ! 解锁
lock();
@ -179,18 +200,23 @@ export class CoreEnvService {
* DESC: 删除环境变量
* DATE: 2024-06-05 17:17:28 -
* */
public async remove(coreEnvIdDTO: CoreEnvIdDTO, pacInfo: PacInfoType) {
public async remove(envId: string, pacInfo: PacInfoType) {
// ! 查看目标环境变量
const result = await this.getMore(coreEnvIdDTO.envId);
const result = await this.getMore(envId);
// ? 判断是否存在
if (result.length > 0) {
// ! root数据,非root用户不允许删除
if (result[0].root && this.config.get<number>('masterId') !== pacInfo.userId) {
throw new HttpException('原始变量,权限不足无法删除!', HttpStatus.BAD_REQUEST);
}
// ! 存在目标环境变量
// ? 判断是否存在子项
if (result[0].haveChildren == 0) {
// ! 删除目标环境变量
await this.deleteEnvItem(coreEnvIdDTO, pacInfo);
await this.deleteEnvItem(envId, pacInfo);
} else {
throw new HttpException('目标环境变量存在子项!', HttpStatus.BAD_REQUEST);
}
@ -217,9 +243,6 @@ export class CoreEnvService {
// ! 生成雪花id,用于环境变量主键
const id = await this.snowflake.generate();
// ? 判断身份是否是pac,如果是pac才能写入
const isPac = this.config.get<number>('masterId') == userInfo.userId && isTrueEnum(createCoreEnvDto.ownOfPac);
// ! 定义即将写入的环境变量数据
const newEnvData = {
envId: id,
@ -229,9 +252,9 @@ export class CoreEnvService {
envVal: createCoreEnvDto.envVal,
valIsDict: isTrueEnum(createCoreEnvDto.valIsDict) ? 1 : 0,
envDesc: createCoreEnvDto.envDesc,
ownOfPac: isPac ? 0 : 1,
root: isTrueEnum(createCoreEnvDto.root) ? 1 : 0,
orderNum: createCoreEnvDto.orderNum,
serviceOf: createCoreEnvDto.serviceOf,
serviceKey: createCoreEnvDto.serviceKey,
createby: userInfo.userId,
createtime: sql`now()`,
};
@ -252,8 +275,6 @@ export class CoreEnvService {
// DB 查Env项的查询函数QueryBuilder,作用于列表和分页查询
private getEnv(data, selectData = undefined) {
this.logger.info(JSON.stringify(data, null, 2));
// ! 定义基础查询函数
// 启用动态查询模式 $dynamic
const query = this.mysqlService.db
@ -289,13 +310,13 @@ export class CoreEnvService {
// }
// ? 是否查pac的数据
wl.push(eq(pacCoreEnv.ownOfPac, isTrueEnum(data['ownOfPac']) ? 0 : 1).if(isExistKey(data, 'ownOfPac') && isTrueEnum(data['ownOfPac'])));
wl.push(eq(pacCoreEnv.root, isTrueEnum(data['root']) ? 0 : 1).if(isExistKey(data, 'root') && isTrueEnum(data['root'])));
// ? 按照层级查
wl.push(eq(pacCoreEnv.pid, data.hierarchy).if(isExistKey(data, 'hierarchy')));
// ? 是否存在目标service
wl.push(eq(pacCoreEnv.serviceOf, data.serviceOf).if(isExistKey(data, 'serviceOf')));
wl.push(eq(pacCoreEnv.serviceKey, data.serviceKey).if(isExistKey(data, 'serviceKey')));
// ? 是否查环境变量状态
wl.push(eq(pacCoreEnv.status, data.status).if(isExistKey(data, 'status')));
@ -321,7 +342,7 @@ export class CoreEnvService {
// 使用基础查询构建分页查询
const paginatedQuery = this.getEnv(getCoreEnvDTO, this.envMoreDataType)
.leftJoin(pacAuthUser, eq(pacCoreEnv.createby, pacAuthUser.userId))
.leftJoin(pacCoreService, eq(pacCoreEnv.serviceOf, pacCoreService.serviceKey))
.leftJoin(pacCoreService, eq(pacCoreEnv.serviceKey, pacCoreService.serviceKey))
.limit(getCoreEnvDTO.pageSize)
.offset(offset);
@ -338,7 +359,7 @@ export class CoreEnvService {
.select(this.envMoreDataType)
.from(pacCoreEnv)
.leftJoin(pacAuthUser, eq(pacCoreEnv.createby, pacAuthUser.userId))
.leftJoin(pacCoreService, eq(pacCoreEnv.serviceOf, pacCoreService.serviceKey))
.leftJoin(pacCoreService, eq(pacCoreEnv.serviceKey, pacCoreService.serviceKey))
.leftJoin(pacCoreDict, and(eq(pacCoreDict.dictId, pacCoreEnv.envVal), eq(pacCoreEnv.valIsDict, 1)))
.where(and(eq(pacCoreEnv.envId, envId), isNull(pacCoreEnv.deleteby)));
}
@ -382,27 +403,25 @@ export class CoreEnvService {
.select(this.envMoreDataType)
.from(pacCoreEnv)
.leftJoin(pacAuthUser, eq(pacCoreEnv.createby, pacAuthUser.userId))
.leftJoin(pacCoreService, eq(pacCoreEnv.serviceOf, pacCoreService.serviceKey))
.leftJoin(pacCoreService, eq(pacCoreEnv.serviceKey, pacCoreService.serviceKey))
.leftJoin(pacCoreDict, and(eq(pacCoreDict.dictId, pacCoreEnv.envVal), eq(pacCoreEnv.valIsDict, 1)))
.where(and(eq(pacCoreEnv.envKey, coreEnvKeyDTO.envKey), isNull(pacCoreEnv.deleteby)));
}
}
// DB 通过ID删除Env
private deleteEnvItem(coreEnvIdDTO: CoreEnvIdDTO, pacInfo: PacInfoType) {
private deleteEnvItem(envId: string, pacInfo: PacInfoType) {
return this.mysqlService.db
.update(pacCoreEnv)
.set({
deletetime: sql`now()`,
deleteby: pacInfo.userId,
})
.where(eq(pacCoreEnv.envId, coreEnvIdDTO.envId));
.where(eq(pacCoreEnv.envId, envId));
}
// DB 更新Env
private updateEnvData(coreEnvIdDTO: CoreEnvIdDTO, updateCoreEnvDto: UpdateCoreEnvDto, pacInfo: PacInfoType) {
// ? 判断身份是否是pac,如果是pac才能写入
const isPac = this.config.get<number>('masterId') == pacInfo.userId && isTrueEnum(updateCoreEnvDto.ownOfPac);
private updateEnvData(envId: string, updateCoreEnvDto: UpdateCoreEnvDto, pacInfo: PacInfoType) {
return this.mysqlService.db
.update(pacCoreEnv)
.set({
@ -411,13 +430,13 @@ export class CoreEnvService {
envVal: updateCoreEnvDto.envVal,
valIsDict: isTrueEnum(updateCoreEnvDto.valIsDict) ? 1 : 0,
envDesc: updateCoreEnvDto.envDesc,
ownOfPac: isPac ? 0 : 1,
root: isTrueEnum(updateCoreEnvDto.root) ? 1 : 0,
orderNum: updateCoreEnvDto.orderNum,
status: updateCoreEnvDto.status,
serviceOf: updateCoreEnvDto.serviceOf,
serviceKey: updateCoreEnvDto.serviceKey,
updateby: pacInfo.userId,
updatetime: sql`now()`,
})
.where(eq(pacCoreEnv.envId, coreEnvIdDTO.envId));
.where(eq(pacCoreEnv.envId, envId));
}
}

@ -49,14 +49,13 @@ export class CreateCoreEnvDto {
description: '环境变量值',
type: String,
example: '#33333333a',
required: false,
required: true,
minLength: 1,
maxLength: 255,
})
@Trim()
@IsString({ message: '环境变量值应为字符串格式!' })
@Length(1, 255, { message: '请将环境变量值长度控制在1到255位之间!' })
@IsOptional()
public readonly envVal: string;
@ApiProperty({
@ -95,7 +94,7 @@ export class CreateCoreEnvDto {
@Trim()
@IsEnum(BooleanEnum, { message: 'envIsDict参数格式错误' })
@IsOptional()
public readonly ownOfPac: BooleanEnum = BooleanEnum.FALSE;
public readonly root: BooleanEnum = BooleanEnum.FALSE;
@ApiProperty({
description: '排序',
@ -129,5 +128,5 @@ export class CreateCoreEnvDto {
@IsString({ message: '服务标识应为字符串格式!' })
@Length(2, 16, { message: '请将服务标识长度控制在2到16位之间!' })
@IsOptional()
public readonly serviceOf: string;
public readonly serviceKey: string;
}

@ -17,8 +17,8 @@ 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 ChangeCase, { CaseType } from '@common/decorator/change-case/change-case.decorator';
import {Type} from "class-transformer";
import Int from "@common/decorator/int/int.descrator";
import { Type } from 'class-transformer';
import Int from '@common/decorator/int/int.descrator';
export class GetCoreEnvDTO extends GetDto {
@ApiProperty({
@ -59,7 +59,7 @@ export class GetCoreEnvDTO extends GetDto {
@IsString({ message: '服务标识应为字符串格式!' })
@Length(2, 16, { message: '请将服务标识长度控制在2到16位之间!' })
@IsOptional()
readonly serviceOf: string;
readonly serviceKey: string;
@ApiProperty({
description: '环境变量状态',
@ -98,20 +98,6 @@ export class GetCoreEnvDTO extends GetDto {
readonly hierarchy?: string;
}
export class CoreEnvIdDTO {
@ApiProperty({
description: '环境变量ID',
type: String,
example: '1123817263136',
required: true,
minLength: 19,
maxLength: 19,
})
@IsString()
@Length(19, 19, { message: '环境变量ID格式错误!' })
readonly envId: string;
}
export class CoreEnvKeyDTO {
@ApiProperty({
description: '环境变量标志',

@ -34,7 +34,7 @@ export class CoreMenuService {
isActivate: pacCoreMenu.isActivate,
orderNum: pacCoreMenu.orderNum,
status: pacCoreMenu.status,
serviceOf: pacCoreMenu.serviceOf,
serviceKey: pacCoreMenu.serviceKey,
serviceName: pacCoreService.serviceName,
createby: pacCoreMenu.createby,
createName: pacAuthUser.nickname,
@ -60,7 +60,7 @@ export class CoreMenuService {
isVisible: pacCoreMenu.isVisible,
isActivate: pacCoreMenu.isActivate,
orderNum: pacCoreMenu.orderNum,
serviceOf: pacCoreMenu.serviceOf,
serviceKey: pacCoreMenu.serviceKey,
serviceName: pacCoreService.serviceName,
};
@ -160,7 +160,7 @@ export class CoreMenuService {
isVisible: isTrueEnum(createCoreMenuDto.isVisible) ? 0 : 1,
isActivate: isTrueEnum(createCoreMenuDto.isActivate) ? 0 : 1,
orderNum: createCoreMenuDto.orderNum,
serviceOf: createCoreMenuDto.serviceOf,
serviceKey: createCoreMenuDto.serviceKey,
createby: pacInfo.userId,
createtime: sql`now()` as any,
};
@ -186,7 +186,7 @@ export class CoreMenuService {
.select(selectData)
.from(pacCoreMenu)
.leftJoin(pacCoreDict, eq(pacCoreMenu.menuType, pacCoreDict.dictId))
.leftJoin(pacCoreService, eq(pacCoreMenu.serviceOf, pacCoreService.serviceKey))
.leftJoin(pacCoreService, eq(pacCoreMenu.serviceKey, pacCoreService.serviceKey))
.orderBy(
isTrueEnum(data.isAsc) ? asc(pacCoreMenu.orderNum) : desc(pacCoreMenu.orderNum),
isTrueEnum(data.isAsc) ? asc(pacCoreMenu.menuId) : desc(pacCoreMenu.menuId),
@ -211,7 +211,7 @@ export class CoreMenuService {
wl.push(eq(pacCoreMenu.menuType, data.menuType).if(isExistKey(data, 'menuType')));
// ? 根据服务名称查
wl.push(eq(pacCoreMenu.serviceOf, data.serviceOf).if(isExistKey(data, 'serviceOf')));
wl.push(eq(pacCoreMenu.serviceKey, data.serviceKey).if(isExistKey(data, 'serviceKey')));
// ? 根据是否是外部链接查
wl.push(eq(pacCoreMenu.isFrame, isTrueEnum(data.isFrame) ? 1 : 0).if(isExistKey(data, 'isFrame')));
@ -303,7 +303,7 @@ export class CoreMenuService {
isActivate: isTrueEnum(updateCoreMenuDto.isActivate) ? 0 : 1,
orderNum: updateCoreMenuDto.orderNum,
status: updateCoreMenuDto.status,
serviceOf: updateCoreMenuDto.serviceOf,
serviceKey: updateCoreMenuDto.serviceKey,
updateby: pacInfo.userId,
updatetime: sql`now()`,
})

@ -1,7 +1,7 @@
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 { IsEnum, IsInt, IsOptional, IsString, Length, Max, Min } from 'class-validator';
import { BooleanEnum } from '@utils/boolean.enum';
export class CreateCoreMenuDto {
@ApiProperty({
@ -181,5 +181,5 @@ export class CreateCoreMenuDto {
@IsString({ message: '服务标识应为字符串格式!' })
@Length(2, 16, { message: '请将服务标识长度控制在2到16位之间!' })
@IsOptional()
readonly serviceOf: string;
readonly serviceKey: string;
}

@ -16,7 +16,6 @@ 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 { Transform, Type } from 'class-transformer';
import Int from '@common/decorator/int/int.descrator';
export class GetPacCoreMenuAllDto extends GetDto {
@ -60,7 +59,7 @@ export class GetPacCoreMenuAllDto extends GetDto {
@IsString({ message: '服务标识应为字符串格式!' })
@Length(2, 16, { message: '请将服务标识长度控制在2到16位之间!' })
@IsOptional()
readonly serviceOf: string;
readonly serviceKey: string;
@ApiProperty({
description: '是否为外部链接',

@ -1,20 +0,0 @@
import { Test, TestingModule } from '@nestjs/testing';
import { CoreServiceController } from './core-service.controller';
import { CoreServiceService } from './core-service.service';
describe('CoreServiceController', () => {
let controller: CoreServiceController;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [CoreServiceController],
providers: [CoreServiceService],
}).compile();
controller = module.get<CoreServiceController>(CoreServiceController);
});
it('should be defined', () => {
expect(controller).toBeDefined();
});
});

@ -6,7 +6,6 @@ import { ApiOperation, ApiProduces, ApiTags } from '@nestjs/swagger';
import { PacInfo } from '@common/decorator/pac-info/pac-info.decorator';
import { PacInfoType } from '@utils/myType';
import { GetCoreServiceDto } from './dto/get-core-service.dto';
import { ServiceKeyDto } from '@app/core-service/dto/serviceKey.dto';
@ApiTags('系统服务')
@Controller('coreservice')
@ -49,7 +48,7 @@ export class CoreServiceController {
})
@ApiProduces('application/json')
@Patch(':serviceKey')
update(@Param() serviceKey: ServiceKeyDto, @Body() updateCoreServiceDto: UpdateCoreServiceDto, @PacInfo() pacInfo: PacInfoType) {
update(@Param('serviceKey') serviceKey: string, @Body() updateCoreServiceDto: UpdateCoreServiceDto, @PacInfo() pacInfo: PacInfoType) {
return this.coreServiceService.update(serviceKey, updateCoreServiceDto, pacInfo);
}
@ -59,7 +58,7 @@ export class CoreServiceController {
})
@ApiProduces('application/json')
@Delete(':serviceKey')
remove(@Param() serviceKey: ServiceKeyDto, @PacInfo() pacInfo: PacInfoType) {
remove(@Param('serviceKey') serviceKey: string, @PacInfo() pacInfo: PacInfoType) {
return this.coreServiceService.remove(serviceKey, pacInfo);
}
}

@ -1,18 +0,0 @@
import { Test, TestingModule } from '@nestjs/testing';
import { CoreServiceService } from './core-service.service';
describe('CoreServiceService', () => {
let service: CoreServiceService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [CoreServiceService],
}).compile();
service = module.get<CoreServiceService>(CoreServiceService);
});
it('should be defined', () => {
expect(service).toBeDefined();
});
});

@ -8,9 +8,9 @@ import { and, asc, desc, eq, isNull, like, or, sql } from 'drizzle-orm';
import { PacInfoType } from '@utils/myType';
import { GetCoreServiceDto } from '@app/core-service/dto/get-core-service.dto';
import { likeQuery } from '@utils/likeQuery';
import { ServiceKeyDto } from '@app/core-service/dto/serviceKey.dto';
import { RedisService } from '@common/service/redis/redis.service';
import { isTrueEnum } from '@utils/boolean.enum';
import { ConfigService } from '@nestjs/config';
@Injectable()
export class CoreServiceService {
@ -18,14 +18,21 @@ export class CoreServiceService {
private readonly logger: LoggerService,
private readonly mysqlService: MysqlService,
private readonly redisService: RedisService,
private readonly config: ConfigService,
) {}
/** Service
* NAME: create
* DESC: 创建服务
* DATE: 2024-05-30 21:06:24 -
* up: 2024-06-23 14:05:20 - root的新增
* */
async create(createCoreServiceDto: CreateCoreServiceDto, pacInfo: PacInfoType) {
public async create(createCoreServiceDto: CreateCoreServiceDto, pacInfo: PacInfoType) {
// ! 判断是否是root账户
if (this.config.get<number>('masterId') !== pacInfo.userId) {
throw new HttpException('没有权限删除菜单!', HttpStatus.UNAUTHORIZED);
}
// ! 上锁
const lock = await this.redisService.distributedLock('SERVICE' + createCoreServiceDto.serviceKey, createCoreServiceDto.serviceKey);
@ -62,7 +69,7 @@ export class CoreServiceService {
* DESC: 查找服务分页/
* DATE: 2024-05-30 21:07:40 -
* */
async findAll(getCoreServiceDto: GetCoreServiceDto) {
public async findAll(getCoreServiceDto: GetCoreServiceDto) {
// ? 是否查询列表
if (isTrueEnum(getCoreServiceDto.isList)) {
// ! 返回列表数据
@ -77,8 +84,32 @@ export class CoreServiceService {
* NAME: update
* DESC: 更新数据
* DATE: 2024-05-30 21:20:19 -
* up: 2024-06-23 14:17:37 - root权限限制serviceKey数据结构
* */
async update(serviceKey: ServiceKeyDto, updateCoreServiceDto: UpdateCoreServiceDto, pacInfo: PacInfoType) {
public async update(serviceKey: string, updateCoreServiceDto: UpdateCoreServiceDto, pacInfo: PacInfoType) {
// ! 判断是否是root账户
if (this.config.get<number>('masterId') !== pacInfo.userId) {
throw new HttpException('没有权限删除菜单!', HttpStatus.UNAUTHORIZED);
}
// ! 查找目标服务是否存在
const oldService = await this.getServiceDataForServiceKey(serviceKey);
// ? 不存在抛出错误
if (oldService.length === 0) {
throw new HttpException('服务不存在!', HttpStatus.BAD_REQUEST);
}
// ? 新旧serviceKey不一致
if (serviceKey != updateCoreServiceDto.serviceKey) {
const check = await this.getServiceDataForServiceKey(updateCoreServiceDto.serviceKey);
// ? 新的serviceKey已存在
if (check.length > 0) {
throw new HttpException('服务标识重复!', HttpStatus.CONFLICT);
}
}
// ! 上锁
const lock = await this.redisService.distributedLock('SERVICE' + updateCoreServiceDto.serviceKey, updateCoreServiceDto.serviceKey);
@ -87,14 +118,6 @@ export class CoreServiceService {
// @ 核心业务
try {
if (serviceKey.serviceKey != updateCoreServiceDto.serviceKey) {
// ! 查重
const result = await this.getServiceDataForServiceKey(updateCoreServiceDto.serviceKey);
if (result.length > 0) {
throw new HttpException('服务标识重复!', HttpStatus.CONFLICT);
}
}
// ! 更新数据
const result = await this.updateServiceItem(serviceKey, updateCoreServiceDto, pacInfo);
@ -116,19 +139,25 @@ export class CoreServiceService {
* NAME: remove
* DESC: 删除数据
* DATE: 2024-05-30 21:24:33 -
* up: 2024-06-23 14:17:37 - root权限限制
* */
async remove(serviceKey: ServiceKeyDto, pacInfo: PacInfoType) {
public async remove(serviceKey: string, pacInfo: PacInfoType) {
// ! 判断是否是root账户
if (this.config.get<number>('masterId') !== pacInfo.userId) {
throw new HttpException('没有权限删除菜单!', HttpStatus.UNAUTHORIZED);
}
// ! 执行删除并返回
return await this.deleteServiceItem(serviceKey, pacInfo);
}
// DB 根据serviceKey查找服务数据 可用于查重
async getServiceDataForServiceKey(serviceKey: string) {
private async getServiceDataForServiceKey(serviceKey: string) {
return await this.mysqlService.db.select().from(pacCoreService).where(eq(pacCoreService.serviceKey, serviceKey));
}
// DB 添加服务数据
async addServiceData(createCoreServiceDto: CreateCoreServiceDto, pacInfo: PacInfoType) {
private async addServiceData(createCoreServiceDto: CreateCoreServiceDto, pacInfo: PacInfoType) {
const newServiceData: typeof pacCoreService.$inferInsert = {
createby: pacInfo.userId,
createtime: sql`now()` as any,
@ -141,7 +170,7 @@ export class CoreServiceService {
}
// DB 获取服务分页
async getServicePage(getCoreServiceDto: GetCoreServiceDto) {
private async getServicePage(getCoreServiceDto: GetCoreServiceDto) {
const offset = (getCoreServiceDto.pageNumber - 1) * getCoreServiceDto.pageSize;
// 定义基础查询函数
@ -194,7 +223,7 @@ export class CoreServiceService {
}
// DB 获取服务列表
async getServiceList(getCoreServiceDto: GetCoreServiceDto) {
private async getServiceList(getCoreServiceDto: GetCoreServiceDto) {
return await this.mysqlService.db
.select({
serviceKey: pacCoreService.serviceKey,
@ -206,22 +235,18 @@ export class CoreServiceService {
}
// DB 删除服务
async deleteServiceItem(serviceKey: ServiceKeyDto, pacInfo: PacInfoType) {
const deleteData = {
serviceKey: serviceKey.serviceKey,
userId: pacInfo.userId,
};
private async deleteServiceItem(serviceKey: string, pacInfo: PacInfoType) {
return await this.mysqlService.db
.update(pacCoreService)
.set({
deletetime: sql`now()`,
deleteby: deleteData.userId,
deleteby: pacInfo.userId,
})
.where(eq(pacCoreService.serviceKey, deleteData.serviceKey));
.where(eq(pacCoreService.serviceKey, serviceKey));
}
// DB 更新服务
updateServiceItem(serviceKey: ServiceKeyDto, updateCoreServiceDto: UpdateCoreServiceDto, pacInfo: PacInfoType) {
private updateServiceItem(serviceKey: string, updateCoreServiceDto: UpdateCoreServiceDto, pacInfo: PacInfoType) {
return this.mysqlService.db
.update(pacCoreService)
.set({
@ -232,6 +257,6 @@ export class CoreServiceService {
updatetime: sql`now()`,
updateby: pacInfo.userId,
})
.where(eq(pacCoreService.serviceKey, serviceKey.serviceKey));
.where(eq(pacCoreService.serviceKey, serviceKey));
}
}

@ -1,36 +0,0 @@
// | ------------------------------------------------------------
// | @版本: version 0.1
// | @创建人: 【Nie-x7129】
// | @E-mail: x71291@outlook.com
// | @所在项目: pac-auth
// | @文件描述: serviceKey.dto.ts -
// | @创建时间: 2024-05-30 15:14
// | @更新时间: 2024-05-30 15:14
// | @修改记录:
// | -*-*-*- (时间--修改人--修改说明) -*-*-*-
// | =
// | ------------------------------------------------------------
import { ApiProperty } from '@nestjs/swagger';
import { IsString, Length } from 'class-validator';
import Trim from '@common/decorator/trim/trim.decorator';
export class ServiceKeyDto {
@ApiProperty({
description: '服务的唯一标识',
type: String,
example: 'CORE-PAC-AUTH',
required: true,
// format: 'email', // email, date-time, uuid
// minimum: 1, // 数字属性的最小值
minLength: 2,
maxLength: 16,
// minItems: 1, // 数组属性的最小项目数
})
@Trim()
@IsString({ message: '服务标识应为字符串格式!' })
@Length(2, 16, { message: '请将服务标识长度控制在2到16位之间!' })
readonly serviceKey: string;
}

@ -7,7 +7,7 @@ import { randomHEX } from '@utils/random';
export class HttpExceptFilter implements ExceptionFilter {
constructor(private readonly logger: LoggerService) {}
catch(exception: HttpException, host: ArgumentsHost) {
console.log(exception);
console.log('错误拦截', exception);
const ctx = host.switchToHttp();
const request = ctx.getRequest<FastifyRequest>();
const status = exception instanceof HttpException ? exception.getStatus() : HttpStatus.INTERNAL_SERVER_ERROR;

@ -3,7 +3,6 @@ import { catchError, Observable, tap, throwError } from 'rxjs';
import { FastifyReply, FastifyRequest } from 'fastify';
import { LoggerService } from '@service/logger/logger.service';
import formatBytes from '@utils/formatBytes';
import * as colors from 'colors';
import mathodColor from '@utils/mathodColor';
@Injectable()

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

@ -31,6 +31,28 @@ export const pacAuthDept = mysqlTable(
},
);
export const pacAuthLinkRoleDept = mysqlTable(
'pac_auth_link_role_dept',
{
index: int('index').autoincrement().notNull(),
roleId: int('role_id').notNull(),
deptId: int('dept_id').notNull(),
scopeId: int('scope_id').notNull(),
createby: int('createby').notNull(),
createtime: datetime('createtime', { mode: 'string' }).notNull(),
updateby: int('updateby'),
updatetime: datetime('updatetime', { mode: 'string' }),
deleteby: int('deleteby'),
deletetime: datetime('deletetime', { mode: 'string' }),
},
(table) => {
return {
pacAuthLinkRoleDeptScopeId: primaryKey({ columns: [table.scopeId], name: 'pac_auth_link_role_dept_scope_id' }),
pacIndex: unique('pac_index').on(table.index),
};
},
);
export const pacAuthLinkRoleMenu = mysqlTable(
'pac_auth_link_role_menu',
{
@ -144,21 +166,21 @@ export const pacAuthRole = mysqlTable(
'pac_auth_role',
{
index: int('index').notNull(),
roleId: int('role_id').notNull(),
pid: int('pid').default(0).notNull(),
roleId: bigint('role_id', { mode: 'number' }).notNull(),
pid: bigint('pid', { mode: 'number' }).notNull(),
roleName: varchar('role_name', { length: 255 }).notNull(),
roleKey: varchar('role_key', { length: 255 }).notNull(),
roleDesc: varchar('role_desc', { length: 255 }),
roleType: int('role_type').default(0).notNull(),
roleDataScope: int('role_data_scope').default(1).notNull(),
ownOfPac: int('own_of_pac').default(0).notNull(),
roleType: bigint('role_type', { mode: 'number' }).notNull(),
deptScope: int('dept_scope').default(1).notNull(),
root: int('root').default(0).notNull(),
orderNum: int('order_num').default(0).notNull(),
status: int('status').default(0).notNull(),
createby: int('createby').notNull(),
createby: bigint('createby', { mode: 'number' }).notNull(),
createtime: datetime('createtime', { mode: 'string' }).notNull(),
updateby: int('updateby'),
updateby: bigint('updateby', { mode: 'number' }),
updatetime: datetime('updatetime', { mode: 'string' }),
deleteby: int('deleteby'),
deleteby: bigint('deleteby', { mode: 'number' }),
deletetime: datetime('deletetime', { mode: 'string' }),
},
(table) => {
@ -169,28 +191,6 @@ export const pacAuthRole = mysqlTable(
},
);
export const pacAuthRoleDataScope = mysqlTable(
'pac_auth_role_data_scope',
{
index: int('index').autoincrement().notNull(),
roleId: int('role_id').notNull(),
deptId: int('dept_id').notNull(),
scopeId: int('scope_id').notNull(),
createby: int('createby').notNull(),
createtime: datetime('createtime', { mode: 'string' }).notNull(),
updateby: int('updateby'),
updatetime: datetime('updatetime', { mode: 'string' }),
deleteby: int('deleteby'),
deletetime: datetime('deletetime', { mode: 'string' }),
},
(table) => {
return {
pacAuthRoleDataScopeScopeId: primaryKey({ columns: [table.scopeId], name: 'pac_auth_role_data_scope_scope_id' }),
pacIndex: unique('pac_index').on(table.index),
};
},
);
export const pacAuthUser = mysqlTable(
'pac_auth_user',
{
@ -235,10 +235,10 @@ export const pacCoreDict = mysqlTable(
dictName: varchar('dict_name', { length: 255 }).notNull(),
dictIcon: varchar('dict_icon', { length: 255 }).default('').notNull(),
dictType: int('dict_type', { unsigned: true }).default(0).notNull(),
ownOfPac: int('own_of_pac', { unsigned: true }).default(0).notNull(),
root: int('root', { unsigned: true }).default(0).notNull(),
orderNum: int('order_num', { unsigned: true }).default(0).notNull(),
status: int('status', { unsigned: true }).default(0).notNull(),
serviceOf: varchar('service_of', { length: 255 }).default('').notNull(),
serviceKey: varchar('serviceKey', { length: 255 }).default('').notNull(),
haveChildren: int('have_children').default(0).notNull(),
createby: bigint('createby', { mode: 'number' }).notNull(),
createtime: datetime('createtime', { mode: 'string' }).notNull(),
@ -267,10 +267,10 @@ export const pacCoreEnv = mysqlTable(
valIsDict: int('val_is_dict').default(0).notNull(),
envDesc: varchar('env_desc', { length: 255 }),
haveChildren: int('have_children').default(0).notNull(),
ownOfPac: int('own_of_pac').default(0).notNull(),
root: int('root').default(0).notNull(),
orderNum: int('order_num').default(0).notNull(),
status: int('status').default(0).notNull(),
serviceOf: varchar('service_of', { length: 255 }).notNull(),
serviceKey: varchar('service_key', { length: 255 }).notNull(),
createby: bigint('createby', { mode: 'number' }).notNull(),
createtime: datetime('createtime', { mode: 'string' }).notNull(),
updateby: bigint('updateby', { mode: 'number' }),
@ -301,11 +301,11 @@ export const pacCoreMenu = mysqlTable(
menuType: bigint('menu_type', { mode: 'number' }).notNull(),
menuIcon: varchar('menu_icon', { length: 255 }),
isFrame: int('is_frame').default(0).notNull(),
isVisible: int('is_visible').default(0).notNull(),
isActivate: int('is_activate').default(0).notNull(),
isVisible: int('is_visible').default(1).notNull(),
isActivate: int('is_activate').default(1).notNull(),
orderNum: int('order_num').default(0).notNull(),
status: int('status').default(0).notNull(),
serviceOf: varchar('service_of', { length: 255 }).notNull(),
serviceKey: varchar('service_key', { length: 255 }).notNull(),
createby: bigint('createby', { mode: 'number' }).notNull(),
createtime: datetime('createtime', { mode: 'string' }).notNull(),
updateby: bigint('updateby', { mode: 'number' }),

@ -39,8 +39,6 @@ export class LoggerService {
}
};
// 创建一个 Winston 的 Logger 实例
private readonly logger: winston.Logger = winston.createLogger({
// 设置日志级别

Loading…
Cancel
Save