package com.ruoyi.unattended.access.service.impl;
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.ruoyi.unattended.access.dto.AccessVerifyRequest;
|
import com.ruoyi.unattended.access.mapper.AccessGateMapper;
|
import com.ruoyi.unattended.access.mapper.AccessRecordMapper;
|
import com.ruoyi.unattended.access.mapper.AccessVehicleMapper;
|
import com.ruoyi.unattended.access.pojo.AccessGate;
|
import com.ruoyi.unattended.access.pojo.AccessRecord;
|
import com.ruoyi.unattended.access.pojo.AccessVehicle;
|
import com.ruoyi.unattended.access.service.AccessService;
|
import com.ruoyi.unattended.pojo.UnattendedOperation;
|
import com.ruoyi.unattended.service.UnattendedOperationService;
|
import lombok.extern.slf4j.Slf4j;
|
import org.springframework.stereotype.Service;
|
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.StringUtils;
|
|
import javax.annotation.Resource;
|
import java.time.LocalDateTime;
|
import java.util.ArrayList;
|
import java.util.List;
|
|
@Slf4j
|
@Service
|
public class AccessServiceImpl implements AccessService {
|
|
@Resource
|
private AccessGateMapper accessGateMapper;
|
|
@Resource
|
private AccessRecordMapper accessRecordMapper;
|
|
@Resource
|
private AccessVehicleMapper accessVehicleMapper;
|
|
@Resource
|
private UnattendedOperationService unattendedOperationService;
|
|
@Override
|
public IPage<AccessGate> gatePage(Page<AccessGate> page, AccessGate query) {
|
LambdaQueryWrapper<AccessGate> wrapper = Wrappers.<AccessGate>lambdaQuery()
|
.like(StringUtils.hasText(query.getGateName()), AccessGate::getGateName, query.getGateName())
|
.like(StringUtils.hasText(query.getArea()), AccessGate::getArea, query.getArea())
|
.orderByDesc(AccessGate::getCreateTime);
|
return accessGateMapper.selectPage(page, wrapper);
|
}
|
|
@Override
|
public boolean gateSave(AccessGate gate) {
|
if (!StringUtils.hasText(gate.getDeviceStatus())) {
|
gate.setDeviceStatus("online");
|
}
|
if (!StringUtils.hasText(gate.getGateType())) {
|
gate.setGateType("all");
|
}
|
return accessGateMapper.insert(gate) > 0;
|
}
|
|
@Override
|
public boolean gateUpdate(AccessGate gate) {
|
return accessGateMapper.updateById(gate) > 0;
|
}
|
|
@Override
|
public boolean gateRemove(List<Long> ids) {
|
if (CollectionUtils.isEmpty(ids)) {
|
return false;
|
}
|
return accessGateMapper.deleteBatchIds(ids) > 0;
|
}
|
|
/* ---------- 车辆通行授权 ---------- */
|
|
@Override
|
public IPage<AccessVehicle> vehiclePage(Page<AccessVehicle> page, AccessVehicle query) {
|
LambdaQueryWrapper<AccessVehicle> wrapper = Wrappers.<AccessVehicle>lambdaQuery()
|
.like(StringUtils.hasText(query.getPlateNumber()), AccessVehicle::getPlateNumber, query.getPlateNumber())
|
.like(StringUtils.hasText(query.getRfidTag()), AccessVehicle::getRfidTag, query.getRfidTag())
|
.like(StringUtils.hasText(query.getCarrierName()), AccessVehicle::getCarrierName, query.getCarrierName())
|
.eq(StringUtils.hasText(query.getStatus()), AccessVehicle::getStatus, query.getStatus())
|
.orderByDesc(AccessVehicle::getId);
|
return accessVehicleMapper.selectPage(page, wrapper);
|
}
|
|
@Override
|
public boolean vehicleSave(AccessVehicle vehicle) {
|
if (!StringUtils.hasText(vehicle.getStatus())) {
|
vehicle.setStatus("valid");
|
}
|
return accessVehicleMapper.insert(vehicle) > 0;
|
}
|
|
@Override
|
public boolean vehicleUpdate(AccessVehicle vehicle) {
|
return accessVehicleMapper.updateById(vehicle) > 0;
|
}
|
|
@Override
|
public boolean vehicleRemove(List<Long> ids) {
|
if (CollectionUtils.isEmpty(ids)) {
|
return false;
|
}
|
return accessVehicleMapper.deleteBatchIds(ids) > 0;
|
}
|
|
private AccessVehicle matchVehicle(String plateNumber, String rfidTag) {
|
AccessVehicle byPlate = null;
|
if (StringUtils.hasText(plateNumber)) {
|
byPlate = accessVehicleMapper.selectOne(Wrappers.<AccessVehicle>lambdaQuery()
|
.eq(AccessVehicle::getPlateNumber, plateNumber).last("limit 1"));
|
}
|
if (byPlate != null) {
|
return byPlate;
|
}
|
if (StringUtils.hasText(rfidTag)) {
|
return accessVehicleMapper.selectOne(Wrappers.<AccessVehicle>lambdaQuery()
|
.eq(AccessVehicle::getRfidTag, rfidTag).last("limit 1"));
|
}
|
return null;
|
}
|
|
/**
|
* 识别核验 + 放行判定 + 记录。
|
*
|
* 车辆:车牌识别 + RFID 双要素,识别到即放行;在车辆档案中的车辆补充承运商信息;
|
* 人员:人脸识别 + 工卡刷卡 双要素;
|
* 地磅联动:指定 weighbridgeRecordId 时,校验该地磅记录存在且红外检测无异常。
|
*/
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public AccessRecord verify(AccessVerifyRequest request) {
|
AccessRecord record = new AccessRecord();
|
record.setAccessTime(LocalDateTime.now());
|
record.setGateId(request.getGateId());
|
record.setDirection(StringUtils.hasText(request.getDirection()) ? request.getDirection() : "in");
|
record.setCarrierName(request.getCarrierName());
|
record.setWeighbridgeRecordId(request.getWeighbridgeRecordId());
|
record.setWeighbridgeLinked(Boolean.TRUE.equals(request.getWeighbridgeLinked()) ? 1 : 0);
|
|
AccessGate gate = request.getGateId() == null ? null : accessGateMapper.selectById(request.getGateId());
|
if (gate != null) {
|
record.setGateName(gate.getGateName());
|
}
|
|
List<String> methods = new ArrayList<>();
|
List<String> rejects = new ArrayList<>();
|
boolean verified = false;
|
|
if ("person".equalsIgnoreCase(request.getAccessType())) {
|
record.setAccessType("person");
|
record.setPersonName(request.getPersonName());
|
record.setWorkCardNo(request.getWorkCardNo());
|
record.setIdCardFace(request.getIdCardFace());
|
if ("matched".equalsIgnoreCase(request.getIdCardFace())) {
|
methods.add("人脸识别");
|
}
|
if (StringUtils.hasText(request.getWorkCardNo())) {
|
methods.add("工卡");
|
}
|
// 双要素:人脸 + 工卡
|
if (!StringUtils.hasText(request.getPersonName()) || !"matched".equalsIgnoreCase(request.getIdCardFace())) {
|
rejects.add("人脸识别未通过");
|
}
|
if (!StringUtils.hasText(request.getWorkCardNo())) {
|
rejects.add("未刷工卡");
|
}
|
verified = rejects.isEmpty();
|
} else {
|
record.setAccessType("vehicle");
|
record.setPlateNumber(request.getPlateNumber());
|
record.setRfidTag(request.getRfidTag());
|
// 车牌识别 + RFID 双因子,识别到即视为通过;未登记车辆不拦截
|
if (StringUtils.hasText(request.getPlateNumber())) {
|
methods.add("车牌识别");
|
} else {
|
rejects.add("车牌识别失败");
|
}
|
if (StringUtils.hasText(request.getRfidTag())) {
|
methods.add("RFID");
|
} else {
|
rejects.add("RFID标签未识别");
|
}
|
if (rejects.isEmpty()) {
|
AccessVehicle vehicle = matchVehicle(request.getPlateNumber(), request.getRfidTag());
|
if (vehicle != null) {
|
if (!StringUtils.hasText(record.getCarrierName()) && StringUtils.hasText(vehicle.getCarrierName())) {
|
record.setCarrierName(vehicle.getCarrierName());
|
}
|
if ("disabled".equalsIgnoreCase(vehicle.getStatus())) {
|
rejects.add("该车辆通行授权已停用");
|
}
|
}
|
}
|
verified = rejects.isEmpty();
|
}
|
|
// 地磅联动校验
|
if (Boolean.TRUE.equals(request.getWeighbridgeLinked())) {
|
if (request.getWeighbridgeRecordId() == null) {
|
rejects.add("缺少关联地磅记录");
|
verified = false;
|
} else {
|
UnattendedOperation op = unattendedOperationService.getById(request.getWeighbridgeRecordId());
|
if (op == null) {
|
rejects.add("关联地磅记录不存在");
|
verified = false;
|
} else {
|
if (StringUtils.hasText(op.getCarrierName())) {
|
record.setCarrierName(op.getCarrierName());
|
}
|
if (op.getCheatFlag() != null && op.getCheatFlag() == 1) {
|
rejects.add("地磅检测异常:" + (op.getCheatReason() == null ? "车辆位置偏移" : op.getCheatReason()));
|
verified = false;
|
}
|
if ("alarm".equalsIgnoreCase(op.getInfraredStatus())) {
|
rejects.add("红外检测报警");
|
verified = false;
|
}
|
}
|
}
|
}
|
|
record.setVerifyMethod(methods.isEmpty() ? null : String.join("+", methods));
|
|
if (verified && rejects.isEmpty()) {
|
record.setVerifyResult("pass");
|
record.setReleaseStatus("released");
|
record.setRejectReason(null);
|
} else {
|
record.setVerifyResult("reject");
|
record.setReleaseStatus("blocked");
|
record.setRejectReason(String.join(";", rejects));
|
}
|
accessRecordMapper.insert(record);
|
|
if ("vehicle".equals(record.getAccessType()) && "released".equals(record.getReleaseStatus())) {
|
log.info("[门禁放行] 车牌={} 门禁={} 方式={}", record.getPlateNumber(), record.getGateName(), record.getVerifyMethod());
|
}
|
return record;
|
}
|
|
@Override
|
public IPage<AccessRecord> recordPage(Page<AccessRecord> page, AccessRecord query) {
|
LambdaQueryWrapper<AccessRecord> wrapper = Wrappers.<AccessRecord>lambdaQuery()
|
.like(StringUtils.hasText(query.getPlateNumber()), AccessRecord::getPlateNumber, query.getPlateNumber())
|
.like(StringUtils.hasText(query.getPersonName()), AccessRecord::getPersonName, query.getPersonName())
|
.eq(StringUtils.hasText(query.getAccessType()), AccessRecord::getAccessType, query.getAccessType())
|
.eq(StringUtils.hasText(query.getGateId() == null ? null : String.valueOf(query.getGateId())),
|
AccessRecord::getGateId, query.getGateId())
|
.orderByDesc(AccessRecord::getAccessTime);
|
return accessRecordMapper.selectPage(page, wrapper);
|
}
|
}
|