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>
232 lines
4.9 KiB
TypeScript
232 lines
4.9 KiB
TypeScript
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;
|
|
}
|
|
} |