diff --git a/backend/src/main/java/com/yfd/platform/qgc_base/domain/MsWarnRuleDetailB.java b/backend/src/main/java/com/yfd/platform/qgc_base/domain/MsWarnRuleDetailB.java new file mode 100644 index 00000000..d6c21da9 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_base/domain/MsWarnRuleDetailB.java @@ -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; +} diff --git a/backend/src/main/java/com/yfd/platform/qgc_base/domain/MsWarnRuleStbprpB.java b/backend/src/main/java/com/yfd/platform/qgc_base/domain/MsWarnRuleStbprpB.java new file mode 100644 index 00000000..4e9cf950 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_base/domain/MsWarnRuleStbprpB.java @@ -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; +} diff --git a/backend/src/main/java/com/yfd/platform/qgc_base/mapper/MsWarnRuleBMapper.java b/backend/src/main/java/com/yfd/platform/qgc_base/mapper/MsWarnRuleBMapper.java index 65897007..242f0f4d 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_base/mapper/MsWarnRuleBMapper.java +++ b/backend/src/main/java/com/yfd/platform/qgc_base/mapper/MsWarnRuleBMapper.java @@ -2,6 +2,41 @@ package com.yfd.platform.qgc_base.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; 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 { + + @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 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); } diff --git a/backend/src/main/java/com/yfd/platform/qgc_base/mapper/MsWarnRuleDetailBMapper.java b/backend/src/main/java/com/yfd/platform/qgc_base/mapper/MsWarnRuleDetailBMapper.java new file mode 100644 index 00000000..ee1916fb --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_base/mapper/MsWarnRuleDetailBMapper.java @@ -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 { +} diff --git a/backend/src/main/java/com/yfd/platform/qgc_base/mapper/MsWarnRuleStbprpBMapper.java b/backend/src/main/java/com/yfd/platform/qgc_base/mapper/MsWarnRuleStbprpBMapper.java new file mode 100644 index 00000000..92ea093c --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_base/mapper/MsWarnRuleStbprpBMapper.java @@ -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 { + + @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); +} diff --git a/backend/src/main/java/com/yfd/platform/qgc_base/service/IMsWarnRuleBService.java b/backend/src/main/java/com/yfd/platform/qgc_base/service/IMsWarnRuleBService.java index 68cba268..21396e56 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_base/service/IMsWarnRuleBService.java +++ b/backend/src/main/java/com/yfd/platform/qgc_base/service/IMsWarnRuleBService.java @@ -4,9 +4,12 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.IService; import com.yfd.platform.common.DataSourceRequest; 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 java.util.List; +import java.util.Map; /** * 预警规则配置 Service 接口 @@ -21,4 +24,49 @@ public interface IMsWarnRuleBService extends IService { * 获取告警类型对应的要素列表 */ List getAllYs(String ruleType); + + /** + * 新增或修改预警规则 + */ + MsWarnRuleB addOrUpdate(MsWarnRuleBVo vo); + + /** + * 校验规则是否被测站引用 + */ + boolean check(String id); + + /** + * 删除规则绑定 + */ + void deleteBind(String id); + + /** + * 删除规则(物理删除详情和绑定,逻辑删除主表) + */ + void deleteRule(String id); + + /** + * 修改规则是否展示 + */ + void updateShow(Integer isShow); + + /** + * 获取水位和生态流量限值 + */ + Map getLimit(DataSourceRequest request); + + /** + * 查询测站和预警规则绑定列表 + */ + Page getRuleBindList(DataSourceRequest request); + + /** + * 根据id查询规则配置详情 + */ + MsWarnRuleBVo getRuleBindDetail(String ruleId, String bindId); + + /** + * 根据stcd查询可绑定的规则 + */ + List getRuleListByStcd(String stcd, String ruleType, String lvl); } diff --git a/backend/src/main/java/com/yfd/platform/qgc_base/service/impl/MsWarnRuleBServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_base/service/impl/MsWarnRuleBServiceImpl.java index 037f0ef9..800651e4 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_base/service/impl/MsWarnRuleBServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_base/service/impl/MsWarnRuleBServiceImpl.java @@ -1,28 +1,38 @@ 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.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.yfd.platform.common.DataSourceRequest; import com.yfd.platform.common.MicroservicDynamicSQLMapper; 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.MsWarnRuleDetailBMapper; +import com.yfd.platform.qgc_base.mapper.MsWarnRuleStbprpBMapper; import com.yfd.platform.qgc_base.service.IMsOperationLogService; 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.utils.DataSourceRequestUtil; import com.yfd.platform.utils.DictCodeToNameConverter; import com.yfd.platform.utils.CodeToNameMetadataBo; import com.yfd.platform.utils.SecurityUtils; import jakarta.annotation.Resource; +import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Collectors; /** * 预警规则配置 Service 实现类 @@ -52,6 +62,12 @@ public class MsWarnRuleBServiceImpl extends ServiceImpl queryPageList(DataSourceRequest request) { Page page = DataSourceRequestUtil.executeQuery(request, MsWarnRuleB.class, this); @@ -64,7 +80,7 @@ public class MsWarnRuleBServiceImpl extends ServiceImpl 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 detailBList = new ArrayList<>(); + AtomicInteger i = new AtomicInteger(); + if (detail != null) { + for (MsWarnRuleDetailVo detailVo : detail) { + List 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 ysSet = detailVo.getYsList().stream().map(WarnYsVo::getYs).collect(Collectors.toSet()); + if (!CollectionUtils.isEmpty(ysSet)) { + LambdaQueryWrapper 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 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 detailWrapper = new LambdaQueryWrapper<>(); + detailWrapper.eq(MsWarnRuleDetailB::getRuleId, id); + msWarnRuleDetailBMapper.delete(detailWrapper); + + // 删除规则绑定 + LambdaQueryWrapper bindWrapper = new LambdaQueryWrapper<>(); + bindWrapper.eq(MsWarnRuleStbprpB::getRuleId, id); + msWarnRuleStbprpBMapper.delete(bindWrapper); + + // 逻辑删除规则主表 + MsWarnRuleB entity = this.getById(id); + LambdaUpdateWrapper 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 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> allList = microservicDynamicSQLMapper.getAllList(sql, null); + return CollectionUtils.isEmpty(allList) ? new HashMap<>() : allList.get(0); + } + + @Override + public Page 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 params = new HashMap<>(); + // 处理过滤条件 + appendFilterConditions(request, sql, params); + + // 处理排序 + appendOrderBy(request, sql); + + Page 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 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 queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(MsWarnRuleDetailB::getRuleId, ruleId); + List detailBList = msWarnRuleDetailBMapper.selectList(queryWrapper); + + List detailVos = new ArrayList<>(); + if (!CollectionUtils.isEmpty(detailBList)) { + Map> warnLevelMap = detailBList.stream() + .collect(Collectors.groupingBy(d -> d.getWarnLevel() != null ? d.getWarnLevel() : 0)); + for (Integer warnLevel : warnLevelMap.keySet()) { + MsWarnRuleDetailVo detailVo = new MsWarnRuleDetailVo(); + List detailGroup = warnLevelMap.get(warnLevel); + List 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 getRuleListByStcd(String stcd, String ruleType, String lvl) { + List ruleList = this.baseMapper.getRuleListByStcd(stcd, ruleType); + if (CollectionUtils.isEmpty(ruleList)) { + return ruleList; + } + Set ruleIdSet = ruleList.stream().map(WarnRuleVo::getId).collect(Collectors.toSet()); + + // 如果测站有绑定规则,默认第一个 + LambdaQueryWrapper 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 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 params) { + if (request == null || request.getFilter() == null) { + return; + } + processFilters(request.getFilter(), sql, params); + } + + private void processFilters(DataSourceRequest.FilterDescriptor filter, StringBuilder sql, Map 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 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(", "); + } + } + } } diff --git a/backend/src/main/java/com/yfd/platform/qgc_sys/warnRule/controller/MsWarnRuleBController.java b/backend/src/main/java/com/yfd/platform/qgc_sys/warnRule/controller/MsWarnRuleBController.java index c1c516c7..40ac8a3c 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_sys/warnRule/controller/MsWarnRuleBController.java +++ b/backend/src/main/java/com/yfd/platform/qgc_sys/warnRule/controller/MsWarnRuleBController.java @@ -3,15 +3,13 @@ package com.yfd.platform.qgc_sys.warnRule.controller; import com.yfd.platform.common.DataSourceRequest; import com.yfd.platform.config.ResponseResult; 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.tags.Tag; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; /** * 告警规则控制器 @@ -42,6 +40,74 @@ public class MsWarnRuleBController { 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 过滤条件中提取指定字段的值 */ diff --git a/backend/src/main/java/com/yfd/platform/qgc_sys/warnRule/vo/MsWarnRuleBVo.java b/backend/src/main/java/com/yfd/platform/qgc_sys/warnRule/vo/MsWarnRuleBVo.java new file mode 100644 index 00000000..428d37f0 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_sys/warnRule/vo/MsWarnRuleBVo.java @@ -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 detail; + + /** 创建人 */ + private String recordUser; + + /** 创建人名称 */ + private String recordUserName; + + /** 更新时间 */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + private Date modifyTime; +} diff --git a/backend/src/main/java/com/yfd/platform/qgc_sys/warnRule/vo/MsWarnRuleDetailVo.java b/backend/src/main/java/com/yfd/platform/qgc_sys/warnRule/vo/MsWarnRuleDetailVo.java new file mode 100644 index 00000000..8b35343d --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_sys/warnRule/vo/MsWarnRuleDetailVo.java @@ -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 ysList; +} diff --git a/backend/src/main/java/com/yfd/platform/qgc_sys/warnRule/vo/WarnRuleVo.java b/backend/src/main/java/com/yfd/platform/qgc_sys/warnRule/vo/WarnRuleVo.java new file mode 100644 index 00000000..5da79a5d --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_sys/warnRule/vo/WarnRuleVo.java @@ -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; +} diff --git a/backend/src/main/java/com/yfd/platform/utils/DataSourceRequestUtil.java b/backend/src/main/java/com/yfd/platform/utils/DataSourceRequestUtil.java index a9a101ee..25b78886 100644 --- a/backend/src/main/java/com/yfd/platform/utils/DataSourceRequestUtil.java +++ b/backend/src/main/java/com/yfd/platform/utils/DataSourceRequestUtil.java @@ -10,6 +10,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.yfd.platform.common.DataSourceRequest; import java.util.ArrayList; +import java.util.Collection; import java.util.List; import java.util.Map; import java.util.regex.Pattern; @@ -240,17 +241,29 @@ public class DataSourceRequestUtil { case "isempty" -> wrapper.eq(columnName, ""); case "isnotempty" -> wrapper.ne(columnName, ""); case "in" -> { - if (value instanceof Iterable) { - wrapper.in(columnName, (Iterable) value); + if (value instanceof Collection) { + if (!((Collection) value).isEmpty()) { + wrapper.in(columnName, (Collection) value); + } } 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" -> { - if (value instanceof Iterable) { - wrapper.notIn(columnName, (Iterable) value); + if (value instanceof Collection) { + if (!((Collection) value).isEmpty()) { + wrapper.notIn(columnName, (Collection) value); + } } 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);