ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/EmployeeVerifyController.java
@@ -62,12 +62,12 @@ * 刷卡验证:现场读卡器读取卡号后调用本接口,与接待人绑定的卡号比对。 */ @PostMapping("/allEmployee") @ApiOperation(value = "查询所有员工接口", notes = "必传设备ID") public AjaxResult getAllEmployee(@RequestBody @Valid ApiVisitorMachineRequest request) { SysVisitorMachine detail = visitorMachineMapper.checkDeviceIdUnique(request.getMachineId(),null); if (detail == null || !detail.getEnabled()) { throw new ServiceException("未找到有效设备"); } @ApiOperation(value = "查询所有员工接口") public AjaxResult getAllEmployee() { // SysVisitorMachine detail = visitorMachineMapper.checkDeviceIdUnique(request.getMachineId(),null); // if (detail == null || !detail.getEnabled()) { // throw new ServiceException("未找到有效设备"); // } List<Employee> employees = employeeMapper.selectAllEnabled(); if (employees == null || employees.isEmpty()) { ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/SysApiDoorMachineController.java
@@ -4,6 +4,8 @@ import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.enums.BusinessType; import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.system.dto.*; import com.ruoyi.system.service.ISysVisitorMachineService; import io.swagger.annotations.Api; @@ -36,7 +38,11 @@ @PostMapping("/activate") @ApiOperation(value = "激活访客机设备") public AjaxResult activate(@Valid @RequestBody ApiVisitorMachineRequest request) { int result = visitorMachineService.activateDevice(request.getMachineId()); if (StringUtils.isEmpty(request.getFingerprint())) { throw new ServiceException("缺少参数"); } int result = visitorMachineService.activateDevice(request.getMachineId(), request.getFingerprint()); return result > 0 ? success("设备激活成功") : error("设备激活失败"); } ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/SysApiVisitorRecordController.java
@@ -1,6 +1,8 @@ package com.ruoyi.web.controller.api; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.domain.AjaxResult; @@ -12,6 +14,7 @@ import com.ruoyi.system.domain.Employee; import com.ruoyi.system.domain.SysVisitArea; import com.ruoyi.system.domain.SysVisitorRecord; import com.ruoyi.system.domain.vo.AreasList; import com.ruoyi.system.dto.SysVisitorIdCardOutRequest; import com.ruoyi.system.dto.SysVisitorRecordAddRequest; import com.ruoyi.system.mapper.EmployeeMapper; @@ -20,6 +23,7 @@ import com.ruoyi.system.mapper.SysVisitorRecordMapper; import com.ruoyi.system.service.ISysVisitAreaService; import com.ruoyi.web.controller.service.SysVisitorRecordService; import com.ruoyi.web.controller.service.VisitorRegisterSyncService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; @@ -29,16 +33,15 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.Arrays; import java.util.Calendar; import java.util.Date; import java.util.Objects; import java.util.*; import java.util.stream.Collectors; @RestController @RequestMapping("/api/visitorRecord") @Api(tags = "现场访客登记-签离") public class SysApiVisitorRecordController extends BaseController { @Autowired private VisitorRegisterSyncService visitorRegisterSyncService; @Autowired private SysVisitorRecordService sysVisitorRecordService; @Autowired @@ -113,6 +116,27 @@ .filter(Objects::nonNull) .collect(Collectors.joining(",")); // ====== 新增:构建 areas 数组 ====== List<AreasList> areasList = Arrays.stream(visitAreaIds) .map(String::trim) .filter(StringUtils::isNotEmpty) .map(id -> { SysVisitArea area = sysVisitAreaMapper.selectById(Long.parseLong(id)); if (area == null) { return null; } AreasList areas = new AreasList(); areas.setAreaCode(area.getAreaCode()); areas.setAreaName(area.getAreaName()); return areas; }) .filter(Objects::nonNull) .collect(Collectors.toList()); if (!areasList.isEmpty()) { record.setAreasList(areasList); } // 使用 visitArea if (StringUtils.isNotEmpty(visitArea)) { record.setVisitAreaNames(visitArea); @@ -132,19 +156,44 @@ } record.setRegisterNo(generateRegisterNo());//登记编号 record.setRegisterType("ONSITE");//现场登记 // record.setRegisterType("ONSITE");//现场登记 record.setRegisterSource("访客机"); record.setStatus("VISITING");//来访中 record.setRegisterTime(new Date()); record.setCreateTime(new Date()); record.setDelFlag("0"); // ================= 同步到对端服务器 ================= try { AjaxResult syncResult = visitorRegisterSyncService.syncVisitorRegister(record); if (syncResult.isSuccess()) { logger.info("访客登记数据已同步到对端,远程ID:{}", syncResult.get("data")); // 可将远程ID保存到本地记录 // record.setRemoteId(syncResult.getRemoteId()); UpdateWrapper<SysVisitorRecord> wrapper = new UpdateWrapper<>(); wrapper.eq("record_id", record.getRecordId()); // 指定ID条件 visitorRecordMapper.update(record, wrapper); } else { String msg = (String) syncResult.get("msg"); logger.error("访客登记同步失败:{}", msg); // 可选择是否允许本地登记成功但同步失败 // 如果要保证数据一致性,这里可以抛出异常回滚事务 throw new ServiceException(msg); } } catch (Exception e) { logger.error("访客登记同步异常", e); throw new ServiceException("服务器登记失败"); } int rows = visitorRecordMapper.insert(record); sysVisitorRecordService.registerVisitor(record); if (rows > 0) { return AjaxResult.success(record); } return AjaxResult.error("登记失败"); } @@ -195,7 +244,10 @@ visitorRecord.setStatus(record.getStatus()); visitorRecord.setRecordId(record.getRecordId()); visitorRecord.setSignTime(new Date()); visitorRecordMapper.updateById(visitorRecord); UpdateWrapper<SysVisitorRecord> wrapperUpdate = new UpdateWrapper<>(); wrapperUpdate.eq("record_id", visitorRecord.getRecordId()); // 指定ID条件 visitorRecordMapper.update(visitorRecord, wrapperUpdate); return success(); } ruoyi-applet/src/main/java/com/ruoyi/web/controller/service/ApiPullSignOutDataService.java
@@ -63,7 +63,7 @@ // 1. 参数校验 if (!StringUtils.hasText(request.getIdCard())) { log.warn("身份证号为空,已跳过,设备编号: {}", request.getDeviceNo()); log.warn("身份证号为空,已跳过,人员姓名: {}", request.getIntervieweeName()); errorCount++; continue; } @@ -73,12 +73,12 @@ request.setSignImageUrl(url); } // 2. 防重校验(基于设备编号+身份证号+签离时间) // 2. 防重校验(身份证号+签离时间) String uniqueKey = generateUniqueKey(request); String redisKey = "offline:signout:" + uniqueKey; if (Boolean.TRUE.equals(redisTemplate.hasKey(redisKey))) { log.warn("签离数据重复,已跳过, 设备编号: {}, 身份证号: {}, 签离时间: {}", request.getDeviceNo(), request.getIdCard(), request.getSignTime()); log.warn("签离数据重复,已跳过, 身份证号: {}, 签离时间: {}", request.getIdCard(), request.getSignTime()); skipCount++; continue; } @@ -94,8 +94,8 @@ } } catch (Exception e) { log.error("处理签离数据失败, 身份证号: {}, 设备编号: {}", request.getIdCard(), request.getDeviceNo(), e); log.error("处理签离数据失败, 身份证号: {}", request.getIdCard(), e); errorCount++; } } @@ -362,7 +362,7 @@ */ private String generateUniqueKey(ApiVisitorRecodeSingoutRequest request) { StringBuilder sb = new StringBuilder(); sb.append(request.getDeviceNo()).append(":"); // sb.append(request.getDeviceNo()).append(":"); sb.append(request.getIdCard()).append(":"); sb.append(request.getSignTime() != null ? request.getSignTime().getTime() : System.currentTimeMillis()); ruoyi-applet/src/main/java/com/ruoyi/web/controller/service/ApiPullSingInDataService.java
@@ -59,7 +59,7 @@ // 1. 参数校验 if (!StringUtils.hasText(request.getIdCard())) { log.warn("身份证号为空,已跳过,设备编号: {}", request.getDeviceNo()); log.warn("身份证号为空,已跳过,访问人姓名: {}", request.getVisitorName()); errorCount++; continue; } @@ -73,8 +73,8 @@ String uniqueKey = generateUniqueKey(request); String redisKey = "offline:signin:" + uniqueKey; if (Boolean.TRUE.equals(redisTemplate.hasKey(redisKey))) { log.warn("签到数据重复,已跳过, 设备编号: {}, 身份证号: {}, 登记时间: {}", request.getDeviceNo(), request.getIdCard(), request.getRegisterTime()); log.warn("签到数据重复,已跳过, 身份证号: {}, 登记时间: {}", request.getIdCard(), request.getRegisterTime()); skipCount++; continue; } @@ -135,7 +135,7 @@ BeanUtils.copyProperties(request, record); record.setRegisterTime(registerTime); record.setRegisterSource("访客机"); record.setRegisterType("ONSITE"); // record.setRegisterType("ONSITE"); record.setCreateTime(new Date()); record.setDelFlag("0"); record.setRegisterNo(generateRegisterNo()); @@ -148,8 +148,6 @@ // 4. 如果有未关联的签离数据,直接关联 if (signoutTemp != null) { // 设置签离信息 record.setSignTime(signoutTemp.getSignTime()); record.setSignReceiverName(signoutTemp.getSignReceiverName()); @@ -321,7 +319,7 @@ */ private String generateUniqueKey(ApiVisitorRecordSinginRequest request) { StringBuilder sb = new StringBuilder(); sb.append(request.getDeviceNo()).append(":"); // sb.append(request.getDeviceNo()).append(":"); sb.append(request.getIdCard()).append(":"); sb.append(request.getRegisterTime() != null ? request.getRegisterTime().getTime() : System.currentTimeMillis()); ruoyi-applet/src/main/java/com/ruoyi/web/controller/service/VisitorRegisterSyncService.java
New file @@ -0,0 +1,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); } } ruoyi-common/src/main/java/com/ruoyi/common/core/domain/BaseEntity.java
@@ -44,16 +44,16 @@ private String remark; @ApiModelProperty(value = "禁用备注") @TableField("disable_remark") @TableField(value = "disable_remark" ,exist = false) private String disableRemark; @ApiModelProperty(value = "操作时间") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") @TableField("operating_time") @TableField(value = "operating_time" ,exist = false) private LocalDateTime operatingTime; @ApiModelProperty(value = "操作人 登录名(登录账号)") @TableField("operating_person") @TableField(value = "operating_person",exist = false) private String operatingPerson; public String getDisableRemark() { @@ -82,6 +82,7 @@ /** 请求参数 */ @JsonInclude(JsonInclude.Include.NON_EMPTY) @TableField(exist = false) private Map<String, Object> params; public String getSearchValue() ruoyi-system/src/main/java/com/ruoyi/system/domain/SysVisitArea.java
@@ -1,5 +1,6 @@ package com.ruoyi.system.domain; import com.baomidou.mybatisplus.annotation.TableName; import com.ruoyi.common.core.domain.BaseEntity; import lombok.Data; import lombok.EqualsAndHashCode; @@ -11,6 +12,7 @@ */ @Data @EqualsAndHashCode(callSuper = true) @TableName("t_visit_area") public class SysVisitArea extends BaseEntity { private static final long serialVersionUID = 1L; ruoyi-system/src/main/java/com/ruoyi/system/domain/SysVisitorMachine.java
@@ -38,4 +38,7 @@ /** 删除标识,0正常 1删除 */ private String delFlag; /** 百度SDK指纹 */ private String fingerprint; } ruoyi-system/src/main/java/com/ruoyi/system/domain/SysVisitorRecord.java
@@ -1,10 +1,14 @@ package com.ruoyi.system.domain; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableName; import com.ruoyi.common.core.domain.BaseEntity; import com.ruoyi.system.domain.vo.AreasList; import lombok.Data; import lombok.EqualsAndHashCode; import java.util.Date; import java.util.List; /** * 访客登记记录 t_visitor_record @@ -13,6 +17,7 @@ */ @Data @EqualsAndHashCode(callSuper = true) @TableName("t_visitor_record") public class SysVisitorRecord extends BaseEntity { private static final long serialVersionUID = 1L; @@ -88,4 +93,9 @@ /** 删除标识:0正常 1删除 */ private String delFlag; @TableField(exist = false) private List<AreasList> areasList; @TableField(exist = false) private String deviceId; } ruoyi-system/src/main/java/com/ruoyi/system/domain/api/ApiSysVisitorRecord.java
New file @@ -0,0 +1,102 @@ package com.ruoyi.system.domain.api; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableName; import com.ruoyi.common.core.domain.BaseEntity; import com.ruoyi.system.domain.vo.AreasList; import lombok.Data; import lombok.EqualsAndHashCode; import java.util.Date; import java.util.List; /** * 访客登记记录 t_visitor_record * * @author ruoyi */ @Data @TableName("t_visitor_record") public class ApiSysVisitorRecord { private static final long serialVersionUID = 1L; /** 访客登记记录主键 */ private Long recordId; /** 登记编号 */ private String registerNo; /** 访客姓名 */ private String visitorName; /** 访客身份证号 */ private String idCard; /** 登记类型:APPOINTMENT预约登记 ONSITE现场登记 */ private String registerType; /** 被访人 */ private String intervieweeName; /** 被访人部门 */ private String intervieweeDept; /** 登记接待人 */ private String receiverName; /** 接待人验证方式 */ private String receiverVerifyMethod; /** 访问区域ID,英文逗号分隔 */ private String visitAreaIds; /** 访问区域名称,英文逗号分隔 */ private String visitAreaNames; /** 车牌号 */ private String plateNo; /** 来访事由 */ private String visitReason; /** 有效期开始时间 */ private Date validStartTime; /** 有效期结束时间 */ private Date validEndTime; /** 登记状态 */ private String status; /** 登记时间 */ private Date registerTime; /** 登记来源 */ private String registerSource; /** 访客人像地址 */ private String faceImageUrl; /** 签离时间 */ private Date signTime; /** 签离接待人 */ private String signReceiverName; /** 签离验证方式 */ private String signVerifyMethod; /** 签离人像地址 */ private String signImageUrl; /** 删除标识:0正常 1删除 */ private String delFlag; @TableField(exist = false) private List<AreasList> areasList; @TableField(exist = false) private String deviceId; private String remark; private Date createTime; } ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/AreasList.java
New file @@ -0,0 +1,9 @@ package com.ruoyi.system.domain.vo; import lombok.Data; @Data public class AreasList { private String areaCode; private String areaName; } ruoyi-system/src/main/java/com/ruoyi/system/dto/ApiVisitorMachineRequest.java
@@ -17,4 +17,7 @@ @ApiModelProperty("设备ID") @NotNull(message = "未找到该设备") private String machineId; @ApiModelProperty("百度指纹") private String fingerprint; } ruoyi-system/src/main/java/com/ruoyi/system/dto/ApiVisitorRecodeSingoutRequest.java
@@ -16,8 +16,8 @@ @ApiModel(value = "ApiVisitorRecodeSingoutRequest", description = "离线上传的访客身份证签离") public class ApiVisitorRecodeSingoutRequest { @NotBlank(message = "设备编号不能为空") @ApiModelProperty(value = "设备编号") // @NotBlank(message = "设备编号不能为空") @ApiModelProperty(value = "设备编号,非必填") private String deviceNo; /** @@ -44,6 +44,10 @@ @ApiModelProperty(value = "签离时间") private Date signTime; // @NotBlank(message = "登记类型不能为空") // @ApiModelProperty(value = "登记类型:APPOINTMENT预约登记 ONSITE现场登记") // private String registerType; /** 签离接待人 */ @ApiModelProperty(value = "签离接待人") private String signReceiverName; ruoyi-system/src/main/java/com/ruoyi/system/dto/ApiVisitorRecordSinginRequest.java
@@ -17,8 +17,8 @@ @ApiModel(value = "ApiVisitorRecordSinginRequest", description = "离线模式签到数据") public class ApiVisitorRecordSinginRequest { @NotBlank(message = "设备编号不能为空") @ApiModelProperty(value = "设备编号") // @NotBlank(message = "设备编号不能为空") @ApiModelProperty(value = "设备编号,非必填") private String deviceNo; /** @@ -48,6 +48,10 @@ @ApiModelProperty(value = "接待人验证方式") private String receiverVerifyMethod; @NotBlank(message = "登记类型不能为空") @ApiModelProperty(value = "登记类型:APPOINTMENT预约登记 ONSITE现场登记") private String registerType; /** * 访问区域ID,英文逗号分隔 */ ruoyi-system/src/main/java/com/ruoyi/system/dto/SysVisitorRecordAddRequest.java
@@ -20,12 +20,22 @@ public class SysVisitorRecordAddRequest { /** * 设备编号 */ @ApiModelProperty(value = "设备编号,非必传") private String deviceId; /** * 访客姓名 */ @NotBlank(message = "访客姓名不能为空") @ApiModelProperty(value = "访客姓名") private String visitorName; @NotBlank(message = "登记类型不能为空") @ApiModelProperty(value = "登记类型:APPOINTMENT预约登记 ONSITE现场登记") private String registerType; /** * 访客身份证号 */ ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysVisitorRecordMapper.java
@@ -21,6 +21,10 @@ @Mapper public interface SysVisitorRecordMapper extends BaseMapper<SysVisitorRecord> { // 显式覆盖 updateById 方法 @Override int updateById(@Param("et") SysVisitorRecord entity); public List<SysVisitorRecordVO> pageList(@Param("query") SysVisitorRecordPageRequest query, @Param("pageInfo") PageInfo<SysVisitorRecordVO> pageInfo); ruoyi-system/src/main/java/com/ruoyi/system/mapper/api/SysApiVisitorRecordMapper.java
New file @@ -0,0 +1,27 @@ package com.ruoyi.system.mapper.api; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.ruoyi.common.basic.PageInfo; import com.ruoyi.system.domain.SysVisitorRecord; import com.ruoyi.system.domain.api.ApiSysVisitorRecord; import com.ruoyi.system.dto.SysVisitorRecordPageRequest; import com.ruoyi.system.vo.SysVisitorPassRecordVO; import com.ruoyi.system.vo.SysVisitorRecordDetailVO; import com.ruoyi.system.vo.SysVisitorRecordVO; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import org.springframework.stereotype.Repository; import java.util.Date; import java.util.List; /** * 访客登记记录数据层 * * @author ruoyi */ @Repository public interface SysApiVisitorRecordMapper extends BaseMapper<ApiSysVisitorRecord> { } ruoyi-system/src/main/java/com/ruoyi/system/service/ISysVisitorMachineService.java
@@ -37,7 +37,7 @@ * @param deviceId 设备ID * @return 影响行数 */ int activateDevice(String deviceId); int activateDevice(String deviceId, String fingerprint); /** * 注销设备 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysVisitorMachineServiceImpl.java
@@ -153,7 +153,7 @@ @Override @Transactional(rollbackFor = Exception.class) public int activateDevice(String deviceId) { public int activateDevice(String deviceId, String fingerprint) { // 1. 根据deviceId查询设备 SysVisitorMachine device = visitorMachineMapper.checkDeviceIdUnique(deviceId, null); if (device == null || device.getDelFlag().equals("1")) { @@ -175,6 +175,7 @@ update.setMachineId(device.getMachineId()); update.setOnlineStatus("ONLINE"); // 或 "ACTIVATED",根据你的枚举定义 update.setUpdateTime(new Date()); update.setFingerprint(fingerprint); return visitorMachineMapper.updateMachine(update); } ruoyi-system/src/main/resources/mapper/system/EmployeeMapper.xml
@@ -22,7 +22,7 @@ <!-- 人脸图片不参与本接口逻辑,且 longtext 体积较大,列表中排除,减少不必要的数据传输 --> <sql id="Base_Column_List"> employee_id, dept_id, employee_name, employee_no, contact_phone_cipher, employee_id, dept_id, employee_name, face_image, employee_no, contact_phone_cipher, contact_phone_hash, `position`, card_no, enabled, del_flag, create_by, create_time, update_by, update_time </sql> @@ -50,7 +50,7 @@ SELECT <include refid="Base_Column_List"/> FROM t_employee AND enabled = 1 where enabled = 1 AND del_flag = '0' </select>