From 832b36ac47182aa75fde0d14592fb6961e05346d Mon Sep 17 00:00:00 2001 From: haohao <1036606149@qq.com> Date: Sat, 17 Jan 2026 11:15:59 +0800 Subject: [PATCH] =?UTF-8?q?feat=EF=BC=9A=E3=80=90iot=E3=80=91=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E6=95=B0=E6=8D=AE=E6=B5=81=E8=BD=AC=E8=A7=84=E5=88=99?= =?UTF-8?q?=E5=92=8C=E7=9B=AE=E7=9A=84=E5=90=8D=E7=A7=B0=E5=94=AF=E4=B8=80?= =?UTF-8?q?=E6=80=A7=E6=A0=A1=E9=AA=8C=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../iot/dal/mysql/rule/IotDataRuleMapper.java | 4 +++ .../iot/dal/mysql/rule/IotDataSinkMapper.java | 4 +++ .../module/iot/enums/ErrorCodeConstants.java | 2 ++ .../rule/data/IotDataRuleServiceImpl.java | 28 +++++++++++++++++ .../rule/data/IotDataSinkServiceImpl.java | 30 +++++++++++++++++++ 5 files changed, 68 insertions(+) diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/rule/IotDataRuleMapper.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/rule/IotDataRuleMapper.java index 7c0c17d3bc..ce2eeb04bc 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/rule/IotDataRuleMapper.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/rule/IotDataRuleMapper.java @@ -35,4 +35,8 @@ public interface IotDataRuleMapper extends BaseMapperX { return selectList(IotDataRuleDO::getStatus, status); } + default IotDataRuleDO selectByName(String name) { + return selectOne(IotDataRuleDO::getName, name); + } + } \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/rule/IotDataSinkMapper.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/rule/IotDataSinkMapper.java index e65001db86..b13510ecc2 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/rule/IotDataSinkMapper.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/rule/IotDataSinkMapper.java @@ -29,4 +29,8 @@ public interface IotDataSinkMapper extends BaseMapperX { return selectList(IotDataSinkDO::getStatus, status); } + default IotDataSinkDO selectByName(String name) { + return selectOne(IotDataSinkDO::getName, name); + } + } \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/enums/ErrorCodeConstants.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/enums/ErrorCodeConstants.java index d1cf60e206..025d61390e 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/enums/ErrorCodeConstants.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/enums/ErrorCodeConstants.java @@ -65,10 +65,12 @@ public interface ErrorCodeConstants { // ========== IoT 数据流转规则 1-050-010-000 ========== ErrorCode DATA_RULE_NOT_EXISTS = new ErrorCode(1_050_010_000, "数据流转规则不存在"); + ErrorCode DATA_RULE_NAME_EXISTS = new ErrorCode(1_050_010_001, "数据流转规则名称已存在"); // ========== IoT 数据流转目的 1-050-011-000 ========== ErrorCode DATA_SINK_NOT_EXISTS = new ErrorCode(1_050_011_000, "数据桥梁不存在"); ErrorCode DATA_SINK_DELETE_FAIL_USED_BY_RULE = new ErrorCode(1_050_011_001, "数据流转目的正在被数据流转规则使用,无法删除"); + ErrorCode DATA_SINK_NAME_EXISTS = new ErrorCode(1_050_011_002, "数据流转目的名称已存在"); // ========== IoT 场景联动 1-050-012-000 ========== ErrorCode RULE_SCENE_NOT_EXISTS = new ErrorCode(1_050_012_000, "场景联动不存在"); diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/data/IotDataRuleServiceImpl.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/data/IotDataRuleServiceImpl.java index 8eafcb681a..8fc27f47df 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/data/IotDataRuleServiceImpl.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/data/IotDataRuleServiceImpl.java @@ -32,6 +32,7 @@ import java.util.*; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; +import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.DATA_RULE_NAME_EXISTS; import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.DATA_RULE_NOT_EXISTS; /** @@ -62,6 +63,8 @@ public class IotDataRuleServiceImpl implements IotDataRuleService { @Override @CacheEvict(value = RedisKeyConstants.DATA_RULE_LIST, allEntries = true) public Long createDataRule(IotDataRuleSaveReqVO createReqVO) { + // 校验名称唯一 + validateDataRuleNameUnique(null, createReqVO.getName()); // 校验数据源配置和数据目的 validateDataRuleConfig(createReqVO); // 新增 @@ -75,6 +78,8 @@ public class IotDataRuleServiceImpl implements IotDataRuleService { public void updateDataRule(IotDataRuleSaveReqVO updateReqVO) { // 校验存在 validateDataRuleExists(updateReqVO.getId()); + // 校验名称唯一 + validateDataRuleNameUnique(updateReqVO.getId(), updateReqVO.getName()); // 校验数据源配置和数据目的 validateDataRuleConfig(updateReqVO); @@ -98,6 +103,29 @@ public class IotDataRuleServiceImpl implements IotDataRuleService { } } + /** + * 校验数据流转规则名称唯一性 + * + * @param id 数据流转规则编号(用于更新时排除自身) + * @param name 数据流转规则名称 + */ + private void validateDataRuleNameUnique(Long id, String name) { + if (StrUtil.isBlank(name)) { + return; + } + IotDataRuleDO dataRule = dataRuleMapper.selectByName(name); + if (dataRule == null) { + return; + } + // 如果 id 为空,说明不用比较是否为相同 id 的规则 + if (id == null) { + throw exception(DATA_RULE_NAME_EXISTS); + } + if (!dataRule.getId().equals(id)) { + throw exception(DATA_RULE_NAME_EXISTS); + } + } + /** * 校验数据流转规则配置 * diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/data/IotDataSinkServiceImpl.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/data/IotDataSinkServiceImpl.java index 9977afba22..09e11c8226 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/data/IotDataSinkServiceImpl.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/data/IotDataSinkServiceImpl.java @@ -1,6 +1,7 @@ package cn.iocoder.yudao.module.iot.service.rule.data; import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.data.sink.IotDataSinkPageReqVO; @@ -19,6 +20,7 @@ import java.util.List; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.DATA_SINK_DELETE_FAIL_USED_BY_RULE; +import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.DATA_SINK_NAME_EXISTS; import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.DATA_SINK_NOT_EXISTS; /** @@ -39,6 +41,9 @@ public class IotDataSinkServiceImpl implements IotDataSinkService { @Override public Long createDataSink(IotDataSinkSaveReqVO createReqVO) { + // 校验名称唯一 + validateDataSinkNameUnique(null, createReqVO.getName()); + // 新增 IotDataSinkDO dataBridge = BeanUtils.toBean(createReqVO, IotDataSinkDO.class); dataSinkMapper.insert(dataBridge); return dataBridge.getId(); @@ -48,6 +53,8 @@ public class IotDataSinkServiceImpl implements IotDataSinkService { public void updateDataSink(IotDataSinkSaveReqVO updateReqVO) { // 校验存在 validateDataBridgeExists(updateReqVO.getId()); + // 校验名称唯一 + validateDataSinkNameUnique(updateReqVO.getId(), updateReqVO.getName()); // 更新 IotDataSinkDO updateObj = BeanUtils.toBean(updateReqVO, IotDataSinkDO.class); dataSinkMapper.updateById(updateObj); @@ -71,6 +78,29 @@ public class IotDataSinkServiceImpl implements IotDataSinkService { } } + /** + * 校验数据流转目的名称唯一性 + * + * @param id 数据流转目的编号(用于更新时排除自身) + * @param name 数据流转目的名称 + */ + private void validateDataSinkNameUnique(Long id, String name) { + if (StrUtil.isBlank(name)) { + return; + } + IotDataSinkDO dataSink = dataSinkMapper.selectByName(name); + if (dataSink == null) { + return; + } + // 如果 id 为空,说明不用比较是否为相同 id 的目的 + if (id == null) { + throw exception(DATA_SINK_NAME_EXISTS); + } + if (!dataSink.getId().equals(id)) { + throw exception(DATA_SINK_NAME_EXISTS); + } + } + @Override public IotDataSinkDO getDataSink(Long id) { return dataSinkMapper.selectById(id);