|
@@ -1,31 +1,44 @@
|
|
|
package org.dromara.server.hik.service.impl;
|
|
package org.dromara.server.hik.service.impl;
|
|
|
|
|
|
|
|
|
|
+import cn.hutool.core.collection.CollectionUtil;
|
|
|
|
|
+import cn.hutool.core.date.DateUtil;
|
|
|
import cn.hutool.core.util.ObjectUtil;
|
|
import cn.hutool.core.util.ObjectUtil;
|
|
|
import cn.hutool.json.JSONObject;
|
|
import cn.hutool.json.JSONObject;
|
|
|
import cn.hutool.json.JSONUtil;
|
|
import cn.hutool.json.JSONUtil;
|
|
|
import lombok.RequiredArgsConstructor;
|
|
import lombok.RequiredArgsConstructor;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
|
|
+import org.apache.dubbo.config.annotation.DubboReference;
|
|
|
|
|
+import org.dromara.backstage.api.RemotePtXfTermService;
|
|
|
|
|
+import org.dromara.backstage.api.RemoteUserAccountService;
|
|
|
|
|
+import org.dromara.backstage.api.domain.vo.RemoteUserAccountVo;
|
|
|
|
|
+import org.dromara.backstage.api.domain.vo.RemoteXfTermVo;
|
|
|
|
|
+import org.dromara.common.core.config.DefaultConfig;
|
|
|
|
|
+import org.dromara.common.core.constant.DefaultConstants;
|
|
|
import org.dromara.common.core.domain.R;
|
|
import org.dromara.common.core.domain.R;
|
|
|
|
|
+import org.dromara.common.core.enums.DeviceBrandEnum;
|
|
|
|
|
+import org.dromara.common.core.exception.ServiceException;
|
|
|
import org.dromara.common.core.utils.StringUtils;
|
|
import org.dromara.common.core.utils.StringUtils;
|
|
|
-import org.dromara.common.json.utils.JsonUtils;
|
|
|
|
|
|
|
+import org.dromara.common.core.utils.ValidatorUtils;
|
|
|
import org.dromara.server.hik.constant.ErrCodeConstants;
|
|
import org.dromara.server.hik.constant.ErrCodeConstants;
|
|
|
import org.dromara.server.hik.constant.HikApiConstants;
|
|
import org.dromara.server.hik.constant.HikApiConstants;
|
|
|
|
|
+import org.dromara.server.hik.constant.HikDefaultConstants;
|
|
|
import org.dromara.server.hik.domain.dto.DeviceDto;
|
|
import org.dromara.server.hik.domain.dto.DeviceDto;
|
|
|
import org.dromara.server.hik.domain.dto.QueryDto;
|
|
import org.dromara.server.hik.domain.dto.QueryDto;
|
|
|
|
|
+import org.dromara.server.hik.domain.dto.UploadEmpDto;
|
|
|
|
|
+import org.dromara.server.hik.domain.dto.UserInfoDto;
|
|
|
|
|
+import org.dromara.server.hik.domain.dto.base.*;
|
|
|
import org.dromara.server.hik.domain.dto.query.QueryEmpResultDto;
|
|
import org.dromara.server.hik.domain.dto.query.QueryEmpResultDto;
|
|
|
import org.dromara.server.hik.enums.ContentTypeEnum;
|
|
import org.dromara.server.hik.enums.ContentTypeEnum;
|
|
|
import org.dromara.server.hik.enums.StatusCodeEnum;
|
|
import org.dromara.server.hik.enums.StatusCodeEnum;
|
|
|
import org.dromara.server.hik.service.ISendDeviceService;
|
|
import org.dromara.server.hik.service.ISendDeviceService;
|
|
|
import org.dromara.server.hik.utils.DigestHttpUtil;
|
|
import org.dromara.server.hik.utils.DigestHttpUtil;
|
|
|
|
|
+import org.dromara.server.hik.utils.JsonConfig;
|
|
|
import org.jetbrains.annotations.NotNull;
|
|
import org.jetbrains.annotations.NotNull;
|
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
+import org.springframework.validation.annotation.Validated;
|
|
|
|
|
|
|
|
-import java.util.ArrayList;
|
|
|
|
|
-import java.util.HashMap;
|
|
|
|
|
-import java.util.List;
|
|
|
|
|
-import java.util.Map;
|
|
|
|
|
-import java.util.concurrent.ExecutionException;
|
|
|
|
|
-import java.util.concurrent.Future;
|
|
|
|
|
|
|
+import java.text.MessageFormat;
|
|
|
|
|
+import java.util.*;
|
|
|
import java.util.concurrent.ScheduledExecutorService;
|
|
import java.util.concurrent.ScheduledExecutorService;
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -44,94 +57,113 @@ import java.util.concurrent.ScheduledExecutorService;
|
|
|
public class SendDeviceServiceImpl implements ISendDeviceService {
|
|
public class SendDeviceServiceImpl implements ISendDeviceService {
|
|
|
private final DigestHttpUtil digestHttpUtil;
|
|
private final DigestHttpUtil digestHttpUtil;
|
|
|
private final ScheduledExecutorService scheduledExecutorService;
|
|
private final ScheduledExecutorService scheduledExecutorService;
|
|
|
|
|
+ private final DefaultConfig defaultConfig;
|
|
|
|
|
+
|
|
|
|
|
+ @DubboReference
|
|
|
|
|
+ private final RemotePtXfTermService remotePtXfTermService;
|
|
|
|
|
+ @DubboReference
|
|
|
|
|
+ private final RemoteUserAccountService remoteUserAccountService;
|
|
|
|
|
+
|
|
|
|
|
+ // region 私有方法
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
- * 给指定设务设置监听服务地址
|
|
|
|
|
|
|
+ * 根据提供的 RemoteUserAccountVo 对象和删除标志,构造并返回一个 EmpInfoDto 对象。
|
|
|
*
|
|
*
|
|
|
- * @param dto 设备信息
|
|
|
|
|
- * @return 设置结果
|
|
|
|
|
|
|
+ * @param accountVo 包含用户账户信息的 RemoteUserAccountVo 对象
|
|
|
|
|
+ * @param deleteUser 布尔标志,指示是否应将用户标记为删除
|
|
|
|
|
+ * @param deleteAllFace 布尔标志,指示是否应删除与用户相关的所有人脸数据
|
|
|
|
|
+ * @param deleteFace 布尔标志,指示是否应删除特定的人脸数据
|
|
|
|
|
+ * @param deleteAllCard 布尔标志,指示是否应删除与用户相关的所有卡片数据
|
|
|
|
|
+ * @param deleteCard 布尔标志,指示是否应删除特定的卡片数据
|
|
|
|
|
+ * @return 一个填充了用户信息、有效性详情、卡片信息和人脸数据的 EmpInfoDto 对象
|
|
|
*/
|
|
*/
|
|
|
- @Override
|
|
|
|
|
- public R<Void> setHttpHostByDto(DeviceDto dto) {
|
|
|
|
|
- String setData = this.createHostXml(dto);
|
|
|
|
|
|
|
+ @NotNull
|
|
|
|
|
+ private static EmpInfoDto getEmpInfoDto(@NotNull RemoteUserAccountVo accountVo, Boolean deleteUser, Boolean deleteAllFace, Boolean deleteFace,
|
|
|
|
|
+ Boolean deleteAllCard, Boolean deleteCard) {
|
|
|
|
|
+ EmpInfoDto empDto = new EmpInfoDto();
|
|
|
|
|
+ // 设置用户基本信息
|
|
|
|
|
+ empDto.setEmployeeNo(accountVo.getUserNo().toString()).setName(accountVo.getRealName());
|
|
|
|
|
+ if (deleteUser) {
|
|
|
|
|
+ empDto.setDeleteUser(Boolean.TRUE);
|
|
|
|
|
+ }
|
|
|
|
|
+ // 设置有效期,海康设备支持有效期最大2037-12-31 23:59:59,所以要和系统的有效期比较取较小值
|
|
|
|
|
+ Date endTime = accountVo.getLifespan();
|
|
|
|
|
+ Date hikEndTime = DateUtil.parse(HikDefaultConstants.EMP_END_TIME);
|
|
|
|
|
+ if (endTime.compareTo(hikEndTime) > 0) {
|
|
|
|
|
+ endTime = hikEndTime;
|
|
|
|
|
+ }
|
|
|
|
|
+ ValidDto validDto = new ValidDto().setBeginTime(getBeginTime()).setEndTime(DateUtil.date(endTime));
|
|
|
|
|
+ empDto.setValid(validDto);
|
|
|
|
|
|
|
|
- JSONObject sendResult = digestHttpUtil.sendPost(dto, setData, HikApiConstants.SET_HTTP_HOSTS, ContentTypeEnum.XML.getCode());
|
|
|
|
|
- R<Void> doResult = this.doSetHostReturnData(sendResult);
|
|
|
|
|
- if (R.isError(doResult)) {
|
|
|
|
|
- return R.fail(StringUtils.format("[IP:{}的设备设置失败,原因:{}]", dto.getDeviceIp(), doResult.getMsg()));
|
|
|
|
|
|
|
+ // 设置用户卡片信息
|
|
|
|
|
+ if (ObjectUtil.isNotEmpty(accountVo.getFactoryId())) {
|
|
|
|
|
+ CardDto cardDto = new CardDto().setCardNo(accountVo.getFactoryId().toString());
|
|
|
|
|
+ if (deleteCard) {
|
|
|
|
|
+ cardDto.setDeleteCard(Boolean.TRUE);
|
|
|
|
|
+ }
|
|
|
|
|
+ List<CardDto> cardList = new ArrayList<>();
|
|
|
|
|
+ cardList.add(cardDto);
|
|
|
|
|
+
|
|
|
|
|
+ CardListDto cardListDto = new CardListDto();
|
|
|
|
|
+ cardListDto.setList(cardList);
|
|
|
|
|
+ if (deleteAllCard) {
|
|
|
|
|
+ cardListDto.setDeleteAllCard(Boolean.TRUE);
|
|
|
|
|
+ }
|
|
|
|
|
+ empDto.setCardInfo(cardListDto);
|
|
|
}
|
|
}
|
|
|
- return R.ok(StringUtils.format("[IP:{}的设备设置成功]", dto.getDeviceIp()));
|
|
|
|
|
|
|
+
|
|
|
|
|
+ // TODO 2025-05-24 因为人员照片原因,暂时不将人脸照片上传到消费机
|
|
|
|
|
+ // 设置用户人脸图片信息
|
|
|
|
|
+ // String photo = accountVo.getFacePicUrl();
|
|
|
|
|
+ // if (ObjectUtil.isNotEmpty(photo)) {
|
|
|
|
|
+ // FaceDto faceDto = new FaceDto().setFDID("1").setFaceID(1L).setFacePicURL(photo);
|
|
|
|
|
+ // if (deleteFace) {
|
|
|
|
|
+ // faceDto.setDeleteFace(Boolean.TRUE);
|
|
|
|
|
+ // }
|
|
|
|
|
+ //
|
|
|
|
|
+ // List<FaceDto> faceList = new ArrayList<>();
|
|
|
|
|
+ // faceList.add(faceDto);
|
|
|
|
|
+ // FaceListDto faceListDto = new FaceListDto().setList(faceList);
|
|
|
|
|
+ // if (deleteAllFace) {
|
|
|
|
|
+ // faceListDto.setDeleteAllFace(Boolean.TRUE);
|
|
|
|
|
+ // }
|
|
|
|
|
+ // empDto.setFaceInfo(faceListDto);
|
|
|
|
|
+ // }
|
|
|
|
|
+
|
|
|
|
|
+ return empDto;
|
|
|
|
|
+
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
- * 给所有设备设置监听服务地址
|
|
|
|
|
|
|
+ * 将 RemoteXfTermVo 对象转换为 DeviceDto 对象。
|
|
|
|
|
+ * 它提取了终端号、管理员名称、管理员密码、设备 IP、设备端口、服务器 IP 和服务器端口等信息,并将其设置到 DeviceDto 实例中。
|
|
|
*
|
|
*
|
|
|
- * @return 设置结果
|
|
|
|
|
|
|
+ * @param termVo 包含终端信息的 RemoteXfTermVo 对象
|
|
|
|
|
+ * @return 转换后的 DeviceDto 对象
|
|
|
*/
|
|
*/
|
|
|
- @Override
|
|
|
|
|
- public R<Void> setHttpHostAll() {
|
|
|
|
|
- // TODO 2025-05-21 luoyibo 所有的设备需要通过远程调用获取
|
|
|
|
|
-
|
|
|
|
|
- List<DeviceDto> list = new ArrayList<>();
|
|
|
|
|
|
|
+ @NotNull
|
|
|
|
|
+ private static DeviceDto getDeviceDto(@NotNull RemoteXfTermVo termVo) {
|
|
|
DeviceDto dto = new DeviceDto();
|
|
DeviceDto dto = new DeviceDto();
|
|
|
- dto.setAdminName("admin");
|
|
|
|
|
- dto.setAdminPwd("Dt20250512");
|
|
|
|
|
- dto.setDeviceIp("192.168.1.15");
|
|
|
|
|
- dto.setDevicePort(8080);
|
|
|
|
|
- dto.setServerIp("192.168.1.8");
|
|
|
|
|
- dto.setServerPort(8080);
|
|
|
|
|
- list.add(dto);
|
|
|
|
|
-
|
|
|
|
|
- dto = new DeviceDto();
|
|
|
|
|
- dto.setAdminName("admin");
|
|
|
|
|
- dto.setAdminPwd("Dt20250512");
|
|
|
|
|
- dto.setDeviceIp("192.168.1.14");
|
|
|
|
|
- dto.setDevicePort(80);
|
|
|
|
|
- dto.setServerIp("192.168.1.8");
|
|
|
|
|
- dto.setServerPort(9000);
|
|
|
|
|
- list.add(dto);
|
|
|
|
|
-
|
|
|
|
|
- List<Future<String>> rlist = new ArrayList<>();
|
|
|
|
|
- List<String> msgList = new ArrayList<>();
|
|
|
|
|
- list.parallelStream().forEach(p -> {
|
|
|
|
|
- Future<String> result = scheduledExecutorService.submit(() -> setHttpHostByDto(p).getMsg());
|
|
|
|
|
- rlist.add(result);
|
|
|
|
|
- });
|
|
|
|
|
- for (Future<String> f : rlist) {
|
|
|
|
|
- try {
|
|
|
|
|
- msgList.add(f.get());
|
|
|
|
|
- } catch (ExecutionException | InterruptedException e) {
|
|
|
|
|
- log.error(e.getCause().getMessage());
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- msgList.forEach(System.out::println);
|
|
|
|
|
- return R.ok("处理完成,详情见处理日志");
|
|
|
|
|
|
|
+ dto.setTermNo(termVo.getTermNo().intValue());
|
|
|
|
|
+ dto.setAdminName(termVo.getAdminName());
|
|
|
|
|
+ dto.setAdminPwd(termVo.getAdminPwd());
|
|
|
|
|
+ dto.setDeviceIp(termVo.getTermIp());
|
|
|
|
|
+ dto.setDevicePort(termVo.getCommPort().intValue());
|
|
|
|
|
+ dto.setServerIp(termVo.getServerIp());
|
|
|
|
|
+ dto.setServerPort(termVo.getServerPort().intValue());
|
|
|
|
|
+
|
|
|
|
|
+ return dto;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
- * 批量查询设备上人员信息。
|
|
|
|
|
- * <p>
|
|
|
|
|
- * 该方法用于向指定设备发起批量查询人员信息的请求,基于提供的查询条件传输对象。
|
|
|
|
|
|
|
+ * 返回当前日期的开始时间,格式化为当天 00:00:00,
|
|
|
*
|
|
*
|
|
|
- * @param dto 查询条件传输对象,包含查询所需的设备信息及分页参数等
|
|
|
|
|
- * @return 响应信息主体,表示查询操作的结果状态及可能的附加信息
|
|
|
|
|
|
|
+ * @return 当前日期的开始时间
|
|
|
*/
|
|
*/
|
|
|
- @Override
|
|
|
|
|
- public R<Void> queryBatchEmpFormDevice(@NotNull QueryDto dto) {
|
|
|
|
|
- DeviceDto device = dto.getDevice();
|
|
|
|
|
- Map<String, Object> params = new HashMap<>();
|
|
|
|
|
- params.put("searchID", dto.getSearchID());
|
|
|
|
|
- params.put("searchResultPosition", (dto.getPageNo() - 1) * dto.getPageSize());
|
|
|
|
|
- params.put("maxResults", dto.getPageSize());
|
|
|
|
|
-
|
|
|
|
|
- String setData = JsonUtils.toJsonString(params);
|
|
|
|
|
- JSONObject sendResult = digestHttpUtil.sendPost(dto.getDevice(), setData, HikApiConstants.QUERY_EMP_ALL, ContentTypeEnum.JSON.getCode());
|
|
|
|
|
-
|
|
|
|
|
- R<Void> doResult = this.doQueryEmpReturnData(sendResult);
|
|
|
|
|
- if (R.isError(doResult)) {
|
|
|
|
|
- return R.fail(StringUtils.format("[IP:{}的设备查询失败,原因:{}]", device.getDeviceIp(), doResult.getMsg()));
|
|
|
|
|
- }
|
|
|
|
|
- return R.ok(StringUtils.format("[IP:{}的设备查询成功],结果:{}", device.getDeviceIp(),doResult.getMsg()));
|
|
|
|
|
|
|
+ private static Date getBeginTime() {
|
|
|
|
|
+ String temp = DateUtil.format(DateUtil.date(), DefaultConstants.DATE_FORMAT);
|
|
|
|
|
+ temp = temp + " 00:00:00";
|
|
|
|
|
+ return DateUtil.parse(temp);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -230,4 +262,428 @@ public class SendDeviceServiceImpl implements ISendDeviceService {
|
|
|
return R.ok(msg);
|
|
return R.ok(msg);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 根据提供的 JSON 对象验证用户检查异常。
|
|
|
|
|
+ * 该方法检查给定 JSON 对象中的 "userCheck" 字段,以确定状态值是否表示错误条件。
|
|
|
|
|
+ * 如果检测到错误,则返回带有适当消息的失败响应。
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param obj 一个非空的 JSON 对象,包含要验证的 "userCheck" 字段
|
|
|
|
|
+ * @return 如果未发现错误则返回成功响应;如果状态值表示错误或发生未知异常,则返回带错误消息的失败响应
|
|
|
|
|
+ */
|
|
|
|
|
+ private R<Void> validUserCheckException(@NotNull JSONObject obj) {
|
|
|
|
|
+ if (ObjectUtil.isNotEmpty(obj.getObj("userCheck"))) {
|
|
|
|
|
+ JSONObject responseStatus = obj.getJSONObject("userCheck");
|
|
|
|
|
+ Integer statusCode = responseStatus.getInt("statusValue");
|
|
|
|
|
+ if (ObjectUtil.notEqual(statusCode, ErrCodeConstants.OK) && ObjectUtil.notEqual(statusCode, ErrCodeConstants.YES)) {
|
|
|
|
|
+ return R.fail(StatusCodeEnum.getMessage("userCheck_" + statusCode.toString()));
|
|
|
|
|
+ } else {
|
|
|
|
|
+ return R.fail("未知异常");
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return R.ok();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 根据提供的 JSON 对象验证状态码异常。
|
|
|
|
|
+ * 如果 JSON 对象中的 "errorMsg" 字段不为空,则返回带有错误消息的失败响应。
|
|
|
|
|
+ * 否则,返回成功响应。
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param obj 包含要验证的错误消息的 JSON 对象;不能为空
|
|
|
|
|
+ * @return 一个响应对象,根据验证结果指示成功或失败
|
|
|
|
|
+ */
|
|
|
|
|
+ private R<Void> validStatusCodeException(@NotNull JSONObject obj) {
|
|
|
|
|
+ String errorMsg = obj.getStr("errorMsg");
|
|
|
|
|
+ if (ObjectUtil.isNotEmpty(errorMsg)) {
|
|
|
|
|
+ return R.fail(errorMsg);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return R.ok();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 验证提供的 JSON 对象中包含的详细信息。
|
|
|
|
|
+ * 检查 "DetailInfo" 对象是否存在,并评估其错误码。
|
|
|
|
|
+ * 如果错误码与可接受的值(ErrCodeConstants.OK 或 ErrCodeConstants.YES)不匹配,
|
|
|
|
|
+ * 则返回失败响应以及相关的用户错误消息。
|
|
|
|
|
+ * 否则,返回成功响应。
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param obj 包含要验证的 "DetailInfo" 的 JSON 对象;不能为空
|
|
|
|
|
+ * @return 如果验证通过则返回成功响应,如果验证失败则返回包含错误消息的失败响应
|
|
|
|
|
+ */
|
|
|
|
|
+ private R<Void> validDetailInfo(@NotNull JSONObject obj) {
|
|
|
|
|
+ if (ObjectUtil.isNotEmpty(obj.getObj("DetailInfo"))) {
|
|
|
|
|
+ JSONObject responseStatus = obj.getJSONObject("DetailInfo");
|
|
|
|
|
+ Integer statusCode = responseStatus.getInt("errorCode");
|
|
|
|
|
+ if (ObjectUtil.notEqual(statusCode, ErrCodeConstants.OK) && ObjectUtil.notEqual(statusCode, ErrCodeConstants.YES)) {
|
|
|
|
|
+ return R.fail(responseStatus.getStr("userErrorMsg"));
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return R.ok();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 创建并发送需要操作的员工信息到指定设备
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param device 员工信息将被发送到的设备
|
|
|
|
|
+ * @param empInfo 要创建并传输的员工信息
|
|
|
|
|
+ * @return 一个表示操作结果的 R 实例,封装了任何可能的异常或验证结果
|
|
|
|
|
+ */
|
|
|
|
|
+ private R<Void> createOperatorEmpInfo(DeviceDto device, EmpInfoDto empInfo) {
|
|
|
|
|
+ UserInfoDto sendDto = new UserInfoDto();
|
|
|
|
|
+ sendDto.setUserInfoAndRight(empInfo);
|
|
|
|
|
+ String setData = JSONUtil.toJsonStr(sendDto, JsonConfig.getConfig());
|
|
|
|
|
+
|
|
|
|
|
+ JSONObject sendResult = digestHttpUtil.sendPost(device, setData, HikApiConstants.SEND_EMP_INFO, ContentTypeEnum.JSON.getCode());
|
|
|
|
|
+ R<Void> check = this.validUserCheckException(sendResult);
|
|
|
|
|
+ if (R.isError(check)) {
|
|
|
|
|
+ return R.fail(
|
|
|
|
|
+ MessageFormat.format("[上传人员信息失败]-[设备IP:{0}, 人员信息:{1}, 错误信息:{2}", device.getDeviceIp(), empInfo,
|
|
|
|
|
+ check.getMsg()));
|
|
|
|
|
+ }
|
|
|
|
|
+ check = this.validStatusCodeException(sendResult);
|
|
|
|
|
+ if (R.isError(check)) {
|
|
|
|
|
+ return R.fail(
|
|
|
|
|
+ MessageFormat.format("[上传人员信息失败]-[设备IP:{0}, 人员信息:{1}, 错误信息:{2}", device.getDeviceIp(), empInfo,
|
|
|
|
|
+ check.getMsg()));
|
|
|
|
|
+ }
|
|
|
|
|
+ check = this.validDetailInfo(sendResult);
|
|
|
|
|
+ if (R.isError(check)) {
|
|
|
|
|
+ return R.fail(
|
|
|
|
|
+ MessageFormat.format("[上传人员信息失败]-[设备IP:{0}, 人员信息:{1}, 错误信息:{2}", device.getDeviceIp(), empInfo,
|
|
|
|
|
+ check.getMsg()));
|
|
|
|
|
+ }
|
|
|
|
|
+ return R.ok(MessageFormat.format("[上传人员信息成功]-[设备IP:{0}, 人员信息:{1}]", device.getDeviceIp(), empInfo));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 根据提供的终端编号获取一个 DeviceDto 对象。
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param termNo 用于查询和检索设备信息的终端编号
|
|
|
|
|
+ * @return 与查询的终端编号对应的 DeviceDto 对象
|
|
|
|
|
+ * @throws ServiceException 如果设备不存在,或者设备不是海康威视(Hikvision)品牌的设备
|
|
|
|
|
+ */
|
|
|
|
|
+ @NotNull
|
|
|
|
|
+ private DeviceDto getDeviceDto(Long termNo) {
|
|
|
|
|
+ RemoteXfTermVo termVo = remotePtXfTermService.queryByNo(termNo, defaultConfig.getTenantId());
|
|
|
|
|
+ if (ObjectUtil.isEmpty(termVo)) {
|
|
|
|
|
+ throw new ServiceException(MessageFormat.format("设备不存在,设备编号:{0}", termNo));
|
|
|
|
|
+ }
|
|
|
|
|
+ if (ObjectUtil.notEqual(DeviceBrandEnum.HK.getCode(), termVo.getBrand())) {
|
|
|
|
|
+ throw new ServiceException(MessageFormat.format("无法处理非海康设备,设备编号:{0}", termNo));
|
|
|
|
|
+ }
|
|
|
|
|
+ return getDeviceDto(termVo);
|
|
|
|
|
+ }
|
|
|
|
|
+ // endregion
|
|
|
|
|
+
|
|
|
|
|
+ // region 设置监听相关
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public R<Void> setHttpHostByDto(@Validated DeviceDto dto) {
|
|
|
|
|
+ ValidatorUtils.validate(dto);
|
|
|
|
|
+
|
|
|
|
|
+ if (ObjectUtil.isEmpty(dto.getServerIp())) {
|
|
|
|
|
+ return R.fail("监听IP不能为空");
|
|
|
|
|
+ }
|
|
|
|
|
+ if (ObjectUtil.isEmpty(dto.getServerPort())) {
|
|
|
|
|
+ return R.fail("监听端口不能为空");
|
|
|
|
|
+ }
|
|
|
|
|
+ String setData = this.createHostXml(dto);
|
|
|
|
|
+
|
|
|
|
|
+ JSONObject sendResult = digestHttpUtil.sendPost(dto, setData, HikApiConstants.SET_HTTP_HOSTS, ContentTypeEnum.XML.getCode());
|
|
|
|
|
+ R<Void> doResult = this.doSetHostReturnData(sendResult);
|
|
|
|
|
+ if (R.isError(doResult)) {
|
|
|
|
|
+ return R.fail(MessageFormat.format("[IP:{0}的设备设置失败,原因:{1}]", dto.getDeviceIp(), doResult.getMsg()));
|
|
|
|
|
+ }
|
|
|
|
|
+ return R.ok(MessageFormat.format("[IP:{0}的设备设置成功]", dto.getDeviceIp()));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public R<Void> setHttpHostByTermNo(Long termNo) {
|
|
|
|
|
+ DeviceDto dto = getDeviceDto(termNo);
|
|
|
|
|
+
|
|
|
|
|
+ return this.setHttpHostByDto(dto);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public R<Void> setHttpHostAll() {
|
|
|
|
|
+ List<RemoteXfTermVo> termList = remotePtXfTermService.queryListByBrand("hk");
|
|
|
|
|
+ if (CollectionUtil.isEmpty(termList)) {
|
|
|
|
|
+ return R.warn("没有要配置的设备");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ termList.parallelStream().forEach(p -> {
|
|
|
|
|
+ scheduledExecutorService.execute(() -> {
|
|
|
|
|
+ DeviceDto dto = getDeviceDto(p);
|
|
|
|
|
+ R<Void> result = setHttpHostByDto(dto);
|
|
|
|
|
+ log.info(result.getMsg());
|
|
|
|
|
+ });
|
|
|
|
|
+ });
|
|
|
|
|
+ return R.ok("处理完成,详情见处理日志");
|
|
|
|
|
+ }
|
|
|
|
|
+ // endregion
|
|
|
|
|
+
|
|
|
|
|
+ // region 从消费机删除人员相关
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public R<Void> deleteEmpByUserNo(DeviceDto device, String userNo) {
|
|
|
|
|
+ EmpInfoDto delEmpDto = new EmpInfoDto();
|
|
|
|
|
+ delEmpDto.setDeleteUser(Boolean.TRUE);
|
|
|
|
|
+ delEmpDto.setEmployeeNo(userNo);
|
|
|
|
|
+
|
|
|
|
|
+ R<Void> delResult = this.createOperatorEmpInfo(device, delEmpDto);
|
|
|
|
|
+ if (R.isError(delResult)) {
|
|
|
|
|
+ return R.fail(
|
|
|
|
|
+ MessageFormat.format("[处理人员失败]-[设备IP:{0}, 人员编号:{1}, 错误信息:{2}", device.getDeviceIp(), userNo, delResult.getMsg()));
|
|
|
|
|
+ }
|
|
|
|
|
+ return R.ok(MessageFormat.format("[处理人员成功]-[设备IP:{0}, 人员编号:{1}]", device.getDeviceIp(), userNo));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public R<Void> deleteEmpFromDevice(Long termNo, Long userId) {
|
|
|
|
|
+ DeviceDto device = getDeviceDto(termNo);
|
|
|
|
|
+ RemoteUserAccountVo accountVo = remoteUserAccountService.getUserAccountVoBy(userId);
|
|
|
|
|
+ if (ObjectUtil.isEmpty(accountVo)) {
|
|
|
|
|
+ return R.fail(
|
|
|
|
|
+ MessageFormat.format("[处理人员失败]-[设备IP:{0}, 人员Id:{1}, 错误信息:无此Id对应的人员信息", device.getDeviceIp(), userId));
|
|
|
|
|
+ }
|
|
|
|
|
+ EmpInfoDto empInfo = getEmpInfoDto(accountVo, true, false, false, false, false);
|
|
|
|
|
+ R<Void> result = createOperatorEmpInfo(device, empInfo);
|
|
|
|
|
+
|
|
|
|
|
+ log.info(result.getMsg());
|
|
|
|
|
+
|
|
|
|
|
+ return result;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public R<Void> deleteEmpFromDevice(Long termNo) {
|
|
|
|
|
+ DeviceDto deviceDto = getDeviceDto(termNo);
|
|
|
|
|
+ List<RemoteUserAccountVo> accountVoList = remoteUserAccountService.getUserAccountVoList();
|
|
|
|
|
+ accountVoList.parallelStream().forEach(p -> {
|
|
|
|
|
+ scheduledExecutorService.execute(() -> {
|
|
|
|
|
+ EmpInfoDto empDto = getEmpInfoDto(p, true, false, false, false, false);
|
|
|
|
|
+ R<Void> result = createOperatorEmpInfo(deviceDto, empDto);
|
|
|
|
|
+ log.info(result.getMsg());
|
|
|
|
|
+ });
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ return R.ok();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public R<Void> deleteOneEmpFromDevice(Long userId) {
|
|
|
|
|
+ RemoteUserAccountVo accountVo = remoteUserAccountService.getUserAccountVoBy(userId);
|
|
|
|
|
+ if (ObjectUtil.isEmpty(accountVo)) {
|
|
|
|
|
+ return R.fail(
|
|
|
|
|
+ MessageFormat.format("[处理人员失败]-[人员Id:{0}, 错误信息:无此Id对应的人员信息", userId));
|
|
|
|
|
+ }
|
|
|
|
|
+ EmpInfoDto empInfo = getEmpInfoDto(accountVo, true, false, false, false, false);
|
|
|
|
|
+
|
|
|
|
|
+ List<RemoteXfTermVo> termList = remotePtXfTermService.queryListByBrand("hk");
|
|
|
|
|
+ if (CollectionUtil.isEmpty(termList)) {
|
|
|
|
|
+ return R.warn("没有要处理人员的设备");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ termList.parallelStream().forEach(p -> {
|
|
|
|
|
+ scheduledExecutorService.execute(() -> {
|
|
|
|
|
+ DeviceDto device = getDeviceDto(p);
|
|
|
|
|
+ R<Void> result = createOperatorEmpInfo(device, empInfo);
|
|
|
|
|
+ log.info(result.getMsg());
|
|
|
|
|
+ });
|
|
|
|
|
+ });
|
|
|
|
|
+ return R.ok();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public R<Void> deleteEmpFromDevice() {
|
|
|
|
|
+ // 获取所有设备
|
|
|
|
|
+ List<RemoteXfTermVo> termList = remotePtXfTermService.queryListByBrand("hk");
|
|
|
|
|
+ if (CollectionUtil.isEmpty(termList)) {
|
|
|
|
|
+ return R.warn("没有要处理人员的设备");
|
|
|
|
|
+ }
|
|
|
|
|
+ // 获取所有人员
|
|
|
|
|
+ List<RemoteUserAccountVo> accountVoList = remoteUserAccountService.getUserAccountVoList();
|
|
|
|
|
+ if (CollectionUtil.isEmpty(accountVoList)) {
|
|
|
|
|
+ return R.warn("没有要处理的人员");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 并行处理
|
|
|
|
|
+ termList.parallelStream().forEach(p -> {
|
|
|
|
|
+ scheduledExecutorService.execute(() -> {
|
|
|
|
|
+ DeviceDto device = getDeviceDto(p);
|
|
|
|
|
+ accountVoList.parallelStream().forEach(t -> {
|
|
|
|
|
+ EmpInfoDto empInfo = getEmpInfoDto(t, true, false, false, false, false);
|
|
|
|
|
+ R<Void> result = createOperatorEmpInfo(device, empInfo);
|
|
|
|
|
+ log.info(result.getMsg());
|
|
|
|
|
+ });
|
|
|
|
|
+ });
|
|
|
|
|
+ });
|
|
|
|
|
+ return R.ok();
|
|
|
|
|
+ }
|
|
|
|
|
+ // endregion
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public R<Void> deleteAllCardByUserNo(DeviceDto device, String userNo) {
|
|
|
|
|
+ CardListDto cardList = new CardListDto();
|
|
|
|
|
+ cardList.setDeleteAllCard(Boolean.TRUE);
|
|
|
|
|
+
|
|
|
|
|
+ EmpInfoDto delEmpDto = new EmpInfoDto();
|
|
|
|
|
+ delEmpDto.setEmployeeNo(userNo);
|
|
|
|
|
+ delEmpDto.setName("胡哲");
|
|
|
|
|
+ delEmpDto.setCardInfo(cardList);
|
|
|
|
|
+
|
|
|
|
|
+ R<Void> check = this.createOperatorEmpInfo(device, delEmpDto);
|
|
|
|
|
+ if (R.isError(check)) {
|
|
|
|
|
+ return R.fail(
|
|
|
|
|
+ MessageFormat.format("[处理人员所有卡片失败]-[设备IP:{0}, 人员编号:{1}, 错误信息:{2}", device.getDeviceIp(), userNo, check.getMsg()));
|
|
|
|
|
+ }
|
|
|
|
|
+ return R.ok(MessageFormat.format("[处理人员所有卡片成功]-[设备IP:{0}, 人员编号:{1}]", device.getDeviceIp(), userNo));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public R<Void> deleteCardByUserNo(DeviceDto device, String userNo, String factoryId) {
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public R<Void> deleteAllFaceByUserNo(DeviceDto device, String userNo) {
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public R<Void> deleteFaceByUserNo(DeviceDto device, String userNo, String faceId) {
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ // region 向消费机上传人员相关
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public R<Void> upLoadEmpToDevice(UploadEmpDto uploadEmpDto) {
|
|
|
|
|
+ DeviceDto device = uploadEmpDto.getDevice();
|
|
|
|
|
+ EmpInfoDto empDto = uploadEmpDto.getEmployee();
|
|
|
|
|
+ ValidDto validDto = uploadEmpDto.getValid();
|
|
|
|
|
+ CardDto cardDto = uploadEmpDto.getCard();
|
|
|
|
|
+ FaceDto faceDto = uploadEmpDto.getFace();
|
|
|
|
|
+ if (ObjectUtil.isNotEmpty(cardDto)) {
|
|
|
|
|
+ List<CardDto> cardList = new ArrayList<>();
|
|
|
|
|
+ cardList.add(cardDto);
|
|
|
|
|
+
|
|
|
|
|
+ CardListDto cardListDto = new CardListDto();
|
|
|
|
|
+ cardListDto.setList(cardList);
|
|
|
|
|
+ empDto.setCardInfo(cardListDto);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (ObjectUtil.isNotEmpty(faceDto)) {
|
|
|
|
|
+ List<FaceDto> faceList = new ArrayList<>();
|
|
|
|
|
+ faceList.add(faceDto);
|
|
|
|
|
+ FaceListDto faceListDto = new FaceListDto();
|
|
|
|
|
+ faceListDto.setList(faceList);
|
|
|
|
|
+ empDto.setFaceInfo(faceListDto);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (ObjectUtil.isNotEmpty(validDto)) {
|
|
|
|
|
+ empDto.setValid(validDto);
|
|
|
|
|
+ }
|
|
|
|
|
+ String strEmpInfo = JSONUtil.toJsonStr(empDto, JsonConfig.getConfig());
|
|
|
|
|
+ R<Void> check = this.createOperatorEmpInfo(device, empDto);
|
|
|
|
|
+ if (R.isError(check)) {
|
|
|
|
|
+ return R.fail(
|
|
|
|
|
+ MessageFormat.format("[上传人员信息失败]-[设备IP:{0}, 人员信息:{1}, 错误信息:{2}", device.getDeviceIp(), strEmpInfo, check.getMsg()));
|
|
|
|
|
+ }
|
|
|
|
|
+ return R.ok(MessageFormat.format("[上传人员信息成功]-[设备IP:{0}, 人员信息:{1}]", device.getDeviceIp(), strEmpInfo));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public R<Void> upLoadEmpToDevice(Long termNo) {
|
|
|
|
|
+ DeviceDto deviceDto = getDeviceDto(termNo);
|
|
|
|
|
+ List<RemoteUserAccountVo> accountVoList = remoteUserAccountService.getUserAccountVoList();
|
|
|
|
|
+ if (CollectionUtil.isEmpty(accountVoList)) {
|
|
|
|
|
+ return R.warn("没有要处理的人员");
|
|
|
|
|
+ }
|
|
|
|
|
+ // 并行处理人员列表
|
|
|
|
|
+ accountVoList.parallelStream().forEach(p -> {
|
|
|
|
|
+ scheduledExecutorService.execute(() -> {
|
|
|
|
|
+ EmpInfoDto empDto = getEmpInfoDto(p, false, false, false, false, false);
|
|
|
|
|
+ R<Void> result = createOperatorEmpInfo(deviceDto, empDto);
|
|
|
|
|
+ log.info(result.getMsg());
|
|
|
|
|
+ });
|
|
|
|
|
+ });
|
|
|
|
|
+ return R.ok();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public R<Void> upLoadEmpToDevice(Long termNo, Long userId) {
|
|
|
|
|
+ DeviceDto deviceDto = getDeviceDto(termNo);
|
|
|
|
|
+
|
|
|
|
|
+ RemoteUserAccountVo accountVo = remoteUserAccountService.getUserAccountVoBy(userId);
|
|
|
|
|
+
|
|
|
|
|
+ EmpInfoDto empDto = getEmpInfoDto(accountVo, false, false, false, false, false);
|
|
|
|
|
+
|
|
|
|
|
+ return this.createOperatorEmpInfo(deviceDto, empDto);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public R<Void> upLoadEmpToDevice() {
|
|
|
|
|
+ // 获取所有设备
|
|
|
|
|
+ List<RemoteXfTermVo> termList = remotePtXfTermService.queryListByBrand("hk");
|
|
|
|
|
+ if (CollectionUtil.isEmpty(termList)) {
|
|
|
|
|
+ return R.warn("没有要处理人员的设备");
|
|
|
|
|
+ }
|
|
|
|
|
+ // 获取所有人员
|
|
|
|
|
+ List<RemoteUserAccountVo> accountVoList = remoteUserAccountService.getUserAccountVoList();
|
|
|
|
|
+ if (CollectionUtil.isEmpty(accountVoList)) {
|
|
|
|
|
+ return R.warn("没有要处理的人员");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 并行处理
|
|
|
|
|
+ termList.parallelStream().forEach(p -> {
|
|
|
|
|
+ scheduledExecutorService.execute(() -> {
|
|
|
|
|
+ DeviceDto device = getDeviceDto(p);
|
|
|
|
|
+ accountVoList.parallelStream().forEach(t -> {
|
|
|
|
|
+ EmpInfoDto empInfo = getEmpInfoDto(t, false, false, false, false, false);
|
|
|
|
|
+ R<Void> result = createOperatorEmpInfo(device, empInfo);
|
|
|
|
|
+ log.info(result.getMsg());
|
|
|
|
|
+ });
|
|
|
|
|
+ });
|
|
|
|
|
+ });
|
|
|
|
|
+ return R.ok();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public R<Void> upLoadEmpToAllDevice(Long userId) {
|
|
|
|
|
+ RemoteUserAccountVo accountVo = remoteUserAccountService.getUserAccountVoBy(userId);
|
|
|
|
|
+ if (ObjectUtil.isEmpty(accountVo)) {
|
|
|
|
|
+ return R.warn(MessageFormat.format("没有要处理的人员信息,userId:{0}", userId));
|
|
|
|
|
+ }
|
|
|
|
|
+ EmpInfoDto empDto = getEmpInfoDto(accountVo, false, false, false, false, false);
|
|
|
|
|
+
|
|
|
|
|
+ List<RemoteXfTermVo> termList = remotePtXfTermService.queryListByBrand("hk");
|
|
|
|
|
+ if (CollectionUtil.isEmpty(termList)) {
|
|
|
|
|
+ return R.warn("没有要处理的设备");
|
|
|
|
|
+ }
|
|
|
|
|
+ termList.parallelStream().forEach(p -> {
|
|
|
|
|
+ scheduledExecutorService.execute(() -> {
|
|
|
|
|
+ DeviceDto deviceDto = getDeviceDto(p);
|
|
|
|
|
+ R<Void> result = this.createOperatorEmpInfo(deviceDto, empDto);
|
|
|
|
|
+ log.info(result.getMsg());
|
|
|
|
|
+ });
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ return R.ok();
|
|
|
|
|
+ }
|
|
|
|
|
+ // endregion
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public R<Void> queryBatchEmpFormDevice(@NotNull QueryDto dto) {
|
|
|
|
|
+ DeviceDto device = dto.getDevice();
|
|
|
|
|
+ Map<String, Object> params = new HashMap<>();
|
|
|
|
|
+ params.put("searchID", dto.getSearchID());
|
|
|
|
|
+ params.put("searchResultPosition", (dto.getPageNo() - 1) * dto.getPageSize());
|
|
|
|
|
+ params.put("maxResults", dto.getPageSize());
|
|
|
|
|
+
|
|
|
|
|
+ String setData = JSONUtil.toJsonStr(params);
|
|
|
|
|
+ JSONObject sendResult = digestHttpUtil.sendPost(dto.getDevice(), setData, HikApiConstants.QUERY_EMP_ALL, ContentTypeEnum.JSON.getCode());
|
|
|
|
|
+
|
|
|
|
|
+ R<Void> doResult = this.doQueryEmpReturnData(sendResult);
|
|
|
|
|
+ if (R.isError(doResult)) {
|
|
|
|
|
+ return R.fail(StringUtils.format("[IP:{}的设备查询失败,原因:{}]", device.getDeviceIp(), doResult.getMsg()));
|
|
|
|
|
+ }
|
|
|
|
|
+ return R.ok(StringUtils.format("[IP:{}的设备查询成功],结果:{}", device.getDeviceIp(), doResult.getMsg()));
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|