唯杰地图 logo唯杰地图
VJMAP
EN

description

vjcad/references/undo/description.md 5.5 KB167 行
原文

本文回答:操作描述 = 给撤销组附加一段文本,会显示在 撤销 / 重做 按钮 tooltip、历史下拉、命令行消息上。三种传值方式:① 字符串简写 '修改颜色';② 完整 UndoDescriptor { category, i18nKey?, resolvedText?, sourceCommand? };③ 不传 → 在命令上下文里自动从 Engine.editor.currentCommandName 推导。监听 CadEvents.UndoStackChanged 拿"下一步撤销/重做"的标签。

一、UndoDescriptor 结构

interface UndoDescriptor {
  i18nKey?: string;                              // 国际化 key
  params?: Record<string, string | number>;     // i18n 参数(预留)
  resolvedText?: string;                         // 已解析文本(最高优先级)
  category: 'edit' | 'view' | 'system';          // 必填,分类
  sourceCommand?: string;                        // 来源命令名
}

type UndoCategory = 'edit' | 'view' | 'system';

MCP 参考:vjcad/doc/undo/undo-redo.md。

二、三种传值

// 方式 1:字符串简写 = { category: 'edit', resolvedText: str }
Engine.startUndoRecord('修改颜色');

// 方式 2:i18n key(推荐多语言)
Engine.startUndoRecord({
  category: 'edit',
  i18nKey: 'undo.modify.color'
});

// 方式 3:明确来源命令
Engine.startUndoRecord({
  category: 'edit',
  sourceCommand: 'MYCMD'
});

// 方式 4:在命令上下文里不传 → 自动推导
class MyCommand {
  async main() {
    Engine.startUndoRecord();    // 自动 = 命令的 description / name
    try { /* ... */ } finally { Engine.endUndoRecord(); }
  }
}

MCP 参考:vjcad/doc/undo/undo-redo.md、vjcad/example/undo/04description.js。

三、解析优先级

显示 label 时按以下顺序查找:

  1. resolvedText — 直接使用
  2. i18nKey — 通过 t() 翻译
  3. sourceCommand — 命令名兜底
  4. 通用文案 — "撤销" / "重做"

MCP 参考:vjcad/doc/undo/undo-redo.md。

四、自动推导(命令上下文)

不传 description 时,系统按以下顺序推导:

  1. Engine.editor.currentCommandName
  2. 从 CommandRegistry 查找命令定义
  3. 用 CommandDefinition.description 或 CommandDefinition.name 当 resolvedText

适用:通过 editor.executerWithOp() 执行的命令(Editor 上是 executerWithOp/invokeCommandWithOp——executeCommand 是 PluginContext 的方法,不是 Editor 的);不适用:属性面板、对话框等非命令上下文(必须显式传 description)。

MCP 参考:vjcad/doc/undo/undo-redo.md。

五、查询撤销 / 重做历史

const u = Engine.undoManager;

const undoHistory = u.getUndoHistory();
console.log('共有', undoHistory.length, '步可撤销');

undoHistory.forEach((item, i) => {
  const desc = item.description;
  const label = desc?.resolvedText || desc?.i18nKey || '(无描述)';
  console.log(`${i + 1}. ${label} 分组=${item.isGroup}`);
});

// 重做历史
const redoHistory = u.getRedoHistory();

// 步数
const undoCount = u.getUndoCount();
const redoCount = u.getRedoCount();

// 最后一次撤销 / 重做的描述
console.log(u.lastUndoDescription);
console.log(u.lastRedoDescription);

UndoHistoryItem 结构:

interface UndoHistoryItem {
  description?: UndoDescriptor;
  index: number;        // 在历史栈中的索引
  isGroup: boolean;     // 是否为分组操作
}

MCP 参考:vjcad/doc/undo/undo-redo.md、vjcad/example/undo/04description.js。

六、按名称撤销 / 重做

u.undoSteps('绘制直线');       // 撤销到最近一次匹配(含),无匹配则不执行
u.redoSteps('绘制圆');        // 同理
u.undoSteps('不存在的');       // 返回 0,不执行
u.undoSteps(3, { silent: true });   // 静默:只抑制逐步的 UndoStackChanged(结束仍派发一次);UndoManager 本就不写命令行

MCP 参考:vjcad/example/undo/04description.js。

七、监听撤销栈变更(UI 必备)

import { CadEventManager, CadEvents } from 'vjcad';

CadEventManager.getInstance().on(CadEvents.UndoStackChanged, (args) => {
  console.log('撤销步数:', args.undoCount);
  console.log('重做步数:', args.redoCount);
  console.log('下一步撤销:', args.nextUndoLabel);
  console.log('下一步重做:', args.nextRedoLabel);
});

事件参数:

interface UndoStackChangedEventArgs {
  document: any;
  undoCount: number;
  redoCount: number;
  nextUndoLabel?: string;     // 已翻译
  nextRedoLabel?: string;     // 已翻译
}

MCP 参考:vjcad/doc/undo/undo-redo.md、vjcad/example/undo/04description.js。

八、操作分类(category)

值 用途 UI 展示
edit 编辑操作(绘图、改属性) 历史面板主列表
view 视图操作(缩放、平移、UCS) 历史面板折叠组
system 系统操作(预留) —

MCP 参考:vjcad/doc/undo/undo-redo.md。

反例

  • 不传 description 但又不在命令上下文(属性面板、对话框):UI 显示 "撤销" 兜底文案,看不出做了什么。
  • 用 i18nKey 但 i18n 字典里没注册:fallback 显示 key 本身(不友好)。
  • 把不可撤销的视图操作也挂 category: 'edit':会污染编辑历史面板。

参考(官方文档 MCP)

  • 文档:vjcad/doc/undo/undo-redo.md
  • 示例:vjcad/example/undo/04description.js