refactor:

This commit is contained in:
louis 2024-02-29 09:29:03 +08:00
parent 6b9b4cdd17
commit 88a97ee162
144 changed files with 387 additions and 387 deletions

View File

@ -33,7 +33,7 @@ import { ContractModule } from './modules/contract/contract.module';
expandVariables: true,
// 指定多个 env 文件时,第一个优先级最高
envFilePath: ['.env.local', `.env.${process.env.NODE_ENV}`, '.env'],
load: [...Object.values(config)],
load: [...Object.values(config)]
}),
SharedModule,
DatabaseModule,
@ -53,7 +53,7 @@ import { ContractModule } from './modules/contract/contract.module';
TodoModule,
ContractModule,
ContractModule
],
providers: [
{ provide: APP_FILTER, useClass: AllExceptionsFilter },
@ -64,7 +64,7 @@ import { ContractModule } from './modules/contract/contract.module';
{ provide: APP_INTERCEPTOR, useClass: IdempotenceInterceptor },
{ provide: APP_GUARD, useClass: JwtAuthGuard },
{ provide: APP_GUARD, useClass: RbacGuard },
],
{ provide: APP_GUARD, useClass: RbacGuard }
]
})
export class AppModule {}

View File

@ -4,7 +4,7 @@ import { FastifyAdapter } from '@nestjs/platform-fastify';
const app: FastifyAdapter = new FastifyAdapter({
trustProxy: true,
logger: false,
logger: false
// forceCloseConnections: true,
});
export { app as fastifyApp };
@ -13,12 +13,12 @@ app.register(FastifyMultipart, {
limits: {
fields: 10, // Max number of non-file fields
fileSize: 1024 * 1024 * 6, // limit size 6M
files: 5, // Max number of file fields
},
files: 5 // Max number of file fields
}
});
app.register(FastifyCookie, {
secret: 'cookie-secret', // 这个 secret 不太重要,不存鉴权相关,无关紧要
secret: 'cookie-secret' // 这个 secret 不太重要,不存鉴权相关,无关紧要
});
app.getInstance().addHook('onRequest', (request, reply, done) => {

View File

@ -18,7 +18,7 @@ export class RedisIoAdapter extends IoAdapter {
const redisAdapter = createAdapter(pubClient, subClient, {
key: RedisIoAdapterKey,
requestsTimeout: 10000,
requestsTimeout: 10000
});
server.adapter(redisAdapter);
return server;

View File

@ -16,7 +16,7 @@ function genBaseProp(type: Type<any>) {
export function ApiResult<TModel extends Type<any>>({
type,
isPage,
status,
status
}: {
type?: TModel | TModel[];
isPage?: boolean;
@ -31,7 +31,7 @@ export function ApiResult<TModel extends Type<any>>({
properties: {
items: {
type: 'array',
items: { $ref: getSchemaPath(type[0]) },
items: { $ref: getSchemaPath(type[0]) }
},
meta: {
type: 'object',
@ -40,15 +40,15 @@ export function ApiResult<TModel extends Type<any>>({
totalItems: { type: 'number', default: 0 },
itemsPerPage: { type: 'number', default: 0 },
totalPages: { type: 'number', default: 0 },
currentPage: { type: 'number', default: 0 },
},
},
},
currentPage: { type: 'number', default: 0 }
}
}
}
};
} else {
prop = {
type: 'array',
items: genBaseProp(type[0]),
items: genBaseProp(type[0])
};
}
} else if (type) {
@ -68,11 +68,11 @@ export function ApiResult<TModel extends Type<any>>({
{ $ref: getSchemaPath(ResOp) },
{
properties: {
data: prop,
},
},
],
},
data: prop
}
}
]
}
})
);
}

View File

@ -11,7 +11,7 @@ import {
Max,
MaxLength,
Min,
MinLength,
MinLength
} from 'class-validator';
import { isNumber } from 'lodash';
@ -22,7 +22,7 @@ import {
ToLowerCase,
ToNumber,
ToTrim,
ToUpperCase,
ToUpperCase
} from './transform.decorator';
interface IOptionalOptions {

View File

@ -7,7 +7,7 @@ export function IdParam() {
errorHttpStatusCode: HttpStatus.NOT_ACCEPTABLE,
exceptionFactory: _error => {
throw new NotAcceptableException('id 格式不正确');
},
}
})
);
}

View File

