|  | @@ -0,0 +1,180 @@
 | 
	
		
			
				|  |  | +type FieldType = 'string' | 'number' | 'boolean' | 'object' | 'array' | 'any';
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +interface FieldSchema {
 | 
	
		
			
				|  |  | +  name: string;
 | 
	
		
			
				|  |  | +  type: FieldType;
 | 
	
		
			
				|  |  | +  description?: string;
 | 
	
		
			
				|  |  | +  required?: boolean;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +interface FlowTaskOptions {
 | 
	
		
			
				|  |  | +  title: string;
 | 
	
		
			
				|  |  | +  input?: FieldSchema[];
 | 
	
		
			
				|  |  | +  output?: FieldSchema[];
 | 
	
		
			
				|  |  | +  initialData?: Record<string, any>;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +export class FlowTask {
 | 
	
		
			
				|  |  | +  // 核心属性
 | 
	
		
			
				|  |  | +  readonly title: string;
 | 
	
		
			
				|  |  | +  protected data: Record<string, any> = {};
 | 
	
		
			
				|  |  | +  private _status: 'idle' | 'running' | 'success' | 'failed' = 'idle';
 | 
	
		
			
				|  |  | +  private _progress: number = 0;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  // 校验规则
 | 
	
		
			
				|  |  | +  private readonly inputSchema: FieldSchema[];
 | 
	
		
			
				|  |  | +  private readonly outputSchema: FieldSchema[];
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  // 添加执行时间记录
 | 
	
		
			
				|  |  | +  private _startTime?: Date;
 | 
	
		
			
				|  |  | +  private _endTime?: Date;
 | 
	
		
			
				|  |  | +  // 添加执行时间信息
 | 
	
		
			
				|  |  | +  get executionTime(): number {
 | 
	
		
			
				|  |  | +    if (!this._startTime) return 0;
 | 
	
		
			
				|  |  | +    const end = this._endTime || new Date();
 | 
	
		
			
				|  |  | +    return (end.getTime() - this._startTime.getTime()) / 1000;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  constructor(options: FlowTaskOptions) {
 | 
	
		
			
				|  |  | +    this.title = options.title;
 | 
	
		
			
				|  |  | +    this.data = options.initialData || {};
 | 
	
		
			
				|  |  | +    this.inputSchema = options.input || [];
 | 
	
		
			
				|  |  | +    this.outputSchema = options.output || [];
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  /************************************
 | 
	
		
			
				|  |  | +   *          核心执行流程              *
 | 
	
		
			
				|  |  | +   ************************************/
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  async execute(): Promise<void> {
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    try {
 | 
	
		
			
				|  |  | +      if (this._status !== 'idle') return;
 | 
	
		
			
				|  |  | +      this._startTime = new Date();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      this._status = 'running';
 | 
	
		
			
				|  |  | +      this.validateInput();  // 输入校验
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      this.beforeExecute();
 | 
	
		
			
				|  |  | +      await this.handle();   // 执行用户自定义逻辑
 | 
	
		
			
				|  |  | +      this.afterExecute();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      this.validateOutput(); // 输出校验
 | 
	
		
			
				|  |  | +      this._status = 'success';
 | 
	
		
			
				|  |  | +      this.onSuccess();
 | 
	
		
			
				|  |  | +    } catch (error) {
 | 
	
		
			
				|  |  | +      this._status = 'failed';
 | 
	
		
			
				|  |  | +      this.onFailure(error as Error);
 | 
	
		
			
				|  |  | +      throw error; // 重新抛出错误确保执行器能捕获
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    this._endTime = new Date();
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  /************************************
 | 
	
		
			
				|  |  | +   *          用户可覆盖方法            *
 | 
	
		
			
				|  |  | +   ************************************/
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  // 主处理函数(用户需要覆盖的核心方法)
 | 
	
		
			
				|  |  | +  protected async handle(): Promise<void> {
 | 
	
		
			
				|  |  | +    // 默认空实现,抛出错误提示需要实现
 | 
	
		
			
				|  |  | +    throw new Error('必须实现 handle() 方法');
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  // 生命周期钩子(可选覆盖)
 | 
	
		
			
				|  |  | +  protected beforeExecute(): void {}
 | 
	
		
			
				|  |  | +  protected afterExecute(): void {}
 | 
	
		
			
				|  |  | +  protected onProgress(progress: number): void {}
 | 
	
		
			
				|  |  | +  protected onSuccess(): void {}
 | 
	
		
			
				|  |  | +  protected onFailure(error: Error): void {}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  /************************************
 | 
	
		
			
				|  |  | +   *          数据校验系统              *
 | 
	
		
			
				|  |  | +   ************************************/
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  private validateInput(): void {
 | 
	
		
			
				|  |  | +    const errors: string[] = [];
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    this.inputSchema.forEach(field => {
 | 
	
		
			
				|  |  | +      const value = this.data[field.name];
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      // 检查必填字段
 | 
	
		
			
				|  |  | +      if (field.required && value === undefined) {
 | 
	
		
			
				|  |  | +        errors.push(`缺少必要字段:${field.name}`);
 | 
	
		
			
				|  |  | +        return;
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      // 类型校验
 | 
	
		
			
				|  |  | +      if (value !== undefined && !this.checkType(value, field.type)) {
 | 
	
		
			
				|  |  | +        errors.push(`${field.name} 类型错误,期望 ${field.type},实际 ${this.getType(value)}`);
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    });
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    if (errors.length > 0) {
 | 
	
		
			
				|  |  | +      throw new Error(`输入校验失败:\n${errors.join('\n')}`);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  private validateOutput(): void {
 | 
	
		
			
				|  |  | +    const missingFields = this.outputSchema
 | 
	
		
			
				|  |  | +      .filter(f => f.required)
 | 
	
		
			
				|  |  | +      .filter(f => !(f.name in this.data))
 | 
	
		
			
				|  |  | +      .map(f => f.name);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    if (missingFields.length > 0) {
 | 
	
		
			
				|  |  | +      throw new Error(`输出校验失败,缺少字段:${missingFields.join(', ')}`);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  /************************************
 | 
	
		
			
				|  |  | +   *          工具方法                *
 | 
	
		
			
				|  |  | +   ************************************/
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  // 类型检查
 | 
	
		
			
				|  |  | +  private checkType(value: any, expected: FieldType): boolean {
 | 
	
		
			
				|  |  | +    const actualType = this.getType(value);
 | 
	
		
			
				|  |  | +    return expected === 'any' || actualType === expected;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  private getType(value: any): FieldType {
 | 
	
		
			
				|  |  | +    if (Array.isArray(value)) return 'array';
 | 
	
		
			
				|  |  | +    if (value === null) return 'object';
 | 
	
		
			
				|  |  | +    return typeof value as FieldType;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  /************************************
 | 
	
		
			
				|  |  | +   *          公共接口                *
 | 
	
		
			
				|  |  | +   ************************************/
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  // 更新任务数据
 | 
	
		
			
				|  |  | +  updateData(key: string, value: any): this {
 | 
	
		
			
				|  |  | +    this.data[key] = value;
 | 
	
		
			
				|  |  | +    return this;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  // 获取任务数据
 | 
	
		
			
				|  |  | +  getData<T = any>(key: string): T {
 | 
	
		
			
				|  |  | +    return this.data[key];
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  // 进度更新
 | 
	
		
			
				|  |  | +  setProgress(value: number): void {
 | 
	
		
			
				|  |  | +    if (value < 0 || value > 1) return;
 | 
	
		
			
				|  |  | +    this._progress = value;
 | 
	
		
			
				|  |  | +    this.onProgress(value);
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  // 状态访问器
 | 
	
		
			
				|  |  | +  get progress(): number {
 | 
	
		
			
				|  |  | +    return this._progress;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  get status() {
 | 
	
		
			
				|  |  | +    return this._status;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  get output() {
 | 
	
		
			
				|  |  | +    return Object.fromEntries(
 | 
	
		
			
				|  |  | +      this.outputSchema.map(f => [f.name, this.data[f.name]])
 | 
	
		
			
				|  |  | +    );
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +}
 |