status: apply created: 2026-07-21 complexity: 🔴复杂 change:
in-app-lowcode-builderdependency:app-first-lowcode-workbench已建立应用聚合、对象编排、工作台和应用级options持久化能力。
当前 Forge 已具备对象、字段、表单、列表、规则、流程、动态 CRUD、组件画布与发布能力,但用户的工作路径仍偏向“应用中心 → 对象 → 专业设计器 → 访问入口”。业务人员难以把它理解为一个可直接打开、拥有首页、目录和菜单的完整应用。
本变更在不新建第二套低代码事实来源、不修改后端接口或数据库结构的前提下,新增“应用内低代码搭建器”的前端交互层。用户从应用进入运行壳后,在具备编辑权限时点击“编辑应用”,即可创建页面组(目录)、页面、首页内容和页面组件;需要配置字段、表单、列表、CRUD、规则或流程时,仍在同一应用上下文中复用既有设计器能力。
完成后应满足以下可验证结果:
ai_business_application.options.inAppBuilder 前端配置保存;继续使用既有应用更新、版本和发布链路。forge-admin-ui/src/views/app-center/application.[applicationCode].vue 已是应用工作台入口,能按应用编码加载工作台、按分区承载对象、入口、流程、权限和发布能力。forge-admin-ui/src/views/app-center/application-preview.[applicationCode].vue 已能以应用为上下文加载业务对象设计草稿并交给 LowcodePreviewPane 预览。forge-admin-ui/src/api/business-application.js 已提供应用工作台读取和应用更新 API;forge-admin-ui/src/api/business-app.js 已提供对象设计保存 API。forge-server/.../domain/entity/AiBusinessApplication.java、BusinessApplicationDTO.java 与 BusinessApplicationVO.java 都包含 options JSON 字段。BusinessApplicationService.update(...) 接收并规范化 options;现有应用聚合发布/版本能力会对应用扩展配置做快照。因此首期应用内页面编排可存入 options,无需新增表、Flyway 或 Controller。forge-admin-ui/src/components/lowcode-builder/page/ComponentPalette.vue 已提供按区块过滤的业务组件、基础控件、字段筛选和 HTML5 拖拽数据协议。forge-admin-ui/src/components/lowcode-builder/page/LowcodePageBuilder.vue、BuilderCanvas.vue、BuilderZone.vue 与 ComponentPropertyPanel.vue 已提供页面画布、放置区和属性编辑基础。forge-admin-ui/src/components/lowcode-builder/page/page-schema.js 是页面 Schema、默认组件、默认布局和字段同步的共享事实来源。forge-admin-ui/src/views/app-center/components/designer/BusinessListDesigner.vue 已支持业务对象内多页面、新增、复制、删除、重命名和页面跳转目标校验;其 pages[] 是对象页面资产,不等同于应用级导航树。forge-admin-ui/src/views/app-center/components/designer/BusinessFormDesigner.vue、BusinessDetailDesigner.vue、BusinessFlowBindingPanel.vue 已覆盖表单、详情与流程配置;runtime-rules.js 和 RuntimeRulesEditor.vue 已统一处理运行规则。forge-admin-ui/src/views/ai/crud-page.vue、ListPageGridDesigner.vue 和 LowcodePreviewPane.vue 已提供真实 CRUD 或设计态运行预览。ai_business_app 是访问入口,不是应用页面树;BusinessAppOpenService.buildRuntimeTargetRoute(...) 仅按入口、configKey、pageKey 和运行模式解析运行页,不能被改造成第二个应用页面存储。pageSchema.pages[] 解决“一个对象内的列表/详情/自定义页”,但不记录跨对象目录、首页或应用级菜单,不能直接作为应用导航树。sys_resource、动态路由和系统 RBAC 管理。应用内编辑不得直接修改该菜单,否则会跨应用影响权限、路由和其他用户。ai:businessApplication:edit 后端授权;新页面级细粒度权限只做前端编排字段预留,不在本变更中声称已完成后端强制。输入:用户从应用中心或应用工作台打开某业务应用。
处理:前端加载应用、对象摘要、发布态配置和 options.inAppBuilder;以“应用壳”替代系统后台侧栏,展示应用名称、应用切换、通知/头像等共享顶栏元素、应用内导航与页面内容。
输出:
输入:编辑者在应用编辑态点击“添加”。
处理:
输出:左侧为清晰的应用导航树;首页默认存在且固定在顶层,其他页面可按目录管理。
输入:编辑者创建空白/介绍页,或点击页面/区块悬浮“添加组件”。
处理:
+;点击后打开组件选择弹窗,支持关键字、常用/业务/内容/高级分类。listPageBlockCatalog、createGridBlock 和 GridBlockRenderer,但按最终页面流直接渲染;编辑态复用列表设计器的拖动手柄、选中边框、八向尺寸锚点、拖动占位/双胞胎阴影和更多操作层。应用页仍保存组件布局数据到 gridLayout,不启用网格背景或完整自由画布工作台。输出:用户可不学习拖拽操作,仅通过点击完成首个页面;插入后自动选中新组件并在右侧显示属性。
输入:当前页面为空、选中页面、选中组件或选中业务数据页。
处理:右侧仅展示当前上下文所需内容:
| 状态 | 右侧内容 |
|---|---|
| 空白页面 | 页面简介、常用组件、页面模板、最近使用组件 |
| 选中页面 | 名称、图标、目录归属、可见性预留、页面说明、页面类型 |
| 选中组件 | 显示选中边框与排序手柄;复杂属性仍在既有专业设计器中维护 |
| 业务数据页 | 绑定对象、打开方式、默认页面/表单、快捷配置入口 |
编辑态未选中组件时不显示右侧属性面板,避免右侧同时承担新增、导航和属性配置。
不得复制现有属性编辑实现;新壳只适配选择状态、插入位置和应用级属性。
输入:编辑者在业务数据页点击“配置数据页面”“配置表单”“配置规则”或“配置流程”。
处理:
pageKey、默认参数和展示设置。BusinessListDesigner、BusinessFormDesigner、BusinessDetailDesigner、RuntimeRulesEditor 和既有流程配置入口,可在抽屉、全屏子工作区或深链中打开,但始终携带应用返回上下文。输出:业务用户把“客户管理、商机表单、审批页”等放入应用并做常用设置;实施人员可无缝进入已存在的专业配置。
输入:用户改变应用导航、页面编排或应用内组件布局。
处理:
options.inAppBuilder,不产生新的后端协议。输出:用户不会误以为保存即对所有运行用户生效。
sys_resource 全局菜单。modelSchema、formDesignerSchema、pageSchema、viewSchema、linkageSchema 或流程 JSON。pageKey 必须显示可理解的占位和“去配置”动作,不能渲染 undefined。本变更不新增表、不新增字段、不执行 Flyway。
应用级编排写入已存在的 ai_business_application.options:
{
"inAppBuilder": {
"schemaVersion": 1,
"homePageId": "page_home",
"nodes": [
{ "id": "page_home", "type": "page", "pageType": "home", "title": "首页", "parentId": null, "sort": 0 },
{ "id": "group_sales", "type": "group", "title": "销售管理", "parentId": null, "sort": 10 },
{ "id": "page_opportunity", "type": "page", "pageType": "object", "title": "商机管理", "parentId": "group_sales", "sort": 0,
"objectRef": { "objectId": "…", "objectCode": "crm_opportunity", "pageKey": "list" } }
],
"pages": {
"page_home": { "layout": { "items": [] } }
}
}
}
约束:配置中不得保存 Token、密码、AK/SK、脚本源代码或对象完整 Schema;版本升级必须通过前端 Schema 归一化兼容旧空 options。
本期不新增或修改后端接口,复用:
| 场景 | 既有接口 | 前端用途 |
|---|---|---|
| 加载应用工作台 | GET /ai/business/application/code/:applicationCode/workspace |
应用、对象、入口摘要与 options |
| 保存应用草稿 | PUT /ai/business/application |
保存 options.inAppBuilder |
| 加载/保存对象设计 | 既有 /ai/business/object/:id/designer 及设计保存接口 |
深度配置字段、列表、表单和规则 |
| 发布/回滚 | 既有应用发布接口 | 继续管理应用版本 |
| 打开运行入口 | 既有 /ai/business/app/:id/open-info |
复用入口权限和安全校验 |
如实施中发现工作台响应未返回 application.options 或已有应用更新接口不允许保留未知 JSON 键,必须停止前端实现并新增后端兼容任务,不允许绕过后端或改用浏览器本地存储作为多人共享事实来源。
forge-admin-ui/src/router/index.js:新增应用运行壳/编辑器前端路由;保持既有工作台和对象设计器路由兼容。forge-admin-ui/src/views/app-center/:应用工作台头部增加“进入应用/编辑应用”入口,新建应用内运行壳和编辑器视图。forge-admin-ui/src/components/lowcode-builder/:只复用或抽取现有画布、组件目录、属性面板和 Schema;不得破坏旧设计器。forge-admin-ui/src/api/business-application.js:只在必要时补充已有接口封装或参数归一化;不新增协议。code-copilot/changes/in-app-lowcode-builder/:本变更的 Spec、任务、测试计划和执行日志。不影响:forge-server/** 业务实现、Flyway、sys_resource、动态 CRUD API、Flowable 引擎和既有对象设计 Schema。
options 适合导航、页面引用和轻量布局。若自定义页面布局逐渐变大或需要独立审计,应另开后端数据模型,不能无限堆进 options。inAppBuilder 时必须根据应用名称、主对象和入口生成只在前端内存中的默认首页,首次保存才写入 options。open-info 的外部页面。pnpm build。执行前必须读取 code-copilot/rules/automated-testing-standard.md 并追加 execution-log。/test 或实际编码前创建/补充 test-spec.md。/app/:applicationCode,还是保持在 /app-center/application/:applicationCode/runtime?建议后者,避免与现有动态菜单和外部部署路径冲突。open-info 校验的访问入口,不提供自由输入外部 URL。options 全量快照?需要在编码前通过现有发布代码和测试确认;若不包含,V1 只能明确标注为“应用草稿编排”,不能承诺随发布版本回滚。objectId/objectCode/pageKey,禁止复制模型、表单或流程 Schema。| Task | 状态 | 实际改动文件 | 备注 |
|---|---|---|---|
| Proposal | completed | spec.md, tasks.md |
仅文档,未修改业务代码、后端接口或数据库 |
| 第三阶段统一体验 | completed-static | 页面设计器、业务应用 API/服务、发布与对象面板、相关单测 | 已完成按需对象门禁、草稿/发布运行分离、设计器内对象与发布抽屉;自动化与生产构建通过,真实服务/角色/菜单 E2E 待人工验收。 |
尚未进入实现审查。编码前需先完成第 9 章待澄清项并获得 HARD-GATE 确认。
/app-center/application/:applicationCode/runtime;首期组件范围按第 9 章建议冻结;外部页面仅引用既有受控访问入口;先复用现有应用 options 和发布快照能力,不新增后端接口或数据库结构。2026-07-26 用户确认:以下能力全部进入本变更,不再仅保留前端编排字段。
options.inAppBuilder 只保存页面树、页面设置和编排;保存草稿绝不写入 sys_resource。ai:business:application:{applicationCode}:page:{pageId},不得使用页面名称。pageId 查询参数定位页面;运行壳必须从已发布快照读取页面,不能读取草稿。pageId 时回退到第一个可访问页面。inAppBuilder 与页面菜单摘要;发布前校验首页、对象引用、菜单权限和动作目标。回滚后按目标快照再次同步菜单和权限。sys_resource / sys_role_resource 只由后端发布服务维护。2026-07-27 用户反馈:页面设计、业务对象工作台和发布工作台的概念仍然割裂,纯页面应用被“必须且只能有一个主对象”错误阻断。本节覆盖前文“纯前端、不新增接口”和“发布跳转工作台”的首期限制,以本节为本轮实现依据。
PRIMARY,不要求用户理解或手动选择对象角色。PRIMARY,前提是每个数据消费节点都显式绑定到本应用内的有效对象;存在一个 PRIMARY 时,未显式绑定的数据节点可回退到该对象。PRIMARY 始终阻断;显式引用应用外对象、对象引用失效、或数据组件无法解析到唯一对象时阻断。pageType=object 页面和 AiCrudPage 区块;对象引用依次识别页面 objectRef、区块 props.objectRef 与 props.businessObjectRef,并递归检查容器子组件、栅格单元格和标签页。AiForm / formAssets 不自动等价于数据库业务对象。代码生成需要根对象时仍在“生成代码”阶段单独校验,不阻断应用发布。edit=1 或 draft=1 读取应用工作台草稿;普通运行态调用 GET /ai/business/application/by-code/:applicationCode/runtime 读取 lastPublishVersion 指向的不可变发布快照。ai:businessApplication:runtime 权限,只返回已启用应用的发布配置,并按发布时生成的稳定页面权限过滤导航节点和页面定义。pages 中删除;其必要父目录保留;已发布首页不可访问时回退到第一个可访问页面。直接传入无权 pageId 由前端选择返回配置中的可访问首页。application / objects / entries 结构,但来源是不可变应用版本快照。PAGE_MENUS 必须出现在运行记录步骤名称和部分失败副作用判断中。2026-07-28 用户反馈:先创建页面表单并绑定
AiCrudPage后,字段选择无法生效,发布仍提示数据页面未绑定业务对象。页面表单和持久化对象的边界虽然在发布规则中正确,但设计态仍允许形成误导性的半绑定状态。
ListPageGridDesigner 的字段清洗必须使用当前组件实际收到的字段目录;页面级 fields 与稳定的页面 modelSchema.fields 分离时,不能把刚选择的字段立即过滤掉。AiCrudPage 的“数据”配置首先展示业务数据源。未绑定对象时必须明确说明页面表单只定义字段和布局、不提供数据库表与 CRUD 接口,并在当前上下文提供选择已有对象、管理/导入对象和从当前页面表单创建对象的入口。formDesignerSchema,创建对象后自动加入当前应用并绑定回当前 AiCrudPage;页面表单原资产保留,不做破坏性删除。2026-07-28 交互复核:普通用户只理解“表单”,不应在保存表单后再手工创建业务对象,更不应连续打开“数据对象”和“新建业务单元”两个抽屉。本节覆盖 15.5 中“从当前表单创建对象”的手动主流程。
AiCrudPage 使用且至少包含一个持久化字段时,首次成功保存必须自动准备表单数据存储,不再要求用户理解或创建“业务对象”。LOWCODE_RUNTIME 数据源,先在元数据事务中创建内部托管业务对象、保存表单派生字段与 formDesignerSchema 并加入当前应用;元数据提交后再按 15.9 执行安全数据库同步。接口不得自动发布对象或应用。AiCrudPage 使用时只准备一个数据存储,并把这些区块统一绑定到返回的对象引用。手工绑定已有对象的页面不自动改写该对象,继续作为高级数据设置处理。2026-07-28 实测反馈:保存表单并自动回绑托管对象后,应用设计器立即请求正式 CRUD 运行接口,因对象尚未发布而提示“低代码应用尚未发布”。
edit=1 和 draft=1 属于设计态,加载对象渲染配置及页面内 CRUD 数据接口时必须统一携带既有 designPreview=1 协议,允许具备设计权限的用户使用最新草稿配置;不得要求先发布对象或应用才能继续保存和配置页面。AiCrudPage 自动加载列表时触发正式运行门禁。2026-07-28 实际保存表单时,自动准备服务生成了超过数据库
varchar(48)的model_code,导致托管数据存储创建事务回滚;同时普通用户仍被要求手工填写应用编码。
ai_business_object.model_code 与 ai_lowcode_model.model_code 的统一运行契约为最多 48 个字符。后端所有模型编码归一化和“业务域 + 对象”组合都必须使用同一 48 位上限;前端对象创建辅助函数也必须遵循该上限,不通过扩大数据库字段掩盖命名规则漂移。applicationCode 为空时由后端根据业务域与应用名称生成符合“字母开头,仅含字母、数字和下划线,2-64 字符”的编码;中文名称无法形成可读单词时使用稳定短摘要,不得生成空编码。_2、_3 等稳定后缀避让已有有效应用;显式填写的编码仍按原规则校验并在重名时失败。数据库唯一索引继续作为并发竞争的最终失败关闭边界。2026-07-28 用户实测反馈:表单保存并显示“数据存储已准备完成”后,真实 CRUD 仍报“数据表不存在”。本节覆盖 15.5~15.8 中“自动准备不执行 DDL”的旧约束,仅针对系统自动托管的页面表单执行受控数据库同步。
options.managedBy=PAGE_FORM,且来源应用、表单资产与本次保存请求一致时,表单数据准备接口在元数据事务成功提交后自动创建对应数据表;后续保存新增字段时自动追加缺失列。allowRuntimeDdl=1 的 LOWCODE_RUNTIME 数据源。没有符合条件的数据源时,不创建半成品托管对象,并用普通用户语言提示“当前数据存储未允许自动建表”。allowDdl 快照误阻断;管理员开启自动建表后,用户重新保存原表单即可复用原对象补建表。BusinessObjectTableMappingService + LowcodeDdlService 的差异预览、数据源解析和安全语句白名单;只允许 CREATE TABLE、ADD COLUMN 与既有安全追加式索引/注释语句。字段删除、重命名、类型/长度/必填调整等非追加式变更不自动执行,保留到高级数据设置人工处理。ai:lowcode:deploy-ddl 权限或显式确认门禁。2026-07-28 用户实测反馈:自动托管表单已经绑定后,画布仍提示“绑定真实数据接口”;已配置的查询条件刷新后有时只剩 ID;发布检查又以
OUT_OF_SYNC阻断。三者必须以同一个表单字段和托管数据表状态为准。
AiCrudPage 查询区必须使用区块显式保存的 props.searchFieldRefs,不能复用列表列的 fieldRefs;只有旧区块没有查询字段属性时才回退到列表字段。显式配置多少个查询字段就按顺序回显多少个,折叠数量继续由组件现有参数控制。PAGE_FORM 数据存储后,首次把对应 CRUD 区块切换为真实草稿预览并持久化初始化标记;用户之后主动关闭真实预览时不得在下次保存被强制重开。已配置接口但主动使用静态预览时,提示应说明“可在右侧开启真实数据预览”,不得再误报“尚未绑定真实数据接口”。PAGE_FORM 托管数据表。CREATE TABLE、ADD COLUMN 等既有安全白名单差异自动处理,已同步结构刷新为当前设计版本后不再因查询/页面布局变化误报 OUT_OF_SYNC。2026-07-28 用户实测反馈:开启真实数据预览后列表接口持续循环调用;打开发布面板和正式发布期间又出现大量重复数据库查询与更新。
lastPreviewStatus、lastPreviewMessage、选择状态、组件位置等展示态写回不得再次触发列表请求。IN_SYNC 证据。只有 OUT_OF_SYNC、TABLE_MISSING、FAILED、UNKNOWN 或设计版本变化时才额外进入自动 DDL 差异同步;已经同步且设计未变化时不再由该入口重复扫描或写回同步状态。对象发布自身的最终表完整性校验继续保留。2026-07-28 用户实测反馈:动态页面已经配置查询字段,但输入条件后列表不筛选;页面配置中的查询方式、查询组件和映射字段也没有进入真实请求。
AiCrudPage 选择查询字段后,运行 Schema 必须同时应用 searchFieldSettings。查询方式、查询组件和映射字段不能只停留在属性面板 JSON 中;映射字段有效时,请求键使用目标字段,标签继续使用页面选择字段的业务名称。searchSchema 白名单静默丢弃。后端允许范围继续限定在动态配置已经公开的查询、列表、编辑字段及真实列映射内,不接受任意列名。searchSchema 继续作为默认查询协议;没有页面级覆盖的传统动态页面保持兼容。页面级查询配置只改变当前页面的筛选呈现和请求,不反向修改共享业务对象设计,也不要求普通用户理解对象查询白名单。