增加宇视AI盒子对接服务
Some checks failed
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 7m18s

iot模块修改为智能安防模块
This commit is contained in:
lxj
2025-06-24 21:09:01 +08:00
parent eff9a0fbaa
commit d4927d2699
69 changed files with 1823 additions and 25 deletions

View File

@@ -0,0 +1,27 @@
# 贝尔实验室 Spring 官方推荐镜像 JDK下载地址 https://bell-sw.com/pages/downloads/
FROM bellsoft/liberica-openjdk-debian:17.0.11-cds
#FROM bellsoft/liberica-openjdk-debian:21.0.5-cds
#FROM findepi/graalvm:java17-native
LABEL maintainer="Lxj"
RUN mkdir -p /smartparks/Sis/logs \
/smartparks/Sis/temp \
/smartparks/Sis/agent
WORKDIR /ruoyi/system
ENV SERVER_PORT=9201 LANG=C.UTF-8 LC_ALL=C.UTF-8 JAVA_OPTS=""
EXPOSE ${SERVER_PORT}
ADD ./target/Sis.jar ./app.jar
SHELL ["/bin/bash", "-c"]
ENTRYPOINT java -Djava.security.egd=file:/dev/./urandom -Dserver.port=${SERVER_PORT} \
#-Dskywalking.agent.service_name=ruoyi-system \
#-javaagent:/ruoyi/skywalking/agent/skywalking-agent.jar \
-XX:+HeapDumpOnOutOfMemoryError -XX:+UseZGC ${JAVA_OPTS} \
-jar app.jar

130
ruoyi-modules/Sis/pom.xml Normal file
View File

@@ -0,0 +1,130 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-modules</artifactId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>Sis</artifactId>
<description>Smart Intelligent Security 智能安防管理系统</description>
<dependencies>
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-nacos</artifactId>
</dependency>
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-sentinel</artifactId>
</dependency>
<!-- RuoYi Common Log -->
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-log</artifactId>
</dependency>
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-service-impl</artifactId>
</dependency>
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-doc</artifactId>
</dependency>
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-web</artifactId>
</dependency>
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-mybatis</artifactId>
</dependency>
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-dubbo</artifactId>
</dependency>
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-seata</artifactId>
</dependency>
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-idempotent</artifactId>
</dependency>
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-tenant</artifactId>
</dependency>
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-security</artifactId>
</dependency>
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-translation</artifactId>
</dependency>
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-sensitive</artifactId>
</dependency>
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-encrypt</artifactId>
</dependency>
<!-- RuoYi Api System -->
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-api-system</artifactId>
</dependency>
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-api-resource</artifactId>
</dependency>
<!-- RuoYi Api System -->
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-api-workflow</artifactId>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,22 @@
package org.dromara.iot;
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.metrics.buffering.BufferingApplicationStartup;
/**
* 物业模块
*
* @author ruoyi
*/
@EnableDubbo
@SpringBootApplication
public class IotyApplication {
public static void main(String[] args) {
SpringApplication application = new SpringApplication(IotyApplication.class);
application.setApplicationStartup(new BufferingApplicationStartup(2048));
application.run(args);
System.out.println("(♥◠‿◠)ノ゙ 设备模块启动成功 ლ(´ڡ`ლ)゙ ");
}
}

View File

@@ -0,0 +1,107 @@
package org.dromara.iot.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
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.excel.utils.ExcelUtil;
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.TbAccessControlBo;
import org.dromara.iot.domain.vo.TbAccessControlVo;
import org.dromara.iot.service.ITbAccessControlService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 门禁管理
* 前端访问路由地址为:/iot/accessControl
*
* @author lxj
* @date 2025-06-17
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/accessControl")
public class TbAccessControlController extends BaseController {
private final ITbAccessControlService tbAccessControlService;
/**
* 查询门禁管理列表
*/
@SaCheckPermission("property:accessControl:list")
@GetMapping("/list")
public TableDataInfo<TbAccessControlVo> list(TbAccessControlBo bo, PageQuery pageQuery) {
return tbAccessControlService.queryPageList(bo, pageQuery);
}
/**
* 导出门禁管理列表
*/
@SaCheckPermission("property:accessControl:export")
@Log(title = "门禁管理", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(TbAccessControlBo bo, HttpServletResponse response) {
List<TbAccessControlVo> list = tbAccessControlService.queryList(bo);
ExcelUtil.exportExcel(list, "门禁管理", TbAccessControlVo.class, response);
}
/**
* 获取门禁管理详细信息
*
* @param id 主键
*/
@SaCheckPermission("property:accessControl:query")
@GetMapping("/{id}")
public R<TbAccessControlVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable("id") Long id) {
return R.ok(tbAccessControlService.queryById(id));
}
/**
* 新增门禁管理
*/
@SaCheckPermission("property:accessControl:add")
@Log(title = "门禁管理", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody TbAccessControlBo bo) {
return toAjax(tbAccessControlService.insertByBo(bo));
}
/**
* 修改门禁管理
*/
@SaCheckPermission("property:accessControl:edit")
@Log(title = "门禁管理", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody TbAccessControlBo bo) {
return toAjax(tbAccessControlService.updateByBo(bo));
}
/**
* 删除门禁管理
*
* @param ids 主键串
*/
@SaCheckPermission("property:accessControl:remove")
@Log(title = "门禁管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable("ids") Long[] ids) {
return toAjax(tbAccessControlService.deleteWithValidByIds(List.of(ids), true));
}
}

View File

@@ -0,0 +1,106 @@
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 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.TdFactoryVo;
import org.dromara.iot.domain.bo.TdFactoryBo;
import org.dromara.iot.service.ITdFactoryService;
import org.dromara.common.mybatis.core.page.TableDataInfo;
/**
* 厂商管理
* 前端访问路由地址为:/iot/factory
*
* @author lxj
* @date 2025-06-17
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/factory")
public class TdFactoryController extends BaseController {
private final ITdFactoryService tdFactoryService;
/**
* 查询厂商管理列表
*/
@SaCheckPermission("property:factory:list")
@GetMapping("/list")
public TableDataInfo<TdFactoryVo> list(TdFactoryBo bo, PageQuery pageQuery) {
return tdFactoryService.queryPageList(bo, pageQuery);
}
/**
* 导出厂商管理列表
*/
@SaCheckPermission("property:factory:export")
@Log(title = "厂商管理", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(TdFactoryBo bo, HttpServletResponse response) {
List<TdFactoryVo> list = tdFactoryService.queryList(bo);
ExcelUtil.exportExcel(list, "厂商管理", TdFactoryVo.class, response);
}
/**
* 获取厂商管理详细信息
*
* @param id 主键
*/
@SaCheckPermission("property:factory:query")
@GetMapping("/{id}")
public R<TdFactoryVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable("id") Long id) {
return R.ok(tdFactoryService.queryById(id));
}
/**
* 新增厂商管理
*/
@SaCheckPermission("property:factory:add")
@Log(title = "厂商管理", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody TdFactoryBo bo) {
return toAjax(tdFactoryService.insertByBo(bo));
}
/**
* 修改厂商管理
*/
@SaCheckPermission("property:factory:edit")
@Log(title = "厂商管理", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody TdFactoryBo bo) {
return toAjax(tdFactoryService.updateByBo(bo));
}
/**
* 删除厂商管理
*
* @param ids 主键串
*/
@SaCheckPermission("property:factory:remove")
@Log(title = "厂商管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable("ids") Long[] ids) {
return toAjax(tdFactoryService.deleteWithValidByIds(List.of(ids), true));
}
}

View File

@@ -0,0 +1,106 @@
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 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.TdMeterConfigVo;
import org.dromara.iot.domain.bo.TdMeterConfigBo;
import org.dromara.iot.service.ITdMeterConfigService;
import org.dromara.common.mybatis.core.page.TableDataInfo;
/**
* 水电气配置
* 前端访问路由地址为:/iot/meterConfig
*
* @author lxj
* @date 2025-06-18
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/meterConfig")
public class TdMeterConfigController extends BaseController {
private final ITdMeterConfigService tdMeterConfigService;
/**
* 查询水电气配置列表
*/
@SaCheckPermission("system:meterConfig:list")
@GetMapping("/list")
public TableDataInfo<TdMeterConfigVo> list(TdMeterConfigBo bo, PageQuery pageQuery) {
return tdMeterConfigService.queryPageList(bo, pageQuery);
}
/**
* 导出水电气配置列表
*/
@SaCheckPermission("system:meterConfig:export")
@Log(title = "水电气配置", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(TdMeterConfigBo bo, HttpServletResponse response) {
List<TdMeterConfigVo> list = tdMeterConfigService.queryList(bo);
ExcelUtil.exportExcel(list, "水电气配置", TdMeterConfigVo.class, response);
}
/**
* 获取水电气配置详细信息
*
* @param id 主键
*/
@SaCheckPermission("system:meterConfig:query")
@GetMapping("/{id}")
public R<TdMeterConfigVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable("id") Long id) {
return R.ok(tdMeterConfigService.queryById(id));
}
/**
* 新增水电气配置
*/
@SaCheckPermission("system:meterConfig:add")
@Log(title = "水电气配置", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody TdMeterConfigBo bo) {
return toAjax(tdMeterConfigService.insertByBo(bo));
}
/**
* 修改水电气配置
*/
@SaCheckPermission("system:meterConfig:edit")
@Log(title = "水电气配置", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody TdMeterConfigBo bo) {
return toAjax(tdMeterConfigService.updateByBo(bo));
}
/**
* 删除水电气配置
*
* @param ids 主键串
*/
@SaCheckPermission("system:meterConfig:remove")
@Log(title = "水电气配置", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable("ids") Long[] ids) {
return toAjax(tdMeterConfigService.deleteWithValidByIds(List.of(ids), true));
}
}

View File

@@ -0,0 +1,121 @@
package org.dromara.iot.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
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.excel.utils.ExcelUtil;
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;
/**
* 水电气
* 前端访问路由地址为:/iot/meter
*
* @author LionLi
* @date 2025-06-19
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/meter")
public class TdMeterController extends BaseController {
private final ITdMeterService tdMeterService;
/**
* 查询水电气列表
*/
@SaCheckPermission("iot:meter:list")
@GetMapping("/list")
public TableDataInfo<TdMeterVo> 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<Boolean> operate(@PathVariable("meterId") Long meterId, @PathVariable("onOff") Integer onOff) {
return R.ok(tdMeterService.operate(meterId, onOff));
}
/**
* 导出水电气列表
*/
@SaCheckPermission("iot:meter:export")
@Log(title = "导出智能表信息", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(TdMeterBo bo, HttpServletResponse response) {
List<TdMeterVo> list = tdMeterService.queryList(bo);
ExcelUtil.exportExcel(list, "水电气", TdMeterVo.class, response);
}
/**
* 获取水电气详细信息
*
* @param id 主键
*/
@SaCheckPermission("iot:meter:query")
@GetMapping("/{id}")
public R<TdMeterVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable("id") Long id) {
return R.ok(tdMeterService.queryById(id));
}
/**
* 新增水电气
*/
@SaCheckPermission("iot:meter:add")
@Log(title = "添加智能表信息", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody TdMeterBo bo) {
return toAjax(tdMeterService.insertByBo(bo));
}
/**
* 修改水电气
*/
@SaCheckPermission("iot:meter:edit")
@Log(title = "修改智能表信息", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody TdMeterBo bo) {
return toAjax(tdMeterService.updateByBo(bo));
}
/**
* 删除水电气
*
* @param ids 主键串
*/
@SaCheckPermission("iot:meter:remove")
@Log(title = "删除智能表信息", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable("ids") Long[] ids) {
return toAjax(tdMeterService.deleteWithValidByIds(List.of(ids), true));
}
}

View File

@@ -0,0 +1,106 @@
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 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.TdMeterRoomVo;
import org.dromara.iot.domain.bo.TdMeterRoomBo;
import org.dromara.iot.service.ITdMeterRoomService;
import org.dromara.common.mybatis.core.page.TableDataInfo;
/**
* 和房间的关联
* 前端访问路由地址为:/iot/meterRoom
*
* @author lxj
* @date 2025-06-18
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/meterRoom")
public class TdMeterRoomController extends BaseController {
private final ITdMeterRoomService tdMeterRoomService;
/**
* 查询和房间的关联列表
*/
@SaCheckPermission("system:meterRoom:list")
@GetMapping("/list")
public TableDataInfo<TdMeterRoomVo> list(TdMeterRoomBo bo, PageQuery pageQuery) {
return tdMeterRoomService.queryPageList(bo, pageQuery);
}
/**
* 导出和房间的关联列表
*/
@SaCheckPermission("system:meterRoom:export")
@Log(title = "和房间的关联", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(TdMeterRoomBo bo, HttpServletResponse response) {
List<TdMeterRoomVo> list = tdMeterRoomService.queryList(bo);
ExcelUtil.exportExcel(list, "和房间的关联", TdMeterRoomVo.class, response);
}
/**
* 获取和房间的关联详细信息
*
* @param id 主键
*/
@SaCheckPermission("system:meterRoom:query")
@GetMapping("/{id}")
public R<TdMeterRoomVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable("id") Long id) {
return R.ok(tdMeterRoomService.queryById(id));
}
/**
* 新增和房间的关联
*/
@SaCheckPermission("system:meterRoom:add")
@Log(title = "和房间的关联", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody TdMeterRoomBo bo) {
return toAjax(tdMeterRoomService.insertByBo(bo));
}
/**
* 修改和房间的关联
*/
@SaCheckPermission("system:meterRoom:edit")
@Log(title = "和房间的关联", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody TdMeterRoomBo bo) {
return toAjax(tdMeterRoomService.updateByBo(bo));
}
/**
* 删除和房间的关联
*
* @param ids 主键串
*/
@SaCheckPermission("system:meterRoom:remove")
@Log(title = "和房间的关联", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable("ids") Long[] ids) {
return toAjax(tdMeterRoomService.deleteWithValidByIds(List.of(ids), true));
}
}

