diff --git a/src/main/java/com/zhgd/redis/lock/RedisRepository.java b/src/main/java/com/zhgd/redis/lock/RedisRepository.java index 0f6a1872f..b8ca507b6 100644 --- a/src/main/java/com/zhgd/redis/lock/RedisRepository.java +++ b/src/main/java/com/zhgd/redis/lock/RedisRepository.java @@ -18,6 +18,7 @@ import org.springframework.data.redis.serializer.StringRedisSerializer; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.util.*; +import java.util.concurrent.TimeUnit; import java.util.function.Supplier; /** @@ -176,6 +177,15 @@ public class RedisRepository { }); } + /** + * @param key + * @param expireTime 毫秒 + * @return + */ + public boolean setNx(final String key, Long expireTime) { + return redisTemplate.opsForValue().setIfAbsent(key, "1", expireTime, TimeUnit.MILLISECONDS); + } + /** * 查询在这个时间段内即将过期的key * diff --git a/src/main/java/com/zhgd/xmgl/call/HikvisionCall.java b/src/main/java/com/zhgd/xmgl/call/HikvisionCall.java index cdf9c67fb..0356e2501 100644 --- a/src/main/java/com/zhgd/xmgl/call/HikvisionCall.java +++ b/src/main/java/com/zhgd/xmgl/call/HikvisionCall.java @@ -10,6 +10,7 @@ import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.zhgd.jeecg.common.api.vo.Result; +import com.zhgd.redis.lock.RedisRepository; import com.zhgd.xmgl.base.*; import com.zhgd.xmgl.modules.basicdata.entity.HikvisionRequestRetry; import com.zhgd.xmgl.modules.basicdata.mapper.HikvisionRequestRetryMapper; @@ -27,6 +28,7 @@ import com.zhgd.xmgl.modules.project.mapper.ProjectMapper; import com.zhgd.xmgl.modules.worker.entity.*; import com.zhgd.xmgl.modules.worker.mapper.EnterpriseInfoMapper; import com.zhgd.xmgl.modules.worker.mapper.UfaceDevMapper; +import com.zhgd.xmgl.modules.worker.mapper.WorkerAttendanceMapper; import com.zhgd.xmgl.modules.worker.mapper.WorkerInfoMapper; import com.zhgd.xmgl.modules.worker.service.IWorkerAttendancePresenceService; import com.zhgd.xmgl.modules.worker.service.IWorkerAttendanceService; @@ -64,6 +66,9 @@ public class HikvisionCall { private ProjectMapper projectMapper; @Autowired @Lazy + private RedisRepository redisRepository; + @Autowired + @Lazy private EnterpriseInfoMapper enterpriseInfoMapper; @Autowired @Lazy @@ -73,6 +78,9 @@ public class HikvisionCall { private IWorkerAttendanceService workerAttendanceService; @Autowired @Lazy + private WorkerAttendanceMapper workerAttendanceMapper; + @Autowired + @Lazy private IWorkerAttendancePresenceService workerAttendancePresenceService; @Autowired @Lazy @@ -284,66 +292,84 @@ public class HikvisionCall { .eq(Project::getSyncHikvision, 1); if (StringUtils.isNotBlank(projectSn)) { queryWrapper.eq(Project::getProjectSn, projectSn); + if (!redisRepository.setNx("getDoorEvents:projectSn" + projectSn, 1000 * 30L)) { + return Result.ok("正在同步中请耐心等待通知!"); + } } List projects = projectMapper.selectList(queryWrapper); - for (Project project : projects) { - List ufaceDevs = ufaceDevMapper.selectList(new LambdaQueryWrapper() - .eq(UfaceDev::getProjectSn, project.getProjectSn())); - for (UfaceDev ufaceDev : ufaceDevs) { - param.put("doorIndexCode", ufaceDev.getDevSn()); - param.put("pageNo", 1); - Integer total = 0; - do { - String rs = getDoorEventsForHttp(project, param); - JSONObject joData = HikvisionUtil.getJSONObjectData(rs); - if (joData != null) { - total = joData.getInteger("total"); - if (!Objects.equals(total, 0)) { - JSONArray listJa = joData.getJSONArray("list"); - for (int i = 0; i < listJa.size(); i++) { - JSONObject listJo = listJa.getJSONObject(i); - String eventTime = listJo.getString("eventTime"); - String personId = listJo.getString("personId"); - String personName = listJo.getString("personName"); - String doorIndexCode = listJo.getString("doorIndexCode"); - String picUri = listJo.getString("picUri"); - String svrIndexCode = listJo.getString("svrIndexCode"); - WorkerInfo workerInfo = workerInfoMapper.selectById(personId); - if (workerInfo == null) { - log.error("未找到该人员信息,personName:{}", personName); - continue; - } - HashMap map = new HashMap<>(); - String time = DateUtil.formatDateTime(DateUtil.parse(eventTime)); - map.put("passTime", time); - map.put("idCard", workerInfo.getIdCard()); - map.put("attendanceNumber", workerInfo.getAttendanceNumber()); - int passType = workerAttendanceServiceImpl.getPassType(ufaceDev, time); - map.put("direction", passType); - map.put("passType", 2); - map.put("projectCode", workerInfo.getProjectSn()); - map.put("devCode", doorIndexCode); - - try { - HikvisionEventsPictureRq rq = new HikvisionEventsPictureRq(); - rq.setPicUri(picUri); - rq.setSvrIndexCode(svrIndexCode); - map.put("faceUrl", saveToLocal(getHikvisionEventsPicture(rq, project.getArtemisConfigHost(), project.getArtemisConfigAppKey(), project.getArtemisConfigAppSecret()))); - } catch (Exception e) { - e.printStackTrace(); - } - - workerAttendanceService.saveExternalPassRecord(map); - } - param.put("pageNo", param.getIntValue("pageNo") + 1); - } - } - } while (total > 0); - } - workerAttendancePresenceService.addNowAllWorkerAttendancePresence(projectSn); + if (CollUtil.isEmpty(projects)) { + return Result.error("项目未配置海康同步功能"); } - log.info("服务挂了主动获取门禁点事件的人员通行记录执行完成,startTime:{},endTime:{}", startTime, endTime); - return Result.ok(); + CompletableFuture.runAsync(() -> { + for (Project project : projects) { + List ufaceDevs = ufaceDevMapper.selectList(new LambdaQueryWrapper() + .eq(UfaceDev::getProjectSn, project.getProjectSn())); + for (UfaceDev ufaceDev : ufaceDevs) { + param.put("doorIndexCode", ufaceDev.getDevSn()); + param.put("pageNo", 1); + Integer total = 0; + do { + String rs = getDoorEventsForHttp(project, param); + JSONObject joData = HikvisionUtil.getJSONObjectData(rs); + if (joData != null) { + total = joData.getInteger("total"); + if (!Objects.equals(total, 0)) { + JSONArray listJa = joData.getJSONArray("list"); + for (int i = 0; i < listJa.size(); i++) { + JSONObject listJo = listJa.getJSONObject(i); + String eventTime = listJo.getString("eventTime"); + String personId = listJo.getString("personId"); + String personName = listJo.getString("personName"); + String doorIndexCode = listJo.getString("doorIndexCode"); + String picUri = listJo.getString("picUri"); + String svrIndexCode = listJo.getString("svrIndexCode"); + WorkerInfo workerInfo = workerInfoMapper.selectById(personId); + if (workerInfo == null) { + log.error("未找到该人员信息,personName:{}", personName); + continue; + } + HashMap map = new HashMap<>(); + String time = DateUtil.formatDateTime(DateUtil.parse(eventTime)); + map.put("passTime", time); + map.put("idCard", workerInfo.getIdCard()); + map.put("attendanceNumber", workerInfo.getAttendanceNumber()); + int passType = workerAttendanceServiceImpl.getPassType(ufaceDev, time); + map.put("direction", passType); + map.put("passType", 2); + map.put("projectCode", workerInfo.getProjectSn()); + map.put("devCode", doorIndexCode); + + try { + HikvisionEventsPictureRq rq = new HikvisionEventsPictureRq(); + rq.setPicUri(picUri); + rq.setSvrIndexCode(svrIndexCode); + map.put("faceUrl", saveToLocal(getHikvisionEventsPicture(rq, project.getArtemisConfigHost(), project.getArtemisConfigAppKey(), project.getArtemisConfigAppSecret()))); + } catch (Exception e) { + e.printStackTrace(); + } + Integer count = workerAttendanceMapper.selectCount(new LambdaQueryWrapper() + .eq(WorkerAttendance::getPersonSn, workerInfo.getPersonSn()) + .eq(WorkerAttendance::getCreateTime, time) + ); + if (count == 0) { + workerAttendanceService.saveExternalPassRecord(map); + } + } + param.put("pageNo", param.getIntValue("pageNo") + 1); + } + } + } while (total > 0); + } + workerAttendancePresenceService.addNowAllWorkerAttendancePresence(projectSn); + } + log.info("服务挂了主动获取门禁点事件的人员通行记录执行完成,startTime:{},endTime:{}", startTime, endTime); + if (SecurityUtils.getUser().getUserId() != null) { + String title = "同步人员通行数据成功"; + String msg = title + ",同步时间段:startTime:" + startTime + ",endTime:" + endTime; + noticeService.addUserNotice(SecurityUtils.getUser().getUserId(), msg, title, "2"); + } + }); + return Result.ok("已在后台同步人员数据,请耐心等待!"); } @ApiOperation(value = "服务挂了主动获取查询过车记录", notes = "服务挂了主动获取查询过车记录", httpMethod = "POST") @@ -366,17 +392,25 @@ public class HikvisionCall { .eq(Project::getSyncHikvision, 1); if (StringUtils.isNotBlank(projectSn)) { queryWrapper.eq(Project::getProjectSn, projectSn); + if (!redisRepository.setNx("getCrossRecords:projectSn" + projectSn, 1000 * 30L)) { + return Result.ok("正在同步中请耐心等待通知!"); + } } List projects = projectMapper.selectList(queryWrapper); - for (Project project : projects) { - List ufaceDevs = ufaceDevMapper.selectList(new LambdaQueryWrapper() - .eq(UfaceDev::getProjectSn, project.getProjectSn())); - for (UfaceDev ufaceDev : ufaceDevs) { - param.put("doorIndexCode", ufaceDev.getDevSn()); + if (CollUtil.isEmpty(projects)) { + return Result.error("项目未配置海康同步功能"); + } + CompletableFuture.runAsync(() -> { + for (Project project : projects) { param.put("pageNo", 1); + String projectParkCode = getProjectParkCode(project); + if (StringUtils.isBlank(projectParkCode)) { + continue; + } + param.put("parkSyscode", projectParkCode); Integer total = 0; do { - String rs = getDoorEventsForHttp(project, param); + String rs = getCrossRecordsForHttp(project, param); JSONObject joData = HikvisionUtil.getJSONObjectData(rs); if (joData != null) { total = joData.getInteger("total"); @@ -384,48 +418,68 @@ public class HikvisionCall { JSONArray listJa = joData.getJSONArray("list"); for (int i = 0; i < listJa.size(); i++) { JSONObject listJo = listJa.getJSONObject(i); - String eventTime = listJo.getString("eventTime"); - String personId = listJo.getString("personId"); - String personName = listJo.getString("personName"); - String doorIndexCode = listJo.getString("doorIndexCode"); - String picUri = listJo.getString("picUri"); - String svrIndexCode = listJo.getString("svrIndexCode"); - WorkerInfo workerInfo = workerInfoMapper.selectById(personId); - if (workerInfo == null) { - log.error("未找到该人员信息,personName:{}", personName); + String plateNo = listJo.getString("plateNo"); + String roadwaySyscode = listJo.getString("roadwaySyscode"); + String aswSyscode = listJo.getString("aswSyscode"); + String crossTime = listJo.getString("crossTime"); + String time = DateUtil.formatDateTime(DateUtil.parse(crossTime)); + String plateNoPicUri = listJo.getString("plateNoPicUri"); + String vehiclePicUri = listJo.getString("vehiclePicUri"); + CarCamera carCamera = carCameraMapper.selectOne(new LambdaQueryWrapper() + .eq(CarCamera::getCameraId, roadwaySyscode)); + if (carCamera == null) { + log.info("海康车辆相机设备不存在:CameraId:{}", roadwaySyscode); continue; } - HashMap map = new HashMap<>(); - String time = DateUtil.formatDateTime(DateUtil.parse(eventTime)); - map.put("passTime", time); - map.put("idCard", workerInfo.getIdCard()); - map.put("attendanceNumber", workerInfo.getAttendanceNumber()); - int passType = workerAttendanceServiceImpl.getPassType(ufaceDev, time); - map.put("direction", passType); - map.put("passType", 2); - map.put("projectCode", workerInfo.getProjectSn()); - map.put("devCode", doorIndexCode); + CarPassRecord entity = new CarPassRecord(); + entity.setCarNumber(plateNo); + entity.setType(getPassType(carCamera.getPassType())); + entity.setPassTime(time); try { - HikvisionEventsPictureRq rq = new HikvisionEventsPictureRq(); - rq.setPicUri(picUri); - rq.setSvrIndexCode(svrIndexCode); - map.put("faceUrl", saveToLocal(getHikvisionEventsPicture(rq, project.getArtemisConfigHost(), project.getArtemisConfigAppKey(), project.getArtemisConfigAppSecret()))); + //车牌 + entity.setImageUrl(saveToLocal(getHikvisionEventsPicture(new HikvisionEventsPictureRq(aswSyscode, plateNoPicUri), project.getArtemisConfigHost(), project.getArtemisConfigAppKey(), project.getArtemisConfigAppSecret()))); + entity.setPanoramaUrl(saveToLocal(getHikvisionEventsPicture(new HikvisionEventsPictureRq(aswSyscode, vehiclePicUri), project.getArtemisConfigHost(), project.getArtemisConfigAppKey(), project.getArtemisConfigAppSecret()))); } catch (Exception e) { e.printStackTrace(); } - workerAttendanceService.saveExternalPassRecord(map); + entity.setCarColor(getCarColor(listJo.getInteger("plateColor"))); + entity.setLocation(carCamera.getCameraName()); + entity.setProjectSn(carCamera.getProjectSn()); + entity.setColor(getColor(listJo.getInteger("vehicleColor"))); + entity.setCameraId(roadwaySyscode); + List carInfos = carInfoMapper.selectList(new LambdaQueryWrapper() + .eq(CarInfo::getProjectSn, carCamera.getProjectSn()) + .eq(CarInfo::getCarNumber, plateNo) + .eq(CarInfo::getIsBlack, 0) + ); + if (CollUtil.isNotEmpty(carInfos)) { + entity.setIsOpen(1); + } else { + entity.setIsOpen(0); + } + Integer count = carPassRecordMapper.selectCount(new LambdaQueryWrapper() + .eq(CarPassRecord::getCarNumber, plateNo) + .eq(CarPassRecord::getPassTime, time) + ); + if (count == 0) { + carPassRecordMapper.insert(entity); + } } param.put("pageNo", param.getIntValue("pageNo") + 1); } } } while (total > 0); } - workerAttendancePresenceService.addNowAllWorkerAttendancePresence(projectSn); - } - log.info("服务挂了主动获取门禁点事件的人员通行记录执行完成,startTime:{},endTime:{}", startTime, endTime); - return Result.ok(); + log.info("服务挂了主动获取车辆事件的车辆通行记录执行完成,startTime:{},endTime:{}", startTime, endTime); + if (SecurityUtils.getUser().getUserId() != null) { + String title = "同步车辆通行数据成功"; + String msg = title + ",同步时间段:startTime:" + startTime + ",endTime:" + endTime; + noticeService.addUserNotice(SecurityUtils.getUser().getUserId(), msg, title, "2"); + } + }); + return Result.ok("已在后台同步车辆通行数据,请耐心等待!"); } /** @@ -1531,7 +1585,7 @@ public class HikvisionCall { } /** - * 获取项目名称的停车场的parkIndexCode + * 获取项目名称的停车场的parkIndexCode,没有一样名字的就取第一个停车场 * * @param project * @return @@ -1539,10 +1593,14 @@ public class HikvisionCall { public String getProjectParkCode(Project project) { JSONArray parkList = getParkList(project); if (parkList != null && parkList.size() > 0) { - JSONObject jo = parkList.getJSONObject(0); - if (Objects.equals(jo.getString("parkName"), project.getProjectName())) { - return jo.getString("parkIndexCode"); + for (int i = 0; i < parkList.size(); i++) { + JSONObject jo = parkList.getJSONObject(i); + if (Objects.equals(jo.getString("parkName"), project.getProjectName())) { + return jo.getString("parkIndexCode"); + } } + //没有一样名字的就取第一个停车场 + return parkList.getJSONObject(0).getString("parkIndexCode"); } return null; } @@ -1711,4 +1769,26 @@ public class HikvisionCall { return HikvisionUtil.doPost(host, path, jo.toJSONString(), null, project.getArtemisConfigAppKey(), project.getArtemisConfigAppSecret()); } + /** + * 查询过车记录 + * + * @param project + * @param param + */ + public String getCrossRecordsForHttp(Project project, JSONObject param) { + if (project == null || !Objects.equals(project.getSyncHikvision(), 1)) { + return null; + } + final String ARTEMIS_PATH = "/artemis"; + final String path = ARTEMIS_PATH + "/api/pms/v1/crossRecords/page"; + String host = "https://" + project.getArtemisConfigHost(); + JSONObject jo = new JSONObject(); + jo.put("pageNo", param.getIntValue("pageNo")); + jo.put("pageSize", 1000); + //ISO8601时间格式 + jo.put("startTime", param.getString("startTime")); + jo.put("endTime", param.getString("endTime")); + jo.put("parkSyscode", param.getString("parkSyscode")); + return HikvisionUtil.doPost(host, path, jo.toJSONString(), null, project.getArtemisConfigAppKey(), project.getArtemisConfigAppSecret()); + } } diff --git a/src/main/java/com/zhgd/xmgl/modules/safetyhat/service/impl/SafetyHatDataServiceImpl.java b/src/main/java/com/zhgd/xmgl/modules/safetyhat/service/impl/SafetyHatDataServiceImpl.java index 8551474f6..add6916a3 100644 --- a/src/main/java/com/zhgd/xmgl/modules/safetyhat/service/impl/SafetyHatDataServiceImpl.java +++ b/src/main/java/com/zhgd/xmgl/modules/safetyhat/service/impl/SafetyHatDataServiceImpl.java @@ -237,6 +237,7 @@ public class SafetyHatDataServiceImpl extends ServiceImpl().eq(TeamInfo::getTeamName, dto.getGroupName())); + List workerTypes = workerTypeMapper.selectList(new LambdaQueryWrapper().eq(WorkerType::getProjectSn, dto.getProjectCode()) + .eq(WorkerType::getTypeName, "其他工种")); + if (CollUtil.isNotEmpty(workerTypes)) { + teamInfo.setWorkerTypeId(workerTypes.get(0).getId()); + } if (teamInfo != null) { //修改 teamInfo.setTeamName(StringUtils.isNotBlank(dto.getNewGroupName()) ? dto.getNewGroupName() : dto.getGroupName());