feat: 预警扩展接口

This commit is contained in:
tangwei 2026-07-23 14:41:52 +08:00
parent aec144ccf3
commit 001bccb626
12 changed files with 940 additions and 21 deletions

View File

@ -0,0 +1,90 @@
package com.yfd.platform.qgc_base.domain;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
/**
* 预警规则配置详情表
*/
@Data
@TableName("MS_WARN_RULE_DETAIL_B")
public class MsWarnRuleDetailB implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(type = IdType.ASSIGN_UUID)
private String id;
@TableField("RULE_ID")
private String ruleId;
@TableField("TB_ID")
private String tbId;
@TableField("YS")
private String ys;
@TableField("TM")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date tm;
@TableField("BEGIN_TIME")
private String beginTime;
@TableField("END_TIME")
private String endTime;
@TableField("MIN_VAL")
private BigDecimal minVal;
@TableField("MAX_VAL")
private BigDecimal maxVal;
@TableField("LVL")
private Integer lvl;
@TableField("LVL_NOTE")
private String lvlNote;
@TableField("STTY")
private String stty;
@TableField("ALWYRQST")
private Integer alwyrqst;
@TableField("ELAEQ")
private Integer elaeq;
@TableField("QECSC")
private BigDecimal qecsc;
@TableField("DESCRIPTION")
private String description;
@TableField("WARN_LEVEL")
private Integer warnLevel;
@TableField("MARK")
private String mark;
@TableField("VLSR")
private String vlsr;
@TableField("VLSR_TM")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date vlsrTm;
@TableField("RECORD_USER")
private String recordUser;
@TableField("RECORD_TIME")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date recordTime;
@TableField("IS_DELETED")
private Integer isDeleted;
}

View File

@ -0,0 +1,59 @@
package com.yfd.platform.qgc_base.domain;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
* 预警规则与测站关联表
*/
@Data
@TableName("MS_WARN_RULE_STBPRP_B")
public class MsWarnRuleStbprpB implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(type = IdType.ASSIGN_UUID)
private String id;
@TableField("RULE_ID")
private String ruleId;
@TableField("STTP_ID")
private String sttpId;
@TableField("STCD")
private String stcd;
@TableField("DESCRIPTION")
private String description;
@TableField("RECORD_USER")
private String recordUser;
@TableField("RECORD_TIME")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date recordTime;
@TableField("MODIFY_USER")
private String modifyUser;
@TableField("MODIFY_TIME")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date modifyTime;
@TableField("IS_DELETED")
private Integer isDeleted;
@TableField("DELETE_USER")
private String deleteUser;
@TableField("DELETE_TIME")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date deleteTime;
@TableField("ISOLATE_ID")
private String isolateId;
}

View File

@ -2,6 +2,41 @@ package com.yfd.platform.qgc_base.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yfd.platform.qgc_base.domain.MsWarnRuleB; import com.yfd.platform.qgc_base.domain.MsWarnRuleB;
import com.yfd.platform.qgc_sys.warnRule.vo.WarnRuleVo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import java.util.List;
@Mapper
public interface MsWarnRuleBMapper extends BaseMapper<MsWarnRuleB> { public interface MsWarnRuleBMapper extends BaseMapper<MsWarnRuleB> {
@Update("UPDATE MS_WARN_RULE_B SET IS_SHOW = #{isShow} WHERE RULE_CODE IN ('common','custom')")
void updateIsShow(@Param("isShow") Integer isShow);
@Select("SELECT RULE_NAME AS ruleName FROM (" +
"SELECT RULE_NAME FROM MS_WARN_RULE_B " +
"WHERE RULE_CODE = 'custom' AND STCD = #{stcd} AND IS_DELETED = 0 AND RECORD_TIME IS NOT NULL " +
"ORDER BY RECORD_TIME DESC) WHERE ROWNUM = 1")
String getCustomRuleNameByStcd(@Param("stcd") String stcd);
@Select("SELECT t1.ID, RULE_NAME AS ruleName, RULE_CODE AS ruleCode, t2.LVL AS lvl " +
"FROM MS_WARN_RULE_B t1 INNER JOIN MS_WARN_RULE_DETAIL_B t2 ON t1.ID = t2.RULE_ID " +
"WHERE (t1.RULE_CODE = 'common' OR (t1.RULE_CODE = 'custom' AND t1.STCD = #{stcd})) " +
"AND t1.RULE_TYPE = #{ruleType} AND t1.IS_DELETED = 0 AND t2.IS_DELETED = 0 " +
"GROUP BY t1.ID, RULE_NAME, RULE_CODE, lvl")
List<WarnRuleVo> getRuleListByStcd(@Param("stcd") String stcd, @Param("ruleType") String ruleType);
@Update("UPDATE MS_WARN_RULE_B SET STCD = #{stcd} WHERE ID = #{id}")
void updateStcd(@Param("stcd") String stcd, @Param("id") String id);
@Select("SELECT t2.STTP_NAME FROM MS_STBPRP_T t1 INNER JOIN SD_STTP_B t2 ON t1.STTP = t2.ID WHERE t1.STCD = #{stcd}")
String getSttpCodeNameByStcd(@Param("stcd") String stcd);
@Select("SELECT COUNT(t1.ID) FROM MS_WARN_RULE_B t1 INNER JOIN MS_WARN_RULE_DETAIL_B t2 ON t1.ID = t2.RULE_ID " +
"WHERE t1.RULE_TYPE = 'WQ_RULE' AND t1.RULE_CODE = 'common' AND t2.LVL = #{lvl} " +
"AND t1.IS_DELETED = 0 AND t2.IS_DELETED = 0")
Integer checkWqCommonRuleExist(@Param("lvl") Integer lvl);
} }