View File

@@ -0,0 +1,107 @@
package org.dromara.iot.domain;
import org.dromara.common.mybatis.core.domain.BaseEntity;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.Date;
import java.io.Serial;
/**
* 门禁管理对象 tb_access_control
*
* @author mocheng
* @since 2025-06-17
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("tb_access_control")
public class TbAccessControl extends BaseEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* id
*/
@TableId(value = "id")
private Long id;
/**
* 门禁设备编码
*/
private String accessCode;
/**
* 门禁名称
*/
private String accessName;
/**
* 园区编码
*/
private String communityCode;
/**
* 建筑编码
*/
private String buildingCode;
/**
* 门禁设备ip
*/
private String accessIp;
/**
* 设备端口
*/
private Long accessPort;
/**
* 门禁设备类型
*/
private Long accessType;
/**
* 工程编号
*/
private String factoryCode;
/**
* 控制卡类型1-系统2-E8
*/
private Long controlType;
/**
* 控制卡类型编码
*/
private String controlCode;
/**
* 外部编码
*/
private String outCode;
/**
* 组织编码
*/
private String orgCode;
/**
* 数据状态1有效0无效
*/
private Long dataState;
/**
* 创建人
*/
private Long createEmpId;
/**
* 修改时间
*/
private Date modifyTime;
}

View File

@@ -0,0 +1,58 @@
package org.dromara.iot.domain;
import org.dromara.common.mybatis.core.domain.BaseEntity;
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;
/**
* 厂商管理对象 td_factory
*
* @author mocheng
* @date 2025-06-17
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("td_factory")
public class TdFactory extends BaseEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* 数据库id
*/
@TableId(value = "id")
private Long id;
/**
* 厂商编码
*/
private String factoryNo;
/**
* 设备厂商名称
*/
private String factoryName;
/**
* 备注
*/
private String remark;
/**
* 数据状态1有效0无效
*/
private Long dataState;
/**
* 修改时间
*/
private Date modifyTime;
}

View File

@@ -0,0 +1,107 @@
package org.dromara.iot.domain;
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
*
* @author LionLi
* @date 2025-06-19
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("td_meter")
public class TdMeter extends BaseEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键id
*/
@TableId(value = "id")
private Long id;
/**
* 水表名称
*/
private String meterName;
/**
* 设备编码
*/
private String meterCode;
/**
* 设备厂商
*/
private String factoryNo;
/**
* 设备类型(1-电表2-水表3-气表)
*/
private Long meterType;
/**
* 表用途(1-分表2-总表3-公摊表)
*/
private Long meterPurpose;
/**
* 分摊类型
* 1-不公摊
* 2-按分表用量
* 3-按租客面积
* 4-按房源数量
* 5-按固定比例
*/
private Long shareType;
/**
* 付费类型(1-先付费2-后付费)
*/
private Long payType;
/**
* 当前表显示读数
*/
private Long display;
/**
* 最大表显读数(超过归0)
*/
private Long maxDisplay;
/**
* 计费倍率
*/
private Float billingRate;
/**
* 剩余量
*/
private Long surplus;
/**
* 通信状态
*/
private Long communicationState;
/**
* 运行状态
*/
private Long runningState;
/**
* 备注
*/
private String remark;
}

View File

@@ -0,0 +1,61 @@
package org.dromara.iot.domain;
import org.dromara.common.mybatis.core.domain.BaseEntity;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serial;
/**
* 水电气配置对象 td_meter_config
*
* @author LionLi
* @date 2025-06-18
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("td_meter_config")
public class TdMeterConfig extends BaseEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键id
*/
@TableId(value = "id")
private Long id;
/**
* 设备类型(1-电表2-水表3-气表)
*/
private Long meterType;
/**
* 付费类型(1-先付费2-后付费)
*/
private Long payType;
/**
* 欠费是否断电/水/气(0-是1-否)
*/
private Long arrearsOutage;
/**
* 后付费模式下是否自动断电/水/气0-是1-否)
*/
private Long autoOutage;
/**
* 当auto_outage=0的时候生效逾期多少天自动断水/电/气
*/
private Long overdueDay;
/**
* 备注
*/
private String remark;
}

View File

@@ -0,0 +1,46 @@
package org.dromara.iot.domain;
import org.dromara.common.mybatis.core.domain.BaseEntity;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serial;
/**
* 和房间的关联对象 td_meter_room
*
* @author LionLi
* @date 2025-06-18
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("td_meter_room")
public class TdMeterRoom extends BaseEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键id
*/
@TableId(value = "id")
private Long id;
/**
* 表id
*/
private Long meterId;
/**
* 房间id
*/
private Long roomId;
/**
* 备注
*/
private String remark;
}

View File

@@ -0,0 +1,104 @@
package org.dromara.iot.domain.bo;
import io.github.linpeilie.annotations.AutoMapper;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import lombok.EqualsAndHashCode;
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.iot.domain.TbAccessControl;
/**
* 门禁管理业务对象 tb_access_control
*
* @author lxj
* @date 2025-06-17
*/
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = TbAccessControl.class, reverseConvertGenerate = false)
public class TbAccessControlBo extends BaseEntity {
/**
* id
*/
private Long id;
/**
* 门禁设备编码
*/
@NotBlank(message = "门禁设备编码不能为空", groups = {AddGroup.class, EditGroup.class})
private String accessCode;
/**
* 门禁名称
*/
@NotBlank(message = "门禁名称不能为空", groups = {AddGroup.class, EditGroup.class})
private String accessName;
/**
* 园区编码
*/
@NotBlank(message = "园区编码不能为空", groups = {AddGroup.class, EditGroup.class})
private String communityCode;
/**
* 建筑编码
*/
@NotBlank(message = "建筑编码不能为空", groups = {AddGroup.class, EditGroup.class})
private String buildingCode;
/**
* 门禁设备ip
*/
private String accessIp;
/**
* 设备端口
*/
private Long accessPort;
/**
* 门禁设备类型
*/
@NotNull(message = "门禁设备类型不能为空", groups = {AddGroup.class, EditGroup.class})
private Long accssType;
/**
* 工程编号
*/
@NotBlank(message = "工程编号不能为空", groups = {AddGroup.class, EditGroup.class})
private String factoryCode;
/**
* 控制卡类型1-系统2-E8
*/
@NotNull(message = "控制卡类型1-系统2-E8不能为空", groups = {AddGroup.class, EditGroup.class})
private Long controlType;
/**
* 控制卡类型编码
*/
private String controlCode;
/**
* 外部编码
*/
private String outCode;
/**
* 组织编码
*/
@NotBlank(message = "组织编码不能为空", groups = {AddGroup.class, EditGroup.class})
private String orgCode;
/**
* 数据状态1有效0无效
*/
@NotNull(message = "数据状态1有效0无效不能为空", groups = {AddGroup.class, EditGroup.class})
private Long dataState;
}

View File

@@ -0,0 +1,54 @@
package org.dromara.iot.domain.bo;
import io.github.linpeilie.annotations.AutoMapper;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import lombok.EqualsAndHashCode;
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.iot.domain.TdFactory;
/**
* 厂商管理业务对象 td_factory
*
* @author lxj
* @date 2025-06-17
*/
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = TdFactory.class, reverseConvertGenerate = false)
public class TdFactoryBo extends BaseEntity {
/**
* 数据库id
*/
@NotNull(message = "数据库id不能为空", groups = {EditGroup.class})
private Long id;
/**
* 厂商编码
*/
@NotBlank(message = "厂商编码不能为空", groups = {AddGroup.class, EditGroup.class})
private String factoryNo;
/**
* 设备厂商名称
*/
@NotBlank(message = "设备厂商名称不能为空", groups = {AddGroup.class, EditGroup.class})
private String factoryName;
/**
* 备注
*/
private String remark;
/**
* 数据状态1有效0无效
*/
@NotNull(message = "数据状态1有效0无效不能为空", groups = {AddGroup.class, EditGroup.class})
private Long dataState;
}

View File

@@ -0,0 +1,96 @@
package org.dromara.iot.domain.bo;
import io.github.linpeilie.annotations.AutoMapper;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import lombok.EqualsAndHashCode;
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.iot.domain.TdMeter;
import java.util.List;
/**
* 水电气业务对象 td_meter
*
* @author LionLi
* @date 2025-06-19
*/
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = TdMeter.class, reverseConvertGenerate = false)
public class TdMeterBo extends BaseEntity {
/**
* 主键id
*/
@NotNull(message = "主键id不能为空", groups = {EditGroup.class})
private Long id;
/**
* 水表名称
*/
@NotBlank(message = "水表名称不能为空", groups = {AddGroup.class, EditGroup.class})
private String meterName;
/**
* 设备编码
*/
private String meterCode;
/**
* 设备厂商
*/
@NotBlank(message = "设备厂商不能为空", groups = {AddGroup.class, EditGroup.class})
private String factoryNo;
/**
* 设备类型(1-电表2-水表3-气表)
*/
private Long meterType;
/**
* 表用途(1-分表2-总表3-公摊表)
*/
private Long meterPurpose;
/**
* 分摊类型
* 1-不公摊
* 2-按分表用量
* 3-按租客面积
* 4-按房源数量
* 5-按固定比例
*/
private Long shareType;
/**
* 付费类型(1-先付费2-后付费)
*/
private Long payType;
/**
* 最大表显读数(超过归0)
*/
private Long maxDisplay;
/**
* 计费倍率
*/
private Float billingRate;
/**
* 备注
*/
private String remark;
/**
* 设备厂商
*/
@NotBlank(message = "表绑定的房间不能为空", groups = {AddGroup.class})
private List<Long> roomIds;
}

View File

@@ -0,0 +1,64 @@
package org.dromara.iot.domain.bo;
import org.dromara.iot.domain.TdMeterConfig;
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 lombok.Data;
import lombok.EqualsAndHashCode;
import jakarta.validation.constraints.*;
/**
* 水电气配置业务对象 td_meter_config
*
* @author lxj
* @date 2025-06-18
*/
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = TdMeterConfig.class, reverseConvertGenerate = false)
public class TdMeterConfigBo extends BaseEntity {
/**
* 主键id
*/
@NotNull(message = "主键id不能为空", groups = { EditGroup.class })
private Long id;
/**
* 设备类型(1-电表2-水表3-气表)
*/
private Long meterType;
/**
* 付费类型(1-先付费2-后付费)
*/
@NotNull(message = "付费类型(1-先付费2-后付费)不能为空", groups = { AddGroup.class, EditGroup.class })
private Long payType;
/**
* 欠费是否断电/水/气(0-是1-否)
*/
@NotNull(message = "欠费是否断电/水/气(0-是1-否)不能为空", groups = { AddGroup.class, EditGroup.class })
private Long arrearsOutage;
/**
* 后付费模式下是否自动断电/水/气0-是1-否)
*/
@NotNull(message = "后付费模式下是否自动断电/水/气0-是1-否)不能为空", groups = { AddGroup.class, EditGroup.class })
private Long autoOutage;
/**
* 当auto_outage=0的时候生效逾期多少天自动断水/电/气
*/
@NotNull(message = "当auto_outage=0的时候生效逾期多少天自动断水/电/气不能为空", groups = { AddGroup.class, EditGroup.class })
private Long overdueDay;
/**
* 备注
*/
private String remark;
}

View File

@@ -0,0 +1,47 @@
package org.dromara.iot.domain.bo;
import org.dromara.iot.domain.TdMeterRoom;
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 lombok.Data;
import lombok.EqualsAndHashCode;
import jakarta.validation.constraints.*;
/**
* 和房间的关联业务对象 td_meter_room
*
* @author lxj
* @date 2025-06-18
*/
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = TdMeterRoom.class, reverseConvertGenerate = false)
public class TdMeterRoomBo extends BaseEntity {
/**
* 主键id
*/
@NotNull(message = "主键id不能为空", groups = { EditGroup.class })
private Long id;
/**
* 表id
*/
@NotNull(message = "表id不能为空", groups = { AddGroup.class, EditGroup.class })
private Long meterId;
/**
* 房间id
*/
@NotNull(message = "房间id不能为空", groups = { AddGroup.class, EditGroup.class })
private Long roomId;
/**
* 备注
*/
private String remark;
}

View File

@@ -0,0 +1,112 @@
package org.dromara.iot.domain.vo;
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import cn.idev.excel.annotation.ExcelProperty;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import org.dromara.iot.domain.TbAccessControl;
import java.io.Serial;
import java.io.Serializable;
/**
* 门禁管理视图对象 tb_access_control
*
* @author lxj
* @date 2025-06-17
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = TbAccessControl.class)
public class TbAccessControlVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* id
*/
@ExcelProperty(value = "id")
private Long id;
/**
* 门禁设备编码
*/
@ExcelProperty(value = "门禁设备编码")
private String accessCode;
/**
* 门禁名称
*/
@ExcelProperty(value = "门禁名称")
private String accessName;
/**
* 园区编码
*/
@ExcelProperty(value = "园区编码")
private String communityCode;
/**
* 建筑编码
*/
@ExcelProperty(value = "建筑编码")
private String buildingCode;
/**
* 门禁设备ip
*/
@ExcelProperty(value = "门禁设备ip")
private String accessIp;
/**
* 设备端口
*/
@ExcelProperty(value = "设备端口")
private Long accessPort;
/**
* 门禁设备类型
*/
@ExcelProperty(value = "门禁设备类型")
private Long accssType;
/**
* 工程编号
*/
@ExcelProperty(value = "工程编号")
private String factoryCode;
/**
* 控制卡类型1-系统2-E8
*/
@ExcelProperty(value = "控制卡类型1-系统2-E8")
private Long controlType;
/**
* 控制卡类型编码
*/
@ExcelProperty(value = "控制卡类型编码")
private String controlCode;
/**
* 外部编码
*/
@ExcelProperty(value = "外部编码")
private String outCode;
/**
* 组织编码
*/
@ExcelProperty(value = "组织编码")
private String orgCode;
/**
* 数据状态1有效0无效
*/
@ExcelProperty(value = "数据状态1有效0无效")
private Long dataState;
}

