海康接口-1
This commit is contained in:
1 parent
5e64f452ba
commit
1f6d49381d
21 files changed
+881
No files matched your search
+13
@@ -0,0 +1,13 @@
|
||||
package com.bsd.pjcloud.thirdparty.dto.visitor;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public abstract class BaseHikvisionResponse {
|
||||
private String code;
|
||||
private String msg;
|
||||
|
||||
public boolean isSuccess() {
|
||||
return "0".equals(code);
|
||||
}
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
package com.bsd.pjcloud.thirdparty.dto.visitor;
|
||||
|
||||
import lombok.Data;
|
||||
import org.apache.poi.ss.formula.functions.T;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class PageListData<T> {
|
||||
|
||||
private Long total;
|
||||
private Integer pageNo;
|
||||
private Integer pageSize;
|
||||
private List<T> list;
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
package com.bsd.pjcloud.thirdparty.dto.visitor;
|
||||
|
||||
|
||||
import jakarta.validation.constraints.Max;
|
||||
import jakarta.validation.constraints.Min;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 通用分页请求参数基类
|
||||
* 适用于所有分页查询接口
|
||||
*/
|
||||
@Data
|
||||
public class PageListRequest {
|
||||
/**
|
||||
* 当前页码(必须>0)
|
||||
*/
|
||||
@Min(value = 1, message = "页码必须大于0")
|
||||
private Integer pageNo;
|
||||
|
||||
/**
|
||||
* 每页记录数(1-1000)
|
||||
*/
|
||||
@Min(value = 1, message = "每页最少1条记录")
|
||||
@Max(value = 1000, message = "每页最多1000条记录")
|
||||
private Integer pageSize;
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
package com.bsd.pjcloud.thirdparty.dto.visitor;
|
||||
|
||||
|
||||
import lombok.Data;
|
||||
import org.apache.poi.ss.formula.functions.T;
|
||||
|
||||
/**
|
||||
* 访客预约响应主类
|
||||
*/
|
||||
@Data
|
||||
public class VisitorObjectResponse {
|
||||
|
||||
/**
|
||||
* 返回码
|
||||
* 0-成功,其他见错误码表
|
||||
*/
|
||||
private String code;
|
||||
|
||||
/**
|
||||
* 返回描述
|
||||
*/
|
||||
private String msg;
|
||||
|
||||
/**
|
||||
* 预约结果数据
|
||||
*/
|
||||
private T data;
|
||||
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
package com.bsd.pjcloud.thirdparty.dto.visitor;
|
||||
|
||||
import lombok.Data;
|
||||
import org.apache.poi.ss.formula.functions.T;
|
||||
|
||||
@Data
|
||||
public class VisitorResponse<T> {
|
||||
|
||||
private String code;
|
||||
private String msg;
|
||||
private PageListData<T> data;
|
||||
}
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
package com.bsd.pjcloud.thirdparty.dto.visitor.request.make;
|
||||
|
||||
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import lombok.Data;
|
||||
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/*
|
||||
* 访客预约请求参数主类
|
||||
* API路径:/api/visitor/v2/appointment
|
||||
*/
|
||||
@Data
|
||||
public class VisitorAppointmentRequest {
|
||||
|
||||
/**
|
||||
* 被访人唯一标识(必填)
|
||||
* 通过人员查询接口获取的personId
|
||||
*/
|
||||
@NotBlank(message = "被访人ID不能为空")
|
||||
private String receptionistId;
|
||||
|
||||
/**
|
||||
* 访客权限配置
|
||||
*/
|
||||
private VisitorPermissionSet visitorPermissionSet;
|
||||
|
||||
/**
|
||||
* 预计来访时间(必填)
|
||||
* ISO8601格式:yyyy-MM-ddTHH:mm:ss+时区
|
||||
*/
|
||||
@NotBlank(message = "来访时间不能为空")
|
||||
private String visitStartTime;
|
||||
|
||||
/**
|
||||
* 预计离开时间(必填)
|
||||
* 必须晚于当前时间和来访时间
|
||||
*/
|
||||
@NotBlank(message = "离开时间不能为空")
|
||||
private String visitEndTime;
|
||||
|
||||
/**
|
||||
* 来访事由(可选)
|
||||
* 长度限制:0-32个字符
|
||||
*/
|
||||
@Size(max = 32, message = "来访事由最长32个字符")
|
||||
private String visitPurpose;
|
||||
|
||||
/**
|
||||
* 访客信息列表(必填)
|
||||
* 最大支持128位访客,其中最多4位可带人脸信息
|
||||
*/
|
||||
@Valid
|
||||
private List<VisitorInfo> visitorInfoList;
|
||||
|
||||
}
|
||||
+135
@@ -0,0 +1,135 @@
|
||||
package com.bsd.pjcloud.thirdparty.dto.visitor.request.make;
|
||||
|
||||
|
||||
import jakarta.validation.constraints.*;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import org.hibernate.validator.constraints.Range;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
/**
|
||||
* 访客详细信息实体
|
||||
* 对应接口文档中 visitorInfoList 的单个访客对象
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
public class VisitorInfo {
|
||||
|
||||
/**
|
||||
* 访客姓名(必填)
|
||||
* 长度限制:1-32字符
|
||||
* 禁止字符:’ / \ : * ? " < >
|
||||
*/
|
||||
@NotBlank(message = "访客姓名不能为空")
|
||||
@Size(min = 1, max = 32, message = "姓名长度需在1-32个字符之间")
|
||||
@Pattern(regexp = "^[^'/\\\\:*?\"<>]+$", message = "姓名包含非法字符")
|
||||
private String visitorName;
|
||||
|
||||
/**
|
||||
* 性别(必填)
|
||||
* 1-男,2-女
|
||||
*/
|
||||
@NotNull(message = "性别不能为空")
|
||||
@Min(value = 1, message = "性别值无效")
|
||||
@Max(value = 2, message = "性别值无效")
|
||||
private Integer gender;
|
||||
|
||||
/**
|
||||
* 联系电话(必填)
|
||||
* 需符合手机号格式:11位数字
|
||||
*/
|
||||
@NotBlank(message = "联系电话不能为空")
|
||||
@Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号格式不正确")
|
||||
private String phoneNo;
|
||||
|
||||
/**
|
||||
* 车牌号(可选)
|
||||
* 格式示例:浙A12345
|
||||
* 禁止字符:’ / \ : * ? " < >
|
||||
*/
|
||||
@Pattern(regexp = "^[^'/\\\\:*?\"<>]*$", message = "车牌号包含非法字符")
|
||||
private String plateNo;
|
||||
|
||||
/**
|
||||
* 证件类型(可选)
|
||||
* 111-身份证,其他类型参考附录A.11
|
||||
*/
|
||||
@Min(value = 1, message = "证件类型代码无效")
|
||||
private Integer certificateType;
|
||||
|
||||
/**
|
||||
* 证件号码(可选)
|
||||
* 当填写证件号时,证件类型必填
|
||||
* 长度限制:1-20位字符
|
||||
*/
|
||||
@Size(min = 1, max = 20, message = "证件号长度需在1-20位之间")
|
||||
private String certificateNo;
|
||||
|
||||
/**
|
||||
* 证件地址(可选)
|
||||
* 格式示例:江苏南京
|
||||
* 长度限制:1-128字符
|
||||
*/
|
||||
@Size(max = 128, message = "证件地址最长128个字符")
|
||||
private String certAddr;
|
||||
|
||||
/**
|
||||
* 发证机关(可选)
|
||||
* 格式示例:南京市公安局
|
||||
* 长度限制:1-32字符
|
||||
*/
|
||||
@Size(max = 32, message = "发证机关最长32个字符")
|
||||
private String certIssuer;
|
||||
|
||||
/**
|
||||
* 民族(可选)
|
||||
* 使用国标GB/T 3304-1991编码
|
||||
*/
|
||||
@Min(value = 1, message = "民族编码无效")
|
||||
private Integer nation;
|
||||
|
||||
/**
|
||||
* 籍贯(可选)
|
||||
* 格式示例:江苏南京
|
||||
* 长度限制:1-32字符
|
||||
*/
|
||||
@Size(max = 32, message = "籍贯最长32个字符")
|
||||
private String birthplace;
|
||||
|
||||
/**
|
||||
* 访客头像(可选)
|
||||
* Base64编码的JPG图片(不超过200KB)
|
||||
* 需要先通过人脸质量检测(评分≥75)
|
||||
*/
|
||||
@Size(max = 300000, message = "头像大小超过200KB限制") // 200KB约对应约273,000字符
|
||||
private String visitorPhoto;
|
||||
|
||||
/**
|
||||
* 来访单位(可选)
|
||||
* 格式示例:海康威视
|
||||
* 长度限制:1-32字符
|
||||
* 禁止字符:’ / \ : * ? " < >
|
||||
*/
|
||||
@Size(max = 32, message = "单位名称最长32个字符")
|
||||
@Pattern(regexp = "^[^'/\\\\:*?\"<>]*$", message = "单位名称包含非法字符")
|
||||
private String visitorWorkUnit;
|
||||
|
||||
/**
|
||||
* 访客住址(可选)
|
||||
* 格式示例:人民路一号
|
||||
* 长度限制:1-128字符
|
||||
*/
|
||||
@Size(max = 128, message = "地址最长128个字符")
|
||||
private String visitorAddress;
|
||||
|
||||
/**
|
||||
* 扩展字段(用于平台自定义属性)
|
||||
* Key需与平台定义的属性key一致
|
||||
* 示例:"emergencyContact": "李四"
|
||||
*/
|
||||
private Map<String, Object> extendedFields;
|
||||
|
||||
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
package com.bsd.pjcloud.thirdparty.dto.visitor.request.make;
|
||||
|
||||
|
||||
|
||||
import jakarta.validation.constraints.Pattern;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 访客权限组配置
|
||||
*/
|
||||
|
||||
@Data
|
||||
public class VisitorPermissionSet {
|
||||
|
||||
/**
|
||||
* 是否使用默认权限组
|
||||
* 1-使用,非1-不使用
|
||||
*/
|
||||
@Pattern(regexp = "1|.*", message = "默认权限组标识格式错误")
|
||||
private String defaultPrivilegeGroupFlag;
|
||||
|
||||
/**
|
||||
* 权限组ID列表
|
||||
* 当defaultPrivilegeGroupFlag不为1时必填
|
||||
*/
|
||||
@Size(min = 1, message = "权限组ID列表不能为空")
|
||||
private List<String> privilegeGroupIds;
|
||||
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
package com.bsd.pjcloud.thirdparty.dto.visitor.request.person;
|
||||
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 人员详细信息实体
|
||||
*/
|
||||
@Data
|
||||
public class PersonInfo {
|
||||
private String personId;
|
||||
private String personName;
|
||||
private Integer gender;
|
||||
private String orgIndexCode;
|
||||
private String phoneNo;
|
||||
private String jobNo;
|
||||
private Integer certificateType;
|
||||
private String certificateNo;
|
||||
private LocalDateTime createTime;
|
||||
private LocalDateTime updateTime;
|
||||
private String orgPath;
|
||||
private String orgPathName;
|
||||
private List<PersonPhoto> personPhoto;
|
||||
|
||||
/**
|
||||
* 人员照片信息
|
||||
*/
|
||||
@Data
|
||||
public static class PersonPhoto {
|
||||
private String personPhotoIndexCode;
|
||||
private String picUri;
|
||||
private String serverIndexCode;
|
||||
private String personId;
|
||||
}
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
package com.bsd.pjcloud.thirdparty.dto.visitor.response.make;
|
||||
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 预约结果数据封装
|
||||
*/
|
||||
|
||||
@Data
|
||||
public class AppointmentData {
|
||||
|
||||
/**
|
||||
* 预约记录唯一ID
|
||||
* 用于后续修改/取消操作
|
||||
*/
|
||||
private String appointRecordId;
|
||||
|
||||
/**
|
||||
* 预约详细信息列表
|
||||
*/
|
||||
private List<AppointmentInfo> appointmentInfoList;
|
||||
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
package com.bsd.pjcloud.thirdparty.dto.visitor.response.make;
|
||||
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 单条预约详细信息
|
||||
*/
|
||||
@Data
|
||||
public class AppointmentInfo {
|
||||
|
||||
/*
|
||||
* 访客姓名
|
||||
*/
|
||||
private String visitorName;
|
||||
|
||||
/**
|
||||
* 被访人ID
|
||||
*/
|
||||
private String receptionistId;
|
||||
|
||||
/**
|
||||
* 动态二维码内容
|
||||
* 需转换为二维码图片
|
||||
*/
|
||||
private String QRCode;
|
||||
|
||||
}
|
||||
@@ -13,6 +13,12 @@
|
||||
<artifactId>pjcloud-thirdparty-biz</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.hikvision.ga</groupId>
|
||||
<artifactId>artemis-http-client</artifactId>
|
||||
<version>1.1.3</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.bsd</groupId>
|
||||
<artifactId>pjcloud-upms-api</artifactId>
|
||||
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
package com.bsd.pjcloud.thirdparty.config;
|
||||
|
||||
import com.hikvision.artemis.sdk.config.ArtemisConfig;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Configuration
|
||||
@ConfigurationProperties(prefix = "hikvision")
|
||||
@Data
|
||||
public class HikvisionProperties {
|
||||
private String host;
|
||||
private String appKey;
|
||||
private String appSecret;
|
||||
private String artemisPath;
|
||||
private Map<String, String> apis = new HashMap<>();
|
||||
|
||||
// 初始化配置到SDK
|
||||
@PostConstruct
|
||||
public void initConfig() {
|
||||
ArtemisConfig.host = this.host;
|
||||
ArtemisConfig.appKey = this.appKey;
|
||||
ArtemisConfig.appSecret = this.appSecret;
|
||||
}
|
||||
|
||||
// getters and setters
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
package com.bsd.pjcloud.thirdparty.exception;
|
||||
|
||||
public class HikvisionApiException extends HikvisionException {
|
||||
public HikvisionApiException(String code, String msg) {
|
||||
super(code, msg);
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package com.bsd.pjcloud.thirdparty.exception;
|
||||
|
||||
// 特定异常类型(可选)
|
||||
public class HikvisionConfigException extends HikvisionException {
|
||||
public HikvisionConfigException(String msg) {
|
||||
super("CONFIG_ERROR", msg);
|
||||
}
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
package com.bsd.pjcloud.thirdparty.exception;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.Getter;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
|
||||
// 基础业务异常
|
||||
@Getter
|
||||
public class HikvisionException extends RuntimeException {
|
||||
private final String code;
|
||||
private final String msg;
|
||||
|
||||
public HikvisionException(String code, String msg) {
|
||||
super(msg);
|
||||
this.code = code;
|
||||
this.msg = msg;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
package com.bsd.pjcloud.thirdparty.service;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONException;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.alibaba.fastjson.TypeReference;
|
||||
import com.bsd.pjcloud.thirdparty.config.HikvisionProperties;
|
||||
import com.bsd.pjcloud.thirdparty.dto.visitor.BaseHikvisionResponse;
|
||||
import com.bsd.pjcloud.thirdparty.exception.HikvisionApiException;
|
||||
import com.bsd.pjcloud.thirdparty.exception.HikvisionException;
|
||||
import com.hikvision.artemis.sdk.ArtemisHttpUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static javax.swing.UIManager.put;
|
||||
|
||||
|
||||
@Slf4j
|
||||
public abstract class BaseHikvisionService {
|
||||
protected final HikvisionProperties properties;
|
||||
|
||||
protected BaseHikvisionService(HikvisionProperties properties) {
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* 公共方法:构建API路径
|
||||
*/
|
||||
protected String buildApiPath(String apiKey) {
|
||||
String apiSuffix = properties.getApis().get(apiKey);
|
||||
if (StringUtils.isBlank(apiSuffix)) {
|
||||
throw new HikvisionException("CONFIG_ERROR", "接口路径未配置: " + apiKey);
|
||||
}
|
||||
return properties.getArtemisPath() + apiSuffix;
|
||||
}
|
||||
|
||||
protected String sendPostRequest(String apiKey, JSONObject body) {
|
||||
try {
|
||||
Map<String, String> path = new HashMap<String, String>() {{
|
||||
put("https://", buildApiPath(apiKey));
|
||||
}};
|
||||
|
||||
return ArtemisHttpUtil.doPostStringArtemis(
|
||||
path,
|
||||
body.toJSONString(),
|
||||
null,
|
||||
null,
|
||||
"application/json",
|
||||
null
|
||||
);
|
||||
} catch (Exception e) {
|
||||
log.error("系统异常: {}", e.getMessage(), e);
|
||||
throw new HikvisionException("SYSTEM_ERROR", "系统内部错误");
|
||||
}
|
||||
}
|
||||
|
||||
protected <T> T parseResponse(String json, TypeReference<T> typeRef) {
|
||||
try {
|
||||
T response = JSON.parseObject(json, typeRef);
|
||||
if (response instanceof BaseHikvisionResponse) {
|
||||
BaseHikvisionResponse baseRes = (BaseHikvisionResponse) response;
|
||||
if (!baseRes.isSuccess()) {
|
||||
throw new HikvisionApiException(baseRes.getCode(), baseRes.getMsg());
|
||||
}
|
||||
}
|
||||
return response;
|
||||
} catch (JSONException e) {
|
||||
log.error("响应解析失败: {}", json);
|
||||
throw new HikvisionException("PARSE_ERROR", "响应数据格式异常");
|
||||
}
|
||||
}
|
||||
}
|
||||
+192
@@ -0,0 +1,192 @@
|
||||
package com.bsd.pjcloud.thirdparty.service;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONException;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.alibaba.fastjson.TypeReference;
|
||||
import com.bsd.pjcloud.thirdparty.config.HikvisionProperties;
|
||||
import com.bsd.pjcloud.thirdparty.dto.visitor.PageListRequest;
|
||||
import com.bsd.pjcloud.thirdparty.dto.visitor.VisitorResponse;
|
||||
import com.bsd.pjcloud.thirdparty.dto.visitor.request.make.VisitorAppointmentRequest;
|
||||
import com.bsd.pjcloud.thirdparty.dto.visitor.VisitorObjectResponse;
|
||||
import com.bsd.pjcloud.thirdparty.dto.visitor.request.person.PersonInfo;
|
||||
import com.bsd.pjcloud.thirdparty.exception.HikvisionException;
|
||||
import com.hikvision.artemis.sdk.ArtemisHttpUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
public class HikvisionService {
|
||||
private final HikvisionProperties properties;
|
||||
|
||||
|
||||
public VisitorObjectResponse createVisitorAppointment(VisitorAppointmentRequest request) {
|
||||
// 1. 构建API路径
|
||||
String apiPath = properties.getArtemisPath() +
|
||||
properties.getApis().get("visitor-appointment");
|
||||
|
||||
// 2. 构建请求路径参数
|
||||
Map<String, String> pathParams = new HashMap<>(2);
|
||||
pathParams.put("https://", apiPath); // 根据环境选择协议
|
||||
|
||||
// 3. 转换请求体
|
||||
JSONObject requestBody = convertRequestToJSON(request);
|
||||
|
||||
// 4. 发送请求
|
||||
String responseJson = ArtemisHttpUtil.doPostStringArtemis(
|
||||
pathParams,
|
||||
requestBody.toJSONString(),
|
||||
null,
|
||||
null,
|
||||
"application/json",
|
||||
null
|
||||
);
|
||||
|
||||
// 5. 解析响应
|
||||
return JSON.parseObject(responseJson, VisitorObjectResponse.class);
|
||||
}
|
||||
|
||||
private JSONObject convertRequestToJSON(VisitorAppointmentRequest request) {
|
||||
JSONObject json = new JSONObject();
|
||||
json.put("receptionistId", request.getReceptionistId());
|
||||
|
||||
// 处理权限组
|
||||
if (request.getVisitorPermissionSet() != null) {
|
||||
JSONObject permissionSet = new JSONObject();
|
||||
permissionSet.put("defaultPrivilegeGroupFlag",
|
||||
request.getVisitorPermissionSet().getDefaultPrivilegeGroupFlag());
|
||||
permissionSet.put("privilegeGroupIds",
|
||||
request.getVisitorPermissionSet().getPrivilegeGroupIds());
|
||||
json.put("visitorPermissionSet", permissionSet);
|
||||
}
|
||||
|
||||
json.put("visitStartTime", request.getVisitStartTime());
|
||||
json.put("visitEndTime", request.getVisitEndTime());
|
||||
json.put("visitPurpose", request.getVisitPurpose());
|
||||
|
||||
// 处理访客列表
|
||||
List<JSONObject> visitorList = request.getVisitorInfoList().stream().map(visitor -> {
|
||||
JSONObject visitorJson = new JSONObject();
|
||||
visitorJson.put("visitorName", visitor.getVisitorName());
|
||||
visitorJson.put("gender", visitor.getGender());
|
||||
visitorJson.put("phoneNo", visitor.getPhoneNo());
|
||||
visitorJson.put("plateNo", visitor.getPlateNo());
|
||||
visitorJson.put("certificateType", visitor.getCertificateType());
|
||||
visitorJson.put("certificateNo", visitor.getCertificateNo());
|
||||
visitorJson.put("certAddr", visitor.getCertAddr());
|
||||
visitorJson.put("certIssuer", visitor.getCertIssuer());
|
||||
visitorJson.put("nation", visitor.getNation());
|
||||
visitorJson.put("birthplace", visitor.getBirthplace());
|
||||
visitorJson.put("visitorPhoto", visitor.getVisitorPhoto());
|
||||
visitorJson.put("visitorWorkUnit", visitor.getVisitorWorkUnit());
|
||||
visitorJson.put("visitorAddress", visitor.getVisitorAddress());
|
||||
visitorJson.put("extendedFields", visitor.getExtendedFields());
|
||||
|
||||
if (visitor.getExtendedFields() != null) {
|
||||
visitor.getExtendedFields().forEach(visitorJson::put);
|
||||
}
|
||||
return visitorJson;
|
||||
}).collect(Collectors.toList());
|
||||
|
||||
json.put("visitorInfoList", visitorList);
|
||||
return json;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取人员列表(分页)
|
||||
* @param request 分页请求参数
|
||||
* @return 分页响应结果
|
||||
*/
|
||||
public VisitorResponse<PersonInfo> getPersonList(PageListRequest request) {
|
||||
// 参数校验
|
||||
validatePageRequest(request);
|
||||
|
||||
try {
|
||||
// 1. 构建API路径
|
||||
String apiPath = buildApiPath("person-list");
|
||||
|
||||
// 2. 构建请求参数(根据ArtemisHttpUtil的要求)
|
||||
Map<String, String> path = new HashMap<String, String>() {{
|
||||
put("https://", apiPath); // 根据实际协议配置
|
||||
}};
|
||||
|
||||
// 3. 构建请求体
|
||||
JSONObject body = new JSONObject();
|
||||
body.put("pageNo", request.getPageNo());
|
||||
body.put("pageSize", request.getPageSize());
|
||||
log.debug("请求体: {}", body);
|
||||
|
||||
// 4. 调用工具类发送请求
|
||||
String result = ArtemisHttpUtil.doPostStringArtemis(
|
||||
path,
|
||||
body.toJSONString(),
|
||||
null, // 查询参数
|
||||
null, // 头信息(可配置Authorization等)
|
||||
"application/json",
|
||||
null // 超时配置(如需要)
|
||||
);
|
||||
|
||||
// 5. 处理响应
|
||||
return parseResponse(result);
|
||||
} catch (Exception e) { // 捕获工具类可能抛出的异常
|
||||
throw new HikvisionException("SERVICE_ERROR", "人员查询失败");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 构建完整API路径
|
||||
*/
|
||||
private String buildApiPath(String apiKey) {
|
||||
String apiSuffix = properties.getApis().get(apiKey);
|
||||
if (StringUtils.isBlank(apiSuffix)) {
|
||||
throw new HikvisionException("CONFIG_ERROR", "接口路径未配置");
|
||||
}
|
||||
return properties.getArtemisPath() + apiSuffix;
|
||||
}
|
||||
/**
|
||||
* 解析响应数据
|
||||
*/
|
||||
private VisitorResponse<PersonInfo> parseResponse(String json) {
|
||||
try {
|
||||
VisitorResponse<PersonInfo> response = JSON.parseObject(json,
|
||||
new TypeReference<VisitorResponse<PersonInfo>>() {});
|
||||
|
||||
if (!"0".equals(response.getCode())) {
|
||||
log.warn("海康业务异常 - Code: {}, Msg: {}",
|
||||
response.getCode(), response.getMsg());
|
||||
throw new HikvisionException(response.getCode(), response.getMsg());
|
||||
}
|
||||
return response;
|
||||
} catch (JSONException e) {
|
||||
log.error("响应数据解析失败: {}", json, e);
|
||||
throw new HikvisionException("PARSE_ERROR", "响应数据格式异常");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 参数校验增强
|
||||
*/
|
||||
private void validatePageRequest(PageListRequest request) {
|
||||
if (request.getPageNo() == null || request.getPageNo() < 1) {
|
||||
throw new IllegalArgumentException("页码参数不合法");
|
||||
}
|
||||
if (request.getPageSize() == null ||
|
||||
request.getPageSize() < 1 ||
|
||||
request.getPageSize() > 1000) {
|
||||
throw new IllegalArgumentException("分页大小需在1-1000之间");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
package com.bsd.pjcloud.thirdparty.service;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.alibaba.fastjson.TypeReference;
|
||||
import com.bsd.pjcloud.thirdparty.config.HikvisionProperties;
|
||||
import com.bsd.pjcloud.thirdparty.dto.visitor.PageListRequest;
|
||||
import com.bsd.pjcloud.thirdparty.dto.visitor.VisitorResponse;
|
||||
import com.bsd.pjcloud.thirdparty.dto.visitor.request.person.PersonInfo;
|
||||
import com.bsd.pjcloud.thirdparty.exception.HikvisionException;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
public class PersonService extends BaseHikvisionService {
|
||||
public PersonService(HikvisionProperties properties) {
|
||||
super(properties);
|
||||
}
|
||||
|
||||
public VisitorResponse<PersonInfo> getPersonList(PageListRequest request) {
|
||||
try {
|
||||
validatePageRequest(request);
|
||||
|
||||
JSONObject body = new JSONObject();
|
||||
body.put("pageNo", request.getPageNo());
|
||||
body.put("pageSize", request.getPageSize());
|
||||
|
||||
String response = sendPostRequest("person-list", body);
|
||||
return parseResponse(response, new TypeReference<VisitorResponse<PersonInfo>>() {});
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new HikvisionException("PARAM_ERROR", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private void validatePageRequest(PageListRequest request) {
|
||||
if (request.getPageNo() == null || request.getPageNo() < 1) {
|
||||
throw new IllegalArgumentException("页码必须大于0");
|
||||
}
|
||||
if (request.getPageSize() == null || request.getPageSize() < 1 || request.getPageSize() > 1000) {
|
||||
throw new IllegalArgumentException("分页大小需在1-1000之间");
|
||||
}
|
||||
}
|
||||
}
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
package com.bsd.pjcloud.thirdparty.service;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.bsd.pjcloud.thirdparty.config.HikvisionProperties;
|
||||
import com.bsd.pjcloud.thirdparty.dto.visitor.VisitorObjectResponse;
|
||||
import com.bsd.pjcloud.thirdparty.dto.visitor.request.make.VisitorAppointmentRequest;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
public class VisitorService extends BaseHikvisionService {
|
||||
public VisitorService(HikvisionProperties properties) {
|
||||
super(properties);
|
||||
}
|
||||
|
||||
public VisitorObjectResponse createVisitorAppointment(VisitorAppointmentRequest request) {
|
||||
JSONObject body = convertRequestToJSON(request);
|
||||
String responseJson = sendPostRequest("visitor-appointment", body);
|
||||
return JSON.parseObject(responseJson, VisitorObjectResponse.class);
|
||||
}
|
||||
|
||||
private JSONObject convertRequestToJSON(VisitorAppointmentRequest request) {
|
||||
JSONObject json = new JSONObject();
|
||||
json.put("receptionistId", request.getReceptionistId());
|
||||
|
||||
// 处理权限组
|
||||
if (request.getVisitorPermissionSet() != null) {
|
||||
JSONObject permissionSet = new JSONObject();
|
||||
permissionSet.put("defaultPrivilegeGroupFlag",
|
||||
request.getVisitorPermissionSet().getDefaultPrivilegeGroupFlag());
|
||||
permissionSet.put("privilegeGroupIds",
|
||||
request.getVisitorPermissionSet().getPrivilegeGroupIds());
|
||||
json.put("visitorPermissionSet", permissionSet);
|
||||
}
|
||||
|
||||
json.put("visitStartTime", request.getVisitStartTime());
|
||||
json.put("visitEndTime", request.getVisitEndTime());
|
||||
json.put("visitPurpose", request.getVisitPurpose());
|
||||
|
||||
// 处理访客列表
|
||||
List<JSONObject> visitorList = request.getVisitorInfoList().stream().map(visitor -> {
|
||||
JSONObject visitorJson = new JSONObject();
|
||||
visitorJson.put("visitorName", visitor.getVisitorName());
|
||||
visitorJson.put("gender", visitor.getGender());
|
||||
visitorJson.put("phoneNo", visitor.getPhoneNo());
|
||||
visitorJson.put("plateNo", visitor.getPlateNo());
|
||||
visitorJson.put("certificateType", visitor.getCertificateType());
|
||||
visitorJson.put("certificateNo", visitor.getCertificateNo());
|
||||
visitorJson.put("certAddr", visitor.getCertAddr());
|
||||
visitorJson.put("certIssuer", visitor.getCertIssuer());
|
||||
visitorJson.put("nation", visitor.getNation());
|
||||
visitorJson.put("birthplace", visitor.getBirthplace());
|
||||
visitorJson.put("visitorPhoto", visitor.getVisitorPhoto());
|
||||
visitorJson.put("visitorWorkUnit", visitor.getVisitorWorkUnit());
|
||||
visitorJson.put("visitorAddress", visitor.getVisitorAddress());
|
||||
visitorJson.put("extendedFields", visitor.getExtendedFields());
|
||||
|
||||
if (visitor.getExtendedFields() != null) {
|
||||
visitor.getExtendedFields().forEach(visitorJson::put);
|
||||
}
|
||||
return visitorJson;
|
||||
}).collect(Collectors.toList());
|
||||
|
||||
json.put("visitorInfoList", visitorList);
|
||||
return json;
|
||||
}
|
||||
}
|
||||
@@ -121,3 +121,14 @@ LianTongSMS:
|
||||
PASSWORD: 'Aa123456'
|
||||
#签名id
|
||||
AUTOGRAPH_ID: ''
|
||||
|
||||
|
||||
hikvision:
|
||||
host: 127.0.0.1:443
|
||||
app-key: 29180881
|
||||
app-secret: XO0wCAYGi4KV70ybjznx
|
||||
artemis-path: /artemis
|
||||
apis:
|
||||
preview-urls: /api/video/v1/cameras/previewURLs
|
||||
person-list: /api/resource/v2/person/personList # 新增人员列表接口
|
||||
visitor-appointment: /api/visitor/v2/appointment # 新增访客预约接口
|
||||
Reference in new issue
Block a user