Skip to content

Workbench 接入自检清单

接入 generator-workbench 后遇到问题,不知道从哪里查?

本文档按功能分类,列出了接入过程中最常见的问题。每个问题都配有一段可以直接复制给 AI 的检查指令——你只需把项目路径填进去,发给 AI,它会自己检查并修复。


功能一:发布模板(Publish as Template)

问题 1:点击 Publish as Template 按钮没有反应

把以下内容发给 AI:

请检查我的生成器项目,找出为什么点击 "Publish as Template" 按钮没有任何反应。

项目路径:<你的项目路径>

请按以下顺序排查:
1. 检查 generator-workbench 配置中 publishAsTemplate 是否被禁用(enablePublishAsTemplate 是否为 false 或未设置)
2. 检查 workbench.config 中是否缺少 getPublishAsTemplateOptions 方法
3. 检查 atomm-pro 弹窗组件是否已正确引入和注册
4. 打开浏览器控制台,检查点击按钮时是否有 JS 错误

对每一项:告诉我当前状态,如果有问题直接修复。

问题 2:发布弹窗弹出了,但模板预览图是空白/黑屏的

把以下内容发给 AI:

请检查我的生成器项目中 Publish as Template 的模板预览图问题。
发布弹窗可以正常打开,但预览图是空白或黑屏的。

项目路径:<你的项目路径>

请排查:
1. 找到 getPublishAsTemplateOptions 的实现,检查 generatorImage 字段是否有值
2. 如果 generatorImage 为空字符串或 undefined,找到生成器中画布/预览区的 DOM 元素(通常是 canvas 标签或带有特定 aria-label 的容器)
3. 检查是否有从这个 DOM 元素截图并转为 base64 PNG 的逻辑
4. 如果没有,帮我实现:从画布元素截图,转为 base64 PNG,在点击 Publish as Template 时传入 generatorImage 字段

修复后告诉我在哪里做了修改。

问题 3:发布的模板没有名称,或者名称显示错误

把以下内容发给 AI:

请检查我的生成器项目中 Publish as Template 的模板名称问题。

项目路径:<你的项目路径>

请排查:
1. 检查 workbench.config.title 是否有值——这个字段会作为模板名称的默认值
2. 检查 getPublishAsTemplateOptions 中 initialData.generatorInfo.generatorName 是否有值
3. 如果 title 为空或未设置,帮我在 workbench 初始化配置中设置一个合理的默认名称

修复后告诉我在哪里做了修改。

问题 4:发布弹窗里"当前模板"字段是空的(应该显示选中的模板名称)

适用场景:生成器有左侧模板预设列表,用户选中某个预设后发布,但弹窗里的 "generatorTag" 字段是空的。

把以下内容发给 AI:

请检查我的生成器项目中 Publish as Template 的模板标签问题。
生成器有模板预设列表,但发布弹窗中没有显示当前选中的模板名称。

项目路径:<你的项目路径>

请排查:
1. 找到生成器中切换模板预设的逻辑(通常是点击左侧模板列表的某一项)
2. 检查切换时是否有触发 runtime 的 select_template 事件,并传入 { name: '<模板名称>' }
3. 如果没有,帮我在模板切换的地方加上:runtime.notify('select_template', { name: template.name })
4. 确认 generator-workbench 会将这个 name 作为 generatorTag 传入发布弹窗

修复后告诉我在哪里做了修改。

问题 5:发布的模板用 Customize 恢复后,画布状态不对

发布了模板,用 Customize 进入生成器后,画布显示的内容和发布时不一样,或者出现一些奇怪的 UI 状态。

把以下内容发给 AI:

请检查我的生成器项目中 Publish as Template 的模板数据问题。
发布的模板用 Customize 恢复后,画布状态和发布时不一致。

项目路径:<你的项目路径>

请排查:
1. 找到 getPublishAsTemplateOptions 中 template 字段的构建逻辑
2. 检查 template 数据中是否混入了 UI 状态(比如:面板是否展开、当前选中的 tab、滚动位置等)
3. 模板数据应该只包含设计参数(params)和元数据(meta),不能包含 UI 展示状态
4. 如果有 UI 状态混入,帮我把 template 数据的构建逻辑修改为只保留设计相关字段

修复后告诉我哪些字段被移除了。

功能二:云保存(Cloud Save)

问题 6:云保存记录列表里没有缩略图

把以下内容发给 AI:

请检查我的生成器项目中云保存封面图的问题。
保存的云记录在历史列表中没有缩略图(封面图为空白)。

项目路径:<你的项目路径>

