diff --git a/pom.xml b/pom.xml index 4b5489047..6adca2944 100644 --- a/pom.xml +++ b/pom.xml @@ -441,5 +441,10 @@ dingtalk-sdk 1.0-20210901 + + cn.hutool + hutool-core + 5.7.22 + diff --git a/src/main/java/com/rebuild/core/service/trigger/aviator/AviatorDate.java b/src/main/java/com/rebuild/core/service/trigger/aviator/AviatorDate.java index 941f7516a..0d1369af1 100644 --- a/src/main/java/com/rebuild/core/service/trigger/aviator/AviatorDate.java +++ b/src/main/java/com/rebuild/core/service/trigger/aviator/AviatorDate.java @@ -20,6 +20,7 @@ import java.util.Map; public class AviatorDate extends AviatorObject { private static final long serialVersionUID = 2930549924386648595L; + protected static final String DU_MINUTE= "I"; protected static final String DU_HOUR = "H"; protected static final String DU_DAY = "D"; protected static final String DU_MONTH = "M"; diff --git a/src/main/java/com/rebuild/core/service/trigger/aviator/DateAddFunction.java b/src/main/java/com/rebuild/core/service/trigger/aviator/DateAddFunction.java index be8a1d54d..4247a79c6 100644 --- a/src/main/java/com/rebuild/core/service/trigger/aviator/DateAddFunction.java +++ b/src/main/java/com/rebuild/core/service/trigger/aviator/DateAddFunction.java @@ -10,6 +10,7 @@ package com.rebuild.core.service.trigger.aviator; import cn.devezhao.commons.CalendarUtils; import cn.devezhao.commons.ObjectUtils; import com.googlecode.aviator.runtime.function.AbstractFunction; +import com.googlecode.aviator.runtime.type.AviatorNil; import com.googlecode.aviator.runtime.type.AviatorObject; import java.util.Calendar; @@ -30,28 +31,35 @@ public class DateAddFunction extends AbstractFunction { public AviatorObject call(Map env, AviatorObject arg1, AviatorObject arg2) { Object o = arg1.getValue(env); Date date = o instanceof Date ? (Date) o : CalendarUtils.parse(o.toString()); + if (date == null) { + return AviatorNil.NIL; + } + String interval = arg2.getValue(env).toString(); - int intervalUnit = Calendar.DATE; + int unit4Interval = Calendar.DATE; // default - if (interval.endsWith(AviatorDate.DU_DAY)) { + if (interval.endsWith(AviatorDate.DU_MINUTE)) { + interval = interval.substring(0, interval.length() - 1); + unit4Interval = Calendar.MINUTE; + } else if (interval.endsWith(AviatorDate.DU_HOUR)) { + interval = interval.substring(0, interval.length() - 1); + unit4Interval = Calendar.HOUR_OF_DAY; + } else if (interval.endsWith(AviatorDate.DU_DAY)) { interval = interval.substring(0, interval.length() - 1); } else if (interval.endsWith(AviatorDate.DU_MONTH)) { interval = interval.substring(0, interval.length() - 1); - intervalUnit = Calendar.MONTH; + unit4Interval = Calendar.MONTH; } else if (interval.endsWith(AviatorDate.DU_YEAR)) { interval = interval.substring(0, interval.length() - 1); - intervalUnit = Calendar.YEAR; - } else if (interval.endsWith(AviatorDate.DU_HOUR)) { - interval = interval.substring(0, interval.length() - 1); - intervalUnit = Calendar.HOUR_OF_DAY; + unit4Interval = Calendar.YEAR; } - Date newDate = dateCalc(date, ObjectUtils.toInt(interval), intervalUnit); + Date newDate = dateAdd(date, ObjectUtils.toInt(interval), unit4Interval); return new AviatorDate(newDate); } - protected Date dateCalc(Date date, int interval, int field) { + protected Date dateAdd(Date date, int interval, int field) { return CalendarUtils.add(date, interval, field); } diff --git a/src/main/java/com/rebuild/core/service/trigger/aviator/DateDiffFunction.java b/src/main/java/com/rebuild/core/service/trigger/aviator/DateDiffFunction.java index 5b9b35edd..51914b0b7 100644 --- a/src/main/java/com/rebuild/core/service/trigger/aviator/DateDiffFunction.java +++ b/src/main/java/com/rebuild/core/service/trigger/aviator/DateDiffFunction.java @@ -8,11 +8,16 @@ See LICENSE and COMMERCIAL in the project root for license information. package com.rebuild.core.service.trigger.aviator; import cn.devezhao.commons.CalendarUtils; +import cn.devezhao.commons.ObjectUtils; +import cn.hutool.core.date.DateUnit; +import cn.hutool.core.date.DateUtil; import com.googlecode.aviator.exception.ExpressionSyntaxErrorException; import com.googlecode.aviator.runtime.function.AbstractFunction; import com.googlecode.aviator.runtime.type.AviatorLong; +import com.googlecode.aviator.runtime.type.AviatorNil; import com.googlecode.aviator.runtime.type.AviatorObject; import com.googlecode.aviator.runtime.type.AviatorString; +import com.rebuild.core.Application; import lombok.extern.slf4j.Slf4j; import java.util.Date; @@ -29,6 +34,17 @@ import java.util.Map; public class DateDiffFunction extends AbstractFunction { private static final long serialVersionUID = 5778729290544711131L; + private boolean isUseMysql; + + protected DateDiffFunction() { + this(Boolean.FALSE); + } + + protected DateDiffFunction(boolean isUseMysql) { + super(); + this.isUseMysql = isUseMysql; + } + @Override public AviatorObject call(Map env, AviatorObject arg1, AviatorObject arg2) { return call(env, arg1, arg2, new AviatorString(AviatorDate.DU_DAY)); @@ -38,31 +54,50 @@ public class DateDiffFunction extends AbstractFunction { public AviatorObject call(Map env, AviatorObject arg1, AviatorObject arg2, AviatorObject arg3) { Object o1 = arg1.getValue(env); Date date1 = o1 instanceof Date ? (Date) o1 : CalendarUtils.parse(o1.toString()); + if (date1 == null) { + return AviatorNil.NIL; + } + Object o2 = arg2.getValue(env); Date date2 = o2 instanceof Date ? (Date) o2 : CalendarUtils.parse(o2.toString()); + if (date2 == null) { + return AviatorNil.NIL; + } + if (arg3.getValue(env) == null) { throw new ExpressionSyntaxErrorException("`dateUnit` cannot be null"); } + String dateUnit = arg3.getValue(env).toString(); - if (date1 == null) { - log.warn("Parseing date1 error : `{}`. Use default", o1); - date1 = CalendarUtils.now(); + if (isUseMysql) { + String mysqlUnit = "DAY"; + if (AviatorDate.DU_YEAR.equalsIgnoreCase(dateUnit)) mysqlUnit = "YEAR"; + else if (AviatorDate.DU_MONTH.equalsIgnoreCase(dateUnit)) mysqlUnit = "MONTH"; + else if (AviatorDate.DU_HOUR.equalsIgnoreCase(dateUnit)) mysqlUnit = "HOUR"; + else if (AviatorDate.DU_MINUTE.equalsIgnoreCase(dateUnit)) mysqlUnit = "MINUTE"; + + // 利用 MySQL 计算,可预期 + String mysql = String.format("select TIMESTAMPDIFF(%s, '%s', '%s')", + mysqlUnit, + CalendarUtils.getUTCDateTimeFormat().format(date1), + CalendarUtils.getUTCDateTimeFormat().format(date2)); + Object[] res = Application.getPersistManagerFactory().createNativeQuery(mysql).unique(); + + return AviatorLong.valueOf(ObjectUtils.toLong(res[0])); + + } else { + + long res = 0; + + if (AviatorDate.DU_YEAR.equalsIgnoreCase(dateUnit)) res = DateUtil.betweenYear(date1, date2, true); + else if (AviatorDate.DU_MONTH.equalsIgnoreCase(dateUnit)) res = DateUtil.betweenMonth(date1, date2, true); + else if (AviatorDate.DU_DAY.equalsIgnoreCase(dateUnit)) res = DateUtil.betweenDay(date1, date2, true); + else if (AviatorDate.DU_HOUR.equalsIgnoreCase(dateUnit)) res = DateUtil.between(date1, date2, DateUnit.HOUR, false); + else if (AviatorDate.DU_MINUTE.equalsIgnoreCase(dateUnit)) res = DateUtil.between(date1, date2, DateUnit.MINUTE, false); + + return AviatorLong.valueOf(res); } - if (date2 == null) { - log.warn("Parseing date2 error : `{}`. Use default", o2); - date2 = CalendarUtils.now(); - } - - long timeLeft = date1.getTime() - date2.getTime(); - timeLeft = timeLeft / 1000 / 60 / 60; // hours - - if (AviatorDate.DU_MONTH.equalsIgnoreCase(dateUnit)) timeLeft = timeLeft / 30; // FIXME 月固定30天 - else if (AviatorDate.DU_YEAR.equalsIgnoreCase(dateUnit)) timeLeft = timeLeft / 365; // FIXME 年固定365天 - else if (AviatorDate.DU_HOUR.equalsIgnoreCase(dateUnit)) ; - else timeLeft = timeLeft / 24; - - return AviatorLong.valueOf(timeLeft); } @Override diff --git a/src/main/java/com/rebuild/core/service/trigger/aviator/DateSubFunction.java b/src/main/java/com/rebuild/core/service/trigger/aviator/DateSubFunction.java index 830801f48..c1bf957f6 100644 --- a/src/main/java/com/rebuild/core/service/trigger/aviator/DateSubFunction.java +++ b/src/main/java/com/rebuild/core/service/trigger/aviator/DateSubFunction.java @@ -20,8 +20,8 @@ public class DateSubFunction extends DateAddFunction { private static final long serialVersionUID = -8857066285235050207L; @Override - protected Date dateCalc(Date date, int interval, int field) { - return super.dateCalc(date, -interval, field); + protected Date dateAdd(Date date, int interval, int field) { + return super.dateAdd(date, -interval, field); } @Override diff --git a/src/main/java/com/rebuild/core/service/trigger/aviator/LocationDistanceFunction.java b/src/main/java/com/rebuild/core/service/trigger/aviator/LocationDistanceFunction.java index fab13b51b..ec37768b9 100644 --- a/src/main/java/com/rebuild/core/service/trigger/aviator/LocationDistanceFunction.java +++ b/src/main/java/com/rebuild/core/service/trigger/aviator/LocationDistanceFunction.java @@ -10,6 +10,7 @@ package com.rebuild.core.service.trigger.aviator; import cn.devezhao.commons.ObjectUtils; import com.googlecode.aviator.runtime.function.AbstractFunction; import com.googlecode.aviator.runtime.type.AviatorDouble; +import com.googlecode.aviator.runtime.type.AviatorNil; import com.googlecode.aviator.runtime.type.AviatorObject; import com.rebuild.core.metadata.MetadataHelper; import lombok.extern.slf4j.Slf4j; @@ -31,14 +32,12 @@ public class LocationDistanceFunction extends AbstractFunction { public AviatorObject call(Map env, AviatorObject arg1, AviatorObject arg2) { final double[] L1s = parseLngLat(arg1.getValue(env).toString()); if (L1s == null) { - log.warn("Bad lnglat(1) format : {}", arg1.getValue(env)); - return AviatorDouble.valueOf(0); + return AviatorNil.NIL; } final double[] L2s = parseLngLat(arg2.getValue(env).toString()); if (L2s == null) { - log.warn("Bad lnglat(2) format : {}", arg2.getValue(env)); - return AviatorDouble.valueOf(0); + return AviatorNil.NIL; } double LNG1 = L1s[0]; diff --git a/src/main/java/com/rebuild/core/service/trigger/aviator/RequestFunctuin.java b/src/main/java/com/rebuild/core/service/trigger/aviator/RequestFunctuin.java index 66069b019..da20ad95d 100644 --- a/src/main/java/com/rebuild/core/service/trigger/aviator/RequestFunctuin.java +++ b/src/main/java/com/rebuild/core/service/trigger/aviator/RequestFunctuin.java @@ -8,6 +8,7 @@ See LICENSE and COMMERCIAL in the project root for license information. package com.rebuild.core.service.trigger.aviator; import com.googlecode.aviator.runtime.function.AbstractFunction; +import com.googlecode.aviator.runtime.type.AviatorNil; import com.googlecode.aviator.runtime.type.AviatorObject; import com.googlecode.aviator.runtime.type.AviatorString; import com.rebuild.utils.HttpUtils; @@ -29,7 +30,7 @@ public class RequestFunctuin extends AbstractFunction { @Override public AviatorObject call(Map env, AviatorObject arg1) { - return call(env, arg1, null); + return call(env, arg1, AviatorNil.NIL); } @Override diff --git a/src/test/java/com/rebuild/core/service/trigger/aviator/AviatorUtilsTest.java b/src/test/java/com/rebuild/core/service/trigger/aviator/AviatorUtilsTest.java index 88b7c344b..e71b494b5 100644 --- a/src/test/java/com/rebuild/core/service/trigger/aviator/AviatorUtilsTest.java +++ b/src/test/java/com/rebuild/core/service/trigger/aviator/AviatorUtilsTest.java @@ -33,14 +33,11 @@ class AviatorUtilsTest { @Test void func() { - Object result = AviatorUtils.evalQuietly("DATEDIFF('2021-01-01 18:17:00', '2021-01-01 16:17:00', 'H')"); - System.out.println(result); + AviatorUtils.evalQuietly("p(DATEDIFF('2022-03-03 17:31:24', '2022-03-04 17:30:24', 'D'))"); - result = AviatorUtils.evalQuietly("DATEADD('2021-01-01 18:17:00', '2H')"); - System.out.println(result); + AviatorUtils.evalQuietly("p(DATEADD('2021-01-01 18:17:00', '2H'))"); - result = AviatorUtils.evalQuietly("DATESUB('2021-01-01 18:17:00', '1')"); - System.out.println(result); + AviatorUtils.evalQuietly("p(DATESUB('2021-01-01 18:17:00', '1'))"); } @Test