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 字段。相关文档
- Generator Workbench — 壳层总览、配置与挂载选项
- Workbench 与 Runtime 通信 —
select_template、state-change、dispatchWorkbenchCommand参考 - Runtime Contract — 完整 runtime 接口参考
- 接入调试指南 — 如何在浏览器中检查 workbench 事件和 payload