mirror of
https://github.com/getrebuild/rebuild.git
synced 2025-02-25 23:05:06 +08:00
优化时间日期
This commit is contained in:
parent
749259238d
commit
bb8a206568
3 changed files with 109 additions and 67 deletions
|
@ -33,7 +33,6 @@ import com.rebuild.server.metadata.entity.DisplayType;
|
|||
import com.rebuild.server.metadata.entity.EasyMeta;
|
||||
import com.rebuild.server.service.bizz.UserHelper;
|
||||
import com.rebuild.server.service.bizz.privileges.Department;
|
||||
import com.rebuild.web.IllegalParameterException;
|
||||
import org.apache.commons.lang.StringEscapeUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.lang.math.NumberUtils;
|
||||
|
@ -169,44 +168,55 @@ public class AdvFilterParser {
|
|||
if (hasAndFlag) {
|
||||
field = field.substring(1);
|
||||
}
|
||||
|
||||
final String[] fieldPath = field.split("\\.");
|
||||
if (fieldPath.length > 2) {
|
||||
throw new IllegalParameterException("Unsupportted joins : " + field);
|
||||
}
|
||||
|
||||
if (!rootEntity.containsField(fieldPath[0])) {
|
||||
|
||||
final Field fieldMeta = MetadataHelper.getLastJoinField(rootEntity, field);
|
||||
if (fieldMeta == null) {
|
||||
LOG.warn("Unknow field '" + field + "' in '" + rootEntity.getName() + "'");
|
||||
return null;
|
||||
}
|
||||
|
||||
Field fieldMeta = rootEntity.getField(fieldPath[0]);
|
||||
if (fieldPath.length > 1) {
|
||||
if (EasyMeta.getDisplayType(fieldMeta) != DisplayType.REFERENCE) {
|
||||
throw new IllegalParameterException("Non reference-field : " + field);
|
||||
}
|
||||
fieldMeta = fieldMeta.getReferenceEntity().getField(fieldPath[1]);
|
||||
}
|
||||
|
||||
DisplayType dt = EasyMeta.getDisplayType(fieldMeta);
|
||||
// TODO 分类字段仅能查询最后一级
|
||||
|
||||
final DisplayType dt = EasyMeta.getDisplayType(fieldMeta);
|
||||
if (dt == DisplayType.CLASSIFICATION || hasAndFlag) {
|
||||
field = "&" + field;
|
||||
}
|
||||
|
||||
final String op = item.getString("op");
|
||||
|
||||
|
||||
String op = item.getString("op");
|
||||
String value = item.getString("value");
|
||||
String valueEnd = null;
|
||||
|
||||
// 日期时间
|
||||
if (dt == DisplayType.DATETIME || dt == DisplayType.DATE) {
|
||||
if ("TDA".equalsIgnoreCase(op) || "YTA".equalsIgnoreCase(op) || "TTA".equalsIgnoreCase(op)) {
|
||||
value = getUTCDateFormat().format(CalendarUtils.now());
|
||||
if ("YTA".equalsIgnoreCase(op)) {
|
||||
value = getUTCDateFormat().format(CalendarUtils.addDay(-1));
|
||||
} else if ("TTA".equalsIgnoreCase(op)) {
|
||||
value = getUTCDateFormat().format(CalendarUtils.addDay(1));
|
||||
}
|
||||
|
||||
if (dt == DisplayType.DATETIME) {
|
||||
op = "BW";
|
||||
valueEnd = parseValue(value, op, fieldMeta, true);
|
||||
} else {
|
||||
op = "EQ";
|
||||
}
|
||||
}
|
||||
|
||||
if ("EQ".equalsIgnoreCase(op) && dt == DisplayType.DATETIME && StringUtils.length(value) == 10) {
|
||||
op = "BW";
|
||||
valueEnd = parseValue(value, op, fieldMeta, true);
|
||||
}
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder(field)
|
||||
.append(' ')
|
||||
.append(convOp(op))
|
||||
.append(' ');
|
||||
.append(convOp(op));
|
||||
if (op.equalsIgnoreCase("NL") || op.equalsIgnoreCase("NT")) {
|
||||
return sb.toString();
|
||||
} else {
|
||||
sb.append(' ');
|
||||
}
|
||||
|
||||
String value = item.getString("value");
|
||||
String valueEnd = null;
|
||||
|
||||
|
||||
// TODO 自定义函数
|
||||
|
||||
if ("BFD".equalsIgnoreCase(op)) {
|
||||
|
@ -221,19 +231,7 @@ public class AdvFilterParser {
|
|||
value = getUTCDateFormat().format(CalendarUtils.addDay(-NumberUtils.toInt(value))) + FULL_TIME;
|
||||
} else if ("REM".equalsIgnoreCase(op)) {
|
||||
value = getUTCDateFormat().format(CalendarUtils.addMonth(-NumberUtils.toInt(value))) + FULL_TIME;
|
||||
} else if ("YTA".equalsIgnoreCase(op)) {
|
||||
value = getUTCDateFormat().format(CalendarUtils.addDay(-1));
|
||||
valueEnd = value + FULL_TIME;
|
||||
value = value + ZERO_TIME;
|
||||
} else if ("TDA".equalsIgnoreCase(op)) {
|
||||
value = getUTCDateFormat().format(CalendarUtils.now());
|
||||
valueEnd = value + FULL_TIME;
|
||||
value = value + ZERO_TIME;
|
||||
} else if ("TTA".equalsIgnoreCase(op)) {
|
||||
value = getUTCDateFormat().format(CalendarUtils.addDay(1));
|
||||
valueEnd = value + FULL_TIME;
|
||||
value = value + ZERO_TIME;
|
||||
} else if ("SFU".equalsIgnoreCase(op)) {
|
||||
} else if ("SFU".equalsIgnoreCase(op)) {
|
||||
value = Application.getCurrentUser().toLiteral();
|
||||
} else if ("SFB".equalsIgnoreCase(op)) {
|
||||
Department dept = UserHelper.getDepartment(Application.getCurrentUser());
|
||||
|
@ -257,40 +255,45 @@ public class AdvFilterParser {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (StringUtils.isBlank(value)) {
|
||||
LOG.warn("Invalid item of AdvFilter : " + item.toJSONString());
|
||||
return null;
|
||||
}
|
||||
|
||||
// 占位 {1}
|
||||
|
||||
// 快速搜索的占位符 {1}
|
||||
if (value.matches("\\{\\d+\\}")) {
|
||||
if (values == null) {
|
||||
LOG.warn("Invalid item of AdvFilter : " + item.toJSONString());
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
String valHold = value.replaceAll("[\\{\\}]", "");
|
||||
value = parseValue(values.get(valHold), op, fieldMeta);
|
||||
value = parseValue(values.get(valHold), op, fieldMeta, false);
|
||||
} else {
|
||||
value = parseValue(value, op, fieldMeta);
|
||||
value = parseValue(value, op, fieldMeta, false);
|
||||
}
|
||||
|
||||
// No value
|
||||
if (value == null) {
|
||||
LOG.warn("Invalid item of AdvFilter : " + item.toJSONString());
|
||||
return null;
|
||||
}
|
||||
|
||||
// 区间
|
||||
boolean isBetween = op.equalsIgnoreCase("BW");
|
||||
valueEnd = isBetween ? parseValue(item.getString("value2"), op, fieldMeta) : valueEnd;
|
||||
if (isBetween && valueEnd == null) {
|
||||
valueEnd = value;
|
||||
}
|
||||
|
||||
valueEnd = parseValue(item.getString("value2"), op, fieldMeta, true);
|
||||
if (valueEnd == null) {
|
||||
valueEnd = value;
|
||||
}
|
||||
}
|
||||
|
||||
// IN
|
||||
if (op.equalsIgnoreCase("IN") || op.equalsIgnoreCase("NIN") || op.equalsIgnoreCase("SFD")) {
|
||||
sb.append(value);
|
||||
} else {
|
||||
// LIKE
|
||||
if (op.equalsIgnoreCase("LK") || op.equalsIgnoreCase("NLK")) {
|
||||
value = '%' + value + '%';
|
||||
}
|
||||
|
@ -298,25 +301,23 @@ public class AdvFilterParser {
|
|||
}
|
||||
|
||||
if (isBetween) {
|
||||
sb.append(" and ").append(quoteValue(valueEnd, fieldMeta.getType()));
|
||||
} else if (valueEnd != null) {
|
||||
sb.insert(0, '(')
|
||||
.append(" and ")
|
||||
.append(field)
|
||||
.append(" <= ")
|
||||
.append(quoteValue(valueEnd, fieldMeta.getType()))
|
||||
.append(')');
|
||||
}
|
||||
return sb.toString();
|
||||
sb.insert(0, "( ")
|
||||
.append(" and ").append(quoteValue(valueEnd, fieldMeta.getType()))
|
||||
.append(" )");
|
||||
}
|
||||
|
||||
System.out.println(item + "\n>> " + sb);
|
||||
return sb.toString().trim();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param val
|
||||
* @param op
|
||||
* @param field
|
||||
* @param endVal 仅对日期时间有意义
|
||||
* @return
|
||||
*/
|
||||
private String parseValue(Object val, String op, Field field) {
|
||||
private String parseValue(Object val, String op, Field field, boolean endVal) {
|
||||
String value;
|
||||
// IN
|
||||
if (val instanceof JSONArray) {
|
||||
|
@ -331,8 +332,19 @@ public class AdvFilterParser {
|
|||
if (StringUtils.isBlank(value)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 兼容 | 号分割
|
||||
|
||||
// TIMESTAMP 仅指定了日期值
|
||||
if (field.getType() == FieldType.TIMESTAMP && StringUtils.length(value) == 10) {
|
||||
if ("GT".equalsIgnoreCase(op)) {
|
||||
value += FULL_TIME;
|
||||
} else if ("LT".equalsIgnoreCase(op)) {
|
||||
value += ZERO_TIME;
|
||||
} else if ("BW".equalsIgnoreCase(op)) {
|
||||
value += (endVal ? FULL_TIME : ZERO_TIME);
|
||||
}
|
||||
}
|
||||
|
||||
// 多个值的情况下,兼容 | 号分割
|
||||
if (op.equalsIgnoreCase("IN") || op.equalsIgnoreCase("NIN") || op.equalsIgnoreCase("SFD")) {
|
||||
Set<String> inVals = new HashSet<>();
|
||||
for (String v : value.split("\\|")) {
|
||||
|
|
|
@ -207,7 +207,7 @@ class AdvFilter extends React.Component {
|
|||
}
|
||||
}
|
||||
|
||||
const OP_TYPE = { LK: '包含', NLK: '不包含', IN: '包含', NIN: '不包含', EQ: '等于', NEQ: '不等于', GT: '大于', LT: '小于', BW: '区间', NL: '为空', NT: '不为空', BFD: '...天前', BFM: '...月前', AFD: '...天后', AFM: '...月后', RED: '最近...天', REM: '最近...月', SFU: '本人', SFB: '本部门', SFD: '本部门及子部门', YTA:'昨天', TDA:'今天', TTA:'明天' }
|
||||
const OP_TYPE = { LK: '包含', NLK: '不包含', IN: '包含', NIN: '不包含', EQ: '等于', NEQ: '不等于', GT: '大于', LT: '小于', BW: '区间', NL: '为空', NT: '不为空', BFD: '...天前', BFM: '...月前', AFD: '...天后', AFM: '...月后', RED: '最近...天', REM: '最近...月', SFU: '本人', SFB: '本部门', SFD: '本部门及子部门', YTA: '昨天', TDA: '今天', TTA: '明天' }
|
||||
const OP_DATE_NOPICKER = ['BFD', 'BFM', 'AFD', 'AFM', 'RED', 'REM']
|
||||
const OP_NOVALUE = ['NL', 'NT', 'SFU', 'SFB', 'SFD', 'YTA', 'TDA', 'TTA']
|
||||
const PICKLIST_CACHE = {}
|
||||
|
@ -259,7 +259,7 @@ class FilterItem extends React.Component {
|
|||
if (fieldType === 'NUMBER' || fieldType === 'DECIMAL') {
|
||||
op = ['GT', 'LT', 'BW', 'EQ']
|
||||
} else if (fieldType === 'DATE' || fieldType === 'DATETIME') {
|
||||
op = ['YTA', 'TDA', 'TTA', 'GT', 'LT', 'BW', 'RED', 'REM', 'BFD', 'BFM', 'AFD', 'AFM']
|
||||
op = ['TDA', 'YTA', 'TTA', 'GT', 'LT', 'EQ', 'BW', 'RED', 'REM', 'BFD', 'BFM', 'AFD', 'AFM']
|
||||
} else if (fieldType === 'FILE' || fieldType === 'IMAGE') {
|
||||
op = []
|
||||
} else if (fieldType === 'PICKLIST') {
|
||||
|
|
|
@ -62,4 +62,34 @@ public class AdvFilterParserTest extends TestSupport {
|
|||
String where = new AdvFilterParser(filterExp).toSqlWhere();
|
||||
System.out.println(where);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDateAndDatetime() throws Exception {
|
||||
JSONObject filterExp = new JSONObject();
|
||||
filterExp.put("entity", TEST_ENTITY);
|
||||
JSONArray items = new JSONArray();
|
||||
filterExp.put("items", items);
|
||||
|
||||
// Use `=`
|
||||
items.add(JSON.parseObject("{ op:'EQ', field:'date', value:'2019-09-09' }"));
|
||||
// Use `between`
|
||||
items.add(JSON.parseObject("{ op:'EQ', field:'datetime', value:'2019-09-09' }"));
|
||||
System.out.println(new AdvFilterParser(filterExp).toSqlWhere());
|
||||
|
||||
items.clear();
|
||||
// Use `=`
|
||||
items.add(JSON.parseObject("{ op:'TDA', field:'date' }"));
|
||||
// Use `between`
|
||||
items.add(JSON.parseObject("{ op:'TDA', field:'datetime' }"));
|
||||
System.out.println(new AdvFilterParser(filterExp).toSqlWhere());
|
||||
|
||||
items.clear();
|
||||
// No padding
|
||||
items.add(JSON.parseObject("{ op:'GT', field:'date', value:'2019-09-09' }"));
|
||||
// Padding time
|
||||
items.add(JSON.parseObject("{ op:'GT', field:'datetime', value:'2019-09-09' }"));
|
||||
// No padding
|
||||
items.add(JSON.parseObject("{ op:'GT', field:'datetime', value:'2019-09-09 12:12:54' }"));
|
||||
System.out.println(new AdvFilterParser(filterExp).toSqlWhere());
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue