# 模块、表单、虚拟表

这是 xly 元数据模型中的三个核心名词。理解它们，就能读懂框架其余部分。代码库中的词汇并不总是一致：同一概念在不同文件里有不同名字；本页的一部分工作就是统一这些同义词。

## 模块

系统中“一个可配置对象”的单位。

- [`gdsmodule`](../auto-catalog/tables/gdsmodule.md) 中**每个模块一行**。
- 携带 URL 片段（`sName`）、显示名（`sChinese`、`sEnglish`、`sBig5`）、树位置（`sParentId`、`sAllId`）、产品版本（`sVersionFlowId`，见[切片 2](../slices/02-multi-tenancy.md)），以及可选 CRUD 存储过程名（`sSaveProName`、`sDeleteProName`、`sProcName`、`sCalcProName`、`sSaveProNameBefore`）。
- 当前实时 DB 中有 1,358 行。

Java 代码库把这个概念叫作 “module”、“model”、“models” 和 “modle”（常见拼写错误）。变量 `sModelsId` 和方法 `getModelConfigByModleId` 虽然命名如此，实际都接收模块 `sId`。见[切片 1](../slices/01-hello-world.md)中的命名提醒。

## 表单

模块的屏幕布局：表头 + N 个字段定义。

- **Master：** [`gdsconfigformmaster`](../auto-catalog/tables/gdsconfigformmaster.md) 中每个表单一行。携带支撑对象（`sTbName`）、支撑对象类型（`sType` ∈ `{table, view, proc}`）、默认 SQL 片段（`sSqlStr`、`sWhere`、`sOrder`）、表格行为（`bGrd`、`iPageSize`）和权限列。
- **Slave：** [`gdsconfigformslave`](../auto-catalog/tables/gdsconfigformslave.md) 中每个*字段*一行。携带字段名（`sName`，匹配支撑对象中的列）、控件类型（`sControlName`）、显示标签、校验规则、默认值、下拉 SQL、按钮指令。
- 模块通过 `gdsconfigformmaster.sParentId = gdsmodule.sId` 连接到表单，这是语义 FK，不强制。（注意：`gdsmodule.sFormId` 虽然存在，但多数模块为空，且不是规范连接。）
- 当前实时 DB 中有 2,022 个 master 行、159,371 个 slave 行。

表单是用户可见的产物：当 PM 在**后台**中“创建页面”时，实际是在 INSERT 一个 `gdsconfigformmaster` 行和 5 到 50 个 `gdsconfigformslave` 行。

## 虚拟表

xly 对“由元数据定义的表”的术语和表前缀。它不是 `CREATE TABLE` 语句创建的真实表，而是元数据声明的“表”。

- [`gdsconfigtbmaster`](../auto-catalog/tables/gdsconfigtbmaster.md) 中每个虚拟表一行。
- [`gdsconfigtbslave`](../auto-catalog/tables/gdsconfigtbslave.md) 中每个虚拟列一行。
- 当前实时 DB 中有 307 个 master 行、14,385 个 slave 行。

虚拟表让 PM 能声明“我想要这种形状的东西”，不必直接找工程师。多数虚拟表最终映射到真实物理表（框架支持迁移步骤，或预创建通用“宽表”供 PM 填充），但运行时看到的*抽象*是元数据声明，而不是底层存储。

这不同于数据库**视图**：虚拟表是元数据；视图是 `CREATE VIEW` SQL 对象。两者都可以支撑表单（通过 `gdsconfigformmaster.sType = 'table'` 或 `'view'`）。视图支撑的情况见[切片 3](../slices/03-report.md)。

## 它们如何组合

```text
gdsmodule  （模块，1 行）
   └── （通过 sParentId 连接）
       gdsconfigformmaster  （表单 master，每个表单 1 行）
          ├── gdsconfigformslave  （字段，N 行）
          ├── gdsconfigformcustomslave  （每租户字段，N 或 0）
          └── gdsconfigformuserslave    （每用户微调，N 或 0）

gdsmodule.sName   →  gdsroute 中注册的路由（URL 白名单）
gdsmodule.sFormId →  （大多为空，历史字段）
```

每个表单恰好有一个模块。每个模块*应该*最多有一个表单，但少数模块有多个 `gdsconfigformmaster` 行指向同一 `sParentId`，表示带多个面板或子 tab 的页面。

## 三个名词，一个引擎

运行时（`BusinessBaseController` 和 `BusinessBaseServiceImpl`，见[切片 1](../slices/01-hello-world.md)）知道如何渲染任意模块 / 表单 / 虚拟表组合。不存在每模块专用 Java 代码。PM 创建新模块是在创建新行，不是在创建新代码路径。

## 业务数据表前缀