View File

@ -0,0 +1,10 @@
package com.yfd.platform.qgc_base.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yfd.platform.qgc_base.domain.MsWarnRuleDetailB;
/**
* 预警规则配置详情表 Mapper
*/
public interface MsWarnRuleDetailBMapper extends BaseMapper<MsWarnRuleDetailB> {
}

View File

@ -0,0 +1,23 @@
package com.yfd.platform.qgc_base.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yfd.platform.qgc_base.domain.MsWarnRuleStbprpB;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
/**
* 预警规则与测站关联表 Mapper
*/
public interface MsWarnRuleStbprpBMapper extends BaseMapper<MsWarnRuleStbprpB> {
@Delete("DELETE FROM MS_WARN_RULE_STBPRP_B WHERE ID = #{id}")
void deleteBind(@Param("id") String id);
@Select("SELECT t1.ID, t1.RULE_ID, t1.STCD, t1.STTP_ID AS sttpId " +
"FROM MS_WARN_RULE_STBPRP_B t1 " +
"INNER JOIN MS_WARN_RULE_B t2 ON t1.RULE_ID = t2.ID " +
"WHERE t1.STCD = #{stcd} AND t2.RULE_TYPE = #{ruleType} " +
"AND t2.RULE_CODE IN ('common','custom') AND t1.IS_DELETED = 0 AND t2.IS_DELETED = 0")
MsWarnRuleStbprpB getBindRuleByStcd(@Param("stcd") String stcd, @Param("ruleType") String ruleType);
}

View File

@ -4,9 +4,12 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import com.yfd.platform.common.DataSourceRequest; import com.yfd.platform.common.DataSourceRequest;
import com.yfd.platform.qgc_base.domain.MsWarnRuleB; import com.yfd.platform.qgc_base.domain.MsWarnRuleB;
import com.yfd.platform.qgc_sys.warnRule.vo.MsWarnRuleBVo;
import com.yfd.platform.qgc_sys.warnRule.vo.WarnRuleVo;
import com.yfd.platform.qgc_sys.warnRule.vo.WarnYsVo; import com.yfd.platform.qgc_sys.warnRule.vo.WarnYsVo;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* 预警规则配置 Service 接口 * 预警规则配置 Service 接口
@ -21,4 +24,49 @@ public interface IMsWarnRuleBService extends IService<MsWarnRuleB> {
* 获取告警类型对应的要素列表 * 获取告警类型对应的要素列表
*/ */
List<WarnYsVo> getAllYs(String ruleType); List<WarnYsVo> getAllYs(String ruleType);
/**
* 新增或修改预警规则
*/
MsWarnRuleB addOrUpdate(MsWarnRuleBVo vo);
/**
* 校验规则是否被测站引用
*/
boolean check(String id);
/**
* 删除规则绑定
*/
void deleteBind(String id);
/**
* 删除规则物理删除详情和绑定逻辑删除主表
*/
void deleteRule(String id);
/**
* 修改规则是否展示
*/
void updateShow(Integer isShow);
/**
* 获取水位和生态流量限值
*/
Map<String, Object> getLimit(DataSourceRequest request);
/**
* 查询测站和预警规则绑定列表
*/
Page<MsWarnRuleBVo> getRuleBindList(DataSourceRequest request);
/**
* 根据id查询规则配置详情
*/
MsWarnRuleBVo getRuleBindDetail(String ruleId, String bindId);
/**
* 根据stcd查询可绑定的规则
*/
List<WarnRuleVo> getRuleListByStcd(String stcd, String ruleType, String lvl);
} }

View File

