
核心解决 "配置→SQL 正向转化" 和 "SQL→配置反向解析" 的双向一致性问题,通过 **"中间配置模型"** 作为桥梁,避免直接解析 SQL 的复杂性,确保用户可重复编辑、查看配置。
一、核心设计:中间配置模型(替代直接解析 SQL)
不直接将用户操作映射为 SQL,而是先转化为一个结构化的 "中间配置模型"(JSON 格式),再基于该模型生成 SQL;反向解析时,也不解析 SQL,而是直接读取这个中间模型,实现双向可逆。
中间配置模型结构(示例)
json
{
"configId": "1001", // 配置唯一ID
"userId": "2001", // 所属用户
"realmSn": "77980225d52fd66561bcc7df2f20190c96b86d2090002", // 所属文件
"statIndicators": [ // 统计指标(对应SELECT)
{
"fieldKey": "in_quantity", // 开发配置的字段标识
"fieldName": "进货数量", // 前端显示名
"calcType": "SUM", // 计算方式
"dbLogic": "CASE WHEN table_sn='进货表SN' THEN param6 ELSE 0 END" // 数据库层逻辑(开发配置,用户不可见)
},
{
"fieldKey": "stock_quantity",
"fieldName": "库存数量",
"calcType": "CUSTOM", // 自定义计算
"customLogic": {
"type": "SUBTRACT", // 计算类型:减法
"leftFieldKey": "in_quantity", // 左操作数(关联其他指标)
"rightFieldKey": "out_quantity" // 右操作数
}
}
],
"groupFields": [ // 分组维度(对应GROUP BY)
{
"fieldKey": "goods_category",
"fieldName": "商品分类",
"dbField": "param3" // 数据库真实字段
}
],
"filters": [ // 筛选条件(对应WHERE)
{
"fieldKey": "stat_date",
"fieldName": "统计日期",
"condition": "BETWEEN",
"value1": "2025-01-01",
"value2": "2025-01-31",
"dbLogic": "table_sn IN ('进货表SN','出货表SN') AND param4 BETWEEN #{value1} AND #{value2}"
},
{
"fieldKey": "sys_realm", // 系统级筛选(用户不可见)
"fieldName": "所属文件",
"condition": "EQ",
"value1": "77980225d52fd66561bcc7df2f20190c96b86d2090002",
"isSystem": true
}
]
}
二、双向转化流程(正向 + 反向)
1. 正向转化:用户配置→中间模型→SQL
-
第一步:用户操作生成中间模型 用户在前端勾选 "统计指标""分组""筛选" 时,前端直接按中间模型的结构组装 JSON(无需接触 SQL)。例:用户选 "进货数量求和"→ 前端自动填充
statIndicators
中的fieldKey
"in_quantity"、calcType
"SUM",dbLogic
从开发配置的字段映射表中读取。 -
第二步:中间模型生成 SQL后端接收中间模型,按预设规则拼接 SQL:
- 统计指标→
SELECT
:遍历statIndicators
,将dbLogic
用calcType
包裹(如SUM(CASE...)
)。 - 分组→
GROUP BY
:遍历groupFields
,拼接dbField
(如param3
)。 - 筛选→
WHERE
:遍历filters
,拼接dbLogic
,系统级筛选(isSystem=true
)强制拼在前面。
- 统计指标→
2. 反向转化:中间模型→用户配置(无需解析 SQL)
当用户需要 "查看 / 修改已保存的配置" 时,后端直接返回中间模型,前端解析模型并还原界面状态,完全不涉及 SQL 解析:
- 还原统计指标:根据
statIndicators
中的fieldKey
,在前端勾选对应的字段,自动选中calcType
。 - 还原分组:根据
groupFields
,在分组区显示已选的 "商品分类" 等维度。 - 还原筛选:根据
filters
,在筛选区显示字段、条件和值(如 "统计日期介于 2025-01-01 至 2025-01-31")。
关键优势:
- 避免解析 SQL 的复杂性:SQL 是中间产物,反向还原依赖的是结构化的中间模型,而非复杂的 SQL 语法解析(无需处理嵌套子查询、函数嵌套等问题)。
- 一致性保障:正向和反向都基于同一套中间模型,不会出现 "配置→SQL→配置" 的信息丢失或错乱。
三、解决 "填错 / 查看" 问题的具体设计
1. 实时校验与错误提示(避免填错)
- 前端校验 :
- 统计指标冲突:如用户同时选 "进货数量(文本类型)" 和 "求和",前端直接提示 "文本类型字段不支持求和"(基于开发配置的 "字段类型" 和 "是否可统计")。
- 筛选条件合法:如日期字段输入非日期格式,输入框实时标红提示。
- 后端校验 :
- 生成 SQL 前,校验中间模型的完整性(如分组字段不能为空时提示 "请选择分组维度")。
- 执行 SQL 前,用 "测试查询"(limit 1)验证 SQL 语法,出错时返回用户可理解的提示(如 "筛选条件的值超出范围")。
2. 配置历史与版本回溯(填错可回滚)
- 每次保存配置时,生成新的版本(保留历史版本),用户可查看 "版本记录"(包含修改时间、修改人、修改内容摘要)。
- 支持 "回滚到上一版本":当发现当前配置错误时,点击版本记录中的 "回滚",直接恢复到之前的中间模型状态。
3. 配置预览与 SQL 查看(进阶用户可校验)
- 普通用户:预览时显示 "统计结果表格 + 图表",直观判断配置是否正确。
- 进阶用户(如管理员):可点击 "查看 SQL"(只读),显示生成的 SQL 语句(但无法修改),用于技术排查。
- 开发配置的 "dbLogic" 对普通用户隐藏,仅管理员可在后台查看。
四、双向转化的难点与解决方案
难点 | 解决方案 |
---|---|
自定义复杂计算(如 "毛利 =(售价 - 成本)* 销量") | 中间模型的customLogic 支持 "组合计算",用fieldKey 关联多个基础指标,如(A-B)*C ,正向转化时拼接对应的CASE WHEN 嵌套逻辑,反向时解析customLogic 的结构还原操作数。 |
多级分组与复杂筛选(如 "分组 1 + 分组 2+3 个筛选条件") | 中间模型的groupFields 和filters 用数组存储,正向按顺序拼接 SQL,反向按顺序还原界面选项,保持顺序一致。 |
系统级筛选与用户筛选的区分 | 中间模型中filters 的isSystem 字段标记系统级筛选,前端不显示这些配置项,但反向还原时保留(确保安全条件不丢失)。 |
五、总结
这套方案通过 "中间配置模型" 绕开了直接解析 SQL 的高难度问题,实现了 "用户配置→中间模型→SQL" 的正向转化和 "中间模型→用户配置" 的反向还原,确保:
- 普通用户可重复编辑、查看配置,无需懂 SQL;
- 进阶用户可查看 SQL 用于校验;
- 开发人员通过配置中间模型的规则,灵活扩展功能,无需修改双向转化的核心逻辑。
和你之前的设计相比,只是多了 "中间模型" 这一层,但解决了 "反向解析" 的核心痛点,同时保留了用户操作的灵活性和数据安全性,复杂度可控。
阿雪技术观
让我们积极投身于技术共享的浪潮中,不仅仅是作为受益者,更要成为贡献者。无论是分享自己的代码、撰写技术博客,还是参与开源项目的维护和改进,每一个小小的举动都可能成为推动技术进步的巨大力量
Embrace open source and sharing, witness the miracle of technological progress, and enjoy the happy times of humanity! Let's actively join the wave of technology sharing. Not only as beneficiaries, but also as contributors. Whether sharing our own code, writing technical blogs, or participating in the maintenance and improvement of open source projects, every small action may become a huge force driving technological progrss.