增加宇视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

@ -1,7 +1,6 @@
package org.dromara.property.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import com.alibaba.fastjson2.JSONObject;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
@ -20,8 +19,6 @@ import org.dromara.property.domain.bo.SysCityAreaBo;
import org.dromara.property.domain.vo.CityAreaTreeVo;
import org.dromara.property.domain.vo.SysCityAreaVo;
import org.dromara.property.service.ISysCityAreaService;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@ -39,7 +36,7 @@ import java.util.List;
@RequiredArgsConstructor
@RestController
@RequestMapping("/cityArea")
public class SysCityAreaController extends BaseController implements ApplicationRunner {
public class SysCityAreaController extends BaseController {
private final ISysCityAreaService SysCityAreaService;
@ -126,10 +123,4 @@ public class SysCityAreaController extends BaseController implements Application
return R.ok(list);
}
@Override
public void run(ApplicationArguments args) throws Exception {
R<List<CityAreaTreeVo>> listR = queryTreeList();
System.out.println(JSONObject.toJSONString(listR));
}
}

View File

@ -3,11 +3,11 @@ 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="Lion Li"
LABEL maintainer="Lxj"
RUN mkdir -p /smartparks/iot/logs \
/smartparks/iot/temp \
/smartparks/iot/agent
RUN mkdir -p /smartparks/Sis/logs \
/smartparks/Sis/temp \
/smartparks/Sis/agent
WORKDIR /ruoyi/system
@ -15,7 +15,7 @@ ENV SERVER_PORT=9201 LANG=C.UTF-8 LC_ALL=C.UTF-8 JAVA_OPTS=""
EXPOSE ${SERVER_PORT}
ADD ./target/iot.jar ./iot.jar
ADD ./target/Sis.jar ./app.jar
SHELL ["/bin/bash", "-c"]
@ -23,5 +23,5 @@ ENTRYPOINT java -Djava.security.egd=file:/dev/./urandom -Dserver.port=${SERVER_P
#-Dskywalking.agent.service_name=ruoyi-system \
#-javaagent:/ruoyi/skywalking/agent/skywalking-agent.jar \
-XX:+HeapDumpOnOutOfMemoryError -XX:+UseZGC ${JAVA_OPTS} \
-jar iot.jar
-jar app.jar

File diff suppressed because it is too large Load Diff

View File

@ -9,11 +9,8 @@
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>Iot</artifactId>
<description>
物业管理模块
</description>
<artifactId>Sis</artifactId>
<description>Smart Intelligent Security 智能安防管理系统</description>
<dependencies>

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

@ -6,7 +6,7 @@ server:
spring:
application:
# 应用名称
name: iot
name: Sis
profiles:
# 环境配置
active: @profiles.active@

View File

@ -15,7 +15,7 @@
<module>ruoyi-resource</module>
<module>ruoyi-workflow</module>
<module>Property</module>
<module>Iot</module>
<module>Sis</module>
</modules>
<artifactId>ruoyi-modules</artifactId>

View File

@ -40,9 +40,9 @@ spring.sql.init.platform=mysql
db.num=1
### Connect URL of DB:
db.url.0=jdbc:mysql://127.0.0.1:3306/cloudconfig?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true
db.url.0=jdbc:mysql://47.109.37.87:3002/ry-config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true
db.user.0=root
db.password.0=root
db.password.0=123456
### the maximum retry times for push
nacos.config.push.maxRetryTime=50