package org.springblade.modules.job; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springblade.common.cache.business.BusLineCache; import org.springblade.common.cache.business.CarInfoCache; import org.springblade.common.cache.business.SiteListCache; import org.springblade.common.constant.BusinessConstant; import org.springblade.common.utils.CommonUtil; import org.springblade.common.utils.HttpClientUtils; import org.springblade.core.tool.api.R; import org.springblade.core.tool.utils.BeanUtil; import org.springblade.core.tool.utils.Func; import org.springblade.modules.business.entity.BusLine; import org.springblade.modules.business.service.ICarInfoService; import org.springblade.modules.business.service.IStationHintService; import org.springblade.modules.business.vo.CarInfoVO; import org.springblade.modules.business.vo.SiteInfoVO; import org.springblade.modules.business.vo.imgVo; import org.springblade.modules.websocket.service.WebsocketService; import org.springblade.modules.websocket.vo.WebSocketMessage; import org.springblade.upload.service.IProBusLineImgService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import org.springframework.web.bind.annotation.RequestParam; import springfox.documentation.spring.web.json.Json; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; /** * @Author: Chents * @Create: 2023-05-09 */ @Component @Slf4j @RequiredArgsConstructor public class CarInfoTask { private static final String WEB = "web"; private static final String CURRENT_CAR_INFO = "current_car_info"; private static final String SPEED = "speed"; private final ICarInfoService carInfoService; private final RedisTemplate redisTemplate; private final WebsocketService websocketService; private final IStationHintService stationHintService; private final IProBusLineImgService proBusLineImgService; /** * 从车辆信息平台同步数据 */ @Scheduled(cron = "0/1 * * * * ?") public void syncCarInfo() { String url = "http://223.99.174.234:9211/BusInfoServer/bus_getstateinfo_1014?userkey=yhlhhh20230323"; String res = HttpClientUtils.doGet(url); CarInfoCache.setAllCarData(res); } /** * 定时将车辆运行信息推送给web */ @Scheduled(cron = "0/5 * * * * ?") public void parseCarInfo() { //从redis获取数据 CarInfoVO info = null; String allCarData = CarInfoCache.getAllCarData(); JSONObject json = JSON.parseObject(allCarData); String carNo = CarInfoCache.getPushCarNo(); JSONArray carInfoList = json.getJSONArray("bus"); for (Object o : carInfoList) { JSONObject carInfo = (JSONObject) o; log.info("============="+carInfo.getString("busno")); if (carNo.equals(carInfo.getString("busno"))) { info = BeanUtil.copy(carInfo, CarInfoVO.class); } } List siteList = SiteListCache.getSiteList(info.getLinename(), info.getUpordown()); int nextSiteIdx = Integer.parseInt(info.getInorder()); if (BusinessConstant.CAR_STAT_IN.toString().equals(info.getNowstate())) { nextSiteIdx -= 1; } // 下一站 List> snameList = new ArrayList<>(); SiteInfoVO nextSite = nextSiteIdx < siteList.size() ? siteList.get(nextSiteIdx) : null; SiteInfoVO nextSite2 = (nextSiteIdx + 1) < siteList.size() ? siteList.get((nextSiteIdx) + 1) : null; SiteInfoVO nextSite3 = (nextSiteIdx + 2) < siteList.size() ? siteList.get(nextSiteIdx + 2) : null; // 上一站 SiteInfoVO preSite = nextSiteIdx - 1 > 0 ? siteList.get(nextSiteIdx - 1) : null; // 上两站 SiteInfoVO preTwoSite = nextSiteIdx - 2 > 0 ? siteList.get(nextSiteIdx - 2) : null; // 上三站 SiteInfoVO preThreeSite = nextSiteIdx - 3 > 0 ? siteList.get(nextSiteIdx - 3) : null; Map siteMsgMap; if (Func.isNotEmpty(preThreeSite)) { siteMsgMap = new HashMap<>(); siteMsgMap.put("siteName", preThreeSite.getSname()); siteMsgMap.put("type", "before"); snameList.add(siteMsgMap); } if (Func.isNotEmpty(preTwoSite)) { siteMsgMap = new HashMap<>(); siteMsgMap.put("siteName", preTwoSite.getSname()); siteMsgMap.put("type", "before"); snameList.add(siteMsgMap); } if (Func.isNotEmpty(preSite)) { siteMsgMap = new HashMap<>(); siteMsgMap.put("siteName", preSite.getSname()); siteMsgMap.put("type", "before"); snameList.add(siteMsgMap); } if (Func.isNotEmpty(nextSite)) { siteMsgMap = new HashMap<>(); siteMsgMap.put("siteName", nextSite.getSname()); siteMsgMap.put("type", "after"); snameList.add(siteMsgMap); } if (Func.isNotEmpty(nextSite2)) { siteMsgMap = new HashMap<>(); siteMsgMap.put("siteName", nextSite2.getSname()); siteMsgMap.put("type", "after"); snameList.add(siteMsgMap); } // 计算当前车辆与前一站和后一站的距离 double pass = 0; if (Func.isNotEmpty(preSite)) { pass = CommonUtil.calculateDistance(Double.parseDouble(preSite.getJingdu()), Double.parseDouble(preSite.getWeidu()), Double.parseDouble(info.getJingdu()), Double.parseDouble(info.getWeidu())); } double unpass = 0; if (Func.isNotEmpty(nextSite)) { unpass = CommonUtil.calculateDistance(Double.parseDouble(nextSite.getJingdu()), Double.parseDouble(nextSite.getWeidu()), Double.parseDouble(info.getJingdu()), Double.parseDouble(info.getWeidu())); } double runPercent = (pass + unpass) > 0 ? (pass / (pass + unpass)) * 100 : 0; DecimalFormat df1 = new DecimalFormat("#"); // 先从缓存中获取上一次的运行百分比, 然后将本次的运行百分比更新到缓存中 String runPercentStr = df1.format(runPercent > 100 ? 100 : runPercent); String prePercentStr = (String) redisTemplate.opsForValue().get("car-run-percent-info"); prePercentStr = Func.isBlank(prePercentStr) ? "0" : prePercentStr; redisTemplate.opsForValue().set("car-run-percent-info", runPercentStr, 30, TimeUnit.SECONDS); Map siteMap = new HashMap<>(); siteMap.put("startSite", siteList.get(0).getSname()); siteMap.put("endSite", siteList.get(siteList.size() - 1).getSname()); siteMap.put("siteList", snameList); siteMap.put("prePercent", prePercentStr); siteMap.put("runPercent", runPercentStr); if (Func.isEmpty(nextSite)) { nextSite = preSite; } BusLine busLine = BusLineCache.getBusLine(info.getUpordown(), nextSite.getSname(), nextSite.getWeizhi()); log.info("================ BusLineCache.getBusLine(" + info.getUpordown() + ", " + nextSite.getSname() + ", " + nextSite.getWeizhi() + ")"); // 组织返回数据 Map resultMap = new HashMap<>(); resultMap.put("siteData", siteMap); resultMap.put("catNo", CarInfoCache.getPushCarNo()); if (Func.isEmpty(busLine)) { resultMap.put("siteTips", ""); resultMap.put("articleData", ""); resultMap.put("activityData", ""); resultMap.put("scenicData", ""); resultMap.put("imgData", new ArrayList<>()); resultMap.put("busNo", ""); resultMap.put("speed", ""); resultMap.put("weidu", ""); resultMap.put("jingdu", ""); } else { resultMap.put("siteTips", busLine.getTips()); resultMap.put("articleData", busLine.getActicle()); resultMap.put("activityData", busLine.getActivity()); resultMap.put("scenicData", busLine.getScenic()); resultMap.put("busNo", info.getBusno()); resultMap.put("speed", info.getSpeed()); resultMap.put("weidu",info.getWeidu()); resultMap.put("jingdu",info.getJingdu()); BusLine busLineByName = stationHintService.getBusLineByName(nextSite.getSname(), nextSite.getWeizhi()); Long busLineId = busLineByName.getId(); List imgList = proBusLineImgService.getImgByid(busLineId); resultMap.put("imgData", imgList); } // 解析车辆信息 HashMap map = new HashMap<>(); map.put("msgType", CURRENT_CAR_INFO); map.put("data", resultMap); String messageJson = JSON.toJSONString(map); WebSocketMessage message = new WebSocketMessage(); message.setTitle(WEB); message.setCode(200); message.setContent(messageJson); // 推送消息给web页面 websocketService.broadcast(message); } /** * 每秒向web推送当前推流车辆的车速和推流状态信息 */ @Scheduled(cron = "0/1 * * * * ?") public void getCarSpeed() { String carNo = CarInfoCache.getPushCarNo(); CarInfoVO info = carInfoService.getCarInfo(carNo); if (Func.isEmpty(info)) { throw new RuntimeException("未获取到车辆信息, 请检查车是否已掉线"); } Map speedMap = new HashMap<>(); speedMap.put("speed", info.getSpeed()); speedMap.put("status", CarInfoCache.getPushStatus()); Map dataMap = new HashMap<>(); dataMap.put("msgType", SPEED); dataMap.put("data", speedMap); WebSocketMessage message = new WebSocketMessage(); message.setTitle(WEB); message.setCode(200); message.setContent(JSON.toJSONString(dataMap)); websocketService.broadcast(message); log.info("车辆实时车速:{}", message.getContent()); } }