diff --git a/ruoyi-modules/E8Service/src/main/java/org/dromara/E8Service/Service/base/DoorDeviceService.java b/ruoyi-modules/E8Service/src/main/java/org/dromara/E8Service/Service/base/DoorDeviceService.java new file mode 100644 index 0000000..08bad5e --- /dev/null +++ b/ruoyi-modules/E8Service/src/main/java/org/dromara/E8Service/Service/base/DoorDeviceService.java @@ -0,0 +1,57 @@ +package org.dromara.E8Service.Service.base; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import org.dromara.E8Service.domain.DoorDevice.req.DoorDeviceAddReq; +import org.dromara.E8Service.domain.DoorDevice.req.DoorDeviceUpdateReq; +import org.dromara.E8Service.domain.DoorDevice.res.DoorDeviceAddRes; +import org.dromara.E8Service.domain.DoorDevice.res.DoorDeviceFindRes; +import org.dromara.E8Service.domain.DoorDevice.res.DoorDeviceUpdateRes; +import org.dromara.E8Service.domain.QueryDto; + +/** + * @author lsm + * @apiNote DoorDeviceService + * @since 2025/6/20 + */ +public interface DoorDeviceService { + + /** + * 查询门禁信息 + * + * @param id 入参 + * @return DoorDeviceFindRes + */ + DoorDeviceFindRes findDoorDevice(Long id); + + /** + * 门禁信息分页查询 + * + * @param dto 入参 + * @return IPage + */ + IPage findDoorDeviceList(QueryDto dto); + + /** + * 新增门禁信息 + * + * @param addReq 入参 + * @return DoorDeviceAddRes + */ + DoorDeviceAddRes addDoorDevice(DoorDeviceAddReq addReq); + + /** + * 门禁信息修改 + * + * @param updateReq 入参 + * @return DoorDeviceUpdateRes + */ + DoorDeviceUpdateRes updateDoorDevice(DoorDeviceUpdateReq updateReq); + + /** + * 删除门禁信息 + * + * @param id 入参 + * @return Boolean + */ + Boolean deleteDoorDevice(Integer id); +} diff --git a/ruoyi-modules/E8Service/src/main/java/org/dromara/E8Service/Service/base/impl/DoorDeviceServiceImpl.java b/ruoyi-modules/E8Service/src/main/java/org/dromara/E8Service/Service/base/impl/DoorDeviceServiceImpl.java new file mode 100644 index 0000000..e97063e --- /dev/null +++ b/ruoyi-modules/E8Service/src/main/java/org/dromara/E8Service/Service/base/impl/DoorDeviceServiceImpl.java @@ -0,0 +1,184 @@ +package org.dromara.E8Service.Service.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.apache.dubbo.config.annotation.DubboService; +import org.dromara.E8Service.Service.base.DoorDeviceService; +import org.dromara.E8Service.domain.ApiResp; +import org.dromara.E8Service.domain.DoorDevice.req.DoorDeviceAddReq; +import org.dromara.E8Service.domain.DoorDevice.req.DoorDeviceFindReq; +import org.dromara.E8Service.domain.DoorDevice.req.DoorDeviceUpdateReq; +import org.dromara.E8Service.domain.DoorDevice.res.DoorDeviceAddRes; +import org.dromara.E8Service.domain.DoorDevice.res.DoorDeviceFindRes; +import org.dromara.E8Service.domain.DoorDevice.res.DoorDeviceUpdateRes; +import org.dromara.E8Service.domain.QueryDto; +import org.dromara.E8Service.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 +@DubboService +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.error("查询E8门禁信息失败 errorMsg:{}", apiResp); + // 如果响应不成功,则返回null + return null; + } + + // 将API响应结果转换为指定的Java对象,并返回该对象 + return JSONUtil.toBean(JSONUtil.toJsonStr(apiResp.getResult()), DoorDeviceFindRes.class); + } + + /** + * 门禁信息分页查询 + * + * @param dto 传参 + * @return IPage + */ + @Override + public IPage findDoorDeviceList(QueryDto dto) { + // 创建一个参数映射,用于存储API请求所需的参数 + Map params = new HashMap<>(); + // 将分页索引和最大结果数放入参数映射中 + params.put("PageIndex", dto.getPageIndex()); + params.put("MaxResultCount", dto.getMaxResultCount()); + // 将查询DTO转换为JSON字符串,再转换为Map对象,然后放入参数映射中 + params.put("QueryDto", JSONUtil.toBean(JSONUtil.toJsonStr(dto.getQueryDto()), DoorDeviceFindReq.class)); + + // 调用第三方API,获取门禁设备分页列表 + ApiResp apiResp = e8ApiUtil.doPost(params, DOOR_DEVICE_GET_PAGE_LIST); + + // 如果API调用不成功,则返回null + if (!apiResp.getSuccess()) { + log.error("分页查询E8门禁信息失败 errorMsg:{}", apiResp); + // 如果响应不成功,则返回null + return null; + } + + // 将API响应结果转换为Map对象,以便后续处理 + Map result = JSONUtil.toBean(JSONUtil.toJsonStr(apiResp.getResult()), new TypeReference<>() { + }, false); + // 创建一个分页对象,用于存储处理后的门禁设备信息 + IPage page = new Page<>(dto.getPageIndex(), dto.getMaxResultCount()); + // 设置分页对象的总记录数 + page.setTotal(Long.parseLong(result.get("total").toString())); + // 将API响应结果中的门禁设备信息列表转换为DoorDeviceFindRes对象列表,并设置到分页对象中 + page.setRecords(JSONUtil.toList(JSONUtil.toJsonStr(result.get("item")), DoorDeviceFindRes.class)); + + // 返回处理后的分页对象 + return page; + } + + /** + * 新增门禁信息 + * + * @param addReq 传参 + * @return Boolean + */ + @Override + public DoorDeviceAddRes addDoorDevice(DoorDeviceAddReq addReq) { + // 将DoorDeviceAddReq转为Map对象,以便作为API请求的参数 + Map params = BeanUtil.beanToMap(addReq); + + // 调用第三方API进行门禁设备创建,并传入转换后的参数 + ApiResp apiResp = e8ApiUtil.doPost(params, DOOR_DEVICE_CREATE); + + if (!apiResp.getSuccess()) { + log.error("新增E8门禁信息,errorMsg:{}", apiResp); + // 如果响应不成功,则返回null + return null; + } + + return JSONUtil.toBean(JSONUtil.toJsonStr(apiResp.getResult()), DoorDeviceAddRes.class); + } + + /** + * 门禁信息修改 + * + * @param updateReq 传参 + * @return DoorDeviceUpdateRes + */ + @Override + public DoorDeviceUpdateRes updateDoorDevice(DoorDeviceUpdateReq updateReq) { + + // 构造门设备更新API的URL + String api = DOOR_DEVICE_UPDATE.replace("{id}", updateReq.getId().toString()); + + // 将门设备信息对象转换为键值对形式的参数 + Map params = BeanUtil.beanToMap(updateReq); + + // 调用API进行门设备信息更新 + ApiResp apiResp = e8ApiUtil.doPost(params, api); + + if (!apiResp.getSuccess()) { + log.error("修改E8门禁信息,errorMsg:{}", apiResp); + // 如果响应不成功,则返回null + return null; + } + + return JSONUtil.toBean(JSONUtil.toJsonStr(apiResp.getResult()), DoorDeviceUpdateRes.class); + } + + /** + * 删除门禁信息 + * + * @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); + + if (!apiResp.getSuccess()) { + log.error("删除E8门禁信息,errorMsg:{}", apiResp); + } + + // 返回API响应的成功标志 + return apiResp.getSuccess(); + } + +} diff --git a/ruoyi-modules/E8Service/src/main/java/org/dromara/E8Service/Service/business/VoucherControlService.java b/ruoyi-modules/E8Service/src/main/java/org/dromara/E8Service/Service/business/VoucherControlService.java index 1266251..998a75e 100644 --- a/ruoyi-modules/E8Service/src/main/java/org/dromara/E8Service/Service/business/VoucherControlService.java +++ b/ruoyi-modules/E8Service/src/main/java/org/dromara/E8Service/Service/business/VoucherControlService.java @@ -5,7 +5,7 @@ package org.dromara.E8Service.Service.business; * @apiNote VoucherControlService * @since 2025/6/24 */ -public class VoucherControlService { +public interface VoucherControlService { /** * 上传人脸 diff --git a/ruoyi-modules/E8Service/src/main/java/org/dromara/E8Service/domain/ApiResp.java b/ruoyi-modules/E8Service/src/main/java/org/dromara/E8Service/domain/ApiResp.java new file mode 100644 index 0000000..7a6d95d --- /dev/null +++ b/ruoyi-modules/E8Service/src/main/java/org/dromara/E8Service/domain/ApiResp.java @@ -0,0 +1,38 @@ +package org.dromara.E8Service.domain; + +import lombok.AllArgsConstructor; +import lombok.Data; + +/** + * @author lsm + * @apiNote ApiResp + * @since 2025/6/20 + */ +@Data +@AllArgsConstructor +public class ApiResp { + /** + * success为false时返回错误信息 + */ + private String message; + + /** + * sessionId + */ + private Long sessionId; + + /** + * 返回处理结果(数据由具体接口决定) + */ + private Object result; + + /** + * true表示成功,false表示失败 + */ + private Boolean success; + + /** + * 状态码 0表示成功,1表示失败 + */ + private Integer code; +} diff --git a/ruoyi-modules/E8Service/src/main/java/org/dromara/E8Service/domain/DoorDevice/req/DoorDeviceAddReq.java b/ruoyi-modules/E8Service/src/main/java/org/dromara/E8Service/domain/DoorDevice/req/DoorDeviceAddReq.java new file mode 100644 index 0000000..92d150d --- /dev/null +++ b/ruoyi-modules/E8Service/src/main/java/org/dromara/E8Service/domain/DoorDevice/req/DoorDeviceAddReq.java @@ -0,0 +1,140 @@ +package org.dromara.E8Service.domain.DoorDevice.req; + +import lombok.Data; + +/** + * @author lsm + * @apiNote DoorDeviceAddReq + * @since 2025/6/20 + */ +@Data +public class DoorDeviceAddReq { + + /** + * 设备名称 + */ + private String name; + + /** + * 父设备ID + */ + private Long parentId; + + /** + * 设备IP + */ + private String ip; + + /** + * 设备端口 + */ + private Long port; + + /** + * 设备MAC + */ + private String mac; + + /** + * 子网掩码 + */ + private String netMask; + + /** + * 设备网关 + */ + private String gatewayIP; + + /** + * 设备产品线类型 + * 0:车行 1:车位 2:人行 + */ + private Integer productType; + + /** + * 设备类型 + * 2201:一体式门禁 2202:分体式门禁 2203:人脸门禁 2204:梯控 2207:人脸盒子终端 + * 2208:人脸盒子面板机 2209:一体式读头 2211:梯控读头 2102:电子哨兵 + */ + private Long type; + + /** + * 业务逻辑设备类 + */ + private Integer logicType; + + /** + * 设备型号 + */ + private Integer model; + + /** + * 设备序列号 + */ + private String sn; + + /** + * 设备CPUID + */ + private String cpuID; + + /** + * 设备在线状态 0:离线 1:在线 2:未知 + */ + private Integer status; + + /** + * 设备在线状态描述 + */ + private String statusDescription; + + /** + * 机号 + */ + private String macNo; + + /** + * 蓝牙地址 + */ + private String bluetoothAddr; + + /** + * 设备层级 + */ + private Integer deviceLevel; + + /** + * 备注 + */ + private String remark; + + /** + * 设备通讯方式 0:TCP/IP 1:RS485 + */ + private Integer commType; + + /** + * 旧IP + */ + private String oldIp; + + /** + * 旧端口号 + */ + private Integer oldPort; + + /** + * 旧机号 + */ + private String oldMacNo; + + /** + * 工单号(设备搜索) + */ + private String projectNumber; + + /** + * 固件版本信息(设备搜索) + */ + private String version; +} diff --git a/ruoyi-modules/E8Service/src/main/java/org/dromara/E8Service/domain/DoorDevice/req/DoorDeviceFindReq.java b/ruoyi-modules/E8Service/src/main/java/org/dromara/E8Service/domain/DoorDevice/req/DoorDeviceFindReq.java new file mode 100644 index 0000000..b509ce6 --- /dev/null +++ b/ruoyi-modules/E8Service/src/main/java/org/dromara/E8Service/domain/DoorDevice/req/DoorDeviceFindReq.java @@ -0,0 +1,43 @@ +package org.dromara.E8Service.domain.DoorDevice.req; + +import lombok.Data; + +/** + * @author lsm + * @apiNote DoorDeviceFindReq + * @since 2025/6/20 + */ +@Data +public class DoorDeviceFindReq { + /** + * 主键 + */ + private Long id; + + /** + * 是否脱敏 true脱敏,敏感信息加***隐藏;false完整显示 + */ + private Boolean isViewFullData; + + /** + * 设备名称 + */ + private String name; + + /** + * 设备类型 + * 2201:一体式门禁 2202:分体式门禁 2203:人脸门禁 2204:梯控 2207:人脸盒子终端 + * 2208:人脸盒子面板机 2209:一体式读头 2211:梯控读头 2102:电子哨兵 + */ + private Long type; + + /** + * 设备型号 + */ + private Integer model; + + /** + * 设备在线状态 0:离线 1:在线 2:未知 + */ + private Integer status; +} diff --git a/ruoyi-modules/E8Service/src/main/java/org/dromara/E8Service/domain/DoorDevice/req/DoorDeviceUpdateReq.java b/ruoyi-modules/E8Service/src/main/java/org/dromara/E8Service/domain/DoorDevice/req/DoorDeviceUpdateReq.java new file mode 100644 index 0000000..efa08e1 --- /dev/null +++ b/ruoyi-modules/E8Service/src/main/java/org/dromara/E8Service/domain/DoorDevice/req/DoorDeviceUpdateReq.java @@ -0,0 +1,139 @@ +package org.dromara.E8Service.domain.DoorDevice.req; + +import lombok.Data; + +/** + * @author lsm + * @apiNote DoorDeviceUpdateReq + * @since 2025/6/20 + */ +@Data +public class DoorDeviceUpdateReq { + /** + * 主键 + */ + private Long id; + + /** + * 设备名称 + */ + private String name; + + /** + * 父设备ID + */ + private Long parentId; + + /** + * 设备IP + */ + private String ip; + + /** + * 设备端口 + */ + private Long port; + + /** + * 设备MAC + */ + private String mac; + + /** + * 子网掩码 + */ + private String netMask; + + /** + * 设备网关 + */ + private String gatewayIP; + + /** + * 设备产品线类型 + * 0:车行 1:车位 2:人行 + */ + private Integer productType; + + /** + * 设备类型 + * 2201:一体式门禁 2202:分体式门禁 2203:人脸门禁 2204:梯控 2207:人脸盒子终端 + * 2208:人脸盒子面板机 2209:一体式读头 2211:梯控读头 2102:电子哨兵 + */ + private Long type; + + /** + * 业务逻辑设备类 + */ + private Integer logicType; + + /** + * 设备型号 + */ + private Integer model; + + /** + * 设备序列号 + */ + private String sn; + + /** + * 设备CPUID + */ + private String cpuID; + + /** + * 机号 + */ + private String macNo; + + /** + * 蓝牙地址 + */ + private String bluetoothAddr; + + /** + * 设备层级 + */ + private Integer deviceLevel; + + /** + * 设备是否需要系统升级 + */ + private Boolean isNeedUpgrade; + + /** + * 备注 + */ + private String remark; + + /** + * 设备通讯方式 0:TCP/IP 1:RS485 + */ + private Integer commType; + + /** + * 旧IP + */ + private String oldIp; + + /** + * 旧端口号 + */ + private Integer oldPort; + + /** + * 旧机号 + */ + private String oldMacNo; + + /** + * 工单号(设备搜索) + */ + private String projectNumber; + + /** + * 固件版本信息(设备搜索) + */ + private String version; +} diff --git a/ruoyi-modules/E8Service/src/main/java/org/dromara/E8Service/domain/DoorDevice/res/DoorDeviceAddRes.java b/ruoyi-modules/E8Service/src/main/java/org/dromara/E8Service/domain/DoorDevice/res/DoorDeviceAddRes.java new file mode 100644 index 0000000..3fd8b13 --- /dev/null +++ b/ruoyi-modules/E8Service/src/main/java/org/dromara/E8Service/domain/DoorDevice/res/DoorDeviceAddRes.java @@ -0,0 +1,198 @@ +package org.dromara.E8Service.domain.DoorDevice.res; + +import lombok.Data; + +import java.util.List; + +/** + * @author lsm + * @apiNote DoorDeviceAddRes + * @since 2025/6/20 + */ +@Data +public class DoorDeviceAddRes { + /** + * 设备ID + */ + private Long id; + /** + * 创建时间 + */ + private String creationTime; + /** + * 创建者ID + */ + private String creatorId; + /** + * 修改时间 + */ + private String lastModificationTime; + /** + * 修改者ID + */ + private String lastModifierId; + /** + * 是否删除 + */ + private Boolean isDeleted; + /** + * 删除者ID + */ + private String deleterId; + /** + * 删除时间 + */ + private String deletionTime; + /** + * 设备编号 + */ + private String no; + /** + * 设备编号编码 + */ + private Integer noCode; + /** + * cloudId + */ + private String cloudId; + /** + * name + */ + private String name; + /** + * 父级设备名称 + */ + private String parentName; + /** + * 父级设备ID,默认0 + */ + private Integer parentId; + /** + * 管理机IP + */ + private String masterIp; + /** + * 设备IP + */ + private String ip; + /** + * 设备端口 + */ + private Long port; + /** + * 设备MAC + */ + private String mac; + /** + * 子网掩码 + */ + private String netMask; + /** + * 设备网关 + */ + private String gatewayIP; + /** + * 设备产品线类型 0:车行 1:车位 2:人行 + */ + private Integer productType; + /** + * 设备类型 + */ + private Long type; + /** + * 设备类型描述 + */ + private String typeDescription; + /** + * 业务逻辑设备类型 + */ + private Integer logicType; + /** + * 设备型号 + */ + private Integer model; + /** + * 设备型号描述 + */ + private String modelDescription; + /** + * 机号 + */ + private String modelName; + /** + * 设备序列号 + */ + private String sn; + /** + * 设备CPUID + */ + private String cpuID; + /** + * 设备在线状态 0:离线 1:在线 2:未知 + */ + private Integer status; + /** + * 设备在线状态描述 + */ + private String statusDescription; + /** + * 机号 + */ + private String macNo; + /** + * 蓝牙地址 + */ + private String bluetoothAddr; + /** + * 设备层级 + */ + private Integer deviceLevel; + /** + * 父级设备路径 默认空 + */ + private String parentIdPath; + /** + * 是否需要升级 + */ + private Boolean isNeedUpgrade; + /** + * 项目ID + */ + private Integer projectId; + /** + * 创建者 + */ + private String creatorName; + /** + * 关联门 + */ + private String relDoors; + /** + * int32 出入口类型 0:未知 1:入口 2:出口 + */ + private Integer gatewayType; + /** + * 出入口类型 + */ + private String gatewayTypeDesc; + /** + * 备注 + */ + private String remark; + /** + * 设备通讯方式 0:TCP/IP 1:RS485 + */ + private Integer commType; + /** + * 工单号(设备搜索) + */ + private String projectNumber; + /** + * 固件版本信息(设备搜索) + */ + private String version; + /** + * 子设备列表 + */ + private List childList; +} diff --git a/ruoyi-modules/E8Service/src/main/java/org/dromara/E8Service/domain/DoorDevice/res/DoorDeviceFindRes.java b/ruoyi-modules/E8Service/src/main/java/org/dromara/E8Service/domain/DoorDevice/res/DoorDeviceFindRes.java new file mode 100644 index 0000000..00d1d9d --- /dev/null +++ b/ruoyi-modules/E8Service/src/main/java/org/dromara/E8Service/domain/DoorDevice/res/DoorDeviceFindRes.java @@ -0,0 +1,251 @@ +package org.dromara.E8Service.domain.DoorDevice.res; + +import lombok.Data; + +import java.util.List; + +/** + * @author lsm + * @apiNote DoorDeviceFindRes + * @since 2025/6/20 + */ +@Data +public class DoorDeviceFindRes { + /** + * 主键 + */ + private Long id; + + /** + * 创建时间 + */ + private String creationTime; + + /** + * 创建人 + */ + private String creatorId; + + /** + * 最后修改时间 + */ + private String lastModificationTime; + + /** + * 最后修改人 + */ + private String lastModifierId; + + /** + * 是否删除 + */ + private Boolean isDeleted; + + /** + * 删除人 + */ + private String deleterId; + + /** + * 删除时间 + */ + private String deletionTime; + + /** + * 设备编号 + */ + private String no; + + /** + * 设备编号序列号 + */ + private Integer noCode; + + /** + * 设备对接平台的ID + */ + private String cloudId; + + /** + * 设备名称 + */ + private String name; + + /** + * 父设备ID + */ + private Long parentId; + + /** + * 父设备名称 + */ + private String parentName; + + /** + * 管理机IP + */ + private String masterIp; + + /** + * 设备IP + */ + private String ip; + + /** + * 设备端口 + */ + private Long port; + + /** + * 设备MAC + */ + private String mac; + + /** + * 子网掩码 + */ + private String netMask; + + /** + * 设备网关 + */ + private String gatewayIP; + + /** + * 设备产品线类型 + * 0:车行 1:车位 2:人行 + */ + private Integer productType; + + /** + * 设备类型 + * 2201:一体式门禁 2202:分体式门禁 2203:人脸门禁 2204:梯控 2207:人脸盒子终端 + * 2208:人脸盒子面板机 2209:一体式读头 2211:梯控读头 2102:电子哨兵 + */ + private Long type; + + /** + * 设备类型描述 + */ + private String typeDescription; + + /** + * 业务逻辑设备类 + */ + private Integer logicType; + + /** + * 设备型号 + */ + private Integer model; + + /** + * 设备型号描述 + */ + private String modelDescription; + + /** + * 设备型号名称 + */ + private String modelName; + + /** + * 设备序列号 + */ + private String sn; + + /** + * 设备CPUID + */ + private String cpuID; + + /** + * 设备在线状态 0:离线 1:在线 2:未知 + */ + private Integer status; + + /** + * 设备在线状态描述 + */ + private String statusDescription; + + /** + * 机号 + */ + private String macNo; + + /** + * 蓝牙地址 + */ + private String bluetoothAddr; + + /** + * 设备层级 + */ + private Integer deviceLevel; + + /** + * 父级设备路径ID列表 + */ + private String parentIdPath; + + /** + * 设备是否需要系统升级 + */ + private Boolean isNeedUpgrade; + + /** + * 项目ID + */ + private Integer projectId; + + /** + * 设备关联的区域组ID + */ + private Integer deviceGroupId; + + /** + * 创建人名称 + */ + private String creatorName; + + /** + * 关联门 + */ + private String relDoors; + + /** + * 出入口类型 0:未知 1:入口 2:出口 + */ + private Integer gatewayType; + + /** + * 出入口类型 + */ + private String gatewayTypeDesc; + + /** + * 备注 + */ + private String remark; + + /** + * 子设备列表 + */ + private List childList; + + /** + * 设备通讯方式 0:TCP/IP 1:RS485 + */ + private Integer commType; + + /** + * 工单号(设备搜索) + */ + private String projectNumber; + + /** + * 固件版本信息(设备搜索) + */ + private String version; +} diff --git a/ruoyi-modules/E8Service/src/main/java/org/dromara/E8Service/domain/QueryDto.java b/ruoyi-modules/E8Service/src/main/java/org/dromara/E8Service/domain/QueryDto.java new file mode 100644 index 0000000..d4156aa --- /dev/null +++ b/ruoyi-modules/E8Service/src/main/java/org/dromara/E8Service/domain/QueryDto.java @@ -0,0 +1,26 @@ +package org.dromara.E8Service.domain; + +import lombok.Data; + +/** + * @author lsm + * @apiNote QueryDto + * @since 2025/6/20 + */ +@Data +public class QueryDto { + /** + * 页数 + */ + private Integer pageIndex; + + /** + * 每页条数 + */ + private Integer maxResultCount; + + /** + * 请求参数 + */ + private Object queryDto; +} diff --git a/ruoyi-modules/E8Service/src/main/java/org/dromara/E8Service/utils/E8ApiUtil.java b/ruoyi-modules/E8Service/src/main/java/org/dromara/E8Service/utils/E8ApiUtil.java new file mode 100644 index 0000000..93bc2d1 --- /dev/null +++ b/ruoyi-modules/E8Service/src/main/java/org/dromara/E8Service/utils/E8ApiUtil.java @@ -0,0 +1,251 @@ +package org.dromara.E8Service.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.E8Service.domain.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://47.109.37.87:4000"; + private static final String SECRET_KEY = "ZG4ocLq1"; + private static final String KEY = "b97c7090379f490bb4b2ead0f57fd1bf"; + + /** + * 发起Post请求 + * + * @param params 请求入参 + * @param api 请求接口 + * @return 请求结果 + */ + public ApiResp doPost(Map params, String api) { + // 时间戳 + String timestamp = Long.toString(System.currentTimeMillis()); + // sign签名 + String sign = getPostSign(params, api, timestamp); + // url + String url = BASE_URL + api; + + // 将params转换为JSON字符串 + String jsonBody = JSONUtil.toJsonStr(params); + // 对请求体进行Base64加密,指定UTF-8编码,避免乱码 + String base64Body = Base64.getEncoder().encodeToString(jsonBody.getBytes(StandardCharsets.UTF_8)); + + // 发送请求获取响应 + // 使用 try-with-resources 确保资源释放 + try (HttpResponse response = HttpRequest.post(url) + .header("Content-Type", "application/json") + .header("key", KEY) + .header("timestamp", timestamp) + .header("sign", sign) + .body(base64Body) + .execute()) { + + return JSONUtil.toBean(response.body(), ApiResp.class); + } + } + + /** + * 发起Get/Delete请求 + * + * @param api 请求接口 + * @param paramStr 请求入参 + * @return 请求结果 + */ + public ApiResp doGetOrDel(String api, String paramStr, Boolean isDelete) { + // 时间戳 + String timestamp = Long.toString(System.currentTimeMillis()); + // sign签名 + String sign = getGetSign(api, timestamp); + // url + String url = BASE_URL + api; + + if (isDelete) { + // 发送请求获取响应 + // 使用 try-with-resources 确保资源释放 + try (HttpResponse response = HttpRequest.delete(url) + .header("key", KEY) + .header("sign", sign) + .header("timestamp", timestamp) + .header("paramstr", paramStr == null ? "50014" : paramStr).execute()) { + return JSONUtil.toBean(response.body(), ApiResp.class); + } + } else { + // 发送请求获取响应 + // 使用 try-with-resources 确保资源释放 + try (HttpResponse response = HttpRequest.get(url) + .header("key", KEY) + .header("sign", sign) + .header("timestamp", timestamp) + .header("paramstr", paramStr == null ? "50014" : paramStr).execute()) { + return JSONUtil.toBean(response.body(), ApiResp.class); + } + } + } + + /** + * e8人脸图片上传接口 + * + * @param imageByte 请求入参 + * @return 请求结果 + */ + public ApiResp doFaceImgUpload(byte[] imageByte) { + // 请求地址 + String api = "/api/E8/voucher/upload-images"; + // 时间戳 + String timestamp = Long.toString(System.currentTimeMillis()); + // sign签名 + String sign = getPostSign(null, api, timestamp); + // url + String url = BASE_URL + api; + + // 创建HttpRequest对象,设置请求参数 + // 使用 try-with-resources 确保资源释放 + try(HttpResponse response = HttpRequest.post(url) + .header("Content-Type", "multipart/form-data") + .header("key", KEY) + .header("sign", sign) + .header("timestamp", timestamp) + .form("file", imageByte, "image.jpg") + .execute()){ + + return JSONUtil.toBean(response.body(), ApiResp.class); + } + } + + /** + * 获取Post接口签名Sign + * + * @param params 请求入参 + * @param api 请求接口 + * @param timestamp 时间戳 + * @return Post接口签名sign + */ + public String getPostSign(Map params, String api, String timestamp) { + String url = BASE_URL + api; + // one&two + String paramsUrl = buildUrlWithParams(url, params) + "×tamp=" + timestamp; + // three + String upperUrl = paramsUrl.toUpperCase(); + // four + String secretUrl = upperUrl + SECRET_KEY; + // five(同时剔除问号) + String md5Url = DigestUtil.md5Hex(secretUrl.replace("?", "")); + // six + return md5Url.toUpperCase(); + } + + /** + * 获取Get接口签名Sign + * + * @param api 请求接口 + * @param timestamp 时间戳 + * @return get/Delete接口签名sign + */ + public String getGetSign(String api, String timestamp) { + // one + String url = BASE_URL + api + timestamp; + String upperUrl = url.toUpperCase(); + // two + String secretUrl = upperUrl + SECRET_KEY; + // three + String md5Url = DigestUtil.md5Hex(secretUrl); + // four + return md5Url.toUpperCase(); + + } + + /** + * Post请求url拼接参数 + * + * @param url 请求链接 + * @param params 请求入参 + * @return 拼接参数后的url + */ + public String buildUrlWithParams(String url, Map params) { + if (params == null || params.isEmpty()) { + return url; + } + + // 过滤出指定类型的参数 + Map filteredParameters = new LinkedHashMap<>(); + for (Map.Entry entry : params.entrySet()) { + Object value = entry.getValue(); + // 判断是否符合拼接类型(int,String,Long,DataTime),并排除空值 + if (isSupportedType(value) && !ObjectUtils.isEmpty(value)) { + filteredParameters.put(entry.getKey(), value); + } + } + + if (filteredParameters.isEmpty()) { + return url; + } + + // 使用 Stream API 对 filteredParameters 按 key 升序排序 + Map sortedParameters = filteredParameters.entrySet() + .stream() + .sorted(Map.Entry.comparingByKey()) + .collect(Collectors.toMap( + Map.Entry::getKey, + Map.Entry::getValue, + (oldValue, newValue) -> oldValue, // 处理键冲突的情况 + LinkedHashMap::new // 保持插入顺序 + )); + + StringBuilder sb = new StringBuilder(url); + if (!url.contains("?")) { + sb.append("?"); + } else { + // 如果 URL 中已有查询参数,确保拼接时参数之间用 & 分隔 + sb.append("&"); + } + + for (Map.Entry entry : sortedParameters.entrySet()) { + String key = entry.getKey(); + Object value = entry.getValue(); + + // 将日期格式化为字符串 + if (value instanceof Date) { + value = new SimpleDateFormat("yyyy-MM-dd").format(value); + } + + sb.append(key) + .append("=") + .append(value.toString()) + .append("&"); + } + + // 去掉最后的多余 & 符号 + sb.setLength(sb.length() - 1); + + return sb.toString(); + } + + /** + * 判断类型是否符合 + * + * @return Boolean + */ + public Boolean isSupportedType(Object value) { + return value instanceof Integer || value instanceof String || value instanceof Long || value instanceof Date; + } + + +}