# 元数据驱动的请求生命周期 这张图会反复用到。xly 中每个元数据驱动页面都遵循同一流程;理解它之后,框架其余部分只是主题变奏。 ## 流程 ```text Browser 1. 任意 URL 加载 SPA shell(服务端对每个路径返回同一 shell; gdsroute 是客户端侧边栏 / deep-link 白名单,不是服务端 404 gate) 2. 用户点击侧边栏项或在 SPA 内导航 3. SPA 决定加载哪个模块 → 调用 /business/... GET /xlyEntry/business/getModelBysId/{moduleId}?sModelsId={moduleId} xlyEntry — BusinessBaseController.getModelBysId() RequestAddParamUtil.addParams(params, userInfo) → sBrandsId、sSubsidiaryId、sUserId、sLanguage 等 → 租户作用域进入所有下游查询 BusinessBaseService.getModelBysId(map) ├── 加载 gdsmodule 行(模块) ├── 加载 gdsconfigformmaster 行(通过 sParentId 连接模块) ├── 加载 gdsconfigformslave 行(通过 sParentId 连接 form-master) ├── 合并 gdsconfigformpersonalize(每租户) ├── 合并 gdsconfigformcustomslave(每租户) ├── 加载 gdsjurisdiction(ADMIN 跳过) ├── 加载 gdsformconst(表单级常量) ├── 加载 sysbillnosettings(单据编号) └── 加载关联到该表单的 sysreport 行 返回一个复合 map: { formData, gdsformconst, gdsjurisdiction, billnosetting, report } Browser SPA 使用 formData 渲染表单;使用 gdsformconst 和按控件另取的 SQL 填充下拉项 调用 /business/getBusinessDataByFormcustomId/{formId} 并带 sModelsId={moduleId} 加载实际数据行 xlyEntry — BusinessBaseController.getBusinessDataByFormcustomId() 从 formMaster.sSqlStr / sWhere / sOrder 拼出参数化 SQL,注入 sBrandsId / sSubsidiaryId,并在表单支撑对象(table | view | proc)上执行 用户看到表格 ``` ## 五键复合结果 `getModelBysId` 返回一个 Java `Map`,按顺序包含这些 key: | Key | 来源 | SPA 用途 | |---|---|---| | `formData` | `gdsmodule` ⋈ `gdsconfigformmaster` ⋈ `gdsconfigformslave`(+ 覆盖) | 表单布局本身:每个字段、控件、标签、校验规则 | | `gdsformconst` | 按租户 + 语言作用域过滤的 `gdsformconst` 行 | 表单级常量:标签、默认值、下拉文本 | | `gdsjurisdiction` | 用户角色的 `gdsjurisdiction` 行 | 按钮和数据权限 | | `billnosetting` | 该模块的 `sysbillnosettings` 行 | 单据编号规则(工单号、报价单号) | | `report` | 关联到该表单的 `sysreport` 行 | 打印模板(jxls Excel、iText PDF) | ## 不在这个生命周期中的内容 - **保存路径。** 保存有自己的端点 `POST /business/addUpdateDelBusinessData`,把新增 / 更新 / 删除打包进一个请求。见[切片 1](../slices/01-hello-world.md#4-user-edits-a-row-clicks-save)。 - **打开已有行编辑的读取。** 与表格加载使用同一端点 `getBusinessDataByFormcustomId`,但 body 中带行 `sId`,handler 按请求一行还是多行分支。 - **工作流步骤。** 如果模块有活动审批流(`bCheck = 1`、填充 `sVersionFlowId`、已部署 Activiti 流程),会插入额外步骤。当前 dev DB 没有这些数据;见[切片 7(暂缓)](../slices/07-workflow.md)。 - **缓存失效。** **后台**修改元数据行时,JMS 消息会让所有运行节点失效缓存副本,即 `xlyErpJmsConsumer` 中的 `ConsumerChangeGdsModuleThread`。它在请求流之外,但紧邻请求流。 ## 其他切片覆盖的变体 - [切片 1](../slices/01-hello-world.md):规范实例,带观察到的网络流量。 - [切片 2](../slices/02-multi-tenancy.md):多租户过滤如何贯穿每一步。 - [切片 3](../slices/03-report.md):视图支撑而非表支撑。 - [切片 4](../slices/04-custom-field.md):`gdsconfigformcustomslave` 合并步骤。 - [切片 5](../slices/05-customer-sql-override.md):某租户的存储过程主体被替换时。 ## 读一次,并保持打开 如果后续章节出现你不认识的术语,它几乎一定指向上图中的某个框。回到这里即可。