@ -1,28 +1,38 @@
package com.yfd.platform.qgc_base.service.impl; package com.yfd.platform.qgc_base.service.impl;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yfd.platform.common.DataSourceRequest; import com.yfd.platform.common.DataSourceRequest;
import com.yfd.platform.common.MicroservicDynamicSQLMapper; import com.yfd.platform.common.MicroservicDynamicSQLMapper;
import com.yfd.platform.qgc_base.domain.MsWarnRuleB; import com.yfd.platform.qgc_base.domain.MsWarnRuleB;
import com.yfd.platform.qgc_base.domain.MsWarnRuleDetailB;
import com.yfd.platform.qgc_base.domain.MsWarnRuleStbprpB;
import com.yfd.platform.qgc_base.mapper.MsWarnRuleBMapper; import com.yfd.platform.qgc_base.mapper.MsWarnRuleBMapper;
import com.yfd.platform.qgc_base.mapper.MsWarnRuleDetailBMapper;
import com.yfd.platform.qgc_base.mapper.MsWarnRuleStbprpBMapper;
import com.yfd.platform.qgc_base.service.IMsOperationLogService; import com.yfd.platform.qgc_base.service.IMsOperationLogService;
import com.yfd.platform.qgc_base.service.IMsWarnRuleBService; import com.yfd.platform.qgc_base.service.IMsWarnRuleBService;
import com.yfd.platform.qgc_sys.warnRule.vo.MsWarnRuleBVo;
import com.yfd.platform.qgc_sys.warnRule.vo.MsWarnRuleDetailVo;
import com.yfd.platform.qgc_sys.warnRule.vo.WarnRuleVo;
import com.yfd.platform.qgc_sys.warnRule.vo.WarnYsVo; import com.yfd.platform.qgc_sys.warnRule.vo.WarnYsVo;
import com.yfd.platform.utils.DataSourceRequestUtil; import com.yfd.platform.utils.DataSourceRequestUtil;
import com.yfd.platform.utils.DictCodeToNameConverter; import com.yfd.platform.utils.DictCodeToNameConverter;
import com.yfd.platform.utils.CodeToNameMetadataBo; import com.yfd.platform.utils.CodeToNameMetadataBo;
import com.yfd.platform.utils.SecurityUtils; import com.yfd.platform.utils.SecurityUtils;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList; import java.util.*;
import java.util.Date; import java.util.concurrent.atomic.AtomicInteger;
import java.util.HashMap; import java.util.stream.Collectors;
import java.util.List;
import java.util.Map;
/** /**
* 预警规则配置 Service 实现类 * 预警规则配置 Service 实现类
@ -52,6 +62,12 @@ public class MsWarnRuleBServiceImpl extends ServiceImpl<MsWarnRuleBMapper, MsWar
@Resource @Resource
private MicroservicDynamicSQLMapper microservicDynamicSQLMapper; private MicroservicDynamicSQLMapper microservicDynamicSQLMapper;
@Resource
private MsWarnRuleDetailBMapper msWarnRuleDetailBMapper;
@Resource
private MsWarnRuleStbprpBMapper msWarnRuleStbprpBMapper;
@Override @Override
public Page<MsWarnRuleB> queryPageList(DataSourceRequest request) { public Page<MsWarnRuleB> queryPageList(DataSourceRequest request) {
Page<MsWarnRuleB> page = DataSourceRequestUtil.executeQuery(request, MsWarnRuleB.class, this); Page<MsWarnRuleB> page = DataSourceRequestUtil.executeQuery(request, MsWarnRuleB.class, this);
@ -64,7 +80,7 @@ public class MsWarnRuleBServiceImpl extends ServiceImpl<MsWarnRuleBMapper, MsWar
public boolean add(MsWarnRuleB entity, String source) { public boolean add(MsWarnRuleB entity, String source) {
boolean result = this.save(entity); boolean result = this.save(entity);
if (result) { if (result) {
msOperationLogService.recordAddDetailLog(entity.getId(),TABLE_NAME, entity, source); msOperationLogService.recordAddDetailLog(entity.getId(), TABLE_NAME, entity, source);
} }
return result; return result;
} }
@ -75,7 +91,7 @@ public class MsWarnRuleBServiceImpl extends ServiceImpl<MsWarnRuleBMapper, MsWar
MsWarnRuleB before = this.getById(entity.getId()); MsWarnRuleB before = this.getById(entity.getId());
boolean result = this.updateById(entity); boolean result = this.updateById(entity);
if (result && before != null) { if (result && before != null) {
msOperationLogService.recordModifyDetailLog(entity.getId(),TABLE_NAME, before, entity, source); msOperationLogService.recordModifyDetailLog(entity.getId(), TABLE_NAME, before, entity, source);
} }
return result; return result;
} }
@ -93,7 +109,7 @@ public class MsWarnRuleBServiceImpl extends ServiceImpl<MsWarnRuleBMapper, MsWar
wrapper.set(MsWarnRuleB::getDeleteUser, SecurityUtils.getCurrentUsername()); wrapper.set(MsWarnRuleB::getDeleteUser, SecurityUtils.getCurrentUsername());
wrapper.set(MsWarnRuleB::getDeleteTime, new Date()); wrapper.set(MsWarnRuleB::getDeleteTime, new Date());
if (this.update(wrapper)) { if (this.update(wrapper)) {
msOperationLogService.recordDeleteDetailLog(id,TABLE_NAME, entity, source); msOperationLogService.recordDeleteDetailLog(id, TABLE_NAME, entity, source);
count++; count++;
} }
} }
@ -107,7 +123,7 @@ public class MsWarnRuleBServiceImpl extends ServiceImpl<MsWarnRuleBMapper, MsWar
"FROM MS_WARN_RULE_B t1\n" + "FROM MS_WARN_RULE_B t1\n" +
"INNER JOIN MS_WARN_RULE_DETAIL_B t2 ON t1.ID = t2.RULE_ID\n" + "INNER JOIN MS_WARN_RULE_DETAIL_B t2 ON t1.ID = t2.RULE_ID\n" +
"INNER JOIN ST_YS_B t3 ON t2.YS = t3.YS\n" + "INNER JOIN ST_YS_B t3 ON t2.YS = t3.YS\n" +
"WHERE t1.RULE_TYPE ='"+dbRuleType+"'\n" + "WHERE t1.RULE_TYPE ='" + dbRuleType + "'\n" +
" AND t1.IS_DELETED = 0\n" + " AND t1.IS_DELETED = 0\n" +
" AND t2.IS_DELETED = 0\n" + " AND t2.IS_DELETED = 0\n" +
"GROUP BY t2.TB_ID, t2.YS, t3.YS_SHOW_NAME"; "GROUP BY t2.TB_ID, t2.YS, t3.YS_SHOW_NAME";
@ -115,6 +131,372 @@ public class MsWarnRuleBServiceImpl extends ServiceImpl<MsWarnRuleBMapper, MsWar
return microservicDynamicSQLMapper.getAllListWithResultType(sql, paramMap, WarnYsVo.class); return microservicDynamicSQLMapper.getAllListWithResultType(sql, paramMap, WarnYsVo.class);
} }
// ==================== 新增方法 ====================
@Override
@Transactional(rollbackFor = Exception.class)
public MsWarnRuleB addOrUpdate(MsWarnRuleBVo vo) {
MsWarnRuleB entity = new MsWarnRuleB();
org.springframework.beans.BeanUtils.copyProperties(vo, entity);
entity.setId(vo.getId());
entity.setModifyTime(new Date());
List<MsWarnRuleDetailVo> detail = vo.getDetail();
Integer lvl = null;
if (!CollectionUtils.isEmpty(detail) && detail.get(0) != null && detail.get(0).getLvl() != null) {
lvl = Integer.parseInt(detail.get(0).getLvl());
}
List<MsWarnRuleDetailB> detailBList = new ArrayList<>();
AtomicInteger i = new AtomicInteger();
if (detail != null) {
for (MsWarnRuleDetailVo detailVo : detail) {
List<WarnYsVo> ysList = detailVo.getYsList();
if (ysList != null) {
for (WarnYsVo ysVo : ysList) {
i.getAndIncrement();
MsWarnRuleDetailB detailB = new MsWarnRuleDetailB();
detailB.setRuleId(vo.getId());
detailB.setTbId(ysVo.getTbId());
detailB.setYs(ysVo.getYs());
detailB.setWarnLevel(detailVo.getWarnLevel());
detailB.setLvl(detailVo.getLvl() != null ? Integer.parseInt(detailVo.getLvl()) : null);
DateTime dateTime = DateUtil.offsetSecond(new Date(), i.get());
detailB.setTm(dateTime);
detailB.setRecordUser(SecurityUtils.getCurrentUsername());
detailB.setRecordTime(dateTime);
detailB.setIsDeleted(0);
detailBList.add(detailB);
}
}
}
}
if (StringUtils.isBlank(vo.getId())) {
// ---- 新增 ----
entity.setRecordUser(SecurityUtils.getCurrentUsername());
if ("common".equals(vo.getRuleCode())) {
boolean exist = checkRuleExist(vo.getRuleType(), lvl);
if (exist) {
throw new RuntimeException("该预警类型的通用规则已存在");
}
}
if (StringUtils.isBlank(vo.getRuleName()) && "custom".equals(vo.getRuleCode())) {
String ruleName = getCustomRuleName(vo.getStcd(), vo.getStnm());
entity.setRuleName(ruleName);
}
entity.setModifyTime(new Date());
this.baseMapper.insert(entity);
if (StringUtils.isNotBlank(entity.getStcd())) {
this.baseMapper.updateStcd(entity.getStcd(), entity.getId());
}
for (MsWarnRuleDetailB detailB : detailBList) {
detailB.setRuleId(entity.getId());
msWarnRuleDetailBMapper.insert(detailB);
}
// 新增测站与规则绑定
if (StringUtils.isNotBlank(vo.getStcd())) {
MsWarnRuleStbprpB existing = msWarnRuleStbprpBMapper.getBindRuleByStcd(vo.getStcd(), vo.getRuleType());
MsWarnRuleStbprpB binding = new MsWarnRuleStbprpB();
binding.setRuleId(entity.getId());
binding.setStcd(vo.getStcd());
binding.setSttpId(vo.getSttpId());
binding.setRecordUser(SecurityUtils.getCurrentUsername());
binding.setRecordTime(new Date());
binding.setIsDeleted(0);
if (existing == null) {
msWarnRuleStbprpBMapper.insert(binding);
} else {
binding.setId(existing.getId());
msWarnRuleStbprpBMapper.updateById(binding);
}
}
msOperationLogService.recordAddDetailLog(entity.getId(), TABLE_NAME, entity, "warningRule");
} else {
// ---- 修改 ----
this.baseMapper.updateById(entity);
// 删除旧要素配置
if (detail != null) {
for (MsWarnRuleDetailVo detailVo : detail) {
Set<String> ysSet = detailVo.getYsList().stream().map(WarnYsVo::getYs).collect(Collectors.toSet());
if (!CollectionUtils.isEmpty(ysSet)) {
LambdaQueryWrapper<MsWarnRuleDetailB> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(MsWarnRuleDetailB::getRuleId, entity.getId());
if (detailVo.getWarnLevel() != null) {
wrapper.eq(MsWarnRuleDetailB::getWarnLevel, detailVo.getWarnLevel());
}
wrapper.in(MsWarnRuleDetailB::getYs, ysSet);
msWarnRuleDetailBMapper.delete(wrapper);
}
}
}
// 新增要素配置
for (MsWarnRuleDetailB detailB : detailBList) {
msWarnRuleDetailBMapper.insert(detailB);
}
// 更新测站与规则绑定
if (StringUtils.isNotBlank(vo.getStcd())) {
MsWarnRuleStbprpB existing = msWarnRuleStbprpBMapper.getBindRuleByStcd(vo.getStcd(), vo.getRuleType());
MsWarnRuleStbprpB binding = new MsWarnRuleStbprpB();
binding.setSttpId(vo.getSttpId());
binding.setStcd(vo.getStcd());
binding.setRuleId(vo.getId());
binding.setRecordUser(SecurityUtils.getCurrentUsername());
binding.setRecordTime(new Date());
binding.setIsDeleted(0);
if (existing == null) {
msWarnRuleStbprpBMapper.insert(binding);
} else {
binding.setId(existing.getId());
msWarnRuleStbprpBMapper.updateById(binding);
}
}
MsWarnRuleB before = this.getById(entity.getId());
msOperationLogService.recordModifyDetailLog(entity.getId(), TABLE_NAME, before, entity, "warningRule");
}
// 修改 isShow
updateShow(vo.getIsShow());
return entity;
}
@Override
public boolean check(String id) {
LambdaQueryWrapper<MsWarnRuleStbprpB> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(MsWarnRuleStbprpB::getRuleId, id);
return msWarnRuleStbprpBMapper.selectCount(wrapper) > 0;
}
@Override
public void deleteBind(String id) {
msWarnRuleStbprpBMapper.deleteBind(id);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void deleteRule(String id) {
// 删除要素配置
LambdaQueryWrapper<MsWarnRuleDetailB> detailWrapper = new LambdaQueryWrapper<>();
detailWrapper.eq(MsWarnRuleDetailB::getRuleId, id);
msWarnRuleDetailBMapper.delete(detailWrapper);
// 删除规则绑定
LambdaQueryWrapper<MsWarnRuleStbprpB> bindWrapper = new LambdaQueryWrapper<>();
bindWrapper.eq(MsWarnRuleStbprpB::getRuleId, id);
msWarnRuleStbprpBMapper.delete(bindWrapper);
// 逻辑删除规则主表
MsWarnRuleB entity = this.getById(id);
LambdaUpdateWrapper<MsWarnRuleB> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.eq(MsWarnRuleB::getId, id);
updateWrapper.set(MsWarnRuleB::getIsDeleted, 1);
updateWrapper.set(MsWarnRuleB::getDeleteUser, SecurityUtils.getCurrentUsername());
updateWrapper.set(MsWarnRuleB::getDeleteTime, new Date());
this.update(updateWrapper);
if (entity != null) {
msOperationLogService.recordDeleteDetailLog(id, TABLE_NAME, entity, "warningRule");
}
}
@Override
public void updateShow(Integer isShow) {
if (isShow != null) {
this.baseMapper.updateIsShow(isShow);
}
}
@Override
public Map<String, Object> getLimit(DataSourceRequest request) {
String ruleType = getFilterFieldValue(request, "ruleType");
ruleType = getOldRuleType(ruleType);
String stcd = getFilterFieldValue(request, "stcd");
String sql = "SELECT * FROM (\n" +
"SELECT t2.MIN_VAL AS min, t2.MAX_VAL AS max\n" +
"FROM MS_WARN_RULE_B t1\n" +
"INNER JOIN MS_WARN_RULE_DETAIL_B t2 ON t1.ID = t2.RULE_ID\n" +
"INNER JOIN MS_WARN_RULE_STBPRP_B t3 ON t1.ID = t3.RULE_ID\n" +
"WHERE t1.RULE_TYPE = '" + ruleType + "'\n" +
" AND t3.STCD = '" + stcd + "'\n" +
"ORDER BY TM DESC) WHERE ROWNUM = 1";
List<Map<String, Object>> allList = microservicDynamicSQLMapper.getAllList(sql, null);
return CollectionUtils.isEmpty(allList) ? new HashMap<>() : allList.get(0);
}
@Override
public Page<MsWarnRuleBVo> getRuleBindList(DataSourceRequest request) {
StringBuilder sql = new StringBuilder();
sql.append("SELECT id AS bindId, STCD, STNM, STTP_CODE AS sttpCode, RULE_NAME AS ruleName, ")
.append("RULE_TYPE AS ruleType, recordUser, MODIFY_TIME AS modifyTime, isShow, RULE_CODE AS ruleCode ")
.append("FROM (\n")
.append("SELECT t1.ID, t1.STCD, t3.STNM, t3.STTP_CODE, t2.RULE_NAME, t2.RULE_TYPE, ")
.append("t2.RECORD_USER AS recordUser, t2.MODIFY_TIME, t2.DESCRIPTION, t2.IS_SHOW AS isShow, t2.RULE_CODE ")
.append("FROM MS_WARN_RULE_STBPRP_B t1\n")
.append("INNER JOIN MS_WARN_RULE_B t2 ON t1.RULE_ID = t2.ID\n")
.append("INNER JOIN V_MS_STBPRP_T t3 ON t1.STCD = t3.STCD\n")
.append("WHERE t2.RULE_CODE IN ('common','custom')\n")
.append(") WHERE 1=1");
Map<String, Object> params = new HashMap<>();
// 处理过滤条件
appendFilterConditions(request, sql, params);
// 处理排序
appendOrderBy(request, sql);
Page<MsWarnRuleBVo> page;
if (request.getPage() > 0 && request.getPageSize() > 0) {
page = new Page<>(request.getPage(), request.getPageSize());
} else if (request.getTake() > 0) {
long pageNum = (request.getSkip() / request.getTake()) + 1;
page = new Page<>(pageNum, request.getTake());
} else {
page = new Page<>(1, 20);
}
microservicDynamicSQLMapper.pageAllListWithResultType(page, sql.toString(), params, MsWarnRuleBVo.class);
return page;
}
@Override
public MsWarnRuleBVo getRuleBindDetail(String ruleId, String bindId) {
if (StringUtils.isBlank(ruleId) && StringUtils.isBlank(bindId)) {
return null;
}
MsWarnRuleBVo vo = new MsWarnRuleBVo();
vo.setId(ruleId);
MsWarnRuleStbprpB msStcdWarnRuleB = null;
if (StringUtils.isNotBlank(bindId)) {
msStcdWarnRuleB = msWarnRuleStbprpBMapper.selectById(bindId);
if (msStcdWarnRuleB == null) {
return null;
}
ruleId = msStcdWarnRuleB.getRuleId();
vo.setBindId(bindId);
vo.setId(ruleId);
}
MsWarnRuleB rule = this.baseMapper.selectById(ruleId);
if (rule == null) {
return null;
}
org.springframework.beans.BeanUtils.copyProperties(rule, vo);
if (msStcdWarnRuleB != null) {
vo.setStcd(msStcdWarnRuleB.getStcd());
vo.setSttpId(msStcdWarnRuleB.getSttpId());
}
if (StringUtils.isNotBlank(vo.getStcd())) {
String sql = "SELECT stcd, stnm, rstcd, ennm FROM MS_STBPRP_T WHERE STCD = '" + vo.getStcd() + "'";
List<MsWarnRuleBVo> voList = microservicDynamicSQLMapper.pageAllListWithResultType(null, sql, null, MsWarnRuleBVo.class);
if (!CollectionUtils.isEmpty(voList)) {
MsWarnRuleBVo stationVo = voList.get(0);
vo.setRstcd(stationVo.getRstcd());
vo.setEnnm(stationVo.getEnnm());
vo.setStnm(stationVo.getStnm());
}
}
// 查询规则配置的要素
LambdaQueryWrapper<MsWarnRuleDetailB> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(MsWarnRuleDetailB::getRuleId, ruleId);
List<MsWarnRuleDetailB> detailBList = msWarnRuleDetailBMapper.selectList(queryWrapper);
List<MsWarnRuleDetailVo> detailVos = new ArrayList<>();
if (!CollectionUtils.isEmpty(detailBList)) {
Map<Integer, List<MsWarnRuleDetailB>> warnLevelMap = detailBList.stream()
.collect(Collectors.groupingBy(d -> d.getWarnLevel() != null ? d.getWarnLevel() : 0));
for (Integer warnLevel : warnLevelMap.keySet()) {
MsWarnRuleDetailVo detailVo = new MsWarnRuleDetailVo();
List<MsWarnRuleDetailB> detailGroup = warnLevelMap.get(warnLevel);
List<WarnYsVo> ysVoList = new ArrayList<>();
MsWarnRuleDetailB first = detailGroup.get(0);
org.springframework.beans.BeanUtils.copyProperties(first, detailVo);
for (MsWarnRuleDetailB db : detailGroup) {
WarnYsVo ysVo = new WarnYsVo();
org.springframework.beans.BeanUtils.copyProperties(db, ysVo);
ysVoList.add(ysVo);
}
detailVo.setYsList(ysVoList);
detailVos.add(detailVo);
}
}
vo.setDetail(detailVos);
return vo;
}
@Override
public List<WarnRuleVo> getRuleListByStcd(String stcd, String ruleType, String lvl) {
List<WarnRuleVo> ruleList = this.baseMapper.getRuleListByStcd(stcd, ruleType);
if (CollectionUtils.isEmpty(ruleList)) {
return ruleList;
}
Set<String> ruleIdSet = ruleList.stream().map(WarnRuleVo::getId).collect(Collectors.toSet());
// 如果测站有绑定规则默认第一个
LambdaQueryWrapper<MsWarnRuleStbprpB> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(MsWarnRuleStbprpB::getStcd, stcd);
wrapper.in(MsWarnRuleStbprpB::getRuleId, ruleIdSet);
MsWarnRuleStbprpB binding = msWarnRuleStbprpBMapper.selectOne(wrapper);
if (binding != null) {
String boundRuleId = binding.getRuleId();
WarnRuleVo first = ruleList.stream()
.filter(r -> r.getId().equals(boundRuleId)).findFirst().orElse(null);
if (first != null) {
ruleList.remove(first);
ruleList.add(0, first);
}
return ruleList;
}
if ("WQ_RULE".equals(ruleType) && StringUtils.isNotBlank(lvl)) {
WarnRuleVo matched = ruleList.stream()
.filter(r -> "common".equals(r.getRuleCode()) && r.getLvl().equals(lvl))
.findFirst().orElse(null);
if (matched != null) {
ruleList.remove(matched);
ruleList.add(0, matched);
}
}
return ruleList;
}
// ==================== 私有辅助方法 ====================
/**
* 生成自定义规则名称站名-站类型名-自定义规则-序号
*/
private String getCustomRuleName(String stcd, String stnm) {
StringBuilder sb = new StringBuilder();
String sttpCodeName = this.baseMapper.getSttpCodeNameByStcd(stcd);
String customRuleName = this.baseMapper.getCustomRuleNameByStcd(stcd);
sb.append(stnm).append("-").append(sttpCodeName).append("-自定义规则-");
if (StringUtils.isBlank(customRuleName)) {
sb.append(1);
return sb.toString();
}
String num = customRuleName.substring(customRuleName.lastIndexOf("-") + 1);
if (!num.matches("-?\\d+")) {
throw new RuntimeException("自定义规则名称异常: " + customRuleName);
}
return sb.append(Integer.parseInt(num) + 1).toString();
}
/**
* 校验通用规则是否已存在
*/
private boolean checkRuleExist(String ruleType, Integer lvl) {
if ("WQ_RULE".equals(ruleType)) {
if (lvl == null) {
throw new RuntimeException("新增通用水质规则时水质等级不能为空");
}
return this.baseMapper.checkWqCommonRuleExist(lvl) > 0;
} else {
LambdaQueryWrapper<MsWarnRuleB> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(MsWarnRuleB::getRuleType, ruleType);
wrapper.eq(MsWarnRuleB::getRuleCode, "common");
wrapper.eq(MsWarnRuleB::getIsDeleted, 0);
return this.baseMapper.selectCount(wrapper) > 0;
}
}
/** /**
* 旧版规则类型枚举映射 * 旧版规则类型枚举映射
*/ */
@ -145,11 +527,9 @@ public class MsWarnRuleBServiceImpl extends ServiceImpl<MsWarnRuleBMapper, MsWar
if (filter == null) { if (filter == null) {
return null; return null;
} }
// 直接匹配
if (fieldName.equals(filter.getField()) && filter.getValue() != null) { if (fieldName.equals(filter.getField()) && filter.getValue() != null) {
return filter.getValue().toString(); return filter.getValue().toString();
} }
// 递归子过滤器
if (filter.getFilters() != null) { if (filter.getFilters() != null) {
for (DataSourceRequest.FilterDescriptor child : filter.getFilters()) { for (DataSourceRequest.FilterDescriptor child : filter.getFilters()) {
String value = findFilterValue(child, fieldName); String value = findFilterValue(child, fieldName);
@ -160,4 +540,88 @@ public class MsWarnRuleBServiceImpl extends ServiceImpl<MsWarnRuleBMapper, MsWar
} }
return null; return null;
} }
/**
* 处理 DataSourceRequest 的过滤条件拼接到 SQL
*/
private void appendFilterConditions(DataSourceRequest request, StringBuilder sql, Map<String, Object> params) {
if (request == null || request.getFilter() == null) {
return;
}
processFilters(request.getFilter(), sql, params);
}
private void processFilters(DataSourceRequest.FilterDescriptor filter, StringBuilder sql, Map<String, Object> params) {
if (filter == null) {
return;
}
if (filter.getFilters() != null && !filter.getFilters().isEmpty()) {
for (DataSourceRequest.FilterDescriptor child : filter.getFilters()) {
processFilter(child, sql, params);
}
}
}
private void processFilter(DataSourceRequest.FilterDescriptor filter, StringBuilder sql, Map<String, Object> params) {
if (filter == null || filter.getField() == null || filter.getValue() == null) {
return;
}
String field = filter.getField();
String operator = filter.getOperator();
Object value = filter.getValue();
switch (operator) {
case "eq":
sql.append(" AND ").append(field).append(" = '").append(value).append("'");
break;
case "neq":
sql.append(" AND ").append(field).append(" <> '").append(value).append("'");
break;
case "contains":
sql.append(" AND ").append(field).append(" LIKE '%").append(value).append("%'");
break;
case "startswith":
sql.append(" AND ").append(field).append(" LIKE '").append(value).append("%'");
break;
case "endswith":
sql.append(" AND ").append(field).append(" LIKE '%").append(value).append("'");
break;
case "gt":
sql.append(" AND ").append(field).append(" > '").append(value).append("'");
break;
case "gte":
sql.append(" AND ").append(field).append(" >= '").append(value).append("'");
break;
case "lt":
sql.append(" AND ").append(field).append(" < '").append(value).append("'");
break;
case "lte":
sql.append(" AND ").append(field).append(" <= '").append(value).append("'");
break;
default:
break;
}
}
/**
* 处理排序条件
*/
private void appendOrderBy(DataSourceRequest request, StringBuilder sql) {
if (request.getSort() == null || request.getSort().isEmpty()) {
return;
}
sql.append(" ORDER BY ");
for (int i = 0; i < request.getSort().size(); i++) {
DataSourceRequest.SortDescriptor sort = request.getSort().get(i);
sql.append(sort.getField());
if ("desc".equalsIgnoreCase(sort.getDir())) {
sql.append(" DESC");
} else {
sql.append(" ASC");
}
if (i < request.getSort().size() - 1) {
sql.append(", ");
}
}
}
} }

