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 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 buildSyncRequest(SysVisitorRecord record) { Map 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); } }