feat: 支持教学案例展示功能

This commit is contained in:
richarjiang
2026-09-18 18:26:47 +08:00
parent 95b9f6511c
commit 87afb786b9
28 changed files with 950 additions and 5 deletions

View File

@@ -0,0 +1,31 @@
import { Transform, Type } from 'class-transformer'
import { ArrayMaxSize, ArrayMinSize, IsArray, IsBoolean, IsIn, IsInt, IsOptional, IsString, Length, Max, MaxLength, Min, ValidateNested } from 'class-validator'
const Trim = () => Transform(({ value }: { value: unknown }) => typeof value === 'string' ? value.trim() : value)
export class TeachingCaseFrameDto {
@IsIn(['pair', 'composite']) kind!: 'pair' | 'composite'
@IsString() @Length(1, 100) beforeId!: string
@IsOptional() @IsString() @Length(1, 100) afterId?: string
@Trim() @IsString() @MaxLength(100) caption!: string
}
export class SaveTeachingCaseDto {
@Trim() @IsString() @Length(1, 80) title!: string
@Trim() @IsString() @Length(1, 30) displayName!: string
@IsInt() @Min(1) @Max(9999) lessonCount!: number
@Trim() @IsString() @MaxLength(500) background!: string
@Trim() @IsString() @Length(1, 1000) achievement!: string
@IsArray() @ArrayMinSize(1) @ArrayMaxSize(9)
@ValidateNested({ each: true }) @Type(() => TeachingCaseFrameDto) frames!: TeachingCaseFrameDto[]
@IsInt() @Min(0) @Max(9999) sortOrder!: number
@IsBoolean() published!: boolean
@IsBoolean() consentConfirmed!: boolean
@Trim() @IsString() @MaxLength(500) consentNote!: string
@IsInt() @Min(0) version!: number
}
export class TeachingCaseQueryDto {
@IsOptional() @Type(() => Number) @IsInt() @Min(1) @Max(100000) page = 1
@IsOptional() @Type(() => Number) @IsInt() @Min(1) @Max(20) limit = 10
}
export class TeachingCaseUploadDto {
@IsString() @Length(1, 200) fileName!: string
}