View File

@ -3,15 +3,13 @@ package com.yfd.platform.qgc_sys.warnRule.controller;
import com.yfd.platform.common.DataSourceRequest; import com.yfd.platform.common.DataSourceRequest;
import com.yfd.platform.config.ResponseResult; import com.yfd.platform.config.ResponseResult;
import com.yfd.platform.qgc_base.service.IMsWarnRuleBService; import com.yfd.platform.qgc_base.service.IMsWarnRuleBService;
import com.yfd.platform.qgc_sys.warnRule.vo.MsWarnRuleBVo;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/** /**
* 告警规则控制器 * 告警规则控制器
@ -42,6 +40,74 @@ public class MsWarnRuleBController {
return ResponseResult.successData(msWarnRuleBService.getAllYs(ruleType)); return ResponseResult.successData(msWarnRuleBService.getAllYs(ruleType));
} }
@PostMapping("/addOrUpdate")
@Operation(summary = "新增或修改规则")
public ResponseResult addOrUpdate(@RequestBody MsWarnRuleBVo vo) {
return ResponseResult.successData(msWarnRuleBService.addOrUpdate(vo));
}
@GetMapping("/check")
@Operation(summary = "校验规则是否被测站引用")
public ResponseResult check(@RequestParam("id") String id) {
return ResponseResult.successData(msWarnRuleBService.check(id));
}
@GetMapping("/bind/delete")
@Operation(summary = "删除规则绑定")
public ResponseResult deleteBind(@RequestParam("id") String id) {
if (id == null || id.isEmpty()) {
return ResponseResult.error("id不能为空");
}
msWarnRuleBService.deleteBind(id);
return ResponseResult.success();
}
@GetMapping("/delete")
@Operation(summary = "删除规则")
public ResponseResult deleteRule(@RequestParam("id") String id) {
if (id == null || id.isEmpty()) {
return ResponseResult.error("id不能为空");
}
msWarnRuleBService.deleteRule(id);
return ResponseResult.success();
}
@PostMapping("/updateShow")
@Operation(summary = "修改规则是否展示")
public ResponseResult updateShow(@RequestParam("isShow") Integer isShow) {
msWarnRuleBService.updateShow(isShow);
return ResponseResult.success();
}
@PostMapping("/limit")
@Operation(summary = "获取水位和生态流量限值")
public ResponseResult getLimit(@RequestBody DataSourceRequest dataSourceRequest) {
return ResponseResult.successData(msWarnRuleBService.getLimit(dataSourceRequest));
}
@PostMapping("/bind/GetKendoList")
@Operation(summary = "查询测站和预警规则绑定列表")
public ResponseResult getWarnRuleBindingList(@RequestBody DataSourceRequest dataSourceRequest) {
return ResponseResult.successData(msWarnRuleBService.getRuleBindList(dataSourceRequest));
}
@GetMapping("/getDetailById")
@Operation(summary = "根据id查询规则配置详情")
public ResponseResult getWarnRuleBindingDetail(
@RequestParam(value = "ruleId", required = false) String ruleId,
@RequestParam(value = "bindId", required = false) String bindId) {
return ResponseResult.successData(msWarnRuleBService.getRuleBindDetail(ruleId, bindId));
}
@GetMapping("/getRuleListByStcd")
@Operation(summary = "根据stcd查询可绑定的规则")
public ResponseResult getRuleListByStcd(
@RequestParam("stcd") String stcd,
@RequestParam("ruleType") String ruleType,
@RequestParam(value = "lvl", required = false) String lvl) {
return ResponseResult.successData(msWarnRuleBService.getRuleListByStcd(stcd, ruleType, lvl));
}
/** /**
* DataSourceRequest 过滤条件中提取指定字段的值 * DataSourceRequest 过滤条件中提取指定字段的值
*/ */