请排查:
1. 检查 workbench.config 中是否有 getCloudSaveOptions 方法
2. 如果有,检查它返回的 cover 字段是否有值(应该是 base64 data URL 格式的图片)
3. 如果 cover 为空,检查生成器中是否有监听 runtime state-change 事件、在状态变化时自动截图画布的逻辑
4. 如果没有,帮我实现:
   - 在 runtime state-change 时,截取画布当前状态,生成 400x225 的 base64 PNG
   - 将截图结果缓存
   - 在 getCloudSaveOptions 中返回这个缓存值

修复后告诉我在哪里做了修改。

问题 7:用户修改画布内容后,没有触发自动保存

把以下内容发给 AI:

请检查我的生成器项目中云保存自动触发的问题。
用户操作画布后,没有自动触发云保存。

项目路径:<你的项目路径>

请排查:
1. 检查 workbench.config 中 autoSave 或 enableAutoSave 是否开启
2. 检查生成器 runtime 是否在状态变化时触发了 state-change 事件(runtime.notify('state-change', ...))
3. 如果 state-change 事件没有触发,找到画布状态更新的地方,确认是否调用了 runtime.notify
4. 对每一项告诉我当前状态,如果有问题直接修复

功能三:模板页面适配(Embed 模式)

问题 8:模板页面里,生成器的左侧模板列表没有隐藏

发布的模板在 atomm 模板页面打开后,生成器的左侧模板预设列表仍然可见,影响模板展示效果。

把以下内容发给 AI:

请检查我的生成器项目在模板页面(embed 模式)下的适配问题。
生成器以 ?mode=embed 嵌入模板页面时,左侧的模板预设列表/sidebar 没有被隐藏。

项目路径:<你的项目路径>

请排查:
1. 检查生成器是否有逻辑检测当前是否为 embed 模式(通过 URL 参数 ?mode=embed 或 workbench 的 embed-mode-start 命令)
2. 检查在 embed 模式下,左侧模板列表是否有条件渲染逻辑(比如 v-if="!isEmbedMode" 或 display: none)
3. 如果没有,帮我实现:
   - 检测 embed 模式(从 URL 读取 mode=embed 参数)
   - 在 embed 模式下隐藏左侧模板列表/sidebar

修复后告诉我在哪里做了修改。

问题 9:模板页面在手机上显示混乱,不只显示画布

把以下内容发给 AI:

请检查我的生成器项目在模板页面移动端下的适配问题。
在手机上打开模板页面,生成器显示混乱,不只是画布内容,还有工具栏/参数面板等多余的元素。

项目路径:<你的项目路径>

请排查:
1. 检查生成器是否有 embed 模式的检测逻辑
2. 检查在 embed 模式 + 移动端视口(≤768px)下,是否有隐藏参数面板、工具栏等次要 UI 的逻辑
3. 如果没有,帮我实现:
   - 检测 embed 模式
   - 在 embed 模式下,添加移动端响应式适配:隐藏参数面板和工具栏,让画布占满屏幕
   - 使用 CSS media query 或运行时判断都可以

修复后告诉我在哪里做了修改。

问题 10:模板页面打开后,画布内容是默认状态而不是模板内容

模板页面应该展示发布时的模板状态,但打开后画布显示的是生成器的默认初始状态。

把以下内容发给 AI:

请检查我的生成器项目在模板页面(embed 模式)下的模板数据加载问题。
打开模板页面后,画布显示的是生成器默认状态,而不是发布的模板内容。

项目路径:<你的项目路径>

请排查:
1. 检查 generator-workbench 在 embed 模式下是否会通过 bridge 将模板数据传给 runtime(通过 dispatchWorkbenchCommand 发送 template 数据)
2. 检查 runtime 的 dispatchWorkbenchCommand 是否实现了接收 template 数据并应用到画布的逻辑
3. 如果 dispatchWorkbenchCommand 未实现或没有处理 template 命令,帮我实现:
   - 监听 workbench 发来的包含模板数据的命令
   - 将模板数据(defaults.params 和 defaults.meta)应用到画布

修复后告诉我在哪里做了修改。

功能四:Customize 流程

问题 11:点击 Customize 跳转到生成器后,画布是默认状态

用户在模板页面点击 Customize,跳转到生成器后,画布没有恢复模板内容,显示的是默认初始状态。

把以下内容发给 AI:

请检查我的生成器项目的 Customize 流程问题。
用户从模板页面点击 Customize 跳转过来,URL 中带有 templateId 参数,但画布显示的是默认状态而不是模板内容。

项目路径:<你的项目路径>

请排查:
1. 检查生成器初始化代码中是否有读取 URL 参数 templateId 的逻辑
2. 如果有,检查是否调用了 sdk.template.get(templateId) 获取模板数据
3. 如果有获取数据,检查是否将模板的 defaults.params 和 defaults.meta 应用到了画布
4. 如果以上任一步骤缺失,帮我按正确顺序实现完整的模板恢复流程:
   读取 templateId → 获取模板数据 → 应用到画布

