refactor:
This commit is contained in:
parent
6b9b4cdd17
commit
88a97ee162
|
@ -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 {}
|
||||
|
|
|
@ -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) => {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -7,7 +7,7 @@ export function IdParam() {
|
|||
errorHttpStatusCode: HttpStatus.NOT_ACCEPTABLE,
|
||||
exceptionFactory: _error => {
|
||||
throw new NotAcceptableException('id 格式不正确');
|
||||
},
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ import {
|
|||
CreateDateColumn,
|
||||
PrimaryGeneratedColumn,
|
||||
UpdateDateColumn,
|
||||
VirtualColumn,
|
||||
VirtualColumn
|
||||
} from 'typeorm';
|
||||
|
||||
// 如果觉得前端转换时间太麻烦,并且不考虑通用性的话,可以在服务端进行转换,eg: @UpdateDateColumn({ name: 'updated_at', transformer })
|
||||
|
|
|
@ -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
|
||||
);
|
||||
|
|
|
@ -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
|
||||
})
|
||||
);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -3,7 +3,7 @@ import {
|
|||
ExecutionContext,
|
||||
HttpStatus,
|
||||
Injectable,
|
||||
NestInterceptor,
|
||||
NestInterceptor
|
||||
} from '@nestjs/common';
|
||||
import { Reflector } from '@nestjs/core';
|
||||
import { Observable } from 'rxjs';
|
||||
|
|
|
@ -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>;
|
||||
|
|
|
@ -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';
|
||||
|
||||
|
|
|
@ -33,5 +33,5 @@ export default {
|
|||
OssConfig,
|
||||
RedisConfig,
|
||||
SecurityConfig,
|
||||
SwaggerConfig,
|
||||
SwaggerConfig
|
||||
};
|
||||
|
|
|
@ -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>;
|
||||
|
|
|
@ -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>;
|
||||
|
|
|
@ -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>;
|
||||
|
|
|
@ -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>;
|
||||
|
|
|
@ -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>;
|
||||
|
|
|
@ -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:';
|
||||
|
|
|
@ -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:已超出支持的最大处理数量'
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
export enum EventBusEvents {
|
||||
TokenExpired = 'token.expired',
|
||||
SystemException = 'system.exception',
|
||||
SystemException = 'system.exception'
|
||||
}
|
||||
|
|
|
@ -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'
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
];
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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]
|
||||
),
|
||||
)
|
||||
})
|
||||
);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 {}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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>()
|
||||
|
|
|
@ -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()
|
||||
]);
|
||||
|
||||
// 控制器没有设置接口权限,则默认通过
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -12,7 +12,7 @@ export class JwtStrategy extends PassportStrategy(Strategy, AuthStrategy.JWT) {
|
|||
super({
|
||||
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
|
||||
ignoreExpiration: false,
|
||||
secretOrKey: securityConfig.jwtSecret,
|
||||
secretOrKey: securityConfig.jwtSecret
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ export class LocalStrategy extends PassportStrategy(Strategy, AuthStrategy.LOCAL
|
|||
constructor(private authService: AuthService) {
|
||||
super({
|
||||
usernameField: 'credential',
|
||||
passwordField: 'password',
|
||||
passwordField: 'password'
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ export const permissions = definePermission('app:contract', {
|
|||
CREATE: 'create',
|
||||
READ: 'read',
|
||||
UPDATE: 'update',
|
||||
DELETE: 'delete',
|
||||
DELETE: 'delete'
|
||||
} as const);
|
||||
|
||||
@ApiTags('Contract - 合同')
|
||||
|
|
|
@ -4,6 +4,6 @@ import { ContractService } from './contract.service';
|
|||
|
||||
@Module({
|
||||
controllers: [ContractController],
|
||||
providers: [ContractService],
|
||||
providers: [ContractService]
|
||||
})
|
||||
export class ContractModule {}
|
||||
|
|
|
@ -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: '/'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,6 @@ import { HealthController } from './health.controller';
|
|||
|
||||
@Module({
|
||||
imports: [TerminusModule, HttpModule],
|
||||
controllers: [HealthController],
|
||||
controllers: [HealthController]
|
||||
})
|
||||
export class HealthModule {}
|
||||
|
|
|
@ -49,7 +49,7 @@ export class SFileInfoDetail {
|
|||
mimeType: string;
|
||||
|
||||
@ApiProperty({
|
||||
description: '文件存储类型,2 表示归档存储,1 表示低频存储,0表示普通存储。',
|
||||
description: '文件存储类型,2 表示归档存储,1 表示低频存储,0表示普通存储。'
|
||||
})
|
||||
type: number;
|
||||
|
||||
|
|
|
@ -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
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ import {
|
|||
ValidateNested,
|
||||
ValidationArguments,
|
||||
ValidatorConstraint,
|
||||
ValidatorConstraintInterface,
|
||||
ValidatorConstraintInterface
|
||||
} from 'class-validator';
|
||||
import { isEmpty } from 'lodash';
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 {}
|
||||
|
|
|
@ -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
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -7,6 +7,6 @@ import { SseService } from './sse.service';
|
|||
imports: [],
|
||||
controllers: [SseController],
|
||||
providers: [SseService],
|
||||
exports: [SseService],
|
||||
exports: [SseService]
|
||||
})
|
||||
export class SseModule {}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -18,7 +18,7 @@ export const permissions = definePermission('system:dept', {
|
|||
CREATE: 'create',
|
||||
READ: 'read',
|
||||
UPDATE: 'update',
|
||||
DELETE: 'delete',
|
||||
DELETE: 'delete'
|
||||
} as const);
|
||||
|
||||
@ApiSecurityAuth()
|
||||
|
|
|
@ -8,7 +8,7 @@ import {
|
|||
IsString,
|
||||
Min,
|
||||
MinLength,
|
||||
ValidateNested,
|
||||
ValidateNested
|
||||
} from 'class-validator';
|
||||
|
||||
export class DeptDto {
|
||||
|
|
|
@ -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 {}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 - 字典项模块')
|
||||
|
|
|
@ -11,6 +11,6 @@ const services = [DictItemService];
|
|||
imports: [TypeOrmModule.forFeature([DictItemEntity])],
|
||||
controllers: [DictItemController],
|
||||
providers: [...services],
|
||||
exports: [TypeOrmModule, ...services],
|
||||
exports: [TypeOrmModule, ...services]
|
||||
})
|
||||
export class DictItemModule {}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -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 - 字典类型模块')
|
||||
|
|
|
@ -11,6 +11,6 @@ const services = [DictTypeService];
|
|||
imports: [TypeOrmModule.forFeature([DictTypeEntity])],
|
||||
controllers: [DictTypeController],
|
||||
providers: [...services],
|
||||
exports: [TypeOrmModule, ...services],
|
||||
exports: [TypeOrmModule, ...services]
|
||||
})
|
||||
export class DictTypeModule {}
|
||||
|
|
|
@ -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 });
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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 {}
|
||||
|
|
|
@ -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
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -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 - 菜单权限模块')
|
||||
|
|
|
@ -7,7 +7,7 @@ import {
|
|||
IsString,
|
||||
Min,
|
||||
MinLength,
|
||||
ValidateIf,
|
||||
ValidateIf
|
||||
} from 'class-validator';
|
||||
|
||||
export class MenuDto {
|
||||
|
|
|
@ -49,7 +49,7 @@ export class MenuEntity extends CommonEntity {
|
|||
status: number;
|
||||
|
||||
@ManyToMany(() => RoleEntity, role => role.menus, {
|
||||
onDelete: 'CASCADE',
|
||||
onDelete: 'CASCADE'
|
||||
})
|
||||
roles: Relation<RoleEntity[]>;
|
||||
}
|
||||
|
|
|
@ -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 {}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 - 在线用户模块')
|
||||
|
|
|
@ -18,10 +18,10 @@ const providers = [OnlineService];
|
|||
forwardRef(() => SocketModule),
|
||||
AuthModule,
|
||||
UserModule,
|
||||
RoleModule,
|
||||
RoleModule
|
||||
],
|
||||
controllers: [OnlineController],
|
||||
providers,
|
||||
exports: [...providers],
|
||||
exports: [...providers]
|
||||
})
|
||||
export class OnlineModule {}
|
||||
|
|
|
@ -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
|
||||
};
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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 - 参数配置模块')
|
||||
|
|
|
@ -11,6 +11,6 @@ const services = [ParamConfigService];
|
|||
imports: [TypeOrmModule.forFeature([ParamConfigEntity])],
|
||||
controllers: [ParamConfigController],
|
||||
providers: [...services],
|
||||
exports: [TypeOrmModule, ...services],
|
||||
exports: [TypeOrmModule, ...services]
|
||||
})
|
||||
export class ParamConfigModule {}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 - 角色模块')
|
||||
|
|
|
@ -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[]>;
|
||||
}
|
||||
|
|
|
@ -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 {}
|
||||
|
|
|
@ -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 }
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,6 @@ const providers = [ServeService];
|
|||
imports: [forwardRef(() => SystemModule)],
|
||||
controllers: [ServeController],
|
||||
providers: [...providers],
|
||||
exports: [...providers],
|
||||
exports: [...providers]
|
||||
})
|
||||
export class ServeModule {}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {}
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -20,7 +20,7 @@ export const permissions = definePermission('system:task', {
|
|||
|
||||
ONCE: 'once',
|
||||
START: 'start',
|
||||
STOP: 'stop',
|
||||
STOP: 'stop'
|
||||
} as const);
|
||||
|
||||
@ApiTags('System - 任务调度模块')
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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 {}
|
||||
|
|
|
@ -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
|
||||
});
|
||||
|
||||
// 安全注解检查
|
||||
|
|
|
@ -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
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ export const permissions = definePermission('todo', {
|
|||
CREATE: 'create',
|
||||
READ: 'read',
|
||||
UPDATE: 'update',
|
||||
DELETE: 'delete',
|
||||
DELETE: 'delete'
|
||||
} as const);
|
||||
|
||||
@ApiTags('Business - Todo模块')
|
||||
|
|
|
@ -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
Loading…
Reference in New Issue