From 323764c813a09cd56cdab780155ef659dbe0b364 Mon Sep 17 00:00:00 2001
From: liujie <1793218484@qq.com>
Date: 星期二, 11 八月 2026 15:08:03 +0800
Subject: [PATCH] update

---
 ruoyi-applet/src/main/java/com/ruoyi/web/controller/service/SysVisitorRecordService.java |   54 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 53 insertions(+), 1 deletions(-)

diff --git a/ruoyi-applet/src/main/java/com/ruoyi/web/controller/service/SysVisitorRecordService.java b/ruoyi-applet/src/main/java/com/ruoyi/web/controller/service/SysVisitorRecordService.java
index 030dd1d..78e2645 100644
--- a/ruoyi-applet/src/main/java/com/ruoyi/web/controller/service/SysVisitorRecordService.java
+++ b/ruoyi-applet/src/main/java/com/ruoyi/web/controller/service/SysVisitorRecordService.java
@@ -5,11 +5,14 @@
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.ruoyi.system.domain.SysVisitorRecord;
 import com.ruoyi.system.mapper.SysVisitorRecordMapper;
+import com.ruoyi.web.integration.dahua.DahuaVisitorAccessService;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
+import org.springframework.transaction.support.TransactionSynchronization;
+import org.springframework.transaction.support.TransactionSynchronizationManager;
 
 import java.util.Date;
 import java.util.List;
@@ -23,14 +26,27 @@
     @Autowired
     private RedisTemplate<String, String> redisTemplate;
 
+    @Autowired
+    private DahuaVisitorAccessService dahuaVisitorAccessService;
+
     private static final String REDIS_KEY_PREFIX = "visitor:expire:";
 
     /**
      * 登记访客时设置 Redis 过期 Key
      */
     public void registerVisitor(SysVisitorRecord record) {
+        if (record.getValidEndTime() == null) {
+            throw new IllegalArgumentException("访客有效期结束时间不能为空");
+        }
+        if (!record.getValidEndTime().after(new Date())) {
+            log.warn("访客记录 {} 登记时已超期,不下发门禁权限", record.getRecordId());
+            autoSignOut(record);
+            return;
+        }
 
-        // 2. 设置 Redis 过期 Key
+        // 下发门禁权限后设置过期监听,确保登记与到期撤权使用同一条业务链路。
+        DahuaVisitorAccessService.OperationResult accessResult = dahuaVisitorAccessService.grant(record);
+        registerGrantRollbackCompensation(record, accessResult);
         setRedisExpireKey(record);
 
         log.info("访客 {} 登记成功,有效期至:{}", record.getRecordId(), record.getValidEndTime());
@@ -42,6 +58,10 @@
     private void setRedisExpireKey(SysVisitorRecord record) {
         Date now = new Date();
         Date validEndTime = record.getValidEndTime();
+
+        if (validEndTime == null) {
+            throw new IllegalArgumentException("访客有效期结束时间不能为空");
+        }
 
         // 如果有效期结束时间小于当前时间,直接签离
         if (validEndTime.before(now)) {
@@ -110,11 +130,42 @@
      */
     private void autoSignOut(SysVisitorRecord record) {
         Date now = new Date();
+        revokeAccess(record);
         record.setStatus("PENDING_CONFIRM");
         record.setSignTime(now);
         record.setRemark("逾期滞留,等待确认");
         record.setUpdateTime(now);
         this.updateById(record);
+    }
+
+    /**
+     * 撤销访客在大华门禁设备上的人脸及人员权限。
+     */
+    public void revokeAccess(SysVisitorRecord record) {
+        dahuaVisitorAccessService.revoke(record);
+    }
+
+    private void registerGrantRollbackCompensation(SysVisitorRecord record,
+                                                   DahuaVisitorAccessService.OperationResult accessResult) {
+        if (accessResult.getSuccessCount() <= 0 || !TransactionSynchronizationManager.isSynchronizationActive()) {
+            return;
+        }
+        TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
+            @Override
+            public void afterCompletion(int status) {
+                if (status != TransactionSynchronization.STATUS_ROLLED_BACK) {
+                    return;
+                }
+                redisTemplate.delete(REDIS_KEY_PREFIX + record.getRecordId());
+                try {
+                    dahuaVisitorAccessService.revoke(record);
+                    log.info("访客登记事务回滚,大华门禁权限补偿撤销完成,recordId={}", record.getRecordId());
+                } catch (Exception e) {
+                    log.error("访客登记事务回滚,大华门禁权限补偿撤销失败,recordId={}",
+                            record.getRecordId(), e);
+                }
+            }
+        });
     }
 
     /**
@@ -164,6 +215,7 @@
         int count = 0;
         for (SysVisitorRecord record : overdueRecords) {
             try {
+                revokeAccess(record);
                 record.setStatus("OVERDUE_AUTO_SIGNED_OUT");
                 record.setSignTime(now);
                 record.setRemark("系统自动签离(启动时检查)");

--
Gitblit v1.7.1