修复后告诉我在哪里做了修改。

问题 12:Customize 恢复模板后,再次发布时数据变了

用户 Customize 后修改了内容,再次点击 Publish as Template,但发布的模板数据和预期不符。

把以下内容发给 AI:

请检查我的生成器项目的 Customize 后再次发布的问题。
用户 Customize 并修改后,再次发布时模板数据不正确。

项目路径:<你的项目路径>

请排查:
1. 检查 getPublishAsTemplateOptions 中 template 字段的构建方式——它是否从 runtime 当前状态实时获取,而不是缓存了 Customize 时传入的旧数据
2. 检查模板恢复后,runtime 的状态是否正确更新(getState() 返回的是最新状态)
3. 对每一项告诉我当前状态,如果有问题直接修复

综合检查

如果你不确定具体是哪个功能有问题,可以让 AI 做一次全面扫描:

请对这个已接入 generator-workbench 的生成器项目做一次全面的接入自检。

项目路径:<你的项目路径>

请按以下四个功能模块逐一检查,并输出状态表:

**发布模板(Publish as Template)**
- Publish as Template 按钮是否可以正常触发
- generatorImage(画布截图)是否已实现
- generatorTag(模板名称标签)是否通过 select_template 事件传递
- workbench.config.title 是否已设置
- template 数据是否排除了 UI 状态

**云保存(Cloud Save)**
- getCloudSaveOptions 中 cover 封面图是否已实现
- state-change 事件是否正常触发自动保存

**Embed 模式适配**
- embed 模式检测是否已实现
- embed 模式下模板列表/sidebar 是否隐藏
- embed 模式下移动端是否适配

**Customize 流程**
- 初始化时是否读取 templateId 参数
- 是否调用 sdk.template.get 获取模板数据
- 是否将模板数据恢复到画布

输出格式:
| 功能 | 检查项 | 状态 | 备注 |
|------|--------|------|------|

状态:✅ 已实现 · ❌ 缺失 · ⚠️ 部分实现

对于所有 ❌ 和 ⚠️ 的项,逐一修复后重新输出状态表。

功能五:项目配置(config.json 与 appKey)

问题 13:上传到 CMS 后,没有识别 code / 没有回填 code

上传生成器到 CMS 后,CMS 无法识别或回填生成器的 code(即 appKey)。常见原因是项目中 appKey 被分散硬编码在各处,而不是统一从根目录的 config.json 读取。

把以下内容发给 AI:

请检查我的生成器项目中 appKey 的配置方式,确认是否符合 config.json 规范。
上传到 CMS 后,没有识别到 code 或无法回填 code。

项目路径:<你的项目路径>

请排查:
1. 检查项目根目录下是否存在 config.json 文件,且文件中包含 appKey 字段,例如:
   {
     "appKey": "your-generator-key"
   }
2. 搜索项目中所有出现 appKey 字符串值(非变量引用)的地方,检查是否有 appKey 被硬编码在业务模块、JS 文件、HTML 文件中,而不是从 config.json 读取
3. 检查 GeneratorSDK.init() 调用处,appKey 的值是否来自 config.json,而不是一个写死的字符串
4. 检查 workbench.config、getPublishAsTemplateOptions 等 workbench 配置中用到 appKey 的地方,是否也统一从 config.json 读取

如果发现以下问题,请帮我修复:
- 项目根目录没有 config.json,帮我创建,把 appKey 放进去
- 有 config.json 但 appKey 字段不在里面,帮我补充
- 业务代码中存在硬编码的 appKey 字符串,帮我统一改为从 config.json 读取
- SDK 初始化时 appKey 不是来自 config.json,帮我修改读取方式

修复后告诉我哪些文件做了修改,以及 config.json 的最终内容。

功能六:环境配置

问题 14:发布后接口请求打到了错误的环境,或 atomm-pro 弹窗行为不对

生成器发布后,接口请求打到了测试服而非正式服,或者 atomm-pro 弹窗的路由、语言、功能表现和预期不符(比如国内版出现了本不应显示的邀请入口)。

把以下内容发给 AI:

请检查我的生成器项目中的环境配置,确认 SDK env 和 workbench 环境是否正确。

项目路径:<你的项目路径>

环境配置说明(供参考):
- Generator Workbench 的环境分两层:
  1. SDK 层:GeneratorSDK.init({ env }) —— 控制所有平台 API 的 base URL 和 Passport 登录地域
  2. Shell 层:workbench.config.atommProEnv —— 控制 workbench 壳层行为、社区模板接口路由、atomm-pro 弹窗上下文
