Jelajahi Sumber

海康服务:调整,缓存都以mac地址为唯一标识

xiari 9 bulan lalu
induk
melakukan
ba0d8d32de

+ 2 - 1
ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/CacheNames.java

@@ -203,7 +203,8 @@ public interface CacheNames {
     String XF_ORIGINAL_ID = "xf_original_id";
     String XF_DETAIL_ID = "xf_detail_id";
 
-    String XF_TERM_IP = "term_ip:";
+    // 记录最后一次下发给设备的时间
+    String XF_MAC_DOWN_SEND_TIME = "mac_down_send_time:";
 
     String USER_HAS_CARD = "user_has_card";
 

+ 1 - 1
ruoyi-server/ruoyi-server-hik/src/main/java/org/dromara/server/hik/event/handler/ConsumptionEventHandler.java

@@ -108,7 +108,7 @@ public class ConsumptionEventHandler implements HikEventHandler {
             remoteBo.setRecordStatus(364L);
             remoteBo.setRecordId(0L);
             remoteBo.setTermNo(termVo.getTermNo());
-            log.info("transactionConfirmingRequest 调用消费服务的消费入库接口,入参:{}", JSONUtil.toJsonStr(remoteBo));
+            log.info("transactionConfirmingRequest 调用调用消费请求与入库接口,入参:{}", JSONUtil.toJsonStr(remoteBo));
             //RemoteResultDto result = remoteConsumeService.dealHikUploadRecord(remoteBo);
             RemoteResultDto result = remoteConsumeService.dealHikFullRecord(remoteBo);
 //            log.info("消费机消费请求确认事件,结果:{}", JSONObject.toJSONString(result.getUpdatedRemoteBo()));

+ 8 - 5
ruoyi-server/ruoyi-server-hik/src/main/java/org/dromara/server/hik/event/handler/HeatBeatHandler.java

@@ -49,13 +49,14 @@ public class HeatBeatHandler implements HikEventHandler {
         }
 
         //不更新设备的IP地址 固定,不能变更
-        String ipAddress = termVo.getTermIp();
+//        String ipAddress = termVo.getTermIp();
 
         // 维护一个心跳列表的缓存
-        RedisUtils.setCacheMapValue(CacheNames.LAST_TIME_HEARTBEAT_LIST ,termVo.getTermNo().toString(), System.currentTimeMillis());
+        RedisUtils.setCacheMapValue(CacheNames.LAST_TIME_HEARTBEAT_LIST ,macAddress, System.currentTimeMillis());
 
         //增量下发 用户数据、人脸数据和卡数据
-        Long cacheObject = RedisUtils.getCacheObject(CacheNames.XF_TERM_IP + ipAddress);
+        String newMacAddress = macAddress.replaceAll(":","-");
+        Long cacheObject = RedisUtils.getCacheObject(CacheNames.XF_MAC_DOWN_SEND_TIME + newMacAddress);
         if(cacheObject == null){
             // 第一次上线 默认只下发最近1天的 新增或修改的数据
             //记录每天第一次上来的心跳数据时 新增或修改的数据
@@ -71,7 +72,8 @@ public class HeatBeatHandler implements HikEventHandler {
             Date date = Date.from(minus.atZone(ZoneId.systemDefault()).toInstant());
             sendDeviceService.upLoadEmpToDevice(macAddress,date,true);
 
-            RedisUtils.setCacheObject(CacheNames.XF_TERM_IP + ipAddress, date.getTime());
+            RedisUtils.setCacheObject(CacheNames.XF_MAC_DOWN_SEND_TIME + newMacAddress, date.getTime());
+            log.info("heartbeat 第一次上线 默认下发最近1天的:mac: {}, termNO:{}", macAddress, termVo.getTermNo());
         }else{
             // 当前时间-上次下发时间 >= 1天 就下发
             Date now = new Date();
@@ -86,7 +88,8 @@ public class HeatBeatHandler implements HikEventHandler {
             if (daysBetween >= 1) {
                 // 相差一天以上,执行下发逻辑
                 sendDeviceService.upLoadEmpToDevice(macAddress, last, true);
-                RedisUtils.setCacheObject(CacheNames.XF_TERM_IP + ipAddress, now.getTime());
+                RedisUtils.setCacheObject(CacheNames.XF_MAC_DOWN_SEND_TIME + newMacAddress, now.getTime());
+                log.info("heartbeat 增量下发数据(离线方式):mac: {}, termNO:{}", macAddress, termVo.getTermNo());
             }
         }
 

+ 20 - 14
ruoyi-server/ruoyi-server-hik/src/main/java/org/dromara/server/hik/event/handler/TransactionRecordEventHandler.java

@@ -43,7 +43,7 @@ public class TransactionRecordEventHandler implements HikEventHandler {
 
     private final IXfConsumeDetailService  consumeDetailService;
 
-    private final IConsumeDetailOriginalService consumeDetailOriginalService;
+//    private final IConsumeDetailOriginalService consumeDetailOriginalService;
 
     private final IXfFailedRecordService failedRecordService;
 
@@ -101,13 +101,14 @@ public class TransactionRecordEventHandler implements HikEventHandler {
             }else{
                 // 在线交易,调用消费记录入库的接口
                 // 根据机号和交易记录流水号查询消费记录
-                // 睡眠一秒,等待消费记录入库成功
-                Thread.sleep(1000);
-                List<XfConsumeDetailVo> vos = consumeDetailService.queryByTermNoAndRecordId(termNo, transactionRecordEvent.getSerialNo().longValue());
+                // 睡眠2秒,等待消费记录入库成功
+                Thread.sleep(2000);
+                List<XfConsumeDetailVo> vos = consumeDetailService.queryByTermNoAndRecordId(termNo,
+                    transactionRecordEvent.getSerialNo().longValue(),remoteBo.getConsumeDate(), remoteBo.getConsumeMoney());
                 if (CollectionUtils.isEmpty(vos)){
                     // 组装参数,调用消费记录入库的接口 // 如果失败要记录入库
-                    log.info("TransactionRecordEvent调用消费入库接口,入参,{}", JSONUtil.toJsonStr(remoteBo));
-                    RemoteResultDto remoteResultDto = remoteConsumeService.dealHikUploadRecord(remoteBo);
+                    log.info("TransactionRecordEvent调用消费请求与入库接口,入参,{}", JSONUtil.toJsonStr(remoteBo));
+                    RemoteResultDto remoteResultDto = remoteConsumeService.dealHikFullRecord(remoteBo);
                     errorInfo = remoteResultDto.getErrorInfo();
                     RemoteConsumeBo updatedRemoteBo = remoteResultDto.getUpdatedRemoteBo();
                     if(updatedRemoteBo !=null) {
@@ -208,6 +209,19 @@ public class TransactionRecordEventHandler implements HikEventHandler {
         if (!error) {
             return;
         }
+        String msg = errorInfo.getMsg();
+        ErrorInfo data = errorInfo.getData();
+        if(data != null){
+            msg = data.getMessage();
+        }
+        if(StringUtils.isNotBlank(msg) && msg.length() >= 2000){
+            msg = msg.substring(0, 2000);
+        }
+        // 消费记录已上传 原始消费记录存在   已处理过的请求不在继续处理,不入库
+        if("消费记录已上传".equals(msg)|| "原始消费记录存在".equals(msg)){
+            return;
+        }
+
         XfFailedRecordBo bo = new XfFailedRecordBo();
         TransactionRecordEventDetail recordEvent = info.getTransactionRecordEvent();
         String consumeMoney;
@@ -232,14 +246,6 @@ public class TransactionRecordEventHandler implements HikEventHandler {
         }
         bo.setStatus("f");
         bo.setFactoryId(recordEvent.getCardNo());
-        String msg = errorInfo.getMsg();
-        ErrorInfo data = errorInfo.getData();
-        if(data != null){
-            msg = data.getMessage();
-        }
-        if(StringUtils.isNotBlank(msg) && msg.length() >= 2000){
-            msg = msg.substring(0, 2000);
-        }
         bo.setFailMsg(msg);
         bo.setConsumeType(modeType);
 

+ 15 - 2
ruoyi-server/ruoyi-server-hik/src/main/java/org/dromara/server/hik/event/timedtask/HandleTask.java

@@ -95,10 +95,11 @@ public class HandleTask {
                 }else{
                     //  在线交易,调用消费记录入库的接口
                     // 在查询一次 消费记录,如果有则不再执行
-                    List<XfConsumeDetailVo> list = consumeDetailService.queryByTermNoAndRecordId(Long.valueOf(vo.getTermNo()), Long.valueOf(vo.getTermRecordId()));
+                    List<XfConsumeDetailVo> list = consumeDetailService.queryByTermNoAndRecordId(Long.valueOf(vo.getTermNo()),
+                        Long.valueOf(vo.getTermRecordId()),remoteBo.getConsumeDate(), remoteBo.getConsumeMoney());
                     if(CollectionUtils.isEmpty(list)){
                         log.info("定时任务,调用消费入库接口,消费机交易记录事件,入参,{}", JSONUtil.toJsonStr(remoteBo));
-                        rs = remoteConsumeService.dealHikUploadRecord(remoteBo);
+                        rs = remoteConsumeService.dealHikFullRecord(remoteBo);
                     }else{
                         log.info("消费机事件,已经存在消费记录,不再处理:{}", JSONUtil.toJsonStr(vo));
                         rs = new RemoteResultDto(R.ok(),null);
@@ -109,6 +110,18 @@ public class HandleTask {
                 if (!R.isError(errorInfo)) {
                     result = true;
                 }
+                String msg = errorInfo.getMsg();
+                ErrorInfo data = errorInfo.getData();
+                if(data != null){
+                    msg = data.getMessage();
+                }
+                if(org.dromara.common.core.utils.StringUtils.isNotBlank(msg) && msg.length() >= 2000){
+                    msg = msg.substring(0, 2000);
+                }
+                // 消费记录已上传 原始消费记录存在   已处理过的请求不在继续处理,不入库
+                if("消费记录已上传".equals(msg)|| "原始消费记录存在".equals(msg)){
+                    result = true;
+                }
 
             }catch (Exception e){
                 e.printStackTrace();

+ 3 - 1
ruoyi-server/ruoyi-server-hik/src/main/java/org/dromara/server/hik/service/IXfConsumeDetailService.java

@@ -4,6 +4,8 @@ package org.dromara.server.hik.service;
 import org.dromara.server.hik.domain.vo.XfConsumeDetailOriginalVo;
 import org.dromara.server.hik.domain.vo.XfConsumeDetailVo;
 
+import java.math.BigDecimal;
+import java.util.Date;
 import java.util.List;
 
 /**
@@ -32,5 +34,5 @@ public interface IXfConsumeDetailService {
      * @param termRecordId 机器流水号
      * @return
      */
-    List<XfConsumeDetailVo> queryByTermNoAndRecordId(Long termNo, Long termRecordId);
+    List<XfConsumeDetailVo> queryByTermNoAndRecordId(Long termNo, Long termRecordId, Date consumeDate, BigDecimal consumeMoney);
 }

+ 11 - 7
ruoyi-server/ruoyi-server-hik/src/main/java/org/dromara/server/hik/service/impl/SendDeviceServiceImpl.java

@@ -1162,16 +1162,16 @@ public class SendDeviceServiceImpl implements ISendDeviceService {
         if (byTermNo == null) {
             throw new ServiceException("设备不存在" + termNo);
         }
-        String ipAddress = byTermNo.getTermIp();
         String termMac = byTermNo.getTermMac();
-        Long cacheObject = RedisUtils.getCacheObject(CacheNames.XF_TERM_IP + ipAddress);
+        String newTermMac = termMac.replaceAll(":", "-");
+        Long cacheObject = RedisUtils.getCacheObject(CacheNames.XF_MAC_DOWN_SEND_TIME + newTermMac);
         if (cacheObject == null) {
             // 第一次上线,下发最近一天的
             throw new ServiceException("设备从未上传过心跳,请等上传过心跳后执行:" + termNo);
         }
         Date last = new Date(cacheObject);
         upLoadEmpToDevice(termMac, last, true);
-        RedisUtils.setCacheObject(CacheNames.XF_TERM_IP + ipAddress, System.currentTimeMillis());
+        RedisUtils.setCacheObject(CacheNames.XF_MAC_DOWN_SEND_TIME + newTermMac, System.currentTimeMillis());
     }
 
     /**
@@ -1185,13 +1185,17 @@ public class SendDeviceServiceImpl implements ISendDeviceService {
 
         cacheMap.forEach((k, v) -> {
             if (v instanceof Long t) {
-                long l = System.currentTimeMillis() - t;
-                // 正常在线的心跳时间间隔是30秒,但怕有网络延迟,这里设置60秒内都算在线
-                if (l <= 60 * 1000) {
-                    rs.add(Long.valueOf(k));
+                XfTermVo termVo = xfTermService.getByMac(k);
+                if(termVo != null){
+                    long l = System.currentTimeMillis() - t;
+                    // 正常在线的心跳时间间隔是30秒,但怕有网络延迟,这里设置60秒内都算在线
+                    if (l <= 60 * 1000) {
+                        rs.add(termVo.getTermNo());
+                    }
                 }
             }
         });
+        log.info("在线设备列表:{}", JSONUtil.toJsonStr(rs));
         return rs;
     }
 }

+ 4 - 1
ruoyi-server/ruoyi-server-hik/src/main/java/org/dromara/server/hik/service/impl/XfConsumeDetailServiceImpl.java

@@ -15,6 +15,8 @@ import org.dromara.server.hik.mapper.XfConsumeDetailMapper;
 import org.dromara.server.hik.service.IXfConsumeDetailService;
 import org.springframework.stereotype.Service;
 
+import java.math.BigDecimal;
+import java.util.Date;
 import java.util.List;
 import java.util.Map;
 
@@ -62,9 +64,10 @@ public class XfConsumeDetailServiceImpl implements IXfConsumeDetailService {
      * @return
      */
     @Override
-    public List<XfConsumeDetailVo> queryByTermNoAndRecordId(Long termNo, Long termRecordId) {
+    public List<XfConsumeDetailVo> queryByTermNoAndRecordId(Long termNo, Long termRecordId, Date consumeDate, BigDecimal consumeMoney) {
         LambdaQueryWrapper<XfConsumeDetail> eq = Wrappers.lambdaQuery(XfConsumeDetail.class)
             .eq(XfConsumeDetail::getTermNo, termNo).eq(XfConsumeDetail::getTermRecordId, termRecordId)
+            .eq(XfConsumeDetail::getConsumeDate, consumeDate).eq(XfConsumeDetail::getConsumeMoney, consumeMoney)
             .orderByDesc(XfConsumeDetail::getCreateTime);
         return this.baseMapper.selectVoList(eq);
     }