添加车速+将图片缓存redis

master
chents 3 years ago
parent 816e1f81e6
commit dfd849972a
  1. 284
      src/main/java/org/springblade/modules/business/controller/CommonApiController.java
  2. 3
      src/main/java/org/springblade/modules/business/service/IStationHintService.java
  3. 9
      src/main/java/org/springblade/modules/business/service/impl/StationHintServiceImpl.java
  4. 15
      src/main/java/org/springblade/modules/job/CarInfoTask.java
  5. 6
      src/main/resources/log/logback-dev.xml

@ -1,14 +1,19 @@
package org.springblade.modules.business.controller; package org.springblade.modules.business.controller;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.swagger.annotations.*; import io.swagger.annotations.*;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.beetl.core.util.ArrayMap; import org.beetl.core.util.ArrayMap;
import org.jetbrains.annotations.NotNull;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STOleUpdate; import org.openxmlformats.schemas.spreadsheetml.x2006.main.STOleUpdate;
import org.springblade.common.cache.business.BusLineCache; import org.springblade.common.cache.business.BusLineCache;
import org.springblade.common.cache.business.SiteListCache; import org.springblade.common.cache.business.SiteListCache;
import org.springblade.common.constant.BusinessConstant; import org.springblade.common.constant.BusinessConstant;
import org.springblade.common.constant.CommonConstant; import org.springblade.common.constant.CommonConstant;
import org.springblade.common.utils.CommonDateUtil;
import org.springblade.common.utils.CommonUtil; import org.springblade.common.utils.CommonUtil;
import org.springblade.core.boot.ctrl.BladeController; import org.springblade.core.boot.ctrl.BladeController;
import org.springblade.core.tenant.annotation.TenantDS; import org.springblade.core.tenant.annotation.TenantDS;
@ -20,9 +25,13 @@ import org.springblade.modules.business.service.IStationHintService;
import org.springblade.modules.business.service.impl.PublishService; import org.springblade.modules.business.service.impl.PublishService;
import org.springblade.modules.business.vo.*; import org.springblade.modules.business.vo.*;
import org.springblade.modules.job.CarInfoTask; import org.springblade.modules.job.CarInfoTask;
import org.springblade.upload.entity.PocBusLineImg;
import org.springblade.upload.mapper.ProBusLineImgMapper;
import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.text.DecimalFormat; import java.text.DecimalFormat;
import java.util.*; import java.util.*;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -50,6 +59,9 @@ public class CommonApiController extends BladeController {
private final IStationHintService stationHintService; private final IStationHintService stationHintService;
@Resource
ProBusLineImgMapper proBusLineImgMapper;
/** /**
* 设置车牌号 * 设置车牌号
* *
@ -252,7 +264,7 @@ public class CommonApiController extends BladeController {
resultMap.put("articleData", busLine.getActicle()); resultMap.put("articleData", busLine.getActicle());
resultMap.put("activityData", busLine.getActivity()); resultMap.put("activityData", busLine.getActivity());
resultMap.put("scenicData", busLine.getScenic()); resultMap.put("scenicData", busLine.getScenic());
resultMap.put("scenicData", busLine.getScenic());
// redis缓存控制显示景区图片还是地图图片, 每10s切换一次, 若无景区图片, 显示地图图片 // redis缓存控制显示景区图片还是地图图片, 每10s切换一次, 若无景区图片, 显示地图图片
if (Func.isBlank(busLine.getImgScenic())) { if (Func.isBlank(busLine.getImgScenic())) {
resultMap.put("imgData", busLine.getImgMap()); resultMap.put("imgData", busLine.getImgMap());
@ -306,179 +318,155 @@ public class CommonApiController extends BladeController {
return R.data(carInfoService.getAllCarInfo()); return R.data(carInfoService.getAllCarInfo());
} }
/** /**
* 获取当前实时的车辆信息 * 获取实时车辆站点信息
*
* @return
*/ */
@ApiOperation(value = "获取当前实时的车辆信息", notes = "carNo") @GetMapping("/get-current-info")
@PostMapping("/get-current-car-info") public R getCurrentInfo(@RequestParam String carNo) {
public R getCurrentCarInfo(@RequestParam String carNo) { CarInfoVO info = carInfoService.getCarInfo(carNo);
CarInfoVO carInfo = carInfoService.getCarInfo(carNo); if (Func.isEmpty(info)) {
//获取当前站点 return R.fail("未获取到车辆信息, 请检查车是否已掉线");
SiteInfoVO currentStation = getCurrentStation(carInfo.getLinename(),carInfo.getUpordown(), carInfo.getInorder()); }
//当前站点 List<SiteInfoVO> siteList = SiteListCache.getSiteList(info.getLinename(), info.getUpordown());
String currentSnameKey = currentStation.getSname(); int nextSiteIdx = Integer.parseInt(info.getInorder());
//获取上一站 if (BusinessConstant.CAR_STAT_IN.toString().equals(info.getNowstate())) {
SiteInfoVO upStation = getUpStation(carInfo.getLinename(), carInfo.getUpordown(), currentSnameKey); nextSiteIdx -= 1;
//获取下一站 }
SiteInfoVO downStation = getDownStation(carInfo.getLinename(), carInfo.getUpordown(), currentSnameKey);
//计算当前车辆距离上一站点百分比 // 下一站
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);
}
// if (Func.isNotEmpty(nextSite3)) {
// snameList.add(nextSite3.getSname());
// }
// 计算当前车辆与前一站和后一站的距离
double pass = 0; double pass = 0;
if (Func.isNotEmpty(upStation)) { if (Func.isNotEmpty(preSite)) {
pass = CommonUtil.calculateDistance(Double.parseDouble(upStation.getJingdu()), Double.parseDouble(upStation.getWeidu()), pass = CommonUtil.calculateDistance(Double.parseDouble(preSite.getJingdu()), Double.parseDouble(preSite.getWeidu()),
Double.parseDouble(carInfo.getJingdu()), Double.parseDouble(carInfo.getWeidu())); Double.parseDouble(info.getJingdu()), Double.parseDouble(info.getWeidu()));
} }
double unpass = 0; double unpass = 0;
if (Func.isNotEmpty(downStation)) { if (Func.isNotEmpty(nextSite)) {
unpass = CommonUtil.calculateDistance(Double.parseDouble(downStation.getJingdu()), Double.parseDouble(downStation.getWeidu()), unpass = CommonUtil.calculateDistance(Double.parseDouble(nextSite.getJingdu()), Double.parseDouble(nextSite.getWeidu()),
Double.parseDouble(carInfo.getJingdu()), Double.parseDouble(carInfo.getWeidu())); Double.parseDouble(info.getJingdu()), Double.parseDouble(info.getWeidu()));
} }
double runPercent = (pass + unpass) > 0 ? (pass / (pass + unpass)) * 100 : 0; 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");
log.error("____________________________________________");
log.error("runPercentStr : " + runPercentStr);
log.error("prePercentStr : " + prePercentStr);
log.error("CarInfoVO: " + info.toString());
BusLine busLine = BusLineCache.getBusLine(carInfo.getUpordown(), downStation.getSname(), downStation.getWeizhi()); 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());
// 组织返回数据
Map<String, Object> resultMap = new HashMap<>(); Map<String, Object> resultMap = new HashMap<>();
resultMap.put("catInfo", redisTemplate.opsForValue().get("car-current-Info" + carNo)); resultMap.put("siteData", siteMap);
resultMap.put("catStat", redisTemplate.opsForValue().get("car-current-stat-info" + carNo));
if (Func.isEmpty(busLine)) { if (Func.isEmpty(busLine)) {
resultMap.put("siteTips", ""); resultMap.put("siteTips", "");
resultMap.put("articleData", ""); resultMap.put("articleData", "");
resultMap.put("activityData", ""); resultMap.put("activityData", "");
resultMap.put("scenicData", ""); resultMap.put("scenicData", "");
resultMap.put("imgData", ""); resultMap.put("imgData", "");
resultMap.put("speed", "");
} else { } else {
resultMap.put("siteTips", busLine.getTips()); resultMap.put("siteTips", busLine.getTips());
resultMap.put("articleData", busLine.getActicle()); resultMap.put("articleData", busLine.getActicle());
resultMap.put("activityData", busLine.getActivity()); resultMap.put("activityData", busLine.getActivity());
resultMap.put("scenicData", busLine.getScenic()); resultMap.put("scenicData", busLine.getScenic());
resultMap.put("speed",info.getSpeed());
// redis缓存控制显示景区图片还是地图图片, 每10s切换一次, 若无景区图片, 显示地图图片 List<imgVo> imgListR = (List<imgVo>) redisTemplate.opsForValue().get("imgList-info");
if (Func.isBlank(busLine.getImgScenic())) { if (CollectionUtils.isEmpty(imgListR)){
resultMap.put("imgData", busLine.getImgMap()); List<BusLine> busLineList = stationHintService.getBusLineByName(nextSite.getSname());
} else { QueryWrapper<PocBusLineImg> queryWrapper = new QueryWrapper<>();
// 图片类型 1: 地图, 2:景点 queryWrapper.select("img_url","img_type");
Integer imgType = (Integer) redisTemplate.opsForValue().get("site-img-type"); queryWrapper.eq("bus_line_id",busLineList.get(0).getId());
if (Func.isEmpty(imgType)) { ArrayList<imgVo> imgList = getImgVos(queryWrapper);
imgType = 2; redisTemplate.opsForValue().set("imgList-info", imgList);
redisTemplate.opsForValue().set("site-img-type", imgType, 30, TimeUnit.SECONDS); resultMap.put("imgData", imgList);
}
// 上一次放入地图的时间
Long prePutImgTime = (Long) redisTemplate.opsForValue().get("site-img-time");
if (Func.isEmpty(prePutImgTime)) {
prePutImgTime = System.currentTimeMillis();
redisTemplate.opsForValue().set("site-img-time", prePutImgTime, 30, TimeUnit.DAYS);
}
// 若距离上一次更新图片<10s, 不修改放入的地图类型
if (System.currentTimeMillis() - prePutImgTime < 10000) {
if (1 == imgType) {
resultMap.put("imgData", busLine.getImgMap());
} else {
resultMap.put("imgData", busLine.getImgScenic());
}
} else {
// 否则, 修改返回的图片类型, 并更新缓存
if (1 == imgType) {
imgType = 2;
resultMap.put("imgData", busLine.getImgScenic());
} else {
imgType = 1;
resultMap.put("imgData", busLine.getImgMap());
}
redisTemplate.opsForValue().set("site-img-type", imgType, 30, TimeUnit.SECONDS);
}
}
}
//组装返回对象
CurrentCarInfoVo currentCarInfoVo = new CurrentCarInfoVo();
currentCarInfoVo.setBusno(carInfo.getBusno());
currentCarInfoVo.setLinename(carInfo.getLinename());
currentCarInfoVo.setSpeed(carInfo.getSpeed());
currentCarInfoVo.setCurrentStation(currentSnameKey);
currentCarInfoVo.setUpStation(upStation.getSname());
currentCarInfoVo.setDownStation(downStation.getSname());
currentCarInfoVo.setPercentage(runPercent);
currentCarInfoVo.setInfoMap(resultMap);
//定时任务缓存 //定时任务缓存
carInfoTask.setCarInfo(currentCarInfoVo); carInfoTask.setCarInfo(resultMap);
return R.data(currentCarInfoVo); return R.data(resultMap);
}
/**
* 根据上下行和已经经过了第几个站点计算当前站点
*
* @param upOrDown 上下行
* @param inOrder 已经经过了第几个站点
* @return 当前站点
*/
private SiteInfoVO getCurrentStation(String linename, String upOrDown, String inOrder) {
// 根据上下行获取对应的站点集合
List<SiteInfoVO> stationList = getStationListByUpOrDown(linename,upOrDown);
// 计算当前站点
int currentStationIndex = Integer.parseInt(inOrder) - 1;
if (currentStationIndex < 0) {
currentStationIndex = 0;
} else if (currentStationIndex >= stationList.size()) {
currentStationIndex = stationList.size() - 1;
}
return stationList.get(currentStationIndex);
}
/**
* 当前车辆上一站
* @Date 2023/5/10 17:02
* @param linename
* @param upordown
* @param currentSnameKey
* @return
**/
private SiteInfoVO getUpStation(String linename, String upordown, String currentSnameKey) {
List<SiteInfoVO> busLineVoList = getStationListByUpOrDown(linename, upordown);
for (int i = 0; i < busLineVoList.size(); i++) {
if (busLineVoList.get(i).getSname().equals(currentSnameKey)) {
if (i == 0) {
return null;
} else {
return busLineVoList.get(i - 1);
}
} }
resultMap.put("imgData", imgListR);
} }
return null; //定时任务缓存
carInfoTask.setCarInfo(resultMap);
return R.data(resultMap);
} }
/** @NotNull
* 当前车辆下一站 private ArrayList<imgVo> getImgVos(QueryWrapper<PocBusLineImg> queryWrapper) {
* @Date 2023/5/10 17:02 List<PocBusLineImg> pocBusLineImgs = proBusLineImgMapper.selectList(queryWrapper);
* @param linename ArrayList<imgVo> imgList = new ArrayList<>();
* @param upordown for(PocBusLineImg pocBusLineImg : pocBusLineImgs){
* @param currentSnameKey imgVo img = new imgVo();
* @return img.setImgUrl(pocBusLineImg.getImgUrl());
**/ img.setImgType(pocBusLineImg.getImgType());
private SiteInfoVO getDownStation(String linename, String upordown, String currentSnameKey) { img.setBusLineId(pocBusLineImg.getBusLineId());
List<SiteInfoVO> busLineVoList = getStationListByUpOrDown(linename, upordown); imgList.add(img);
for (int i = 0; i < busLineVoList.size(); i++) {
if (busLineVoList.get(i).getSname().equals(currentSnameKey)) {
if (i == busLineVoList.size() - 1) {
return null;
} else {
return busLineVoList.get(i + 1);
}
}
} }
return null; return imgList;
}
/**
* 根据上下行获取对应的站点集合
*
* @param upOrDown 上下行
* @return 站点集合
*/
private List<SiteInfoVO> getStationListByUpOrDown(String linename,String upOrDown) {
//根据在那条线路,上下行获取对应的站点集合
List<SiteInfoVO> siteList = SiteListCache.getSiteList(linename,upOrDown);
return siteList;
} }

