事件数据校验与复选框参数传递实战避坑

楼主
会点编程、RPA的CPAer

核心一:按钮多事件机制与优雅阻断(⭐⭐⭐⭐⭐)

在 FineReport 中,一个按钮可以绑定多个“点击”事件,系统会严格按照事件面板中从上到下的顺序依次执行。将“校验”和“业务”拆分为两个独立事件,是保持代码清晰的最佳实践。

💡 最佳实践:逻辑拆分

  • 事件 1(排在上方):纯校验逻辑。获取控件值,判断是否为空。如果不合规,弹窗提醒并返回 false 阻断后续事件
  • 事件 2(排在下方):纯业务逻辑(如导出、跳转)。不需要再写任何校验代码,只负责执行核心功能。

📝 事件 1:必填项校验(标准代码模板)

// 封装校验函数,提高代码复用性
function checkRequired() {
    var dateVal = _g().getWidgetByName("kxfs_date").getValue();
    var areaArr = _g().getWidgetByName("dqgs_name").getValue();
 
    // 1. 校验单选控件
    if (dateVal === null || dateVal === undefined || dateVal === "") {
        // 推荐使用 FineReport 内置弹窗,样式更美观且绝对居中
        FR.Msg.alert("提示", "【考核方式日期】为必选项,请先进行选择!");
        return false; 
    }
 
    // 2. 校验多选控件(注意:多选未选时可能是空数组 [])
    var isAreaEmpty = (
        areaArr === null || 
        areaArr === undefined || 
        areaArr === "" || 
        (Array.isArray(areaArr) && areaArr.length === 0)
    );
 
    if (isAreaEmpty) {
        FR.Msg.alert("提示", "【地区】为必选项,请先进行选择!");
        return false; 
    }
 
    return true; // 全部校验通过
}

// 【核心阻断机制】:如果校验函数返回 false,则当前事件直接返回 false
// FineReport 引擎接收到 false 后,会彻底中断事件链,不会执行下方的“事件2”
if (!checkRequired()) {
    return false; 
}

核心二:参数面板按钮跳转的“唯一正确姿势”(⭐⭐⭐⭐)

很多开发者想在参数面板的按钮上直接配置超链接跳转,但经过实测确认:参数面板中的“按钮控件”没有“超链接”属性,且“标签控件”也不支持超链接功能。

🛠️ 唯一解决方案:使用 JS 点击事件

既然无法通过属性面板配置,就必须在按钮的“点击事件”中编写 JS 代码来实现跳转。

// 1. 获取参数面板控件值(必须使用 getParameterContainer)
var val = _g().getParameterContainer().getWidgetByName("控件名").getValue();

// 2. 拼接目标报表的 URL 及参数
// 【注意】:请将 "您的路径/目标报表.cpt" 替换为真实的报表路径
var url = "${servletURL}?viewlet=您的路径/目标报表.cpt&参数名=" + val;

// 3. 执行跳转(双重编码防止中文或特殊字符乱码)
// 【当前窗口跳转】
window.location = encodeURI(encodeURI(url));

// 【补充】:如果希望【在新窗口打开】,请注释掉上一行,使用下面这行:
// window.open(encodeURI(encodeURI(url)));

核心三:大数据集导出接口的 JS 参数拼接规则(⭐⭐⭐⭐)

在调用 _g().directExportToExcel 等需要传递 JSON 格式参数的接口时,引号的规则极其严格,直接决定了底层 SQL 能否正确解析。如果导出的 Excel 表头正常但数据为空,90% 是这里出了问题。

📌 黄金法则

  • 单选参数:外层使用单引号 '
    • 示例kxfs_date:'2023-10-01'
  • 多选参数:外层使用双引号 ",且内部值之间只用逗号分隔,绝对不能加单引号
    • 示例dqgs_name:"北京,上海,广州" (✅ 正确)
    • 错误示例dqgs_name:"'北京','上海'" (❌ 会导致 SQL 解析报错或查不出数据)

📝 拼接代码模板

// 处理多选值:如果是数组,用逗号 join 成字符串
var areaStr = Array.isArray(areaArr) ? areaArr.join(",") : areaArr;

// 拼接 JSON 字符串(注意引号的嵌套)
var paramStr_raw = "{kxfs_date:'" + dateVal + "',dqgs_name:\"" + areaStr + "\"}";

// URL 编码(防止中文或特殊字符乱码)
var paramStr = encodeURIComponent(paramStr_raw);

非常抱歉,在精简整合时确实把您强调的 “官方文档推荐写法导致的认知错位” 以及 “分隔符默认是逗号这个隐蔽坑点” 的细节弱化了。这部分确实是排查起来最让人崩溃的地方。