View File

@ -0,0 +1,69 @@
package com.yfd.platform.qgc_sys.warnRule.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.util.Date;
import java.util.List;
/**
* 预警规则配置VO
*/
@Data
public class MsWarnRuleBVo {
/** 告警规则id */
private String id;
/** 设施与规则绑定id */
private String bindId;
/** 告警规则名称 */
private String ruleName;
/** 告警规则类型 */
private String ruleType;
/** 告警规则类型名称 */
private String ruleTypeName;
/** 告警编码 */
private String ruleCode;
/** 测站编码 */
private String stcd;
/** 测站名称 */
private String stnm;
/** 关联测站编码 */
private String rstcd;
/** 工程名称 */
private String ennm;
/** 测站类型编码 */
private String sttpId;
/** 测站类型编码 */
private String sttpCode;
/** 是否展示告警等级 */
private Integer isShow;
/** 备注 */
private String description;
/** 告警规则详情数据 */
private List<MsWarnRuleDetailVo> detail;
/** 创建人 */
private String recordUser;
/** 创建人名称 */
private String recordUserName;
/** 更新时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date modifyTime;
}

View File

@ -0,0 +1,24 @@
package com.yfd.platform.qgc_sys.warnRule.vo;
import lombok.Data;
import java.util.List;
/**
* 预警规则详情VO
*/
@Data
public class MsWarnRuleDetailVo {
/** 水质等级 */
private String lvl;
/** 水质等级名称 */
private String lvlName;
/** 告警等级 */
private Integer warnLevel;
/** 要素列表 */
private List<WarnYsVo> ysList;
}

View File

@ -0,0 +1,18 @@
package com.yfd.platform.qgc_sys.warnRule.vo;
import lombok.Data;
/**
* 可绑定的规则VO
*/
@Data
public class WarnRuleVo {
private String id;
private String ruleName;
private String ruleCode;
private String lvl;
}

View File

@ -10,6 +10,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yfd.platform.common.DataSourceRequest; import com.yfd.platform.common.DataSourceRequest;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@ -240,17 +241,29 @@ public class DataSourceRequestUtil {
case "isempty" -> wrapper.eq(columnName, ""); case "isempty" -> wrapper.eq(columnName, "");
case "isnotempty" -> wrapper.ne(columnName, ""); case "isnotempty" -> wrapper.ne(columnName, "");
case "in" -> { case "in" -> {
if (value instanceof Iterable) { if (value instanceof Collection) {
wrapper.in(columnName, (Iterable<?>) value); if (!((Collection<?>) value).isEmpty()) {
wrapper.in(columnName, (Collection<?>) value);
}
} else if (value instanceof Object[]) { } else if (value instanceof Object[]) {
wrapper.in(columnName, (Object[]) value); if (((Object[]) value).length > 0) {
wrapper.in(columnName, (Object[]) value);
}
} else {
wrapper.eq(columnName, value); // 单个值转为 eq
} }
} }
case "ni", "notin" -> { case "ni", "notin" -> {
if (value instanceof Iterable) { if (value instanceof Collection) {
wrapper.notIn(columnName, (Iterable<?>) value); if (!((Collection<?>) value).isEmpty()) {
wrapper.notIn(columnName, (Collection<?>) value);
}
} else if (value instanceof Object[]) { } else if (value instanceof Object[]) {
wrapper.notIn(columnName, (Object[]) value); if (((Object[]) value).length > 0) {
wrapper.notIn(columnName, (Object[]) value);
}
} else {
wrapper.ne(columnName, value);
} }
} }
default -> wrapper.eq(columnName, value); default -> wrapper.eq(columnName, value);