指标库:保存原子指标
This commit is contained in:
parent
bec249ced3
commit
0a682ac155
@ -53,4 +53,11 @@ public class TargetController {
|
|||||||
String result = targetService.getResult(params);
|
String result = targetService.getResult(params);
|
||||||
return R.ok(result);
|
return R.ok(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "保存指标")
|
||||||
|
@PostMapping("/saveTarget")
|
||||||
|
public R<?> saveTarget(@RequestBody JSONObject params) {
|
||||||
|
targetService.saveTarget(params);
|
||||||
|
return R.ok();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -83,7 +83,7 @@ public class Monitor {
|
|||||||
* 目标值
|
* 目标值
|
||||||
*/
|
*/
|
||||||
@TableField(value = "target")
|
@TableField(value = "target")
|
||||||
private String target;
|
private Double target;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -1,13 +1,25 @@
|
|||||||
package iet.ustb.sf.service;
|
package iet.ustb.sf.service;
|
||||||
|
|
||||||
|
import iet.ustb.sf.domain.Target;
|
||||||
import iet.ustb.sf.domain.TargetData;
|
import iet.ustb.sf.domain.TargetData;
|
||||||
import com.baomidou.mybatisplus.extension.service.IService;
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author hyy
|
* @author hyy
|
||||||
* @description 针对表【mbgk_target_data】的数据库操作Service
|
* @description 针对表【mbgk_target_data】的数据库操作Service
|
||||||
* @createDate 2025-08-05 15:40:32
|
* @createDate 2025-08-05 15:40:32
|
||||||
*/
|
*/
|
||||||
public interface TargetDataService extends IService<TargetData> {
|
public interface TargetDataService extends IService<TargetData> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新历史数据
|
||||||
|
*
|
||||||
|
* @param target 指标
|
||||||
|
* @param strArr xShow, cycle, setDate, start, end
|
||||||
|
* @param map 关联的指标数据
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
TargetData updateHistory(Target target, String[] strArr, Map<String, TargetData> map);
|
||||||
}
|
}
|
||||||
|
@ -19,4 +19,6 @@ public interface TargetService extends IService<Target> {
|
|||||||
List<String> searchColumn(JSONObject params);
|
List<String> searchColumn(JSONObject params);
|
||||||
|
|
||||||
String getResult(JSONObject params);
|
String getResult(JSONObject params);
|
||||||
|
|
||||||
|
void saveTarget(JSONObject params);
|
||||||
}
|
}
|
||||||
|
54
src/main/java/iet/ustb/sf/service/UtilService.java
Normal file
54
src/main/java/iet/ustb/sf/service/UtilService.java
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
package iet.ustb.sf.service;
|
||||||
|
|
||||||
|
import iet.ustb.sf.domain.Monitor;
|
||||||
|
import iet.ustb.sf.domain.Rule;
|
||||||
|
import iet.ustb.sf.domain.Target;
|
||||||
|
import iet.ustb.sf.domain.TargetData;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UtilService
|
||||||
|
*
|
||||||
|
* @author huangge1199
|
||||||
|
* @since 2025/8/7 15:11:03
|
||||||
|
*/
|
||||||
|
public interface UtilService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取指定周期的对应日期 xShow, cycle, setDate, start, end
|
||||||
|
*
|
||||||
|
* @param date 日期
|
||||||
|
* @param cycle 周期
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
String[] getCurrentCycleDataByCycle(Date date, String cycle);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算表达式结果
|
||||||
|
*
|
||||||
|
* @param expression 表达式
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
double getEvalResult(String expression);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 该规则是否触发
|
||||||
|
*
|
||||||
|
* @param rule 规则信息
|
||||||
|
* @param target 指标信息
|
||||||
|
* @param targetData 指标数据
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
boolean isWarn(Rule rule, Target target, TargetData targetData);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取初始化监控数据
|
||||||
|
*
|
||||||
|
* @param targetData 指标数据
|
||||||
|
* @param target 指标信息
|
||||||
|
* @param rule 规则信息
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
Monitor getInitMonitor(TargetData targetData, Target target, Rule rule);
|
||||||
|
}
|
@ -1,20 +1,171 @@
|
|||||||
package iet.ustb.sf.service.impl;
|
package iet.ustb.sf.service.impl;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
import iet.ustb.sf.domain.TargetData;
|
import com.baomidou.mybatisplus.extension.toolkit.SqlRunner;
|
||||||
|
import iet.ustb.sf.domain.*;
|
||||||
|
import iet.ustb.sf.mapper.MonitorMapper;
|
||||||
|
import iet.ustb.sf.mapper.RuleMapper;
|
||||||
|
import iet.ustb.sf.mapper.TargetMapper;
|
||||||
import iet.ustb.sf.service.TargetDataService;
|
import iet.ustb.sf.service.TargetDataService;
|
||||||
import iet.ustb.sf.mapper.TargetDataMapper;
|
import iet.ustb.sf.mapper.TargetDataMapper;
|
||||||
|
import iet.ustb.sf.service.UtilService;
|
||||||
|
import iet.ustb.sf.util.CheckUtils;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author hyy
|
* @author hyy
|
||||||
* @description 针对表【mbgk_target_data】的数据库操作Service实现
|
* @description 针对表【mbgk_target_data】的数据库操作Service实现
|
||||||
* @createDate 2025-08-05 15:40:32
|
* @createDate 2025-08-05 15:40:32
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
public class TargetDataServiceImpl extends ServiceImpl<TargetDataMapper, TargetData>
|
public class TargetDataServiceImpl extends ServiceImpl<TargetDataMapper, TargetData>
|
||||||
implements TargetDataService{
|
implements TargetDataService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private TargetDataMapper targetDataMapper;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private TargetMapper targetMapper;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private UtilService utilService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private MonitorMapper monitorMapper;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private RuleMapper ruleMapper;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TargetData updateHistory(Target target, String[] strArr, Map<String, TargetData> map) {
|
||||||
|
String xShow = strArr[0];
|
||||||
|
QueryWrapper<TargetData> queryWrapper = new QueryWrapper<>();
|
||||||
|
queryWrapper.eq("target_id", target.getId());
|
||||||
|
queryWrapper.eq("x_show", xShow);
|
||||||
|
TargetData targetData = targetDataMapper.selectOne(queryWrapper);
|
||||||
|
if (targetData != null && targetData.getId() != null) {
|
||||||
|
return targetData;
|
||||||
|
}
|
||||||
|
double result;
|
||||||
|
if (target.getType() < 2) {
|
||||||
|
List<Map<String, Object>> list = SqlRunner.db().selectList(target.getResultSql(), strArr[3], strArr[4]);
|
||||||
|
result = Double.parseDouble(list.get(0).get("result").toString());
|
||||||
|
} else {
|
||||||
|
String exprStr = target.getResultSql();
|
||||||
|
String[] expressionList = exprStr.split(",");
|
||||||
|
List<String> opList = Arrays.asList("+", "-", "*", "/", "(", ")");
|
||||||
|
List<String> idList = new ArrayList<>();
|
||||||
|
for (String expression : expressionList) {
|
||||||
|
if (!opList.contains(expression) && !idList.contains(expression)) {
|
||||||
|
idList.add(expression);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
List<Target> targetList = targetMapper.selectByIds(idList);
|
||||||
|
exprStr = exprStr.replaceAll(",", "");
|
||||||
|
if (map == null) {
|
||||||
|
map = new HashMap<>();
|
||||||
|
}
|
||||||
|
for (Target child : targetList) {
|
||||||
|
double val;
|
||||||
|
if (map.containsKey(child.getId())) {
|
||||||
|
val = map.get(child.getId()).getVal();
|
||||||
|
} else {
|
||||||
|
TargetData tmp = updateHistory(child, strArr, map);
|
||||||
|
map.put(child.getId(), tmp);
|
||||||
|
val = tmp.getVal();
|
||||||
|
}
|
||||||
|
exprStr = exprStr.replaceAll(child.getId(), val + "");
|
||||||
|
}
|
||||||
|
result = utilService.getEvalResult(exprStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
Date now = new Date();
|
||||||
|
try {
|
||||||
|
targetData = TargetData.builder()
|
||||||
|
.id(UUID.randomUUID().toString())
|
||||||
|
.targetId(target.getId())
|
||||||
|
.setDate(new SimpleDateFormat("yyyy-MM-dd").parse(strArr[2]))
|
||||||
|
.xShow(xShow)
|
||||||
|
.cycle(strArr[1])
|
||||||
|
.createTime(now)
|
||||||
|
.updateTime(now)
|
||||||
|
.val(CheckUtils.roundToDecimalPlaces(result, 6))
|
||||||
|
.targetCycle(target.getCycle())
|
||||||
|
.build();
|
||||||
|
targetDataMapper.insert(targetData);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
saveMonitor(targetData);
|
||||||
|
return targetData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新的指标数据添加监控数据
|
||||||
|
*
|
||||||
|
* @param targetData 指标数据
|
||||||
|
*/
|
||||||
|
public void saveMonitor(TargetData targetData) {
|
||||||
|
double val = targetData.getVal();
|
||||||
|
String targetId = targetData.getTargetId();
|
||||||
|
|
||||||
|
Target target = targetMapper.selectById(targetId);
|
||||||
|
Date now = new Date();
|
||||||
|
|
||||||
|
QueryWrapper<Monitor> queryWrapper = new QueryWrapper<>();
|
||||||
|
queryWrapper.eq("target_id", target.getId());
|
||||||
|
queryWrapper.eq("x_show", targetData.getXShow());
|
||||||
|
monitorMapper.delete(queryWrapper);
|
||||||
|
|
||||||
|
Monitor monitor = Monitor.builder()
|
||||||
|
.id(UUID.randomUUID().toString())
|
||||||
|
.targetId(targetId)
|
||||||
|
.name(target.getName())
|
||||||
|
.type(target.getType())
|
||||||
|
.topic(target.getTopic())
|
||||||
|
.organization(target.getOrganization())
|
||||||
|
.level(target.getLevel())
|
||||||
|
.unit(target.getUnit())
|
||||||
|
.val(val)
|
||||||
|
.warnLevel(999)
|
||||||
|
.setDate(targetData.getSetDate())
|
||||||
|
.xShow(targetData.getXShow())
|
||||||
|
.createTime(now)
|
||||||
|
.updateTime(now)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
List<Rule> ruleList = ruleMapper.selectList(new QueryWrapper<Rule>().eq("target_id", target.getId()));
|
||||||
|
if (ruleList == null || ruleList.isEmpty()) {
|
||||||
|
monitorMapper.insert(monitor);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Monitor> monitorList = new ArrayList<>();
|
||||||
|
monitorList.add(monitor);
|
||||||
|
|
||||||
|
boolean bl = false;
|
||||||
|
Rule oneRule = null;
|
||||||
|
for (Rule rule : ruleList) {
|
||||||
|
if (oneRule == null || oneRule.getWarnLevel() > rule.getWarnLevel()) {
|
||||||
|
oneRule = rule;
|
||||||
|
}
|
||||||
|
bl = utilService.isWarn(rule, target, targetData);
|
||||||
|
if (bl) {
|
||||||
|
monitorList.add(utilService.getInitMonitor(targetData, target, rule));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!bl) {
|
||||||
|
Monitor mbgkMonitor = utilService.getInitMonitor(targetData, target, oneRule);
|
||||||
|
mbgkMonitor.setWarnLevel(998);
|
||||||
|
monitorList.add(mbgkMonitor);
|
||||||
|
}
|
||||||
|
monitorMapper.insert(monitorList);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
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;
|
||||||
@ -9,21 +8,22 @@ 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.TargetData;
|
||||||
import iet.ustb.sf.domain.TargetOption;
|
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;
|
||||||
|
import iet.ustb.sf.mapper.TargetDataMapper;
|
||||||
|
import iet.ustb.sf.service.TargetDataService;
|
||||||
import iet.ustb.sf.service.TargetService;
|
import iet.ustb.sf.service.TargetService;
|
||||||
import iet.ustb.sf.mapper.TargetMapper;
|
import iet.ustb.sf.mapper.TargetMapper;
|
||||||
|
import iet.ustb.sf.service.UtilService;
|
||||||
import iet.ustb.sf.util.CheckUtils;
|
import iet.ustb.sf.util.CheckUtils;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
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 org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
@ -42,6 +42,15 @@ public class TargetServiceImpl extends ServiceImpl<TargetMapper, Target>
|
|||||||
@Resource
|
@Resource
|
||||||
private CategoryMapper categoryMapper;
|
private CategoryMapper categoryMapper;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private TargetDataMapper targetDataMapper;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private TargetDataService targetDataService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private UtilService utilService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IPage<Target> getTargetsByCategory(JSONObject params) {
|
public IPage<Target> getTargetsByCategory(JSONObject params) {
|
||||||
int pageIndex = Optional.ofNullable(params.getInteger("pageIndex")).orElse(1);
|
int pageIndex = Optional.ofNullable(params.getInteger("pageIndex")).orElse(1);
|
||||||
@ -94,6 +103,178 @@ public class TargetServiceImpl extends ServiceImpl<TargetMapper, Target>
|
|||||||
return list.get(0).get(result.getColumnName()).toString();
|
return list.get(0).get(result.getColumnName()).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public void saveTarget(JSONObject params) {
|
||||||
|
Target target = params.getJSONObject("target").toJavaObject(Target.class);
|
||||||
|
List<TargetOption> showList = params.getJSONArray("show").toJavaList(TargetOption.class);
|
||||||
|
List<TargetOption> searchList = params.getJSONArray("search").toJavaList(TargetOption.class);
|
||||||
|
TargetOption result = params.getJSONObject("result").toJavaObject(TargetOption.class);
|
||||||
|
|
||||||
|
checkTarget(target);
|
||||||
|
String columns = showList.stream().map(TargetOption::getColumnName).collect(Collectors.joining(","));
|
||||||
|
CheckUtils.checkColumns(columns, target.getTableName());
|
||||||
|
CheckUtils.checkSearchOption(searchList, target.getTableName());
|
||||||
|
CheckUtils.checkResultOption(result, target.getTableName());
|
||||||
|
|
||||||
|
Date now = new Date();
|
||||||
|
target.setSearchSql(getSearchSql(showList, searchList, target.getTableName()));
|
||||||
|
params.put("tableName", target.getTableName());
|
||||||
|
target.setResultSql(getResultSql(params));
|
||||||
|
target.setUpdateTime(now);
|
||||||
|
|
||||||
|
Map<String, List<TargetOption>> optionsMap = showList.stream()
|
||||||
|
.peek(option -> {
|
||||||
|
option.setTargetId(target.getId());
|
||||||
|
if (option.getCreateTime() == null) {
|
||||||
|
option.setCreateTime(now);
|
||||||
|
}
|
||||||
|
option.setUpdateTime(now);
|
||||||
|
})
|
||||||
|
.collect(Collectors.groupingBy(TargetOption::getColumnName));
|
||||||
|
|
||||||
|
String cycle = null;
|
||||||
|
for (TargetOption option : searchList) {
|
||||||
|
List<TargetOption> options = optionsMap.get(option.getColumnName());
|
||||||
|
if (options != null && !options.isEmpty()) {
|
||||||
|
TargetOption ori = options.get(0);
|
||||||
|
ori.setOp(ori.getOp() + "," + option.getOp());
|
||||||
|
ori.setFun(option.getFun());
|
||||||
|
ori.setVal(option.getVal());
|
||||||
|
if ("1".equals(option.getOp()) && option.getType() == 1) {
|
||||||
|
if (cycle == null) {
|
||||||
|
cycle = option.getFun();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ThrowUtils.throwIf(!cycle.equals(option.getFun()), ErrorCode.PARAMS_ERROR, "日期类型的周期不一致!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ThrowUtils.throwIf(StringUtils.isEmpty(cycle), ErrorCode.PARAMS_ERROR, "缺少时间条件,无法保存!");
|
||||||
|
target.setCycle(cycle);
|
||||||
|
|
||||||
|
if (target.getId() == null) {
|
||||||
|
target.setId(UUID.randomUUID().toString());
|
||||||
|
target.setCreateTime(now);
|
||||||
|
if (!StringUtils.isEmpty(target.getCategoryId())) {
|
||||||
|
categoryDeal(null, target);
|
||||||
|
}
|
||||||
|
targetMapper.insert(target);
|
||||||
|
saveDate(target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 指标变动后,指标数据处理
|
||||||
|
*
|
||||||
|
* @param target 指标
|
||||||
|
*/
|
||||||
|
private void saveDate(Target target) {
|
||||||
|
targetDataMapper.delete(new QueryWrapper<TargetData>().eq("target_id", target.getId()));
|
||||||
|
String[] strArr = utilService.getCurrentCycleDataByCycle(new Date(), target.getCycle());
|
||||||
|
targetDataService.updateHistory(target, strArr, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 指标变动,处理对应的分类
|
||||||
|
*
|
||||||
|
* @param oldTarget 旧指标
|
||||||
|
* @param newTarget 新指标
|
||||||
|
*/
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public void categoryDeal(Target oldTarget, Target newTarget) {
|
||||||
|
if (oldTarget == null && newTarget == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Set<String> oldList = oldTarget == null ? new HashSet<>() : getOrganizationList(oldTarget.getOrganization());
|
||||||
|
Set<String> newList = newTarget == null ? new HashSet<>() : getOrganizationList(newTarget.getOrganization());
|
||||||
|
|
||||||
|
String tagetId = oldTarget == null ? newTarget.getId() : oldTarget.getId();
|
||||||
|
String categoryId = oldTarget == null ? newTarget.getCategoryId() : oldTarget.getCategoryId();
|
||||||
|
QueryWrapper<Target> query = new QueryWrapper<>();
|
||||||
|
query.eq("category_id", categoryId);
|
||||||
|
query.ne("id", tagetId);
|
||||||
|
List<Target> targetList = targetMapper.selectList(query);
|
||||||
|
Set<String> set = new HashSet<>();
|
||||||
|
for (Target target : targetList) {
|
||||||
|
set.addAll(getOrganizationList(target.getOrganization()));
|
||||||
|
}
|
||||||
|
|
||||||
|
Category category = categoryMapper.selectById(categoryId);
|
||||||
|
Set<String> organizationSet = getOrganizationList(category.getOrganization());
|
||||||
|
|
||||||
|
Iterator<String> iterator = newList.iterator();
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
String news = iterator.next();
|
||||||
|
if (!oldList.isEmpty() && oldList.contains(news)) {
|
||||||
|
oldList.remove(news);
|
||||||
|
iterator.remove();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!set.contains(news)) {
|
||||||
|
organizationSet.add(news);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (String old : oldList) {
|
||||||
|
if (!set.contains(old)) {
|
||||||
|
organizationSet.remove(old);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
category.setOrganization(String.join(",", organizationSet));
|
||||||
|
categoryMapper.insertOrUpdate(category);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 把用逗号拼接的组织字符串转为set集合
|
||||||
|
*
|
||||||
|
* @param organization 组织字符串
|
||||||
|
* @return set组织集合
|
||||||
|
*/
|
||||||
|
private Set<String> getOrganizationList(String organization) {
|
||||||
|
Set<String> set = new HashSet<>();
|
||||||
|
if (StringUtils.isEmpty(organization)) {
|
||||||
|
return set;
|
||||||
|
}
|
||||||
|
if (organization.contains(",")) {
|
||||||
|
set.addAll(Arrays.asList(organization.split(",")));
|
||||||
|
} else {
|
||||||
|
set.add(organization);
|
||||||
|
}
|
||||||
|
return set;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 拼接列表查询SQL
|
||||||
|
*
|
||||||
|
* @param showList 查询集合
|
||||||
|
* @param searchList 条件集合
|
||||||
|
* @param tableName 表名
|
||||||
|
* @return SQL
|
||||||
|
*/
|
||||||
|
private String getSearchSql(List<TargetOption> showList, List<TargetOption> searchList, String tableName) {
|
||||||
|
return "SELECT " + showList.stream().map(TargetOption::getColumnName).collect(Collectors.joining(","))
|
||||||
|
+ " FROM " + tableName + " WHERE " + getWhereSql(searchList);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 指标空值校验
|
||||||
|
*
|
||||||
|
* @param target 指标
|
||||||
|
*/
|
||||||
|
private void checkTarget(Target target) {
|
||||||
|
CheckUtils.checkEmpty(target.getName(), "指标名称");
|
||||||
|
QueryWrapper<Target> query = new QueryWrapper<>();
|
||||||
|
query.eq("name", target.getName());
|
||||||
|
Target nameCheck = targetMapper.selectOne(query);
|
||||||
|
boolean bl = nameCheck != null && (target.getId() == null || !nameCheck.getId().equals(target.getId()));
|
||||||
|
ThrowUtils.throwIf(bl, ErrorCode.PARAMS_ERROR, "指标名称不能重复!");
|
||||||
|
CheckUtils.checkEmpty(String.valueOf(target.getType()), "类型");
|
||||||
|
CheckUtils.checkEmpty(String.valueOf(target.getIsKey()), "是否启用");
|
||||||
|
CheckUtils.checkEmpty(target.getOrganization(), "组织");
|
||||||
|
CheckUtils.checkEmpty(target.getTopic(), "主题");
|
||||||
|
CheckUtils.checkTableName(target.getTableName());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 拼接结果sql
|
* 拼接结果sql
|
||||||
*
|
*
|
||||||
@ -107,8 +288,8 @@ public class TargetServiceImpl extends ServiceImpl<TargetMapper, Target>
|
|||||||
CheckUtils.checkSearchOption(searchList, tableName);
|
CheckUtils.checkSearchOption(searchList, tableName);
|
||||||
TargetOption result = params.getJSONObject("result").toJavaObject(TargetOption.class);
|
TargetOption result = params.getJSONObject("result").toJavaObject(TargetOption.class);
|
||||||
CheckUtils.checkResultOption(result, tableName);
|
CheckUtils.checkResultOption(result, tableName);
|
||||||
return "SELECT ROUND(" + result.getFun() + "(CAST(" + result.getColumnName() + " AS DOUBLE)), 6) AS " +
|
return "SELECT ROUND(" + result.getFun() + "(CAST(" + result.getColumnName() + " AS DOUBLE)), 6) AS result " +
|
||||||
result.getColumnName() + " FROM " + tableName + " WHERE " + getWhereSql(searchList);
|
"FROM " + tableName + " WHERE " + getWhereSql(searchList);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -122,66 +303,8 @@ public class TargetServiceImpl extends ServiceImpl<TargetMapper, Target>
|
|||||||
for (TargetOption option : searchList) {
|
for (TargetOption option : searchList) {
|
||||||
int type = option.getType();
|
int type = option.getType();
|
||||||
if (type == 1) {
|
if (type == 1) {
|
||||||
String start, end;
|
sql.append(option.getColumnName()).append(" >= {0} and ")
|
||||||
LocalDate day = LocalDate.now();
|
.append(option.getColumnName()).append(" < {1} and ");
|
||||||
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) {
|
} else if (type == 2) {
|
||||||
sql.append(getIsNullSql(option));
|
sql.append(getIsNullSql(option));
|
||||||
} else {
|
} else {
|
||||||
|
337
src/main/java/iet/ustb/sf/service/impl/UtilServiceImpl.java
Normal file
337
src/main/java/iet/ustb/sf/service/impl/UtilServiceImpl.java
Normal file
@ -0,0 +1,337 @@
|
|||||||
|
package iet.ustb.sf.service.impl;
|
||||||
|
|
||||||
|
import iet.ustb.sf.domain.Monitor;
|
||||||
|
import iet.ustb.sf.domain.Rule;
|
||||||
|
import iet.ustb.sf.domain.Target;
|
||||||
|
import iet.ustb.sf.domain.TargetData;
|
||||||
|
import iet.ustb.sf.exception.ErrorCode;
|
||||||
|
import iet.ustb.sf.exception.MyException;
|
||||||
|
import iet.ustb.sf.service.UtilService;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import javax.script.ScriptEngine;
|
||||||
|
import javax.script.ScriptEngineManager;
|
||||||
|
import javax.script.ScriptException;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UtilServiceImpl
|
||||||
|
*
|
||||||
|
* @author huangge1199
|
||||||
|
* @since 2025/8/7 15:11:27
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class UtilServiceImpl implements UtilService {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String[] getCurrentCycleDataByCycle(Date date, String cycle) {
|
||||||
|
Calendar calendar = Calendar.getInstance();
|
||||||
|
calendar.setTime(date);
|
||||||
|
calendar.set(Calendar.HOUR_OF_DAY, 0);
|
||||||
|
calendar.set(Calendar.MINUTE, 0);
|
||||||
|
calendar.set(Calendar.SECOND, 0);
|
||||||
|
calendar.set(Calendar.MILLISECOND, 0);
|
||||||
|
|
||||||
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
|
||||||
|
String xShow, showCycle, setDate, start, end;
|
||||||
|
end = sdf.format(calendar.getTime());
|
||||||
|
|
||||||
|
switch (cycle) {
|
||||||
|
case "yesterday":
|
||||||
|
calendar.add(Calendar.DATE, -1);
|
||||||
|
xShow = sdf.format(calendar.getTime());
|
||||||
|
showCycle = "day";
|
||||||
|
setDate = sdf.format(calendar.getTime());
|
||||||
|
start = sdf.format(calendar.getTime());
|
||||||
|
break;
|
||||||
|
case "nearlyWeek":
|
||||||
|
calendar.add(Calendar.DATE, -1);
|
||||||
|
xShow = sdf.format(calendar.getTime());
|
||||||
|
showCycle = "day";
|
||||||
|
setDate = sdf.format(calendar.getTime());
|
||||||
|
calendar.add(Calendar.DATE, -6);
|
||||||
|
start = sdf.format(calendar.getTime());
|
||||||
|
break;
|
||||||
|
case "nearlyMonth":
|
||||||
|
calendar.add(Calendar.DATE, -1);
|
||||||
|
xShow = sdf.format(calendar.getTime());
|
||||||
|
showCycle = "day";
|
||||||
|
setDate = sdf.format(calendar.getTime());
|
||||||
|
calendar.add(Calendar.DATE, -29);
|
||||||
|
start = sdf.format(calendar.getTime());
|
||||||
|
break;
|
||||||
|
case "week":
|
||||||
|
case "lastWeek":
|
||||||
|
if (calendar.get(Calendar.DAY_OF_WEEK) == Calendar.MONDAY) {
|
||||||
|
calendar.add(Calendar.DATE, -7);
|
||||||
|
} else {
|
||||||
|
if (calendar.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) {
|
||||||
|
calendar.add(Calendar.DATE, -7);
|
||||||
|
}
|
||||||
|
calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
|
||||||
|
if ("lastWeek".equals(cycle)) {
|
||||||
|
end = sdf.format(calendar.getTime());
|
||||||
|
calendar.add(Calendar.DATE, -7);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setDate = sdf.format(calendar.getTime());
|
||||||
|
start = sdf.format(calendar.getTime());
|
||||||
|
if (calendar.get(Calendar.WEEK_OF_YEAR) == 1) {
|
||||||
|
calendar.add(Calendar.YEAR, 1);
|
||||||
|
}
|
||||||
|
xShow = calendar.get(Calendar.YEAR) + "-" + String.format("%02d", calendar.get(Calendar.WEEK_OF_YEAR));
|
||||||
|
showCycle = "week";
|
||||||
|
break;
|
||||||
|
case "month":
|
||||||
|
case "lastMonth":
|
||||||
|
if (calendar.get(Calendar.DAY_OF_MONTH) == 1) {
|
||||||
|
calendar.add(Calendar.MONTH, -1);
|
||||||
|
xShow = new SimpleDateFormat("yyyy-MM").format(calendar.getTime());
|
||||||
|
setDate = sdf.format(calendar.getTime());
|
||||||
|
start = sdf.format(calendar.getTime());
|
||||||
|
} else {
|
||||||
|
calendar.set(Calendar.DAY_OF_MONTH, 1);
|
||||||
|
if ("lastMonth".equals(cycle)) {
|
||||||
|
end = sdf.format(calendar.getTime());
|
||||||
|
calendar.add(Calendar.MONTH, -1);
|
||||||
|
}
|
||||||
|
xShow = new SimpleDateFormat("yyyy-MM").format(calendar.getTime());
|
||||||
|
setDate = sdf.format(calendar.getTime());
|
||||||
|
start = sdf.format(calendar.getTime());
|
||||||
|
}
|
||||||
|
showCycle = "month";
|
||||||
|
break;
|
||||||
|
case "product":
|
||||||
|
if (calendar.get(Calendar.DAY_OF_MONTH) <= 26) {
|
||||||
|
calendar.set(Calendar.DAY_OF_MONTH, 26);
|
||||||
|
xShow = new SimpleDateFormat("yyyy-MM").format(calendar.getTime());
|
||||||
|
calendar.add(Calendar.MONTH, -1);
|
||||||
|
setDate = sdf.format(calendar.getTime());
|
||||||
|
start = sdf.format(calendar.getTime());
|
||||||
|
} else {
|
||||||
|
calendar.set(Calendar.DAY_OF_MONTH, 26);
|
||||||
|
setDate = sdf.format(calendar.getTime());
|
||||||
|
start = sdf.format(calendar.getTime());
|
||||||
|
calendar.add(Calendar.MONTH, 1);
|
||||||
|
xShow = new SimpleDateFormat("yyyy-MM").format(calendar.getTime());
|
||||||
|
}
|
||||||
|
showCycle = "product";
|
||||||
|
break;
|
||||||
|
case "lastProduct":
|
||||||
|
if (calendar.get(Calendar.DAY_OF_MONTH) < 26) {
|
||||||
|
calendar.add(Calendar.MONTH, -1);
|
||||||
|
}
|
||||||
|
calendar.set(Calendar.DAY_OF_MONTH, 26);
|
||||||
|
xShow = new SimpleDateFormat("yyyy-MM").format(calendar.getTime());
|
||||||
|
end = sdf.format(calendar.getTime());
|
||||||
|
calendar.add(Calendar.MONTH, -1);
|
||||||
|
setDate = sdf.format(calendar.getTime());
|
||||||
|
start = sdf.format(calendar.getTime());
|
||||||
|
showCycle = "product";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
xShow = null;
|
||||||
|
showCycle = null;
|
||||||
|
setDate = null;
|
||||||
|
start = null;
|
||||||
|
end = null;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new String[]{xShow, showCycle, setDate, start, end};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double getEvalResult(String expression) {
|
||||||
|
expression = replaceFunction(expression, "SUM", this::sum);
|
||||||
|
expression = replaceFunction(expression, "AVG", this::avg);
|
||||||
|
expression = replaceFunction(expression, "MIN", this::min);
|
||||||
|
expression = replaceFunction(expression, "MAX", this::max);
|
||||||
|
expression = replaceFunction(expression, "COUNT", this::count);
|
||||||
|
expression = replaceFunction(expression, "MEDIAN", this::median);
|
||||||
|
ScriptEngineManager manager = new ScriptEngineManager();
|
||||||
|
ScriptEngine engine = manager.getEngineByName("javascript");
|
||||||
|
double result;
|
||||||
|
try {
|
||||||
|
result = Double.parseDouble(engine.eval(expression).toString());
|
||||||
|
} catch (ScriptException e) {
|
||||||
|
throw new MyException(ErrorCode.SYSTEM_ERROR, "表达式错误");
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isWarn(Rule rule, Target target, TargetData targetData) {
|
||||||
|
double targetVal = rule.getTarget();
|
||||||
|
double val = targetData.getVal();
|
||||||
|
double rate = rule.getRate();
|
||||||
|
switch (rule.getOp()) {
|
||||||
|
case ">":
|
||||||
|
if (val > targetVal + targetVal * rate) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "<":
|
||||||
|
if (val < targetVal - targetVal * rate) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ">=":
|
||||||
|
if (val >= targetVal + targetVal * rate) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "<=":
|
||||||
|
if (val <= targetVal - targetVal * rate) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "=":
|
||||||
|
if (val == targetVal * rate) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "!=":
|
||||||
|
if (val != targetVal * rate) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "between":
|
||||||
|
if (val > targetVal - targetVal * rate && val < targetVal + targetVal * rate) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Monitor getInitMonitor(TargetData targetData, Target target, Rule rule) {
|
||||||
|
Date now = new Date();
|
||||||
|
return Monitor.builder()
|
||||||
|
.id(UUID.randomUUID().toString())
|
||||||
|
.targetId(targetData.getTargetId())
|
||||||
|
.ruleId(rule.getId())
|
||||||
|
.name(target.getName())
|
||||||
|
.type(target.getType())
|
||||||
|
.topic(target.getTopic())
|
||||||
|
.organization(target.getOrganization())
|
||||||
|
.level(target.getLevel())
|
||||||
|
.cycle(rule.getCycle())
|
||||||
|
.unit(target.getUnit())
|
||||||
|
.target(rule.getTarget())
|
||||||
|
.val(targetData.getVal())
|
||||||
|
.warnLevel(rule.getWarnLevel())
|
||||||
|
.setDate(targetData.getSetDate())
|
||||||
|
.xShow(targetData.getXShow())
|
||||||
|
.createTime(now)
|
||||||
|
.updateTime(now)
|
||||||
|
.warnType(rule.getType())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理函数方法
|
||||||
|
*
|
||||||
|
* @param expression 字符串表达式
|
||||||
|
* @param functionName 方法名
|
||||||
|
* @param function 计数方法的值
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
private String replaceFunction(String expression, String functionName, Function<double[], Double> function) {
|
||||||
|
Pattern pattern = Pattern.compile(functionName + "\\(([^)]+)\\)");
|
||||||
|
Matcher matcher = pattern.matcher(expression);
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
|
||||||
|
while (matcher.find()) {
|
||||||
|
String numbers = matcher.group(1);
|
||||||
|
double result = function.apply(parseNumbers(numbers));
|
||||||
|
matcher.appendReplacement(sb, String.valueOf(result));
|
||||||
|
}
|
||||||
|
matcher.appendTail(sb);
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将以逗号分割的数字字符串转为数值数组
|
||||||
|
*
|
||||||
|
* @param numbers 以逗号分割的数字字符串
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
private double[] parseNumbers(String numbers) {
|
||||||
|
return Arrays.stream(numbers.split(",")).mapToDouble(Double::parseDouble).toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 求和
|
||||||
|
*
|
||||||
|
* @param numbers 数字集合
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
private double sum(double[] numbers) {
|
||||||
|
return Arrays.stream(numbers).sum();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 平均值
|
||||||
|
*
|
||||||
|
* @param numbers 数字集合
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
private double avg(double[] numbers) {
|
||||||
|
return sum(numbers) / numbers.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 最小值
|
||||||
|
*
|
||||||
|
* @param numbers 数字集合
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
private double min(double[] numbers) {
|
||||||
|
return Arrays.stream(numbers).min().orElse(Double.NaN);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 最大值
|
||||||
|
*
|
||||||
|
* @param numbers 数字集合
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
private double max(double[] numbers) {
|
||||||
|
return Arrays.stream(numbers).max().orElse(Double.NaN);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计数
|
||||||
|
*
|
||||||
|
* @param numbers 数字集合
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
private double count(double[] numbers) {
|
||||||
|
return numbers.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 中位数
|
||||||
|
*
|
||||||
|
* @param numbers 数字集合
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
private double median(double[] numbers) {
|
||||||
|
Arrays.sort(numbers);
|
||||||
|
int length = numbers.length;
|
||||||
|
if (length % 2 == 0) {
|
||||||
|
return (numbers[length / 2 - 1] + numbers[length / 2]) / 2.0;
|
||||||
|
} else {
|
||||||
|
return numbers[length / 2];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -8,6 +8,8 @@ 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.math.BigDecimal;
|
||||||
|
import java.math.RoundingMode;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
@ -151,4 +153,17 @@ public class CheckUtils {
|
|||||||
ThrowUtils.throwIf(!funList.contains(fun), ErrorCode.PARAMS_ERROR, "方法错误!");
|
ThrowUtils.throwIf(!funList.contains(fun), ErrorCode.PARAMS_ERROR, "方法错误!");
|
||||||
checkColumns(option.getColumnName(), tableName);
|
checkColumns(option.getColumnName(), tableName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保留指定位小数
|
||||||
|
*
|
||||||
|
* @param value 传入值
|
||||||
|
* @param round 保留位数
|
||||||
|
* @return 结果值
|
||||||
|
*/
|
||||||
|
public static double roundToDecimalPlaces(Double value, int round) {
|
||||||
|
BigDecimal bd = new BigDecimal(value);
|
||||||
|
bd = bd.setScale(round, RoundingMode.HALF_UP);
|
||||||
|
return bd.doubleValue();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user