切片 3 — 由视图支撑的模块(只读报表)
切片 1 追踪的是 CRUD 模块:表单读写一张表。切片 3 前进一步:模块从数据库视图读取,连接多张基础表,并把连接结果呈现为可排序、可过滤的表格。没有保存,没有删除,只读。
这是 xly 中所有“列表视图”的基础:订单汇总、日报、库存快照、KPI 看板。框架通过与表支撑模块相同的元数据管线处理视图支撑模块,唯一差异是 gdsconfigformmaster.sType = 'view' 会抑制写操作。
记录对象
| 模块 |
工单工序明细(Work-Order Process Details) |
| URL 片段 |
/indexPage/commonList(通用“只读列表”页面模板) |
模块 sId |
19211681019715708462888040 |
| 支撑对象 |
viw_mftworkorderprocess,数据库视图,不是基础表 |
| 字段数 | 40 |
| 写过程 | 无,设计上只读 |
| 打印模板 | 无,纯表格 |
该视图把工单 master / slave 表族连接成扁平的每行表示。视图本身的存在就是 xly 报表渲染约定的一部分:与其在每个读取查询中重新写 join,xly 会编写数据库侧 CREATE VIEW,并让一行元数据指向它。
为什么选这个模块 {#why-this-module}
它是 xly 最常见运行模式之一的最简单成员:视图支撑的列表页。这个 dev DB 中有 405 个视图支撑表单(全部表单的 20%),仅次于表支撑表单。理解本切片后,其他运维报表都是变体。
它也反驳切片 1 可能造成的两个误解:
- 并非每个模块都从单表读取;视图支撑模块读取 join。
- 并非每个 URL 都是唯一拼音路径。
/indexPage/commonList是共享模板 URL,许多不同模块都使用它。URL 不标识模块;API 调用上的sModelsId参数才标识模块。
追踪
1. 页面 shell
与切片 1 相同:访问 /indexPage/commonList 进入 SPA shell;SPA 再通过侧边栏 / 菜单状态解析要加载的模块。URL 是显示状态,不是路由驱动。
2. 元数据获取
GET /xlyEntry/business/getModelBysId/19211681019715708462888040?sModelsId=19211681019715708462888040
同一个 handler,同一个五键复合响应:formData、gdsformconst、gdsjurisdiction、billnosetting、report。这里的 report 为空,因为该模块没有附加打印模板。
与切片 1 的关键差异在 formData:form-master 行包含:
sType = 'view'
sTbName = 'viw_mftworkorderprocess'
sSqlStr = SELECT ... FROM viw_mftworkorderprocess ... 骨架
sWhere/sOrder = 默认谓词
sType = 'view' 是框架判断只读的唯一信号。其余元数据结构与 CRUD 模块相同。
3. 表格数据获取
POST /xlyEntry/business/getBusinessDataByFormcustomId/{formId}?sModelsId={moduleId}
仍然是切片 1 的同一端点。handler 不关心支撑对象是表还是视图,只把 sTbName 代入由 sSqlStr + sWhere + sOrder 组合出的参数化 SQL。视图负责 join;框架负责租户过滤和分页。
为什么用视图而不是运行时 JOIN? xly 把 join 写进 SQL DDL(
CREATE VIEW),使运行时 SQL 保持扁平的SELECT ... FROM <one-name> WHERE ...。这样可以把 table、view、proc 等不同“形状”来源插入同一表单机制。代价是命名视图增多;此 dev DB 中有 311 个。
4. 视图本身
viw_mftworkorderprocess 把工单 master 与每工序 slave 明细连接起来。完整 CREATE VIEW 定义见该视图的自动目录页。
命名约定:xly 视图前缀是 viw_ 或 Viw_(schema 中大小写不一致)。join 视图常常很宽,40+ 列很常见。它们几乎总是从主基础表带出 sBrandsId / sSubsidiaryId,使框架的通用租户过滤仍然有效。
5. 保存:不存在
对 sType = 'view',框架不提供新增 / 更新 / 删除按钮。理论上,如果被要求,addUpdateDelBusinessData 的 MyBatis 侧会尝试写入视图;但框架不会为它渲染按钮。需要让某个视图可写时,维护人员通常应把表单指向基础表并使用自定义保存过程,或依赖 MySQL 自动可更新视图能力;本模块都没有这样做。
6. 打印报表(存在时)
一些视图支撑模块确实有打印模板:Excel via jxls、PDF via iText。机制与表格分离:
-
getModelBysId返回report数组,来自通过sFormId关联到表单的sysreport行。 - 前端“打印” / “导出”按钮调用
xlyEntry/com/xly/report/下的 controller,加载 jxls / iText 模板,使用同一视图查询的“取全部行”包装,并把二进制文件流回。 - 本模块没有模板,因此不覆盖打印路径。未来修订应选一个确实有模板的模块;
print template值得单独成章。
本切片引入或强化的概念
-
视图支撑模块:
gdsconfigformmaster.sType = 'view'让模块只读,其余元数据流相同。 -
共享模板 URL:
/indexPage/commonList、/indexPage/commonBill、/indexPage/commonClassify、/indexPage/commonNewBill被数百个模块复用。URL 选择页面形状;模块身份来自sModelsId。 -
报表模板(仅预览):
sysreport通过sFormId关联,jxls / iText 模板由PrintReportController提供。
待验证项
- 带打印模板的视图支撑模块:选择一个并端到端追踪 jxls 导出。
-
sType = 'proc'变体:209 个表单由存储过程支撑,应另开切片说明过程如何返回结果集和参数如何流动。 -
视图租户安全。 需要脚本审计哪些视图没有带出
sBrandsId/sSubsidiaryId。