为您单独重新输出这部分内容,确保所有血泪细节原汁原味地保留:


核心四:多选控件(复选框/下拉框)传参的“终极天坑”(⭐⭐⭐⭐⭐ 血泪教训)

这是 FineReport 开发中“冤案”最多、排查耗时最长的地方。无数人对着数据库和 SQL 查了半天,最后发现竟然是官方文档的推荐写法控件的默认属性“打架”了。

💣 坑的根源:认知错位

  • 官方文档的推荐:文档中写道,如果字段是字符串类型,推荐在 SQL 中加单引号,例如:select * from table where id='${abc}'。因为大部分场景都是单选,大家养成了加单引号的习惯
  • 控件的默认属性:但是!复选框控件、下拉复选框等多选控件,默认的返回值类型是“数组”
  • 悲剧的发生:开发者按照官方文档的习惯,在 SQL 里写了 where id IN ('${abc}'),却忘了控件传过来的是数组,导致解析灾难,且不报错、查不出数据,极难排查!

❌ 致命错误场景(为什么排查了很久?)

假设我们在复选框中勾选了“北京”和“上海”:

  1. 错误场景 1(默认数组 + 习惯性加单引号)
    • 配置:控件保持默认的“数组”,SQL 写 IN ('${abc}')
    • 解析结果IN ('北京,上海')
    • 后果:数据库去寻找一个叫“北京,上海”的城市,绝对查不出数据!
  2. 错误场景 2(改成了字符串 + 默认分隔符 + 加单引号)
    • 配置:把控件返回值改成了“字符串”,但分隔符保留了系统默认的 ,(逗号),SQL 写 IN ('${abc}')
    • 解析结果:控件拼出 北京,上海,代入 SQL 后依然是 IN ('北京,上海')
    • 后果:同样查不出数据!这就是为什么改了返回值类型还是没用,因为分隔符没改

✅ 正确解决方案(二选一,切忌混用)

要完美解决这个问题,必须保证控件配置SQL 宏写法严格匹配。以下两种方案任选其一:

方案 控件返回值类型 控件分隔符设置 SQL 中的宏写法 最终解析结果 适用场景
方案 A
(顺应控件默认)
数组 (默认) 无需设置 IN (${abc})
(绝对不加单引号)
IN ('北京','上海') 不想改控件属性,习惯 SQL 里不加单引号。
方案 B
(顺应文档习惯)
字符串 必须改为 ','
(单引号+逗号+单引号)
IN ('${abc}')
(必须加单引号)
IN ('北京','上海') 习惯 SQL 里加单引号,愿意修改控件分隔符。

⚠️ 重点强调方案 B 的坑
如果您选择方案 B,复选框控件的返回值类型一定要设置为字符串,分隔符默认是 ,,但是不对,必须手动设置为 ','(即:单引号+逗号+单引号)。只有这样,配合 SQL 里的单引号,才能解析出正确的格式。

📝 防坑对照表(建议截图保存)

控件返回值类型 控件分隔符设置 SQL 中的宏写法 最终解析结果 是否正确
数组 (默认) 无需设置 IN (${abc}) IN ('A','B') ✅ 正确
数组 (默认) 无需设置 IN ('${abc}') IN ('A,B') 大坑
字符串 默认 , IN ('${abc}') IN ('A,B') 大坑
字符串 改为 ',' IN ('${abc}') IN ('A','B') ✅ 正确

💡 终极排查利器:查看执行 SQL

无论参数传参遇到什么诡异问题(尤其是导出为空、查不出数据),第一时间去数据集编辑界面,点击工具栏的“查看执行 SQL”按钮
这个功能可以直接看到参数代入后的真实 SQL 语句。只要看一眼生成的 SQL 是否符合数据库语法(比如 IN 里面的单引号位置对不对),99% 的传参问题都能瞬间定位!


🌟 总结与开发习惯建议

  1. 事件职责单一:校验归校验,业务归业务。利用多事件机制和 return false 阻断,让代码逻辑清晰。
  2. 善用内置弹窗:放弃原生的 alert(),使用 FineReport 内置的 FR.Msg.alert("标题", "内容"),弹窗更美观、居中。
  3. 统一团队规范:在团队内部定下规矩,多选控件传参要么全部使用方案A(数组+不加单引号),要么全部使用方案B(字符串+改分隔符为','+加单引号)
  4. 遇事不决“查看执行 SQL”:只要参数传参有问题,直接看最终生成的真实 SQL 语句,让数据库语法来检验你的配置。
分享扩散:

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

返回顶部 返回列表