request-lifecycle.md 4.09 KB

元数据驱动的请求生命周期

这张图会反复用到。xly 中每个元数据驱动页面都遵循同一流程;理解它之后,框架其余部分只是主题变奏。

流程

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 gdsmodulegdsconfigformmastergdsconfigformslave(+ 覆盖) 表单布局本身:每个字段、控件、标签、校验规则
gdsformconst 按租户 + 语言作用域过滤的 gdsformconst 表单级常量:标签、默认值、下拉文本
gdsjurisdiction 用户角色的 gdsjurisdiction 按钮和数据权限
billnosetting 该模块的 sysbillnosettings 单据编号规则(工单号、报价单号)
report 关联到该表单的 sysreport 打印模板(jxls Excel、iText PDF)

不在这个生命周期中的内容

  • 保存路径。 保存有自己的端点 POST /business/addUpdateDelBusinessData,把新增 / 更新 / 删除打包进一个请求。见切片 1
  • 打开已有行编辑的读取。 与表格加载使用同一端点 getBusinessDataByFormcustomId,但 body 中带行 sId,handler 按请求一行还是多行分支。
  • 工作流步骤。 如果模块有活动审批流(bCheck = 1、填充 sVersionFlowId、已部署 Activiti 流程),会插入额外步骤。当前 dev DB 没有这些数据;见切片 7(暂缓)
  • 缓存失效。 后台修改元数据行时,JMS 消息会让所有运行节点失效缓存副本,即 xlyErpJmsConsumer 中的 ConsumerChangeGdsModuleThread。它在请求流之外,但紧邻请求流。

其他切片覆盖的变体

  • 切片 1:规范实例,带观察到的网络流量。
  • 切片 2:多租户过滤如何贯穿每一步。
  • 切片 3:视图支撑而非表支撑。
  • 切片 4gdsconfigformcustomslave 合并步骤。
  • 切片 5:某租户的存储过程主体被替换时。

读一次,并保持打开

如果后续章节出现你不认识的术语,它几乎一定指向上图中的某个框。回到这里即可。