[enh] trigger func

This commit is contained in:
devezhao 2022-03-02 17:23:41 +08:00
parent 0168872575
commit da7ebcd240
8 changed files with 85 additions and 39 deletions

View file

@ -441,5 +441,10 @@
<artifactId>dingtalk-sdk</artifactId> <artifactId>dingtalk-sdk</artifactId>
<version>1.0-20210901</version> <version>1.0-20210901</version>
</dependency> </dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-core</artifactId>
<version>5.7.22</version>
</dependency>
</dependencies> </dependencies>
</project> </project>

View file

@ -20,6 +20,7 @@ import java.util.Map;
public class AviatorDate extends AviatorObject { public class AviatorDate extends AviatorObject {
private static final long serialVersionUID = 2930549924386648595L; 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_HOUR = "H";
protected static final String DU_DAY = "D"; protected static final String DU_DAY = "D";
protected static final String DU_MONTH = "M"; protected static final String DU_MONTH = "M";

View file

@ -10,6 +10,7 @@ package com.rebuild.core.service.trigger.aviator;
import cn.devezhao.commons.CalendarUtils; import cn.devezhao.commons.CalendarUtils;
import cn.devezhao.commons.ObjectUtils; import cn.devezhao.commons.ObjectUtils;
import com.googlecode.aviator.runtime.function.AbstractFunction; 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.AviatorObject;
import java.util.Calendar; import java.util.Calendar;
@ -30,28 +31,35 @@ public class DateAddFunction extends AbstractFunction {
public AviatorObject call(Map<String, Object> env, AviatorObject arg1, AviatorObject arg2) { public AviatorObject call(Map<String, Object> env, AviatorObject arg1, AviatorObject arg2) {
Object o = arg1.getValue(env); Object o = arg1.getValue(env);
Date date = o instanceof Date ? (Date) o : CalendarUtils.parse(o.toString()); Date date = o instanceof Date ? (Date) o : CalendarUtils.parse(o.toString());
if (date == null) {
return AviatorNil.NIL;
}
String interval = arg2.getValue(env).toString(); 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); interval = interval.substring(0, interval.length() - 1);
} else if (interval.endsWith(AviatorDate.DU_MONTH)) { } else if (interval.endsWith(AviatorDate.DU_MONTH)) {
interval = interval.substring(0, interval.length() - 1); interval = interval.substring(0, interval.length() - 1);
intervalUnit = Calendar.MONTH; unit4Interval = Calendar.MONTH;
} else if (interval.endsWith(AviatorDate.DU_YEAR)) { } else if (interval.endsWith(AviatorDate.DU_YEAR)) {
interval = interval.substring(0, interval.length() - 1); interval = interval.substring(0, interval.length() - 1);
intervalUnit = Calendar.YEAR; unit4Interval = Calendar.YEAR;
} else if (interval.endsWith(AviatorDate.DU_HOUR)) {
interval = interval.substring(0, interval.length() - 1);
intervalUnit = Calendar.HOUR_OF_DAY;
} }
Date newDate = dateCalc(date, ObjectUtils.toInt(interval), intervalUnit); Date newDate = dateAdd(date, ObjectUtils.toInt(interval), unit4Interval);
return new AviatorDate(newDate); 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); return CalendarUtils.add(date, interval, field);
} }

View file