View File

@@ -0,0 +1,58 @@
package org.dromara.iot.domain.vo;
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import cn.idev.excel.annotation.ExcelProperty;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import org.dromara.iot.domain.TdFactory;
import java.io.Serial;
import java.io.Serializable;
/**
* 厂商管理视图对象 td_factory
*
* @author lxj
* @date 2025-06-17
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = TdFactory.class)
public class TdFactoryVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 数据库id
*/
@ExcelProperty(value = "数据库id")
private Long id;
/**
* 厂商编码
*/
@ExcelProperty(value = "厂商编码")
private String factoryNo;
/**
* 设备厂商名称
*/
@ExcelProperty(value = "设备厂商名称")
private String factoryName;
/**
* 备注
*/
@ExcelProperty(value = "备注")
private String remark;
/**
* 数据状态1有效0无效
*/
@ExcelProperty(value = "数据状态1有效0无效")
private Long dataState;
}

View File

@@ -0,0 +1,73 @@
package org.dromara.iot.domain.vo;
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import cn.idev.excel.annotation.ExcelProperty;
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.iot.domain.TdMeterConfig;
import java.io.Serial;
import java.io.Serializable;
/**
* 水电气配置视图对象 td_meter_config
*
* @author lxj
* @date 2025-06-18
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = TdMeterConfig.class)
public class TdMeterConfigVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键id
*/
@ExcelProperty(value = "主键id")
private Long id;
/**
* 设备类型(1-电表2-水表3-气表)
*/
@ExcelProperty(value = "设备类型(1-电表2-水表3-气表)")
private Long meterType;
/**
* 付费类型(1-先付费2-后付费)
*/
@ExcelProperty(value = "付费类型(1-先付费2-后付费)")
private Long payType;
/**
* 欠费是否断电/水/气(0-是1-否)
*/
@ExcelProperty(value = "欠费是否断电/水/气(0-是1-否)")
private Long arrearsOutage;
/**
* 后付费模式下是否自动断电/水/气0-是1-否)
*/
@ExcelProperty(value = "后付费模式下是否自动断电/水/气", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "0=-是1-否")
private Long autoOutage;
/**
* 当auto_outage=0的时候生效逾期多少天自动断水/电/气
*/
@ExcelProperty(value = "当auto_outage=0的时候生效逾期多少天自动断水/电/气")
private Long overdueDay;
/**
* 备注
*/
@ExcelProperty(value = "备注")
private String remark;
}

View File

@@ -0,0 +1,52 @@
package org.dromara.iot.domain.vo;
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import cn.idev.excel.annotation.ExcelProperty;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import org.dromara.iot.domain.TdMeterRoom;
import java.io.Serial;
import java.io.Serializable;
/**
* 和房间的关联视图对象 td_meter_room
*
* @author LionLi
* @date 2025-06-18
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = TdMeterRoom.class)
public class TdMeterRoomVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键id
*/
@ExcelProperty(value = "主键id")
private Long id;
/**
* 表id
*/
@ExcelProperty(value = "表id")
private Long meterId;
/**
* 房间id
*/
@ExcelProperty(value = "房间id")
private Long roomId;
/**
* 备注
*/
@ExcelProperty(value = "备注")
private String remark;
}

View File

@@ -0,0 +1,112 @@
package org.dromara.iot.domain.vo;
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import cn.idev.excel.annotation.ExcelProperty;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import org.dromara.iot.domain.TdMeter;
import java.io.Serial;
import java.io.Serializable;
/**
* 水电气视图对象 td_meter
*
* @author LionLi
* @date 2025-06-19
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = TdMeter.class)
public class TdMeterVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键id
*/
@ExcelProperty(value = "主键id")
private Long id;
/**
* 水表名称
*/
@ExcelProperty(value = "水表名称")
private String meterName;
/**
* 设备编码
*/
@ExcelProperty(value = "设备编码")
private String meterCode;
/**
* 设备厂商
*/
@ExcelProperty(value = "设备厂商")
private String factoryNo;
/**
* 设备类型(1-电表2-水表3-气表)
*/
@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-后付费)
*/
@ExcelProperty(value = "付费类型(1-先付费2-后付费)")
private Long payType;
/**
* 当前表显示读数
*/
@ExcelProperty(value = "当前表显示读数")
private Long display;
/**
* 剩余量
*/
@ExcelProperty(value = "剩余量")
private Long surplus;
/**
* 通信状态
*/
@ExcelProperty(value = "通信状态")
private Long communicationState;
/**
* 运行状态
*/
@ExcelProperty(value = "运行状态")
private Long runningState;
/**
* 备注
*/
@ExcelProperty(value = "备注")
private String remark;
}

View File

@@ -0,0 +1,17 @@
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;
/**
* 门禁管理Mapper接口
*
* @author mocheng
* @date 2025-06-17
*/
@Mapper
public interface TbAccessControlMapper extends BaseMapperPlus<TbAccessControl, TbAccessControlVo> {
}

View File

@@ -0,0 +1,15 @@
package org.dromara.iot.mapper;
import org.dromara.iot.domain.TdFactory;
import org.dromara.iot.domain.vo.TdFactoryVo;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
/**
* 厂商管理Mapper接口
*
* @author mocheng
* @date 2025-06-17
*/
public interface TdFactoryMapper extends BaseMapperPlus<TdFactory, TdFactoryVo> {
}

View File

@@ -0,0 +1,15 @@
package org.dromara.iot.mapper;
import org.dromara.iot.domain.TdMeterConfig;
import org.dromara.iot.domain.vo.TdMeterConfigVo;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
/**
* 水电气配置Mapper接口
*
* @author LionLi
* @date 2025-06-18
*/
public interface TdMeterConfigMapper extends BaseMapperPlus<TdMeterConfig, TdMeterConfigVo> {
}

View File

@@ -0,0 +1,15 @@
package org.dromara.iot.mapper;
import org.dromara.iot.domain.TdMeter;
import org.dromara.iot.domain.vo.TdMeterVo;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
/**
* 水电气Mapper接口
*
* @author LionLi
* @date 2025-06-19
*/
public interface TdMeterMapper extends BaseMapperPlus<TdMeter, TdMeterVo> {
}

View File

@@ -0,0 +1,15 @@
package org.dromara.iot.mapper;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
import org.dromara.iot.domain.TdMeterRoom;
import org.dromara.iot.domain.vo.TdMeterRoomVo;
/**
* 和房间的关联Mapper接口
*
* @author LionLi
* @date 2025-06-18
*/
public interface TdMeterRoomMapper extends BaseMapperPlus<TdMeterRoom, TdMeterRoomVo> {
}

View File

@@ -0,0 +1,68 @@
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.TbAccessControlBo;
import org.dromara.iot.domain.vo.TbAccessControlVo;
import java.util.Collection;
import java.util.List;
/**
* 门禁管理Service接口
*
* @author mocheng
* @date 2025-06-17
*/
public interface ITbAccessControlService {
/**
* 查询门禁管理
*
* @param id 主键
* @return 门禁管理
*/
TbAccessControlVo queryById(Long id);
/**
* 分页查询门禁管理列表
*
* @param bo 查询条件
* @param pageQuery 分页参数
* @return 门禁管理分页列表
*/
TableDataInfo<TbAccessControlVo> queryPageList(TbAccessControlBo bo, PageQuery pageQuery);
/**
* 查询符合条件的门禁管理列表
*
* @param bo 查询条件
* @return 门禁管理列表
*/
List<TbAccessControlVo> queryList(TbAccessControlBo bo);
/**
* 新增门禁管理
*
* @param bo 门禁管理
* @return 是否新增成功
*/
Boolean insertByBo(TbAccessControlBo bo);
/**
* 修改门禁管理
*
* @param bo 门禁管理
* @return 是否修改成功
*/
Boolean updateByBo(TbAccessControlBo bo);
/**
* 校验并批量删除门禁管理信息
*
* @param ids 待删除的主键集合
* @param isValid 是否进行有效性校验
* @return 是否删除成功
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
}

View File

@@ -0,0 +1,68 @@
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.TdFactoryBo;
import org.dromara.iot.domain.vo.TdFactoryVo;
import java.util.Collection;
import java.util.List;
/**
* 厂商管理Service接口
*
* @author mocheng
* @date 2025-06-17
*/
public interface ITdFactoryService {
/**
* 查询厂商管理
*
* @param id 主键
* @return 厂商管理
*/
TdFactoryVo queryById(Long id);
/**
* 分页查询厂商管理列表
*
* @param bo 查询条件
* @param pageQuery 分页参数
* @return 厂商管理分页列表
*/
TableDataInfo<TdFactoryVo> queryPageList(TdFactoryBo bo, PageQuery pageQuery);
/**
* 查询符合条件的厂商管理列表
*
* @param bo 查询条件
* @return 厂商管理列表
*/
List<TdFactoryVo> queryList(TdFactoryBo bo);
/**
* 新增厂商管理
*
* @param bo 厂商管理
* @return 是否新增成功
*/
Boolean insertByBo(TdFactoryBo bo);
/**
* 修改厂商管理
*
* @param bo 厂商管理
* @return 是否修改成功
*/
Boolean updateByBo(TdFactoryBo bo);
/**
* 校验并批量删除厂商管理信息
*
* @param ids 待删除的主键集合
* @param isValid 是否进行有效性校验
* @return 是否删除成功
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
}

View File

@@ -0,0 +1,68 @@
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.TdMeterConfigBo;
import org.dromara.iot.domain.vo.TdMeterConfigVo;
import java.util.Collection;
import java.util.List;
/**
* 水电气配置Service接口
*
* @author LionLi
* @date 2025-06-18
*/
public interface ITdMeterConfigService {
/**
* 查询水电气配置
*
* @param id 主键
* @return 水电气配置
*/
TdMeterConfigVo queryById(Long id);
/**
* 分页查询水电气配置列表
*
* @param bo 查询条件
* @param pageQuery 分页参数
* @return 水电气配置分页列表
*/
TableDataInfo<TdMeterConfigVo> queryPageList(TdMeterConfigBo bo, PageQuery pageQuery);
/**
* 查询符合条件的水电气配置列表
*
* @param bo 查询条件
* @return 水电气配置列表
*/
List<TdMeterConfigVo> queryList(TdMeterConfigBo bo);
/**
* 新增水电气配置
*
* @param bo 水电气配置
* @return 是否新增成功
*/
Boolean insertByBo(TdMeterConfigBo bo);
/**
* 修改水电气配置
*
* @param bo 水电气配置
* @return 是否修改成功
*/
Boolean updateByBo(TdMeterConfigBo bo);
/**
* 校验并批量删除水电气配置信息
*
* @param ids 待删除的主键集合
* @param isValid 是否进行有效性校验
* @return 是否删除成功
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
}

View File

@@ -0,0 +1,85 @@
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;
import java.util.Collection;
import java.util.List;
/**
* 和房间的关联Service接口
*
* @author LionLi
* @date 2025-06-18
*/
public interface ITdMeterRoomService {
/**
* 查询和房间的关联
*
* @param id 主键
* @return 和房间的关联
*/
TdMeterRoomVo queryById(Long id);
/**
* 分页查询和房间的关联列表
*
* @param bo 查询条件
* @param pageQuery 分页参数
* @return 和房间的关联分页列表
*/
TableDataInfo<TdMeterRoomVo> queryPageList(TdMeterRoomBo bo, PageQuery pageQuery);
/**
* 查询符合条件的和房间的关联列表
*
* @param bo 查询条件
* @return 和房间的关联列表
*/
List<TdMeterRoomVo> queryList(TdMeterRoomBo bo);
/**
* 新增和房间的关联
*
* @param bo 和房间的关联
* @return 是否新增成功
*/
Boolean insertByBo(TdMeterRoomBo bo);
/**
* 修改和房间的关联
*
* @param bo 和房间的关联
* @return 是否修改成功
*/
Boolean updateByBo(TdMeterRoomBo bo);
/**
* 校验并批量删除和房间的关联信息
*
* @param ids 待删除的主键集合
* @param isValid 是否进行有效性校验
* @return 是否删除成功
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
/**
* 批量写入表和房间的关联关系
*
* @param rels 写入数据
* @return 是否写入成功
*/
Boolean insertBatch(List<TdMeterRoom> rels);
/**
* 根据表id删除关联数据
* @param meterId 表id
* @return 是否删除成功
*/
Integer deleteByMeterId(Long meterId);
}

View File

@@ -0,0 +1,77 @@
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.vo.TdMeterVo;
import java.util.Collection;
import java.util.List;
/**
* 水电气Service接口
*
* @author LionLi
* @date 2025-06-19
*/
public interface ITdMeterService {
/**
* 查询水电气
*
* @param id 主键
* @return 水电气
*/
TdMeterVo queryById(Long id);
/**
* 分页查询水电气列表
*
* @param bo 查询条件
* @param pageQuery 分页参数
* @return 水电气分页列表
*/
TableDataInfo<TdMeterVo> queryPageList(TdMeterBo bo, PageQuery pageQuery);
/**
* 查询符合条件的水电气列表
*
* @param bo 查询条件
* @return 水电气列表
*/
List<TdMeterVo> queryList(TdMeterBo bo);
/**
* 新增水电气
*
* @param bo 水电气
* @return 是否新增成功
*/
Boolean insertByBo(TdMeterBo bo);
/**
* 修改水电气
*
* @param bo 水电气
* @return 是否修改成功
*/
Boolean updateByBo(TdMeterBo bo);
/**
* 校验并批量删除水电气信息
*
* @param ids 待删除的主键集合
* @param isValid 是否进行有效性校验
* @return 是否删除成功
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
/**
* 打开或关闭表
*
* @param meterId 智能表编码
* @param onOff 0: 打开2关闭
* @return 是否操作成功
*/
Boolean operate(Long meterId, Integer onOff);
}

View File

@@ -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<DoorDeviceFindRes>
*/
IPage<DoorDeviceFindRes> 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);
}

View File

@@ -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<DoorDeviceFindRes>
*/
@Override
public IPage<DoorDeviceFindRes> findDoorDeviceList(QueryDto dto) {
// 创建一个参数映射用于存储API请求所需的参数
Map<String, Object> 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<String, Object> result = JSONUtil.toBean(JSONUtil.toJsonStr(apiResp.getResult()), new TypeReference<>() {
}, false);
// 创建一个分页对象,用于存储处理后的门禁设备信息
IPage<DoorDeviceFindRes> 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<String, Object> 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<String, Object> 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();
}
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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<DoorDeviceAddRes> childList;
}

