import { IsNotEmpty, IsOptional, IsString, IsInt, IsNumber, IsArray, IsDateString, IsIn, ArrayNotEmpty, Matches, Min, Max, MaxLength } from "class-validator"; export class SurveyOrderQueryDTO { @IsOptional() @IsInt() @Min(1) page?: number = 1; @IsOptional() @IsInt() @Min(1) @Max(200) pageSize?: number = 10; @IsOptional() @IsString() @MaxLength(64) keyword?: string; @IsOptional() @IsInt() customerId?: number; @IsOptional() @IsInt() @Min(0) @Max(5) status?: number; @IsOptional() @IsInt() @Min(1) @Max(3) priority?: number; @IsOptional() @IsInt() workerId?: number; @IsOptional() @IsInt() salesmanId?: number; // 计划到场日期窗口(YYYY-MM-DD) @IsOptional() @IsString() @MaxLength(10) planStartDate?: string; @IsOptional() @IsString() @MaxLength(10) planEndDate?: string; // 是否包含草稿:字符串或数字,服务层统一转 number 判定 @IsOptional() includeDraft?: string | number; } export class SurveyOrderCreateDTO { @IsNotEmpty({ message: '所属客户不能为空' }) @IsInt() customerId!: number; @IsOptional() @IsString() @MaxLength(128) @Matches(/^[^<>]*$/) taskTitle?: string; @IsOptional() @IsString() @MaxLength(255) @Matches(/^[^<>]*$/) siteLocation?: string; @IsOptional() @IsInt() @Min(1) @Max(3) priority?: number; @IsOptional() @IsString() @MaxLength(128) @Matches(/^[^<>]*$/) loopSpec?: string; @IsOptional() @IsInt() @Min(0) loopCount?: number; @IsOptional() @IsString() @MaxLength(128) @Matches(/^[^<>]*$/) techContact?: string; @IsOptional() @IsDateString() planStart?: string; @IsOptional() @IsDateString() planEnd?: string; @IsOptional() @IsInt() @Min(0) expectMinutes?: number; @IsOptional() @IsString() @MaxLength(32) @Matches(/^[^<>]*$/) slaLevel?: string; @IsOptional() @IsInt() workerId?: number; @IsOptional() @IsInt() salesmanId?: number; @IsOptional() @IsNumber() estimatedFee?: number; @IsOptional() @IsString() @MaxLength(2000) @Matches(/^[^<>]*$/) remark?: string; @IsOptional() @IsString() @MaxLength(32) @Matches(/^[^<>]*$/) source?: string; @IsOptional() @IsInt() @Min(0) @Max(1) isDraft?: number; // 勘察明细(建筑/楼层/房间 + 现场照片),非持久化列,仅用于创建时一并写入 @IsOptional() @IsArray() details?: any[]; } export class SurveyOrderUpdateDTO extends SurveyOrderCreateDTO { @IsOptional() @IsInt() declare customerId: number; @IsOptional() @IsString() @MaxLength(128) @Matches(/^[^<>]*$/) declare taskTitle?: string; @IsOptional() @IsString() @MaxLength(255) @Matches(/^[^<>]*$/) declare siteLocation?: string; @IsOptional() @IsInt() @Min(1) @Max(3) declare priority?: number; @IsOptional() @IsString() @MaxLength(128) @Matches(/^[^<>]*$/) declare loopSpec?: string; @IsOptional() @IsInt() @Min(0) declare loopCount?: number; @IsOptional() @IsString() @MaxLength(128) @Matches(/^[^<>]*$/) declare techContact?: string; @IsOptional() @IsDateString() declare planStart?: string; @IsOptional() @IsDateString() declare planEnd?: string; @IsOptional() @IsInt() @Min(0) declare expectMinutes?: number; @IsOptional() @IsString() @MaxLength(32) @Matches(/^[^<>]*$/) declare slaLevel?: string; @IsOptional() @IsInt() declare workerId?: number; @IsOptional() @IsInt() declare salesmanId?: number; @IsOptional() @IsNumber() declare estimatedFee?: number; @IsOptional() @IsString() @MaxLength(2000) @Matches(/^[^<>]*$/) declare remark?: string; @IsOptional() @IsString() @MaxLength(32) @Matches(/^[^<>]*$/) declare source?: string; @IsOptional() @IsInt() @Min(0) @Max(1) declare isDraft?: number; @IsOptional() @IsArray() declare details?: any[]; } // 指派 / 改派(0待指派→指派,1现场勘察中→改派) export class SurveyOrderAssignDTO { @IsNotEmpty({ message: '请选择共享电工' }) @IsInt() workerId!: number; @IsOptional() @IsNumber() estimatedFee?: number; } // 批量指派 export class SurveyOrderBatchAssignDTO { @IsArray() @ArrayNotEmpty({ message: '请至少选择一条工单' }) @IsInt({ each: true }) ids!: number[]; @IsNotEmpty({ message: '请选择共享电工' }) @IsInt() workerId!: number; } // 技术复核 export class SurveyOrderReviewDTO { @IsIn(['pass', 'reject'], { message: '复核结果不合法' }) result!: 'pass' | 'reject'; @IsOptional() @IsString() @MaxLength(500) @Matches(/^[^<>]*$/) remark?: string; } // 取消工单 export class SurveyOrderCancelDTO { @IsOptional() @IsString() @MaxLength(255) @Matches(/^[^<>]*$/) reason?: string; }