@ -8,11 +8,16 @@ See LICENSE and COMMERCIAL in the project root for license information.
package com.rebuild.core.service.trigger.aviator; package com.rebuild.core.service.trigger.aviator;
import cn.devezhao.commons.CalendarUtils; 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.exception.ExpressionSyntaxErrorException;
import com.googlecode.aviator.runtime.function.AbstractFunction; import com.googlecode.aviator.runtime.function.AbstractFunction;
import com.googlecode.aviator.runtime.type.AviatorLong; 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.AviatorObject;
import com.googlecode.aviator.runtime.type.AviatorString; import com.googlecode.aviator.runtime.type.AviatorString;
import com.rebuild.core.Application;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import java.util.Date; import java.util.Date;
@ -29,6 +34,17 @@ import java.util.Map;
public class DateDiffFunction extends AbstractFunction { public class DateDiffFunction extends AbstractFunction {
private static final long serialVersionUID = 5778729290544711131L; private static final long serialVersionUID = 5778729290544711131L;
private boolean isUseMysql;
protected DateDiffFunction() {
this(Boolean.FALSE);
}
protected DateDiffFunction(boolean isUseMysql) {
super();
this.isUseMysql = isUseMysql;
}
@Override @Override
public AviatorObject call(Map<String, Object> env, AviatorObject arg1, AviatorObject arg2) { public AviatorObject call(Map<String, Object> env, AviatorObject arg1, AviatorObject arg2) {
return call(env, arg1, arg2, new AviatorString(AviatorDate.DU_DAY)); return call(env, arg1, arg2, new AviatorString(AviatorDate.DU_DAY));
@ -38,31 +54,50 @@ public class DateDiffFunction extends AbstractFunction {
public AviatorObject call(Map<String, Object> env, AviatorObject arg1, AviatorObject arg2, AviatorObject arg3) { public AviatorObject call(Map<String, Object> env, AviatorObject arg1, AviatorObject arg2, AviatorObject arg3) {
Object o1 = arg1.getValue(env); Object o1 = arg1.getValue(env);
Date date1 = o1 instanceof Date ? (Date) o1 : CalendarUtils.parse(o1.toString()); Date date1 = o1 instanceof Date ? (Date) o1 : CalendarUtils.parse(o1.toString());
if (date1 == null) {
return AviatorNil.NIL;
}
Object o2 = arg2.getValue(env); Object o2 = arg2.getValue(env);
Date date2 = o2 instanceof Date ? (Date) o2 : CalendarUtils.parse(o2.toString()); Date date2 = o2 instanceof Date ? (Date) o2 : CalendarUtils.parse(o2.toString());
if (date2 == null) {
return AviatorNil.NIL;
}
if (arg3.getValue(env) == null) { if (arg3.getValue(env) == null) {
throw new ExpressionSyntaxErrorException("`dateUnit` cannot be null"); throw new ExpressionSyntaxErrorException("`dateUnit` cannot be null");
} }
String dateUnit = arg3.getValue(env).toString(); String dateUnit = arg3.getValue(env).toString();
if (date1 == null) { if (isUseMysql) {
log.warn("Parseing date1 error : `{}`. Use default", o1); String mysqlUnit = "DAY";
date1 = CalendarUtils.now(); 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 @Override

View file

@ -20,8 +20,8 @@ public class DateSubFunction extends DateAddFunction {
private static final long serialVersionUID = -8857066285235050207L; private static final long serialVersionUID = -8857066285235050207L;
@Override @Override
protected Date dateCalc(Date date, int interval, int field) { protected Date dateAdd(Date date, int interval, int field) {
return super.dateCalc(date, -interval, field); return super.dateAdd(date, -interval, field);
} }
@Override @Override

View file

@ -10,6 +10,7 @@ package com.rebuild.core.service.trigger.aviator;
import cn.devezhao.commons.ObjectUtils; import cn.devezhao.commons.ObjectUtils;
import com.googlecode.aviator.runtime.function.AbstractFunction; import com.googlecode.aviator.runtime.function.AbstractFunction;
import com.googlecode.aviator.runtime.type.AviatorDouble; import com.googlecode.aviator.runtime.type.AviatorDouble;
import com.googlecode.aviator.runtime.type.AviatorNil;
import com.googlecode.aviator.runtime.type.AviatorObject; import com.googlecode.aviator.runtime.type.AviatorObject;
import com.rebuild.core.metadata.MetadataHelper; import com.rebuild.core.metadata.MetadataHelper;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -31,14 +32,12 @@ public class LocationDistanceFunction extends AbstractFunction {
public AviatorObject call(Map<String, Object> env, AviatorObject arg1, AviatorObject arg2) { public AviatorObject call(Map<String, Object> env, AviatorObject arg1, AviatorObject arg2) {
final double[] L1s = parseLngLat(arg1.getValue(env).toString()); final double[] L1s = parseLngLat(arg1.getValue(env).toString());
if (L1s == null) { if (L1s == null) {
log.warn("Bad lnglat(1) format : {}", arg1.getValue(env)); return AviatorNil.NIL;
return AviatorDouble.valueOf(0);
} }
final double[] L2s = parseLngLat(arg2.getValue(env).toString()); final double[] L2s = parseLngLat(arg2.getValue(env).toString());
if (L2s == null) { if (L2s == null) {
log.warn("Bad lnglat(2) format : {}", arg2.getValue(env)); return AviatorNil.NIL;
return AviatorDouble.valueOf(0);
} }
double LNG1 = L1s[0]; double LNG1 = L1s[0];

View file

@ -8,6 +8,7 @@ See LICENSE and COMMERCIAL in the project root for license information.
package com.rebuild.core.service.trigger.aviator; package com.rebuild.core.service.trigger.aviator;
import com.googlecode.aviator.runtime.function.AbstractFunction; 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.AviatorObject;
import com.googlecode.aviator.runtime.type.AviatorString; import com.googlecode.aviator.runtime.type.AviatorString;
import com.rebuild.utils.HttpUtils; import com.rebuild.utils.HttpUtils;
@ -29,7 +30,7 @@ public class RequestFunctuin extends AbstractFunction {
@Override @Override
public AviatorObject call(Map<String, Object> env, AviatorObject arg1) { public AviatorObject call(Map<String, Object> env, AviatorObject arg1) {
return call(env, arg1, null); return call(env, arg1, AviatorNil.NIL);
} }
@Override @Override

View file

@ -33,14 +33,11 @@ class AviatorUtilsTest {
@Test @Test
void func() { void func() {
Object result = AviatorUtils.evalQuietly("DATEDIFF('2021-01-01 18:17:00', '2021-01-01 16:17:00', 'H')"); AviatorUtils.evalQuietly("p(DATEDIFF('2022-03-03 17:31:24', '2022-03-04 17:30:24', 'D'))");
System.out.println(result);
result = AviatorUtils.evalQuietly("DATEADD('2021-01-01 18:17:00', '2H')"); AviatorUtils.evalQuietly("p(DATEADD('2021-01-01 18:17:00', '2H'))");
System.out.println(result);
result = AviatorUtils.evalQuietly("DATESUB('2021-01-01 18:17:00', '1')"); AviatorUtils.evalQuietly("p(DATESUB('2021-01-01 18:17:00', '1'))");
System.out.println(result);
} }
@Test @Test