- 正确做法:env 只在 SDK 中设置一次,执行 workbench.sdk = sdk 后,shell 层会自动从 sdk.getEnv() 派生 atommProEnv,不需要重复设置
- 支持的 env 取值:
  · prod:正式服(美国),API: https://api.xtool.com
  · prod_cn:正式服(中国),API: https://api.makeblock.com
  · pre:预发布环境
  · test:测试环境
  · dev:开发环境

- prod_cn 特殊行为(自动生效,无需手动配置):
  · 隐藏邀请/Earn Credits 入口
  · 隐藏 Publish as Template 入口
  · URL 中无 ?lang= 参数时,默认语言为 zh 而非 en

请排查:
1. 找到 GeneratorSDK.init() 的调用,检查 env 参数当前是什么值
2. 检查是否根据实际运行环境动态切换 env(比如本地用 dev/test,线上用 prod 或 prod_cn)
3. 检查 workbench.config 中是否手动设置了 atommProEnv——如果有,且与 SDK env 不一致,workbench 会打印警告并以 SDK env 为准;建议删除手动设置,改为依赖自动同步
4. 如果生成器需要区分国内/国外版本,检查 env 是否正确区分了 prod(美国)和 prod_cn(中国)

如果发现问题,请帮我修复:
- env 写死为某个值时,帮我改为根据环境变量动态读取
- 手动设置了 atommProEnv 时,如果与 SDK env 一致,帮我删除冗余配置;如果不一致,帮我找出哪个是正确的并统一

修复后告诉我在哪里做了修改,以及最终的 env 配置逻辑。

功能七:多语言配置

问题 15:workbench 顶栏文字是英文,但生成器应该显示中文(或其他语言)

workbench 的顶栏按钮、弹窗文案始终显示英文,没有根据用户语言切换;或者多语言切换逻辑和 runtime 内部的语言不同步。

把以下内容发给 AI:

请检查我的生成器项目中 workbench 的多语言配置,确认语言读取方式和显示语言是否正确。

项目路径:<你的项目路径>

多语言配置说明(供参考):
- workbench shell 的语言通过 URL 中的 ?lang= 参数读取,例如 ?lang=zh、?lang=en
- 当 URL 中没有 ?lang= 参数时,默认显示英文(en)
- 例外情况:当 SDK env 为 prod_cn 时,无 ?lang= 参数默认显示中文(zh)
- 通过 workbench.config.atommProLocale 可手动指定语言,覆盖 URL 参数的自动读取结果
- workbench 支持的语言列表:
  zh(简体中文)、en(English)、zh-hant(繁體中文)、de(Deutsch)、
  es(Español)、fr(Français)、it(Italiano)、ja(日本語)、
  ko(한국어)、ru(Русский)、uk(Українська)、th(ไทย)、
  cs(Čeština)、vi(Tiếng Việt)、id(Bahasa Indonesia)等

请排查:
1. 检查当前生成器 URL 是否通过 ?lang= 参数传入语言,还是依赖其他方式(比如 localStorage、路由参数)
2. 检查 workbench.config 中是否有 atommProLocale 字段,以及它的值是什么
3. 如果 runtime 内部有自己的多语言系统(比如 i18n 库),检查它读取语言的方式和 workbench 是否一致——两者都应从同一个来源(优先 ?lang= URL 参数)读取,避免 workbench 显示中文但 runtime 内部显示英文(或反过来)
4. 如果生成器需要支持 prod_cn(中国正式环境),检查 runtime 内部语言逻辑是否也实现了:当 env 为 prod_cn 且 URL 中无 ?lang= 参数时,默认使用 zh

如果发现问题,请帮我修复:
- workbench 显示语言和 runtime 不同步时,帮我统一两者的语言读取来源
- 缺少 prod_cn 默认语言兜底时,帮我补充该逻辑
- 想手动固定某个语言时,帮我在 workbench.config 中设置 atommProLocale

修复后告诉我在哪里做了修改,以及最终的语言读取逻辑。

综合检查

如果你不确定哪个功能有问题,可以让 AI 做一次全面扫描:

请对这个已接入 generator-workbench 的生成器项目做一次全面的接入自检。

项目路径:<你的项目路径>

请按以下七个功能模块逐一检查,并输出状态表:

**发布模板(Publish as Template)**
- Publish as Template 按钮是否可以正常触发
- generatorImage(画布截图)是否已实现
- generatorTag(模板名称标签)是否通过 select_template 事件传递
- workbench.config.title 是否已设置
- template 数据是否排除了 UI 状态