@ -9,7 +9,7 @@ export class CursorDto<T = any> {
@Expose()
@IsOptional({ always: true })
@Transform(({ value: val }) => (val ? Number.parseInt(val) : 0), {
toClassOnly: true,
toClassOnly: true
})
cursor?: number;
@ -20,7 +20,7 @@ export class CursorDto<T = any> {
@IsOptional({ always: true })
@Expose()
@Transform(({ value: val }) => (val ? Number.parseInt(val) : 10), {
toClassOnly: true,
toClassOnly: true
})
limit?: number;
}

View File

@ -4,7 +4,7 @@ import { Allow, IsEnum, IsInt, IsOptional, IsString, Max, Min } from 'class-vali
export enum Order {
ASC = 'ASC',
DESC = 'DESC',
DESC = 'DESC'
}
export class PagerDto<T = any> {
@ -14,7 +14,7 @@ export class PagerDto<T = any> {
@Expose()
@IsOptional({ always: true })
@Transform(({ value: val }) => (val ? Number.parseInt(val) : 1), {
toClassOnly: true,
toClassOnly: true
})
page?: number;
@ -25,7 +25,7 @@ export class PagerDto<T = any> {
@IsOptional({ always: true })
@Expose()
@Transform(({ value: val }) => (val ? Number.parseInt(val) : 10), {
toClassOnly: true,
toClassOnly: true
})
pageSize?: number;

View File

@ -6,7 +6,7 @@ import {
CreateDateColumn,
PrimaryGeneratedColumn,
UpdateDateColumn,
VirtualColumn,
VirtualColumn
} from 'typeorm';
// 如果觉得前端转换时间太麻烦并且不考虑通用性的话可以在服务端进行转换eg: @UpdateDateColumn({ name: 'updated_at', transformer })

View File

@ -12,7 +12,7 @@ export class BusinessException extends HttpException {
super(
HttpException.createBody({
code: RESPONSE_SUCCESS_CODE,
message: error,
message: error
}),
HttpStatus.OK
);
@ -24,7 +24,7 @@ export class BusinessException extends HttpException {
super(
HttpException.createBody({
code,
message,
message
}),
HttpStatus.OK
);

View File

@ -14,7 +14,7 @@ export class SocketException extends WsException {
super(
HttpException.createBody({
code: 0,
message: error,
message: error
})
);
this.errorCode = 0;
@ -25,7 +25,7 @@ export class SocketException extends WsException {
super(
HttpException.createBody({
code,
message,
message
})
);

View File

@ -4,7 +4,7 @@ import {
ExceptionFilter,
HttpException,
HttpStatus,
Logger,
Logger
} from '@nestjs/common';
import { FastifyReply, FastifyRequest } from 'fastify';
@ -62,7 +62,7 @@ export class AllExceptionsFilter implements ExceptionFilter {
const resBody: IBaseResponse = {
code: apiErrorCode,
message,
data: null,
data: null
};
response.status(status).send(resBody);

View File

@ -12,7 +12,7 @@ import { getRedisKey } from '~/utils/redis.util';
import {
HTTP_IDEMPOTENCE_KEY,
HTTP_IDEMPOTENCE_OPTIONS,
HTTP_IDEMPOTENCE_OPTIONS
} from '../decorators/idempotence.decorator';
const IdempotenceHeaderKey = 'x-idempotence';
@ -70,7 +70,7 @@ export class IdempotenceInterceptor implements NestInterceptor {
pendingMessage = '相同请求正在处理中...',
handler: errorHandler,
expired = 60,
disableGenerateKey = false,
disableGenerateKey = false
} = options;
const redis = this.cacheService.getClient();
@ -93,7 +93,7 @@ export class IdempotenceInterceptor implements NestInterceptor {
const message = {
1: errorMessage,
0: pendingMessage,
0: pendingMessage
}[resultValue];
throw new ConflictException(message);
} else {

View File

@ -3,7 +3,7 @@ import {
ExecutionContext,
Injectable,
NestInterceptor,
RequestTimeoutException,
RequestTimeoutException
} from '@nestjs/common';
import { Observable, TimeoutError, throwError } from 'rxjs';
import { catchError, timeout } from 'rxjs/operators';

View File

@ -3,7 +3,7 @@ import {
ExecutionContext,
HttpStatus,
Injectable,
NestInterceptor,
NestInterceptor
} from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import { Observable } from 'rxjs';

View File

@ -13,8 +13,8 @@ export const AppConfig = registerAs(appRegToken, () => ({
logger: {
level: env('LOGGER_LEVEL'),
maxFiles: envNumber('LOGGER_MAX_FILES'),
},
maxFiles: envNumber('LOGGER_MAX_FILES')
}
}));
export type IAppConfig = ConfigType<typeof AppConfig>;

View File

@ -24,7 +24,7 @@ const dataSourceOptions: DataSourceOptions = {
multipleStatements: currentScript === 'typeorm',
entities: ['dist/modules/**/*.entity{.ts,.js}'],
migrations: ['dist/migrations/*{.ts,.js}'],
subscribers: ['dist/modules/**/*.subscriber{.ts,.js}'],
subscribers: ['dist/modules/**/*.subscriber{.ts,.js}']
};
export const dbRegToken = 'database';

View File

@ -33,5 +33,5 @@ export default {
OssConfig,
RedisConfig,
SecurityConfig,
SwaggerConfig,
SwaggerConfig
};

View File

@ -11,8 +11,8 @@ export const MailerConfig = registerAs(mailerRegToken, () => ({
secure: true,
auth: {
user: env('SMTP_USER'),
pass: env('SMTP_PASS'),
},
pass: env('SMTP_PASS')
}
}));
export type IMailerConfig = ConfigType<typeof MailerConfig>;

View File

@ -26,7 +26,7 @@ export const OssConfig = registerAs(ossRegToken, () => ({
domain: env('OSS_DOMAIN'),
bucket: env('OSS_BUCKET'),
zone: parseZone(env('OSS_ZONE') || 'Zone_z2'),
access: (env('OSS_ACCESS_TYPE') as any) || 'public',
access: (env('OSS_ACCESS_TYPE') as any) || 'public'
}));
export type IOssConfig = ConfigType<typeof OssConfig>;

View File

@ -8,7 +8,7 @@ export const RedisConfig = registerAs(redisRegToken, () => ({
host: env('REDIS_HOST', '127.0.0.1'),
port: envNumber('REDIS_PORT', 6379),
password: env('REDIS_PASSWORD'),
db: envNumber('REDIS_DB'),
db: envNumber('REDIS_DB')
}));
export type IRedisConfig = ConfigType<typeof RedisConfig>;

View File

@ -8,7 +8,7 @@ export const SecurityConfig = registerAs(securityRegToken, () => ({
jwtSecret: env('JWT_SECRET'),
jwtExprire: envNumber('JWT_EXPIRE'),
refreshSecret: env('REFRESH_TOKEN_SECRET'),
refreshExpire: envNumber('REFRESH_TOKEN_EXPIRE'),
refreshExpire: envNumber('REFRESH_TOKEN_EXPIRE')
}));
export type ISecurityConfig = ConfigType<typeof SecurityConfig>;

View File

@ -6,7 +6,7 @@ export const swaggerRegToken = 'swagger';
export const SwaggerConfig = registerAs(swaggerRegToken, () => ({
enable: envBoolean('SWAGGER_ENABLE'),
path: env('SWAGGER_PATH'),
path: env('SWAGGER_PATH')
}));
export type ISwaggerConfig = ConfigType<typeof SwaggerConfig>;

View File

@ -3,6 +3,6 @@ export enum RedisKeys {
CAPTCHA_IMG_PREFIX = 'captcha:img:',
AUTH_TOKEN_PREFIX = 'auth:token:',
AUTH_PERM_PREFIX = 'auth:permission:',
AUTH_PASSWORD_V_PREFIX = 'auth:passwordVersion:',
AUTH_PASSWORD_V_PREFIX = 'auth:passwordVersion:'
}
export const API_CACHE_PREFIX = 'api-cache:';

View File

@ -45,5 +45,5 @@ export enum ErrorEnum {
// OSS相关
OSS_FILE_OR_DIR_EXIST = '1401:当前创建的文件或目录已存在',
OSS_NO_OPERATION_REQUIRED = '1402:无需操作',
OSS_EXCEE_MAXIMUM_QUANTITY = '1403:已超出支持的最大处理数量',
OSS_EXCEE_MAXIMUM_QUANTITY = '1403:已超出支持的最大处理数量'
}

View File

@ -1,4 +1,4 @@
export enum EventBusEvents {
TokenExpired = 'token.expired',
SystemException = 'system.exception',
SystemException = 'system.exception'
}

View File

@ -11,5 +11,5 @@ export enum ContentTypeEnum {
// form-data qs
FORM_URLENCODED = 'application/x-www-form-urlencoded;charset=UTF-8',
// form-data upload
FORM_DATA = 'multipart/form-data;charset=UTF-8',
FORM_DATA = 'multipart/form-data;charset=UTF-8'
}

View File

@ -13,7 +13,7 @@ import { BaseService } from './base.service';
export function BaseCrudFactory<E extends new (...args: any[]) => any>({
entity,
dto,
permissions,
permissions
}: {
entity: E;
dto?: Type<any>;
@ -35,7 +35,7 @@ export function BaseCrudFactory<E extends new (...args: any[]) => any>({
CREATE: `${prefix}:create`,
READ: `${prefix}:read`,
UPDATE: `${prefix}:update`,
DELETE: `${prefix}:delete`,
DELETE: `${prefix}:delete`
} as const);
@Controller(pluralizeName)

View File

@ -5,7 +5,7 @@ export function createPaginationObject<T>({
items,
totalItems,
currentPage,
limit,
limit
}: {
items: T[];
totalItems?: number;
@ -19,7 +19,7 @@ export function createPaginationObject<T>({
itemCount: items.length,
itemsPerPage: limit,
totalPages,
currentPage,
currentPage
};
return new Pagination<T>(items, meta);

View File

@ -3,7 +3,7 @@ import {
FindOptionsWhere,
ObjectLiteral,
Repository,
SelectQueryBuilder,
SelectQueryBuilder
} from 'typeorm';
import { createPaginationObject } from './create-pagination';
@ -19,7 +19,7 @@ function resolveOptions(options: IPaginationOptions): [number, number, Paginatio
return [
page || DEFAULT_PAGE,
pageSize || DEFAULT_LIMIT,
paginationType || PaginationTypeEnum.TAKE_AND_SKIP,
paginationType || PaginationTypeEnum.TAKE_AND_SKIP
];
}
@ -34,9 +34,9 @@ async function paginateRepository<T>(
repository.find({
skip: limit * (page - 1),
take: limit,
...searchOptions,
...searchOptions
}),
undefined,
undefined
];
const [items, total] = await Promise.all(promises);
@ -45,7 +45,7 @@ async function paginateRepository<T>(
items,
totalItems: total,
currentPage: page,
limit,
limit
});
}
@ -65,7 +65,7 @@ async function paginateQueryBuilder<T>(
items,
totalItems: total,
currentPage: page,
limit,
limit
});
}
@ -80,7 +80,7 @@ export async function paginateRaw<T>(
? queryBuilder.limit(limit).offset((page - 1) * limit)
: queryBuilder.take(limit).skip((page - 1) * limit)
).getRawMany<T>(),
queryBuilder.getCount(),
queryBuilder.getCount()
];
const [items, total] = await Promise.all(promises);
@ -89,7 +89,7 @@ export async function paginateRaw<T>(
items,
totalItems: total,
currentPage: page,
limit,
limit
});
}
@ -104,7 +104,7 @@ export async function paginateRawAndEntities<T>(
? queryBuilder.limit(limit).offset((page - 1) * limit)
: queryBuilder.take(limit).skip((page - 1) * limit)
).getRawAndEntities<T>(),
queryBuilder.getCount(),
queryBuilder.getCount()
];
const [itemObject, total] = await Promise.all(promises);
@ -114,9 +114,9 @@ export async function paginateRawAndEntities<T>(
items: itemObject.entities,
totalItems: total,
currentPage: page,
limit,
limit
}),
itemObject.raw,
itemObject.raw
];
}

View File

@ -2,7 +2,7 @@ import { ObjectLiteral } from 'typeorm';
export enum PaginationTypeEnum {
LIMIT_AND_OFFSET = 'limit',
TAKE_AND_SKIP = 'take',
TAKE_AND_SKIP = 'take'
}
export interface IPaginationOptions {

View File

@ -23,7 +23,7 @@ declare const module: any;
async function bootstrap() {
const app = await NestFactory.create<NestFastifyApplication>(AppModule, fastifyApp, {
bufferLogs: true,
snapshot: true,
snapshot: true
// forceCloseConnections: true,
});
@ -57,7 +57,7 @@ async function bootstrap() {
const msg = e.constraints![rule];
return msg;
})[0]
),
)
})
);

