package com.ruoyi.system.service.impl; import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.system.domain.Employee; import com.ruoyi.system.dto.CardVerifyRequest; import com.ruoyi.system.enums.VerifyResultEnum; import com.ruoyi.system.mapper.EmployeeMapper; import com.ruoyi.system.service.EmployeeVerifyService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; import javax.annotation.Resource; @Service public class EmployeeVerifyServiceImpl implements EmployeeVerifyService { private static final Logger log = LoggerFactory.getLogger(EmployeeVerifyServiceImpl.class); @Resource private EmployeeMapper employeeMapper; @Override public AjaxResult verifyByCard(CardVerifyRequest request) { Employee employee = employeeMapper.selectEnabledByCardNo(request.getCardNo()); if (employee == null) { return recordAndReturn(VerifyResultEnum.RECEPTIONIST_UNAVAILABLE); } String boundCardNo = employee.getCardNo(); if (boundCardNo == null || boundCardNo.trim().isEmpty()) { return recordAndReturn(VerifyResultEnum.CARD_NOT_BOUND); } String inputCardNo = request.getCardNo() == null ? "" : request.getCardNo().trim(); if (!boundCardNo.trim().equalsIgnoreCase(inputCardNo)) { return recordAndReturn(VerifyResultEnum.CARD_NOT_MATCH); } return recordAndReturn(VerifyResultEnum.SUCCESS); } /** * 统一出口:记录验证流水(成功/失败均记录)并返回结果。 * TODO: 落库到 t_employee_verify_log(建表脚本见 sql/verify_log.sql),字段建议包含: * employee_id, result_code, client_ip, device_no, create_time。 * TODO: 结合 Redis 按 employeeId + 来源IP/设备号 做滑动窗口计数,连续失败N次后返回 * VERIFY_LOCKED 并锁定一段时间,防止对某个接待人反复试卡的暴力破解/撞库。 */ private AjaxResult recordAndReturn(VerifyResultEnum result) { if (VerifyResultEnum.SUCCESS.equals(result)) { log.info("接待人刷卡验证成功"); return AjaxResult.success(); } log.warn("接待人刷卡验证失败, result={}", result.getMessage()); return AjaxResult.error(result.getMessage()); } }