内部 API(xlyEntry)
xlyEntry 服务承载 SPA 的运行时 API。它是三层中最大的一层:控制器和框架的元数据驱动运行时编译到同一个 WAR,大多数调用会落到少数几个可以读写任意模块的通用端点上。
这个 API 不是给外部调用方使用的稳定契约。端点形状会随框架变化而变化。外部集成应该使用外部 API。本页面面向维护人员和 SPA 扩展作者。
请求生命周期和代码级 walkthrough 见维护人员运行时章节。本页只列 HTTP 入口。
通用 CRUD 接口面:/business/*
| 端点 | 方法 | 用途 |
|---|---|---|
/business/getModelBysId/{sModelsId} |
GET | 返回某个模块的表单布局,也就是五键组合(formData、gdsformconst、gdsjurisdiction、billnosetting、report)。 |
/business/getBusinessDataByFormcustomId/{gdsconfigformmasterId} |
POST | 返回某个表单的业务数据行,带分页。设置 sGroupList 时会分支到 getBusinessDataByGroup。 |
/business/getBusinessDataByIndex |
POST | 首条 / 末条 / 下一条 / 上一条记录导航。 |
/business/addBusinessData |
POST | 单行新增。 |
/business/addUpdateDelBusinessData |
POST | 在一个事务调用里组合新增 + 修改 + 删除。前端通过 sTable 直接指定目标表。 |
/business/getSelectDataBysControlId/{sId} |
POST | 按控件 sId 为单个控件加载下拉选项。 |
/business/getSelectLimit/{sId} |
POST | 下拉加载调用的分页变体。 |
/business/addSysLocking |
POST | 用户开始编辑单据时获取乐观锁,在系统锁表中按 (sFormGuid, sUserId) 插入一行。SPA 进入编辑模式时会触发它,使并发编辑者收到冲突提示。处理器:BusinessBaseController.java:400-407。 |
/business/doExamine |
POST | 简单“审核”:通过 SQL 把指定行的 bCheck 翻为 1。不会调用 Activiti;这是不需要多步工作流的模块使用的 xly 轻量审批路径。处理器:BusinessBaseController.java:384-391 → BusinessBaseServiceImpl.doExamine → ExamineServiceImpl。何时改用 Activiti,见 xly 如何在不使用 Activiti 的情况下处理工作流。 |
/business/getProData |
POST | 面向模块的通用存储过程调用,是 /procedureCall/doGenericProcedureCall 的另一条路径。处理器:BusinessBaseController.java:350-358 → BusinessBaseServiceImpl.getProData。FROUNT 会用它做模块级 proc 读取,例如首页看板的 /getProData?sModelsId=...&sName= 模式。 |
这些端点在切片 1(getModelBysId + 网格加载 + 保存)和切片 3(基于视图的读取变体)中有更详细说明。处理类位于 xlyEntry/src/main/java/com/xly/web/businessweb/。
元数据管理端点
配置侧动作(创建模块、定义表单、声明虚拟表)在 xlyEntry/src/main/java/com/xly/web/systemweb/ 下有一套并行接口面:
| 端点前缀 | Controller | 用途 |
|---|---|---|
/gdsmodule/* |
GdsmoduleController |
模块树 CRUD,包括 getModuleTreePro、addGdsmodule、updateGdsmodule。 |
/gdsconfigform/* |
GdsconfigformController |
表单主表和表单明细元数据 CRUD。 |
/gdsconfigtb/* |
GdsconfigtbController |
虚拟表主表 / 明细元数据 CRUD。 |
专用运行时端点
| 端点前缀 | Controller | 用途 |
|---|---|---|
/configform/* |
BusinessConfigformController |
用户 / 用户组级显示定制。 |
/treegrid/* |
BusinessTreeGridController |
树表端点(当前分支实现的是存储过程支撑路径)。 |
/procedureCall/* |
GenericProcedureCallController |
按名称 + 参数通用调用存储过程;见通用存储过程分发。 |
/panel/* |
ConfigformPanelController |
gdsconfigformpanel 中的面板布局持久化。 |
/checkflow/* |
CheckFlowController |
空壳,返回 404。 该类只声明前缀,没有任何 handler 方法。真正的工作流审核 / 驳回 / 完成 URL 来自 xlyFlow 的 CurrencyFlowController(因为 xlyFlow 作为库依赖被编进 xlyEntry,所以仍挂在 xlyEntry context-path 下):/currencyFlow/complete/{taskId}/{sBrandsId}/{sSubsidiaryId}/{sUserId}、/currencyFlow/completeerp/{sBrandsId}/{sSubsidiaryId}/{sUserName},以及根路径映射的 BPMN modeler /modeler/*。见 Activiti 集成。 |
/modelCenter/getModelCenter、/modelCenter/getModelCenterCalculation
|
BusinessModelCenterController |
FROUNT 首页的 KPI 工作中心卡片(标题为 KPI监控)。它聚合标记为 gdsmodule.bUnTask=1 的模块上的未清任务,按角色和业务流程分组。不是 Activiti 驱动。 见 KPI 工作中心。 |
报表与打印
打印接口面位于 xlyEntry/src/main/java/com/xly/web/report/:
-
PrintReportController— 当前 jxls / iText 打印路径。 -
PrintReportControllerOld.java— 文件存在,但类体已全部注释掉(而且注释内类名是PrintReportController,不是*Old)。这是保留作参考的死代码,不是活跃 controller。
前端的“打印” / “导出”按钮会调用这些控制器,控制器从 sysreport 加载模板,执行匹配的视图查询,并把二进制文件流回前端。流程见切片 3。
认证
所有参与业务数据的控制器方法都标注 @Authorization,并通过 @CurrentUser 接收解析后的 UserInfo。session 到 UserInfo 的映射由框架自己处理(cookie + Redis 支撑的 session);见多租户概念页。
如果某个请求未认证却进入了控制器,正常情况下会被 @Authorization 拦下;如果没有被拦下(例如某个方法未加注解),这个方法也会绕过 RequestAddParamUtil 中的通用租户注入,因此就是多租户 bug。
BACK 配置侧边栏(管理接口面) {#back-builder-sidebar-admin-surface}
BACK 管理侧边栏的 10 个顶层项(登录 admin/123,版本 基础版/8s)都通过上面的框架原语接线成元数据驱动页面:
| 侧边栏 | URL 片段 | 支撑 form-master sTbName
|
所属 service |
|---|---|---|---|
| 系统模块配置 | /xtmkpz |
gdsmodule |
GdsmoduleServiceImpl |
| 数据表内容配置 | n/a |
gdsconfigtbmaster/slave
|
GdsconfigtbServiceImpl |
| 界面显示内容配置 | n/a |
gdsconfigformmaster/slave/customslave/personalize
|
GdsconfigformServiceImpl |
| 接口自定义配置 | /sjbnrpz |
sysapi 表族 |
xlyApi 侧管理接口 |
| 系统常量配置 | /xtclpz |
gdsformconst |
GdsformconstServiceImpl,切片 1 锚点 |
| 系统权限配置 | n/a | gdsjurisdiction |
GdsjurisdictionServiceImpl |
| 常用操作配置 | n/a | 当前 dev DB 中没有对应 gdsconfigformmaster 行;页面是 SPA 中直接接线的管理特例。若通过元数据扩展,数据位于用户自定义按钮组层。 |
n/a |
| 用户信息配置 | n/a |
sftlogininfo 表族 |
GdslogininfoServiceImpl |
| Mysql脚本配置 | n/a | BACK 对 templesql/ 脚手架的编辑器 |
SqlScriptsServiceImpl |
| 图表配置 | 无 gdsroute 项;通过 SPA state 导航 |
gdsconfigcharmaster/slave
|
GdsconfigformServiceImpl(图表子集) |
10 项里有 8 项是本目录和维护人员参考覆盖的框架原语。常用操作配置 是 SPA 侧管理特例:它出现在侧边栏,但 dev DB 中没有对应的 gdsconfigformmaster 行,说明该页在 BACK 中硬编码,而不是元数据驱动。图表配置 则完全由元数据驱动:两条 gdsconfigformmaster 行分别指向 gdsconfigcharmaster 和 gdsconfigcharslave,其中的图表定义由 SPA 其他位置的看板渲染消费。
框架原语之外:xlyEntry 的其余接口面
xlyEntry 总共托管 70 个 controller。其中 18 个属于框架侧:上面明确列出的通用运行时 controller,加上支撑 BACK 配置侧边栏 的 7 个 systemweb/ 管理 controller(GdsformconstController、GdsjurisdictionController、GdslogininfoController、GdsparameterController、LicenseController、LoginController、SysbrandsController)。每个元数据驱动表单的生命周期都在这些接口面里。
剩余 52 个 controller 存在,是因为框架的通用 CRUD + 存储过程分发路径不足以表达对应用例。换句话说,每一个都是数据驱动论点停止扩展的位置标记。
即使它们不属于框架目录化接口面,也值得枚举:它们展示了 xly 哪些内容硬编码在 Java 里,哪些内容留给元数据。维护人员读这些 controller,能直接看到框架逃生口的形状。
命名空间重叠。
BusinessBaseController(/business/*)和QuoquotationController(同样@RequestMapping("/business"))共享 URL 前缀。Spring 会按方法级路径解析,所以/business/addQuotationsheet和/business/getQuoquotationProgress落在QuoquotationController,其他/business/*端点落在BusinessBaseController。当前没有方法路径冲突,因此能正常工作;但这个约定很容易踩坑:未来如果有人在BusinessBaseController里新增@PostMapping("/addQuotationsheet"),就会悄悄遮蔽报价路径。
表单辅助与 SPA 扩展 controller(22)
这些是贴近框架的端点,是通用 CRUD 路径的扩展,但不适合放进 form-master / form-slave 的固定形状里。多数会在同一个 SPA 页面里和 /business/* 一起被调用。
| 端点前缀 | Controller | 角色 |
|---|---|---|
/bill/* |
BillController |
复制单据操作(billCopyToCheck、billCopyToCheckWork):把一组 master + slave 行克隆成新单据。它不放在 /business/* 下,是因为 SPA 需要在一次请求里拿到新 sId 集合,而通用保存端点没有这种响应形状。 |
/change/* |
ChangeController |
通用字段变更重算(changeParam):字段值触发派生重算且需要调用存储过程时,SPA 会调用它。 |
/parameter/* |
BusinessParameterController |
每模块参数读取。 |
/treeclassify/* |
BusinessTreeClassifyController |
表单数据加载的树分组变体:/treeclassify/getTreeClassify/{gdsconfigformmasterId}。它位于 /business/* 之外,是因为响应形状是嵌套树,不是平铺行集。 |
/calcprocedure/* |
CalcProcedureController |
计算公式 功能的运行时侧:/calc 调用命名计算过程。 |
/calculationFormula/* |
CalculationFormulaController |
计算公式的构建侧元数据。 |
/calculationStd/* |
CalculationStdController |
标准计算查找目录。 |
/char/* |
CharController |
BACK 图表配置页面的图表配置 CRUD,包装 gdsconfigcharmaster / slave。 |
/checkModel/* |
CheckmodelController |
审批模型成员读取(getUserListByModelId/{sCheckModeId}),供轻量级(非 Activiti)审批流使用。 |
/comparatorTree/* |
ComparatorTreeController |
可过滤层级选择器使用的比较树读取。 |
/excel/* |
ExcelController |
网格 Excel 导出:/export/{gdsconfigformmasterId}。它是打印的兄弟路径,但输出数据而不是报表版式。 |
/import/* |
ImportExcelController |
Excel 导入:先 /checkExcel 校验,再提交。插入前会按表单 slave 定义验证。 |
/filterTree/* |
FilterTreeController |
网格过滤用树形下拉。 |
/notClear/* |
NotClearController |
条码扫描“未清”保存路径(doNotClearSave、getNotClearScanData/{sProcName}/{sId}),特定于扫描驱动的仓库流程。 |
/notice/* |
NoticeController |
站内通知获取 / 标记已读。 |
/replaceField/* |
ReplaceFieldController |
跨行批量字段替换。 |
/searchgroupby/* |
SearchgroupbyController |
带 group-by 的保存搜索定义。 |
/searchupdown/* |
SearchUpDownController |
按搜索结果上一条 / 下一条导航,是 /business/getBusinessDataByIndex 的变体。 |
/syssearch/* |
SyssearchController |
保存搜索定义 CRUD。 |
/syssystem/* |
SyssystemController |
系统表读取专用的 getBusinessDataByFormcustomId 变体(/getSyssystemDataByFormcustomId/{gdsconfigformmasterId}),用于全局元数据读取时绕过租户作用域。 |
/sqlfile/* |
SqlFileController |
“Mysql脚本配置”管理页面背后的 SQL 文件加载 / 保存。 |
/instruct/* |
InstructController |
直接执行 SQL 的端点(/exesql、/opensql):管理侧查询控制台。 |
用户与权限管理(4)
同一关注点下有多个重叠 controller。New 后缀,以及 sftlogininfo、userinfo、gdslogininfo(在 systemweb/ 中)同时存在,说明这里有一次迁移中的重构:旧路径和新路径会并存,直到调用方迁移完成。
| 端点前缀 | Controller | 角色 |
|---|---|---|
/userinfo/* |
UserInfoController |
当前用户资料与 session 信息。 |
/sftlogininfo/* |
SftlogininfoController |
用户账号 CRUD(两条路径中较新的一个)。 |
/sysjurisdiction/* |
SysjurisdictionController |
用户组 / 用户权限读取(getGroupData、getUserData)。 |
/sysjurisdictionNew/* |
SysjurisdictionNewController |
较新的并行路径(getGroupDataNew、getGroupUserIdNew/{sUserId})。关注点相同,形状不同。 |
生产 / MES(7)
这些是行业层流程;它们的状态机、多表连接或硬件集成无法只靠 gdsconfigformmaster SQL 表达。这是框架中硬编码业务逻辑最集中的一组。
| 端点前缀 | Controller | 角色 |
|---|---|---|
/sysworkorder/* |
WorkOrderController |
带副作用的工单 CRUD(/add、/update/{sId}):印刷行业工单会跨很多 slave 和存储过程调用,通用保存端点无法原子串起这些操作。 |
/workOrderFlow/* |
WorkOrderFlowController |
工单工艺路线 / 流程读取(getWorkOrderFlow、getSplitWorkOrderData/{sId})。 |
/workOrderPlan/* |
WorkOrderPlanController |
连接工单与计划行的生产计划读取(getControlProcess/{sProductionPlanId}、getProductionPlanInfo)。 |
/splitWorkOrder/* |
SplitWorkOrderController |
把一个主工单拆成多个子工单(getSplitWorkOrderData)。 |
/productionPlan/* |
ProductionPlanController |
计划树读取(getProductionPlanTree)。 |
/process/* |
ProcessController |
生产工序目录读取。 |
/oee/* |
OeeController |
OEE(Overall Equipment Effectiveness,设备综合效率):条码扫描和 MES 状态回调(updateBarcode/{sBarCodeId}/{sBarCode}、doSysMesMsg/{sStatus}/{sMachineId})。 |
销售、库存、财务、采购、人事(9)
| 端点前缀 | Controller | 角色 |
|---|---|---|
/salesorder/* |
SalesOrderController |
超出通用 CRUD 的销售订单专用逻辑。 |
/business/addQuotationsheet、/business/getQuoquotationProgress
|
QuoquotationController |
报价单创建(长运行,因此有进度端点)。注意:它和 BusinessBaseController 共享 /business/* 前缀,见上面的命名空间重叠说明。 |
/eleMaterialsStock/* |
EleMaterialsStockController |
原材料库存读取(getEleMaterialsStock、getEleMaterialsStoreCurrQty)。 |
/eleProductStock/* |
EleProductStockController |
成品库存读取。 |
/costCenter/* |
CostCenterController |
成本中心数据与凭证导入(getCostCenterData、getCosvoucherImportData)。 |
/sysAccountPeriod/* |
SysAccountPeriodController |
会计期间启用 / 关闭逻辑。 |
/erpOrderProcurement/* |
ErpOrderProcurementController |
采购订单专用逻辑。 |
/sisproductclassify/* |
SisproductclassifyController |
产品分类树。 |
/eleteamemployee/* |
EleteamemployeeController |
车间流程中的班组 / 员工分配。 |
集成与硬件(5)
| 端点前缀 | Controller | 角色 |
|---|---|---|
/file/* |
FileController |
文件上传,包括微信移动端变体 mobileuploadwechat。 |
/plc/* |
PlcController |
PLC 桥接入口(getplcMachine/{iOrder}/{sParentId}),见切片 6。 |
/mobilephone/* |
MobliePhoneController |
移动 App 端点。(类名中的 Moblie 拼写错误来自源码;URL 是 /mobilephone。) |
/sysWebsocket/* |
SysWebSocketController |
推送通知的 WebSocket 建立 / 关闭。 |
/wechat/* |
WechatController |
微信集成(站内二维码、OAuth 回调)。 |
按首页范围说明排除(5)
为完整性列出;它们不属于本框架 Wiki 的范围内接口面,但确实存在于 WAR 中。
| 端点前缀 | Controller | 状态 |
|---|---|---|
/ai/* |
AiController |
AI assistant。范围外(见 index.md)。 |
/robot/* |
ChatGptController |
ChatGPT 集成。范围外(见 index.md)。 |
/test/* |
TestController |
开发脚手架(/file、/getDinkToken)。 |
| (根路径) | TestProcessController |
开发脚手架;没有类级 @RequestMapping。 |
| (已注释) | XsController |
死文件:@RestController 和 @RequestMapping 都被注释掉;类存在,但不会注册任何端点。 |
把这些 controller 当作诊断线索
扫完整个列表后,三个模式很明显:
-
长运行或多步骤事务(
QuoquotationController.getQuoquotationProgress、BillController.billCopyToCheck、SplitWorkOrderController):通用保存是一次性请求;任何需要进度端点,或“克隆后跳转”语义的流程,都需要自己的 controller。 -
行业专用状态机(
OeeController、工单家族、SysAccountPeriodController):当“下一个合法状态”不能从单个列推出时,存储过程分发路径就不够用了,controller 会在 Java 中串起编排逻辑。 -
硬件或外部系统(
PlcController、WechatController、SysWebSocketController、FileController):凡是不只是“MySQL + HTTP”的能力,都需要 Java 胶水;元数据无法描述入站 websocket 或串口握手。
这些 controller 的职责,正好就是框架通用运行时没有覆盖的部分。
这个 API 不是什么
- 不是稳定接口。 端点形状会随框架变化。
- 不是给外部调用方认证的接口。 这里没有 API key 流程;cookie/session 不是集成方需要的东西。
- 不是自助式公开文档。 这个接口面太大、太通用了,不适合发布成 OpenAPI 文档。外部集成方应该使用经过收敛的外部 API。