View File

@ -14,12 +14,12 @@ export const AuthStrategy = {
JWT: 'jwt',
GITHUB: 'github',
GOOGLE: 'google',
GOOGLE: 'google'
} as const;
export const Roles = {
ADMIN: 'admin',
USER: 'user',
USER: 'user'
// GUEST: 'guest',
} as const;

View File

@ -41,18 +41,18 @@ const strategies = [LocalStrategy, JwtStrategy];
return {
secret: jwtSecret,
expires: jwtExprire,
ignoreExpiration: isDev,
ignoreExpiration: isDev
};
},
inject: [ConfigService],
inject: [ConfigService]
}),
UserModule,
RoleModule,
MenuModule,
LogModule,
LogModule
],
controllers: [...controllers],
providers: [...providers, ...strategies],
exports: [TypeOrmModule, JwtModule, ...providers],
exports: [TypeOrmModule, JwtModule, ...providers]
})
export class AuthModule {}

View File

@ -35,11 +35,11 @@ export class CaptchaController {
noise: 4,
width: isEmpty(width) ? 100 : width,
height: isEmpty(height) ? 50 : height,
charPreset: '1234567890',
charPreset: '1234567890'
});
const result = {
img: `data:image/svg+xml;base64,${Buffer.from(svg.data).toString('base64')}`,
id: generateUUID(),
id: generateUUID()
};
// 5分钟过期时间
await this.redis.set(genCaptchaImgKey(result.id), svg.text, 'EX', 60 * 5);

View File

