liujie
2026-07-21 f453ee77ba5eb2704d5a8e967a130dc43b8ff799
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
package com.ruoyi.web.controller.service;
 
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.ContentType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.JsonNode;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.SysVisitorRecord;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
 
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
 
/**
 * 访客登记同步服务
 * 将本地访客登记数据同步到对端服务器
 */
@Slf4j
@Service
public class VisitorRegisterSyncService {
 
    @Value("${visitor.sync.url:}")
    private String syncUrl;
 
    @Value("${visitor.sync.enabled:false}")
    private Boolean syncEnabled;
 
    private final ObjectMapper objectMapper = new ObjectMapper();
 
    private static final DateTimeFormatter DATE_FORMATTER =
            DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
 
    /**
     * 同步访客登记信息到对端服务器
     *
     * @param record 本地访客登记记录
     * @return 同步结果
     */
    public AjaxResult syncVisitorRegister(SysVisitorRecord record) {
        // 检查同步开关
        if (!syncEnabled) {
            log.info("访客登记同步已关闭,跳过同步");
            return AjaxResult.success("同步功能未开启");
        }
 
        if (StringUtils.isBlank(syncUrl)) {
            log.warn("同步URL未配置,跳过同步");
            return AjaxResult.warn("同步URL未配置");
        }
 
        try {
            // 1. 构建同步请求参数
            Map<String, Object> requestBody = buildSyncRequest(record);
 
            String jsonBody = objectMapper.writeValueAsString(requestBody);
            log.info("同步访客登记数据:{}", jsonBody);
 
            // 2. 发送HTTP请求
            HttpResponse response = HttpRequest.post(syncUrl)
                    .header("Content-Type", ContentType.JSON.getValue())
                    .body(jsonBody)
                    .timeout(30000)
                    .execute();
 
            // 3. 解析响应
            String responseBody = response.body();
            log.info("同步响应:{}", responseBody);
 
            JsonNode jsonNode = objectMapper.readTree(responseBody);
            boolean success = jsonNode.has("success") && jsonNode.get("success").asBoolean();
 
            if (success) {
                String remoteId = jsonNode.has("data") && jsonNode.get("data").has("id")
                        ? jsonNode.get("data").get("id").asText() : null;
                log.info("访客登记同步成功,远程ID:{}", remoteId);
                return AjaxResult.success(remoteId);
            } else {
                String errorMsg = jsonNode.has("description")
                        ? jsonNode.get("description").asText() : "未知错误";
                log.error("访客登记同步失败:{}", errorMsg);
                return AjaxResult.error(errorMsg);
            }
        } catch (Exception e) {
            log.error("访客登记同步异常", e);
            return AjaxResult.error("同步异常:" + e.getMessage());
        }
    }
 
    /**
     * 构建同步请求参数
     */
    private Map<String, Object> buildSyncRequest(SysVisitorRecord record) {
        Map<String, Object> params = new HashMap<>();
 
        // 必填字段
        params.put("name", record.getVisitorName());
        params.put("certType", "111");
        params.put("certNo", record.getIdCard());
//        params.put("qrCode", generateQrCode(record));
        params.put("person", record.getIntervieweeName());
        params.put("reason", StringUtils.isNotBlank(record.getVisitReason())
                ? record.getVisitReason() : "来访");
        params.put("estimatedTimeStart", formatTime(record.getValidStartTime()));
        params.put("estimatedTimeEnd", formatTime(record.getValidEndTime()));
 
        if (record.getAreasList() != null && !record.getAreasList().isEmpty()) {
            params.put("areas", record.getAreasList());
        }
 
        // 可选字段
//        params.put("gender", convertGender(record.getGender()));
//        params.put("phone", record.getPhone());
        params.put("licensePlateNumber", record.getPlateNo());
//        params.put("visitorDept", record.getVisitorCompany());
        params.put("dept", record.getIntervieweeDept());
        params.put("areaName", record.getVisitAreaNames());
        params.put("registerGate", record.getRegisterSource());
        params.put("registerMachineCode", record.getDeviceId());
        params.put("status", "1"); // 1-已登记
 
        // 如果有证件照片或现场照片,可以传递
        // params.put("idPhoto", record.getIdCardPhoto());
         params.put("pic", record.getFaceImageUrl());
 
        return params;
    }
 
    /**
     * 转换证件类型:本地字典 → 对方字典值
     */
    private String convertCertType(String localCertType) {
        if (StringUtils.isBlank(localCertType)) {
            return "111"; // 默认身份证
        }
        // 根据实际情况映射
        switch (localCertType) {
            case "ID_CARD": return "111";      // 居民身份证
            case "PASSPORT": return "414";     // 护照
            case "DRIVER_LICENSE": return "335"; // 驾驶证
            case "HK_MACAU_PASS": return "337";  // 港澳通行证
            default: return "111";
        }
    }
 
    /**
     * 转换性别:本地字典 → 对方字典值
     */
    private String convertGender(String localGender) {
        if (StringUtils.isBlank(localGender)) {
            return null;
        }
        switch (localGender) {
            case "MALE": return "1";
            case "FEMALE": return "2";
            default: return null;
        }
    }
 
    /**
     * 格式化时间
     */
    private String formatTime(Date date) {
        if (date == null) {
            return null;
        }
        LocalDateTime localDateTime = date.toInstant()
                .atZone(ZoneId.systemDefault())
                .toLocalDateTime();
        return localDateTime.format(DATE_FORMATTER);
    }
 
    /**
     * 生成二维码内容
     * 格式:vms:visitor:{日期}:{登记编号}
     */
    private String generateQrCode(SysVisitorRecord record) {
        String dateStr = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
        String registerNo = record.getRegisterNo();
        return String.format("vms:visitor:%s:%s", dateStr, registerNo);
    }
}