|
|
|
|
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<String, Object> 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<SiteInfoVO> 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<Map<String, String>> 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<String, String> 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<String, Object> 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<String, Object> 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<imgVo> imgList = proBusLineImgService.getImgByid(busLineId);
|
|
|
|
|
resultMap.put("imgData", imgList);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 解析车辆信息
|
|
|
|
|
HashMap<String, Object> 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<String, String> speedMap = new HashMap<>();
|
|
|
|
|
speedMap.put("speed", info.getSpeed());
|
|
|
|
|
speedMap.put("status", CarInfoCache.getPushStatus());
|
|
|
|
|
|
|
|
|
|
Map<String, Object> 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());
|
|
|
|
|
}
|
|
|
|
|
}
|