From bd0b87c75d31f1ae292aff609c6bfc93242ff610 Mon Sep 17 00:00:00 2001 From: fengyarnom Date: Fri, 21 Feb 2025 10:09:34 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9Esim=E5=8D=A1=E6=B5=81?= =?UTF-8?q?=E9=87=8F=E6=9F=A5=E8=AF=A2=E5=92=8C=E7=8A=B6=E6=80=81=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2=E5=90=8E=E5=8F=B0=E4=BB=BB=E5=8A=A1=201.=20=E7=8A=B6?= =?UTF-8?q?=E6=80=81=E6=9F=A5=E8=AF=A2=EF=BC=88=E6=AF=8F=E5=B0=8F=E6=97=B6?= =?UTF-8?q?=EF=BC=89=202.=20=E6=B5=81=E9=87=8F=E6=9F=A5=E8=AF=A2=20?= =?UTF-8?q?=EF=BC=88=E6=AF=8F=E4=B8=A4=E5=B0=8F=E6=97=B6=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sideslope/task/SimStatusChecker.java | 203 ++++++++++++++++++ 1 file changed, 203 insertions(+) create mode 100644 sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/task/SimStatusChecker.java diff --git a/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/task/SimStatusChecker.java b/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/task/SimStatusChecker.java new file mode 100644 index 00000000..319be556 --- /dev/null +++ b/sec-beidou-rtcm/src/main/java/com/imdroid/sideslope/task/SimStatusChecker.java @@ -0,0 +1,203 @@ +package com.imdroid.sideslope.task; + +import com.alibaba.excel.util.StringUtils; +import com.imdroid.secapi.dto.*; +import com.imdroid.sideslope.sal.Device; +import com.imdroid.sideslope.sal.DeviceService; +import com.imdroid.sideslope.service.SimCardQueryServiceImpl; +import com.imdroid.sideslope.service.WarningServiceImpl; +import com.imdroid.sideslope.simcard.BaseResponse; +import com.imdroid.sideslope.simcard.CardInfoData; +import com.imdroid.sideslope.simcard.CardStatusData; +import com.imdroid.sideslope.simcard.GprsData; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.math.BigDecimal; +import java.util.*; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +@Component +@Configuration +@EnableScheduling +public class SimStatusChecker { + // SIM 卡流量和状态查询定时任务 + // 1. 每小时任务 + // a. 通过CardInfo 检查 iccid 和 sim卡号 + // b. 通过QueryCardStatus 检查SIM卡当前的状态 + // 2. 每两小时任务 + // a. QueryGprs 检查 SIM 流量 + final Logger logger = LoggerFactory.getLogger(SimStatusChecker.class); + @Autowired + private GnssStatusMapper gnssStatusMapper; + + @Autowired + private WarningServiceImpl warningService; + + @Autowired + private SimCardsMapper simCardsMapper; + @Resource(name = "local") + private DeviceService deviceService; + + private static final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); + @Autowired + private SimCardQueryServiceImpl simCardQueryServiceImpl; + + // 每小时执行一次状态检查调度 + @Scheduled(cron = "0 0 * * * ?") + private void scheduleSimCardStatusCheck() { + List onlineDevices = gnssStatusMapper.queryOnline(); + //logger.debug("当前在线设备数量: {}", onlineDevices.size()); + + for (GnssStatusJoin onlineDevice : onlineDevices) { + int delay = Math.abs(onlineDevice.getDeviceid().hashCode() % 3600 ); + //logger.debug("设备: {}, SIM状态查询,延迟执行: {}秒", onlineDevice.getDeviceid(), delay); + + scheduler.schedule(() -> checkDeviceSimCardStatus(onlineDevice.getDeviceid()), + delay, TimeUnit.SECONDS); + } + } + + // 每两小时执行一次流量检查调度 + @Scheduled(cron = "0 0 0/2 * * ?") + private void scheduleSimCardTrafficCheck() { + List onlineDevices = gnssStatusMapper.queryOnline(); + //logger.debug("当前在线设备数量: {}", onlineDevices.size()); + + for (GnssStatusJoin onlineDevice : onlineDevices) { + int delay = Math.abs(onlineDevice.getDeviceid().hashCode() % 7200); + //logger.debug("设备: {}, SIM流量查询,延迟执行: {}秒", onlineDevice.getDeviceid(), delay); + + scheduler.schedule(() -> checkDeviceSimCardTraffic(onlineDevice.getDeviceid()), + delay, TimeUnit.SECONDS); + } + } + + private void checkDeviceSimCardStatus(String deviceId) { + try { + Device device = deviceService.findByDeviceId(deviceId); + // 不允许尚未从自检得到 ICCID 的设备参加 SIM 卡状态查询 + if (!simCardQueryServiceImpl.hasValidIccid(device)) { + return; + } + // SimCards 表中没有数据就初始化,这其实说明它在自检中刚获得属于自己的 ICCID 号 + SimCard simCard = simCardQueryServiceImpl.CreateOrUpdateSimCard(device); + updateSimCardInfo(device, simCard); + + } catch (Exception e) { + logger.error("设备{}状态查询失败: ", deviceId, e); + } + } + + private void checkDeviceSimCardTraffic(String deviceId) { + try { + Device device = deviceService.findByDeviceId(deviceId); + // 不允许尚未从自检得到 ICCID 的设备参加 SIM 卡状态查询 + if (!simCardQueryServiceImpl.hasValidIccid(device)) { + return; + } + // SimCards 表中没有数据就初始化,这说明它在自检中获得属于自己的 ICCID 号 + SimCard simCard = simCardQueryServiceImpl.CreateOrUpdateSimCard(device); + // 如果该卡状态不是已激活,而是其他状态,那么不运行它参与 SIM 卡流量检测 + if(simCard.getStatus() != SimCard.STATUS_ACTIVATED){ + return; + } + updateSimCardTrafficFromAPI(device, simCard); + + } catch (Exception e) { + logger.error("设备{}查询失败: ", deviceId, e); + } + } + + private void updateSimCardInfo(Device device, SimCard simCard) throws Exception { + // 自检中只是获取保存了设备的 ICCID ,所有如果判断如果没有 MSISDN,先更新基本信息 + if (StringUtils.isBlank(simCard.getMsisdn())) { + updateSimCardBasicInfoFromAPI(device, simCard); + } + // 更新状态 + updateSimCardStatusFromAPI(device, simCard); + } + private void updateSimCardBasicInfoFromAPI(Device device, SimCard simCard) { + try { + BaseResponse response = simCardQueryServiceImpl.queryCardInfo(device); + if (!simCardQueryServiceImpl.isValidResponse(response)) { + return; + } + + CardInfoData info = response.getData(); + simCard.setUpdatetime(new Date()); + simCard.setMsisdn(info.getMsisdn()); + simCardsMapper.updateSimCardInfo(simCard); + + // logger.debug("更新SIM卡基本信息 - imsi: {}, msisdn: {}, iccid: {}", + // info.getImsi(), info.getMsisdn(), info.getIccid()); + } catch (Exception e) { + logger.error("更新设备{}的SIM卡基本信息失败: ", device.getDeviceId(), e); + throw e; + } + } + private void updateSimCardStatusFromAPI(Device device, SimCard simCard) { + try { + BaseResponse response = simCardQueryServiceImpl.queryCardStatus(device); + if (!simCardQueryServiceImpl.isValidResponse(response)) { + return; + } + CardStatusData status = response.getData(); + simCard.setUpdatetime(new Date()); + simCard.setStatus(status.getStatusCode()); + simCard.setStatus(3); + simCardsMapper.updateSimCardInfo(simCard); + + warningService.checkSimCardStatus(device, simCard); + +// logger.debug("更新SIM卡状态 - Code: {}, 描述: {}", +// status.getStatusCode(), status.getStatusDesc()); + } catch (Exception e) { + logger.error("更新设备{}的SIM卡状态失败: ", device.getDeviceId(), e); + throw e; + } + } + + private void updateSimCardTrafficFromAPI(Device device, SimCard simCard) { + try { + BaseResponse response = simCardQueryServiceImpl.queryGprs(device); + if (!simCardQueryServiceImpl.isValidResponse(response)) { + return; + } + + GprsData gprsData = response.getData(); + GprsData.GprsUsage usage = gprsData.getFirstGprsUsage(); + if (usage == null) { + logger.warn("无可用流量数据查询, deviceId: {}", device.getDeviceId()); + return; + } + + simCard.setUpdatetime(new Date()); + simCard.setRemaining(BigDecimal.valueOf(usage.getLeft())); + simCard.setUsed(BigDecimal.valueOf(usage.getUsed())); + simCard.setTotal(BigDecimal.valueOf(usage.getTotal())); + simCardsMapper.updateSimCardInfo(simCard); + + warningService.checkSimCardTraffic(device, simCard); + +// logger.info("更新流量信息成功 - deviceId: {}, 剩余: {}MB, 总量: {}MB, 已用: {}MB", +// device.getIccid(), +// simCard.getRemaining(), +// simCard.getTotal(), +// simCard.getUsed()); + + } catch (Exception e) { + logger.error("设备{}更新SIM卡流量失败: ", device.getDeviceId(), e); + throw e; + } + } + +}