指标库:原子指标编辑页:输出查询
This commit is contained in:
parent
b095d6926c
commit
bec249ced3
@ -46,4 +46,11 @@ public class TargetController {
|
|||||||
List<String> result = targetService.searchColumn(params);
|
List<String> result = targetService.searchColumn(params);
|
||||||
return R.ok(result);
|
return R.ok(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "指标输出查询")
|
||||||
|
@PostMapping("/getResult")
|
||||||
|
public R<String> getResult(@RequestBody JSONObject params) {
|
||||||
|
String result = targetService.getResult(params);
|
||||||
|
return R.ok(result);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,4 +17,6 @@ public interface TargetService extends IService<Target> {
|
|||||||
IPage<Target> getTargetsByCategory(JSONObject params);
|
IPage<Target> getTargetsByCategory(JSONObject params);
|
||||||
|
|
||||||
List<String> searchColumn(JSONObject params);
|
List<String> searchColumn(JSONObject params);
|
||||||
|
|
||||||
|
String getResult(JSONObject params);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package iet.ustb.sf.service.impl;
|
package iet.ustb.sf.service.impl;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
@ -8,6 +9,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|||||||
import com.baomidou.mybatisplus.extension.toolkit.SqlRunner;
|
import com.baomidou.mybatisplus.extension.toolkit.SqlRunner;
|
||||||
import iet.ustb.sf.domain.Category;
|
import iet.ustb.sf.domain.Category;
|
||||||
import iet.ustb.sf.domain.Target;
|
import iet.ustb.sf.domain.Target;
|
||||||
|
import iet.ustb.sf.domain.TargetOption;
|
||||||
import iet.ustb.sf.exception.ErrorCode;
|
import iet.ustb.sf.exception.ErrorCode;
|
||||||
import iet.ustb.sf.exception.ThrowUtils;
|
import iet.ustb.sf.exception.ThrowUtils;
|
||||||
import iet.ustb.sf.mapper.CategoryMapper;
|
import iet.ustb.sf.mapper.CategoryMapper;
|
||||||
@ -19,6 +21,9 @@ import lombok.val;
|
|||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.time.DayOfWeek;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@ -80,6 +85,154 @@ public class TargetServiceImpl extends ServiceImpl<TargetMapper, Target>
|
|||||||
List<Map<String, Object>> list = SqlRunner.db().selectList(sql);
|
List<Map<String, Object>> list = SqlRunner.db().selectList(sql);
|
||||||
return list.stream().map(target -> target.get(columnName).toString()).collect(Collectors.toList());
|
return list.stream().map(target -> target.get(columnName).toString()).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getResult(JSONObject params) {
|
||||||
|
String sql = getResultSql(params);
|
||||||
|
List<Map<String, Object>> list = SqlRunner.db().selectList(sql);
|
||||||
|
TargetOption result = params.getJSONObject("result").toJavaObject(TargetOption.class);
|
||||||
|
return list.get(0).get(result.getColumnName()).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 拼接结果sql
|
||||||
|
*
|
||||||
|
* @param params 传入参数
|
||||||
|
* @return 结果sql
|
||||||
|
*/
|
||||||
|
private String getResultSql(JSONObject params) {
|
||||||
|
String tableName = params.getString("tableName");
|
||||||
|
CheckUtils.checkTableName(tableName);
|
||||||
|
List<TargetOption> searchList = params.getJSONArray("search").toJavaList(TargetOption.class);
|
||||||
|
CheckUtils.checkSearchOption(searchList, tableName);
|
||||||
|
TargetOption result = params.getJSONObject("result").toJavaObject(TargetOption.class);
|
||||||
|
CheckUtils.checkResultOption(result, tableName);
|
||||||
|
return "SELECT ROUND(" + result.getFun() + "(CAST(" + result.getColumnName() + " AS DOUBLE)), 6) AS " +
|
||||||
|
result.getColumnName() + " FROM " + tableName + " WHERE " + getWhereSql(searchList);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 拼接条件sql
|
||||||
|
*
|
||||||
|
* @param searchList 条件列表
|
||||||
|
* @return 条件sql
|
||||||
|
*/
|
||||||
|
private String getWhereSql(List<TargetOption> searchList) {
|
||||||
|
StringBuilder sql = new StringBuilder();
|
||||||
|
for (TargetOption option : searchList) {
|
||||||
|
int type = option.getType();
|
||||||
|
if (type == 1) {
|
||||||
|
String start, end;
|
||||||
|
LocalDate day = LocalDate.now();
|
||||||
|
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
||||||
|
switch (option.getFun()) {
|
||||||
|
case "yesterday":
|
||||||
|
end = day.format(dtf);
|
||||||
|
start = day.minusDays(1).format(dtf);
|
||||||
|
break;
|
||||||
|
case "week":
|
||||||
|
end = day.format(dtf);
|
||||||
|
start = day.minusDays(1).with(DayOfWeek.MONDAY).format(dtf);
|
||||||
|
break;
|
||||||
|
case "lastWeek":
|
||||||
|
day = day.minusDays(1).with(DayOfWeek.MONDAY);
|
||||||
|
start = day.minusDays(7).format(dtf);
|
||||||
|
end = day.format(dtf);
|
||||||
|
break;
|
||||||
|
case "nearlyWeek":
|
||||||
|
end = day.format(dtf);
|
||||||
|
start = day.minusDays(7).format(dtf);
|
||||||
|
break;
|
||||||
|
case "month":
|
||||||
|
end = day.format(dtf);
|
||||||
|
start = day.minusDays(1).withDayOfMonth(1).format(dtf);
|
||||||
|
break;
|
||||||
|
case "lastMonth":
|
||||||
|
day = day.withDayOfMonth(1);
|
||||||
|
end = day.format(dtf);
|
||||||
|
start = day.minusMonths(1).format(dtf);
|
||||||
|
break;
|
||||||
|
case "nearlyMonth":
|
||||||
|
end = day.format(dtf);
|
||||||
|
start = day.minusDays(30).format(dtf);
|
||||||
|
break;
|
||||||
|
case "product":
|
||||||
|
end = day.format(dtf);
|
||||||
|
day = day.minusDays(1);
|
||||||
|
if (day.getDayOfMonth() < 26) {
|
||||||
|
start = day.minusMonths(1).withDayOfMonth(26).format(dtf);
|
||||||
|
} else {
|
||||||
|
start = day.withDayOfMonth(26).format(dtf);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "lastProduct":
|
||||||
|
day = day.minusDays(1);
|
||||||
|
if (day.getDayOfMonth() < 26) {
|
||||||
|
day = day.minusMonths(1).withDayOfMonth(26);
|
||||||
|
} else {
|
||||||
|
day = day.withDayOfMonth(26);
|
||||||
|
}
|
||||||
|
end = day.format(dtf);
|
||||||
|
start = day.minusMonths(1).format(dtf);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
start = "";
|
||||||
|
end = "";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
sql.append(option.getColumnName()).append(" >= '").append(start).append("' and ")
|
||||||
|
.append(option.getColumnName()).append(" < '").append(end).append("' and ");
|
||||||
|
} else if (type == 2) {
|
||||||
|
sql.append(getIsNullSql(option));
|
||||||
|
} else {
|
||||||
|
sql.append("CAST(").append(option.getColumnName()).append(" AS DOUBLE)");
|
||||||
|
if ("between".equals(option.getFun())) {
|
||||||
|
double[] vals = Arrays.stream(option.getVal().split(",")).mapToDouble(Double::parseDouble).toArray();
|
||||||
|
sql.append(("between ")).append(vals[0]).append(" and ").append(vals[1]).append(" ");
|
||||||
|
} else {
|
||||||
|
sql.append(option.getFun()).append(" ").append(option.getVal()).append(" ");
|
||||||
|
}
|
||||||
|
sql.append("and ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sql = new StringBuilder(sql.substring(0, sql.length() - 4));
|
||||||
|
return sql.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理条件中可能包含NULL的情况
|
||||||
|
*
|
||||||
|
* @param option 单个条件
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
private String getIsNullSql(TargetOption option) {
|
||||||
|
boolean isNull = false;
|
||||||
|
StringBuilder tmpSql = new StringBuilder();
|
||||||
|
if (StringUtils.isEmpty(option.getVal())) {
|
||||||
|
return "( " + option.getColumnName() + " IS NULL OR " + option.getColumnName() + "='' ) AND ";
|
||||||
|
}
|
||||||
|
if (option.getVal().startsWith(",") || option.getVal().endsWith(",")) {
|
||||||
|
isNull = true;
|
||||||
|
}
|
||||||
|
String[] vals = option.getVal().split(",");
|
||||||
|
tmpSql.append(option.getColumnName()).append(" in(");
|
||||||
|
for (String val : vals) {
|
||||||
|
if (StringUtils.isEmpty(val)) {
|
||||||
|
isNull = true;
|
||||||
|
} else {
|
||||||
|
tmpSql.append("'").append(val).append("',");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tmpSql = new StringBuilder(tmpSql.substring(0, tmpSql.length() - 1));
|
||||||
|
tmpSql.append(")");
|
||||||
|
if (isNull) {
|
||||||
|
tmpSql = new StringBuilder("(" + tmpSql + " OR "
|
||||||
|
+ option.getColumnName() + " IS NULL OR "
|
||||||
|
+ option.getColumnName() + " ='' )");
|
||||||
|
}
|
||||||
|
tmpSql.append(" and ");
|
||||||
|
return tmpSql.toString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,13 +1,16 @@
|
|||||||
package iet.ustb.sf.util;
|
package iet.ustb.sf.util;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.extension.toolkit.SqlRunner;
|
import com.baomidou.mybatisplus.extension.toolkit.SqlRunner;
|
||||||
|
import iet.ustb.sf.domain.TargetOption;
|
||||||
import iet.ustb.sf.exception.ErrorCode;
|
import iet.ustb.sf.exception.ErrorCode;
|
||||||
|
import iet.ustb.sf.exception.MyException;
|
||||||
import iet.ustb.sf.exception.ThrowUtils;
|
import iet.ustb.sf.exception.ThrowUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CheckUtils
|
* CheckUtils
|
||||||
@ -35,7 +38,8 @@ public class CheckUtils {
|
|||||||
*/
|
*/
|
||||||
public static void checkTableName(String tableName) {
|
public static void checkTableName(String tableName) {
|
||||||
checkEmpty(tableName, "表名");
|
checkEmpty(tableName, "表名");
|
||||||
String sql = "SELECT COUNT(1) FROM information_schema.tables WHERE table_schema = 'dwops_extension' AND table_name = '" + tableName + "'";
|
String sql = "SELECT COUNT(1) FROM information_schema.tables " +
|
||||||
|
"WHERE table_schema = 'dwops_extension' AND table_name = '" + tableName + "'";
|
||||||
long cnt = SqlRunner.db().selectCount(sql);
|
long cnt = SqlRunner.db().selectCount(sql);
|
||||||
ThrowUtils.throwIf(cnt <= 0, new RuntimeException("表" + tableName + "不存在!"));
|
ThrowUtils.throwIf(cnt <= 0, new RuntimeException("表" + tableName + "不存在!"));
|
||||||
}
|
}
|
||||||
@ -51,4 +55,100 @@ public class CheckUtils {
|
|||||||
String sql = "SELECT " + columns + " FROM " + tableName + " limit 5";
|
String sql = "SELECT " + columns + " FROM " + tableName + " limit 5";
|
||||||
SqlRunner.db().selectList(sql);
|
SqlRunner.db().selectList(sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 条件指标验证
|
||||||
|
*
|
||||||
|
* @param optionList 条件指标集合
|
||||||
|
* @param tableName 表名
|
||||||
|
*/
|
||||||
|
public static void checkSearchOption(List<TargetOption> optionList, String tableName) {
|
||||||
|
String columns = optionList.stream().map(TargetOption::getColumnName).collect(Collectors.joining(","));
|
||||||
|
checkColumns(columns, tableName);
|
||||||
|
for (TargetOption option : optionList) {
|
||||||
|
checkSingleOption(option);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 单个条件指标
|
||||||
|
*
|
||||||
|
* @param option 指标
|
||||||
|
*/
|
||||||
|
public static void checkSingleOption(TargetOption option) {
|
||||||
|
String columns = option.getColumnName();
|
||||||
|
checkEmpty(columns, "列名");
|
||||||
|
List<Integer> typeList = Arrays.asList(1, 2, 3);
|
||||||
|
ThrowUtils.throwIf(
|
||||||
|
!typeList.contains(option.getType()),
|
||||||
|
ErrorCode.PARAMS_ERROR,
|
||||||
|
columns + ":指标中的类型不对!"
|
||||||
|
);
|
||||||
|
List<String> funList;
|
||||||
|
switch (option.getType()) {
|
||||||
|
case 1:
|
||||||
|
ThrowUtils.throwIf(
|
||||||
|
StringUtils.isEmpty(option.getFun()),
|
||||||
|
ErrorCode.PARAMS_ERROR,
|
||||||
|
columns + ":日期类型的指标,日期选项不能为空!"
|
||||||
|
);
|
||||||
|
funList = Arrays.asList("yesterday", "week", "nearlyWeek", "lastWeek", "month", "lastMonth",
|
||||||
|
"nearlyMonth", "product", "lastProduct");
|
||||||
|
ThrowUtils.throwIf(
|
||||||
|
!funList.contains(option.getFun()),
|
||||||
|
ErrorCode.PARAMS_ERROR,
|
||||||
|
columns + ":日期类型的指标,日期选项不对!"
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
ThrowUtils.throwIf(
|
||||||
|
StringUtils.isEmpty(option.getFun()),
|
||||||
|
ErrorCode.PARAMS_ERROR,
|
||||||
|
columns + ":数值类型的指标,符号不能为空!"
|
||||||
|
);
|
||||||
|
funList = Arrays.asList(">", ">=", "<", "<=", "=", "!=", "between");
|
||||||
|
ThrowUtils.throwIf(
|
||||||
|
!funList.contains(option.getFun()),
|
||||||
|
ErrorCode.PARAMS_ERROR,
|
||||||
|
columns + ":数值类型的指标,符号不对!"
|
||||||
|
);
|
||||||
|
ThrowUtils.throwIf(
|
||||||
|
StringUtils.isEmpty(option.getVal()),
|
||||||
|
ErrorCode.PARAMS_ERROR,
|
||||||
|
columns + ":数值类型的指标,值不能为空!"
|
||||||
|
);
|
||||||
|
if ("between".equals(option.getFun())) {
|
||||||
|
String[] nums = option.getVal().split(",");
|
||||||
|
ThrowUtils.throwIf(
|
||||||
|
nums.length != 2,
|
||||||
|
ErrorCode.PARAMS_ERROR,
|
||||||
|
columns + "范围条件请输入两个数值!"
|
||||||
|
);
|
||||||
|
try {
|
||||||
|
if (Double.parseDouble(nums[0]) > Double.parseDouble(nums[1])) {
|
||||||
|
throw new MyException(ErrorCode.PARAMS_ERROR, columns + ":范围条件请确保前面的值小于等于后面的值!");
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new MyException(ErrorCode.PARAMS_ERROR, columns + ":请传入两个数值!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 结果指标验证
|
||||||
|
*
|
||||||
|
* @param option 结果指标
|
||||||
|
* @param tableName 表名
|
||||||
|
*/
|
||||||
|
public static void checkResultOption(TargetOption option, String tableName) {
|
||||||
|
String fun = option.getFun();
|
||||||
|
checkEmpty(fun, "函数");
|
||||||
|
List<String> funList = Arrays.asList("SUM", "AVG", "MAX", "MIN", "MEDIAN", "COUNT");
|
||||||
|
ThrowUtils.throwIf(!funList.contains(fun), ErrorCode.PARAMS_ERROR, "方法错误!");
|
||||||
|
checkColumns(option.getColumnName(), tableName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user