Initial commit: Telegram Management System
Some checks failed
Deploy / deploy (push) Has been cancelled

Full-stack web application for Telegram management
- Frontend: Vue 3 + Vben Admin
- Backend: NestJS
- Features: User management, group broadcast, statistics

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
你的用户名
2025-11-04 15:37:50 +08:00
commit 237c7802e5
3674 changed files with 525172 additions and 0 deletions

View File

@@ -0,0 +1,232 @@
import {
Entity,
PrimaryGeneratedColumn,
Column,
CreateDateColumn,
UpdateDateColumn,
ManyToOne,
JoinColumn,
Index,
} from 'typeorm';
import { ApiProperty } from '@nestjs/swagger';
import { Task } from './task.entity';
export enum TaskExecutionStatus {
RUNNING = 'running',
SUCCESS = 'success',
FAILED = 'failed',
CANCELLED = 'cancelled',
TIMEOUT = 'timeout',
}
@Entity('task_executions')
@Index('idx_task_id', ['taskId'])
@Index('idx_status', ['status'])
@Index('idx_start_time', ['startTime'])
@Index('idx_duration', ['duration'])
export class TaskExecution {
@ApiProperty({ description: '执行记录ID' })
@PrimaryGeneratedColumn()
id: number;
@ApiProperty({ description: '任务ID' })
@Column({
type: 'int',
comment: '任务ID'
})
taskId: number;
@ApiProperty({ description: '执行批次号' })
@Column({
type: 'varchar',
length: 50,
nullable: true,
comment: '执行批次号'
})
batchId?: string;
@ApiProperty({ description: '执行节点' })
@Column({
type: 'varchar',
length: 100,
nullable: true,
comment: '执行节点标识'
})
nodeId?: string;
@ApiProperty({ description: '开始时间' })
@Column({
type: 'datetime',
comment: '开始时间'
})
startTime: Date;
@ApiProperty({ description: '结束时间' })
@Column({
type: 'datetime',
nullable: true,
comment: '结束时间'
})
endTime?: Date;
@ApiProperty({ description: '执行状态' })
@Column({
type: 'enum',
enum: TaskExecutionStatus,
comment: '执行状态',
})
status: TaskExecutionStatus;
@ApiProperty({ description: '执行结果' })
@Column({
type: 'json',
nullable: true,
comment: '执行结果'
})
result?: any;
@ApiProperty({ description: '错误信息' })
@Column({
type: 'text',
nullable: true,
comment: '错误信息'
})
error?: string;
@ApiProperty({ description: '错误堆栈' })
@Column({
type: 'text',
nullable: true,
comment: '错误堆栈信息'
})
errorStack?: string;
@ApiProperty({ description: '执行时长(秒)' })
@Column({
type: 'int',
nullable: true,
comment: '执行时长(秒)'
})
duration?: number;
@ApiProperty({ description: '处理记录数' })
@Column({
type: 'int',
default: 0,
comment: '处理记录数'
})
processedCount: number;
@ApiProperty({ description: '成功记录数' })
@Column({
type: 'int',
default: 0,
comment: '成功记录数'
})
successCount: number;
@ApiProperty({ description: '失败记录数' })
@Column({
type: 'int',
default: 0,
comment: '失败记录数'
})
failedCount: number;
@ApiProperty({ description: '跳过记录数' })
@Column({
type: 'int',
default: 0,
comment: '跳过记录数'
})
skippedCount: number;
@ApiProperty({ description: '执行进度' })
@Column({
type: 'decimal',
precision: 5,
scale: 2,
default: 0,
comment: '执行进度(0-100)'
})
progress: number;
@ApiProperty({ description: '内存使用(MB)' })
@Column({
type: 'decimal',
precision: 10,
scale: 2,
nullable: true,
comment: '内存使用(MB)'
})
memoryUsage?: number;
@ApiProperty({ description: 'CPU使用率(%)' })
@Column({
type: 'decimal',
precision: 5,
scale: 2,
nullable: true,
comment: 'CPU使用率(%)'
})
cpuUsage?: number;
@ApiProperty({ description: '执行日志' })
@Column({
type: 'text',
nullable: true,
comment: '执行日志'
})
logs?: string;
@ApiProperty({ description: '执行参数' })
@Column({
type: 'json',
nullable: true,
comment: '执行时的参数快照'
})
executionParams?: any;
@ApiProperty({ description: '执行环境信息' })
@Column({
type: 'json',
nullable: true,
comment: '执行环境信息'
})
environmentInfo?: any;
@ApiProperty({ description: '创建时间' })
@CreateDateColumn({ comment: '创建时间' })
createdAt: Date;
@ApiProperty({ description: '更新时间' })
@UpdateDateColumn({ comment: '更新时间' })
updatedAt: Date;
// 关联关系
@ManyToOne(() => Task)
@JoinColumn({ name: 'taskId' })
task: Task;
// 计算属性
get isCompleted(): boolean {
return [TaskExecutionStatus.SUCCESS, TaskExecutionStatus.FAILED, TaskExecutionStatus.CANCELLED].includes(this.status);
}
get isSuccessful(): boolean {
return this.status === TaskExecutionStatus.SUCCESS;
}
get executionDuration(): number {
if (!this.endTime || !this.startTime) return 0;
return Math.round((this.endTime.getTime() - this.startTime.getTime()) / 1000);
}
get successRate(): number {
return this.processedCount > 0 ? (this.successCount / this.processedCount) * 100 : 0;
}
get throughput(): number {
return this.duration > 0 ? this.processedCount / this.duration : 0;
}
}