**云保存(Cloud Save)**
- getCloudSaveOptions 中 cover 封面图是否已实现
- state-change 事件是否正常触发自动保存

**Embed 模式适配**
- embed 模式检测是否已实现
- embed 模式下模板列表/sidebar 是否隐藏
- embed 模式下移动端是否适配

**Customize 流程**
- 初始化时是否读取 templateId 参数
- 是否调用 sdk.template.get 获取模板数据
- 是否将模板数据恢复到画布

**项目配置(config.json 与 appKey)**
- 根目录是否有 config.json 且包含 appKey 字段
- 项目中 appKey 是否统一从 config.json 读取,无硬编码

**环境配置**
- SDK env 参数是否与实际运行环境匹配
- workbench 是否依赖 SDK 自动同步环境,未手动设置冲突的 atommProEnv

**多语言配置**
- workbench 语言读取来源是否正确(?lang= URL 参数优先)
- runtime 内部语言是否与 workbench 保持同步
- prod_cn 环境下是否有中文兜底逻辑

输出格式:
| 功能 | 检查项 | 状态 | 备注 |
|------|--------|------|------|

状态:✅ 已实现 · ❌ 缺失 · ⚠️ 部分实现

对于所有 ❌ 和 ⚠️ 的项,逐一修复后重新输出状态表。

功能八:调试面板(?debug=true)错误快速修复

在生成器 URL 末尾加上 ?debug=true 后,面板中每个 ❌/⚠️ 检查项下方都有「📋 复制 AI 修复提示词」按钮,点击即可将对应提示词复制到剪贴板,直接粘贴给 AI 处理。

以下是每类错误的完整修复提示词,方便你在无法打开调试面板时直接使用。


接入检查类

这些错误出现在调试面板的「接入检查」区块。

问题 A1:workbench.sdk 未绑定(❌)

面板显示workbench.sdk 已绑定到元素

我的生成器接入了 generator-workbench,调试面板(?debug=true)显示 workbench.sdk 未绑定,导致登录、积分、导出等平台能力全部失效。

请帮我检查生成器的入口文件(通常是 index.html 或 main.js/index.js),找到初始化和挂载代码,确认以下问题是否存在:

1. 是否有 workbench.sdk = sdk 这行赋值?如果没有,请添加。
2. workbench.sdk = sdk 是否在 workbench.mount() 之前执行?如果在 mount() 之后,请调整顺序。
3. sdk 赋值是否放在了异步回调(如 setTimeout、Promise.then、async/await)里,导致 mount() 先执行?

正确的初始化顺序(请对照我的代码检查并修复):

const sdk = GeneratorSDK.init({ appKey: '...', env: 'prod' })
const runtime = new MyRuntime()
const workbench = document.getElementById('workbench')

workbench.sdk = sdk        // 必须在 mount 之前赋值
workbench.runtime = runtime
workbench.config = { ... }

await workbench.mount()    // 最后调用

请直接修改我的代码,确保以上顺序正确。

问题 A2:workbench.runtime 未绑定(❌)

面板显示workbench.runtime 已绑定到元素

我的生成器接入了 generator-workbench,调试面板(?debug=true)显示 workbench.runtime 未绑定,导致生成器功能全部无法使用。

请帮我检查生成器的入口文件(通常是 index.html 或 main.js/index.js),找到初始化代码,确认以下问题是否存在:

1. 是否有 workbench.runtime = runtime 这行赋值?如果没有,请添加。
2. runtime 对象是否已正确创建(如 new MyRuntime() 或导出的 runtime 实例)?
3. workbench.runtime = runtime 是否在 workbench.mount() 之前执行?

正确的初始化顺序:

workbench.sdk = sdk
workbench.runtime = runtime   // 确保这行存在且在 mount 之前
workbench.config = { ... }

await workbench.mount()       // 最后调用

同时,请确认 runtime 对象实现了标准接口:mount、getState、setState、getPanelSchema、subscribe。

问题 A3:atommProEnv 未配置(❌)

面板显示workbench.config.atommProEnv
症状:点击头像没有反应、无法登录。

我的生成器接入了 generator-workbench,调试面板(?debug=true)显示 atommProEnv 未配置,导致点击头像没有反应、无法登录。

请帮我检查环境配置。优先确认 GeneratorSDK.init({ env }) 使用了正确环境,并且 sdk 已在 workbench.mount() 前赋值:

const sdk = GeneratorSDK.init({
  appKey: config.appKey,
  env: config.env,
})

workbench.sdk = sdk

如果当前调试面板版本仍要求显式字段,请在 workbench.config 中补充同一个环境来源:

workbench.config = {
  title: '我的生成器',
  atommProEnv: config.env,     // 与 GeneratorSDK.init({ env }) 保持一致
  atommProDomain: 'atomm',     // 同时也需要这个字段
  // ...其他已有配置保持不变
}