@ -57,7 +57,7 @@ export class MenuMeta extends PartialType(
'id',
'roles',
'path',
'name',
'name'
] as const)
) {
title: string;
@ -66,7 +66,7 @@ export class AccountMenus extends PickType(MenuEntity, [
'id',
'path',
'name',
'component',
'component'
] as const) {
meta: MenuMeta;
}

View File

@ -6,7 +6,7 @@ export class ImageCaptchaDto {
@ApiProperty({
required: false,
default: 100,
description: '验证码宽度',
description: '验证码宽度'
})
@Type(() => Number)
@IsInt()
@ -16,7 +16,7 @@ export class ImageCaptchaDto {
@ApiProperty({
required: false,
default: 50,
description: '验证码宽度',
description: '验证码宽度'
})
@Type(() => Number)
@IsInt()

View File

@ -6,7 +6,7 @@ import {
JoinColumn,
ManyToOne,
OneToOne,
PrimaryGeneratedColumn,
PrimaryGeneratedColumn
} from 'typeorm';
import { UserEntity } from '~/modules/user/user.entity';
@ -28,12 +28,12 @@ export class AccessTokenEntity extends BaseEntity {
created_at!: Date;
@OneToOne(() => RefreshTokenEntity, refreshToken => refreshToken.accessToken, {
cascade: true,
cascade: true
})
refreshToken!: RefreshTokenEntity;
@ManyToOne(() => UserEntity, user => user.accessTokens, {
onDelete: 'CASCADE',
onDelete: 'CASCADE'
})
@JoinColumn({ name: 'user_id' })
user!: UserEntity;

View File

@ -5,7 +5,7 @@ import {
Entity,
JoinColumn,
OneToOne,
PrimaryGeneratedColumn,
PrimaryGeneratedColumn
} from 'typeorm';
import { AccessTokenEntity } from './access-token.entity';
@ -25,7 +25,7 @@ export class RefreshTokenEntity extends BaseEntity {
created_at!: Date;
@OneToOne(() => AccessTokenEntity, accessToken => accessToken.refreshToken, {
onDelete: 'CASCADE',
onDelete: 'CASCADE'
})
@JoinColumn()
accessToken!: AccessTokenEntity;

View File

@ -27,7 +27,7 @@ export class JwtAuthGuard extends AuthGuard(AuthStrategy.JWT) {
async canActivate(context: ExecutionContext): Promise<any> {
const isPublic = this.reflector.getAllAndOverride<boolean>(PUBLIC_KEY, [
context.getHandler(),
context.getClass(),
context.getClass()
]);
const request = context.switchToHttp().getRequest<FastifyRequest>();
// const response = context.switchToHttp().getResponse<FastifyReply>()

View File

@ -18,7 +18,7 @@ export class RbacGuard implements CanActivate {
async canActivate(context: ExecutionContext): Promise<any> {
const isPublic = this.reflector.getAllAndOverride<boolean>(PUBLIC_KEY, [
context.getHandler(),
context.getClass(),
context.getClass()
]);
if (isPublic) return true;
@ -34,7 +34,7 @@ export class RbacGuard implements CanActivate {
const payloadPermission = this.reflector.getAllAndOverride<string | string[]>(PERMISSION_KEY, [
context.getHandler(),
context.getClass(),
context.getClass()
]);
// 控制器没有设置接口权限,则默认通过

View File

@ -23,7 +23,7 @@ export class ResourceGuard implements CanActivate {
async canActivate(context: ExecutionContext): Promise<any> {
const isPublic = this.reflector.getAllAndOverride<boolean>(PUBLIC_KEY, [
context.getHandler(),
context.getClass(),
context.getClass()
]);
const request = context.switchToHttp().getRequest<FastifyRequest>();
@ -66,9 +66,9 @@ export class ResourceGuard implements CanActivate {
const recordQuery = {
where: {
id: In(items),
user: { id: user.uid },
user: { id: user.uid }
},
relations: ['user'],
relations: ['user']
};
const records = await repo.find(recordQuery);

View File

@ -56,7 +56,7 @@ export class TokenService {
const payload: IAuthUser = {
uid,
pv: 1,
roles,
roles
};
const jwtSign = this.jwtService.sign(payload);
@ -74,7 +74,7 @@ export class TokenService {
return {
accessToken: jwtSign,
refreshToken,
refreshToken
};
}
@ -85,11 +85,11 @@ export class TokenService {
*/
async generateRefreshToken(accessToken: AccessTokenEntity, now: dayjs.Dayjs): Promise<string> {
const refreshTokenPayload = {
uuid: generateUUID(),
uuid: generateUUID()
};
const refreshTokenSign = this.jwtService.sign(refreshTokenPayload, {
secret: this.securityConfig.refreshSecret,
secret: this.securityConfig.refreshSecret
});
const refreshToken = new RefreshTokenEntity();
@ -110,7 +110,7 @@ export class TokenService {
return AccessTokenEntity.findOne({
where: { value },
relations: ['user', 'refreshToken'],
cache: true,
cache: true
});
}
@ -120,7 +120,7 @@ export class TokenService {
*/
async removeAccessToken(value: string) {
const accessToken = await AccessTokenEntity.findOne({
where: { value },
where: { value }
});
if (accessToken) await accessToken.remove();
}
@ -132,7 +132,7 @@ export class TokenService {
async removeRefreshToken(value: string) {
const refreshToken = await RefreshTokenEntity.findOne({
where: { value },
relations: ['accessToken'],
relations: ['accessToken']
});
if (refreshToken) {
if (refreshToken.accessToken) await refreshToken.accessToken.remove();

View File

@ -12,7 +12,7 @@ export class JwtStrategy extends PassportStrategy(Strategy, AuthStrategy.JWT) {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
ignoreExpiration: false,
secretOrKey: securityConfig.jwtSecret,
secretOrKey: securityConfig.jwtSecret
});
}

View File

@ -10,7 +10,7 @@ export class LocalStrategy extends PassportStrategy(Strategy, AuthStrategy.LOCAL
constructor(private authService: AuthService) {
super({
usernameField: 'credential',
passwordField: 'password',
passwordField: 'password'
});
}

View File

@ -9,7 +9,7 @@ export const permissions = definePermission('app:contract', {
CREATE: 'create',
READ: 'read',
UPDATE: 'update',
DELETE: 'delete',
DELETE: 'delete'
} as const);
@ApiTags('Contract - 合同')

View File

@ -4,6 +4,6 @@ import { ContractService } from './contract.service';
@Module({
controllers: [ContractController],
providers: [ContractService],
providers: [ContractService]
})
export class ContractModule {}

View File

@ -5,7 +5,7 @@ import {
HealthCheck,
HttpHealthIndicator,
MemoryHealthIndicator,
TypeOrmHealthIndicator,
TypeOrmHealthIndicator
} from '@nestjs/terminus';
import { Perm, definePermission } from '../auth/decorators/permission.decorator';
@ -15,7 +15,7 @@ export const PermissionHealth = definePermission('app:health', {
DB: 'database',
MH: 'memory-heap',
MR: 'memory-rss',
DISK: 'disk',
DISK: 'disk'
} as const);
@ApiTags('Health - 健康检查')
@ -65,7 +65,7 @@ export class HealthController {
return this.disk.checkStorage('disk', {
// The used disk storage should not exceed 75% of the full disk size
thresholdPercent: 0.75,
path: '/',
path: '/'
});
}
}

View File

@ -6,6 +6,6 @@ import { HealthController } from './health.controller';
@Module({
imports: [TerminusModule, HttpModule],
controllers: [HealthController],
controllers: [HealthController]
})
export class HealthModule {}

View File

@ -49,7 +49,7 @@ export class SFileInfoDetail {
mimeType: string;
@ApiProperty({
description: '文件存储类型2 表示归档存储1 表示低频存储0表示普通存储。',
description: '文件存储类型2 表示归档存储1 表示低频存储0表示普通存储。'
})
type: number;

View File

@ -17,7 +17,7 @@ import {
GetFileListDto,
MKDirDto,
MarkFileDto,
RenameDto,
RenameDto
} from './manage.dto';
import { NetDiskManageService } from './manage.service';
@ -33,7 +33,7 @@ export const permissions = definePermission('netdisk:manage', {
DOWNLOAD: 'download',
RENAME: 'rename',
CUT: 'cut',
COPY: 'copy',
COPY: 'copy'
} as const);
@ApiTags('NetDiskManage - 网盘管理模块')
@ -67,7 +67,7 @@ export class NetDiskManageController {
checkIsDemoMode();
return {
token: this.manageService.createUploadToken(`${user.uid}`),
token: this.manageService.createUploadToken(`${user.uid}`)
};
}
@ -84,7 +84,7 @@ export class NetDiskManageController {
@Perm(permissions.MARK)
async mark(@Body() dto: MarkFileDto): Promise<void> {
await this.manageService.changeFileHeaders(dto.name, dto.path, {
mark: dto.mark,
mark: dto.mark
});
}

View File

@ -11,7 +11,7 @@ import {
ValidateNested,
ValidationArguments,
ValidatorConstraint,
ValidatorConstraintInterface,
ValidatorConstraintInterface
} from 'class-validator';
import { isEmpty } from 'lodash';

View File

@ -11,7 +11,7 @@ import {
NETDISK_COPY_SUFFIX,
NETDISK_DELIMITER,
NETDISK_HANDLE_MAX_ITEM,
NETDISK_LIMIT,
NETDISK_LIMIT
} from '~/constants/oss.constant';
import { AccountInfo } from '~/modules/user/user.model';
@ -38,7 +38,7 @@ export class NetDiskManageService {
) {
this.mac = new qiniu.auth.digest.Mac(this.qiniuConfig.accessKey, this.qiniuConfig.secretKey);
this.config = new qiniu.conf.Config({
zone: this.qiniuConfig.zone,
zone: this.qiniuConfig.zone
});
// bucket manager
this.bucketManager = new qiniu.rs.BucketManager(this.mac, this.config);
@ -60,7 +60,7 @@ export class NetDiskManageService {
prefix: searching ? '' : prefix,
limit: NETDISK_LIMIT,
delimiter: searching ? '' : NETDISK_DELIMITER,
marker,
marker
},
(err, respBody, respInfo) => {
if (err) {
@ -80,7 +80,7 @@ export class NetDiskManageService {
fileList.push({
name: (dirPath as string).substr(0, dirPath.length - 1).replace(prefix, ''),
type: 'dir',
id: generateRandomValue(10),
id: generateRandomValue(10)
});
}
}
@ -104,7 +104,7 @@ export class NetDiskManageService {
id: generateRandomValue(10),
name: ditName,
type: 'dir',
belongTo: pathList.join(NETDISK_DELIMITER),
belongTo: pathList.join(NETDISK_DELIMITER)
});
} else if (name.includes(skey)) {
// 文件
@ -115,7 +115,7 @@ export class NetDiskManageService {
fsize: item.fsize,
mimeType: item.mimeType,
putTime: new Date(Number.parseInt(item.putTime) / 10000),
belongTo: pathList.join(NETDISK_DELIMITER),
belongTo: pathList.join(NETDISK_DELIMITER)
});
}
} else {
@ -128,7 +128,7 @@ export class NetDiskManageService {
type: 'file',
fsize: item.fsize,
mimeType: item.mimeType,
putTime: new Date(Number.parseInt(item.putTime) / 10000),
putTime: new Date(Number.parseInt(item.putTime) / 10000)
});
}
}
@ -136,7 +136,7 @@ export class NetDiskManageService {
}
resolve({
list: fileList,
marker: respBody.marker || null,
marker: respBody.marker || null
});
} else {
reject(
@ -170,7 +170,7 @@ export class NetDiskManageService {
putTime: new Date(Number.parseInt(respBody.putTime) / 10000),
type: respBody.type,
uploader: '',
mark: respBody?.['x-qn-meta']?.['!mark'] ?? '',
mark: respBody?.['x-qn-meta']?.['!mark'] ?? ''
};
if (!respBody.endUser) {
resolve(detailInfo);
@ -295,7 +295,7 @@ export class NetDiskManageService {
scope: this.qiniuConfig.bucket,
insertOnly: 1,
fsizeLimit: 1024 ** 2 * 10,
endUser,
endUser
});
const uploadToken = policy.uploadToken(this.mac);
return uploadToken;
@ -310,7 +310,7 @@ export class NetDiskManageService {
const fileName = `${dir}${name}`;
const toFileName = `${dir}${toName}`;
const op = {
force: true,
force: true
};
return new Promise((resolve, reject) => {
this.bucketManager.move(
@ -345,7 +345,7 @@ export class NetDiskManageService {
const fileName = `${dir}${name}`;
const toFileName = `${toDir}${name}`;
const op = {
force: true,
force: true
};
return new Promise((resolve, reject) => {
this.bucketManager.move(
@ -383,7 +383,7 @@ export class NetDiskManageService {
const bn = basename(name, ext);
const toFileName = `${toDir}${bn}${NETDISK_COPY_SUFFIX}${ext}`;
const op = {
force: true,
force: true
};
return new Promise((resolve, reject) => {
this.bucketManager.copy(
@ -420,7 +420,7 @@ export class NetDiskManageService {
let hasFile = true;
let marker = '';
const op = {
force: true,
force: true
};
const bucketName = this.qiniuConfig.bucket;
while (hasFile) {
@ -431,7 +431,7 @@ export class NetDiskManageService {
{
prefix: dirName,
limit: NETDISK_HANDLE_MAX_ITEM,
marker,
marker
},
(err, respBody, respInfo) => {
if (err) {
@ -567,7 +567,7 @@ export class NetDiskManageService {
{
prefix: dirName,
limit: NETDISK_HANDLE_MAX_ITEM,
marker,
marker
},
(err, respBody, respInfo) => {
if (err) {
@ -618,7 +618,7 @@ export class NetDiskManageService {
async copyMultiFileOrDir(fileList: FileOpItem[], dir: string, toDir: string): Promise<void> {
const files = fileList.filter(item => item.type === 'file');
const op = {
force: true,
force: true
};
if (files.length > 0) {
// 批处理文件
@ -671,7 +671,7 @@ export class NetDiskManageService {
{
prefix: dirName,
limit: NETDISK_HANDLE_MAX_ITEM,
marker,
marker
},
(err, respBody, respInfo) => {
if (err) {
@ -729,7 +729,7 @@ export class NetDiskManageService {
async moveMultiFileOrDir(fileList: FileOpItem[], dir: string, toDir: string): Promise<void> {
const files = fileList.filter(item => item.type === 'file');
const op = {
force: true,
force: true
};
if (files.length > 0) {
// 批处理文件
@ -782,7 +782,7 @@ export class NetDiskManageService {
{
prefix: dirName,
limit: NETDISK_HANDLE_MAX_ITEM,
marker,
marker
},
(err, respBody, respInfo) => {
if (err) {

View File

@ -15,11 +15,11 @@ import { NetDiskOverviewService } from './overview/overview.service';
RouterModule.register([
{
path: 'netdisk',
module: NetdiskModule,
},
]),
module: NetdiskModule
}
])
],
controllers: [NetDiskManageController, NetDiskOverviewController],
providers: [NetDiskManageService, NetDiskOverviewService],
providers: [NetDiskManageService, NetDiskOverviewService]
})
export class NetdiskModule {}

View File

@ -8,7 +8,7 @@ import { OverviewSpaceInfo } from './overview.dto';
import { NetDiskOverviewService } from './overview.service';
export const permissions = definePermission('netdisk:overview', {
DESC: 'desc',
DESC: 'desc'
} as const);
@ApiTags('NetDiskOverview - 网盘概览模块')
@ -35,7 +35,7 @@ export class NetDiskOverviewController {
hitSize: hit.datas[hit.datas.length - 1],
spaceSize: space.datas[space.datas.length - 1],
flowTrend: flow,
sizeTrend: space,
sizeTrend: space
};
}
}

View File

@ -36,7 +36,7 @@ export class NetDiskOverviewService {
getStatisticUrl(type: string, queryParams = {}) {
const defaultParams = {
$bucket: this.qiniuConfig.bucket,
g: 'day',
g: 'day'
};
const searchParams = new URLSearchParams({ ...defaultParams, ...queryParams });
return decodeURIComponent(`${OSS_API}/v6/${type}?${searchParams}`);
@ -53,8 +53,8 @@ export class NetDiskOverviewService {
return this.httpService.axiosRef.get(url, {
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
Authorization: `${accessToken}`,
},
Authorization: `${accessToken}`
}
});
}
@ -89,7 +89,7 @@ export class NetDiskOverviewService {
datas: data.datas,
times: data.times.map(e => {
return dayjs.unix(e).date();
}),
})
};
}
@ -105,7 +105,7 @@ export class NetDiskOverviewService {
times: data.times.map(e => {
return dayjs.unix(e).date();
}),
datas: data.datas,
datas: data.datas
};
}
@ -121,7 +121,7 @@ export class NetDiskOverviewService {
end,
$ftype: 0,
$src: 'origin',
select: 'flow',
select: 'flow'
});
const { data } = await this.getStatisticData(url);
const times = [];
@ -132,7 +132,7 @@ export class NetDiskOverviewService {
});
return {
times,
datas,
datas
};
}
@ -148,7 +148,7 @@ export class NetDiskOverviewService {
end,
$ftype: 0,
$src: 'inner',
select: 'hit',
select: 'hit'
});
const { data } = await this.getStatisticData(url);
const times = [];
@ -159,7 +159,7 @@ export class NetDiskOverviewService {
});
return {
times,
datas,
datas
};
}
}

View File

@ -5,7 +5,7 @@ import {
ParseIntPipe,
Req,
Res,
Sse,
Sse
} from '@nestjs/common';
import { ApiTags } from '@nestjs/swagger';
import { FastifyReply, FastifyRequest } from 'fastify';
@ -26,7 +26,7 @@ export class SseController implements BeforeApplicationShutdown {
private closeAllConnect() {
this.sseService.sendToAll({
type: 'close',
data: 'bye~',
data: 'bye~'
});
this.replyMap.forEach(reply => {
reply.raw.end().destroy();

View File

@ -7,6 +7,6 @@ import { SseService } from './sse.service';
imports: [],
controllers: [SseController],
providers: [SseService],
exports: [SseService],
exports: [SseService]
})
export class SseModule {}

View File

@ -58,9 +58,9 @@ export class SseService {
const roleMenus = await RoleEntity.find({
where: {
menus: {
id: In(menuIds),
},
},
id: In(menuIds)
}
}
});
const roleIds = roleMenus.map(n => n.id).concat(ROOT_ROLE_ID);
await this.noticeClientToUpdateMenusByRoleIds(roleIds);
@ -73,9 +73,9 @@ export class SseService {
const users = await UserEntity.find({
where: {
roles: {
id: In(roleIds),
},
},
id: In(roleIds)
}
}
});
if (users) {
const userIds = users.map(n => n.id);

View File

@ -18,7 +18,7 @@ export const permissions = definePermission('system:dept', {
CREATE: 'create',
READ: 'read',
UPDATE: 'update',
DELETE: 'delete',
DELETE: 'delete'
} as const);
@ApiSecurityAuth()

View File

@ -8,7 +8,7 @@ import {
IsString,
Min,
MinLength,
ValidateNested,
ValidateNested
} from 'class-validator';
export class DeptDto {

View File

@ -14,6 +14,6 @@ const services = [DeptService];
imports: [TypeOrmModule.forFeature([DeptEntity]), UserModule, RoleModule],
controllers: [DeptController],
providers: [...services],
exports: [TypeOrmModule, ...services],
exports: [TypeOrmModule, ...services]
})
export class DeptModule {}

View File

@ -46,7 +46,7 @@ export class DeptService {
await this.deptRepository.save({
...data,
parent,
parent
});
}
@ -61,7 +61,7 @@ export class DeptService {
await this.deptRepository.save({
...item,
...data,
parent,
parent
});
}
@ -117,7 +117,7 @@ export class DeptService {
const deptTree = await this.deptRepository.findTrees({
depth: 2,
relations: ['parent'],
relations: ['parent']
});
deleteEmptyChildren(deptTree);

View File

@ -17,7 +17,7 @@ export const permissions = definePermission('system:dict-item', {
CREATE: 'create',
READ: 'read',
UPDATE: 'update',
DELETE: 'delete',
DELETE: 'delete'
} as const);
@ApiTags('System - 字典项模块')

View File

@ -11,6 +11,6 @@ const services = [DictItemService];
imports: [TypeOrmModule.forFeature([DictItemEntity])],
controllers: [DictItemController],
providers: [...services],
exports: [TypeOrmModule, ...services],
exports: [TypeOrmModule, ...services]
})
export class DictItemModule {}

View File

@ -26,7 +26,7 @@ export class DictItemService {
pageSize,
label,
value,
typeId,
typeId
}: DictItemQueryDto): Promise<Pagination<DictItemEntity>> {
const queryBuilder = this.dictItemRepository
.createQueryBuilder('dict_item')
@ -35,8 +35,8 @@ export class DictItemService {
...(label && { label: Like(`%${label}%`) }),
...(value && { value: Like(`%${value}%`) }),
type: {
id: typeId,
},
id: typeId
}
});
return paginate(queryBuilder, { page, pageSize });
@ -57,8 +57,8 @@ export class DictItemService {
await this.dictItemRepository.insert({
...rest,
type: {
id: typeId,
},
id: typeId
}
});
}
@ -70,8 +70,8 @@ export class DictItemService {
await this.dictItemRepository.update(id, {
...rest,
type: {
id: typeId,
},
id: typeId
}
});
}

View File

@ -17,7 +17,7 @@ export const permissions = definePermission('system:dict-type', {
CREATE: 'create',
READ: 'read',
UPDATE: 'update',
DELETE: 'delete',
DELETE: 'delete'
} as const);
@ApiTags('System - 字典类型模块')

View File

@ -11,6 +11,6 @@ const services = [DictTypeService];
imports: [TypeOrmModule.forFeature([DictTypeEntity])],
controllers: [DictTypeController],
providers: [...services],
exports: [TypeOrmModule, ...services],
exports: [TypeOrmModule, ...services]
})
export class DictTypeModule {}

View File

@ -25,11 +25,11 @@ export class DictTypeService {
page,
pageSize,
name,
code,
code
}: DictTypeQueryDto): Promise<Pagination<DictTypeEntity>> {
const queryBuilder = this.dictTypeRepository.createQueryBuilder('dict_type').where({
...(name && { name: Like(`%${name}%`) }),
...(code && { code: Like(`%${code}%`) }),
...(code && { code: Like(`%${code}%`) })
});
return paginate(queryBuilder, { page, pageSize });

View File

@ -17,7 +17,7 @@ import { TaskLogService } from './services/task-log.service';
export const permissions = definePermission('system:log', {
TaskList: 'task:list',
LogList: 'login:list',
CaptchaList: 'captcha:list',
CaptchaList: 'captcha:list'
} as const);
@ApiSecurityAuth()

View File

@ -16,10 +16,10 @@ const providers = [LoginLogService, TaskLogService, CaptchaLogService];
@Module({
imports: [
TypeOrmModule.forFeature([LoginLogEntity, CaptchaLogEntity, TaskLogEntity]),
UserModule,
UserModule
],
controllers: [LogController],
providers: [...providers],
exports: [TypeOrmModule, ...providers],
exports: [TypeOrmModule, ...providers]
})
export class LogModule {}

View File

@ -25,7 +25,7 @@ export class CaptchaLogService {
account,
code,
provider,
userId: uid,
userId: uid
});
}
@ -36,7 +36,7 @@ export class CaptchaLogService {
return paginate<CaptchaLogEntity>(queryBuilder, {
page,
pageSize,
pageSize
});
}

View File

@ -23,7 +23,7 @@ async function parseLoginLog(e: any, parser: UAParser): Promise<LoginLogInfo> {
os: `${`${uaResult.os.name ?? ''} `}${uaResult.os.version}`,
browser: `${`${uaResult.browser.name ?? ''} `}${uaResult.browser.version}`,
username: e.user_username,
time: e.login_log_created_at,
time: e.login_log_created_at
};
}
@ -42,7 +42,7 @@ export class LoginLogService {
ip,
ua,
address,
user: { id: uid },
user: { id: uid }
});
} catch (e) {
console.error(e);
@ -59,15 +59,15 @@ export class LoginLogService {
...(time && { createdAt: Between(time[0], time[1]) }),
...(username && {
user: {
username: Like(`%${username}%`),
},
}),
username: Like(`%${username}%`)
}
})
})
.orderBy('login_log.created_at', 'DESC');
const { items, ...rest } = await paginateRaw<LoginLogEntity>(queryBuilder, {
page,
pageSize,
pageSize
});
const parser = new UAParser();
@ -75,7 +75,7 @@ export class LoginLogService {
return {
items: loginLogInfos,
...rest,
...rest
};
}

View File

@ -20,7 +20,7 @@ export class TaskLogService {
status,
detail: err,
time,
task: { id: tid },
task: { id: tid }
});
return result.id;
}
@ -33,7 +33,7 @@ export class TaskLogService {
return paginate<TaskLogEntity>(queryBuilder, {
page,
pageSize,
pageSize
});
}

View File

@ -6,7 +6,7 @@ import {
Get,
Post,
Put,
Query,
Query
} from '@nestjs/common';
import { ApiOperation, ApiTags } from '@nestjs/swagger';
import { flattenDeep } from 'lodash';
@ -17,7 +17,7 @@ import { ApiSecurityAuth } from '~/common/decorators/swagger.decorator';
import {
Perm,
definePermission,
getDefinePermissions,
getDefinePermissions
} from '~/modules/auth/decorators/permission.decorator';
import { MenuDto, MenuQueryDto, MenuUpdateDto } from './menu.dto';
@ -29,7 +29,7 @@ export const permissions = definePermission('system:menu', {
CREATE: 'create',
READ: 'read',
UPDATE: 'update',
DELETE: 'delete',
DELETE: 'delete'
} as const);
@ApiTags('System - 菜单权限模块')

View File

@ -7,7 +7,7 @@ import {
IsString,
Min,
MinLength,
ValidateIf,
ValidateIf
} from 'class-validator';
export class MenuDto {

View File

@ -49,7 +49,7 @@ export class MenuEntity extends CommonEntity {
status: number;
@ManyToMany(() => RoleEntity, role => role.menus, {
onDelete: 'CASCADE',
onDelete: 'CASCADE'
})
roles: Relation<RoleEntity[]>;
}

View File

@ -15,6 +15,6 @@ const providers = [MenuService, SseService];
imports: [TypeOrmModule.forFeature([MenuEntity]), forwardRef(() => RoleModule)],
controllers: [MenuController],
providers: [...providers],
exports: [TypeOrmModule, ...providers],
exports: [TypeOrmModule, ...providers]
})
export class MenuModule {}

View File

@ -39,9 +39,9 @@ export class MenuService {
...(path && { path: Like(`%${path}%`) }),
...(permission && { permission: Like(`%${permission}%`) }),
...(component && { component: Like(`%${component}%`) }),
...(isNumber(status) ? { status } : null),
...(isNumber(status) ? { status } : null)
},
order: { orderNo: 'ASC' },
order: { orderNo: 'ASC' }
});
const menuList = generatorMenu(menus);
@ -166,7 +166,7 @@ export class MenuService {
if (this.roleService.hasAdminRole(roleIds)) {
result = await this.menuRepository.findBy({
permission: Not(IsNull()),
type: In([1, 2]),
type: In([1, 2])
});
} else {
if (isEmpty(roleIds)) return permission;
@ -237,9 +237,9 @@ export class MenuService {
return !!(await this.menuRepository.findOne({
where: {
roles: {
id,
},
},
id
}
}
}));
}
}

View File

@ -16,7 +16,7 @@ import { OnlineService } from './online.service';
export const permissions = definePermission('system:online', {
LIST: 'list',
KICK: 'kick',
KICK: 'kick'
} as const);
@ApiTags('System - 在线用户模块')

View File

@ -18,10 +18,10 @@ const providers = [OnlineService];
forwardRef(() => SocketModule),
AuthModule,
UserModule,
RoleModule,
RoleModule
],
controllers: [OnlineController],
providers,
exports: [...providers],
exports: [...providers]
})
export class OnlineModule {}

View File

@ -90,7 +90,7 @@ export class OnlineService {
time: e.created_at,
os: `${u.os.name} ${u.os.version}`,
browser: `${u.browser.name} ${u.browser.version}`,
disable: currentUid === e.id || e.id === rootUserId,
disable: currentUid === e.id || e.id === rootUserId
};
});
}

View File

@ -16,7 +16,7 @@ export const permissions = definePermission('system:param-config', {
CREATE: 'create',
READ: 'read',
UPDATE: 'update',
DELETE: 'delete',
DELETE: 'delete'
} as const);
@ApiTags('System - 参数配置模块')

View File

@ -11,6 +11,6 @@ const services = [ParamConfigService];
imports: [TypeOrmModule.forFeature([ParamConfigEntity])],
controllers: [ParamConfigController],
providers: [...services],
exports: [TypeOrmModule, ...services],
exports: [TypeOrmModule, ...services]
})
export class ParamConfigModule {}

View File

@ -24,13 +24,13 @@ export class ParamConfigService {
async page({
page,
pageSize,
name,
name
}: ParamConfigQueryDto): Promise<Pagination<ParamConfigEntity>> {
const queryBuilder = this.paramConfigRepository.createQueryBuilder('config');
if (name) {
queryBuilder.where('config.name LIKE :name', {
name: `%${name}%`,
name: `%${name}%`
});
}
@ -80,7 +80,7 @@ export class ParamConfigService {
async findValueByKey(key: string): Promise<string | null> {
const result = await this.paramConfigRepository.findOne({
where: { key },
select: ['value'],
select: ['value']
});
if (result) return result.value;

View File

@ -6,7 +6,7 @@ import {
Get,
Post,
Put,
Query,
Query
} from '@nestjs/common';
import { ApiOperation, ApiTags } from '@nestjs/swagger';
@ -28,7 +28,7 @@ export const permissions = definePermission('system:role', {
CREATE: 'create',
READ: 'read',
UPDATE: 'update',
DELETE: 'delete',
DELETE: 'delete'
} as const);
@ApiTags('System - 角色模块')

View File

@ -37,7 +37,7 @@ export class RoleEntity extends CommonEntity {
@JoinTable({
name: 'sys_role_menus',
joinColumn: { name: 'role_id', referencedColumnName: 'id' },
inverseJoinColumn: { name: 'menu_id', referencedColumnName: 'id' },
inverseJoinColumn: { name: 'menu_id', referencedColumnName: 'id' }
})
menus: Relation<MenuEntity[]>;
}

View File

@ -15,6 +15,6 @@ const providers = [RoleService, SseService];
imports: [TypeOrmModule.forFeature([RoleEntity]), forwardRef(() => MenuModule)],
controllers: [RoleController],
providers: [...providers],
exports: [TypeOrmModule, ...providers],
exports: [TypeOrmModule, ...providers]
})
export class RoleModule {}

View File

@ -32,17 +32,17 @@ export class RoleService {
pageSize,
name,
value,
status,
status
}: RoleQueryDto): Promise<Pagination<RoleEntity>> {
const queryBuilder = this.roleRepository.createQueryBuilder('role').where({
...(name ? { name: Like(`%${name}%`) } : null),
...(value ? { value: Like(`%${value}%`) } : null),
...(isNumber(status) ? { status } : null),
...(isNumber(status) ? { status } : null)
});
return paginate<RoleEntity>(queryBuilder, {
page,
pageSize,
pageSize
});
}
@ -53,13 +53,13 @@ export class RoleService {
const info = await this.roleRepository
.createQueryBuilder('role')
.where({
id,
id
})
.getOne();
const menus = await this.menuRepository.find({
where: { roles: { id } },
select: ['id'],
select: ['id']
});
return { ...info, menuIds: menus.map(m => m.id) };
@ -76,7 +76,7 @@ export class RoleService {
async create({ menuIds, ...data }: RoleDto): Promise<{ roleId: number }> {
const role = await this.roleRepository.save({
...data,
menus: menuIds ? await this.menuRepository.findBy({ id: In(menuIds) }) : [],
menus: menuIds ? await this.menuRepository.findBy({ id: In(menuIds) }) : []
});
return { roleId: role.id };
@ -92,7 +92,7 @@ export class RoleService {
// using transaction
await this.entityManager.transaction(async manager => {
const menus = await this.menuRepository.find({
where: { id: In(menuIds) },
where: { id: In(menuIds) }
});
const role = await this.roleRepository.findOne({ where: { id } });
@ -108,8 +108,8 @@ export class RoleService {
async getRoleIdsByUser(id: number): Promise<number[]> {
const roles = await this.roleRepository.find({
where: {
users: { id },
},
users: { id }
}
});
if (!isEmpty(roles)) return roles.map(r => r.id);
@ -120,7 +120,7 @@ export class RoleService {
async getRoleValues(ids: number[]): Promise<string[]> {
return (
await this.roleRepository.findBy({
id: In(ids),
id: In(ids)
})
).map(r => r.value);
}
@ -128,8 +128,8 @@ export class RoleService {
async isAdminRoleByUser(uid: number): Promise<boolean> {
const roles = await this.roleRepository.find({
where: {
users: { id: uid },
},
users: { id: uid }
}
});
if (!isEmpty(roles)) {
@ -149,9 +149,9 @@ export class RoleService {
return this.roleRepository.exist({
where: {
users: {
roles: { id },
},
},
roles: { id }
}
}
});
}
}

View File

@ -11,6 +11,6 @@ const providers = [ServeService];
imports: [forwardRef(() => SystemModule)],
controllers: [ServeController],
providers: [...providers],
exports: [...providers],
exports: [...providers]
})
export class ServeModule {}

View File

@ -15,7 +15,7 @@ export class ServeService {
si.osInfo(),
si.cpu(),
si.currentLoad(),
si.mem(),
si.mem()
])
).map((p: any) => p.value);
@ -36,7 +36,7 @@ export class ServeService {
npmVersion: versions.npm,
nodeVersion: versions.node,
os: osinfo.platform,
arch: osinfo.arch,
arch: osinfo.arch
},
cpu: {
manufacturer: cpuinfo.manufacturer,
@ -49,15 +49,15 @@ export class ServeService {
coresLoad: currentLoadinfo.cpus.map(e => {
return {
rawLoad: e.rawLoad,
rawLoadIdle: e.rawLoadIdle,
rawLoadIdle: e.rawLoadIdle
};
}),
})
},
disk: diskinfo,
memory: {
total: meminfo.total,
available: meminfo.available,
},
available: meminfo.available
}
};
}
}

