|
|
@@ -36,11 +36,14 @@ import org.dromara.server.hik.service.IXfTermService;
|
|
|
import org.dromara.server.hik.utils.DigestHttpUtil;
|
|
|
import org.dromara.server.hik.utils.JsonConfig;
|
|
|
import org.jetbrains.annotations.NotNull;
|
|
|
+import org.springframework.beans.factory.annotation.Value;
|
|
|
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
import org.springframework.validation.annotation.Validated;
|
|
|
|
|
|
import java.text.MessageFormat;
|
|
|
+import java.time.ZonedDateTime;
|
|
|
+import java.time.format.DateTimeFormatter;
|
|
|
import java.util.*;
|
|
|
|
|
|
/**
|
|
|
@@ -68,6 +71,15 @@ public class SendDeviceServiceImpl implements ISendDeviceService {
|
|
|
@DubboReference
|
|
|
private final RemoteUserAccountService remoteUserAccountService;
|
|
|
|
|
|
+ /**
|
|
|
+ * 映射的出口IP
|
|
|
+ */
|
|
|
+ @Value("${common.ip:}")
|
|
|
+ private String commonIP;
|
|
|
+
|
|
|
+ @Value("${device.listen.url}")
|
|
|
+ private String listenUrl;
|
|
|
+
|
|
|
// region 私有方法
|
|
|
|
|
|
/**
|
|
|
@@ -160,27 +172,32 @@ public class SendDeviceServiceImpl implements ISendDeviceService {
|
|
|
* @return 转换后的 DeviceDto 对象
|
|
|
*/
|
|
|
@NotNull
|
|
|
- private static DeviceDto getDeviceDto(@NotNull RemoteXfTermVo termVo) {
|
|
|
+ private DeviceDto getDeviceDto(@NotNull RemoteXfTermVo termVo) {
|
|
|
return getDeviceDto(termVo.getTermNo(), termVo.getAdminName(), termVo.getAdminPwd(), termVo.getTermIp(),
|
|
|
termVo.getCommPort(), termVo.getServerIp(), termVo.getServerPort());
|
|
|
}
|
|
|
|
|
|
@NotNull
|
|
|
- private static DeviceDto getDeviceDto(@NotNull XfTermVo termVo) {
|
|
|
+ private DeviceDto getDeviceDto(@NotNull XfTermVo termVo) {
|
|
|
return getDeviceDto(termVo.getTermNo(), termVo.getAdminName(), termVo.getAdminPwd(), termVo.getTermIp(),
|
|
|
termVo.getCommPort(), termVo.getServerIp(), termVo.getServerPort());
|
|
|
}
|
|
|
|
|
|
@NotNull
|
|
|
- private static DeviceDto getDeviceDto(Long termNo, String adminName, String adminPwd, String termIp, Long commPort, String serverIp, Long serverPort) {
|
|
|
+ private DeviceDto getDeviceDto(Long termNo, String adminName, String adminPwd, String termIp, Long commPort, String serverIp, Long serverPort) {
|
|
|
DeviceDto dto = new DeviceDto();
|
|
|
dto.setTermNo(termNo.intValue());
|
|
|
dto.setAdminName(adminName);
|
|
|
dto.setAdminPwd(adminPwd);
|
|
|
- dto.setDeviceIp(termIp);
|
|
|
- dto.setDevicePort(commPort.intValue());
|
|
|
+ // 如果配置了映射IP,则使用映射IP
|
|
|
+ boolean hasCommonIp = StringUtils.isNotBlank(commonIP);
|
|
|
+ dto.setDeviceIp(hasCommonIp ? commonIP :termIp);
|
|
|
+ // 海康设备的端口 都是80
|
|
|
+ dto.setDevicePort(hasCommonIp ? commPort.intValue() : 80);
|
|
|
dto.setServerIp(serverIp);
|
|
|
dto.setServerPort(serverPort.intValue());
|
|
|
+ // 监听接口地址
|
|
|
+ dto.setServerUrl(listenUrl);
|
|
|
|
|
|
return dto;
|
|
|
}
|
|
|
@@ -228,6 +245,65 @@ public class SendDeviceServiceImpl implements ISendDeviceService {
|
|
|
return StringUtils.format(xmlTemplate,dto.getServerUrl(), dto.getServerIp(), dto.getServerPort());
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 动态构建下发监听服务地址的请求报文 监听地址为域名
|
|
|
+ *
|
|
|
+ * @param dto 设备信息
|
|
|
+ * @return 下发的请求报文
|
|
|
+ */
|
|
|
+ private String createDomainXml(@NotNull DeviceDto dto) {
|
|
|
+ String xmlTemplate = """
|
|
|
+ <?xml version="1.0" encoding="UTF-8"?>
|
|
|
+ <HttpHostNotification version="2.0" xmlns="http://www.isapi.org/ver20/XMLSchema">
|
|
|
+ <id>1</id>
|
|
|
+ <url>{}</url>
|
|
|
+ <protocolType>HTTPS</protocolType>
|
|
|
+ <parameterFormatType>XML</parameterFormatType>
|
|
|
+ <addressingFormatType>hostname</addressingFormatType>
|
|
|
+ <hostName>{}</hostName>
|
|
|
+ <portNo>443</portNo>
|
|
|
+ <httpAuthenticationMethod>none</httpAuthenticationMethod>
|
|
|
+ <SubscribeEvent>
|
|
|
+ <heartbeat>30</heartbeat>
|
|
|
+ <eventMode>list</eventMode>
|
|
|
+ <EventList>
|
|
|
+ <Event>
|
|
|
+ <type>ConsumptionAndTransactionRecordEvent</type>
|
|
|
+ </Event>
|
|
|
+ </EventList>
|
|
|
+ </SubscribeEvent>
|
|
|
+ </HttpHostNotification>
|
|
|
+ """;
|
|
|
+
|
|
|
+ return StringUtils.format(xmlTemplate,dto.getServerUrl(), dto.getServerIp());
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 动态构建下发校时时间
|
|
|
+ *
|
|
|
+ * @return 下发的请求报文
|
|
|
+ */
|
|
|
+ public static String createTimeXml() {
|
|
|
+ String xmlTemplate = """
|
|
|
+ <?xml version="1.0" encoding="UTF-8" ?>
|
|
|
+ <Time xmlns="http://www.isapi.org/ver20/XMLSchema" version="2.0">
|
|
|
+ <timeMode>manual</timeMode>
|
|
|
+ <localTime>{}</localTime>
|
|
|
+ <timeZone>CST-8:00:00</timeZone>
|
|
|
+ </Time>
|
|
|
+ """;
|
|
|
+ // 获取当前时间(带时区)
|
|
|
+ ZonedDateTime now = ZonedDateTime.now();
|
|
|
+
|
|
|
+ // 定义格式
|
|
|
+ DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss");
|
|
|
+
|
|
|
+ // 格式化时间
|
|
|
+ String nowTime = now.format(formatter);
|
|
|
+ return StringUtils.format(xmlTemplate,nowTime);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
/**
|
|
|
* 处理设置监听服务地址返回数据
|
|
|
* <p>
|
|
|
@@ -437,7 +513,19 @@ public class SendDeviceServiceImpl implements ISendDeviceService {
|
|
|
if (ObjectUtil.isEmpty(dto.getServerPort())) {
|
|
|
return R.fail("监听端口不能为空");
|
|
|
}
|
|
|
+
|
|
|
+ if(ObjectUtil.isEmpty(dto.getServerUrl())){
|
|
|
+ dto.setServerUrl(listenUrl);
|
|
|
+ }
|
|
|
String setData = this.createHostXml(dto);
|
|
|
+ // 判断地址是域名还是IP
|
|
|
+ List<String> commonSuffix = Arrays.asList("com", "cn", "org", "net", "edu", "gov", "io", "biz", "info", "xyz", "top");
|
|
|
+ for (String item : commonSuffix) {
|
|
|
+ if (dto.getServerIp().contains(item)) {
|
|
|
+ setData = this.createDomainXml(dto);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
JSONObject sendResult = digestHttpUtil.sendPost(dto, setData, HikApiConstants.SET_HTTP_HOSTS, ContentTypeEnum.XML.getCode());
|
|
|
R<Void> doResult = this.doSetHostReturnData(sendResult);
|
|
|
@@ -470,7 +558,53 @@ public class SendDeviceServiceImpl implements ISendDeviceService {
|
|
|
});
|
|
|
return R.ok("处理完成,详情见处理日志");
|
|
|
}
|
|
|
- // endregion
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public R<Void> syncTimeToAll() {
|
|
|
+ List<RemoteXfTermVo> termList = remotePtXfTermService.queryListByBrand("hk");
|
|
|
+ if (CollectionUtil.isEmpty(termList)) {
|
|
|
+ throw new ServiceException("没有要处理的设备");
|
|
|
+ }
|
|
|
+ termList.forEach(p -> {
|
|
|
+ threadPoolTaskExecutor.execute(() -> {
|
|
|
+ DeviceDto dto = getDeviceDto(p);
|
|
|
+ R<Void> result = syncTimeToDevice(dto);
|
|
|
+ log.info(result.getMsg());
|
|
|
+ });
|
|
|
+ });
|
|
|
+ return R.ok("处理完成");
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 同步时间到设备
|
|
|
+ * @param device 设备信息
|
|
|
+ * @return R
|
|
|
+ */
|
|
|
+ private R<Void> syncTimeToDevice(DeviceDto device) {
|
|
|
+ String setData = createTimeXml();
|
|
|
+ if (ObjectUtil.isEmpty(device.getDeviceIp())) {
|
|
|
+ return R.fail("设备IP不能为空");
|
|
|
+ }
|
|
|
+ Integer termNo = device.getTermNo();
|
|
|
+ String requestUrl = StringUtils.format("http://{}:{}{}", device.getDeviceIp(), device.getDevicePort(), HikApiConstants.SYNC_TIME_URL);
|
|
|
+ JSONObject sendResult = digestHttpUtil.sendPut(setData, requestUrl, ContentTypeEnum.XML.getCode(), device.getAdminName(), device.getAdminPwd());
|
|
|
+ if(sendResult == null){
|
|
|
+// log.error("同步时间失败,设备无返回,设备号:{}", termNo);
|
|
|
+ return R.fail("同步时间失败,设备无返回,设备号:"+ termNo);
|
|
|
+ }
|
|
|
+ if (ObjectUtil.isEmpty(sendResult.getObj("ResponseStatus"))) {
|
|
|
+// log.error("同步时间失败,设备返回格式异常,设备号:{}", termNo);
|
|
|
+ return R.fail("同步时间失败,设备返回格式异常,设备号:"+ termNo);
|
|
|
+ }
|
|
|
+ JSONObject responseStatus = sendResult.getJSONObject("ResponseStatus");
|
|
|
+ Integer statusCode = responseStatus.getInt("statusCode");
|
|
|
+ if (ObjectUtil.notEqual(statusCode, ErrCodeConstants.OK) && ObjectUtil.notEqual(statusCode, ErrCodeConstants.YES)) {
|
|
|
+ String message = StatusCodeEnum.getMessage(statusCode.toString());
|
|
|
+// log.error("同步时间失败,设备返回错误码:{}{},设备号:{}", statusCode,message, termNo);
|
|
|
+ return R.fail(message);
|
|
|
+ }
|
|
|
+ return R.ok("同步时间成功,设备号:"+ termNo);
|
|
|
+ }
|
|
|
|
|
|
// region 从消费机删除人员相关
|
|
|
@Override
|
|
|
@@ -713,7 +847,7 @@ public class SendDeviceServiceImpl implements ISendDeviceService {
|
|
|
if (CollectionUtil.isEmpty(vos)) {
|
|
|
return R.warn("没有要处理人员数据");
|
|
|
}
|
|
|
- log.info("day处理人员数据条数" + vos.size());
|
|
|
+ log.info("day处理人员数据条数{}", vos.size());
|
|
|
XfTermVo termVo = xfTermService.getByMac(macAddress);
|
|
|
if (ObjectUtil.isEmpty(termVo)) {
|
|
|
return R.warn(MessageFormat.format("设备未找到,mac:{0}", macAddress));
|
|
|
@@ -775,7 +909,6 @@ public class SendDeviceServiceImpl implements ISendDeviceService {
|
|
|
EmpInfoDto empDto = getEmpInfoDto(accountVo, false, false, false, deleteAllCard, deleteCard, false);
|
|
|
|
|
|
sendEmpToAllDevice(empDto);
|
|
|
-
|
|
|
return R.ok();
|
|
|
}
|
|
|
|