注意:workbench.sdk、workbench.config 的赋值必须在 workbench.mount() 调用之前完成。请检查代码顺序是否正确。

问题 A4:atommProDomain 未配置(❌)

面板显示workbench.config.atommProDomain
症状:点击头像没有反应、无法登录。

我的生成器接入了 generator-workbench,调试面板(?debug=true)显示 atommProDomain 未配置,导致点击头像没有反应、无法登录。

请帮我在 workbench.config 中添加 atommProDomain 字段:

workbench.config = {
  title: '我的生成器',
  atommProEnv: 'prod',
  atommProDomain: 'atomm',     // 必须添加这行
  // ...其他已有配置保持不变
}

请确认 workbench.config 赋值在 workbench.mount() 之前完成。

问题 A5:window.GENERATOR_RUNTIME 未暴露(❌)

面板显示window.__GENERATOR_RUNTIME__ 已暴露

我的生成器接入了 generator-workbench,调试面板(?debug=true)显示 window.__GENERATOR_RUNTIME__ 未暴露。

这是平台的标准约定,主站页面和调试工具会通过这个全局变量访问 runtime。

请帮我在入口文件中,runtime 初始化完成后,添加以下这行代码:

window.__GENERATOR_RUNTIME__ = runtime

通常放在初始化代码的末尾比较合适:

const runtime = new MyRuntime()
window.__GENERATOR_RUNTIME__ = runtime   // 添加这行

workbench.runtime = runtime
await workbench.mount()

请直接修改我的代码加上这行。

问题 A6:runtime 接口不合规(❌)

面板显示runtime 接口合规 ❌,并列出缺少的方法名。
症状:多种功能异常。

我的生成器接入了 generator-workbench,调试面板(?debug=true)显示 runtime 缺少必要的接口方法,导致多种功能异常。

请帮我检查 runtime 对象的实现文件(通常是 runtime.js、MyRuntime.js 或类似文件),确保以下所有方法都存在且是函数类型:

class MyRuntime {
  // 必须实现:将生成器挂载到指定 DOM 容器
  async mount(options) {
    return { unmount: () => { /* 清理逻辑 */ } }
  }

  // 必须实现:返回当前生成器状态(纯数据,可 JSON 序列化)
  getState() {
    return { /* 当前状态 */ }
  }

  // 必须实现:用给定状态恢复生成器
  setState(nextState) { }

  // 必须实现:返回参数面板的字段定义
  getPanelSchema() {
    return { fields: [] }
  }

  // 必须实现:注册事件监听,返回取消订阅函数
  subscribe(listener) {
    this._listeners.push(listener)
    return () => {
      this._listeners = this._listeners.filter(l => l !== listener)
    }
  }
}

请对照我现有的 runtime 代码,补全缺少的方法。

问题 A7:export 错误实现在 runtime 上(⚠️)

面板显示export 错误地实现在 runtime 对象上 ⚠️
症状:导出按钮无效或行为异常。

我的生成器接入了 generator-workbench,调试面板(?debug=true)显示 export 方法被错误地放在了 runtime 对象上。

正确做法是使用 sdk.export.register() 注册导出处理器,而不是在 runtime 上实现 export 方法。

请帮我:
1. 从 runtime 类或对象上删除 export() 方法
2. 在初始化代码中(sdk 初始化后)添加 sdk.export.register() 调用

// 正确方式:通过 sdk.export.register() 注册
sdk.export.register({
  type: 'svg',
  label: '导出 SVG',
  handler: async () => {
    const svgContent = runtime.exportToSVG()
    return {
      blob: new Blob([svgContent], { type: 'image/svg+xml' }),
      filename: 'design.svg',
    }
  },
})

请直接修改我的代码:删除 runtime 上的 export 方法,改为 sdk.export.register()。

问题 A8:getCloudSaveOptions 未实现(⚠️)

面板显示getCloudSaveOptions(cloud profile) ⚠️
症状:云保存时 title 显示为 undefined。

我的生成器接入了 generator-workbench(cloud profile),调试面板(?debug=true)显示 getCloudSaveOptions 未实现,导致云保存时 title 显示为 undefined。

请帮我在 workbench.config 中添加 getCloudSaveOptions 方法:

workbench.config = {
  // ...其他已有配置保持不变
  getCloudSaveOptions: ({ state }) => ({
    title: '我的作品',
    snapshot: state,
  }),
}

如果希望标题能动态反映当前内容,可以从 state 中读取:

getCloudSaveOptions: ({ state }) => ({
  title: state.projectName || state.title || '未命名作品',
  snapshot: state,
}),

