调试修改海康访客-1

This commit is contained in:
zjf committed 2025-05-29 17:07:50 +08:00
1 parent 82fe8afa3e
commit 2ac305e479
14 files changed
+265 -23

No files matched your search

@@ -47,7 +47,7 @@ public interface RemoterVisitorService {
* @return
*/
@PostMapping("/visitors/appointment")
R<VisitorObjectResponse<AppointmentData>> createVisitorAppointment(@Valid @RequestBody VisitorAppointmentRequest request);
VisitorObjectResponse<AppointmentData> createVisitorAppointment(@Valid @RequestBody VisitorAppointmentRequest request);
/**
@@ -1,6 +1,7 @@
package com.bsd.pjcloud.thirdparty.dto.visitor;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
/**
@@ -23,6 +24,7 @@ public class AppointmentInfo {
* 动态二维码内容
* 需转换为二维码图片
*/
private String QRCode;
@@ -20,7 +20,7 @@ public class VisitorAppointmentRequest {
* 被访人唯一标识(必填)
* 通过人员查询接口获取的personId
*/
@NotBlank(message = "被访人ID不能为空")
// @NotBlank(message = "被访人ID不能为空")
private String receptionistId;
/**
@@ -31,10 +31,10 @@ public class VisitorInfo {
* 性别(必填)
* 1-男,2-女
*/
@NotNull(message = "性别不能为空")
// @NotNull(message = "性别不能为空")
@Min(value = 1, message = "性别值无效")
@Max(value = 2, message = "性别值无效")
private Integer gender;
private Integer gender=1;
/**
* 联系电话(必填)
@@ -17,6 +17,7 @@ public class HikvisionProperties {
private String appKey;
private String appSecret;
private String artemisPath;
private String personId;
private Map<String, String> apis = new HashMap<>();
// 初始化配置到SDK
@@ -6,6 +6,7 @@ import com.bsd.pjcloud.thirdparty.dto.visitor.VisitorObjectResponse;
import com.bsd.pjcloud.thirdparty.dto.visitor.request.make.CheckOutRequest;
import com.bsd.pjcloud.thirdparty.dto.visitor.request.make.RegisterAppointmentRequest;
import com.bsd.pjcloud.thirdparty.dto.visitor.request.make.VisitorAppointmentRequest;
import com.bsd.pjcloud.thirdparty.dto.visitor.request.make.VisitorInfo;
import com.bsd.pjcloud.thirdparty.dto.visitor.response.make.AppointmentData;
import com.bsd.pjcloud.thirdparty.dto.visitor.response.make.RegisterAppointmentResponse;
import com.bsd.pjcloud.thirdparty.service.VisitorService;
@@ -20,6 +21,7 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.List;
@RestController
@@ -39,8 +41,24 @@ public class VisitorController {
*/
@Operation(summary = "访客预约" , description = "访客预约" )
@PostMapping("/appointment")
public R<VisitorObjectResponse<AppointmentData>> createVisitorAppointment(@Valid @RequestBody VisitorAppointmentRequest request) {
return R.ok(visitorService.createVisitorAppointment(request));
public VisitorObjectResponse<AppointmentData> createVisitorAppointment(@Valid @RequestBody VisitorAppointmentRequest request) {
// List<VisitorInfo> visitorInfoList = new ArrayList<>();
// for (int i = 0; i <2;i++){
// VisitorInfo visitorInfo = new VisitorInfo();
// visitorInfo.setVisitorName("张家富"+i);
// visitorInfo.setGender(1);
// visitorInfo.setPhoneNo("1846739904"+i);
// visitorInfoList.add(visitorInfo);
// request.setVisitorInfoList(visitorInfoList);
// }
return visitorService.createVisitorAppointment(request);
/**
* 如果已预约会返回如下
* "code": "0x0531401d",
* "msg": "time conflict",
*/
}
@@ -1,15 +1,15 @@
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.alibaba.fastjson.*;
import com.alibaba.nacos.common.utils.CollectionUtils;
import com.bsd.pjcloud.common.core.exception.ServiceException;
import com.bsd.pjcloud.thirdparty.config.HikvisionProperties;
import com.bsd.pjcloud.thirdparty.dto.visitor.AppointmentInfo;
import com.bsd.pjcloud.thirdparty.dto.visitor.VisitorObjectResponse;
import com.bsd.pjcloud.thirdparty.dto.visitor.request.make.CheckOutRequest;
import com.bsd.pjcloud.thirdparty.dto.visitor.request.make.RegisterAppointmentRequest;
import com.bsd.pjcloud.thirdparty.dto.visitor.request.make.VisitorAppointmentRequest;
import com.bsd.pjcloud.thirdparty.dto.visitor.response.make.AppointmentData;
import com.bsd.pjcloud.thirdparty.dto.visitor.response.make.CancelAppointmentResponse;
import com.bsd.pjcloud.thirdparty.dto.visitor.response.make.CheckOutResponse;
import com.bsd.pjcloud.thirdparty.dto.visitor.response.make.RegisterAppointmentResponse;
@@ -21,6 +21,7 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@@ -39,9 +40,125 @@ public class VisitorService extends BaseHikvisionService {
* @return
*/
public VisitorObjectResponse createVisitorAppointment(VisitorAppointmentRequest request) {
request.setReceptionistId(properties.getPersonId());
JSONObject body = convertRequestToJSON(request);
String responseJson = sendPostRequest("visitor-appointment", body);
return JSON.parseObject(responseJson, VisitorObjectResponse.class);
// 添加日志便于调试
log.info("海康返回的原始JSON: {}", responseJson);
// VisitorObjectResponse visitorObjectResponse = JSON.parseObject(responseJson, VisitorObjectResponse.class);
VisitorObjectResponse visitorObjectResponse = parseVisitorResponse(responseJson);
// if (!visitorObjectResponse.getCode().equals("0") ) {
// throw new ServiceException("预约失败,请检查第三方接口");
// }
// 处理不同的错误码
String code = visitorObjectResponse.getCode();
if (code.equals("0")) {
// 成功情况
log.info("海康预约成功,预约记录ID: {}",
visitorObjectResponse.getData() != null ?
visitorObjectResponse.getData().getAppointRecordId() : "null");
} else if (code.equals("0x0531f002")) {
throw new ServiceException("预约时间不能小于当前日期");
} else if (code.equals("0x0531401d")) {
throw new ServiceException("当前时间段已有预约");
} else {
// 其他错误码
log.error("海康预约失败,错误码: {}, 错误信息: {}", code, visitorObjectResponse.getMsg());
throw new ServiceException("预约失败: " + visitorObjectResponse.getMsg());
}
return visitorObjectResponse;
}
/**
* 手动解析响应,处理字段映射问题和不同的data类型
*/
private VisitorObjectResponse parseVisitorResponse(String responseJson) {
try {
JSONObject jsonObject = JSON.parseObject(responseJson);
VisitorObjectResponse response = new VisitorObjectResponse();
response.setCode(jsonObject.getString("code"));
response.setMsg(jsonObject.getString("msg"));
// 处理data部分 - 关键:判断data的类型
Object dataObj = jsonObject.get("data");
if (dataObj != null) {
if (dataObj instanceof JSONObject) {
// 正常情况:data是对象
AppointmentData appointmentData = parseAppointmentData((JSONObject) dataObj);
response.setData(appointmentData);
} else if (dataObj instanceof JSONArray) {
// 异常情况:data是数组,比如 ["张"]
JSONArray dataArray = (JSONArray) dataObj;
log.warn("海康接口返回异常数据格式,data为数组: {}, 错误码: {}, 错误信息: {}",
dataArray.toJSONString(), response.getCode(), response.getMsg());
// 不直接抛异常,让上层的错误码判断逻辑来处理
// response.setData(null); // data设置为null,由错误码判断逻辑处理
} else if (dataObj instanceof String) {
// data是字符串的情况
log.warn("海康接口返回异常数据格式,data为字符串: {}, 错误码: {}, 错误信息: {}",
dataObj.toString(), response.getCode(), response.getMsg());
// 不直接抛异常,让上层的错误码判断逻辑来处理
// response.setData(null);
} else {
// 其他未知类型
log.warn("海康接口返回未知的data类型: {}, 错误码: {}, 完整响应: {}",
dataObj.getClass().getSimpleName(), response.getCode(), responseJson);
// 不直接抛异常,让上层的错误码判断逻辑来处理
// response.setData(null);
}
}
return response;
} catch (JSONException e) {
log.error("解析海康响应JSON失败: {}", responseJson, e);
throw new ServiceException("海康接口响应解析失败");
}
}
/**
* 解析正常的预约数据
*/
private AppointmentData parseAppointmentData(JSONObject dataObj) {
AppointmentData appointmentData = new AppointmentData();
appointmentData.setAppointRecordId(dataObj.getString("appointRecordId"));
// 处理appointmentInfoList
JSONArray appointmentInfoArray = dataObj.getJSONArray("appointmentInfoList");
if (appointmentInfoArray != null) {
List<AppointmentInfo> appointmentInfoList = new ArrayList<>();
for (int i = 0; i < appointmentInfoArray.size(); i++) {
JSONObject infoObj = appointmentInfoArray.getJSONObject(i);
AppointmentInfo info = new AppointmentInfo();
info.setVisitorName(infoObj.getString("visitorName"));
info.setReceptionistId(infoObj.getString("receptionistId"));
info.setReceptionistName(infoObj.getString("receptionistName"));
info.setVerificationCode(infoObj.getString("verificationCode"));
info.setOrderId(infoObj.getString("orderId"));
// info.setVisitorInfoId(infoObj.getString("visitorInfoId"));
info.setSvrIndexCode(infoObj.getString("svrIndexCode"));
info.setPicUri(infoObj.getString("picUri"));
// 关键:手动映射QRCode字段
info.setQRCode(infoObj.getString("QRCode"));
appointmentInfoList.add(info);
}
appointmentData.setAppointmentInfoList(appointmentInfoList);
}
return appointmentData;
}
private JSONObject convertRequestToJSON(VisitorAppointmentRequest request) {
@@ -124,14 +124,15 @@ LianTongSMS:
hikvision:
host: 127.0.0.1:443
app-key: 29180881
app-secret: XO0wCAYGi4KV70ybjznx
host: 60.12.184.22:1443
app-key: 21470882
app-secret: lYRm5YwBp90qdg5eb0p6
artemis-path: /artemis
person-id: 639f8b57bb6c438e884ae48c5cd535c8
apis:
person-list: /api/resource/v2/person/personList # 新增人员列表接口
visitor-appointment: /api/visitor/v2/appointment # 新增访客预约接口
person-detail: /api/resource/v1/person/condition/personInfo # 新增人员详情接口
cancel-appointment: /api/visitor/v1/appointment/cancel # 新增取消预约接口
register-appointment: /api/visitor/v1/order/register # 新增登记接口
visitor-checkout: /api/visitor/v1/visitor/out # 新增签离接口
visitor-checkout: /api/visitor/v1/visitor/out # 新增签离接口