From fabb2d8abc94e2a4897931d337698afbfead9ba6 Mon Sep 17 00:00:00 2001 From: lxj <15683799673@163.com> Date: Thu, 19 Jun 2025 18:19:58 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E8=A1=8C=E6=94=BF?= =?UTF-8?q?=E5=8C=BA=E5=88=92=E6=A0=91=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/core/domain/TreeEntity.java | 15 ++ .../dromara/common/core/utils/TreeUtils.java | 46 +++++ .../controller/TbAccessControlController.java | 2 +- .../iot/controller/TdFactoryController.java | 2 +- .../controller/TdMeterConfigController.java | 2 +- .../iot/controller/TdMeterController.java | 71 +++++--- .../iot/controller/TdMeterRoomController.java | 4 +- .../java/org/dromara/iot/domain/TdMeter.java | 38 ++++- .../org/dromara/iot/domain/bo/TdMeterBo.java | 50 +++--- .../org/dromara/iot/domain/vo/TdMeterVo.java | 28 ++- .../org/dromara/iot/mapper/TdMeterMapper.java | 2 +- .../iot/service/ITdMeterRoomService.java | 17 ++ .../dromara/iot/service/ITdMeterService.java | 18 +- .../service/impl/TdMeterRoomServiceImpl.java | 30 +++- .../iot/service/impl/TdMeterServiceImpl.java | 76 +++++++-- .../mapper/TbAccessControlMapper.xml | 2 +- .../main/resources/mapper/TdFactoryMapper.xml | 2 +- .../resources/mapper/TdMeterConfigMapper.xml | 2 +- .../main/resources/mapper/TdMeterMapper.xml | 2 +- .../resources/mapper/TdMeterRoomMapper.xml | 2 +- ...roller.java => SysCityAreaController.java} | 86 ++++++---- .../{TbCityArea.java => SysCityArea.java} | 16 +- .../{TbCityAreaBo.java => SysCityAreaBo.java} | 15 +- .../domain/convert/SysCityAreaCovert.java | 24 +++ .../property/domain/vo/CityAreaTreeVo.java | 62 +++++++ .../{TbCityAreaVo.java => SysCityAreaVo.java} | 11 +- .../property/mapper/SysCityAreaMapper.java | 16 ++ .../property/mapper/TbCityAreaMapper.java | 16 -- ...aService.java => ISysCityAreaService.java} | 27 +-- .../service/impl/SysCityAreaServiceImpl.java | 161 ++++++++++++++++++ .../service/impl/TbCityAreaServiceImpl.java | 151 ---------------- ...tyAreaMapper.xml => SysCityAreaMapper.xml} | 2 +- 32 files changed, 666 insertions(+), 332 deletions(-) create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/TreeEntity.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/TreeUtils.java rename ruoyi-modules/Property/src/main/java/org/dromara/property/controller/{TbCityAreaController.java => SysCityAreaController.java} (55%) rename ruoyi-modules/Property/src/main/java/org/dromara/property/domain/{TbCityArea.java => SysCityArea.java} (74%) rename ruoyi-modules/Property/src/main/java/org/dromara/property/domain/bo/{TbCityAreaBo.java => SysCityAreaBo.java} (88%) create mode 100644 ruoyi-modules/Property/src/main/java/org/dromara/property/domain/convert/SysCityAreaCovert.java create mode 100644 ruoyi-modules/Property/src/main/java/org/dromara/property/domain/vo/CityAreaTreeVo.java rename ruoyi-modules/Property/src/main/java/org/dromara/property/domain/vo/{TbCityAreaVo.java => SysCityAreaVo.java} (91%) create mode 100644 ruoyi-modules/Property/src/main/java/org/dromara/property/mapper/SysCityAreaMapper.java delete mode 100644 ruoyi-modules/Property/src/main/java/org/dromara/property/mapper/TbCityAreaMapper.java rename ruoyi-modules/Property/src/main/java/org/dromara/property/service/{ITbCityAreaService.java => ISysCityAreaService.java} (66%) create mode 100644 ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/SysCityAreaServiceImpl.java delete mode 100644 ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/TbCityAreaServiceImpl.java rename ruoyi-modules/Property/src/main/resources/mapper/Property/{TbCityAreaMapper.xml => SysCityAreaMapper.xml} (70%) diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/TreeEntity.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/TreeEntity.java new file mode 100644 index 00000000..92653b4c --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/TreeEntity.java @@ -0,0 +1,15 @@ +package org.dromara.common.core.domain; + +import java.util.List; + +/** + * 通用tree构建工具类 + * @param + */ +public interface TreeEntity { + public T getId(); + + public T getParentId(); + + public void setChildren(List children); +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/TreeUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/TreeUtils.java new file mode 100644 index 00000000..1a97516a --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/TreeUtils.java @@ -0,0 +1,46 @@ +package org.dromara.common.core.utils; + +import cn.hutool.core.collection.CollectionUtil; +import org.dromara.common.core.domain.TreeEntity; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + + +/** + * *解析树形数据工具类 + */ +public class TreeUtils { + + /** + * 将列表数据构建成树结构 + * + * @param entityList 列表数据 + * @param rootCode 根节点编码 + * @return 构建树状 + */ + public static List getTreeList(List entityList, Object rootCode) { + if (CollectionUtil.isEmpty(entityList)) { + return new ArrayList<>(); + } + //第一次循环 数据分组 + Map> groupData = new HashMap<>(); + for (T entity : entityList) { + groupData.computeIfAbsent(entity.getParentId(), (k) -> new ArrayList()).add(entity); + } + // 第二次循环 生成树结构 + for (TreeEntity entity : entityList) { + List children = groupData.get(entity.getId()); + if (children != null) { + entity.setChildren(children); + } else { + entity.setChildren(new ArrayList<>()); + } + } + return groupData.get(rootCode); + } +} + + diff --git a/ruoyi-modules/Iot/src/main/java/org/dromara/iot/controller/TbAccessControlController.java b/ruoyi-modules/Iot/src/main/java/org/dromara/iot/controller/TbAccessControlController.java index 613a4a8a..5eaaf6f7 100644 --- a/ruoyi-modules/Iot/src/main/java/org/dromara/iot/controller/TbAccessControlController.java +++ b/ruoyi-modules/Iot/src/main/java/org/dromara/iot/controller/TbAccessControlController.java @@ -25,7 +25,7 @@ import java.util.List; /** * 门禁管理 - * 前端访问路由地址为:/property/accessControl + * 前端访问路由地址为:/iot/accessControl * * @author lxj * @date 2025-06-17 diff --git a/ruoyi-modules/Iot/src/main/java/org/dromara/iot/controller/TdFactoryController.java b/ruoyi-modules/Iot/src/main/java/org/dromara/iot/controller/TdFactoryController.java index e5bfaea8..3afbf831 100644 --- a/ruoyi-modules/Iot/src/main/java/org/dromara/iot/controller/TdFactoryController.java +++ b/ruoyi-modules/Iot/src/main/java/org/dromara/iot/controller/TdFactoryController.java @@ -24,7 +24,7 @@ import org.dromara.common.mybatis.core.page.TableDataInfo; /** * 厂商管理 - * 前端访问路由地址为:/property/factory + * 前端访问路由地址为:/iot/factory * * @author lxj * @date 2025-06-17 diff --git a/ruoyi-modules/Iot/src/main/java/org/dromara/iot/controller/TdMeterConfigController.java b/ruoyi-modules/Iot/src/main/java/org/dromara/iot/controller/TdMeterConfigController.java index 68750545..d4299ea8 100644 --- a/ruoyi-modules/Iot/src/main/java/org/dromara/iot/controller/TdMeterConfigController.java +++ b/ruoyi-modules/Iot/src/main/java/org/dromara/iot/controller/TdMeterConfigController.java @@ -24,7 +24,7 @@ import org.dromara.common.mybatis.core.page.TableDataInfo; /** * 水电气配置 - * 前端访问路由地址为:/system/meterConfig + * 前端访问路由地址为:/iot/meterConfig * * @author lxj * @date 2025-06-18 diff --git a/ruoyi-modules/Iot/src/main/java/org/dromara/iot/controller/TdMeterController.java b/ruoyi-modules/Iot/src/main/java/org/dromara/iot/controller/TdMeterController.java index 81834bb9..3b5cec27 100644 --- a/ruoyi-modules/Iot/src/main/java/org/dromara/iot/controller/TdMeterController.java +++ b/ruoyi-modules/Iot/src/main/java/org/dromara/iot/controller/TdMeterController.java @@ -1,38 +1,39 @@ package org.dromara.iot.controller; -import java.util.List; - -import lombok.RequiredArgsConstructor; -import jakarta.servlet.http.HttpServletResponse; -import jakarta.validation.constraints.*; import cn.dev33.satoken.annotation.SaCheckPermission; -import org.springframework.web.bind.annotation.*; -import org.springframework.validation.annotation.Validated; -import org.dromara.common.idempotent.annotation.RepeatSubmit; -import org.dromara.common.log.annotation.Log; -import org.dromara.common.web.core.BaseController; -import org.dromara.common.mybatis.core.page.PageQuery; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; +import lombok.RequiredArgsConstructor; import org.dromara.common.core.domain.R; import org.dromara.common.core.validate.AddGroup; import org.dromara.common.core.validate.EditGroup; -import org.dromara.common.log.enums.BusinessType; import org.dromara.common.excel.utils.ExcelUtil; -import org.dromara.iot.domain.vo.TdMeterVo; -import org.dromara.iot.domain.bo.TdMeterBo; -import org.dromara.iot.service.ITdMeterService; +import org.dromara.common.idempotent.annotation.RepeatSubmit; +import org.dromara.common.log.annotation.Log; +import org.dromara.common.log.enums.BusinessType; +import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.common.web.core.BaseController; +import org.dromara.iot.domain.bo.TdMeterBo; +import org.dromara.iot.domain.vo.TdMeterVo; +import org.dromara.iot.service.ITdMeterService; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.util.List; /** * 水电气 - * 前端访问路由地址为:/system/ meter + * 前端访问路由地址为:/iot/meter * * @author LionLi - * @date 2025-06-18 + * @date 2025-06-19 */ @Validated @RequiredArgsConstructor @RestController -@RequestMapping("/ meter") +@RequestMapping("/meter") public class TdMeterController extends BaseController { private final ITdMeterService tdMeterService; @@ -40,17 +41,31 @@ public class TdMeterController extends BaseController { /** * 查询水电气列表 */ - @SaCheckPermission("system: meter:list") + @SaCheckPermission("iot:meter:list") @GetMapping("/list") public TableDataInfo list(TdMeterBo bo, PageQuery pageQuery) { return tdMeterService.queryPageList(bo, pageQuery); } + /** + * 打开或关闭表 + * + * @param meterId 智能表id + * @param onOff 0: 打开,2:关闭 + * @return 是否操作成功 + */ + @SaCheckPermission("iot:meter:operate") + @Log(title = "开/关智能表", businessType = BusinessType.OTHER) + @GetMapping("/operate/{meterId}/{onOff}") + public R operate(@PathVariable("meterId") Long meterId, @PathVariable("onOff") Integer onOff) { + return R.ok(tdMeterService.operate(meterId, onOff)); + } + /** * 导出水电气列表 */ - @SaCheckPermission("system: meter:export") - @Log(title = "水电气", businessType = BusinessType.EXPORT) + @SaCheckPermission("iot:meter:export") + @Log(title = "导出智能表信息", businessType = BusinessType.EXPORT) @PostMapping("/export") public void export(TdMeterBo bo, HttpServletResponse response) { List list = tdMeterService.queryList(bo); @@ -62,7 +77,7 @@ public class TdMeterController extends BaseController { * * @param id 主键 */ - @SaCheckPermission("system: meter:query") + @SaCheckPermission("iot:meter:query") @GetMapping("/{id}") public R getInfo(@NotNull(message = "主键不能为空") @PathVariable("id") Long id) { @@ -72,8 +87,8 @@ public class TdMeterController extends BaseController { /** * 新增水电气 */ - @SaCheckPermission("system: meter:add") - @Log(title = "水电气", businessType = BusinessType.INSERT) + @SaCheckPermission("iot:meter:add") + @Log(title = "添加智能表信息", businessType = BusinessType.INSERT) @RepeatSubmit() @PostMapping() public R add(@Validated(AddGroup.class) @RequestBody TdMeterBo bo) { @@ -83,8 +98,8 @@ public class TdMeterController extends BaseController { /** * 修改水电气 */ - @SaCheckPermission("system: meter:edit") - @Log(title = "水电气", businessType = BusinessType.UPDATE) + @SaCheckPermission("iot:meter:edit") + @Log(title = "修改智能表信息", businessType = BusinessType.UPDATE) @RepeatSubmit() @PutMapping() public R edit(@Validated(EditGroup.class) @RequestBody TdMeterBo bo) { @@ -96,8 +111,8 @@ public class TdMeterController extends BaseController { * * @param ids 主键串 */ - @SaCheckPermission("system: meter:remove") - @Log(title = "水电气", businessType = BusinessType.DELETE) + @SaCheckPermission("iot:meter:remove") + @Log(title = "删除智能表信息", businessType = BusinessType.DELETE) @DeleteMapping("/{ids}") public R remove(@NotEmpty(message = "主键不能为空") @PathVariable("ids") Long[] ids) { diff --git a/ruoyi-modules/Iot/src/main/java/org/dromara/iot/controller/TdMeterRoomController.java b/ruoyi-modules/Iot/src/main/java/org/dromara/iot/controller/TdMeterRoomController.java index f5bf6f60..d26bfecb 100644 --- a/ruoyi-modules/Iot/src/main/java/org/dromara/iot/controller/TdMeterRoomController.java +++ b/ruoyi-modules/Iot/src/main/java/org/dromara/iot/controller/TdMeterRoomController.java @@ -1,4 +1,4 @@ -package org.dromara.system.controller; +package org.dromara.iot.controller; import java.util.List; @@ -24,7 +24,7 @@ import org.dromara.common.mybatis.core.page.TableDataInfo; /** * 和房间的关联 - * 前端访问路由地址为:/system/meterRoom + * 前端访问路由地址为:/iot/meterRoom * * @author lxj * @date 2025-06-18 diff --git a/ruoyi-modules/Iot/src/main/java/org/dromara/iot/domain/TdMeter.java b/ruoyi-modules/Iot/src/main/java/org/dromara/iot/domain/TdMeter.java index ef3fbfb7..f04301ab 100644 --- a/ruoyi-modules/Iot/src/main/java/org/dromara/iot/domain/TdMeter.java +++ b/ruoyi-modules/Iot/src/main/java/org/dromara/iot/domain/TdMeter.java @@ -1,21 +1,22 @@ package org.dromara.iot.domain; -import org.dromara.common.mybatis.core.domain.BaseEntity; -import com.baomidou.mybatisplus.annotation.*; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; import lombok.EqualsAndHashCode; +import org.dromara.common.mybatis.core.domain.BaseEntity; import java.io.Serial; /** - * 水电气对象 td_ meter + * 水电气对象 td_meter * * @author LionLi - * @date 2025-06-18 + * @date 2025-06-19 */ @Data @EqualsAndHashCode(callSuper = true) -@TableName("td_ meter") +@TableName("td_meter") public class TdMeter extends BaseEntity { @Serial @@ -47,6 +48,21 @@ public class TdMeter extends BaseEntity { */ private Long meterType; + /** + * 表用途(1-分表,2-总表,3-公摊表) + */ + private Long meterPurpose; + + /** + * 分摊类型 + * 1-不公摊 + * 2-按分表用量 + * 3-按租客面积 + * 4-按房源数量 + * 5-按固定比例 + */ + private Long shareType; + /** * 付费类型(1-先付费,2-后付费) */ @@ -58,7 +74,17 @@ public class TdMeter extends BaseEntity { private Long display; /** - * + * 最大表显读数(超过归0) + */ + private Long maxDisplay; + + /** + * 计费倍率 + */ + private Float billingRate; + + /** + * 剩余量 */ private Long surplus; diff --git a/ruoyi-modules/Iot/src/main/java/org/dromara/iot/domain/bo/TdMeterBo.java b/ruoyi-modules/Iot/src/main/java/org/dromara/iot/domain/bo/TdMeterBo.java index e2c22cdd..f4c69a2f 100644 --- a/ruoyi-modules/Iot/src/main/java/org/dromara/iot/domain/bo/TdMeterBo.java +++ b/ruoyi-modules/Iot/src/main/java/org/dromara/iot/domain/bo/TdMeterBo.java @@ -10,11 +10,13 @@ import org.dromara.common.core.validate.EditGroup; import org.dromara.common.mybatis.core.domain.BaseEntity; import org.dromara.iot.domain.TdMeter; +import java.util.List; + /** - * 水电气业务对象 td_ meter + * 水电气业务对象 td_meter * - * @author lxj - * @date 2025-06-18 + * @author LionLi + * @date 2025-06-19 */ @Data @EqualsAndHashCode(callSuper = true) @@ -36,7 +38,6 @@ public class TdMeterBo extends BaseEntity { /** * 设备编码 */ - @NotBlank(message = "设备编码不能为空", groups = {AddGroup.class, EditGroup.class}) private String meterCode; /** @@ -48,34 +49,37 @@ public class TdMeterBo extends BaseEntity { /** * 设备类型(1-电表,2-水表,3-气表) */ - @NotNull(message = "设备类型(1-电表,2-水表,3-气表)不能为空", groups = {AddGroup.class, EditGroup.class}) private Long meterType; + /** + * 表用途(1-分表,2-总表,3-公摊表) + */ + private Long meterPurpose; + + /** + * 分摊类型 + * 1-不公摊 + * 2-按分表用量 + * 3-按租客面积 + * 4-按房源数量 + * 5-按固定比例 + */ + private Long shareType; + /** * 付费类型(1-先付费,2-后付费) */ - @NotNull(message = "付费类型(1-先付费,2-后付费)不能为空", groups = {AddGroup.class, EditGroup.class}) private Long payType; /** - * 当前表显示读数 + * 最大表显读数(超过归0) */ - private Long display; + private Long maxDisplay; /** - * + * 计费倍率 */ - private Long surplus; - - /** - * 通信状态 - */ - private Long communicationState; - - /** - * 运行状态 - */ - private Long runningState; + private Float billingRate; /** * 备注 @@ -83,4 +87,10 @@ public class TdMeterBo extends BaseEntity { private String remark; + /** + * 设备厂商 + */ + @NotBlank(message = "表绑定的房间不能为空", groups = {AddGroup.class}) + private List roomIds; + } diff --git a/ruoyi-modules/Iot/src/main/java/org/dromara/iot/domain/vo/TdMeterVo.java b/ruoyi-modules/Iot/src/main/java/org/dromara/iot/domain/vo/TdMeterVo.java index 52cfd406..6a5326d5 100644 --- a/ruoyi-modules/Iot/src/main/java/org/dromara/iot/domain/vo/TdMeterVo.java +++ b/ruoyi-modules/Iot/src/main/java/org/dromara/iot/domain/vo/TdMeterVo.java @@ -10,11 +10,12 @@ import java.io.Serial; import java.io.Serializable; + /** - * 水电气视图对象 td_ meter + * 水电气视图对象 td_meter * - * @author lxj - * @date 2025-06-18 + * @author LionLi + * @date 2025-06-19 */ @Data @ExcelIgnoreUnannotated @@ -54,6 +55,23 @@ public class TdMeterVo implements Serializable { @ExcelProperty(value = "设备类型(1-电表,2-水表,3-气表)") private Long meterType; + /** + * 表用途(1-分表,2-总表,3-公摊表) + */ + @ExcelProperty(value = "表用途(1-分表,2-总表,3-公摊表)") + private Long meterPurpose; + + /** + * 分摊类型 + * 1-不公摊 + * 2-按分表用量 + * 3-按租客面积 + * 4-按房源数量 + * 5-按固定比例 + */ + @ExcelProperty(value = "分摊类型 1-不公摊 2-按分表用量 3-按租客面积 4-按房源数量 5-按固定比例") + private Long shareType; + /** * 付费类型(1-先付费,2-后付费) */ @@ -67,9 +85,9 @@ public class TdMeterVo implements Serializable { private Long display; /** - * + * 剩余量 */ - @ExcelProperty(value = "") + @ExcelProperty(value = "剩余量") private Long surplus; /** diff --git a/ruoyi-modules/Iot/src/main/java/org/dromara/iot/mapper/TdMeterMapper.java b/ruoyi-modules/Iot/src/main/java/org/dromara/iot/mapper/TdMeterMapper.java index 4b0ed255..b1018c00 100644 --- a/ruoyi-modules/Iot/src/main/java/org/dromara/iot/mapper/TdMeterMapper.java +++ b/ruoyi-modules/Iot/src/main/java/org/dromara/iot/mapper/TdMeterMapper.java @@ -8,7 +8,7 @@ import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; * 水电气Mapper接口 * * @author LionLi - * @date 2025-06-18 + * @date 2025-06-19 */ public interface TdMeterMapper extends BaseMapperPlus { diff --git a/ruoyi-modules/Iot/src/main/java/org/dromara/iot/service/ITdMeterRoomService.java b/ruoyi-modules/Iot/src/main/java/org/dromara/iot/service/ITdMeterRoomService.java index 57a3c3c1..97d2d1f1 100644 --- a/ruoyi-modules/Iot/src/main/java/org/dromara/iot/service/ITdMeterRoomService.java +++ b/ruoyi-modules/Iot/src/main/java/org/dromara/iot/service/ITdMeterRoomService.java @@ -2,6 +2,7 @@ package org.dromara.iot.service; import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.iot.domain.TdMeterRoom; import org.dromara.iot.domain.bo.TdMeterRoomBo; import org.dromara.iot.domain.vo.TdMeterRoomVo; @@ -65,4 +66,20 @@ public interface ITdMeterRoomService { * @return 是否删除成功 */ Boolean deleteWithValidByIds(Collection ids, Boolean isValid); + + /** + * 批量写入表和房间的关联关系 + * + * @param rels 写入数据 + * @return 是否写入成功 + */ + Boolean insertBatch(List rels); + + /** + * 根据表id删除关联数据 + * @param meterId 表id + * @return 是否删除成功 + */ + Integer deleteByMeterId(Long meterId); + } diff --git a/ruoyi-modules/Iot/src/main/java/org/dromara/iot/service/ITdMeterService.java b/ruoyi-modules/Iot/src/main/java/org/dromara/iot/service/ITdMeterService.java index 7331f9d9..248598a5 100644 --- a/ruoyi-modules/Iot/src/main/java/org/dromara/iot/service/ITdMeterService.java +++ b/ruoyi-modules/Iot/src/main/java/org/dromara/iot/service/ITdMeterService.java @@ -1,9 +1,10 @@ package org.dromara.iot.service; -import org.dromara.common.mybatis.core.page.PageQuery; -import org.dromara.common.mybatis.core.page.TableDataInfo; -import org.dromara.iot.domain.bo.TdMeterBo; +import org.dromara.iot.domain.TdMeter; import org.dromara.iot.domain.vo.TdMeterVo; +import org.dromara.iot.domain.bo.TdMeterBo; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.common.mybatis.core.page.PageQuery; import java.util.Collection; import java.util.List; @@ -12,7 +13,7 @@ import java.util.List; * 水电气Service接口 * * @author LionLi - * @date 2025-06-18 + * @date 2025-06-19 */ public interface ITdMeterService { @@ -65,4 +66,13 @@ public interface ITdMeterService { * @return 是否删除成功 */ Boolean deleteWithValidByIds(Collection ids, Boolean isValid); + + /** + * 打开或关闭表 + * + * @param meterId 智能表编码 + * @param onOff 0: 打开,2:关闭 + * @return 是否操作成功 + */ + Boolean operate(Long meterId, Integer onOff); } diff --git a/ruoyi-modules/Iot/src/main/java/org/dromara/iot/service/impl/TdMeterRoomServiceImpl.java b/ruoyi-modules/Iot/src/main/java/org/dromara/iot/service/impl/TdMeterRoomServiceImpl.java index 719839e9..5f7561ec 100644 --- a/ruoyi-modules/Iot/src/main/java/org/dromara/iot/service/impl/TdMeterRoomServiceImpl.java +++ b/ruoyi-modules/Iot/src/main/java/org/dromara/iot/service/impl/TdMeterRoomServiceImpl.java @@ -1,24 +1,25 @@ package org.dromara.iot.service.impl; -import org.dromara.common.core.utils.MapstructUtils; -import org.dromara.common.core.utils.StringUtils; -import org.dromara.common.mybatis.core.page.TableDataInfo; -import org.dromara.common.mybatis.core.page.PageQuery; -import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import cn.hutool.core.lang.Assert; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; +import org.dromara.common.core.utils.MapstructUtils; +import org.dromara.common.mybatis.core.page.PageQuery; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.iot.domain.TdMeterRoom; import org.dromara.iot.domain.bo.TdMeterRoomBo; import org.dromara.iot.domain.vo.TdMeterRoomVo; -import org.dromara.iot.domain.TdMeterRoom; import org.dromara.iot.mapper.TdMeterRoomMapper; import org.dromara.iot.service.ITdMeterRoomService; +import org.springframework.stereotype.Service; +import java.util.Collection; import java.util.List; import java.util.Map; -import java.util.Collection; /** * 和房间的关联Service业务层处理 @@ -130,4 +131,17 @@ public class TdMeterRoomServiceImpl implements ITdMeterRoomService { } return baseMapper.deleteByIds(ids) > 0; } + + @Override + public Boolean insertBatch(List rels) { + return baseMapper.insertBatch(rels); + } + + @Override + public Integer deleteByMeterId(Long meterId) { + Assert.notNull(meterId, "表id不能为null"); + LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>(); + updateWrapper.eq(TdMeterRoom::getMeterId, meterId); + return baseMapper.delete(updateWrapper); + } } diff --git a/ruoyi-modules/Iot/src/main/java/org/dromara/iot/service/impl/TdMeterServiceImpl.java b/ruoyi-modules/Iot/src/main/java/org/dromara/iot/service/impl/TdMeterServiceImpl.java index 3505e446..d1b95c78 100644 --- a/ruoyi-modules/Iot/src/main/java/org/dromara/iot/service/impl/TdMeterServiceImpl.java +++ b/ruoyi-modules/Iot/src/main/java/org/dromara/iot/service/impl/TdMeterServiceImpl.java @@ -1,30 +1,36 @@ package org.dromara.iot.service.impl; -import org.dromara.common.core.utils.MapstructUtils; -import org.dromara.common.core.utils.StringUtils; -import org.dromara.common.mybatis.core.page.TableDataInfo; -import org.dromara.common.mybatis.core.page.PageQuery; -import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import cn.hutool.core.collection.CollUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; +import org.dromara.common.core.exception.ServiceException; +import org.dromara.common.core.utils.MapstructUtils; +import org.dromara.common.core.utils.StringUtils; +import org.dromara.common.mybatis.core.page.PageQuery; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.iot.domain.TdMeter; +import org.dromara.iot.domain.TdMeterRoom; import org.dromara.iot.domain.bo.TdMeterBo; import org.dromara.iot.domain.vo.TdMeterVo; -import org.dromara.iot.domain.TdMeter; import org.dromara.iot.mapper.TdMeterMapper; +import org.dromara.iot.service.ITdMeterRoomService; import org.dromara.iot.service.ITdMeterService; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import java.util.Collection; import java.util.List; import java.util.Map; -import java.util.Collection; +import java.util.stream.Collectors; /** * 水电气Service业务层处理 * * @author LionLi - * @date 2025-06-18 + * @date 2025-06-19 */ @Slf4j @RequiredArgsConstructor @@ -33,6 +39,8 @@ public class TdMeterServiceImpl implements ITdMeterService { private final TdMeterMapper baseMapper; + private final ITdMeterRoomService meterRoomService; + /** * 查询水电气 * @@ -78,11 +86,9 @@ public class TdMeterServiceImpl implements ITdMeterService { lqw.eq(StringUtils.isNotBlank(bo.getMeterCode()), TdMeter::getMeterCode, bo.getMeterCode()); lqw.eq(StringUtils.isNotBlank(bo.getFactoryNo()), TdMeter::getFactoryNo, bo.getFactoryNo()); lqw.eq(bo.getMeterType() != null, TdMeter::getMeterType, bo.getMeterType()); + lqw.eq(bo.getMeterPurpose() != null, TdMeter::getMeterPurpose, bo.getMeterPurpose()); + lqw.eq(bo.getShareType() != null, TdMeter::getShareType, bo.getShareType()); lqw.eq(bo.getPayType() != null, TdMeter::getPayType, bo.getPayType()); - lqw.eq(bo.getDisplay() != null, TdMeter::getDisplay, bo.getDisplay()); - lqw.eq(bo.getSurplus() != null, TdMeter::getSurplus, bo.getSurplus()); - lqw.eq(bo.getCommunicationState() != null, TdMeter::getCommunicationState, bo.getCommunicationState()); - lqw.eq(bo.getRunningState() != null, TdMeter::getRunningState, bo.getRunningState()); return lqw; } @@ -93,14 +99,23 @@ public class TdMeterServiceImpl implements ITdMeterService { * @return 是否新增成功 */ @Override + @Transactional(rollbackFor = Exception.class) public Boolean insertByBo(TdMeterBo bo) { TdMeter add = MapstructUtils.convert(bo, TdMeter.class); validEntityBeforeSave(add); + // 写入表信息 boolean flag = baseMapper.insert(add) > 0; if (flag) { bo.setId(add.getId()); } - return flag; + // 写入表和房间的关联信息 + List collect = bo.getRoomIds().stream().map(item -> { + TdMeterRoom rel = new TdMeterRoom(); + rel.setMeterId(bo.getId()); + rel.setRoomId(item); + return rel; + }).collect(Collectors.toList()); + return meterRoomService.insertBatch(collect); } /** @@ -110,10 +125,28 @@ public class TdMeterServiceImpl implements ITdMeterService { * @return 是否修改成功 */ @Override + @Transactional(rollbackFor = Exception.class) public Boolean updateByBo(TdMeterBo bo) { TdMeter update = MapstructUtils.convert(bo, TdMeter.class); validEntityBeforeSave(update); - return baseMapper.updateById(update) > 0; + boolean b = baseMapper.updateById(update) > 0; + // 如果关联的房间列表没有发生变化,则不修改 + if (b && CollUtil.isNotEmpty(bo.getRoomIds())) { + // 删除已有的关联关系 + int num = meterRoomService.deleteByMeterId(bo.getId()); + log.info("删除智能表和房间关联数据条数: {}", num); + // 建立新的关系 + // 写入表和房间的关联信息 + List collect = bo.getRoomIds().stream().map(item -> { + TdMeterRoom rel = new TdMeterRoom(); + rel.setMeterId(bo.getId()); + rel.setRoomId(item); + return rel; + }).collect(Collectors.toList()); + Boolean b1 = meterRoomService.insertBatch(collect); + log.info("批量写入智能表和房间的关联关系,result={}", b1); + } + return b; } /** @@ -137,4 +170,17 @@ public class TdMeterServiceImpl implements ITdMeterService { } return baseMapper.deleteByIds(ids) > 0; } + + @Override + public Boolean operate(Long meterId, Integer onOff) { + // 校验当前表是否存在 + TdMeterVo tdMeterVo = queryById(meterId); + if (tdMeterVo == null) { + throw new ServiceException("只能表不存在"); + } + // todo 下发表操作 + + // todo 如果同步的情况下还需要更新表信息 + return true; + } } diff --git a/ruoyi-modules/Iot/src/main/resources/mapper/TbAccessControlMapper.xml b/ruoyi-modules/Iot/src/main/resources/mapper/TbAccessControlMapper.xml index ac7f1040..53db1490 100644 --- a/ruoyi-modules/Iot/src/main/resources/mapper/TbAccessControlMapper.xml +++ b/ruoyi-modules/Iot/src/main/resources/mapper/TbAccessControlMapper.xml @@ -2,6 +2,6 @@ - + diff --git a/ruoyi-modules/Iot/src/main/resources/mapper/TdFactoryMapper.xml b/ruoyi-modules/Iot/src/main/resources/mapper/TdFactoryMapper.xml index e5f1557a..a0b86302 100644 --- a/ruoyi-modules/Iot/src/main/resources/mapper/TdFactoryMapper.xml +++ b/ruoyi-modules/Iot/src/main/resources/mapper/TdFactoryMapper.xml @@ -2,6 +2,6 @@ - + diff --git a/ruoyi-modules/Iot/src/main/resources/mapper/TdMeterConfigMapper.xml b/ruoyi-modules/Iot/src/main/resources/mapper/TdMeterConfigMapper.xml index 1c9e7405..fc09999e 100644 --- a/ruoyi-modules/Iot/src/main/resources/mapper/TdMeterConfigMapper.xml +++ b/ruoyi-modules/Iot/src/main/resources/mapper/TdMeterConfigMapper.xml @@ -2,6 +2,6 @@ - + diff --git a/ruoyi-modules/Iot/src/main/resources/mapper/TdMeterMapper.xml b/ruoyi-modules/Iot/src/main/resources/mapper/TdMeterMapper.xml index d9e5ec5e..69fddacb 100644 --- a/ruoyi-modules/Iot/src/main/resources/mapper/TdMeterMapper.xml +++ b/ruoyi-modules/Iot/src/main/resources/mapper/TdMeterMapper.xml @@ -2,6 +2,6 @@ - + diff --git a/ruoyi-modules/Iot/src/main/resources/mapper/TdMeterRoomMapper.xml b/ruoyi-modules/Iot/src/main/resources/mapper/TdMeterRoomMapper.xml index 9f175fd4..373e9f45 100644 --- a/ruoyi-modules/Iot/src/main/resources/mapper/TdMeterRoomMapper.xml +++ b/ruoyi-modules/Iot/src/main/resources/mapper/TdMeterRoomMapper.xml @@ -2,6 +2,6 @@ - + diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/controller/TbCityAreaController.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/controller/SysCityAreaController.java similarity index 55% rename from ruoyi-modules/Property/src/main/java/org/dromara/property/controller/TbCityAreaController.java rename to ruoyi-modules/Property/src/main/java/org/dromara/property/controller/SysCityAreaController.java index 15387c26..0ba68b1f 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/controller/TbCityAreaController.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/controller/SysCityAreaController.java @@ -1,26 +1,31 @@ package org.dromara.property.controller; -import java.util.List; - -import lombok.RequiredArgsConstructor; -import jakarta.servlet.http.HttpServletResponse; -import jakarta.validation.constraints.*; import cn.dev33.satoken.annotation.SaCheckPermission; -import org.springframework.web.bind.annotation.*; -import org.springframework.validation.annotation.Validated; -import org.dromara.common.idempotent.annotation.RepeatSubmit; -import org.dromara.common.log.annotation.Log; -import org.dromara.common.web.core.BaseController; -import org.dromara.common.mybatis.core.page.PageQuery; +import com.alibaba.fastjson2.JSONObject; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; +import lombok.RequiredArgsConstructor; import org.dromara.common.core.domain.R; import org.dromara.common.core.validate.AddGroup; import org.dromara.common.core.validate.EditGroup; -import org.dromara.common.log.enums.BusinessType; import org.dromara.common.excel.utils.ExcelUtil; -import org.dromara.property.domain.vo.TbCityAreaVo; -import org.dromara.property.domain.bo.TbCityAreaBo; -import org.dromara.property.service.ITbCityAreaService; +import org.dromara.common.idempotent.annotation.RepeatSubmit; +import org.dromara.common.log.annotation.Log; +import org.dromara.common.log.enums.BusinessType; +import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.common.web.core.BaseController; +import org.dromara.property.domain.bo.SysCityAreaBo; +import org.dromara.property.domain.vo.CityAreaTreeVo; +import org.dromara.property.domain.vo.SysCityAreaVo; +import org.dromara.property.service.ISysCityAreaService; +import org.springframework.boot.ApplicationArguments; +import org.springframework.boot.ApplicationRunner; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.util.List; /** * 行政区划 @@ -34,9 +39,9 @@ import org.dromara.common.mybatis.core.page.TableDataInfo; @RequiredArgsConstructor @RestController @RequestMapping("/cityArea") -public class TbCityAreaController extends BaseController { +public class SysCityAreaController extends BaseController implements ApplicationRunner { - private final ITbCityAreaService tbCityAreaService; + private final ISysCityAreaService SysCityAreaService; /** * 查询行政区划 @@ -44,8 +49,8 @@ public class TbCityAreaController extends BaseController { */ @SaCheckPermission("property:cityArea:list") @GetMapping("/list") - public TableDataInfo list(TbCityAreaBo bo, PageQuery pageQuery) { - return tbCityAreaService.queryPageList(bo, pageQuery); + public TableDataInfo list(SysCityAreaBo bo, PageQuery pageQuery) { + return SysCityAreaService.queryPageList(bo, pageQuery); } /** @@ -55,22 +60,20 @@ public class TbCityAreaController extends BaseController { @SaCheckPermission("property:cityArea:export") @Log(title = "行政区划", businessType = BusinessType.EXPORT) @PostMapping("/export") - public void export(TbCityAreaBo bo, HttpServletResponse response) { - List list = tbCityAreaService.queryList(bo); - ExcelUtil.exportExcel(list, "行政区划", TbCityAreaVo.class, response); + public void export(SysCityAreaBo bo, HttpServletResponse response) { + List list = SysCityAreaService.queryList(bo); + ExcelUtil.exportExcel(list, "行政区划", SysCityAreaVo.class, response); } /** - * 获取行政区划 -详细信息 - * + * 获取行政区划详细信息 * @param areaCode 主键 */ @SaCheckPermission("property:cityArea:query") @GetMapping("/{areaCode}") - public R getInfo(@NotNull(message = "主键不能为空") + public R getInfo(@NotNull(message = "主键不能为空") @PathVariable("areaCode") String areaCode) { - return R.ok(tbCityAreaService.queryById(areaCode)); + return R.ok(SysCityAreaService.queryById(areaCode)); } /** @@ -81,8 +84,8 @@ public class TbCityAreaController extends BaseController { @Log(title = "行政区划", businessType = BusinessType.INSERT) @RepeatSubmit() @PostMapping() - public R add(@Validated(AddGroup.class) @RequestBody TbCityAreaBo bo) { - return toAjax(tbCityAreaService.insertByBo(bo)); + public R add(@Validated(AddGroup.class) @RequestBody SysCityAreaBo bo) { + return toAjax(SysCityAreaService.insertByBo(bo)); } /** @@ -93,8 +96,8 @@ public class TbCityAreaController extends BaseController { @Log(title = "行政区划", businessType = BusinessType.UPDATE) @RepeatSubmit() @PutMapping() - public R edit(@Validated(EditGroup.class) @RequestBody TbCityAreaBo bo) { - return toAjax(tbCityAreaService.updateByBo(bo)); + public R edit(@Validated(EditGroup.class) @RequestBody SysCityAreaBo bo) { + return toAjax(SysCityAreaService.updateByBo(bo)); } /** @@ -108,6 +111,25 @@ public class TbCityAreaController extends BaseController { @DeleteMapping("/{areaCodes}") public R remove(@NotEmpty(message = "主键不能为空") @PathVariable("areaCodes") String[] areaCodes) { - return toAjax(tbCityAreaService.deleteWithValidByIds(List.of(areaCodes), true)); + return toAjax(SysCityAreaService.deleteWithValidByIds(List.of(areaCodes), true)); + } + + + /** + * 查询行政区划树结构 + * + * @return 返回行政区划树结构 + */ + @GetMapping("/treeList") + public R> queryTreeList() { + List list = SysCityAreaService.queryTreeList(); + return R.ok(list); + } + + + @Override + public void run(ApplicationArguments args) throws Exception { + R> listR = queryTreeList(); + System.out.println(JSONObject.toJSONString(listR)); } } diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/TbCityArea.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/SysCityArea.java similarity index 74% rename from ruoyi-modules/Property/src/main/java/org/dromara/property/domain/TbCityArea.java rename to ruoyi-modules/Property/src/main/java/org/dromara/property/domain/SysCityArea.java index 56bef61f..2fa1e495 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/TbCityArea.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/SysCityArea.java @@ -1,9 +1,8 @@ package org.dromara.property.domain; -import org.dromara.common.tenant.core.TenantEntity; -import com.baomidou.mybatisplus.annotation.*; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; -import lombok.EqualsAndHashCode; import java.io.Serial; @@ -15,9 +14,8 @@ import java.io.Serial; * @date 2025-06-18 */ @Data -@EqualsAndHashCode(callSuper = true) -@TableName("tb_city_area") -public class TbCityArea extends TenantEntity { +@TableName("sys_city_area") +public class SysCityArea { @Serial private static final long serialVersionUID = 1L; @@ -68,10 +66,4 @@ public class TbCityArea extends TenantEntity { */ private Long dataState; - /** - * 搜索值 - */ - private String searchValue; - - } diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/bo/TbCityAreaBo.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/bo/SysCityAreaBo.java similarity index 88% rename from ruoyi-modules/Property/src/main/java/org/dromara/property/domain/bo/TbCityAreaBo.java rename to ruoyi-modules/Property/src/main/java/org/dromara/property/domain/bo/SysCityAreaBo.java index 041c062e..97a11f32 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/bo/TbCityAreaBo.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/bo/SysCityAreaBo.java @@ -1,13 +1,14 @@ package org.dromara.property.domain.bo; -import org.dromara.property.domain.TbCityArea; -import org.dromara.common.mybatis.core.domain.BaseEntity; -import org.dromara.common.core.validate.AddGroup; -import org.dromara.common.core.validate.EditGroup; import io.github.linpeilie.annotations.AutoMapper; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; import lombok.Data; import lombok.EqualsAndHashCode; -import jakarta.validation.constraints.*; +import org.dromara.common.core.validate.AddGroup; +import org.dromara.common.core.validate.EditGroup; +import org.dromara.common.mybatis.core.domain.BaseEntity; +import org.dromara.property.domain.SysCityArea; /** * 行政区划 @@ -18,8 +19,8 @@ import jakarta.validation.constraints.*; */ @Data @EqualsAndHashCode(callSuper = true) -@AutoMapper(target = TbCityArea.class, reverseConvertGenerate = false) -public class TbCityAreaBo extends BaseEntity { +@AutoMapper(target = SysCityArea.class, reverseConvertGenerate = false) +public class SysCityAreaBo extends BaseEntity { /** * 主键ID diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/convert/SysCityAreaCovert.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/convert/SysCityAreaCovert.java new file mode 100644 index 00000000..704bf2d8 --- /dev/null +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/convert/SysCityAreaCovert.java @@ -0,0 +1,24 @@ +package org.dromara.property.domain.convert; + +import org.dromara.property.domain.SysCityArea; +import org.dromara.property.domain.vo.CityAreaTreeVo; +import org.mapstruct.Mapper; +import org.mapstruct.MappingConstants; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.factory.Mappers; + +import java.util.List; + +/** + * 客户端数据转换器 + * + * @author Michelle.Chung + */ +@Mapper(componentModel = MappingConstants.ComponentModel.SPRING, unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface SysCityAreaCovert { + + SysCityAreaCovert INSTANCE = Mappers.getMapper(SysCityAreaCovert.class); + + List entity2Vo(List cityAreas); + +} diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/vo/CityAreaTreeVo.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/vo/CityAreaTreeVo.java new file mode 100644 index 00000000..7800fedd --- /dev/null +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/vo/CityAreaTreeVo.java @@ -0,0 +1,62 @@ +package org.dromara.property.domain.vo; + +import lombok.Data; +import org.dromara.common.core.domain.TreeEntity; + +import java.util.List; + +@Data +public class CityAreaTreeVo implements TreeEntity { + + /** + * 城市编码 + */ + private String areaCode; + + /** + * 城市名称 + */ + private String areaName; + + /** + * 101 省级 202 市州 303 区县 + */ + private String areaLevel; + + /** + * 父级城市编码 + */ + private String parentAreaCode; + + /** + * 父级城市名称 + */ + private String parentAreaName; + + /** + * 经度 + */ + private String lon; + + /** + * 维度 + */ + private String lat; + + private List children; + + @Override + public String getId() { + return getAreaCode(); + } + + @Override + public String getParentId() { + return getParentAreaCode(); + } + + @Override + public void setChildren(List children) { + this.children = children; + } +} diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/vo/TbCityAreaVo.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/vo/SysCityAreaVo.java similarity index 91% rename from ruoyi-modules/Property/src/main/java/org/dromara/property/domain/vo/TbCityAreaVo.java rename to ruoyi-modules/Property/src/main/java/org/dromara/property/domain/vo/SysCityAreaVo.java index 658f8e7b..b71cc605 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/vo/TbCityAreaVo.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/vo/SysCityAreaVo.java @@ -1,16 +1,15 @@ package org.dromara.property.domain.vo; -import org.dromara.property.domain.TbCityArea; import cn.idev.excel.annotation.ExcelIgnoreUnannotated; import cn.idev.excel.annotation.ExcelProperty; -import org.dromara.common.excel.annotation.ExcelDictFormat; -import org.dromara.common.excel.convert.ExcelDictConvert; import io.github.linpeilie.annotations.AutoMapper; import lombok.Data; +import org.dromara.common.excel.annotation.ExcelDictFormat; +import org.dromara.common.excel.convert.ExcelDictConvert; +import org.dromara.property.domain.SysCityArea; import java.io.Serial; import java.io.Serializable; -import java.util.Date; @@ -23,8 +22,8 @@ import java.util.Date; */ @Data @ExcelIgnoreUnannotated -@AutoMapper(target = TbCityArea.class) -public class TbCityAreaVo implements Serializable { +@AutoMapper(target = SysCityArea.class) +public class SysCityAreaVo implements Serializable { @Serial private static final long serialVersionUID = 1L; diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/mapper/SysCityAreaMapper.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/mapper/SysCityAreaMapper.java new file mode 100644 index 00000000..385368da --- /dev/null +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/mapper/SysCityAreaMapper.java @@ -0,0 +1,16 @@ +package org.dromara.property.mapper; + +import org.dromara.property.domain.SysCityArea; +import org.dromara.property.domain.vo.SysCityAreaVo; +import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; + +/** + * 行政区划 +Mapper接口 + * + * @author mocheng + * @date 2025-06-18 + */ +public interface SysCityAreaMapper extends BaseMapperPlus { + +} diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/mapper/TbCityAreaMapper.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/mapper/TbCityAreaMapper.java deleted file mode 100644 index 221356f5..00000000 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/mapper/TbCityAreaMapper.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.dromara.property.mapper; - -import org.dromara.property.domain.TbCityArea; -import org.dromara.property.domain.vo.TbCityAreaVo; -import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; - -/** - * 行政区划 -Mapper接口 - * - * @author mocheng - * @date 2025-06-18 - */ -public interface TbCityAreaMapper extends BaseMapperPlus { - -} diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/ITbCityAreaService.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/ISysCityAreaService.java similarity index 66% rename from ruoyi-modules/Property/src/main/java/org/dromara/property/service/ITbCityAreaService.java rename to ruoyi-modules/Property/src/main/java/org/dromara/property/service/ISysCityAreaService.java index c91bc3a6..446b9316 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/ITbCityAreaService.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/ISysCityAreaService.java @@ -1,10 +1,10 @@ package org.dromara.property.service; -import org.dromara.property.domain.TbCityArea; -import org.dromara.property.domain.vo.TbCityAreaVo; -import org.dromara.property.domain.bo.TbCityAreaBo; -import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.mybatis.core.page.PageQuery; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.property.domain.bo.SysCityAreaBo; +import org.dromara.property.domain.vo.CityAreaTreeVo; +import org.dromara.property.domain.vo.SysCityAreaVo; import java.util.Collection; import java.util.List; @@ -16,7 +16,7 @@ Service接口 * @author mocheng * @date 2025-06-18 */ -public interface ITbCityAreaService { +public interface ISysCityAreaService { /** * 查询行政区划 @@ -26,7 +26,7 @@ public interface ITbCityAreaService { * @return 行政区划 */ - TbCityAreaVo queryById(String areaCode); + SysCityAreaVo queryById(String areaCode); /** * 分页查询行政区划 @@ -37,7 +37,7 @@ public interface ITbCityAreaService { * @return 行政区划 分页列表 */ - TableDataInfo queryPageList(TbCityAreaBo bo, PageQuery pageQuery); + TableDataInfo queryPageList(SysCityAreaBo bo, PageQuery pageQuery); /** * 查询符合条件的行政区划 @@ -47,7 +47,7 @@ public interface ITbCityAreaService { * @return 行政区划 列表 */ - List queryList(TbCityAreaBo bo); + List queryList(SysCityAreaBo bo); /** * 新增行政区划 @@ -57,7 +57,7 @@ public interface ITbCityAreaService { * @return 是否新增成功 */ - Boolean insertByBo(TbCityAreaBo bo); + Boolean insertByBo(SysCityAreaBo bo); /** * 修改行政区划 @@ -67,7 +67,7 @@ public interface ITbCityAreaService { * @return 是否修改成功 */ - Boolean updateByBo(TbCityAreaBo bo); + Boolean updateByBo(SysCityAreaBo bo); /** * 校验并批量删除行政区划 @@ -78,4 +78,11 @@ public interface ITbCityAreaService { * @return 是否删除成功 */ Boolean deleteWithValidByIds(Collection ids, Boolean isValid); + + /** + * 生成行政区划树结构 + * + * @return 返回行政区划树结构 + */ + List queryTreeList(); } diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/SysCityAreaServiceImpl.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/SysCityAreaServiceImpl.java new file mode 100644 index 00000000..eac5cd58 --- /dev/null +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/SysCityAreaServiceImpl.java @@ -0,0 +1,161 @@ +package org.dromara.property.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.dromara.common.core.utils.MapstructUtils; +import org.dromara.common.core.utils.StringUtils; +import org.dromara.common.core.utils.TreeUtils; +import org.dromara.common.mybatis.core.page.PageQuery; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.property.domain.SysCityArea; +import org.dromara.property.domain.bo.SysCityAreaBo; +import org.dromara.property.domain.convert.SysCityAreaCovert; +import org.dromara.property.domain.vo.CityAreaTreeVo; +import org.dromara.property.domain.vo.SysCityAreaVo; +import org.dromara.property.mapper.SysCityAreaMapper; +import org.dromara.property.service.ISysCityAreaService; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +/** + * 行政区划 + * Service业务层处理 + * + * @author mocheng + * @date 2025-06-18 + */ +@Slf4j +@RequiredArgsConstructor +@Service +public class SysCityAreaServiceImpl implements ISysCityAreaService { + + private final SysCityAreaMapper baseMapper; + + /** + * 查询行政区划 + * + * @param areaCode 主键 + * @return 行政区划 + */ + @Override + public SysCityAreaVo queryById(String areaCode) { + return baseMapper.selectVoById(areaCode); + } + + /** + * 分页查询行政区划 + * 列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 行政区划 + * 分页列表 + */ + @Override + public TableDataInfo queryPageList(SysCityAreaBo bo, PageQuery pageQuery) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); + return TableDataInfo.build(result); + } + + /** + * 查询符合条件的行政区划 + * 列表 + * + * @param bo 查询条件 + * @return 行政区划 + * 列表 + */ + @Override + public List queryList(SysCityAreaBo bo) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + return baseMapper.selectVoList(lqw); + } + + private LambdaQueryWrapper buildQueryWrapper(SysCityAreaBo bo) { + Map params = bo.getParams(); + LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); + lqw.eq(StringUtils.isNotBlank(bo.getAreaCode()), SysCityArea::getAreaCode, bo.getAreaCode()); + lqw.orderByAsc(SysCityArea::getAreaCode); + lqw.like(StringUtils.isNotBlank(bo.getAreaName()), SysCityArea::getAreaName, bo.getAreaName()); + lqw.eq(StringUtils.isNotBlank(bo.getAreaLevel()), SysCityArea::getAreaLevel, bo.getAreaLevel()); + lqw.eq(StringUtils.isNotBlank(bo.getParentAreaCode()), SysCityArea::getParentAreaCode, bo.getParentAreaCode()); + lqw.like(StringUtils.isNotBlank(bo.getParentAreaName()), SysCityArea::getParentAreaName, bo.getParentAreaName()); + lqw.eq(StringUtils.isNotBlank(bo.getLon()), SysCityArea::getLon, bo.getLon()); + lqw.eq(StringUtils.isNotBlank(bo.getLat()), SysCityArea::getLat, bo.getLat()); + lqw.eq(bo.getDataState() != null, SysCityArea::getDataState, bo.getDataState()); + return lqw; + } + + /** + * 新增行政区划 + * + * @param bo 行政区划 + * @return 是否新增成功 + */ + @Override + public Boolean insertByBo(SysCityAreaBo bo) { + SysCityArea add = MapstructUtils.convert(bo, SysCityArea.class); + validEntityBeforeSave(add); + boolean flag = baseMapper.insert(add) > 0; + if (flag) { + bo.setAreaCode(add.getAreaCode()); + } + return flag; + } + + /** + * 修改行政区划 + * + * @param bo 行政区划 + * @return 是否修改成功 + */ + @Override + public Boolean updateByBo(SysCityAreaBo bo) { + SysCityArea update = MapstructUtils.convert(bo, SysCityArea.class); + validEntityBeforeSave(update); + return baseMapper.updateById(update) > 0; + } + + /** + * 保存前的数据校验 + */ + private void validEntityBeforeSave(SysCityArea entity) { + //TODO 做一些数据校验,如唯一约束 + } + + /** + * 校验并批量删除行政区划 + * 信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + @Override + public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { + if (isValid) { + //TODO 做一些业务上的校验,判断是否需要校验 + } + return baseMapper.deleteByIds(ids) > 0; + } + + @Override + public List queryTreeList() { + // 查询所有的行政区划数据 + List cityAreas = baseMapper.selectList(null); + if (CollectionUtil.isEmpty(cityAreas)) { + return new ArrayList<>(); + } + List vo = SysCityAreaCovert.INSTANCE.entity2Vo(cityAreas); + return TreeUtils.getTreeList(vo, "0"); + } +} diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/TbCityAreaServiceImpl.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/TbCityAreaServiceImpl.java deleted file mode 100644 index cd13b836..00000000 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/TbCityAreaServiceImpl.java +++ /dev/null @@ -1,151 +0,0 @@ -package org.dromara.property.service.impl; - -import org.dromara.common.core.utils.MapstructUtils; -import org.dromara.common.core.utils.StringUtils; -import org.dromara.common.mybatis.core.page.TableDataInfo; -import org.dromara.common.mybatis.core.page.PageQuery; -import com.baomidou.mybatisplus.extension.plugins.pagination.Page; -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import com.baomidou.mybatisplus.core.toolkit.Wrappers; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; -import org.dromara.property.domain.bo.TbCityAreaBo; -import org.dromara.property.domain.vo.TbCityAreaVo; -import org.dromara.property.domain.TbCityArea; -import org.dromara.property.mapper.TbCityAreaMapper; -import org.dromara.property.service.ITbCityAreaService; - -import java.util.List; -import java.util.Map; -import java.util.Collection; - -/** - * 行政区划 -Service业务层处理 - * - * @author mocheng - * @date 2025-06-18 - */ -@Slf4j -@RequiredArgsConstructor -@Service -public class TbCityAreaServiceImpl implements ITbCityAreaService { - - private final TbCityAreaMapper baseMapper; - - /** - * 查询行政区划 - - * - * @param areaCode 主键 - * @return 行政区划 - - */ - @Override - public TbCityAreaVo queryById(String areaCode){ - return baseMapper.selectVoById(areaCode); - } - - /** - * 分页查询行政区划 -列表 - * - * @param bo 查询条件 - * @param pageQuery 分页参数 - * @return 行政区划 -分页列表 - */ - @Override - public TableDataInfo queryPageList(TbCityAreaBo bo, PageQuery pageQuery) { - LambdaQueryWrapper lqw = buildQueryWrapper(bo); - Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); - return TableDataInfo.build(result); - } - - /** - * 查询符合条件的行政区划 -列表 - * - * @param bo 查询条件 - * @return 行政区划 -列表 - */ - @Override - public List queryList(TbCityAreaBo bo) { - LambdaQueryWrapper lqw = buildQueryWrapper(bo); - return baseMapper.selectVoList(lqw); - } - - private LambdaQueryWrapper buildQueryWrapper(TbCityAreaBo bo) { - Map params = bo.getParams(); - LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); - lqw.eq(StringUtils.isNotBlank(bo.getAreaCode()), TbCityArea::getAreaCode, bo.getAreaCode()); - lqw.orderByAsc(TbCityArea::getAreaCode); - lqw.like(StringUtils.isNotBlank(bo.getAreaName()), TbCityArea::getAreaName, bo.getAreaName()); - lqw.eq(StringUtils.isNotBlank(bo.getAreaLevel()), TbCityArea::getAreaLevel, bo.getAreaLevel()); - lqw.eq(StringUtils.isNotBlank(bo.getParentAreaCode()), TbCityArea::getParentAreaCode, bo.getParentAreaCode()); - lqw.like(StringUtils.isNotBlank(bo.getParentAreaName()), TbCityArea::getParentAreaName, bo.getParentAreaName()); - lqw.eq(StringUtils.isNotBlank(bo.getLon()), TbCityArea::getLon, bo.getLon()); - lqw.eq(StringUtils.isNotBlank(bo.getLat()), TbCityArea::getLat, bo.getLat()); - lqw.eq(bo.getDataState() != null, TbCityArea::getDataState, bo.getDataState()); - return lqw; - } - - /** - * 新增行政区划 - - * - * @param bo 行政区划 - - * @return 是否新增成功 - */ - @Override - public Boolean insertByBo(TbCityAreaBo bo) { - TbCityArea add = MapstructUtils.convert(bo, TbCityArea.class); - validEntityBeforeSave(add); - boolean flag = baseMapper.insert(add) > 0; - if (flag) { - bo.setAreaCode(add.getAreaCode()); - } - return flag; - } - - /** - * 修改行政区划 - - * - * @param bo 行政区划 - - * @return 是否修改成功 - */ - @Override - public Boolean updateByBo(TbCityAreaBo bo) { - TbCityArea update = MapstructUtils.convert(bo, TbCityArea.class); - validEntityBeforeSave(update); - return baseMapper.updateById(update) > 0; - } - - /** - * 保存前的数据校验 - */ - private void validEntityBeforeSave(TbCityArea entity){ - //TODO 做一些数据校验,如唯一约束 - } - - /** - * 校验并批量删除行政区划 -信息 - * - * @param ids 待删除的主键集合 - * @param isValid 是否进行有效性校验 - * @return 是否删除成功 - */ - @Override - public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { - if(isValid){ - //TODO 做一些业务上的校验,判断是否需要校验 - } - return baseMapper.deleteByIds(ids) > 0; - } -} diff --git a/ruoyi-modules/Property/src/main/resources/mapper/Property/TbCityAreaMapper.xml b/ruoyi-modules/Property/src/main/resources/mapper/Property/SysCityAreaMapper.xml similarity index 70% rename from ruoyi-modules/Property/src/main/resources/mapper/Property/TbCityAreaMapper.xml rename to ruoyi-modules/Property/src/main/resources/mapper/Property/SysCityAreaMapper.xml index 6ee1cd71..b766234e 100644 --- a/ruoyi-modules/Property/src/main/resources/mapper/Property/TbCityAreaMapper.xml +++ b/ruoyi-modules/Property/src/main/resources/mapper/Property/SysCityAreaMapper.xml @@ -2,6 +2,6 @@ - + From d6903acf64a595e3849997eceea50402f2757686 Mon Sep 17 00:00:00 2001 From: lxj <15683799673@163.com> Date: Thu, 19 Jun 2025 18:26:41 +0800 Subject: [PATCH 2/4] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E8=A1=8C=E6=94=BF?= =?UTF-8?q?=E5=8C=BA=E5=88=92=E6=A0=91=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/org/dromara/common/core/domain/TreeEntity.java | 6 +++--- .../main/java/org/dromara/common/core/utils/TreeUtils.java | 6 +++--- .../main/java/org/dromara/iot/service/ITdMeterService.java | 7 +++---- .../main/java/org/dromara/property/domain/SysCityArea.java | 3 ++- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/TreeEntity.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/TreeEntity.java index 92653b4c..a1f3079b 100644 --- a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/TreeEntity.java +++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/TreeEntity.java @@ -7,9 +7,9 @@ import java.util.List; * @param */ public interface TreeEntity { - public T getId(); + T getId(); - public T getParentId(); + T getParentId(); - public void setChildren(List children); + void setChildren(List children); } diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/TreeUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/TreeUtils.java index 1a97516a..68eb8a99 100644 --- a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/TreeUtils.java +++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/TreeUtils.java @@ -21,17 +21,17 @@ public class TreeUtils { * @param rootCode 根节点编码 * @return 构建树状 */ - public static List getTreeList(List entityList, Object rootCode) { + public static > List getTreeList(List entityList, Object rootCode) { if (CollectionUtil.isEmpty(entityList)) { return new ArrayList<>(); } //第一次循环 数据分组 Map> groupData = new HashMap<>(); for (T entity : entityList) { - groupData.computeIfAbsent(entity.getParentId(), (k) -> new ArrayList()).add(entity); + groupData.computeIfAbsent(entity.getParentId(), (k) -> new ArrayList<>()).add(entity); } // 第二次循环 生成树结构 - for (TreeEntity entity : entityList) { + for (TreeEntity entity : entityList) { List children = groupData.get(entity.getId()); if (children != null) { entity.setChildren(children); diff --git a/ruoyi-modules/Iot/src/main/java/org/dromara/iot/service/ITdMeterService.java b/ruoyi-modules/Iot/src/main/java/org/dromara/iot/service/ITdMeterService.java index 248598a5..b0189e21 100644 --- a/ruoyi-modules/Iot/src/main/java/org/dromara/iot/service/ITdMeterService.java +++ b/ruoyi-modules/Iot/src/main/java/org/dromara/iot/service/ITdMeterService.java @@ -1,10 +1,9 @@ package org.dromara.iot.service; -import org.dromara.iot.domain.TdMeter; -import org.dromara.iot.domain.vo.TdMeterVo; -import org.dromara.iot.domain.bo.TdMeterBo; -import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.mybatis.core.page.PageQuery; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.iot.domain.bo.TdMeterBo; +import org.dromara.iot.domain.vo.TdMeterVo; import java.util.Collection; import java.util.List; diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/SysCityArea.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/SysCityArea.java index 2fa1e495..48d8a6e2 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/SysCityArea.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/SysCityArea.java @@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; import java.io.Serial; +import java.io.Serializable; /** * 行政区划 @@ -15,7 +16,7 @@ import java.io.Serial; */ @Data @TableName("sys_city_area") -public class SysCityArea { +public class SysCityArea implements Serializable { @Serial private static final long serialVersionUID = 1L; From 636b8d2f7e8636501a13864fb0b0a4a4795b8384 Mon Sep 17 00:00:00 2001 From: zcxlsm Date: Fri, 20 Jun 2025 17:49:01 +0800 Subject: [PATCH 3/4] =?UTF-8?q?feat(iot):=20=E6=B7=BB=E5=8A=A0=20E8?= =?UTF-8?q?=E9=97=A8=E7=A6=81=E8=AE=BE=E5=A4=87=E7=AE=A1=E7=90=86=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 E8 门禁设备相关的数据模型和接口 - 实现 E8 门禁设备的添加、查询、修改和删除功能- 在门禁管理服务中集成 E8 门禁设备的添加逻辑 --- .../dromara/iot/domain/TbAccessControl.java | 5 +- .../iot/mapper/TbAccessControlMapper.java | 2 + .../e8/api/base/DoorDeviceService.java | 56 ++++ .../api/base/impl/DoorDeviceServiceImpl.java | 173 ++++++++++++ .../dromara/iot/service/e8/model/ApiResp.java | 38 +++ .../DoorDevice/req/DoorDeviceAddReq.java | 140 ++++++++++ .../DoorDevice/req/DoorDeviceFindReq.java | 43 +++ .../DoorDevice/req/DoorDeviceUpdateReq.java | 139 ++++++++++ .../DoorDevice/res/DoorDeviceAddRes.java | 198 ++++++++++++++ .../DoorDevice/res/DoorDeviceFindRes.java | 251 ++++++++++++++++++ .../iot/service/e8/model/QueryDto.java | 26 ++ .../iot/service/e8/utils/E8ApiUtil.java | 221 +++++++++++++++ .../impl/TbAccessControlServiceImpl.java | 28 +- 13 files changed, 1313 insertions(+), 7 deletions(-) create mode 100644 ruoyi-modules/Iot/src/main/java/org/dromara/iot/service/e8/api/base/DoorDeviceService.java create mode 100644 ruoyi-modules/Iot/src/main/java/org/dromara/iot/service/e8/api/base/impl/DoorDeviceServiceImpl.java create mode 100644 ruoyi-modules/Iot/src/main/java/org/dromara/iot/service/e8/model/ApiResp.java create mode 100644 ruoyi-modules/Iot/src/main/java/org/dromara/iot/service/e8/model/DoorDevice/req/DoorDeviceAddReq.java create mode 100644 ruoyi-modules/Iot/src/main/java/org/dromara/iot/service/e8/model/DoorDevice/req/DoorDeviceFindReq.java create mode 100644 ruoyi-modules/Iot/src/main/java/org/dromara/iot/service/e8/model/DoorDevice/req/DoorDeviceUpdateReq.java create mode 100644 ruoyi-modules/Iot/src/main/java/org/dromara/iot/service/e8/model/DoorDevice/res/DoorDeviceAddRes.java create mode 100644 ruoyi-modules/Iot/src/main/java/org/dromara/iot/service/e8/model/DoorDevice/res/DoorDeviceFindRes.java create mode 100644 ruoyi-modules/Iot/src/main/java/org/dromara/iot/service/e8/model/QueryDto.java create mode 100644 ruoyi-modules/Iot/src/main/java/org/dromara/iot/service/e8/utils/E8ApiUtil.java diff --git a/ruoyi-modules/Iot/src/main/java/org/dromara/iot/domain/TbAccessControl.java b/ruoyi-modules/Iot/src/main/java/org/dromara/iot/domain/TbAccessControl.java index 7cdc1b79..72a34bd1 100644 --- a/ruoyi-modules/Iot/src/main/java/org/dromara/iot/domain/TbAccessControl.java +++ b/ruoyi-modules/Iot/src/main/java/org/dromara/iot/domain/TbAccessControl.java @@ -5,7 +5,6 @@ import com.baomidou.mybatisplus.annotation.*; import lombok.Data; import lombok.EqualsAndHashCode; import java.util.Date; -import com.fasterxml.jackson.annotation.JsonFormat; import java.io.Serial; @@ -13,7 +12,7 @@ import java.io.Serial; * 门禁管理对象 tb_access_control * * @author mocheng - * @date 2025-06-17 + * @since 2025-06-17 */ @Data @EqualsAndHashCode(callSuper = true) @@ -62,7 +61,7 @@ public class TbAccessControl extends BaseEntity { /** * 门禁设备类型 */ - private Long accssType; + private Long accessType; /** * 工程编号 diff --git a/ruoyi-modules/Iot/src/main/java/org/dromara/iot/mapper/TbAccessControlMapper.java b/ruoyi-modules/Iot/src/main/java/org/dromara/iot/mapper/TbAccessControlMapper.java index cf104d43..7b85fb06 100644 --- a/ruoyi-modules/Iot/src/main/java/org/dromara/iot/mapper/TbAccessControlMapper.java +++ b/ruoyi-modules/Iot/src/main/java/org/dromara/iot/mapper/TbAccessControlMapper.java @@ -1,5 +1,6 @@ package org.dromara.iot.mapper; +import org.apache.ibatis.annotations.Mapper; import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; import org.dromara.iot.domain.TbAccessControl; import org.dromara.iot.domain.vo.TbAccessControlVo; @@ -10,6 +11,7 @@ import org.dromara.iot.domain.vo.TbAccessControlVo; * @author mocheng * @date 2025-06-17 */ +@Mapper public interface TbAccessControlMapper extends BaseMapperPlus { } diff --git a/ruoyi-modules/Iot/src/main/java/org/dromara/iot/service/e8/api/base/DoorDeviceService.java b/ruoyi-modules/Iot/src/main/java/org/dromara/iot/service/e8/api/base/DoorDeviceService.java new file mode 100644 index 00000000..76901684 --- /dev/null +++ b/ruoyi-modules/Iot/src/main/java/org/dromara/iot/service/e8/api/base/DoorDeviceService.java @@ -0,0 +1,56 @@ +package org.dromara.iot.service.e8.api.base; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import org.dromara.iot.service.e8.model.DoorDevice.req.DoorDeviceAddReq; +import org.dromara.iot.service.e8.model.DoorDevice.req.DoorDeviceUpdateReq; +import org.dromara.iot.service.e8.model.DoorDevice.res.DoorDeviceAddRes; +import org.dromara.iot.service.e8.model.DoorDevice.res.DoorDeviceFindRes; +import org.dromara.iot.service.e8.model.QueryDto; + +/** + * @author lsm + * @apiNote DoorDeviceService + * @since 2025/6/20 + */ +public interface DoorDeviceService { + + /** + * 查询门禁信息 + * + * @param id 入参 + * @return DoorDeviceFindRes + */ + DoorDeviceFindRes findDoorDevice(Long id); + + /** + * 门禁信息分页查询 + * + * @param dto 入参 + * @return IPage + */ + IPage findDoorDeviceList(QueryDto dto); + + /** + * 新增门禁信息 + * + * @param addReq 入参 + * @return DoorDeviceAddRes + */ + DoorDeviceAddRes addDoorDevice(DoorDeviceAddReq addReq); + + /** + * 门禁信息修改 + * + * @param updateReq 入参 + * @return Boolean + */ + Boolean updateDoorDevice(DoorDeviceUpdateReq updateReq); + + /** + * 删除门禁信息 + * + * @param id 入参 + * @return Boolean + */ + Boolean deleteDoorDevice(Integer id); +} diff --git a/ruoyi-modules/Iot/src/main/java/org/dromara/iot/service/e8/api/base/impl/DoorDeviceServiceImpl.java b/ruoyi-modules/Iot/src/main/java/org/dromara/iot/service/e8/api/base/impl/DoorDeviceServiceImpl.java new file mode 100644 index 00000000..c45efebe --- /dev/null +++ b/ruoyi-modules/Iot/src/main/java/org/dromara/iot/service/e8/api/base/impl/DoorDeviceServiceImpl.java @@ -0,0 +1,173 @@ +package org.dromara.iot.service.e8.api.base.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.lang.TypeReference; +import cn.hutool.json.JSONUtil; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import lombok.extern.slf4j.Slf4j; +import org.dromara.iot.service.e8.api.base.DoorDeviceService; +import org.dromara.iot.service.e8.model.ApiResp; +import org.dromara.iot.service.e8.model.DoorDevice.req.DoorDeviceAddReq; +import org.dromara.iot.service.e8.model.DoorDevice.req.DoorDeviceFindReq; +import org.dromara.iot.service.e8.model.DoorDevice.req.DoorDeviceUpdateReq; +import org.dromara.iot.service.e8.model.DoorDevice.res.DoorDeviceAddRes; +import org.dromara.iot.service.e8.model.DoorDevice.res.DoorDeviceFindRes; +import org.dromara.iot.service.e8.model.QueryDto; +import org.dromara.iot.service.e8.utils.E8ApiUtil; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.HashMap; +import java.util.Map; + +/** + * @author lsm + * @apiNote DoorDeviceServiceImpl + * @since 2025/6/20 + */ +@Slf4j +@Service +public class DoorDeviceServiceImpl implements DoorDeviceService { + + private final static String DOOR_DEVICE_GET_PAGE_LIST = "/api/e8door/man-device-info/get-page-list"; + private final static String DOOR_DEVICE_GET_FIRST_OR_DEFAULT = "/api/E8Door/man-device-info/{id}"; + private final static String DOOR_DEVICE_CREATE = "/api/E8Door/man-device-info"; + private final static String DOOR_DEVICE_UPDATE = "/api/E8Door/man-device-info/{id}/update"; + private final static String DOOR_DEVICE_DELETE = "/api/E8Door/man-device-info/{id}"; + + @Resource + private E8ApiUtil e8ApiUtil; + + /** + * 查询门禁信息 + * + * @param id 传参 + * @return DoorDeviceFindRes + */ + @Override + public DoorDeviceFindRes findDoorDevice(Long id) { + + // 使用给定的ID替换API模板中的{id}占位符 + String api = DOOR_DEVICE_GET_FIRST_OR_DEFAULT.replace("{id}", id.toString()); + + // 调用E8 API工具类的doGetOrDel方法发送GET请求,并获取响应结果 + ApiResp apiResp = e8ApiUtil.doGetOrDel(api, null, false); + + // 检查API响应是否成功 + if (!apiResp.getSuccess()) { + log.debug("查询E8门禁信息失败 msg:{}", apiResp); + // 如果响应不成功,则返回null + return null; + } + + // 将API响应结果转换为指定的Java对象,并返回该对象 + return JSONUtil.toBean(JSONUtil.toJsonStr(apiResp.getResult()), DoorDeviceFindRes.class); + } + + /** + * 门禁信息分页查询 + * + * @param dto 传参 + * @return IPage + */ + @Override + public IPage findDoorDeviceList(QueryDto dto) { + // 创建一个参数映射,用于存储API请求所需的参数 + Map params = new HashMap<>(); + // 将分页索引和最大结果数放入参数映射中 + params.put("PageIndex", dto.getPageIndex()); + params.put("MaxResultCount", dto.getMaxResultCount()); + // 将查询DTO转换为JSON字符串,再转换为Map对象,然后放入参数映射中 + params.put("QueryDto", JSONUtil.toBean(JSONUtil.toJsonStr(dto.getQueryDto()), DoorDeviceFindReq.class)); + + // 调用第三方API,获取门禁设备分页列表 + ApiResp apiResp = e8ApiUtil.doPost(params, DOOR_DEVICE_GET_PAGE_LIST); + + log.info("apiResp:{}", apiResp); + + // 如果API调用不成功,则返回null + if (!apiResp.getSuccess()) { + log.debug("分页查询E8门禁信息失败 msg:{}", apiResp); + return null; + } + + + // 将API响应结果转换为Map对象,以便后续处理 + Map result = JSONUtil.toBean(JSONUtil.toJsonStr(apiResp.getResult()), new TypeReference<>() { + }, false); + // 创建一个分页对象,用于存储处理后的门禁设备信息 + IPage page = new Page<>(dto.getPageIndex(), dto.getMaxResultCount()); + // 设置分页对象的总记录数 + page.setTotal(Long.parseLong(result.get("total").toString())); + // 将API响应结果中的门禁设备信息列表转换为DoorDeviceFindRes对象列表,并设置到分页对象中 + page.setRecords(JSONUtil.toList(JSONUtil.toJsonStr(result.get("item")), DoorDeviceFindRes.class)); + + // 返回处理后的分页对象 + return page; + } + + /** + * 新增门禁信息 + * + * @param addReq 传参 + * @return Boolean + */ + @Override + public DoorDeviceAddRes addDoorDevice(DoorDeviceAddReq addReq) { + // 将DoorDeviceAddReq转为Map对象,以便作为API请求的参数 + Map params = BeanUtil.beanToMap(addReq); + + // 调用第三方API进行门禁设备创建,并传入转换后的参数 + ApiResp apiResp = e8ApiUtil.doPost(params, DOOR_DEVICE_CREATE); + + if (!apiResp.getSuccess()) { + log.info("新增E8门禁信息,msg:{}", apiResp); + return null; + } + + return JSONUtil.toBean(JSONUtil.toJsonStr(apiResp.getResult()), DoorDeviceAddRes.class); + } + + /** + * 门禁信息修改 + * + * @param updateReq 传参 + * @return Boolean + */ + @Override + public Boolean updateDoorDevice(DoorDeviceUpdateReq updateReq) { + + // 构造门设备更新API的URL + String api = DOOR_DEVICE_UPDATE.replace("{id}", updateReq.getId().toString()); + + // 将门设备信息对象转换为键值对形式的参数 + Map params = BeanUtil.beanToMap(updateReq); + + // 调用API进行门设备信息更新 + ApiResp apiResp = e8ApiUtil.doPost(params, api); + + // 返回API调用是否成功的结果 + return apiResp.getSuccess(); + } + + /** + * 删除门禁信息 + * + * @param id 传参 + * @return Boolean + */ + @Override + public Boolean deleteDoorDevice(Integer id) { + + // 构造删除门设备的API路径,使用设备ID替换占位符 + String api = DOOR_DEVICE_DELETE.replace("{id}", id.toString()); + + // 调用E8 API工具类进行HTTP DELETE请求,参数为构造的API路径和null(因为DELETE请求通常不需要请求体) + ApiResp apiResp = e8ApiUtil.doGetOrDel(api, null, true); + + // 返回API响应的成功标志 + return apiResp.getSuccess(); + } + +} diff --git a/ruoyi-modules/Iot/src/main/java/org/dromara/iot/service/e8/model/ApiResp.java b/ruoyi-modules/Iot/src/main/java/org/dromara/iot/service/e8/model/ApiResp.java new file mode 100644 index 00000000..5d85b476 --- /dev/null +++ b/ruoyi-modules/Iot/src/main/java/org/dromara/iot/service/e8/model/ApiResp.java @@ -0,0 +1,38 @@ +package org.dromara.iot.service.e8.model; + +import lombok.AllArgsConstructor; +import lombok.Data; + +/** + * @author lsm + * @apiNote ApiResp + * @since 2025/6/20 + */ +@Data +@AllArgsConstructor +public class ApiResp { + /** + * success为false时返回错误信息 + */ + private String message; + + /** + * sessionId + */ + private Long sessionId; + + /** + * 返回处理结果(数据由具体接口决定) + */ + private Object result; + + /** + * true表示成功,false表示失败 + */ + private Boolean success; + + /** + * 状态码 0表示成功,1表示失败 + */ + private Integer code; +} diff --git a/ruoyi-modules/Iot/src/main/java/org/dromara/iot/service/e8/model/DoorDevice/req/DoorDeviceAddReq.java b/ruoyi-modules/Iot/src/main/java/org/dromara/iot/service/e8/model/DoorDevice/req/DoorDeviceAddReq.java new file mode 100644 index 00000000..9bdfecf7 --- /dev/null +++ b/ruoyi-modules/Iot/src/main/java/org/dromara/iot/service/e8/model/DoorDevice/req/DoorDeviceAddReq.java @@ -0,0 +1,140 @@ +package org.dromara.iot.service.e8.model.DoorDevice.req; + +import lombok.Data; + +/** + * @author lsm + * @apiNote DoorDeviceAddReq + * @since 2025/6/20 + */ +@Data +public class DoorDeviceAddReq { + + /** + * 设备名称 + */ + private String name; + + /** + * 父设备ID + */ + private Long parentId; + + /** + * 设备IP + */ + private String ip; + + /** + * 设备端口 + */ + private Long port; + + /** + * 设备MAC + */ + private String mac; + + /** + * 子网掩码 + */ + private String netMask; + + /** + * 设备网关 + */ + private String gatewayIP; + + /** + * 设备产品线类型 + * 0:车行 1:车位 2:人行 + */ + private Integer productType; + + /** + * 设备类型 + * 2201:一体式门禁 2202:分体式门禁 2203:人脸门禁 2204:梯控 2207:人脸盒子终端 + * 2208:人脸盒子面板机 2209:一体式读头 2211:梯控读头 2102:电子哨兵 + */ + private Long type; + + /** + * 业务逻辑设备类 + */ + private Integer logicType; + + /** + * 设备型号 + */ + private Integer model; + + /** + * 设备序列号 + */ + private String sn; + + /** + * 设备CPUID + */ + private String cpuID; + + /** + * 设备在线状态 0:离线 1:在线 2:未知 + */ + private Integer status; + + /** + * 设备在线状态描述 + */ + private String statusDescription; + + /** + * 机号 + */ + private String macNo; + + /** + * 蓝牙地址 + */ + private String bluetoothAddr; + + /** + * 设备层级 + */ + private Integer deviceLevel; + + /** + * 备注 + */ + private String remark; + + /** + * 设备通讯方式 0:TCP/IP 1:RS485 + */ + private Integer commType; + + /** + * 旧IP + */ + private String oldIp; + + /** + * 旧端口号 + */ + private Integer oldPort; + + /** + * 旧机号 + */ + private String oldMacNo; + + /** + * 工单号(设备搜索) + */ + private String projectNumber; + + /** + * 固件版本信息(设备搜索) + */ + private String version; +} diff --git a/ruoyi-modules/Iot/src/main/java/org/dromara/iot/service/e8/model/DoorDevice/req/DoorDeviceFindReq.java b/ruoyi-modules/Iot/src/main/java/org/dromara/iot/service/e8/model/DoorDevice/req/DoorDeviceFindReq.java new file mode 100644 index 00000000..0b60a579 --- /dev/null +++ b/ruoyi-modules/Iot/src/main/java/org/dromara/iot/service/e8/model/DoorDevice/req/DoorDeviceFindReq.java @@ -0,0 +1,43 @@ +package org.dromara.iot.service.e8.model.DoorDevice.req; + +import lombok.Data; + +/** + * @author lsm + * @apiNote DoorDeviceFindReq + * @since 2025/6/20 + */ +@Data +public class DoorDeviceFindReq { + /** + * 主键 + */ + private Long id; + + /** + * 是否脱敏 true脱敏,敏感信息加***隐藏;false完整显示 + */ + private Boolean isViewFullData; + + /** + * 设备名称 + */ + private String name; + + /** + * 设备类型 + * 2201:一体式门禁 2202:分体式门禁 2203:人脸门禁 2204:梯控 2207:人脸盒子终端 + * 2208:人脸盒子面板机 2209:一体式读头 2211:梯控读头 2102:电子哨兵 + */ + private Long type; + + /** + * 设备型号 + */ + private Integer model; + + /** + * 设备在线状态 0:离线 1:在线 2:未知 + */ + private Integer status; +} diff --git a/ruoyi-modules/Iot/src/main/java/org/dromara/iot/service/e8/model/DoorDevice/req/DoorDeviceUpdateReq.java b/ruoyi-modules/Iot/src/main/java/org/dromara/iot/service/e8/model/DoorDevice/req/DoorDeviceUpdateReq.java new file mode 100644 index 00000000..e90ea0b2 --- /dev/null +++ b/ruoyi-modules/Iot/src/main/java/org/dromara/iot/service/e8/model/DoorDevice/req/DoorDeviceUpdateReq.java @@ -0,0 +1,139 @@ +package org.dromara.iot.service.e8.model.DoorDevice.req; + +import lombok.Data; + +/** + * @author lsm + * @apiNote DoorDeviceUpdateReq + * @since 2025/6/20 + */ +@Data +public class DoorDeviceUpdateReq { + /** + * 主键 + */ + private Long id; + + /** + * 设备名称 + */ + private String name; + + /** + * 父设备ID + */ + private Long parentId; + + /** + * 设备IP + */ + private String ip; + + /** + * 设备端口 + */ + private Long port; + + /** + * 设备MAC + */ + private String mac; + + /** + * 子网掩码 + */ + private String netMask; + + /** + * 设备网关 + */ + private String gatewayIP; + + /** + * 设备产品线类型 + * 0:车行 1:车位 2:人行 + */ + private Integer productType; + + /** + * 设备类型 + * 2201:一体式门禁 2202:分体式门禁 2203:人脸门禁 2204:梯控 2207:人脸盒子终端 + * 2208:人脸盒子面板机 2209:一体式读头 2211:梯控读头 2102:电子哨兵 + */ + private Long type; + + /** + * 业务逻辑设备类 + */ + private Integer logicType; + + /** + * 设备型号 + */ + private Integer model; + + /** + * 设备序列号 + */ + private String sn; + + /** + * 设备CPUID + */ + private String cpuID; + + /** + * 机号 + */ + private String macNo; + + /** + * 蓝牙地址 + */ + private String bluetoothAddr; + + /** + * 设备层级 + */ + private Integer deviceLevel; + + /** + * 设备是否需要系统升级 + */ + private Boolean isNeedUpgrade; + + /** + * 备注 + */ + private String remark; + + /** + * 设备通讯方式 0:TCP/IP 1:RS485 + */ + private Integer commType; + + /** + * 旧IP + */ + private String oldIp; + + /** + * 旧端口号 + */ + private Integer oldPort; + + /** + * 旧机号 + */ + private String oldMacNo; + + /** + * 工单号(设备搜索) + */ + private String projectNumber; + + /** + * 固件版本信息(设备搜索) + */ + private String version; +} diff --git a/ruoyi-modules/Iot/src/main/java/org/dromara/iot/service/e8/model/DoorDevice/res/DoorDeviceAddRes.java b/ruoyi-modules/Iot/src/main/java/org/dromara/iot/service/e8/model/DoorDevice/res/DoorDeviceAddRes.java new file mode 100644 index 00000000..e800ceae --- /dev/null +++ b/ruoyi-modules/Iot/src/main/java/org/dromara/iot/service/e8/model/DoorDevice/res/DoorDeviceAddRes.java @@ -0,0 +1,198 @@ +package org.dromara.iot.service.e8.model.DoorDevice.res; + +import lombok.Data; + +import java.util.List; + +/** + * @author lsm + * @apiNote DoorDeviceAddRes + * @since 2025/6/20 + */ +@Data +public class DoorDeviceAddRes { + /** + * 设备ID + */ + private Long id; + /** + * 创建时间 + */ + private String creationTime; + /** + * 创建者ID + */ + private String creatorId; + /** + * 修改时间 + */ + private String lastModificationTime; + /** + * 修改者ID + */ + private String lastModifierId; + /** + * 是否删除 + */ + private Boolean isDeleted; + /** + * 删除者ID + */ + private String deleterId; + /** + * 删除时间 + */ + private String deletionTime; + /** + * 设备编号 + */ + private String no; + /** + * 设备编号编码 + */ + private Integer noCode; + /** + * cloudId + */ + private String cloudId; + /** + * name + */ + private String name; + /** + * 父级设备名称 + */ + private String parentName; + /** + * 父级设备ID,默认0 + */ + private Integer parentId; + /** + * 管理机IP + */ + private String masterIp; + /** + * 设备IP + */ + private String ip; + /** + * 设备端口 + */ + private Long port; + /** + * 设备MAC + */ + private String mac; + /** + * 子网掩码 + */ + private String netMask; + /** + * 设备网关 + */ + private String gatewayIP; + /** + * 设备产品线类型 0:车行 1:车位 2:人行 + */ + private Integer productType; + /** + * 设备类型 + */ + private Long type; + /** + * 设备类型描述 + */ + private String typeDescription; + /** + * 业务逻辑设备类型 + */ + private Integer logicType; + /** + * 设备型号 + */ + private Integer model; + /** + * 设备型号描述 + */ + private String modelDescription; + /** + * 机号 + */ + private String modelName; + /** + * 设备序列号 + */ + private String sn; + /** + * 设备CPUID + */ + private String cpuID; + /** + * 设备在线状态 0:离线 1:在线 2:未知 + */ + private Integer status; + /** + * 设备在线状态描述 + */ + private String statusDescription; + /** + * 机号 + */ + private String macNo; + /** + * 蓝牙地址 + */ + private String bluetoothAddr; + /** + * 设备层级 + */ + private Integer deviceLevel; + /** + * 父级设备路径 默认空 + */ + private String parentIdPath; + /** + * 是否需要升级 + */ + private Boolean isNeedUpgrade; + /** + * 项目ID + */ + private Integer projectId; + /** + * 创建者 + */ + private String creatorName; + /** + * 关联门 + */ + private String relDoors; + /** + * int32 出入口类型 0:未知 1:入口 2:出口 + */ + private Integer gatewayType; + /** + * 出入口类型 + */ + private String gatewayTypeDesc; + /** + * 备注 + */ + private String remark; + /** + * 设备通讯方式 0:TCP/IP 1:RS485 + */ + private Integer commType; + /** + * 工单号(设备搜索) + */ + private String projectNumber; + /** + * 固件版本信息(设备搜索) + */ + private String version; + /** + * 子设备列表 + */ + private List childList; +} diff --git a/ruoyi-modules/Iot/src/main/java/org/dromara/iot/service/e8/model/DoorDevice/res/DoorDeviceFindRes.java b/ruoyi-modules/Iot/src/main/java/org/dromara/iot/service/e8/model/DoorDevice/res/DoorDeviceFindRes.java new file mode 100644 index 00000000..93db8ebe --- /dev/null +++ b/ruoyi-modules/Iot/src/main/java/org/dromara/iot/service/e8/model/DoorDevice/res/DoorDeviceFindRes.java @@ -0,0 +1,251 @@ +package org.dromara.iot.service.e8.model.DoorDevice.res; + +import lombok.Data; + +import java.util.List; + +/** + * @author lsm + * @apiNote DoorDeviceFindRes + * @since 2025/6/20 + */ +@Data +public class DoorDeviceFindRes { + /** + * 主键 + */ + private Long id; + + /** + * 创建时间 + */ + private String creationTime; + + /** + * 创建人 + */ + private String creatorId; + + /** + * 最后修改时间 + */ + private String lastModificationTime; + + /** + * 最后修改人 + */ + private String lastModifierId; + + /** + * 是否删除 + */ + private Boolean isDeleted; + + /** + * 删除人 + */ + private String deleterId; + + /** + * 删除时间 + */ + private String deletionTime; + + /** + * 设备编号 + */ + private String no; + + /** + * 设备编号序列号 + */ + private Integer noCode; + + /** + * 设备对接平台的ID + */ + private String cloudId; + + /** + * 设备名称 + */ + private String name; + + /** + * 父设备ID + */ + private Long parentId; + + /** + * 父设备名称 + */ + private String parentName; + + /** + * 管理机IP + */ + private String masterIp; + + /** + * 设备IP + */ + private String ip; + + /** + * 设备端口 + */ + private Long port; + + /** + * 设备MAC + */ + private String mac; + + /** + * 子网掩码 + */ + private String netMask; + + /** + * 设备网关 + */ + private String gatewayIP; + + /** + * 设备产品线类型 + * 0:车行 1:车位 2:人行 + */ + private Integer productType; + + /** + * 设备类型 + * 2201:一体式门禁 2202:分体式门禁 2203:人脸门禁 2204:梯控 2207:人脸盒子终端 + * 2208:人脸盒子面板机 2209:一体式读头 2211:梯控读头 2102:电子哨兵 + */ + private Long type; + + /** + * 设备类型描述 + */ + private String typeDescription; + + /** + * 业务逻辑设备类 + */ + private Integer logicType; + + /** + * 设备型号 + */ + private Integer model; + + /** + * 设备型号描述 + */ + private String modelDescription; + + /** + * 设备型号名称 + */ + private String modelName; + + /** + * 设备序列号 + */ + private String sn; + + /** + * 设备CPUID + */ + private String cpuID; + + /** + * 设备在线状态 0:离线 1:在线 2:未知 + */ + private Integer status; + + /** + * 设备在线状态描述 + */ + private String statusDescription; + + /** + * 机号 + */ + private String macNo; + + /** + * 蓝牙地址 + */ + private String bluetoothAddr; + + /** + * 设备层级 + */ + private Integer deviceLevel; + + /** + * 父级设备路径ID列表 + */ + private String parentIdPath; + + /** + * 设备是否需要系统升级 + */ + private Boolean isNeedUpgrade; + + /** + * 项目ID + */ + private Integer projectId; + + /** + * 设备关联的区域组ID + */ + private Integer deviceGroupId; + + /** + * 创建人名称 + */ + private String creatorName; + + /** + * 关联门 + */ + private String relDoors; + + /** + * 出入口类型 0:未知 1:入口 2:出口 + */ + private Integer gatewayType; + + /** + * 出入口类型 + */ + private String gatewayTypeDesc; + + /** + * 备注 + */ + private String remark; + + /** + * 子设备列表 + */ + private List childList; + + /** + * 设备通讯方式 0:TCP/IP 1:RS485 + */ + private Integer commType; + + /** + * 工单号(设备搜索) + */ + private String projectNumber; + + /** + * 固件版本信息(设备搜索) + */ + private String version; +} diff --git a/ruoyi-modules/Iot/src/main/java/org/dromara/iot/service/e8/model/QueryDto.java b/ruoyi-modules/Iot/src/main/java/org/dromara/iot/service/e8/model/QueryDto.java new file mode 100644 index 00000000..1f3fa60d --- /dev/null +++ b/ruoyi-modules/Iot/src/main/java/org/dromara/iot/service/e8/model/QueryDto.java @@ -0,0 +1,26 @@ +package org.dromara.iot.service.e8.model; + +import lombok.Data; + +/** + * @author lsm + * @apiNote QueryDto + * @since 2025/6/20 + */ +@Data +public class QueryDto { + /** + * 页数 + */ + private Integer pageIndex; + + /** + * 每页条数 + */ + private Integer maxResultCount; + + /** + * 请求参数 + */ + private Object queryDto; +} diff --git a/ruoyi-modules/Iot/src/main/java/org/dromara/iot/service/e8/utils/E8ApiUtil.java b/ruoyi-modules/Iot/src/main/java/org/dromara/iot/service/e8/utils/E8ApiUtil.java new file mode 100644 index 00000000..4a660ac7 --- /dev/null +++ b/ruoyi-modules/Iot/src/main/java/org/dromara/iot/service/e8/utils/E8ApiUtil.java @@ -0,0 +1,221 @@ +package org.dromara.iot.service.e8.utils; + +import cn.hutool.crypto.digest.DigestUtil; +import cn.hutool.http.HttpRequest; +import cn.hutool.http.HttpResponse; +import cn.hutool.json.JSONUtil; +import org.dromara.iot.service.e8.model.ApiResp; +import org.springframework.stereotype.Component; +import org.springframework.util.ObjectUtils; + +import java.nio.charset.StandardCharsets; +import java.text.SimpleDateFormat; +import java.util.Base64; +import java.util.Date; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @author lsm + * @apiNote E8ApiUtil + * @since 2025/6/20 + */ +@Component +public class E8ApiUtil { + + private static final String BASE_URL = "http://192.168.8.230:50014"; + private static final String SECRET_KEY = "ZG4ocLq1"; + private static final String KEY = "b97c7090379f490bb4b2ead0f57fd1bf"; + + /** + * 发起Post请求 + * + * @param params 请求入参 + * @param api 请求接口 + * @return 请求结果 + */ + public ApiResp doPost(Map params, String api) { + // 时间戳 + String timestamp = Long.toString(System.currentTimeMillis()); + // sign签名 + String sign = getPostSign(params, api, timestamp); + // url + String url = BASE_URL + api; + + // 将params转换为JSON字符串 + String jsonBody = JSONUtil.toJsonStr(params); + // 对请求体进行Base64加密,指定UTF-8编码,避免乱码 + String base64Body = Base64.getEncoder().encodeToString(jsonBody.getBytes(StandardCharsets.UTF_8)); + + // 发送请求获取响应 + // 使用 try-with-resources 确保资源释放 + try (HttpResponse response = HttpRequest.post(url) + .header("Content-Type", "application/json") + .header("key", KEY) + .header("timestamp", timestamp) + .header("sign", sign) + .body(base64Body) + .execute()) { + + return JSONUtil.toBean(response.body(), ApiResp.class); + } + } + + /** + * 发起Get/Delete请求 + * + * @param api 请求接口 + * @param paramStr 请求入参 + * @return 请求结果 + */ + public ApiResp doGetOrDel(String api, String paramStr, Boolean isDelete) { + // 时间戳 + String timestamp = Long.toString(System.currentTimeMillis()); + // sign签名 + String sign = getGetSign(api, timestamp); + // url + String url = BASE_URL + api; + + if (isDelete) { + // 发送请求获取响应 + // 使用 try-with-resources 确保资源释放 + try (HttpResponse response = HttpRequest.delete(url) + .header("key", KEY) + .header("sign", sign) + .header("timestamp", timestamp) + .header("paramstr", paramStr == null ? "50014" : paramStr).execute()) { + return JSONUtil.toBean(response.body(), ApiResp.class); + } + }else { + // 发送请求获取响应 + // 使用 try-with-resources 确保资源释放 + try (HttpResponse response = HttpRequest.get(url) + .header("key", KEY) + .header("sign", sign) + .header("timestamp", timestamp) + .header("paramstr", paramStr == null ? "50014" : paramStr).execute()) { + return JSONUtil.toBean(response.body(), ApiResp.class); + } + } + } + + /** + * 获取Post接口签名Sign + * + * @param params 请求入参 + * @param api 请求接口 + * @param timestamp 时间戳 + * @return Post接口签名sign + */ + public String getPostSign(Map params, String api, String timestamp) { + String url = BASE_URL + api; + // one&two + String paramsUrl = buildUrlWithParams(url, params) + "×tamp=" + timestamp; + // three + String upperUrl = paramsUrl.toUpperCase(); + // four + String secretUrl = upperUrl + SECRET_KEY; + // five(同时剔除问号) + String md5Url = DigestUtil.md5Hex(secretUrl.replace("?", "")); + // six + return md5Url.toUpperCase(); + } + + /** + * 获取Get接口签名Sign + * + * @param api 请求接口 + * @param timestamp 时间戳 + * @return get/Delete接口签名sign + */ + public String getGetSign(String api, String timestamp) { + // one + String url = BASE_URL + api + timestamp; + String upperUrl = url.toUpperCase(); + // two + String secretUrl = upperUrl + SECRET_KEY; + // three + String md5Url = DigestUtil.md5Hex(secretUrl); + // four + return md5Url.toUpperCase(); + + } + + /** + * Post请求url拼接参数 + * + * @param url 请求链接 + * @param params 请求入参 + * @return 拼接参数后的url + */ + public String buildUrlWithParams(String url, Map params) { + if (params == null || params.isEmpty()) { + return url; + } + + // 过滤出指定类型的参数 + Map filteredParameters = new LinkedHashMap<>(); + for (Map.Entry entry : params.entrySet()) { + Object value = entry.getValue(); + // 判断是否符合拼接类型(int,String,Long,DataTime),并排除空值 + if (isSupportedType(value) && !ObjectUtils.isEmpty(value)) { + filteredParameters.put(entry.getKey(), value); + } + } + + if (filteredParameters.isEmpty()) { + return url; + } + + // 使用 Stream API 对 filteredParameters 按 key 升序排序 + Map sortedParameters = filteredParameters.entrySet() + .stream() + .sorted(Map.Entry.comparingByKey()) + .collect(Collectors.toMap( + Map.Entry::getKey, + Map.Entry::getValue, + (oldValue, newValue) -> oldValue, // 处理键冲突的情况 + LinkedHashMap::new // 保持插入顺序 + )); + + StringBuilder sb = new StringBuilder(url); + if (!url.contains("?")) { + sb.append("?"); + } else { + // 如果 URL 中已有查询参数,确保拼接时参数之间用 & 分隔 + sb.append("&"); + } + + for (Map.Entry entry : sortedParameters.entrySet()) { + String key = entry.getKey(); + Object value = entry.getValue(); + + // 将日期格式化为字符串 + if (value instanceof Date) { + value = new SimpleDateFormat("yyyy-MM-dd").format(value); + } + + sb.append(key) + .append("=") + .append(value.toString()) + .append("&"); + } + + // 去掉最后的多余 & 符号 + sb.setLength(sb.length() - 1); + + return sb.toString(); + } + + /** + * 判断类型是否符合 + * + * @return Boolean + */ + public Boolean isSupportedType(Object value) { + return value instanceof Integer || value instanceof String || value instanceof Long || value instanceof Date; + } + + +} diff --git a/ruoyi-modules/Iot/src/main/java/org/dromara/iot/service/impl/TbAccessControlServiceImpl.java b/ruoyi-modules/Iot/src/main/java/org/dromara/iot/service/impl/TbAccessControlServiceImpl.java index 9ae63216..e5bc13f8 100644 --- a/ruoyi-modules/Iot/src/main/java/org/dromara/iot/service/impl/TbAccessControlServiceImpl.java +++ b/ruoyi-modules/Iot/src/main/java/org/dromara/iot/service/impl/TbAccessControlServiceImpl.java @@ -9,6 +9,9 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.dromara.iot.service.e8.api.base.DoorDeviceService; +import org.dromara.iot.service.e8.model.DoorDevice.req.DoorDeviceAddReq; +import org.dromara.iot.service.e8.model.DoorDevice.res.DoorDeviceAddRes; import org.springframework.stereotype.Service; import org.dromara.iot.domain.bo.TbAccessControlBo; import org.dromara.iot.domain.vo.TbAccessControlVo; @@ -24,7 +27,7 @@ import java.util.Collection; * 门禁管理Service业务层处理 * * @author mocheng - * @date 2025-06-17 + * @since 2025-06-17 */ @Slf4j @RequiredArgsConstructor @@ -32,6 +35,7 @@ import java.util.Collection; public class TbAccessControlServiceImpl implements ITbAccessControlService { private final TbAccessControlMapper baseMapper; + private final DoorDeviceService doorDeviceService; /** * 查询门禁管理 @@ -40,7 +44,7 @@ public class TbAccessControlServiceImpl implements ITbAccessControlService { * @return 门禁管理 */ @Override - public TbAccessControlVo queryById(Long id){ + public TbAccessControlVo queryById(Long id) { return baseMapper.selectVoById(id); } @@ -99,6 +103,22 @@ public class TbAccessControlServiceImpl implements ITbAccessControlService { @Override public Boolean insertByBo(TbAccessControlBo bo) { TbAccessControl add = MapstructUtils.convert(bo, TbAccessControl.class); + + // 添加E8门禁设备 + if (add.getControlType() == 2L){ + DoorDeviceAddReq e8DoorReq = new DoorDeviceAddReq(); + e8DoorReq.setIp(add.getAccessIp()); + e8DoorReq.setType(add.getAccssType()); + e8DoorReq.setPort(add.getAccessPort()); + e8DoorReq.setName(add.getAccessName()); + DoorDeviceAddRes e8DoorRes = doorDeviceService.addDoorDevice(e8DoorReq); + if (e8DoorRes != null) { + add.setOutCode(e8DoorRes.getId().toString()); + } else { + return false; + } + } + validEntityBeforeSave(add); boolean flag = baseMapper.insert(add) > 0; if (flag) { @@ -123,7 +143,7 @@ public class TbAccessControlServiceImpl implements ITbAccessControlService { /** * 保存前的数据校验 */ - private void validEntityBeforeSave(TbAccessControl entity){ + private void validEntityBeforeSave(TbAccessControl entity) { //TODO 做一些数据校验,如唯一约束 } @@ -136,7 +156,7 @@ public class TbAccessControlServiceImpl implements ITbAccessControlService { */ @Override public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { - if(isValid){ + if (isValid) { //TODO 做一些业务上的校验,判断是否需要校验 } return baseMapper.deleteByIds(ids) > 0; From 71a351c14cb38f387668ae20911e2bd8b06bae7d Mon Sep 17 00:00:00 2001 From: zcxlsm Date: Fri, 20 Jun 2025 17:50:04 +0800 Subject: [PATCH 4/4] =?UTF-8?q?feat(iot):=20=E6=B7=BB=E5=8A=A0=20E8?= =?UTF-8?q?=E9=97=A8=E7=A6=81=E8=AE=BE=E5=A4=87=E7=AE=A1=E7=90=86=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 E8 门禁设备相关的数据模型和接口 - 实现 E8 门禁设备的添加、查询、修改和删除功能- 在门禁管理服务中集成 E8 门禁设备的添加逻辑 --- .../dromara/iot/service/impl/TbAccessControlServiceImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ruoyi-modules/Iot/src/main/java/org/dromara/iot/service/impl/TbAccessControlServiceImpl.java b/ruoyi-modules/Iot/src/main/java/org/dromara/iot/service/impl/TbAccessControlServiceImpl.java index e5bc13f8..8576bf5e 100644 --- a/ruoyi-modules/Iot/src/main/java/org/dromara/iot/service/impl/TbAccessControlServiceImpl.java +++ b/ruoyi-modules/Iot/src/main/java/org/dromara/iot/service/impl/TbAccessControlServiceImpl.java @@ -84,7 +84,7 @@ public class TbAccessControlServiceImpl implements ITbAccessControlService { lqw.eq(StringUtils.isNotBlank(bo.getBuildingCode()), TbAccessControl::getBuildingCode, bo.getBuildingCode()); lqw.eq(StringUtils.isNotBlank(bo.getAccessIp()), TbAccessControl::getAccessIp, bo.getAccessIp()); lqw.eq(bo.getAccessPort() != null, TbAccessControl::getAccessPort, bo.getAccessPort()); - lqw.eq(bo.getAccssType() != null, TbAccessControl::getAccssType, bo.getAccssType()); + lqw.eq(bo.getAccssType() != null, TbAccessControl::getAccessType, bo.getAccssType()); lqw.eq(StringUtils.isNotBlank(bo.getFactoryCode()), TbAccessControl::getFactoryCode, bo.getFactoryCode()); lqw.eq(bo.getControlType() != null, TbAccessControl::getControlType, bo.getControlType()); lqw.eq(StringUtils.isNotBlank(bo.getControlCode()), TbAccessControl::getControlCode, bo.getControlCode()); @@ -108,7 +108,7 @@ public class TbAccessControlServiceImpl implements ITbAccessControlService { if (add.getControlType() == 2L){ DoorDeviceAddReq e8DoorReq = new DoorDeviceAddReq(); e8DoorReq.setIp(add.getAccessIp()); - e8DoorReq.setType(add.getAccssType()); + e8DoorReq.setType(add.getAccessType()); e8DoorReq.setPort(add.getAccessPort()); e8DoorReq.setName(add.getAccessName()); DoorDeviceAddRes e8DoorRes = doorDeviceService.addDoorDevice(e8DoorReq);