请对照我的 runtime getState() 返回的数据结构,选择合适的字段作为 title。

问题 A9:templateEnabled 未设置(⚠️)

面板显示templateEnabled(workbench-template profile) ⚠️
症状:「Publish as Template」按钮不显示。

我的生成器接入了 generator-workbench,调试面板(?debug=true)显示 templateEnabled 未设置,导致 "Publish as Template" 按钮不显示。

请帮我在 workbench.config 中添加 templateEnabled: true:

workbench.config = {
  // ...其他已有配置保持不变
  templateEnabled: true,    // 添加这行,让发布模板按钮显示出来
}

注意:只有在确实需要 Publish as Template 功能时才设置这个字段。如果你的生成器不需要发布模板功能,可以忽略此项。

问题 A10:params_change.cover 未收到(⚠️)

面板显示params_change.cover(等待事件中…) ⚠️
症状:发布模板时无法获取画布预览图(workbench 有兜底,但质量较低)。

我的生成器接入了 generator-workbench(workbench-template profile),调试面板(?debug=true)显示尚未收到含 cover 字段的 params_change 事件,这可能导致发布模板时无法获取画布预览图。

请帮我在 runtime 的 subscribe 方法实现中,当画布状态发生变化时,emit 含 cover 字段的 params_change 事件。

请先找到 runtime 的 subscribe 方法,然后按如下方式修改:

subscribe(listener) {
  const emitParamsChange = () => {
    const canvas = document.querySelector('canvas')
    const cover = canvas ? canvas.toDataURL('image/png') : ''

    listener({
      type: 'params_change',
      data: { cover },
    })
  }

  // 在状态变化时调用 emitParamsChange
  // 根据你的具体实现,把 emitParamsChange() 加入到状态变化的回调里

  return () => { /* 清理订阅 */ }
}

如果画布不是 <canvas> 元素(如 SVG 或 div),也可以使用 html2canvas 截图:

import html2canvas from 'html2canvas'
const canvasEl = await html2canvas(document.getElementById('preview'))
const cover = canvasEl.toDataURL('image/png')

请直接修改我的 runtime subscribe 方法,加入 params_change 事件的 emit 逻辑。

问题 A11:template_publish_media_change 未收到(⚠️)

面板显示template_publish_media_change(等待事件中…) ⚠️
说明:这是可选优化项,workbench 已有兜底截图机制,不实现不影响发布功能,只影响预览图质量。

我的生成器接入了 generator-workbench(workbench-template profile),调试面板(?debug=true)显示 template_publish_media_change 事件未携带 generatorImage,将使用 workbench 的兜底截图(质量可能较低)。

如果想提供更高质量的发布预览图,请帮我在 runtime 的 subscribe 方法中 emit template_publish_media_change 事件:

subscribe(listener) {
  const emitPublishMedia = () => {
    const canvas = document.querySelector('canvas')
    if (!canvas) return

    listener({
      type: 'template_publish_media_change',
      data: {
        generatorImage: canvas.toDataURL('image/png'),
      },
    })
  }

  // 在状态变化时调用 emitPublishMedia
  return () => { /* 清理 */ }
}

如果已经实现了 params_change 事件并携带了 cover 字段,workbench 会自动使用该截图作为兜底,无需额外实现此事件。

发布参数字段类

这些错误出现在调试面板的「📤 发布参数」区块,在点击「Publish as Template」按钮后显示。

问题 B1:generatorImage 为空(❌)

面板显示generatorImage(空)
症状:发布的模板没有预览图。

我的生成器接入了 generator-workbench,点击 "Publish as Template" 后,调试面板(?debug=true)的"发布参数"区显示 generatorImage 字段为空,这会导致发布的模板没有预览图。

workbench 会按以下优先级自动尝试获取 generatorImage,请帮我检查哪一步失败了并修复:

优先级 ①(最优):runtime emit template_publish_media_change 事件
listener({
  type: 'template_publish_media_change',
  data: {
    generatorImage: canvas.toDataURL('image/png'),
  },
})

优先级 ②:runtime emit params_change 事件并携带 cover 字段
listener({
  type: 'params_change',
  data: {
    cover: canvas.toDataURL('image/png'),
  },
})

优先级 ③(兜底):在画布 DOM 上加 data-generator-canvas 属性
<canvas id="myCanvas" data-generator-canvas></canvas>

请先查看我的 runtime subscribe 实现,判断以上哪条路径可以最方便地添加,然后帮我实现。如果画布不是 <canvas> 元素,可以使用 html2canvas:

import html2canvas from 'html2canvas'
const snap = await html2canvas(document.getElementById('preview-area'))
const cover = snap.toDataURL('image/png')

