343 lines
7.5 KiB
TypeScript
343 lines
7.5 KiB
TypeScript
// Request DTOs
|
|
export * from './request';
|
|
|
|
// Response DTOs
|
|
export * from './response';
|
|
|
|
// 其他通用DTOs
|
|
import { IsString, IsOptional, IsNotEmpty, Matches, IsEnum, IsNumber } from 'class-validator';
|
|
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
|
|
|
export class AutoLoginDto {
|
|
@ApiProperty()
|
|
@IsString()
|
|
@IsNotEmpty()
|
|
refreshToken: string;
|
|
|
|
@ApiProperty()
|
|
@IsString()
|
|
@IsNotEmpty()
|
|
deviceId: string;
|
|
}
|
|
|
|
export class SendSmsCodeDto {
|
|
@ApiProperty({ example: '13800138000' })
|
|
@IsString()
|
|
@Matches(/^1[3-9]\d{9}$/, { message: '手机号格式错误' })
|
|
phoneNumber: string;
|
|
|
|
@ApiProperty({ enum: ['REGISTER', 'LOGIN', 'BIND', 'RECOVER'] })
|
|
@IsEnum(['REGISTER', 'LOGIN', 'BIND', 'RECOVER'])
|
|
type: 'REGISTER' | 'LOGIN' | 'BIND' | 'RECOVER';
|
|
}
|
|
|
|
export class RegisterDto {
|
|
@ApiProperty({ example: '13800138000' })
|
|
@IsString()
|
|
@Matches(/^1[3-9]\d{9}$/, { message: '手机号格式错误' })
|
|
phoneNumber: string;
|
|
|
|
@ApiProperty({ example: '123456' })
|
|
@IsString()
|
|
@Matches(/^\d{6}$/, { message: '验证码格式错误' })
|
|
smsCode: string;
|
|
|
|
@ApiProperty()
|
|
@IsString()
|
|
@IsNotEmpty()
|
|
deviceId: string;
|
|
|
|
@ApiProperty()
|
|
@IsString()
|
|
@IsNotEmpty()
|
|
provinceCode: string;
|
|
|
|
@ApiProperty()
|
|
@IsString()
|
|
@IsNotEmpty()
|
|
cityCode: string;
|
|
|
|
@ApiPropertyOptional()
|
|
@IsOptional()
|
|
@IsString()
|
|
deviceName?: string;
|
|
|
|
@ApiPropertyOptional()
|
|
@IsOptional()
|
|
@IsString()
|
|
inviterReferralCode?: string;
|
|
}
|
|
|
|
export class LoginDto {
|
|
@ApiProperty({ example: '13800138000' })
|
|
@IsString()
|
|
@Matches(/^1[3-9]\d{9}$/, { message: '手机号格式错误' })
|
|
phoneNumber: string;
|
|
|
|
@ApiProperty({ example: '123456' })
|
|
@IsString()
|
|
@Matches(/^\d{6}$/, { message: '验证码格式错误' })
|
|
smsCode: string;
|
|
|
|
@ApiProperty()
|
|
@IsString()
|
|
@IsNotEmpty()
|
|
deviceId: string;
|
|
}
|
|
|
|
export class UpdateProfileDto {
|
|
@ApiPropertyOptional()
|
|
@IsOptional()
|
|
@IsString()
|
|
nickname?: string;
|
|
|
|
@ApiPropertyOptional()
|
|
@IsOptional()
|
|
@IsString()
|
|
avatarUrl?: string;
|
|
|
|
@ApiPropertyOptional()
|
|
@IsOptional()
|
|
@IsString()
|
|
address?: string;
|
|
}
|
|
|
|
export class BindWalletDto {
|
|
@ApiProperty({ enum: ['KAVA', 'DST', 'BSC'] })
|
|
@IsEnum(['KAVA', 'DST', 'BSC'])
|
|
chainType: string;
|
|
|
|
@ApiProperty()
|
|
@IsString()
|
|
@IsNotEmpty()
|
|
address: string;
|
|
}
|
|
|
|
export class RemoveDeviceDto {
|
|
@ApiProperty()
|
|
@IsString()
|
|
@IsNotEmpty()
|
|
deviceId: string;
|
|
}
|
|
|
|
// Response DTOs
|
|
export class AutoCreateAccountResponseDto {
|
|
@ApiProperty({ example: 100001, description: '用户序列号 (唯一标识)' })
|
|
userSerialNum: number;
|
|
|
|
@ApiProperty({ example: 'ABC123', description: '推荐码' })
|
|
referralCode: string;
|
|
|
|
@ApiProperty({ example: '榴莲勇士_38472', description: '随机用户名' })
|
|
username: string;
|
|
|
|
@ApiProperty({ example: '<svg>...</svg>', description: '随机SVG头像' })
|
|
avatarSvg: string;
|
|
|
|
@ApiProperty({ description: '访问令牌' })
|
|
accessToken: string;
|
|
|
|
@ApiProperty({ description: '刷新令牌' })
|
|
refreshToken: string;
|
|
}
|
|
|
|
export class RecoverAccountResponseDto {
|
|
@ApiProperty()
|
|
userId: string;
|
|
|
|
@ApiProperty()
|
|
accountSequence: number;
|
|
|
|
@ApiProperty()
|
|
nickname: string;
|
|
|
|
@ApiProperty({ nullable: true })
|
|
avatarUrl: string | null;
|
|
|
|
@ApiProperty()
|
|
referralCode: string;
|
|
|
|
@ApiProperty()
|
|
accessToken: string;
|
|
|
|
@ApiProperty()
|
|
refreshToken: string;
|
|
}
|
|
|
|
// 钱包地址响应
|
|
export class WalletAddressesDto {
|
|
@ApiProperty({ example: '0x1234...', description: 'KAVA链地址' })
|
|
kava: string;
|
|
|
|
@ApiProperty({ example: 'dst1...', description: 'DST链地址' })
|
|
dst: string;
|
|
|
|
@ApiProperty({ example: '0x5678...', description: 'BSC链地址' })
|
|
bsc: string;
|
|
}
|
|
|
|
// 钱包状态响应 (就绪)
|
|
export class WalletStatusReadyResponseDto {
|
|
@ApiProperty({ example: 'ready', description: '钱包状态' })
|
|
status: 'ready';
|
|
|
|
@ApiProperty({ type: WalletAddressesDto, description: '三链钱包地址' })
|
|
walletAddresses: WalletAddressesDto;
|
|
|
|
@ApiProperty({ example: 'word1 word2 ... word12', description: '助记词 (12词)' })
|
|
mnemonic: string;
|
|
}
|
|
|
|
// 钱包状态响应 (生成中)
|
|
export class WalletStatusGeneratingResponseDto {
|
|
@ApiProperty({ example: 'generating', description: '钱包状态' })
|
|
status: 'generating';
|
|
}
|
|
|
|
export class LoginResponseDto {
|
|
@ApiProperty()
|
|
userId: string;
|
|
|
|
@ApiProperty()
|
|
accountSequence: number;
|
|
|
|
@ApiProperty()
|
|
accessToken: string;
|
|
|
|
@ApiProperty()
|
|
refreshToken: string;
|
|
}
|
|
|
|
// ============ Referral DTOs ============
|
|
|
|
export class GenerateReferralLinkDto {
|
|
@ApiPropertyOptional({ description: '渠道标识: wechat, telegram, twitter 等' })
|
|
@IsOptional()
|
|
@IsString()
|
|
channel?: string;
|
|
|
|
@ApiPropertyOptional({ description: '活动ID' })
|
|
@IsOptional()
|
|
@IsString()
|
|
campaignId?: string;
|
|
}
|
|
|
|
export class MeResponseDto {
|
|
@ApiProperty()
|
|
userId: string;
|
|
|
|
@ApiProperty({ description: '账户序列号' })
|
|
accountSequence: number;
|
|
|
|
@ApiProperty({ nullable: true })
|
|
phoneNumber: string | null;
|
|
|
|
@ApiProperty()
|
|
nickname: string;
|
|
|
|
@ApiProperty({ nullable: true })
|
|
avatarUrl: string | null;
|
|
|
|
@ApiProperty({ description: '推荐码' })
|
|
referralCode: string;
|
|
|
|
@ApiProperty({ description: '完整推荐链接' })
|
|
referralLink: string;
|
|
|
|
@ApiProperty({ description: '钱包地址列表' })
|
|
walletAddresses: Array<{ chainType: string; address: string }>;
|
|
|
|
@ApiProperty()
|
|
kycStatus: string;
|
|
|
|
@ApiProperty()
|
|
status: string;
|
|
|
|
@ApiProperty()
|
|
registeredAt: Date;
|
|
}
|
|
|
|
export class ReferralValidationResponseDto {
|
|
@ApiProperty({ description: '推荐码是否有效' })
|
|
valid: boolean;
|
|
|
|
@ApiPropertyOptional()
|
|
referralCode?: string;
|
|
|
|
@ApiPropertyOptional({ description: '邀请人信息' })
|
|
inviterInfo?: {
|
|
accountSequence: number;
|
|
nickname: string;
|
|
avatarUrl: string | null;
|
|
};
|
|
|
|
@ApiPropertyOptional({ description: '错误信息' })
|
|
message?: string;
|
|
}
|
|
|
|
export class ReferralLinkResponseDto {
|
|
@ApiProperty()
|
|
linkId: string;
|
|
|
|
@ApiProperty()
|
|
referralCode: string;
|
|
|
|
@ApiProperty({ description: '短链' })
|
|
shortUrl: string;
|
|
|
|
@ApiProperty({ description: '完整链接' })
|
|
fullUrl: string;
|
|
|
|
@ApiProperty({ nullable: true })
|
|
channel: string | null;
|
|
|
|
@ApiProperty({ nullable: true })
|
|
campaignId: string | null;
|
|
|
|
@ApiProperty()
|
|
createdAt: Date;
|
|
}
|
|
|
|
export class InviteRecordDto {
|
|
@ApiProperty()
|
|
accountSequence: number;
|
|
|
|
@ApiProperty()
|
|
nickname: string;
|
|
|
|
@ApiProperty({ nullable: true })
|
|
avatarUrl: string | null;
|
|
|
|
@ApiProperty()
|
|
registeredAt: Date;
|
|
|
|
@ApiProperty({ description: '1=直接邀请, 2=间接邀请' })
|
|
level: number;
|
|
}
|
|
|
|
export class ReferralStatsResponseDto {
|
|
@ApiProperty()
|
|
referralCode: string;
|
|
|
|
@ApiProperty({ description: '总邀请人数' })
|
|
totalInvites: number;
|
|
|
|
@ApiProperty({ description: '直接邀请人数' })
|
|
directInvites: number;
|
|
|
|
@ApiProperty({ description: '间接邀请人数 (二级)' })
|
|
indirectInvites: number;
|
|
|
|
@ApiProperty({ description: '今日邀请' })
|
|
todayInvites: number;
|
|
|
|
@ApiProperty({ description: '本周邀请' })
|
|
thisWeekInvites: number;
|
|
|
|
@ApiProperty({ description: '本月邀请' })
|
|
thisMonthInvites: number;
|
|
|
|
@ApiProperty({ description: '最近邀请记录', type: [InviteRecordDto] })
|
|
recentInvites: InviteRecordDto[];
|
|
}
|