@ -31,4 +31,7 @@ public interface IStationHintService extends BaseService<BusLine> {
boolean delete(String ids); boolean delete(String ids);
R<List<StationHintVo>> QueryBusLineMessage(String linename, String updown); R<List<StationHintVo>> QueryBusLineMessage(String linename, String updown);
//根据name获取返回id
List<BusLine> getBusLineByName(String name);
} }

@ -139,6 +139,15 @@ public class StationHintServiceImpl extends BaseServiceImpl<BusLineMapper,BusLin
return R.data(stationArr); return R.data(stationArr);
} }
@Override
public List<BusLine> getBusLineByName(String name) {
QueryWrapper<BusLine> busLineQueryWrapper = new QueryWrapper<>();
busLineQueryWrapper.select("id");
busLineQueryWrapper.eq("sname_key", name);
List<BusLine> busLines = busLineMapper.selectList(busLineQueryWrapper);
return busLines;
}
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)

@ -13,6 +13,7 @@ import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* @Author: Chents * @Author: Chents
@ -35,16 +36,16 @@ public class CarInfoTask {
private IStationHintService stationHintService; private IStationHintService stationHintService;
//@Scheduled(cron = "0/1 * * * * ?") //@Scheduled(cron = "0/1 * * * * ?")
public void setCarInfo(CurrentCarInfoVo currentCarInfoVo) { public void setCarInfo(Map<String,Object> resultMap) {
redisTemplate.opsForValue().set("current_car_info", currentCarInfoVo); redisTemplate.opsForValue().set("current_car_info", resultMap);
System.out.println("======存入实时车辆信息到redis成功========="); System.out.println("======存入实时车辆信息到redis成功=========");
} }
//@Scheduled(cron = "0/1 * * * * ?") //@Scheduled(cron = "0/1 * * * * ?")
public void parseCarInfo() { public void parseCarInfo() {
//从redis获取数据 //从redis获取数据
CurrentCarInfoVo carInfo = (CurrentCarInfoVo) redisTemplate.opsForValue().get("current_car_info"); Map<String,Object> carInfoMap = (Map<String,Object> ) redisTemplate.opsForValue().get("current_car_info");
if (carInfo == null) { if (carInfoMap.isEmpty()) {
log.info("======未从redis获取当前车辆实时数据======="); log.info("======未从redis获取当前车辆实时数据=======");
return; return;
} }
@ -52,11 +53,11 @@ public class CarInfoTask {
WebSocketMessage message = new WebSocketMessage(); WebSocketMessage message = new WebSocketMessage();
message.setTitle("current_car_info"); message.setTitle("current_car_info");
message.setCode(200); message.setCode(200);
message.setContent("车辆信息:" + carInfo.toString()); message.setContent("车辆信息:" + carInfoMap.toString());
log.info("解析车辆信息:{}", carInfo.toString()); log.info("解析车辆信息:{}", carInfoMap.toString());
// 推送消息给web页面 // 推送消息给web页面
websocketService.broadcast(message); websocketService.broadcast(message);
log.info("推送车辆信息:{}", carInfo.toString()); log.info("推送车辆信息:{}", carInfoMap.toString());
} }
} }

@ -17,7 +17,7 @@
<!-- 控制台输出 --> <!-- 控制台输出 -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender"> <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<filter class="ch.qos.logback.classic.filter.LevelFilter"> <filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level> <level>DEBUG</level>
<onMatch>ACCEPT</onMatch> <onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch> <onMismatch>DENY</onMismatch>
</filter> </filter>
@ -45,11 +45,11 @@
<appender-ref ref="file"/> <appender-ref ref="file"/>
</appender> </appender>
<root level="INFO"> <root level="DEBUG">
<appender-ref ref="console"/> <appender-ref ref="console"/>
</root> </root>
<root level="INFO"> <root level="DEBUG">
<appender-ref ref="file"/> <appender-ref ref="file"/>
</root> </root>

Loading…
Cancel
Save