ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

致远OA实施中,使用groovy自定义函数实现客户需求-时间校验

2026/8/15 10:33:48 拓冰建站 浏览量
致远OA实施中,使用groovy自定义函数实现客户需求-时间校验 摘要本文针对致远表单绘制工具中时间计算功能的不足通过自定义函数提供了两种实用解决方案一是校验明细表中同一员工的日期时间段是否重叠避免重复上报二是精确计算两个日期时间之间的小时差满足特殊业务规则。文章详细说明了参数类型识别、Groovy代码实现、函数调用方法及实际效果验证为开发者提供了可直接复用的代码示例。在表单绘制工具中对于时间的计算公式致远只提供了日期差和日期时间差可以算出两个时间中间的差额。但对于时间需要校验的场景和计算的情况很多会存在系统校验无法满足的情况。那我们怎么在自定义函数中来做校验呢首先要用函数来做校验得先知道参数类型是什么小编之前一直以为时间控件的类型是Date类型写完函数上了系统一直无效。后面才在去去了类型看结果是字符串类型。。。我们可以使用getClass方法去取控件里数据的类型查看。def timeType param[0] return timeType.getClass().name一、校验明细表中日期是否重叠现在有调休申请单需要客户输入员工的加班开始日期和加班结束日期要求同一个员工的加班时间不能报重叠比如第一行第二行都是张三上报的加班信息一行加班日期 8-13 -- 8-15 第二行8-14 -- 8-15,则重复上报加班这种情况咋给校验呢首先一定得明确参数类型如果要校验全部的明细表数据就得取明细全量数据。如果我把明细字段传入自定义函数的参数列表得到的是什么类型的参数我们依旧用getClass方法看看。可以看出明细参数是个List列表并且开始时间、结束时间、员工编号三列都是单独的等长的三组列表。并且根据索引一一对应。找到对应关系那这校验就好做了。def startStrList param[0] def endStrList param[1] def personCodeList param[2] def parseDay { str - Date.parse(yyyy-MM-dd, str).time } try { def ranges [] startStrList.eachWithIndex { s, idx - long sTime parseDay(s) long eTime parseDay(endStrList[idx]) String userCode personCodeList[idx] ranges.add([ index: idx, person: userCode, start: sTime, end: eTime ]) } def overlapIndexArr [] int len ranges.size() for (int i 0; i len; i) { def a ranges[i] for (int j i 1; j len; j) { def b ranges[j] if (a.person b.person a.start b.end b.start a.end) { overlapIndexArr.add((${a.person}${a.index1}行与${b.index1}行)) } } } return overlapIndexArr.isEmpty() ? 0 : 请检查以下行中存在重叠日期 overlapIndexArr.join( ) } catch (Exception err) { return err.getMessage() }参数如果要直接复制代码使用参数顺序一定不能写错。日期控件传来的参数是字符串类型如果算时间差首先得转成Date类型。Groovy 为 java.util.Date 添加了静态扩展方法Date.parse(pattern, 字符串)这个方法等价于 new SimpleDateFormat(yyyy-MM-dd).parse(str) 方法。我们可以把它封装到一个内部闭包中方便后续调用闭包是一段可以单独打包、可以随时调用的可执行代码块相当于 Java 的方法但它是变量可以定义在方法里面也就是内部闭包。接收三组下标对应的数组开始日期、结束日期、人员编码先将日期字符串转为毫秒时间戳封装成时间段对象采用双层循环两两比对所有时间段只校验同一人员依靠区间重叠公式判断时间冲突记录冲突行号无重叠返回 0存在重叠输出提示信息。返回结果正常填写情况存在重叠数据时二、计算两个日期时间相差多少小时现在有这么个需求客户公司要求出差补助规则结束时间-开始时间满24小时算一天按一天来报48小时算两天且不满24小时不报。虽然规则很不合理但得按客户要求来做现在小编使用的版本没有小时差的公式且日期时间差算出来结果如下如果算成天还得再转为小时就更麻烦了。那有函数能算出小时差吗有的兄弟有的 。但可能是小编技术有限或是系统限制我只能算到一个文本控件上再把文本控件转为数字所以这个函数仅供参考蛤首先加一个文本控件函数如下def startStr param[0] def endStr param[1] try { long sTime Date.parse (yyyy-MM-dd HH:mm,startStr).time long eTime Date.parse (yyyy-MM-dd HH:mm,endStr).time long ms Math.abs (eTime - sTime) def hourNum Math.floor (ms / (1000 * 60 * 60d)) return ${hourNum} 小时 } catch (Exception err) { return err.getMessage () }接收起止时间yyyy‑MM‑dd HH:mm解析成毫秒时间戳求取时间差绝对值换算小时之后向下取整返回整数小时文本不足一小时会直接舍弃例如相差 59 分钟返回0小时。结果再加一个数字控件用来把文本的408.0小时转为数字408def str param[0] try{ if(!str) return BigDecimal.ZERO def matcher (str ~ /([0-9]\.?[0-9]*)/) if(matcher.find()){ String numStr matcher.group(1) return new BigDecimal(numStr) } return BigDecimal.ZERO }catch (Exception e){ return BigDecimal.ZERO }然后就能根据时间差来算天数了