527 lines
14 KiB
Java
527 lines
14 KiB
Java
package com.whdc.valid.service;
|
|
|
|
import com.alibaba.fastjson.JSON;
|
|
import com.alibaba.fastjson.JSONException;
|
|
import com.alibaba.fastjson.JSONObject;
|
|
import com.whdc.model.bean.ItemType;
|
|
import com.whdc.valid.component.RuleRedisService;
|
|
import com.whdc.valid.mapper.ValidateMapper;
|
|
import com.whdc.valid.model.ValidateDto;
|
|
import com.whdc.valid.model.ValidateVo;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import org.apache.commons.collections.CollectionUtils;
|
|
import org.apache.commons.lang3.StringUtils;
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.stereotype.Service;
|
|
|
|
import java.math.BigDecimal;
|
|
import java.util.Date;
|
|
import java.util.List;
|
|
import java.util.Objects;
|
|
import java.util.stream.Collectors;
|
|
|
|
import static com.whdc.model.bean.ItemType.getByValue;
|
|
import static com.whdc.valid.error.MyException.getException;
|
|
|
|
|
|
@Slf4j
|
|
@Service
|
|
public class ValidateServiceImpl implements ValidateService {
|
|
|
|
@Autowired
|
|
private ValidateMapper validateMapper;
|
|
|
|
@Autowired
|
|
private RuleRedisService ruleRedis;
|
|
|
|
/**
|
|
* 正常值判断
|
|
*
|
|
* @param json
|
|
* @return true: 通过 false: 不通过
|
|
*/
|
|
public Boolean validate(String json) {
|
|
return validate(json, null);
|
|
}
|
|
|
|
/**
|
|
* 弃用
|
|
*
|
|
* @param json
|
|
* @return
|
|
*/
|
|
public Boolean validateV1(String json) {
|
|
|
|
ValidateDto dto = getValidateDto(json); //正常值
|
|
|
|
ValidateDto.Data data = dto.getData();
|
|
BigDecimal p = data.getP();
|
|
BigDecimal z = data.getZ();
|
|
BigDecimal q = data.getQ();
|
|
|
|
if (BigDecimal.ZERO.compareTo(p) < 0
|
|
&& BigDecimal.ZERO.compareTo(z) < 0
|
|
&& BigDecimal.ZERO.compareTo(q) < 0
|
|
) {
|
|
return false;
|
|
}
|
|
|
|
List<ValidateVo> rule = ruleRedis.getRule(dto.getStcd(), validateMapper);
|
|
if (CollectionUtils.isEmpty(rule)) {
|
|
return true;
|
|
}
|
|
|
|
// Map<String, List<ValidateVo>> items = rule.stream()
|
|
// .collect(Collectors.groupingBy(ValidateVo::getItem));
|
|
//
|
|
// List<ValidateVo> rules = new ArrayList<>();
|
|
//
|
|
// if (Objects.nonNull(p)) {
|
|
// List<ValidateVo> list = items.get("P");
|
|
// if (CollectionUtils.isNotEmpty(list)) {
|
|
// rules.addAll(list);
|
|
// }
|
|
// }
|
|
// if (Objects.nonNull(z)) {
|
|
// List<ValidateVo> list = items.get("Z");
|
|
// if (CollectionUtils.isNotEmpty(list)) {
|
|
// rules.addAll(list);
|
|
// }
|
|
// }
|
|
// if (Objects.nonNull(q)) {
|
|
// List<ValidateVo> list = items.get("Q");
|
|
// if (CollectionUtils.isNotEmpty(list)) {
|
|
// rules.addAll(list);
|
|
// }
|
|
// }
|
|
// if (CollectionUtils.isEmpty(rules)) {
|
|
// return true;
|
|
// }
|
|
|
|
|
|
Date tm = dto.getTm();
|
|
long currentTime = System.currentTimeMillis();
|
|
|
|
|
|
for (ValidateVo vo : rule) {
|
|
|
|
BigDecimal min = vo.getMin();
|
|
BigDecimal max = vo.getMax();
|
|
Integer leadingTime = vo.getLeadingTime();
|
|
Integer lagTime = vo.getLagTime();
|
|
|
|
if (Objects.nonNull(leadingTime)) {
|
|
if (tm.getTime() > currentTime + (leadingTime * 1000)) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if (Objects.nonNull(lagTime)) {
|
|
if (tm.getTime() < currentTime - (lagTime * 1000)) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
String item = vo.getItem();
|
|
|
|
if (StringUtils.isBlank(item)) {
|
|
continue;
|
|
}
|
|
|
|
if (Objects.isNull(min) && Objects.isNull(max) && Objects.isNull(leadingTime) && Objects.isNull(lagTime)) {
|
|
continue;
|
|
}
|
|
|
|
ItemType itemType = getByValue(item);
|
|
|
|
if (Objects.isNull(itemType)) {
|
|
continue;
|
|
}
|
|
|
|
switch (itemType) {
|
|
case YU_LIANG: { // 雨量判断 P
|
|
if (!rangeRuleValidate(p, min, max)) {
|
|
return false;
|
|
}
|
|
|
|
break;
|
|
}
|
|
case SHUI_WEI: { // 水位判断 Z
|
|
|
|
if (!rangeRuleValidate(z, min, max)) {
|
|
return false;
|
|
}
|
|
|
|
break;
|
|
}
|
|
case LIU_LIANG: { // 流量判断 Q
|
|
|
|
if (!rangeRuleValidate(q, min, max)) {
|
|
return false;
|
|
}
|
|
|
|
break;
|
|
}
|
|
default: {
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
return true;
|
|
}
|
|
|
|
private Boolean rangeRuleValidate(BigDecimal value, BigDecimal min, BigDecimal max) {
|
|
|
|
if (Objects.nonNull(value)) {
|
|
|
|
if (Objects.nonNull(min) && value.compareTo(min) < 0) {
|
|
log.info("对比值小于最小值: {} < {}", value, min);
|
|
return false;
|
|
}
|
|
|
|
if (Objects.nonNull(max) && value.compareTo(max) > 0) {
|
|
log.info("对比值大于最大值: {} < {}", max, value);
|
|
return false;
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* 判断差值
|
|
*
|
|
* @param json
|
|
* @param prevJson
|
|
* @return true: 通过 false: 不通过
|
|
*/
|
|
public Boolean validate(String json, String prevJson) {
|
|
|
|
ValidateDto dto = getValidateDto(json); //正常值
|
|
ValidateDto prevDto = null;
|
|
|
|
if (StringUtils.isNotBlank(prevJson)) {
|
|
|
|
prevDto = getValidateDto(prevJson); // 老差值
|
|
}
|
|
|
|
ValidateDto.Data data = dto.getData();
|
|
BigDecimal p = data.getP();
|
|
BigDecimal z = data.getZ();
|
|
BigDecimal q = data.getQ();
|
|
|
|
if (BigDecimal.ZERO.compareTo(p) < 0
|
|
&& BigDecimal.ZERO.compareTo(z) < 0
|
|
&& BigDecimal.ZERO.compareTo(q) < 0
|
|
) {
|
|
log.info("对比值小于0: {} {} {}", p, z, q);
|
|
|
|
return false;
|
|
}
|
|
|
|
List<ValidateVo> rule = ruleRedis.getRule(dto.getStcd(), validateMapper);
|
|
if (CollectionUtils.isEmpty(rule)) {
|
|
log.info("规则为空: {}", rule);
|
|
return true;
|
|
}
|
|
|
|
|
|
Date tm = dto.getTm();
|
|
long currentTime = System.currentTimeMillis();
|
|
|
|
|
|
for (ValidateVo vo : rule) {
|
|
|
|
BigDecimal min = vo.getMin();
|
|
BigDecimal max = vo.getMax();
|
|
Integer leadingTime = vo.getLeadingTime();
|
|
Integer lagTime = vo.getLagTime();
|
|
String item = vo.getItem();
|
|
ItemType itemType = getByValue(item);
|
|
|
|
if (Objects.nonNull(min) && Objects.nonNull(max) && Objects.nonNull(leadingTime) && Objects.nonNull(lagTime)) {
|
|
if (Objects.nonNull(leadingTime)) {
|
|
long time = currentTime + (leadingTime * 1000);
|
|
if (tm.getTime() > time) {
|
|
log.info("时间大于最大差值时间: {} > {}", tm.getTime(), time);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if (Objects.nonNull(lagTime)) {
|
|
long time = currentTime - (lagTime * 1000);
|
|
if (tm.getTime() < time) {
|
|
log.info("时间小于最小差值时间: {} < {}", tm.getTime(), time);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
if (StringUtils.isBlank(item)) {
|
|
log.info("规则类型为空");
|
|
continue;
|
|
}
|
|
|
|
|
|
if (Objects.isNull(itemType)) {
|
|
continue;
|
|
}
|
|
|
|
switch (itemType) {
|
|
case YU_LIANG: { // 雨量判断 P
|
|
if (!rangeRuleValidate(p, min, max)) {
|
|
return false;
|
|
}
|
|
|
|
break;
|
|
}
|
|
case SHUI_WEI: { // 水位判断 Z
|
|
|
|
if (!rangeRuleValidate(z, min, max)) {
|
|
return false;
|
|
}
|
|
|
|
break;
|
|
}
|
|
case LIU_LIANG: { // 流量判断 Q
|
|
|
|
if (!rangeRuleValidate(q, min, max)) {
|
|
return false;
|
|
}
|
|
|
|
break;
|
|
}
|
|
default: {
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
if (Objects.isNull(prevDto)) {
|
|
continue;
|
|
}
|
|
|
|
ValidateDto.Data oldData = prevDto.getData();
|
|
|
|
BigDecimal oldP = oldData.getP();
|
|
BigDecimal oldZ = oldData.getZ();
|
|
BigDecimal oldQ = oldData.getQ();
|
|
|
|
if (BigDecimal.ZERO.compareTo(oldP) < 0
|
|
&& BigDecimal.ZERO.compareTo(oldZ) < 0
|
|
&& BigDecimal.ZERO.compareTo(oldQ) < 0
|
|
) {
|
|
return false;
|
|
}
|
|
|
|
// 获取时间
|
|
Date oldTm = prevDto.getTm();
|
|
|
|
BigDecimal diffMax = vo.getDiffMax();
|
|
Integer duration = vo.getDuration();
|
|
|
|
if (Objects.nonNull(duration)) {
|
|
|
|
if (Math.abs(tm.getTime() - oldTm.getTime()) > duration * 1000) {
|
|
continue;
|
|
}
|
|
|
|
|
|
if (Objects.isNull(itemType)) {
|
|
continue;
|
|
}
|
|
|
|
switch (itemType) {
|
|
case YU_LIANG: { // 雨量判断 P
|
|
if (Objects.nonNull(p) && Objects.nonNull(oldP) && Math.abs(p.subtract(oldP).doubleValue()) > diffMax.doubleValue()) {
|
|
return false;
|
|
}
|
|
|
|
break;
|
|
}
|
|
case SHUI_WEI: { // 水位判断 Z
|
|
|
|
if (Objects.nonNull(z) && Objects.nonNull(oldZ) && Math.abs(z.subtract(oldZ).doubleValue()) > diffMax.doubleValue()) {
|
|
return false;
|
|
}
|
|
|
|
break;
|
|
}
|
|
case LIU_LIANG: { // 流量判断 Q
|
|
|
|
if (Objects.nonNull(q) && Objects.nonNull(oldQ) && Math.abs(q.subtract(oldQ).doubleValue()) > diffMax.doubleValue()) {
|
|
return false;
|
|
}
|
|
|
|
|
|
break;
|
|
}
|
|
default: {
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
public Boolean validateV1(String json, String prevJson) {
|
|
|
|
if (!validate(json)) { // 正常值判断
|
|
return false;
|
|
}
|
|
|
|
ValidateDto dto = getValidateDto(json); // 差值
|
|
|
|
List<ValidateVo> rule = ruleRedis.getRule(dto.getStcd(), validateMapper);
|
|
if (CollectionUtils.isEmpty(rule)) {
|
|
return true;
|
|
}
|
|
|
|
|
|
ValidateDto prevDto = getValidateDto(prevJson); // 老差值
|
|
|
|
|
|
ValidateDto.Data data = dto.getData();
|
|
|
|
BigDecimal p = data.getP();
|
|
BigDecimal z = data.getZ();
|
|
BigDecimal q = data.getQ();
|
|
|
|
if (BigDecimal.ZERO.compareTo(p) < 0
|
|
&& BigDecimal.ZERO.compareTo(z) < 0
|
|
&& BigDecimal.ZERO.compareTo(q) < 0
|
|
) {
|
|
return false;
|
|
}
|
|
|
|
ValidateDto.Data oldData = prevDto.getData();
|
|
BigDecimal oldP = oldData.getP();
|
|
BigDecimal oldZ = oldData.getZ();
|
|
BigDecimal oldQ = oldData.getQ();
|
|
|
|
if (BigDecimal.ZERO.compareTo(oldP) < 0
|
|
&& BigDecimal.ZERO.compareTo(oldZ) < 0
|
|
&& BigDecimal.ZERO.compareTo(oldQ) < 0
|
|
) {
|
|
return false;
|
|
}
|
|
|
|
|
|
// 获取时间
|
|
Date tm = dto.getTm();
|
|
Date oldTm = prevDto.getTm();
|
|
|
|
for (ValidateVo vo : rule) {
|
|
|
|
BigDecimal diffMax = vo.getDiffMax();
|
|
Integer duration = vo.getDuration();
|
|
|
|
if (Objects.nonNull(duration)) {
|
|
|
|
if (Math.abs(tm.getTime() - oldTm.getTime()) > duration * 1000) {
|
|
continue;
|
|
}
|
|
|
|
if (Objects.nonNull(p) && Objects.nonNull(oldP) && Math.abs(p.subtract(oldP).doubleValue()) > diffMax.doubleValue()) {
|
|
return false;
|
|
}
|
|
if (Objects.nonNull(z) && Objects.nonNull(oldZ) && Math.abs(z.subtract(oldZ).doubleValue()) > diffMax.doubleValue()) {
|
|
return false;
|
|
}
|
|
if (Objects.nonNull(q) && Objects.nonNull(oldQ) && Math.abs(q.subtract(oldQ).doubleValue()) > diffMax.doubleValue()) {
|
|
return false;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* 判断是否需要传入多个值
|
|
*
|
|
* @param json
|
|
* @return true: 需要, false: 不需要
|
|
*/
|
|
public Boolean needPrev(String json) {
|
|
|
|
ValidateDto dto = getValidateDto(json); // 多个值
|
|
|
|
List<ValidateVo> rule = ruleRedis.getRule(dto.getStcd(), validateMapper);
|
|
|
|
if (CollectionUtils.isEmpty(rule)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (CollectionUtils.isEmpty(
|
|
|
|
rule.stream().map(ValidateVo::getDiffMax)
|
|
|
|
.filter(Objects::nonNull)
|
|
|
|
.collect(Collectors.toList())
|
|
|
|
)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
private ValidateDto getValidateDto(String json) {
|
|
JSONObject jsonObject;
|
|
try {
|
|
jsonObject = JSON.parseObject(json);
|
|
} catch (JSONException e) {
|
|
throw getException("格式错误: " + json);
|
|
}
|
|
|
|
|
|
if (Objects.isNull(jsonObject)) {
|
|
throw getException("空数据");
|
|
}
|
|
|
|
ValidateDto validateDto = JSON.toJavaObject(jsonObject, ValidateDto.class);
|
|
|
|
if (Objects.isNull(validateDto.getStcd())) {
|
|
throw getException("编码不能为空");
|
|
}
|
|
|
|
Date tm = validateDto.getTm();
|
|
if (Objects.isNull(tm)) {
|
|
throw getException("时间不能为空");
|
|
}
|
|
|
|
|
|
ValidateDto.Data data = validateDto.getData();
|
|
|
|
if (Objects.isNull(data)) {
|
|
throw getException("数据不能为空");
|
|
} else {
|
|
if (Objects.isNull(data.getP())
|
|
&& Objects.isNull(data.getQ())
|
|
&& Objects.isNull(data.getZ())
|
|
) {
|
|
throw getException("数据内容不能为空");
|
|
}
|
|
}
|
|
|
|
return validateDto;
|
|
}
|
|
|
|
|
|
}
|