/** * 基础命令类 * 所有命令都应该继承这个类 */ export class Command { constructor(options = {}) { this.name = options.name || "未命名命令"; this.description = options.description || ""; this.undoable = options.undoable !== false; // 默认可撤销 this.timestamp = Date.now(); } /** * 执行命令 * @returns {*} 执行结果,可以是Promise */ execute() { throw new Error("子类必须实现execute方法"); } /** * 撤销命令 * @returns {*} 撤销结果,可以是Promise */ undo() { if (!this.undoable) { throw new Error("此命令不支持撤销"); } throw new Error("可撤销命令必须实现undo方法"); } /** * 获取命令信息 */ getInfo() { return { name: this.name, description: this.description, undoable: this.undoable, timestamp: this.timestamp, }; } } /** * 复合命令类 * 用于批量执行多个命令,替代事务系统 */ export class CompositeCommand extends Command { constructor(commands = [], options = {}) { super({ name: options.name || "复合命令", description: options.description || "批量执行多个命令", ...options, }); this.commands = Array.isArray(commands) ? commands : []; this.executedCommands = []; // 记录已执行的命令,用于撤销 this.isExecuting = false; } /** * 添加子命令 */ addCommand(command) { if (!command || typeof command.execute !== "function") { throw new Error("无效的命令对象"); } this.commands.push(command); return this; } /** * 批量添加子命令 */ addCommands(commands) { if (Array.isArray(commands)) { commands.forEach((cmd) => this.addCommand(cmd)); } return this; } /** * 执行所有子命令(串行执行) */ async execute() { if (this.isExecuting) { throw new Error("复合命令正在执行中"); } this.isExecuting = true; this.executedCommands = []; try { const results = []; // 串行执行所有子命令 for (const command of this.commands) { try { console.log(`📦 复合命令执行子命令: ${command.constructor.name}`); const result = command.execute(); // 如果是异步命令,等待完成 const finalResult = this._isPromise(result) ? await result : result; results.push(finalResult); this.executedCommands.push(command); console.log(`✅ 子命令执行成功: ${command.constructor.name}`); } catch (error) { console.error(`❌ 子命令执行失败: ${command.constructor.name}`, error); // 执行失败时,撤销已执行的命令 await this._rollbackExecutedCommands(); throw new Error(`复合命令执行失败:${error.message}`); } } this.isExecuting = false; console.log(`✅ 复合命令执行完成,共执行 ${results.length} 个子命令`); return results; } catch (error) { this.isExecuting = false; throw error; } } /** * 撤销所有已执行的子命令(逆序撤销) */ async undo() { if (this.isExecuting) { throw new Error("复合命令正在执行中,无法撤销"); } if (this.executedCommands.length === 0) { console.warn("没有已执行的子命令需要撤销"); return true; } console.log(`↩️ 开始撤销复合命令,共 ${this.executedCommands.length} 个子命令`); try { // 逆序撤销已执行的命令 const commands = [...this.executedCommands].reverse(); const results = []; for (const command of commands) { if (typeof command.undo === "function") { try { console.log(`↩️ 撤销子命令: ${command.constructor.name}`); const result = command.undo(); // 如果是异步撤销,等待完成 const finalResult = this._isPromise(result) ? await result : result; results.push(finalResult); console.log(`✅ 子命令撤销成功: ${command.constructor.name}`); } catch (error) { console.error(`❌ 子命令撤销失败: ${command.constructor.name}`, error); // 撤销失败不中断整个撤销过程,但要记录错误 } } else { console.warn(`⚠️ 子命令不支持撤销: ${command.constructor.name}`); } } this.executedCommands = []; console.log(`✅ 复合命令撤销完成`); return results; } catch (error) { console.error("❌ 复合命令撤销过程中发生错误:", error); throw error; } } /** * 回滚已执行的命令(内部使用) * @private */ async _rollbackExecutedCommands() { console.log(`🔄 开始回滚已执行的 ${this.executedCommands.length} 个子命令`); const commands = [...this.executedCommands].reverse(); for (const command of commands) { if (typeof command.undo === "function") { try { console.log(`🔄 回滚子命令: ${command.constructor.name}`); const result = command.undo(); if (this._isPromise(result)) { await result; } console.log(`✅ 子命令回滚成功: ${command.constructor.name}`); } catch (error) { console.error(`❌ 子命令回滚失败: ${command.constructor.name}`, error); // 回滚失败不中断整个回滚过程 } } } this.executedCommands = []; console.log(`✅ 回滚完成`); } /** * 检查返回值是否为Promise * @private */ _isPromise(value) { return ( value && typeof value === "object" && typeof value.then === "function" && typeof value.catch === "function" ); } /** * 获取复合命令信息 */ getInfo() { return { ...super.getInfo(), commandCount: this.commands.length, executedCount: this.executedCommands.length, isExecuting: this.isExecuting, subCommands: this.commands.map((cmd) => (cmd.getInfo ? cmd.getInfo() : cmd.constructor.name)), }; } } /** * 函数命令包装器 * 将普通函数包装为命令对象 */ export class FunctionCommand extends Command { constructor(executeFn, undoFn = null, options = {}) { super({ name: options.name || "函数命令", undoable: typeof undoFn === "function", ...options, }); if (typeof executeFn !== "function") { throw new Error("执行函数不能为空"); } this.executeFn = executeFn; this.undoFn = undoFn; this.executeResult = null; // 保存执行结果用于撤销 } async execute() { const result = this.executeFn(); this.executeResult = this._isPromise(result) ? await result : result; return this.executeResult; } async undo() { if (!this.undoFn) { throw new Error("此函数命令不支持撤销"); } const result = this.undoFn(this.executeResult); return this._isPromise(result) ? await result : result; } /** * 检查返回值是否为Promise * @private */ _isPromise(value) { return ( value && typeof value === "object" && typeof value.then === "function" && typeof value.catch === "function" ); } }