204 lines
4.2 KiB
TypeScript
204 lines
4.2 KiB
TypeScript
import { signal, Signal } from '@preact/signals-core';
|
|
import type { Command, CommandLogEntry, CommandExecutionResult, StepResult, QueuedCommand } from './Command';
|
|
import { CommandStatus } from './Command';
|
|
|
|
/**
|
|
* 命令日志过滤器
|
|
*/
|
|
export interface CommandLogFilter {
|
|
commandId?: string;
|
|
success?: boolean;
|
|
startTime?: number;
|
|
endTime?: number;
|
|
}
|
|
|
|
/**
|
|
* 命令日志类
|
|
* 记录所有执行的命令及其结果
|
|
*/
|
|
export class CommandLog {
|
|
/** 日志条目信号 */
|
|
private entries: Signal<CommandLogEntry[]>;
|
|
|
|
/** 待执行队列 */
|
|
private queue: QueuedCommand[];
|
|
|
|
constructor() {
|
|
this.entries = signal<CommandLogEntry[]>([]);
|
|
this.queue = [];
|
|
}
|
|
|
|
/**
|
|
* 记录命令执行
|
|
*/
|
|
log(
|
|
command: Command,
|
|
result: CommandExecutionResult,
|
|
stepResults: StepResult[]
|
|
): void {
|
|
const entry: CommandLogEntry = {
|
|
timestamp: Date.now(),
|
|
commandId: command.id,
|
|
commandName: command.name,
|
|
result,
|
|
stepResults,
|
|
};
|
|
|
|
const current = this.entries.value;
|
|
this.entries.value = [...current, entry];
|
|
}
|
|
|
|
/**
|
|
* 获取所有日志条目
|
|
*/
|
|
getEntries(): CommandLogEntry[] {
|
|
return this.entries.value;
|
|
}
|
|
|
|
/**
|
|
* 获取日志信号
|
|
*/
|
|
getEntriesSignal(): Signal<CommandLogEntry[]> {
|
|
return this.entries;
|
|
}
|
|
|
|
/**
|
|
* 根据过滤器获取日志条目
|
|
*/
|
|
getFilteredEntries(filter: CommandLogFilter): CommandLogEntry[] {
|
|
return this.entries.value.filter((entry) => {
|
|
if (filter.commandId && entry.commandId !== filter.commandId) {
|
|
return false;
|
|
}
|
|
if (filter.success !== undefined && entry.result.success !== filter.success) {
|
|
return false;
|
|
}
|
|
if (filter.startTime && entry.timestamp < filter.startTime) {
|
|
return false;
|
|
}
|
|
if (filter.endTime && entry.timestamp > filter.endTime) {
|
|
return false;
|
|
}
|
|
return true;
|
|
});
|
|
}
|
|
|
|
/**
|
|
* 获取命令的执行历史
|
|
*/
|
|
getCommandHistory(commandId: string): CommandLogEntry[] {
|
|
return this.getFilteredEntries({ commandId });
|
|
}
|
|
|
|
/**
|
|
* 获取失败的命令
|
|
*/
|
|
getFailedCommands(): CommandLogEntry[] {
|
|
return this.getFilteredEntries({ success: false });
|
|
}
|
|
|
|
/**
|
|
* 获取成功的命令
|
|
*/
|
|
getSuccessfulCommands(): CommandLogEntry[] {
|
|
return this.getFilteredEntries({ success: true });
|
|
}
|
|
|
|
/**
|
|
* 清空日志
|
|
*/
|
|
clear(): void {
|
|
this.entries.value = [];
|
|
}
|
|
|
|
/**
|
|
* 导出日志为 JSON
|
|
*/
|
|
exportToJson(): string {
|
|
return JSON.stringify(this.entries.value, null, 2);
|
|
}
|
|
|
|
/**
|
|
* 获取日志条目数量
|
|
*/
|
|
getCount(): number {
|
|
return this.entries.value.length;
|
|
}
|
|
|
|
/**
|
|
* 获取最后一个日志条目
|
|
*/
|
|
getLastEntry(): CommandLogEntry | null {
|
|
const entries = this.entries.value;
|
|
return entries.length > 0 ? entries[entries.length - 1] : null;
|
|
}
|
|
|
|
// ========== 队列管理 ==========
|
|
|
|
/**
|
|
* 添加命令到队列
|
|
*/
|
|
enqueue(command: Command): QueuedCommand {
|
|
const queued: QueuedCommand = {
|
|
id: command.id,
|
|
command,
|
|
status: CommandStatus.Pending,
|
|
queuedAt: Date.now(),
|
|
};
|
|
this.queue.push(queued);
|
|
return queued;
|
|
}
|
|
|
|
/**
|
|
* 从队列中移除命令
|
|
*/
|
|
dequeue(): QueuedCommand | null {
|
|
if (this.queue.length === 0) {
|
|
return null;
|
|
}
|
|
return this.queue.shift() || null;
|
|
}
|
|
|
|
/**
|
|
* 获取队列中的所有命令
|
|
*/
|
|
getQueue(): QueuedCommand[] {
|
|
return [...this.queue];
|
|
}
|
|
|
|
/**
|
|
* 更新队列中命令的状态
|
|
*/
|
|
updateQueueStatus(commandId: string, status: CommandStatus, result?: CommandExecutionResult): void {
|
|
const index = this.queue.findIndex((q) => q.command.id === commandId);
|
|
if (index !== -1) {
|
|
this.queue[index].status = status;
|
|
if (status === CommandStatus.Completed || status === CommandStatus.Failed) {
|
|
this.queue[index].executedAt = Date.now();
|
|
this.queue[index].result = result;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 清空队列
|
|
*/
|
|
clearQueue(): void {
|
|
this.queue = [];
|
|
}
|
|
|
|
/**
|
|
* 获取队列长度
|
|
*/
|
|
getQueueLength(): number {
|
|
return this.queue.length;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 创建命令日志
|
|
*/
|
|
export function createCommandLog(): CommandLog {
|
|
return new CommandLog();
|
|
}
|