import { Entity, PrimaryGeneratedColumn, Column, CreateDateColumn, UpdateDateColumn, ManyToOne, JoinColumn, Index, } from 'typeorm'; import { ApiProperty } from '@nestjs/swagger'; import { SmsPlatform } from './sms-platform.entity'; import { TgAccount } from './tg-account.entity'; export enum SmsStatus { PENDING = 'pending', WAITING = 'waiting', RECEIVED = 'received', COMPLETE = 'complete', CANCEL = 'cancel', TIMEOUT = 'timeout', } @Entity('sms_records') @Index('idx_order_id', ['orderId']) @Index('idx_platform_code', ['platformCode']) @Index('idx_phone', ['phone']) @Index('idx_status', ['status']) @Index('idx_request_time', ['requestTime']) @Index('idx_tg_account_id', ['tgAccountId']) export class SmsRecord { @ApiProperty({ description: '记录ID' }) @PrimaryGeneratedColumn() id: number; @ApiProperty({ description: '订单ID' }) @Column({ type: 'varchar', length: 100, unique: true, comment: '订单ID' }) orderId: string; @ApiProperty({ description: '平台代码' }) @Column({ type: 'varchar', length: 50, comment: '平台代码' }) platformCode: string; @ApiProperty({ description: '手机号码' }) @Column({ type: 'varchar', length: 20, comment: '手机号码' }) phone: string; @ApiProperty({ description: '国家代码' }) @Column({ type: 'varchar', length: 10, nullable: true, comment: '国家代码' }) country?: string; @ApiProperty({ description: '服务类型' }) @Column({ type: 'varchar', length: 50, default: 'tg', comment: '服务类型' }) service: string; @ApiProperty({ description: '验证码' }) @Column({ type: 'varchar', length: 10, nullable: true, comment: '验证码' }) smsCode?: string; @ApiProperty({ description: '价格' }) @Column({ type: 'decimal', precision: 10, scale: 4, default: 0, comment: '价格' }) price: number; @ApiProperty({ description: '货币单位' }) @Column({ type: 'varchar', length: 10, default: 'USD', comment: '货币单位' }) currency: string; @ApiProperty({ description: '状态' }) @Column({ type: 'enum', enum: SmsStatus, default: SmsStatus.PENDING, comment: '状态', }) status: SmsStatus; @ApiProperty({ description: '请求时间' }) @Column({ type: 'datetime', default: () => 'CURRENT_TIMESTAMP', comment: '请求时间' }) requestTime: Date; @ApiProperty({ description: '接收时间' }) @Column({ type: 'datetime', nullable: true, comment: '接收时间' }) receiveTime?: Date; @ApiProperty({ description: '完成时间' }) @Column({ type: 'datetime', nullable: true, comment: '完成时间' }) completeTime?: Date; @ApiProperty({ description: '重试次数' }) @Column({ type: 'int', default: 0, comment: '重试次数' }) retryCount: number; @ApiProperty({ description: '错误信息' }) @Column({ type: 'text', nullable: true, comment: '错误信息' }) errorMessage?: string; @ApiProperty({ description: '关联TG账号ID' }) @Column({ type: 'int', nullable: true, comment: '关联TG账号ID' }) tgAccountId?: number; @ApiProperty({ description: '操作员' }) @Column({ type: 'varchar', length: 50, nullable: true, comment: '操作员' }) operator?: string; @ApiProperty({ description: '备注' }) @Column({ type: 'text', nullable: true, comment: '备注' }) remark?: string; @ApiProperty({ description: '创建时间' }) @CreateDateColumn({ comment: '创建时间' }) createdAt: Date; @ApiProperty({ description: '更新时间' }) @UpdateDateColumn({ comment: '更新时间' }) updatedAt: Date; // 关联关系 @ManyToOne(() => SmsPlatform, platform => platform.smsRecords) @JoinColumn({ name: 'platformCode', referencedColumnName: 'platformCode' }) platform: SmsPlatform; @ManyToOne(() => TgAccount) @JoinColumn({ name: 'tgAccountId' }) tgAccount?: TgAccount; // 计算属性 get isCompleted(): boolean { return this.status === SmsStatus.COMPLETE; } get isFailed(): boolean { return [SmsStatus.CANCEL, SmsStatus.TIMEOUT].includes(this.status); } get duration(): number { if (!this.completeTime) return 0; return this.completeTime.getTime() - this.requestTime.getTime(); } get isExpired(): boolean { if (this.status !== SmsStatus.WAITING) return false; const now = new Date(); const expireTime = new Date(this.requestTime.getTime() + 10 * 60 * 1000); // 10分钟超时 return now > expireTime; } }