问题 B2:generatorTag 为空(❌)

面板显示generatorTag(空)
说明:生成器没有模板预设选择功能时,此项为空是正常的,可忽略。

我的生成器接入了 generator-workbench,点击 "Publish as Template" 后,调试面板(?debug=true)的"发布参数"区显示 generatorTag 字段为空。generatorTag 是发布时记录"当前选中了哪个模板预设"的标识,为空时模板将没有名称标签。

如果我的生成器有模板预设选择功能(左侧有 Template Presets 列表),请帮我在用户点击某个模板预设时,emit select_template 事件:

function onTemplateSelect(templateName) {
  // ...更新界面逻辑

  listeners.forEach(listener => {
    listener({
      type: 'select_template',
      data: {
        name: templateName,   // 模板名称,如 "Spring Sale"
        category: '',
      },
    })
  })
}

如果不想修改 runtime 代码,也可以在模板卡片 DOM 上加属性,workbench 会自动读取:
<div class="template-item active" data-generator-template-name="Spring Sale">
  Spring Sale
</div>
(workbench 自动识别带 .selected / .active / aria-selected="true" 的元素)

如果我的生成器没有模板预设选择功能,generatorTag 为空是正常的,可以忽略此项。

问题 B3:appKey 为空(❌)

面板显示initialData.generatorInfo.appKey(空)
症状:发布的模板无法关联到正确的生成器。

我的生成器接入了 generator-workbench,点击 "Publish as Template" 后,调试面板(?debug=true)的"发布参数"区显示 appKey 字段为空,这会导致发布的模板无法关联到正确的生成器。

appKey 由 generator-sdk 自动读取并传递给 workbench,为空通常意味着 SDK 初始化时 appKey 没有正确设置。

请帮我检查以下几点:

1. config.json 是否存在于项目根目录,且包含正确的 appKey:
{
  "appKey": "your-actual-app-key",
  "env": "prod"
}

2. 入口脚本是否正确读取了 config.json(appKey 不应该硬编码):
const config = await fetch('./config.json').then(r => r.json())
const sdk = GeneratorSDK.init({ appKey: config.appKey, env: config.env })

3. SDK 是否在 workbench.mount() 之前完成了初始化,并通过 workbench.sdk = sdk 绑定?

请检查我的入口代码,确认以上三点都正确。

问题 B4:template 为空(❌)

面板显示initialData.generatorInfo.template
症状:发布的模板没有参数数据,用户 Customize 时无法恢复生成器状态。

我的生成器接入了 generator-workbench(workbench-template profile),点击 "Publish as Template" 后,调试面板(?debug=true)的"发布参数"区显示 template 字段为空,这会导致发布的模板没有参数数据,用户 customize 时无法恢复生成器状态。

template 数据需要通过 sdk.template.build() 生成。请帮我在 workbench.config 中配置 getTemplatePublishPayload:

workbench.config = {
  // ...其他配置
  getTemplatePublishPayload: () => {
    const state = runtime.getState()
    return {
      template: sdk.template.build({
        generatorId: 'your-generator-id',   // 替换为你的生成器 ID(通常与 appKey 相同)
        defaults: {
          meta: {},
          params: state,
        },
        panelFilter: {
          // 可选:限制用户在 customize 时可以修改的参数字段
          // includeFields: ['color', 'text']
        },
        adjustableFields: [],
      }),
    }
  },
}

注意:template 数据中不能包含 UI 状态(如菜单展开/收起),只保存用户参数数据。请检查 runtime.getState() 的返回值,确保它只包含业务参数。

问题 B5:template.generatorId 为空(❌)

面板显示└ template.generatorId
症状:模板无法正确绑定到生成器。

我的生成器接入了 generator-workbench(workbench-template profile),点击 "Publish as Template" 后,调试面板(?debug=true)的"发布参数"区显示 template.generatorId 字段为空。generatorId 是平台关联模板与生成器的关键标识,缺失会导致模板无法正确绑定到生成器。

请帮我找到生成器中调用 sdk.template.build() 的地方,确保 generatorId 字段被正确设置:

sdk.template.build({
  generatorId: 'your-generator-id',   // 必须填写,通常与 appKey 相同
  defaults: {
    meta: {},
    params: runtime.getState(),
  },
  panelFilter: {},
  adjustableFields: [],
})

generatorId 的值通常与 config.json 中的 appKey 保持一致。可以这样动态读取:

const config = await fetch('./config.json').then(r => r.json())
sdk.template.build({
  generatorId: config.appKey,   // 直接使用 appKey 作为 generatorId
  // ...
})

请检查我的代码中 sdk.template.build() 的调用位置,补充 generatorId 字段。

相关文档

MIT Licensed