import { BadRequestException } from '@nestjs/common' import { ApiProperty, ApiPropertyOptional, IntersectionType, PartialType } from '@nestjs/swagger' import { IsDateString, IsIn, IsInt, IsOptional, IsString, MaxLength, Min, MinLength, Validate, ValidateIf, ValidationArguments, ValidatorConstraint, ValidatorConstraintInterface, } from 'class-validator' import * as parser from 'cron-parser' import { isEmpty } from 'lodash' import { PagerDto } from '~/common/dto/pager.dto' // cron 表达式验证,bull lib下引用了cron-parser @ValidatorConstraint({ name: 'isCronExpression', async: false }) export class IsCronExpression implements ValidatorConstraintInterface { validate(value: string, _args: ValidationArguments) { try { if (isEmpty(value)) throw new BadRequestException('cron expression is empty') parser.parseExpression(value) return true } catch (e) { return false } } defaultMessage(_args: ValidationArguments) { return 'this cron expression ($value) invalid' } } export class TaskDto { @ApiProperty({ description: '任务名称' }) @IsString() @MinLength(2) @MaxLength(50) name: string @ApiProperty({ description: '调用的服务' }) @IsString() @MinLength(1) service: string @ApiProperty({ description: '任务类别:cron | interval' }) @IsIn([0, 1]) type: number @ApiProperty({ description: '任务状态' }) @IsIn([0, 1]) status: number @ApiPropertyOptional({ description: '开始时间', type: Date }) @IsDateString() @ValidateIf(o => !isEmpty(o.startTime)) startTime: string @ApiPropertyOptional({ description: '结束时间', type: Date }) @IsDateString() @ValidateIf(o => !isEmpty(o.endTime)) endTime: string @ApiPropertyOptional({ description: '限制执行次数,负数则无限制', }) @IsOptional() @IsInt() limit?: number = -1 @ApiProperty({ description: 'cron表达式' }) @Validate(IsCronExpression) @ValidateIf(o => o.type === 0) cron: string @ApiProperty({ description: '执行间隔,毫秒单位' }) @IsInt() @Min(100) @ValidateIf(o => o.type === 1) every?: number @ApiPropertyOptional({ description: '执行参数' }) @IsOptional() @IsString() data?: string @ApiPropertyOptional({ description: '任务备注' }) @IsOptional() @IsString() remark?: string } export class TaskUpdateDto extends PartialType(TaskDto) {} export class TaskQueryDto extends IntersectionType(PagerDto, PartialType(TaskDto)) {}