View File

@ -26,7 +26,7 @@ const modules = [
LogModule,
TaskModule,
OnlineModule,
ServeModule,
ServeModule
];
@Module({
@ -36,10 +36,10 @@ const modules = [
{
path: 'system',
module: SystemModule,
children: [...modules],
},
]),
children: [...modules]
}
])
],
exports: [...modules],
exports: [...modules]
})
export class SystemModule {}

View File

@ -1,11 +1,11 @@
export enum TaskStatus {
Disabled = 0,
Activited = 1,
Activited = 1
}
export enum TaskType {
Cron = 0,
Interval = 1,
Interval = 1
}
export const SYS_TASK_QUEUE_NAME = 'system:sys-task';

View File

@ -20,7 +20,7 @@ export const permissions = definePermission('system:task', {
ONCE: 'once',
START: 'start',
STOP: 'stop',
STOP: 'stop'
} as const);
@ApiTags('System - 任务调度模块')

View File

@ -13,7 +13,7 @@ import {
ValidateIf,
ValidationArguments,
ValidatorConstraint,
ValidatorConstraintInterface,
ValidatorConstraintInterface
} from 'class-validator';
import * as parser from 'cron-parser';
import { isEmpty } from 'lodash';
@ -70,7 +70,7 @@ export class TaskDto {
endTime: string;
@ApiPropertyOptional({
description: '限制执行次数,负数则无限制',
description: '限制执行次数,负数则无限制'
})
@IsOptional()
@IsInt()

View File

@ -24,14 +24,14 @@ const providers = [TaskService, TaskConsumer];
name: SYS_TASK_QUEUE_NAME,
useFactory: (configService: ConfigService<ConfigKeyPaths>) => ({
redis: configService.get<IRedisConfig>('redis'),
prefix: SYS_TASK_QUEUE_PREFIX,
prefix: SYS_TASK_QUEUE_PREFIX
}),
inject: [ConfigService],
inject: [ConfigService]
}),
LogModule,
LogModule
],
controllers: [TaskController],
providers: [...providers],
exports: [TypeOrmModule, ...providers],
exports: [TypeOrmModule, ...providers]
})
export class TaskModule {}

