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 rule = ruleRedis.getRule(dto.getStcd(), validateMapper); if (CollectionUtils.isEmpty(rule)) { return true; } // Map> items = rule.stream() // .collect(Collectors.groupingBy(ValidateVo::getItem)); // // List rules = new ArrayList<>(); // // if (Objects.nonNull(p)) { // List list = items.get("P"); // if (CollectionUtils.isNotEmpty(list)) { // rules.addAll(list); // } // } // if (Objects.nonNull(z)) { // List list = items.get("Z"); // if (CollectionUtils.isNotEmpty(list)) { // rules.addAll(list); // } // } // if (Objects.nonNull(q)) { // List 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 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 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 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; } }