本 Wiki 把业务模块当作示例，而不是章节主体；但 schema 的命名有规律。维护人员可以通过三字母前缀判断业务数据表所属领域：

| 前缀 | 领域 | 示例表（实时数量） |
|---|---|---|
| `gds` | 框架元数据（模块、表单、字段、权限、参数、图表） | `gdsmodule`、`gdsconfigformmaster`、`gdsconfigformslave`、`gdsjurisdiction`、`gdsroute`、`gdsformconst`、`gdsparameter`、`gdsconfigcharmaster`/`slave`（BACK 图表配置使用的图表定义）等 |
| `sys` | 框架系统层（编号、授权、报表、搜索、账单设置），区别于 `gds*` 定义层 | `sysjurisdiction`、`sysbillnosettings`、`sysreport`、`syssearch`、`sysapi`、`syssystemsettings` 等（68 张表） |
| `sis` | 支撑下拉项的共享字典 / 分类表 | `sisbank`、`siscolor`、`sisversionflow`、`sisjurisdictionclassify` 等（80 张表） |
| `sft` | 登录 session / 用户组权限连接表 | `sftlogininfo`、`sftlogininfojurisdictiongroup` 等（8 张表） |
| `ele` | 主数据（element）：客户、员工、机台、材料、产品、工序、半成品、成本框架 | `elecustomer*`、`eleemployee*`、`elemachine*`、`elematerials*`、`eleproduct*` 等（89 张表） |
| `mft` | 制造：工单、生产计划、生产报工 | `mftworkordermaster`、`mftproductionplan*`、`mftproductionreport*` 等（82 张表） |
| `sal` | 销售 | `salsalesordermaster`、`salsalesorderslave`、`salsalesorderprocess` 等（67 张表） |
| `quo` | 报价 | `quoquotationmaster`、`quoquotationslave`、`quoquotationcalc_tmp` 等（23 张表） |
| `acc` | 会计 / 成本 | `accordercostanalysis`、`accordercostanalysisoperation` 等（31 张表） |
| `pur` | 采购 | `purpurchaseapply`、`purpurchasearrive`、`purpurchasechecking` 等（28 张表） |
| `ops` | 外协 / 外发加工 | `opsoutsidearrive`、`opsoutsidechecking`、`opsoutsideinstore` 等（23 张表） |
| `cah` | 出纳 / 财务 | `cahcashierinit`、`cahcostchangemaster`、`cahpaymentmaster`、`cahreceiptmaster` 等（22 张表） |
| `sgd` | 半成品 | `sgdsemigoodscheck`、`sgdsemigoodsinstore`、`sgdsemigoodsmatchbill` 等（21 张表） |
| `ept` | 设备 / 机台固定资产 | `eptmachinefixedborrow`、`eptmachinefixedchange`、`eptmachinefixedinstore` 等（21 张表） |
| `mit` | 材料库存事务 | `mitmaterialsadjust`、`mitmaterialscheck`、`mitmaterialsinstore` 等（19 张表） |
| `pit` | 产品库存事务 | `pitproductadjust`、`pitproductbarcode`、`pitproductcheck`、`pitproductinstore` 等（18 张表） |
| `qly` | 质量检测 | `qlycomematerialstest`、`qlyproducttest`、`qlyprocesstest` 等（8 张表） |
| `kpi` | KPI 跟踪 | `kpimaster`、`kpidetail`、`kpimoduleuserday` 等（7 张表） |
| `udf` | 自定义 / 通用凭证框架 | `udfaccountno`、`udfvouchermaster`、`udfvouchertemplatemaster` 等（5 张表） |
| `viw_` / `Viw_` | 数据库**视图**（schema 中大小写不一致） | `viw_mftworkorderprocess`、`viw_corebusinessreport`、`viw_accordercostanalysisnew` 等（共 311 个视图） |
| `plat_` | B2B 印刷平台层（按[首页](../index.md)说明属于范围外） | 92 张表；本 Wiki 不展开 |
| `ai_` | AI / LLM 功能（范围外） | 7 张表；本 Wiki 不展开 |
| `act_`、`qrtz_` | 第三方 schema（Activiti 工作流、Quartz 调度） | 在 [Activiti](../reference/maintainer/activiti.md) 和[技术栈 Quartz](../reference/maintainer/tech-stack.md)中间接覆盖 |

业务领域前缀（`ele`、`mft`、`sal`、`quo`、`acc`、`pur`、`ops`、`cah`、`sgd`、`ept`、`mit`、`pit`、`qly`、`kpi`、`udf`）及其从表都走同一套元数据驱动运行时：没有按前缀区分的 Java 代码，只有 `gdsconfigformmaster` / `gdsconfigformslave` 中指向各支撑表或视图的行。
