|
@@ -25,10 +25,14 @@ import org.springframework.stereotype.Service;
|
|
|
import javax.annotation.Resource;
|
|
|
import javax.servlet.ServletOutputStream;
|
|
|
import javax.servlet.http.HttpServletResponse;
|
|
|
+import java.math.BigDecimal;
|
|
|
+import java.math.RoundingMode;
|
|
|
import java.time.LocalDateTime;
|
|
|
import java.time.format.DateTimeFormatter;
|
|
|
import java.util.*;
|
|
|
import java.util.concurrent.atomic.AtomicReference;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+import java.util.stream.Stream;
|
|
|
|
|
|
import static com.zkqy.common.utils.StringUtils.*;
|
|
|
|
|
@@ -507,7 +511,90 @@ public class CommonServiceImpl implements ICommonService {
|
|
|
return commonEntity;
|
|
|
}
|
|
|
|
|
|
- public static String extractSubstring(String input, String identifier) {
|
|
|
+ @Override
|
|
|
+ public CommonEntity queryCommonByCalculateBtn(CommonEntity commonEntity, String dfVueTemplate) {
|
|
|
+ //分析模板数据
|
|
|
+ JSONObject options = new JSONObject();
|
|
|
+ List<Map> columnList = new ArrayList<>();
|
|
|
+ try {
|
|
|
+ JSONObject dfVtemplateJson = JSONObject.parseObject(dfVueTemplate);
|
|
|
+ options = dfVtemplateJson
|
|
|
+ .getJSONArray("list")
|
|
|
+ .getJSONObject(0)
|
|
|
+ .getJSONObject("options");
|
|
|
+ JSONArray tableColumns = options
|
|
|
+ .getJSONArray("tableColumns");
|
|
|
+ columnList = tableColumns.toJavaList(Map.class);
|
|
|
+ }catch (NullPointerException e){
|
|
|
+ e.printStackTrace();
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ // 得到需要查询的结果列
|
|
|
+ List<String> columns = columnList.stream()
|
|
|
+ .filter(map -> (map.get("type") != null && !map.get("type").equals("result")) || (map.get("type") == null))
|
|
|
+ .flatMap(map -> {
|
|
|
+ Object prop = map.get("prop");
|
|
|
+ return prop != null ? Stream.of(prop.toString()) : Stream.empty();
|
|
|
+ })
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ //构建得到sql所需要的查询列
|
|
|
+ String queryColumn = "";
|
|
|
+ for (int i = 0; i < columns.size(); i++) {
|
|
|
+ queryColumn += columns.get(i);
|
|
|
+ if (i != columns.size()-1){
|
|
|
+ queryColumn += ",";
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //动态构建sql语句 得到查询结果
|
|
|
+ String mainTableName = options.getString("tableName");
|
|
|
+ String mainTableCondition = options.getString("mainTableCondition");
|
|
|
+ String joinTableCondition = options.getString("joinTableCondition");
|
|
|
+ // 判空
|
|
|
+ if (StringUtils.isBlank(mainTableName) || StringUtils.isBlank(mainTableCondition) || StringUtils.isBlank(joinTableCondition)){
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ CommonEntity infoById = getInfoById(commonEntity);
|
|
|
+ String joinTableConditionValue = infoById.getResultMap().get(joinTableCondition).toString();
|
|
|
+ String sql = "select " + queryColumn + " from {DBNAME}." + mainTableName + " where " + mainTableCondition + "= " + joinTableConditionValue;
|
|
|
+ //这里查询到的是驼峰的k-v,需要整体数组拷贝成下划线的,方便展示
|
|
|
+ List<Map<String, Object>> maps = commonMapper.executeSqlSelectData(sql);
|
|
|
+ List<Map<String, Object>> mapsUnderLine = copyListMapWithCamelToUnderline(maps);
|
|
|
+ //得到需要手动计算的特殊列名
|
|
|
+ List<String> columnsNeedHandle = columnList.stream()
|
|
|
+ .filter(map -> (map.get("type") != null && map.get("type").equals("result")))
|
|
|
+ .flatMap(map -> {
|
|
|
+ Object prop = map.get("prop");
|
|
|
+ return prop != null ? Stream.of(prop.toString()) : Stream.empty();
|
|
|
+ })
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ //为每一行的返回结果加上手动计算列,根据数据库查询出来的数据二次计算
|
|
|
+ for (Map<String, Object> map : mapsUnderLine) {
|
|
|
+ for (String column : columnsNeedHandle) {
|
|
|
+ map.put(column,calculate(column,map));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ HashMap<String, Object> map = new HashMap<>();
|
|
|
+ map.put("tableColumn",columnList);
|
|
|
+ map.put("tableValue",mapsUnderLine);
|
|
|
+ // 计算公式类型返回
|
|
|
+ map.put("formula",options.get("formula"));
|
|
|
+ map.put("showSummary",options.get("showSummary"));
|
|
|
+ infoById.setCalculateResultMap(map);
|
|
|
+ return infoById;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 复制集合,将驼峰转换成下划线
|
|
|
+ private List<Map<String, Object>> copyListMapWithCamelToUnderline(List<Map<String, Object>> maps) {
|
|
|
+ List<Map<String, Object>> resMap = new ArrayList<>();
|
|
|
+ for (Map<String, Object> map : maps) {
|
|
|
+ HashMap<String, Object> tempMap = new HashMap<>();
|
|
|
+ map.forEach((s, o) -> tempMap.put(StringUtils.toUnderScoreCase(s),o));
|
|
|
+ resMap.add(tempMap);
|
|
|
+ }
|
|
|
+ return resMap;
|
|
|
+ }
|
|
|
+
|
|
|
+ public String extractSubstring(String input, String identifier) {
|
|
|
int startIndex = input.indexOf(identifier);
|
|
|
if (startIndex == -1) {
|
|
|
return null; // 如果找不到指定的标识符,则返回空
|
|
@@ -520,6 +607,53 @@ public class CommonServiceImpl implements ICommonService {
|
|
|
String sqlColumn = input.substring(startIndex + identifier.length() + 1, endIndex);
|
|
|
return convertToCamelCase(sqlColumn);
|
|
|
}
|
|
|
+
|
|
|
+ // 目前只支持两列的加减乘除,后续如果需要支持多列待补充
|
|
|
+ public static Object calculate(String columns, Map<String, Object> resMap) {
|
|
|
+ try {
|
|
|
+ if (columns.contains("~+~")) {
|
|
|
+ String[] split = columns.split("~\\+~");
|
|
|
+ BigDecimal one = getBigDecimalFromMap(resMap, split[0]);
|
|
|
+ BigDecimal two = getBigDecimalFromMap(resMap, split[1]);
|
|
|
+ return roundToTwoDecimalPlaces(one.add(two));
|
|
|
+ } else if (columns.contains("~-~")) {
|
|
|
+ String[] split = columns.split("~-~");
|
|
|
+ BigDecimal one = getBigDecimalFromMap(resMap, split[0]);
|
|
|
+ BigDecimal two = getBigDecimalFromMap(resMap, split[1]);
|
|
|
+ return roundToTwoDecimalPlaces(one.subtract(two));
|
|
|
+ } else if (columns.contains("~*~")) {
|
|
|
+ String[] split = columns.split("~\\*~");
|
|
|
+ BigDecimal one = getBigDecimalFromMap(resMap, split[0]);
|
|
|
+ BigDecimal two = getBigDecimalFromMap(resMap, split[1]);
|
|
|
+ return roundToTwoDecimalPlaces(one.multiply(two));
|
|
|
+ } else if (columns.contains("~/~")) {
|
|
|
+ String[] split = columns.split("~/~");
|
|
|
+ BigDecimal one = getBigDecimalFromMap(resMap, split[0]);
|
|
|
+ BigDecimal two = getBigDecimalFromMap(resMap, split[1]);
|
|
|
+ if (two.compareTo(BigDecimal.ZERO) == 0) {
|
|
|
+ return BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP); // 除数为零时返回 0.00
|
|
|
+ }
|
|
|
+ return roundToTwoDecimalPlaces(one.divide(two, RoundingMode.HALF_UP));
|
|
|
+ } else {
|
|
|
+ throw new IllegalArgumentException("无效的表达式");
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ throw new IllegalArgumentException("计算失败: " + e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static BigDecimal getBigDecimalFromMap(Map<String, Object> resMap, String key) {
|
|
|
+ Object value = resMap.getOrDefault(key, BigDecimal.ZERO);
|
|
|
+ if (value instanceof Number) {
|
|
|
+ return new BigDecimal(value.toString()); // 将 Number 转换为 BigDecimal
|
|
|
+ } else {
|
|
|
+ throw new IllegalArgumentException("值不是数字类型: " + key);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static BigDecimal roundToTwoDecimalPlaces(BigDecimal number) {
|
|
|
+ return number.setScale(2, RoundingMode.HALF_UP); // 保留两位小数,四舍五入
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/*
|