Files
plates-server/src/challenges/dto/create-custom-challenge.dto.ts
richarjiang ac231a7742 feat(challenges): 支持自定义挑战类型并优化必填字段验证
- 新增 CUSTOM 挑战类型枚举值
- requirementLabel 字段改为可选,允许为空并添加默认值处理
- minimumCheckInDays 最大值从 365 提升至 1000,支持更长周期挑战
- 推送通知模板支持自定义挑战的动态文案生成
- 新增 getCustomEncouragementTemplate 和 getCustomInvitationTemplate 函数
2025-11-27 11:11:26 +08:00

89 lines
2.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { ApiProperty } from '@nestjs/swagger';
import { IsString, IsNotEmpty, IsNumber, Min, Max, IsEnum, IsOptional, IsBoolean, MaxLength, MinLength } from 'class-validator';
import { ChallengeType } from '../models/challenge.model';
export class CreateCustomChallengeDto {
@ApiProperty({ description: '挑战标题', example: '21天喝水挑战' })
@IsString()
@IsNotEmpty()
@MaxLength(100)
title: string;
@ApiProperty({ description: '挑战类型', enum: ChallengeType, example: ChallengeType.WATER })
@IsEnum(ChallengeType)
@IsNotEmpty()
type: ChallengeType;
@ApiProperty({ description: '挑战封面图 URL', required: false })
@IsString()
@IsOptional()
@MaxLength(512)
image?: string;
@ApiProperty({ description: '开始时间戳(毫秒)', example: 1704067200000 })
@IsNumber()
startAt: number;
@ApiProperty({ description: '结束时间戳(毫秒)', example: 1705881600000 })
@IsNumber()
endAt: number;
@ApiProperty({ description: '每日目标值如喝水8杯', example: 8, minimum: 1, maximum: 1000 })
@IsNumber()
@Min(1)
@Max(1000)
targetValue: number;
@ApiProperty({ description: '最少打卡天数', example: 21, minimum: 1, maximum: 1000 })
@IsNumber()
@Min(1)
@Max(1000)
minimumCheckInDays: number;
@ApiProperty({ description: '持续时间标签', example: '持续21天' })
@IsString()
@IsNotEmpty()
@MaxLength(128)
durationLabel: string;
@ApiProperty({ description: '挑战要求标签', example: '每日喝水8杯' })
@IsString()
@IsOptional()
@MaxLength(255)
requirementLabel: string;
@ApiProperty({ description: '挑战概要说明', required: false })
@IsString()
@IsOptional()
summary?: string;
@ApiProperty({ description: '进度单位', example: '天', required: true })
@IsString()
@MaxLength(64)
progressUnit?: string;
@ApiProperty({ description: '周期标签', example: '21天挑战', required: false })
@IsString()
@IsOptional()
@MaxLength(128)
periodLabel?: string;
@ApiProperty({ description: '排行榜描述', example: '连续打卡榜', required: false })
@IsString()
@IsOptional()
@MaxLength(255)
rankingDescription?: string;
@ApiProperty({ description: '是否公开(可通过分享码加入)', default: true })
@IsBoolean()
@IsOptional()
isPublic?: boolean;
@ApiProperty({ description: '最大参与人数限制null表示无限制', required: false, minimum: 2, maximum: 10000 })
@IsNumber()
@IsOptional()
@Min(2)
@Max(10000)
maxParticipants?: number;
}