View File

@ -5,7 +5,7 @@ import {
Injectable,
Logger,
NotFoundException,
OnModuleInit,
OnModuleInit
} from '@nestjs/common';
import { ModuleRef, Reflector } from '@nestjs/core';
import { UnknownElementException } from '@nestjs/core/errors/exceptions/unknown-element.exception';
@ -69,7 +69,7 @@ export class TaskService implements OnModuleInit {
'failed',
'paused',
'waiting',
'completed',
'completed'
]);
jobs.forEach(j => {
j.remove();
@ -90,7 +90,7 @@ export class TaskService implements OnModuleInit {
name,
service,
type,
status,
status
}: TaskQueryDto): Promise<Pagination<TaskEntity>> {
const queryBuilder = this.taskRepository
.createQueryBuilder('task')
@ -98,7 +98,7 @@ export class TaskService implements OnModuleInit {
...(name ? { name: Like(`%${name}%`) } : null),
...(service ? { service: Like(`%${service}%`) } : null),
...(type ? { type } : null),
...(isNumber(status) ? { status } : null),
...(isNumber(status) ? { status } : null)
})
.orderBy('task.id', 'ASC');
@ -166,12 +166,12 @@ export class TaskService implements OnModuleInit {
if (task.type === 1) {
// 间隔 Repeat every millis (cron setting cannot be used together with this setting.)
repeat = {
every: task.every,
every: task.every
};
} else {
// cron
repeat = {
cron: task.cron,
cron: task.cron
};
// Start date when the repeat job should start repeating (only with cron).
if (task.startTime) repeat.startDate = task.startTime;
@ -187,13 +187,13 @@ export class TaskService implements OnModuleInit {
if (job && job.opts) {
await this.taskRepository.update(task.id, {
jobOpts: JSON.stringify(job.opts.repeat),
status: 1,
status: 1
});
} else {
// update status to 0标识暂停任务因为启动失败
await job?.remove();
await this.taskRepository.update(task.id, {
status: TaskStatus.Disabled,
status: TaskStatus.Disabled
});
throw new BadRequestException('Task Start failed');
}
@ -208,7 +208,7 @@ export class TaskService implements OnModuleInit {
const exist = await this.existJob(task.id.toString());
if (!exist) {
await this.taskRepository.update(task.id, {
status: TaskStatus.Disabled,
status: TaskStatus.Disabled
});
return;
}
@ -218,7 +218,7 @@ export class TaskService implements OnModuleInit {
'failed',
'paused',
'waiting',
'completed',
'completed'
]);
jobs
.filter(j => j.data.id === task.id)
@ -301,7 +301,7 @@ export class TaskService implements OnModuleInit {
if (!methodName) throw new BadRequestException('serviceName define BadRequestException');
const service = await this.moduleRef.get(serviceName, {
strict: false,
strict: false
});
// 安全注解检查

View File

@ -21,7 +21,7 @@ function createAliasProviders(): ExistingProvider[] {
for (const p of providers) {
aliasProviders.push({
provide: p.name,
useExisting: p,
useExisting: p
});
}
return aliasProviders;
@ -40,7 +40,7 @@ export class TasksModule {
module: TasksModule,
imports: [SystemModule, LogModule],
providers: [...providers, ...aliasProviders],
exports: aliasProviders,
exports: aliasProviders
};
}
}

View File

@ -19,7 +19,7 @@ export const permissions = definePermission('todo', {
CREATE: 'create',
READ: 'read',
UPDATE: 'update',
DELETE: 'delete',
DELETE: 'delete'
} as const);
@ApiTags('Business - Todo模块')

View File

@ -11,6 +11,6 @@ const services = [TodoService];
imports: [TypeOrmModule.forFeature([TodoEntity])],
controllers: [TodoController],
providers: [...services],
exports: [TypeOrmModule, ...services],
exports: [TypeOrmModule, ...services]
})
export class TodoModule {}

Some files were not shown because too many files have changed in this diff Show More