View File

@@ -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<DoorDeviceFindRes> childList;
/**
* 设备通讯方式 0:TCP/IP 1:RS485
*/
private Integer commType;
/**
* 工单号(设备搜索)
*/
private String projectNumber;
/**
* 固件版本信息(设备搜索)
*/
private String version;
}

View File

@@ -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;
}

View File

@@ -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<String, Object> 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<String, Object> params, String api, String timestamp) {
String url = BASE_URL + api;
// one&two
String paramsUrl = buildUrlWithParams(url, params) + "&timestamp=" + 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<String, Object> params) {
if (params == null || params.isEmpty()) {
return url;
}
// 过滤出指定类型的参数
Map<String, Object> filteredParameters = new LinkedHashMap<>();
for (Map.Entry<String, Object> 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<String, Object> 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<String, Object> 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;
}
}

View File

@@ -0,0 +1,164 @@
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 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;
import org.dromara.iot.domain.TbAccessControl;
import org.dromara.iot.mapper.TbAccessControlMapper;
import org.dromara.iot.service.ITbAccessControlService;
import java.util.List;
import java.util.Map;
import java.util.Collection;
/**
* 门禁管理Service业务层处理
*
* @author mocheng
* @since 2025-06-17
*/
@Slf4j
@RequiredArgsConstructor
@Service
public class TbAccessControlServiceImpl implements ITbAccessControlService {
private final TbAccessControlMapper baseMapper;
private final DoorDeviceService doorDeviceService;
/**
* 查询门禁管理
*
* @param id 主键
* @return 门禁管理
*/
@Override
public TbAccessControlVo queryById(Long id) {
return baseMapper.selectVoById(id);
}
/**
* 分页查询门禁管理列表
*
* @param bo 查询条件
* @param pageQuery 分页参数
* @return 门禁管理分页列表
*/
@Override
public TableDataInfo<TbAccessControlVo> queryPageList(TbAccessControlBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<TbAccessControl> lqw = buildQueryWrapper(bo);
Page<TbAccessControlVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
* 查询符合条件的门禁管理列表
*
* @param bo 查询条件
* @return 门禁管理列表
*/
@Override
public List<TbAccessControlVo> queryList(TbAccessControlBo bo) {
LambdaQueryWrapper<TbAccessControl> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private LambdaQueryWrapper<TbAccessControl> buildQueryWrapper(TbAccessControlBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<TbAccessControl> lqw = Wrappers.lambdaQuery();
lqw.orderByAsc(TbAccessControl::getId);
lqw.eq(StringUtils.isNotBlank(bo.getAccessCode()), TbAccessControl::getAccessCode, bo.getAccessCode());
lqw.like(StringUtils.isNotBlank(bo.getAccessName()), TbAccessControl::getAccessName, bo.getAccessName());
lqw.eq(StringUtils.isNotBlank(bo.getCommunityCode()), TbAccessControl::getCommunityCode, bo.getCommunityCode());
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::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());
lqw.eq(StringUtils.isNotBlank(bo.getOutCode()), TbAccessControl::getOutCode, bo.getOutCode());
lqw.eq(StringUtils.isNotBlank(bo.getOrgCode()), TbAccessControl::getOrgCode, bo.getOrgCode());
lqw.eq(bo.getDataState() != null, TbAccessControl::getDataState, bo.getDataState());
return lqw;
}
/**
* 新增门禁管理
*
* @param bo 门禁管理
* @return 是否新增成功
*/
@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.getAccessType());
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) {
bo.setId(add.getId());
}
return flag;
}
/**
* 修改门禁管理
*
* @param bo 门禁管理
* @return 是否修改成功
*/
@Override
public Boolean updateByBo(TbAccessControlBo bo) {
TbAccessControl update = MapstructUtils.convert(bo, TbAccessControl.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
/**
* 保存前的数据校验
*/
private void validEntityBeforeSave(TbAccessControl entity) {
//TODO 做一些数据校验,如唯一约束
}
/**
* 校验并批量删除门禁管理信息
*
* @param ids 待删除的主键集合
* @param isValid 是否进行有效性校验
* @return 是否删除成功
*/
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if (isValid) {
//TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteByIds(ids) > 0;
}
}

View File

@@ -0,0 +1,134 @@
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 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.iot.domain.bo.TdFactoryBo;
import org.dromara.iot.domain.vo.TdFactoryVo;
import org.dromara.iot.domain.TdFactory;
import org.dromara.iot.mapper.TdFactoryMapper;
import org.dromara.iot.service.ITdFactoryService;
import java.util.List;
import java.util.Map;
import java.util.Collection;
/**
* 厂商管理Service业务层处理
*
* @author mocheng
* @date 2025-06-17
*/
@Slf4j
@RequiredArgsConstructor
@Service
public class TdFactoryServiceImpl implements ITdFactoryService {
private final TdFactoryMapper baseMapper;
/**
* 查询厂商管理
*
* @param id 主键
* @return 厂商管理
*/
@Override
public TdFactoryVo queryById(Long id){
return baseMapper.selectVoById(id);
}
/**
* 分页查询厂商管理列表
*
* @param bo 查询条件
* @param pageQuery 分页参数
* @return 厂商管理分页列表
*/
@Override
public TableDataInfo<TdFactoryVo> queryPageList(TdFactoryBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<TdFactory> lqw = buildQueryWrapper(bo);
Page<TdFactoryVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
* 查询符合条件的厂商管理列表
*
* @param bo 查询条件
* @return 厂商管理列表
*/
@Override
public List<TdFactoryVo> queryList(TdFactoryBo bo) {
LambdaQueryWrapper<TdFactory> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private LambdaQueryWrapper<TdFactory> buildQueryWrapper(TdFactoryBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<TdFactory> lqw = Wrappers.lambdaQuery();
lqw.orderByAsc(TdFactory::getId);
lqw.eq(StringUtils.isNotBlank(bo.getFactoryNo()), TdFactory::getFactoryNo, bo.getFactoryNo());
lqw.like(StringUtils.isNotBlank(bo.getFactoryName()), TdFactory::getFactoryName, bo.getFactoryName());
lqw.eq(bo.getDataState() != null, TdFactory::getDataState, bo.getDataState());
return lqw;
}
/**
* 新增厂商管理
*
* @param bo 厂商管理
* @return 是否新增成功
*/
@Override
public Boolean insertByBo(TdFactoryBo bo) {
TdFactory add = MapstructUtils.convert(bo, TdFactory.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setId(add.getId());
}
return flag;
}
/**
* 修改厂商管理
*
* @param bo 厂商管理
* @return 是否修改成功
*/
@Override
public Boolean updateByBo(TdFactoryBo bo) {
TdFactory update = MapstructUtils.convert(bo, TdFactory.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
/**
* 保存前的数据校验
*/
private void validEntityBeforeSave(TdFactory entity){
//TODO 做一些数据校验,如唯一约束
}
/**
* 校验并批量删除厂商管理信息
*
* @param ids 待删除的主键集合
* @param isValid 是否进行有效性校验
* @return 是否删除成功
*/
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if(isValid){
//TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteByIds(ids) > 0;
}
}

View File

@@ -0,0 +1,136 @@
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 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.iot.domain.bo.TdMeterConfigBo;
import org.dromara.iot.domain.vo.TdMeterConfigVo;
import org.dromara.iot.domain.TdMeterConfig;
import org.dromara.iot.mapper.TdMeterConfigMapper;
import org.dromara.iot.service.ITdMeterConfigService;
import java.util.List;
import java.util.Map;
import java.util.Collection;
/**
* 水电气配置Service业务层处理
*
* @author LionLi
* @date 2025-06-18
*/
@Slf4j
@RequiredArgsConstructor
@Service
public class TdMeterConfigServiceImpl implements ITdMeterConfigService {
private final TdMeterConfigMapper baseMapper;
/**
* 查询水电气配置
*
* @param id 主键
* @return 水电气配置
*/
@Override
public TdMeterConfigVo queryById(Long id){
return baseMapper.selectVoById(id);
}
/**
* 分页查询水电气配置列表
*
* @param bo 查询条件
* @param pageQuery 分页参数
* @return 水电气配置分页列表
*/
@Override
public TableDataInfo<TdMeterConfigVo> queryPageList(TdMeterConfigBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<TdMeterConfig> lqw = buildQueryWrapper(bo);
Page<TdMeterConfigVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
* 查询符合条件的水电气配置列表
*
* @param bo 查询条件
* @return 水电气配置列表
*/
@Override
public List<TdMeterConfigVo> queryList(TdMeterConfigBo bo) {
LambdaQueryWrapper<TdMeterConfig> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private LambdaQueryWrapper<TdMeterConfig> buildQueryWrapper(TdMeterConfigBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<TdMeterConfig> lqw = Wrappers.lambdaQuery();
lqw.orderByAsc(TdMeterConfig::getId);
lqw.eq(bo.getMeterType() != null, TdMeterConfig::getMeterType, bo.getMeterType());
lqw.eq(bo.getPayType() != null, TdMeterConfig::getPayType, bo.getPayType());
lqw.eq(bo.getArrearsOutage() != null, TdMeterConfig::getArrearsOutage, bo.getArrearsOutage());
lqw.eq(bo.getAutoOutage() != null, TdMeterConfig::getAutoOutage, bo.getAutoOutage());
lqw.eq(bo.getOverdueDay() != null, TdMeterConfig::getOverdueDay, bo.getOverdueDay());
return lqw;
}
/**
* 新增水电气配置
*
* @param bo 水电气配置
* @return 是否新增成功
*/
@Override
public Boolean insertByBo(TdMeterConfigBo bo) {
TdMeterConfig add = MapstructUtils.convert(bo, TdMeterConfig.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setId(add.getId());
}
return flag;
}
/**
* 修改水电气配置
*
* @param bo 水电气配置
* @return 是否修改成功
*/
@Override
public Boolean updateByBo(TdMeterConfigBo bo) {
TdMeterConfig update = MapstructUtils.convert(bo, TdMeterConfig.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
/**
* 保存前的数据校验
*/
private void validEntityBeforeSave(TdMeterConfig entity){
//TODO 做一些数据校验,如唯一约束
}
/**
* 校验并批量删除水电气配置信息
*
* @param ids 待删除的主键集合
* @param isValid 是否进行有效性校验
* @return 是否删除成功
*/
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if(isValid){
//TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteByIds(ids) > 0;
}
}

View File

@@ -0,0 +1,147 @@
package org.dromara.iot.service.impl;
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.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.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;
/**
* 和房间的关联Service业务层处理
*
* @author LionLi
* @date 2025-06-18
*/
@Slf4j
@RequiredArgsConstructor
@Service
public class TdMeterRoomServiceImpl implements ITdMeterRoomService {
private final TdMeterRoomMapper baseMapper;
/**
* 查询和房间的关联
*
* @param id 主键
* @return 和房间的关联
*/
@Override
public TdMeterRoomVo queryById(Long id){
return baseMapper.selectVoById(id);
}
/**
* 分页查询和房间的关联列表
*
* @param bo 查询条件
* @param pageQuery 分页参数
* @return 和房间的关联分页列表
*/
@Override
public TableDataInfo<TdMeterRoomVo> queryPageList(TdMeterRoomBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<TdMeterRoom> lqw = buildQueryWrapper(bo);
Page<TdMeterRoomVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
* 查询符合条件的和房间的关联列表
*
* @param bo 查询条件
* @return 和房间的关联列表
*/
@Override
public List<TdMeterRoomVo> queryList(TdMeterRoomBo bo) {
LambdaQueryWrapper<TdMeterRoom> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private LambdaQueryWrapper<TdMeterRoom> buildQueryWrapper(TdMeterRoomBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<TdMeterRoom> lqw = Wrappers.lambdaQuery();
lqw.orderByAsc(TdMeterRoom::getId);
lqw.eq(bo.getMeterId() != null, TdMeterRoom::getMeterId, bo.getMeterId());
lqw.eq(bo.getRoomId() != null, TdMeterRoom::getRoomId, bo.getRoomId());
return lqw;
}
/**
* 新增和房间的关联
*
* @param bo 和房间的关联
* @return 是否新增成功
*/
@Override
public Boolean insertByBo(TdMeterRoomBo bo) {
TdMeterRoom add = MapstructUtils.convert(bo, TdMeterRoom.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setId(add.getId());
}
return flag;
}
/**
* 修改和房间的关联
*
* @param bo 和房间的关联
* @return 是否修改成功
*/
@Override
public Boolean updateByBo(TdMeterRoomBo bo) {
TdMeterRoom update = MapstructUtils.convert(bo, TdMeterRoom.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
/**
* 保存前的数据校验
*/
private void validEntityBeforeSave(TdMeterRoom entity){
//TODO 做一些数据校验,如唯一约束
}
/**
* 校验并批量删除和房间的关联信息
*
* @param ids 待删除的主键集合
* @param isValid 是否进行有效性校验
* @return 是否删除成功
*/
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if(isValid){
//TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteByIds(ids) > 0;
}
@Override
public Boolean insertBatch(List<TdMeterRoom> rels) {
return baseMapper.insertBatch(rels);
}
@Override
public Integer deleteByMeterId(Long meterId) {
Assert.notNull(meterId, "表id不能为null");
LambdaUpdateWrapper<TdMeterRoom> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.eq(TdMeterRoom::getMeterId, meterId);
return baseMapper.delete(updateWrapper);
}
}

View File

@@ -0,0 +1,186 @@
package org.dromara.iot.service.impl;
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.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.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.stream.Collectors;
/**
* 水电气Service业务层处理
*
* @author LionLi
* @date 2025-06-19
*/
@Slf4j
@RequiredArgsConstructor
@Service
public class TdMeterServiceImpl implements ITdMeterService {
private final TdMeterMapper baseMapper;
private final ITdMeterRoomService meterRoomService;
/**
* 查询水电气
*
* @param id 主键
* @return 水电气
*/
@Override
public TdMeterVo queryById(Long id){
return baseMapper.selectVoById(id);
}
/**
* 分页查询水电气列表
*
* @param bo 查询条件
* @param pageQuery 分页参数
* @return 水电气分页列表
*/
@Override
public TableDataInfo<TdMeterVo> queryPageList(TdMeterBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<TdMeter> lqw = buildQueryWrapper(bo);
Page<TdMeterVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
* 查询符合条件的水电气列表
*
* @param bo 查询条件
* @return 水电气列表
*/
@Override
public List<TdMeterVo> queryList(TdMeterBo bo) {
LambdaQueryWrapper<TdMeter> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private LambdaQueryWrapper<TdMeter> buildQueryWrapper(TdMeterBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<TdMeter> lqw = Wrappers.lambdaQuery();
lqw.orderByAsc(TdMeter::getId);
lqw.like(StringUtils.isNotBlank(bo.getMeterName()), TdMeter::getMeterName, bo.getMeterName());
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());
return lqw;
}
/**
* 新增水电气
*
* @param bo 水电气
* @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());
}
// 写入表和房间的关联信息
List<TdMeterRoom> 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);
}
/**
* 修改水电气
*
* @param bo 水电气
* @return 是否修改成功
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean updateByBo(TdMeterBo bo) {
TdMeter update = MapstructUtils.convert(bo, TdMeter.class);
validEntityBeforeSave(update);
boolean b = baseMapper.updateById(update) > 0;
// 如果关联的房间列表没有发生变化,则不修改
if (b && CollUtil.isNotEmpty(bo.getRoomIds())) {
// 删除已有的关联关系
int num = meterRoomService.deleteByMeterId(bo.getId());
log.info("删除智能表和房间关联数据条数: {}", num);
// 建立新的关系
// 写入表和房间的关联信息
List<TdMeterRoom> 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;
}
/**
* 保存前的数据校验
*/
private void validEntityBeforeSave(TdMeter entity){
//TODO 做一些数据校验,如唯一约束
}
/**
* 校验并批量删除水电气信息
*
* @param ids 待删除的主键集合
* @param isValid 是否进行有效性校验
* @return 是否删除成功
*/
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if(isValid){
//TODO 做一些业务上的校验,判断是否需要校验
}
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;
}
}

View File

@@ -0,0 +1,258 @@
package org.dromara.iot.service.unview;
import java.awt.*;
import java.util.List;
import static org.dromara.iot.service.unview.model.UvModel.*;
public interface UnViewAiBoxApi {
/**
* 行为分析检索
*
* @param params 检索参数
* @param uvSystemInfo 设备信息
* @return 发你检索数据
*/
SearchBehaviorResult searchBehavior(UvSystemInfo uvSystemInfo, SearchBehaviorParams params);
/**
* 添加人脸库
*
* @param libName 人脸库名称
* @param uvSystemInfo 设备信息
* @return 返回人像库id
*/
AddLibResult addPersonLib(UvSystemInfo uvSystemInfo, String libName);
/**
* 删除人像库
*
* @param libIds 人像库id列表
* @param uvSystemInfo 设备信息
* @return 是否删除成功
*/
boolean deletePersonLib(UvSystemInfo uvSystemInfo, Integer... libIds);
/**
* 更新人像库信息
*
* @param uvSystemInfo 设备信息
* @param libId 人像库id
* @param LibName 人像库名称
* @return
*/
boolean updatePersonLib(UvSystemInfo uvSystemInfo, Integer libId, String LibName);
/**
* 分页查询人像库信息
*
* @param uvSystemInfo 设备信息
* @param libName 人像库名称
* @param current 页面
* @param size 查询数量
* @return 返回人像库数据
*/
QueryLibResult findPagePersonLib(UvSystemInfo uvSystemInfo, String libName, Integer current, Integer size);
/**
* 添加人像
*
* @param uvSystemInfo 设备信息
* @param personAddReq 人像信息
* @return 返回人像信息
*/
AddPersonResult addPerson(UvSystemInfo uvSystemInfo, AddPersonParams personAddReq);
/**
* 批量添加人像
*
* @param uvSystemInfo 设备信息
* @param personParams 批量人像信息
* @return 返回批量的人像信息
*/
BatchAddPersonResult batchAddPerson(UvSystemInfo uvSystemInfo, BatchAddPersonParams personParams);
/**
* 批量删除人像信息
*
* @param uvSystemInfo 设备信息
* @param personIds 人像id
* @return 返回是否删除成功
*/
Boolean batchDeletePerson(UvSystemInfo uvSystemInfo, Integer[] personIds);
/**
* 更新人像信息
*
* @param uvSystemInfo 设备信息
* @param params 更新参数
* @return 返回是否更新成功
*/
Boolean updatePerson(UvSystemInfo uvSystemInfo, UpdatePersonParams params);
/**
* 分页查询人像信息
*
* @param uvSystemInfo 设备信息
* @param params 查询参数
* @return 返回是否查询成功
*/
queryPersonPageResult findPersonPage(UvSystemInfo uvSystemInfo, queryPersonPageParams params);
/**
* 获取 rsa 公钥
*
* @param uvSystemInfo 设备信息
* @return GetPublickeyResp 获取公钥响应
*/
GetPublickeyResult getPublickey(UvSystemInfo uvSystemInfo);
/**
* 获取码流信息
*
* @param uvSystemInfo 设备信息
* @param uvSystemInfo req 查询参数
* @return 返回码流信息
*/
QueryOnvifResult getOnvif(UvSystemInfo uvSystemInfo);
/**
* 新增点位
*
* @param uvSystemInfo 设备信息
* @param params 点位新增请求
* @return 点位新增响应
*/
AddPointResult addPoint(UvSystemInfo uvSystemInfo, PointParams params);
/**
* 删除设备中的点位信息
*
* @param uvSystemInfo 设备信息
* @param channelIds 点位ID列表
* @return 删除结果
*/
Boolean deletePoint(UvSystemInfo uvSystemInfo, List<Integer> channelIds);
/**
* 更新设备中的点位信息
*
* @param uvSystemInfo 设备信息
* @param params 点位更新请求
* @return 更新结果
*/
Boolean updatePoint(UvSystemInfo uvSystemInfo, UpdatePointParams params);
/**
* 根据设备信息和点位查找请求来查找点位信息
*
* @param uvSystemInfo 设备信息
* @param req 点位查找请求
* @return 点位查找响应
*/
QueryPointResult queryPoint(UvSystemInfo uvSystemInfo, QueryPointParams req);
/**
* 批量添加点位信息到设备中
*
* @param uvSystemInfo 设备信息
* @param params 批量添加点位请求
* @return 批量添加点位响应
*/
BatchAddPersonResult batchAddPoint(UvSystemInfo uvSystemInfo, BatchAddPointParams params);
/**
* 添加/修改 设备布防时间
*/
Boolean pointControlTimeUpdate(UvSystemInfo uvSystemInfo, ModifyControlTime params);
/**
* 获取布防时间
*
* @param uvSystemInfo 设备信息
* @param channel_id 通道 id
* @param algo_model 算法类型
* @return 返回查询结果
*/
ControlTime queryControlTime(UvSystemInfo uvSystemInfo, Integer channel_id, Integer algo_model);
/**
* 新增工服库
*
* @param systemInfo 设备信息
* @param libName 工服库名称
* @return 是否添加成功
*/
Integer addWorkClothesLib(UvSystemInfo systemInfo, String libName);
/**
* 修改工服库信息
*
* @param systemInfo 设备信息
* @param libId 库id
* @param libName 库名称
* @return 是否修改成功
*/
Boolean updateWorkClothesLib(UvSystemInfo systemInfo, Integer libId, String libName);
/**
* 删除工服库
*
* @param systemInfo 设备信息
* @param libId 工服库id
* @return 是否删除成功
*/
Boolean deleteWorkClothesLib(UvSystemInfo systemInfo, Integer libId);
/**
* @param systemInfo 设备信息
* @param libName 库名称
* @param page 页码
* @param pageSize 查询数量
* @return 返回分页数据
*/
QueryLibResult findPageWorkClothesLib(UvSystemInfo systemInfo, String libName, Integer page, Integer pageSize);
/**
* 新增工服-单个
*
* @param systemInfo 增加工服的设备
* @param libId 新增工服的库id
* @param imageBase64 工服图片base64
* @return 返回工服的人员id
*/
Integer addWorkClothes(UvSystemInfo systemInfo, Integer libId, String imageBase64);
/**
* 批量新增工服一次最多添加50条
*
* @param systemInfo 增加工服的设备
* @param libId 新增工服的库id
* @param imageBase64s 工服图片base64列表
* @return 返回成功以及失败的数据
*/
BatchAddWorkClothesResult batchAddWorkClothes(UvSystemInfo systemInfo, Integer libId, List<String> imageBase64s);
/**
* 删除工服库
*
* @param systemInfo 设备信息
* @param libId 库id
* @param workClothesIds 工服id列表
* @return
*/
Boolean deleteWorkClothes(UvSystemInfo systemInfo, Integer libId, List<Integer> workClothesIds);
/**
* 分页查询工服
*
* @param systemInfo 设备
* @param libId 设备id
* @param page 分页查询页码
* @param size 分页查询size
* @param status 建模状态 999全部1未建模 2建模中3建模成功4建模失败
*/
FindWorkClothesResult findPageWorkClothes(UvSystemInfo systemInfo, Integer libId, Integer page, Integer size, Integer status);
}

View File

@@ -0,0 +1,8 @@
package org.dromara.iot.service.unview;
public class UniViewConstants {
}

View File

@@ -0,0 +1,728 @@
package org.dromara.iot.service.unview.model;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
public class UvModel {
@Data
public static class UniViewResult<T> {
private Integer code;
private String msg;
private Integer status_code;
private T data;
public boolean success() {
return code.equals(0);
}
public boolean unAuth() {
return code.equals(401);
}
public static <T> UniViewResult<T> success(T data) {
UniViewResult<T> result = new UniViewResult<>();
result.setCode(0);
result.setStatus_code(0);
result.setMsg("Succeed");
return result;
}
public T result() {
if (success()) {
return data;
} else {
return null;
}
}
}
@Data
public static class Page {
private Integer pageNum;
private Integer pageSize;
}
@Data
public static class UvSystemInfo {
private String account; // 账号
private String password; // 密码
private String ip; // 设备ip
private Integer port; // 设备端口
}
@Data
public static class UvAuthInfo {
/**
* 摘要加密算法,首次请求时由设备返回
*/
String algorithm;
/**
* 保护质量,首次请求时由设备返回
*/
String qop;
/**
* 摘要加密字段,首次请求时由设备返回
*/
String realm;
/**
* 随机字符串,每当返回 401 时就会生成一个新的值,
* 原值失效,客户端需使用此值生成新的摘要信息
*/
String nonce;
/**
* 指示上个请求中的 nonce 是否过期,由设备返回
*/
String stale;
}
@EqualsAndHashCode(callSuper = true)
@Data
public static class UvRequestAuthInfo extends UvAuthInfo {
/**
* 鉴权用户名,由设备分配
*/
private String username;
/**
* 当前请求的 URI
*/
private String uri;
/**
* nonce 计数器,防止重放攻击,由请求方生成
*/
private String nc;
/**
* 唯一字符串,用于提供额外防护,由请求方生成
*/
private String cnonce;
/**
* 摘要信息,用于验证身份,由请求方生成
*/
private String response;
}
@Data
public static class AlarmReportInfo {
/**
* 上报内容
* 1行为分析告警数据
* 2告警恢复数据
* 3人脸抓拍数据
* 4人脸比对数据
* 5行为比对数据
* 6保活数据
* 7点位变更数据
*/
private Integer type;
private String event_id;
/**
* 有无比对结果 1 有 0 无
*/
private Integer has_result;
private DeviceInfo device_info;
private ChannelInfo channel_info;
private Behaviour behaviour;
/**
* 人脸抓拍数据
*/
private Face face;
/**
* 人脸比对结果(为空代
* 表比对失败)
*/
private List<CompareResult> compare_results;
}
@Data
public static class CompareResult {
private Integer target_id;
private Integer lib_id;
private String lib_name;
private Integer person_id;
private String person_name;
private Integer sex;
private String email;
private String tel;
private Integer certificate_type;
private String certificate_no;
private String image_path;
private String image_base64;
private String similarity;
}
@Data
public static class Face {
private Integer capture_time;
private String point_x;
private String point_y;
private String orig_image_path;
private String crop_image_path;
private String orig_image_base64; // 人脸抓拍大图base64
private String crop_image_base64; // 人脸抓拍小图base64
}
@Data
public static class CaptureInfo {
private Integer target_id;
private String point_x;
private String point_y;
private Integer object_type;
private String plate_no;
}
@Setter
@Getter
public static class Behaviour {
private String algo_model;
private String image_base64;
private String image_path;
private Integer capture_time;
private Integer in_num;
private Integer out_num;
private Integer area_num; // 区域统计人数
private String video_uuid;
private String video_url;
private List<CaptureInfo> capture_info; // 目标信息
@Override
public String toString() {
return "Behaviour{" +
"algo_model='" + algo_model + '\'' +
// ", image_base64='" + image_base64 + '\'' +
", image_path='" + image_path + '\'' +
", capture_time=" + capture_time +
", in_num=" + in_num +
", out_num=" + out_num +
", area_num=" + area_num +
", video_uuid='" + video_uuid + '\'' +
", video_url='" + video_url + '\'' +
", capture_info=" + capture_info +
'}';
}
}
@Data
public static class ChannelInfo {
/**
* 上报模式:
* 0点位信息
* 1添加点位
* 2修改点位
* 3删除点位
* 4点位状态变化
*/
private Integer mode;
private String ipc_sn;
private String ipc_addr;
private Integer channel_id;
private String channel_name;
private Integer status;
private String custom_code;
}
@Data
public static class DeviceInfo {
private Integer device_code;
private String device_name;
private String device_sn;
private String custom_code;
}
@Data
public static class AddPersonParams {
/**
* 人像名称
* 必填
*/
private String person_name;
/**
* 人像的base64图片
* 必填
*/
private String image_base64;
/**
* 人像库id
* 必填
*/
private Integer lib_id;
/**
* 性别
*/
private String sex;
/**
* 邮件
*/
private String email;
/**
* 联系方式
*/
private String tel;
/**
* 证件类型
* 1身份证 2护照 3行驶证 99其它
*/
private String certificate_type;
/**
* 证件号码
*/
private String certificate_no;
/**
* 出生日期
*/
private String birth_date;
}
@Data
public static class AddPersonResult {
private Integer person_id;
}
@Data
public static class BatchAddPersonParams {
/**
* 批量添加人像信息
*/
private List<AddPersonParams> person_list;
}
@Data
public static class BatchAddPersonResult {
private List<Object> fail_list;
}
@EqualsAndHashCode(callSuper = true)
@Data
public static class queryPersonPageParams extends Page {
/**
* 人员库 id
* 必填
*/
private Integer lib_id;
/**
* 姓名(支持模糊查询)
*/
private String person_name;
/**
* 性别
* 999全部
* 1
* 2
* 99未说明
*/
private Integer sex = 999;
/**
* 证件号
*/
private String certificate_no;
/**
* 建模状态 999全部
* 1未建模 2建模中3建模成功4建模失败
*/
private Integer model_status = 999;
}
@Data
public static class queryPersonPageResult {
/**
* 查询数据
*/
private List<PersonInfo> data;
/**
* 数据总数
*/
private Integer total;
}
@Data
public static class PersonInfo {
/**
* 人员 id
*/
private Integer person_id;
/**
* 姓名
*/
private String person_name;
/**
* 性别 1男 2女 99未说明
*/
private Integer sex;
/**
* 邮箱
*/
private String email;
/**
* 联系方式
*/
private String tel;
/**
* 建模状态 1未建模 2建模中3建模成功4建模失败
*/
private Integer modeling_type;
/**
* 证件类型 1身份证 2护照 3行驶证 99其它
*/
private Integer certificate_type;
/**
* 证件号码
*/
private String certificate_no;
/**
* 图片路径
*/
private String image_path;
/**
* 人员库 id
*/
private Integer lib_id;
/**
* 出生日期
*/
private String birth_date;
/**
* 创建时间
*/
private Integer create_time;
}
/**
* 添加人像库请求参数封装
*/
@Data
public static class UpdatePersonParams {
/**
* 人员 id
* 必填
*/
private String person_id;
/**
* 名称
*/
private String person_name;
/**
* 性别
*/
private Integer sex;
/**
* 邮箱
*/
private String email;
/**
* 联系方式
*/
private String tel;
/**
* 证件类型 1身份证 2护照 3行驶证 99其它
*/
private Integer certificate_type;
/**
* 证件号码
*/
private Integer certificate_no;
/**
* 人脸照片 base64
*/
private String image_base64;
/**
* 出生日期
*/
private String birth_date;
}
@Data
public static class QueryLibResult {
private Integer total;
private List<LibInfo> list;
}
@Data
public static class LibInfo {
private Integer lib_id;
private String lib_name;
private Integer create_time;
}
@Data
public static class AddLibResult {
private Integer lib_id;
}
@Data
public static class BatchAddWorkClothesResult {
private List<Integer> workclothes_id;
private List<BatchAddWorkClothesFailInfo> fail_list;
}
@Data
public static class BatchAddWorkClothesFailInfo {
private Integer index;
private String reason;
}
@Data
public static class FindWorkClothesResult {
private Integer total;
private List<WorkClothesInfo> workclothes_list;
}
@Data
public static class WorkClothesInfo {
private Integer lib_id;
private Integer workclothes_id;
private String image_path;
private Integer create_time;
private Integer model_status;
}
@Data
public static class SearchBehaviorParams {
/**
* 页码数
*/
private Integer page;
/**
* 每页数据量
*/
private Integer pagesize;
/**
* 通道 id
*/
private List<Integer> channel_id;
/**
* 算法类型,送空查全部
*/
private List<String> algo_model;
/**
* 开始时间10 位时间戳(秒级)
*/
private Integer start_time;
/**
* 结束时间10 位时间戳(秒级)
*/
private Integer end_time;
/**
* 是否有比对1 全部2 有比对 不传查全部
*/
private Integer compare_flag;
/**
* 目标类型 区域入侵告警查询条件 1 行人 2
* 机动车 3 非机动车
*/
private Integer object_type;
/**
* 车牌号
*/
private String plate_no;
}
@Data
public static class SearchBehaviorResult {
private Integer total;
private List<BehaviorInfo> list;
}
@Data
public static class BehaviorInfo {
private Integer alarm_id;
private String big_picture_url;
private String BigImageData;
private String algo_model;
private Integer capture_time;
private Integer channel_id;
private String channel_name;
private String video_url;
private List<ObjectInfo> object_list;
private List<CompareInfo> compare_list;
}
@Data
public static class ObjectInfo {
private Integer plate_no;
}
@Data
public static class CompareInfo {
private Integer base_image_id;
private String base_image_url;
private String name;
private String certificate_no;
private Integer similarity;
private Integer match_type;
}
@Data
public static class TimeSlot {
/**
* 开始时间,例如 00:00
*/
private String start;
/**
* 结束时间例如04:00
*/
private String end;
}
@Data
public static class ControlTime {
private List<TimeSlot> monday;
private List<TimeSlot> tuesday;
private List<TimeSlot> wednesday;
private List<TimeSlot> thursday;
private List<TimeSlot> friday;
private List<TimeSlot> saturday;
private List<TimeSlot> sunday;
}
@Data
public static class ModifyControlTime {
private Integer channel_id; // 点位 id
private String algo_model; // 算法类型
private ControlTime control_time; // 布防时间
}
@Data
public static class QueryOnvifResult {
/**
* 厂商
*/
private String manufacturer;
/**
* 型号
*/
private String model;
/**
* 固件版本
*/
private String firmware_version;
/**
* 序列号
*/
private String serial_number;
/**
* 硬件 id
*/
private String hardware_id;
/**
* 码流列表
*/
private List<OnvifVideoInfo> video;
}
@Data
private static class OnvifVideoInfo {
/**
* 码流 id
*/
private Integer id;
/**
* rtsp 地址
*/
private String rtsp;
/**
* 码率
*/
private String bitrate;
/**
* 编码格式
*/
private String encoding;
/**
* 帧率
*/
private String fps;
/**
* 画面组
*/
private String gop;
/**
* 质量
*/
private String quality;
/**
* 分辨率
*/
private String ratio;
}
@Data
public static class GetPublickeyResult {
private String public_key;
}
@Data
public static class PointParams {
private Integer type; // 视频协议 1onvif 2rtsp
private Integer transport_type; // 传输协议(AIBOX 需要,一体机不需要) 1: tcp 2: udp
private String channel_name; // 点位名称
private String rtsp; // rtsp 地址当视频协议为rtsp 时,该字段必填)
private String ip; // 相机 iponvif 添加流时必填)
private Integer port; // 相机端口onvif 添加流时必填)
private String username; // 相机用户名
private String pwd; // 相机密码RSA 加密)
private Integer video_type; // onvif 设备码流添加方式1主码流 2自定义码流
private Integer video_id; // 码流 id当选择自定义码流时该字段必填值为获取设备码流信息接口返回的码流 id
private String custom_code; // 自定义编码
}
@Data
public static class AddPointResult {
private Integer channel_id; // 点位id
}
@Data
public static class BatchAddPointParams {
private List<PointParams> channel_list;
}
@Data
public static class BatchAddPointResult {
/**
* 失败的点位名称列表
*/
private List<String> fail_list;
}
@EqualsAndHashCode(callSuper = true)
@Data
public static class UpdatePointParams extends PointParams {
private Integer channel_id; // 点位 id
}
@EqualsAndHashCode(callSuper = true)
@Data
public static class QueryPointParams extends Page {
private String channel_name;
}
@Data
public static class QueryPointResult {
private String channel_name;
}
}

View File

@@ -0,0 +1,79 @@
package org.dromara.iot.service.unview.model.enums;
/**
* [
* "FieldDetectorObjectsInside", // 区域入侵报警
* "SafetyHelmetAlarm", // 未戴安全帽报警
* "WorkClothesAlarm", // 未穿工服报警
* "TelephoningAlarm", // 打电话报警
* "NoMaskAlarm", // 未戴口罩报警
* "FallOverAlarm", // 跌倒报警
* "OffDutyDetectionAlarm", // 离岗报警
* "SmokingAlarm", // 吸烟报警
* "ReflectiveClothesDetectionAlarm", // 未穿反光服报警
* "FireDetection", // 明火报警
* "FumesAlarmBegin", // 烟雾报警
* "CrowdDensityCriticalAlarm", //人员数量超限报警
* "AbnormalParkingDetection", //车辆违停占用报警
* "DisorderStackingDetection", // 物料乱堆放报警
* "BareSoilCoverDetection", // 裸土未覆盖
* "SafetyHarnessDetection", // 未穿安全背带报警
* "UnwashedVehicleDetection" // 车辆未清洗报警
* ]
*/
public enum AlarmModelEnum {
FieldDetectorObjectsInside(10, 1014, "区域入侵报警"),
SafetyHelmetAlarm(10, 1015, "未戴安全帽报警"),
WorkClothesAlarm(10, 1016, "未穿工服报警"),
TelephoningAlarm(10, 1017, "打电话报警"),
NoMaskAlarm(10, 1013, "未戴口罩报警"),
FallOverAlarm(10, 1018, "跌倒报警"),
OffDutyDetectionAlarm(10, 1019, "离岗报警"),
SmokingAlarm(10, 1020, "吸烟报警"),
ReflectiveClothesDetectionAlarm(10, 1021, "未穿反光服报警"),
FireDetection(10, 1022, "明火报警"),
FumesAlarmBegin(10, 1023, "烟雾报警"),
CrowdDensityCriticalAlarm(10, 1024, "人员数量超限报警"),
AbnormalParkingDetection(10, 1025, "车辆违停占用报警"),
DisorderStackingDetection(10, 1026, "物料乱堆放报警"),
BareSoilCoverDetection(10, 1027, "裸土未覆盖"),
SafetyHarnessDetection(10, 1028, "未穿安全背带报警"),
UnwashedVehicleDetection(10, 1029, "车辆未清洗报警"),
UnKnow(-1, -1, "未知类型");
private final Integer bigType;
private final Integer smallType;
private final String desc;
AlarmModelEnum(Integer bigType, Integer smallType, String desc) {
this.bigType = bigType;
this.smallType = smallType;
this.desc = desc;
}
public static AlarmModelEnum getAlarmModel(String alarmModel) {
for (AlarmModelEnum value : AlarmModelEnum.values()) {
if (value.name().equals(alarmModel)) {
return value;
}
}
return UnKnow;
}
public Integer getBigType() {
return bigType;
}
public Integer getSmallType() {
return smallType;
}
public String getDesc() {
return desc;
}
}

View File

@@ -0,0 +1,42 @@
package org.dromara.iot.service.unview.model.enums;
import java.util.Objects;
public enum AlarmTypeEnum {
BehaviorAnalysis(1, "行为分析告警数据"),
AlarmRecovery(2, "告警恢复数据"),
FacialCapture(3, "人脸抓拍数据"),
FacialComparison(4, "人脸比对数据"),
BehavioralComparison(5, "行为比对数据"),
HeartBerth(6, "保活数据"),
PointChange(7, "点位变更数据"),
;
private final Integer type;
private final String desc;
AlarmTypeEnum(Integer type, String desc) {
this.type = type;
this.desc = desc;
}
public static AlarmTypeEnum getAlarmType(Integer type) {
AlarmTypeEnum[] values = AlarmTypeEnum.values();
for (AlarmTypeEnum value : values) {
if (Objects.equals(type, value.getType())) {
return value;
}
}
return null;
}
public Integer getType() {
return type;
}
public String getDesc() {
return desc;
}
}

View File

@@ -0,0 +1,126 @@
package org.dromara.iot.service.unview.model.enums;
import lombok.Getter;
import org.springframework.http.HttpMethod;
/**
* 宇视请求枚举
*/
@Getter
public enum UniViewApiEnum {
/**
* 新增人像库
*/
PERSONLIB_ADD("/api/v2/personlib/add", HttpMethod.POST),
PERSONLIB_DEL("/api/v2/personlib/delete", HttpMethod.POST),
PERSONLIB_UPDATE("/api/v2/personlib/update", HttpMethod.POST),
PERSONLIB_FIND("/api/v2/personlib/list", HttpMethod.POST),
/**
* 新增人像
*/
PERSON_ADD("/api/v2/person/add", HttpMethod.POST),
/**
* 批量新增人像
*/
PERSON_BATCH_ADD("/api/v2/person/import", HttpMethod.POST),
/**
* 批量删除
*/
PERSON_BATCH_DEL("/api/v2/person/delete", HttpMethod.POST),
/**
* 修改人像信息
*/
PERSON_UPDATE("/api/v2/person/update", HttpMethod.POST),
/**
* 查询人像信息
*/
PERSON_FIND("/api/v2/person/list", HttpMethod.POST),
/**
* 获取 rsa 公钥
*/
POINT_RAS("/api/v2/rsa/publickey", HttpMethod.POST),
/**
* 通过 onvif 获取设备码流信息
*/
POINT_DEVICE_INFO("/api/v2/channel/device/info", HttpMethod.POST),
/**
* 新增点位
*/
POINT_ADD("/api/v2/channel/add", HttpMethod.POST),
/**
* 删除点位
*/
POINT_DEL("/api/v2/channel/delete", HttpMethod.POST),
/**
* 修改点位信息
*/
POINT_UPDATE("/api/v2/channel/update", HttpMethod.POST),
/**
* 获取点位列表
*/
POINT_FIND("/api/v2/channel/list", HttpMethod.POST),
/**
* 批量新增点位
*/
POINT_BATCH_ADD("/api/v2/channel/import", HttpMethod.POST),
/**
* 跟新布防时间
*/
POINT_CONTROL_TIME_UPDATE("/api/v2/control/time/update", HttpMethod.POST),
/**
* 查询布防时间
*/
POINT_CONTROL_TIME_FIND("/api/v2/control/time/get", HttpMethod.POST),
/**
* 工服库相关
*/
WORK_CLOTHES_LIB_ADD("/api/v2/workclotheslib/add", HttpMethod.POST),
WORK_CLOTHES_LIB_UPDATE("/api/v2/workclotheslib/update", HttpMethod.POST),
WORK_CLOTHES_LIB_DELETE("/api/v2/workclotheslib/delete", HttpMethod.POST),
WORK_CLOTHES_LIB_FIND("/api/v2/workclotheslib/list", HttpMethod.POST),
/**
* 工服管理相关
*/
WORK_CLOTHES_ADD("/api/v2/workclothes/add", HttpMethod.POST),
WORK_CLOTHES_BATCH_ADD("/api/v2/workclothes/batchadd", HttpMethod.POST),
WORK_CLOTHES_DELETE("/api/v2/workclothes/delete", HttpMethod.POST),
WORK_CLOTHES_FIND("/api/v2/workclothes/list", HttpMethod.POST),
/*---------------------------------------------------- 数据检索 -------------------------------------------------------------*/
SEARCH_BEHAVIOR("/api/v2/search/behavior", HttpMethod.POST), // 行为分析检索
SEARCH_FACECAP("/api/v2/search/facecap", HttpMethod.POST), // 人脸检索
SEARCH_BEHAVIORMATCH("/api/v2/search/behaviormatch", HttpMethod.POST), // 行为比对检索
SEARCH_FACEMATCH("/api/v2/search/facematch", HttpMethod.POST), // 人脸检索
;
/**
* 请求uri
*/
private final String uri;
/**
* 请求方法类型
*/
private final HttpMethod method;
/**
* 资源路径描述
*/
UniViewApiEnum(String uri, HttpMethod method) {
this.uri = uri;
this.method = method;
}
}

View File

@@ -0,0 +1,235 @@
package org.dromara.iot.service.unview.service;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.dromara.iot.service.unview.UnViewAiBoxApi;
import org.dromara.iot.service.unview.model.enums.UniViewApiEnum;
import org.dromara.iot.service.unview.utils.UniViewHttp;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static org.dromara.iot.service.unview.model.UvModel.*;
/**
* 宇试AI盒子接口
*
* @author lxj
* @since 2025-06-24
*/
@Slf4j
@Component
public class UnViewAiBoxApiService implements UnViewAiBoxApi {
@Resource
private UniViewHttp uniViewHttp;
public SearchBehaviorResult searchBehavior(UvSystemInfo uvSystemInfo, SearchBehaviorParams params) {
UniViewResult<SearchBehaviorResult> request = uniViewHttp.request(uvSystemInfo, UniViewApiEnum.SEARCH_BEHAVIOR, params, SearchBehaviorResult.class);
return request.getData();
}
public AddLibResult addPersonLib(UvSystemInfo systemInfo, String libName) {
Map<String, String> params = new HashMap<>(1);
params.put("lib_name", libName);
UniViewResult<AddLibResult> request = uniViewHttp.request(systemInfo, UniViewApiEnum.PERSONLIB_ADD, params, AddLibResult.class);
return request.getData();
}
public boolean deletePersonLib(UvSystemInfo systemInfo, Integer... libIds) {
if (libIds.length == 0) {
log.info("libIds 不能为空");
return false;
}
JSONObject params = new JSONObject();
params.put("lib_id", Arrays.asList(libIds));
UniViewResult<Integer> request = uniViewHttp.request(systemInfo, UniViewApiEnum.PERSONLIB_DEL, params, Integer.class);
return request.success();
}
public boolean updatePersonLib(UvSystemInfo systemInfo, Integer libId, String LibName) {
JSONObject params = new JSONObject();
params.put("lib_id", libId);
params.put("lib_name", LibName);
UniViewResult<Integer> request = uniViewHttp.request(systemInfo, UniViewApiEnum.PERSONLIB_UPDATE, params, Integer.class);
return request.success();
}
public QueryLibResult findPagePersonLib(UvSystemInfo systemInfo, String libName, Integer current, Integer size) {
JSONObject params = new JSONObject();
if (StrUtil.isNotBlank(libName)) {
params.put("lib_name", libName);
}
if (current == null) {
current = 1;
}
if (size == null) {
size = 10;
}
params.put("page", current);
params.put("pagesize", size);
UniViewResult<QueryLibResult> request = uniViewHttp.request(systemInfo, UniViewApiEnum.PERSONLIB_FIND, params, QueryLibResult.class);
return request.getData();
}
public AddPersonResult addPerson(UvSystemInfo uvSystemInfo, AddPersonParams addPersonParams) {
UniViewResult<AddPersonResult> request = uniViewHttp.request(uvSystemInfo, UniViewApiEnum.PERSON_ADD, addPersonParams, AddPersonResult.class);
return request.result();
}
public BatchAddPersonResult batchAddPerson(UvSystemInfo uvSystemInfo, BatchAddPersonParams personParams) {
UniViewResult<BatchAddPersonResult> request = uniViewHttp.request(uvSystemInfo, UniViewApiEnum.PERSON_BATCH_ADD, personParams, BatchAddPersonResult.class);
return request.result();
}
public Boolean batchDeletePerson(UvSystemInfo uvSystemInfo, Integer[] personIds) {
JSONObject params = new JSONObject();
params.put("person_id_list", personIds);
UniViewResult<String> request = uniViewHttp.request(uvSystemInfo, UniViewApiEnum.PERSON_BATCH_DEL, params, String.class);
return request.success();
}
public Boolean updatePerson(UvSystemInfo uvSystemInfo, UpdatePersonParams params) {
UniViewResult<String> request = uniViewHttp.request(uvSystemInfo, UniViewApiEnum.PERSON_UPDATE, params, String.class);
return request.success();
}
public queryPersonPageResult findPersonPage(UvSystemInfo uvSystemInfo, queryPersonPageParams params) {
UniViewResult<queryPersonPageResult> request = uniViewHttp.request(uvSystemInfo, UniViewApiEnum.PERSON_FIND, params, queryPersonPageResult.class);
return request.result();
}
/*--------------------------------------------------------------------- 点位管理 -------------------------------------------------------------------------*/
public GetPublickeyResult getPublickey(UvSystemInfo uvSystemInfo) {
UniViewResult<GetPublickeyResult> request = uniViewHttp.request(uvSystemInfo, UniViewApiEnum.POINT_RAS, null, GetPublickeyResult.class);
return request.result();
}
public QueryOnvifResult getOnvif(UvSystemInfo uvSystemInfo) {
JSONObject params = new JSONObject();
params.put("ip", uvSystemInfo.getIp());
params.put("port", uvSystemInfo.getPort());
params.put("username", uvSystemInfo.getAccount());
params.put("pwd", uvSystemInfo.getPassword());
UniViewResult<QueryOnvifResult> request = uniViewHttp.request(uvSystemInfo, UniViewApiEnum.POINT_RAS, params, QueryOnvifResult.class);
return request.result();
}
public AddPointResult addPoint(UvSystemInfo uvSystemInfo, PointParams req) {
UniViewResult<AddPointResult> request = uniViewHttp.request(uvSystemInfo, UniViewApiEnum.POINT_ADD, req, AddPointResult.class);
return request.result();
}
public Boolean deletePoint(UvSystemInfo uvSystemInfo, List<Integer> channelIds) {
JSONObject params = new JSONObject();
params.put("channel_id_list", channelIds);
UniViewResult<String> request = uniViewHttp.request(uvSystemInfo, UniViewApiEnum.POINT_DEL, params, String.class);
return request.success();
}
public Boolean updatePoint(UvSystemInfo uvSystemInfo, UpdatePointParams params) {
UniViewResult<String> request = uniViewHttp.request(uvSystemInfo, UniViewApiEnum.POINT_UPDATE, params, String.class);
return request.success();
}
public QueryPointResult queryPoint(UvSystemInfo uvSystemInfo, QueryPointParams req) {
UniViewResult<QueryPointResult> request = uniViewHttp.request(uvSystemInfo, UniViewApiEnum.POINT_FIND, req, QueryPointResult.class);
return request.result();
}
public BatchAddPersonResult batchAddPoint(UvSystemInfo uvSystemInfo, BatchAddPointParams params) {
UniViewResult<BatchAddPersonResult> request = uniViewHttp.request(uvSystemInfo, UniViewApiEnum.POINT_BATCH_ADD, params, BatchAddPersonResult.class);
return request.result();
}
public Boolean pointControlTimeUpdate(UvSystemInfo uvSystemInfo, ModifyControlTime params) {
UniViewResult<String> request = uniViewHttp.request(uvSystemInfo, UniViewApiEnum.POINT_CONTROL_TIME_UPDATE, params, String.class);
return request.success();
}
public ControlTime queryControlTime(UvSystemInfo uvSystemInfo, Integer channel_id, Integer algo_model) {
JSONObject params = new JSONObject();
params.put("channel_id", channel_id);
params.put("algo_model", algo_model);
UniViewResult<ControlTime> request = uniViewHttp.request(uvSystemInfo, UniViewApiEnum.POINT_CONTROL_TIME_FIND, params, ControlTime.class);
return request.result();
}
/*---------------------------------------------------------------- 工服库 ---------------------------------------------------------------------------*/
public Integer addWorkClothesLib(UvSystemInfo uvSystemInfo, String libName) {
JSONObject params = new JSONObject();
params.put("lib_name", libName);
UniViewResult<Integer> request = uniViewHttp.request(uvSystemInfo, UniViewApiEnum.WORK_CLOTHES_LIB_ADD, params, Integer.class);
return request.result();
}
public Boolean updateWorkClothesLib(UvSystemInfo uvSystemInfo, Integer libId, String libName) {
JSONObject params = new JSONObject();
params.put("lib_id", libId);
params.put("lib_name", libName);
UniViewResult<String> request = uniViewHttp.request(uvSystemInfo, UniViewApiEnum.WORK_CLOTHES_LIB_UPDATE, params, String.class);
return request.success();
}
public Boolean deleteWorkClothesLib(UvSystemInfo uvSystemInfo, Integer libId) {
JSONObject params = new JSONObject();
params.put("lib_id", libId);
UniViewResult<String> request = uniViewHttp.request(uvSystemInfo, UniViewApiEnum.WORK_CLOTHES_LIB_DELETE, params, String.class);
return request.success();
}
public QueryLibResult findPageWorkClothesLib(UvSystemInfo uvSystemInfo, String libName, Integer page, Integer pageSize) {
JSONObject params = new JSONObject();
params.put("lib_name", libName);
params.put("page", page);
params.put("pagesize", pageSize);
UniViewResult<QueryLibResult> request = uniViewHttp.request(uvSystemInfo, UniViewApiEnum.WORK_CLOTHES_LIB_FIND, params, QueryLibResult.class);
return request.result();
}
/*--------------------------------------------------------------------工服 ---------------------------------------------------------------------------*/
public Integer addWorkClothes(UvSystemInfo uvSystemInfo, Integer libId, String imageBase64) {
JSONObject params = new JSONObject();
params.put("lib_id", libId);
params.put("image_base64", imageBase64);
UniViewResult<Integer> request = uniViewHttp.request(uvSystemInfo, UniViewApiEnum.WORK_CLOTHES_ADD, params, Integer.class);
return request.result();
}
public BatchAddWorkClothesResult batchAddWorkClothes(UvSystemInfo uvSystemInfo, Integer libId, List<String> imageBase64s) {
JSONObject params = new JSONObject();
params.put("lib_id", libId);
params.put("image_base64", imageBase64s);
UniViewResult<BatchAddWorkClothesResult> request = uniViewHttp.request(uvSystemInfo, UniViewApiEnum.WORK_CLOTHES_BATCH_ADD, params, BatchAddWorkClothesResult.class);
return request.result();
}
public Boolean deleteWorkClothes(UvSystemInfo uvSystemInfo, Integer libId, List<Integer> workClothesIds) {
JSONObject params = new JSONObject();
params.put("lib_id", libId);
params.put("workclothes_id_list", workClothesIds);
UniViewResult<String> request = uniViewHttp.request(uvSystemInfo, UniViewApiEnum.WORK_CLOTHES_DELETE, params, String.class);
return request.success();
}
public FindWorkClothesResult findPageWorkClothes(UvSystemInfo uvSystemInfo, Integer libId, Integer page, Integer size, Integer status) {
JSONObject params = new JSONObject();
params.put("lib_id", libId);
params.put("page", page);
params.put("pagesize", size);
params.put("model_status", status);
UniViewResult<FindWorkClothesResult> request = uniViewHttp.request(uvSystemInfo, UniViewApiEnum.WORK_CLOTHES_FIND, params, FindWorkClothesResult.class);
return request.result();
}
}

View File

@@ -0,0 +1,121 @@
package org.dromara.iot.service.unview.service;
import lombok.extern.slf4j.Slf4j;
import org.dromara.iot.service.unview.model.UvModel;
import org.dromara.iot.service.unview.model.enums.AlarmTypeEnum;
import org.springframework.stereotype.Service;
/**
* 宇视人体设备告警数据处理
*
* @author lxj
*/
@Slf4j
@Service
public class VideoAlarmService {
public void handleAlarmData(UvModel.AlarmReportInfo alarmReportData) {
Integer type = alarmReportData.getType();
AlarmTypeEnum alarmType = AlarmTypeEnum.getAlarmType(type);
if (alarmType == null) {
log.info("未知的数据上报类型。");
return;
}
switch (alarmType) {
case BehaviorAnalysis: {
handleBehaviorAnalysis(alarmReportData);
break;
}
case AlarmRecovery: {
handleAlarmRecovery(alarmReportData);
break;
}
case FacialCapture: {
handleFacialCapture(alarmReportData);
break;
}
case FacialComparison: {
handleFacialComparison(alarmReportData);
break;
}
case BehavioralComparison: {
handleBehavioralComparison(alarmReportData);
break;
}
case HeartBerth: {
handleHeartBerth(alarmReportData);
break;
}
case PointChange: {
handlePointChange(alarmReportData);
break;
}
}
}
/**
* 设备心跳上报
*
* @param alarmReportData 上报数据
*/
private void handleHeartBerth(UvModel.AlarmReportInfo alarmReportData) {
// 处理心跳数据
log.info("设备心跳数据上报,data={}", alarmReportData);
}
/**
* 行为分析告警数据上报
*
* @param alarmReportData 告警数据
*/
private void handleBehaviorAnalysis(UvModel.AlarmReportInfo alarmReportData) {
}
/**
* 告警恢复数据上报
*
* @param alarmReportData 告警数据
*/
private void handleAlarmRecovery(UvModel.AlarmReportInfo alarmReportData) {
}
/**
* 人脸抓拍上报
*
* @param alarmReportData 告警数据
*/
private void handleFacialCapture(UvModel.AlarmReportInfo alarmReportData) {
}
/**
* 人脸比对数据上报
*
* @param alarmReportData 告警数据
*/
private void handleFacialComparison(UvModel.AlarmReportInfo alarmReportData) {
}
/**
* 行为比对数据上报
*
* @param alarmReportData 告警数据
*/
private void handleBehavioralComparison(UvModel.AlarmReportInfo alarmReportData) {
}
/**
* 点位变更数据上报
*
* @param alarmReportData 告警数据
*/
private void handlePointChange(UvModel.AlarmReportInfo alarmReportData) {
}
}

View File

@@ -0,0 +1,213 @@
package org.dromara.iot.service.unview.utils;
import cn.hutool.core.util.IdUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.http.HttpStatus;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import lombok.extern.slf4j.Slf4j;
import org.dromara.iot.service.unview.model.UvModel;
import org.dromara.iot.service.unview.model.enums.UniViewApiEnum;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static org.dromara.iot.service.unview.model.UvModel.*;
/**
* 宇视HTTP处理
*/
@Slf4j
@Component
public class UniViewHttp {
/**
* 请求头Authorization 字段前缀
*/
public static final String UNIVIEW_HTTP_PROTOCOL = "http://";
/**
* 请求头Authorization 字段前缀
*/
public static final String UNIVIEW_AUTH_PREFIX = "Digest ";
/**
* 宇视请求返回401鉴权信息字段
*/
public static final String UNIVIEW_AUTH_FAIL_PRFIX = "WWW-Authenticate";
/**
* Authorization 放入设备鉴权信息字段
*/
public static final String UNIVIEW_REQUEST_AUTH_KEY = "Authorization";
@Resource
private RestTemplate restTemplate;
/**
* 用于缓存宇视设备鉴权信息的map
* key设备ip
* value设备的鉴权信息
*/
private static final Map<String, UvModel.UvAuthInfo> CACHE_AUTH_MAP = new HashMap<>(16);
public <T> UniViewResult<T> request(UvSystemInfo systemInfo, UniViewApiEnum api, Object data, Class<T> cls) {
UniViewResult<T> result = r(systemInfo, api, data, cls);
if (result.success()) {
log.info("宇视设备请求成功result: {}", result);
return result;
} else if (result.unAuth()) {
// 鉴权失败则再次请求
return r(systemInfo, api, data, cls);
} else {
// 如果请求失败,尝试再次请求,如果依然失败则放弃
return r(systemInfo, api, data, cls);
}
}
/**
* 发起宇视平台请求
* <p>由于宇视所有请求均为POST所以请求的时候不做区分</p>
*
* @param systemInfo 请求到达的设备信息
* @param api 请求资源信息
* @param data 请求数据
* @param cls 返回数据类型
* @param <T> 返回数据裂隙
* @return 返回响应数据
*/
private <T> UniViewResult<T> r(UvSystemInfo systemInfo, UniViewApiEnum api, Object data, Class<T> cls) {
// 生成请求完整路径
String requestUrl = UNIVIEW_HTTP_PROTOCOL + systemInfo.getIp() + ":" + systemInfo.getPort() + api.getUri();
// 获取鉴权信息
UvAuthInfo authData = CACHE_AUTH_MAP.get(systemInfo.getIp());
// 如果存在鉴权信息,依据文档生成鉴权信息
String authorization = null;
if (authData != null) {
authorization = createAuthData(systemInfo, api, authData);
}
try {
// 设置请求头
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
if (authorization != null) {
headers.add(UNIVIEW_REQUEST_AUTH_KEY, authorization);
}
HttpEntity<String> requestEntity = null;
if (data == null) {
requestEntity = new HttpEntity<>(null, headers);
}
if (data instanceof JSONObject) {
JSONObject obj = (JSONObject) data;
requestEntity = new HttpEntity<>(obj.toJSONString(), headers);
} else {
requestEntity = new HttpEntity<>(JSONObject.toJSONString(data), headers);
}
ResponseEntity<String> exchange = restTemplate.exchange(requestUrl, api.getMethod(), requestEntity, String.class);
int statusCode = exchange.getStatusCodeValue();
String body = exchange.getBody();
if (HttpStatus.HTTP_UNAUTHORIZED == statusCode) {
// 处理401请求参数并且返回鉴权信息
handleAuthData(exchange.getHeaders(), systemInfo);
UvAuthInfo authData1 = CACHE_AUTH_MAP.get(systemInfo.getIp());
log.info("宇视设备请求返回401, 开始处理鉴权数据authData1 = {}", authData1);
return JSONObject.parseObject(body, new TypeReference<UniViewResult<T>>(cls) {
});
}
UniViewResult<T> result = JSONObject.parseObject(body, new TypeReference<UniViewResult<T>>(cls) {
});
log.info("宇视设备请求返回完成result={}", result);
return result;
} catch (Exception e) {
log.info("发起宇视设备请求失败,msg:{}", e.getMessage());
if (e instanceof HttpClientErrorException exception) {
if (exception.getStatusCode().value() == 401) {
HttpHeaders responseHeaders = exception.getResponseHeaders();
handleAuthData(responseHeaders, systemInfo);
UvAuthInfo authData1 = CACHE_AUTH_MAP.get(systemInfo.getIp());
log.info("宇视设备请求返回401, 开始处理鉴权数据authData1 = {}", authData1);
}
}
UniViewResult<T> uniViewResult = new UniViewResult<>();
uniViewResult.setCode(-1);
uniViewResult.setMsg("发起请求异常,msg=" + e.getMessage());
uniViewResult.setStatus_code(-1);
return uniViewResult;
}
}
private static String createAuthData(UvSystemInfo systemInfo, UniViewApiEnum api, UvAuthInfo authData) {
// r1 原始字符串
String OriginalR1 = systemInfo.getAccount() + ":" + authData.getRealm() + ":" + systemInfo.getPassword();
// 进行md5加密
String md5R1 = SecureUtil.md5(OriginalR1);
// 生成r1
// String r1 = HexUtil.encodeHexStr(md5R1);
// r2原始字符串
String OriginalR2 = api.getMethod().name() + ":" + api.getUri();
// 进行md5加密
String md5R2 = SecureUtil.md5(OriginalR2);
// 生成r1
// String r2 = HexUtil.encodeHexStr(md5R2);
// response 原始字符串
String cnonce = IdUtil.fastSimpleUUID();
String nc = "00000002";
String OriginalResponse = md5R1 + ":" + authData.getNonce() + ":" + nc + ":" + cnonce + ":" + authData.getQop() + ":" + md5R2;
// 进行md5加密
String md5Response = SecureUtil.md5(OriginalResponse);
// 生成r1
// String response = HexUtil.encodeHexStr(md5Response);
return UNIVIEW_AUTH_PREFIX + "username=\"" + systemInfo.getAccount() + "\"," +
"realm=\"" + authData.getRealm() + "\"," +
"nonce=\"" + authData.getNonce() + "\"," +
"uri=\"" + api.getUri() + "\"," +
"algorithm=\"" + authData.getAlgorithm() + "\"," +
"qop=\"" + authData.getQop() + "\"," +
"nc=\"" + nc + "\"," +
"cnonce=\"" + cnonce + "\"," +
"response=\"" + md5Response + "\"";
}
/**
* 解析响应体参数并缓存到鉴权map里
*/
private void handleAuthData(HttpHeaders responseHeaders, UvSystemInfo systemInfo) {
List<String> headers = responseHeaders.get(UNIVIEW_AUTH_FAIL_PRFIX);
headers.forEach(header -> {
log.info("获取到宇视设备返回的响应体参数: data: {}", header);
if (header.startsWith(UNIVIEW_AUTH_PREFIX)) {
header = header.replace(UNIVIEW_AUTH_PREFIX, "");
}
String[] s = header.split(",");
if (s.length > 0) {
Map<String, String> m = new HashMap<>();
for (String str : s) {
String[] split = str.split("=");
String s1 = split[1].replaceAll("\"", "");
m.put(split[0], s1);
}
UvRequestAuthInfo authData = new UvRequestAuthInfo();
authData.setAlgorithm(m.get("algorithm"));
authData.setQop(m.get("qop"));
authData.setRealm(m.get("realm"));
authData.setNonce(m.get("nonce"));
authData.setStale(m.get("stale"));
CACHE_AUTH_MAP.put(systemInfo.getIp(), authData);
log.info("生成鉴权信息成功, authData={}", authData);
}
});
}
}

View File

@@ -0,0 +1,34 @@
# Tomcat
server:
port: 10001
# Spring
spring:
application:
# 应用名称
name: Sis
profiles:
# 环境配置
active: @profiles.active@
--- # nacos 配置
spring:
cloud:
nacos:
# nacos 服务地址
server-addr: @nacos.server@
username: @nacos.username@
password: @nacos.password@
discovery:
# 注册组
group: @nacos.discovery.group@
namespace: ${spring.profiles.active}
config:
# 配置组
group: @nacos.config.group@
namespace: ${spring.profiles.active}
config:
import:
- optional:nacos:application-common.yml
- optional:nacos:datasource.yml
- optional:nacos:${spring.application.name}.yml

View File

@@ -0,0 +1,10 @@
Spring Boot Version: ${spring-boot.version}
Spring Application Name: ${spring.application.name}
_ _
(_) | |
_ __ _ _ ___ _ _ _ ______ ___ _ _ ___ | |_ ___ _ __ ___
| '__|| | | | / _ \ | | | || ||______|/ __|| | | |/ __|| __| / _ \| '_ ` _ \
| | | |_| || (_) || |_| || | \__ \| |_| |\__ \| |_ | __/| | | | | |
|_| \__,_| \___/ \__, ||_| |___/ \__, ||___/ \__| \___||_| |_| |_|
__/ | __/ |
|___/ |___/

View File

@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<!-- 日志存放路径 -->
<property name="log.path" value="logs/${project.artifactId}" />
<!-- 日志输出格式 -->
<property name="console.log.pattern"
value="%cyan(%d{yyyy-MM-dd HH:mm:ss}) %green([%thread]) %highlight(%-5level) %boldMagenta(%logger{36}%n) - %msg%n"/>
<!-- 控制台输出 -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${console.log.pattern}</pattern>
<charset>utf-8</charset>
</encoder>
</appender>
<include resource="logback-common.xml" />
<include resource="logback-logstash.xml" />
<!-- 开启 skywalking 日志收集 -->
<include resource="logback-skylog.xml" />
<!--系统操作日志-->
<root level="info">
<appender-ref ref="console" />
</root>
</configuration>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.dromara.iot.mapper.TbAccessControlMapper">
</mapper>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.dromara.iot.mapper.TdFactoryMapper">
</mapper>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.dromara.iot.mapper.TdMeterConfigMapper">
</mapper>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.dromara.iot.mapper.TdMeterMapper">
</mapper>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.dromara.iot.mapper.TdMeterRoomMapper">
</mapper>