CamelDataUtil.java 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464
  1. package org.dromara.util;
  2. import cn.hutool.core.date.DateUtil;
  3. import cn.hutool.core.util.CharsetUtil;
  4. import cn.hutool.core.util.StrUtil;
  5. import cn.hutool.json.JSON;
  6. import cn.hutool.json.JSONArray;
  7. import cn.hutool.json.JSONUtil;
  8. import io.netty.buffer.ByteBuf;
  9. import io.netty.buffer.Unpooled;
  10. import io.netty.channel.ChannelHandlerContext;
  11. import lombok.extern.slf4j.Slf4j;
  12. import org.apache.camel.CamelContext;
  13. import org.apache.camel.Exchange;
  14. import org.apache.camel.ProducerTemplate;
  15. import org.apache.commons.lang3.time.DateFormatUtils;
  16. import org.dromara.common.core.constant.Constants;
  17. import org.dromara.common.core.utils.DateUtils;
  18. import org.dromara.common.core.utils.SpringUtils;
  19. import org.dromara.common.core.utils.StringUtils;
  20. import org.dromara.common.json.utils.JsonUtils;
  21. import org.dromara.common.redis.utils.CacheUtils;
  22. import org.dromara.common.redis.utils.RedisUtils;
  23. import org.dromara.netty.NettyChannelHandlerContextMapCache;
  24. import org.dromara.netty.pojo.NettyChannelHandlerContext;
  25. import org.dromara.sms4j.api.universal.RedisUtil;
  26. import org.dromara.system.domain.CountData;
  27. import org.dromara.system.domain.GpsData;
  28. import org.dromara.system.domain.SysDictData;
  29. import org.dromara.system.domain.TblCarInfo;
  30. import org.dromara.system.domain.bo.CountDataBo;
  31. import org.dromara.system.domain.bo.SysDictDataBo;
  32. import org.dromara.system.domain.bo.TblCarInfoBo;
  33. import org.dromara.system.domain.bo.TblCarScheduleBo;
  34. import org.dromara.system.domain.vo.SysDictDataVo;
  35. import org.dromara.system.domain.vo.TblCarInfoVo;
  36. import org.dromara.system.domain.vo.TblCarScheduleVo;
  37. import org.dromara.system.service.*;
  38. import org.springframework.beans.factory.annotation.Autowired;
  39. import cn.hutool.json.JSONObject;
  40. import org.springframework.stereotype.Component;
  41. import java.io.UnsupportedEncodingException;
  42. import java.nio.charset.Charset;
  43. import java.time.Duration;
  44. import java.util.*;
  45. import static org.dromara.netty.NettyChannelHandlerContextMapCache.ChannelMapCache;
  46. import static org.dromara.netty.NettyChannelHandlerContextMapCache.ChannelMapCache;
  47. @Slf4j
  48. @Component("camelDataUtil")
  49. public class CamelDataUtil {
  50. @Autowired
  51. private CamelContext camelContext;
  52. @Autowired
  53. ITblGpsDataService gpsDataService;
  54. @Autowired
  55. ITblCountDataService countDataService;
  56. @Autowired
  57. ITblCarInfoService tblCarInfoService;
  58. @Autowired
  59. ITblCarScheduleService tblCarScheduleService;
  60. @Autowired
  61. ISysDictDataService sysDictDataService;
  62. private StandardThreadExecutor threadPoolExecutor=new StandardThreadExecutor();
  63. public void SendData(String endrouter,Object payload,String headerkey,Object headervalue){
  64. ProducerTemplate template = camelContext.createProducerTemplate();
  65. template.sendBodyAndHeader(endrouter,payload,headerkey,headervalue);
  66. }
  67. public void processdata(String body, Exchange exchange) throws UnsupportedEncodingException {
  68. Map<String,String> o = exchange.getMessage().getHeader("mqheader", Map.class);
  69. exchange.getMessage().setHeader("CamelPahoOverrideTopic","/dev/"+o.get("devtype")+"/0001/");
  70. exchange.getMessage().setBody(body.getBytes(Charset.forName("utf8")));
  71. // exchange.getMessage().setBody(body);
  72. }
  73. public static void setPlayList(String carNum,Object data)
  74. {
  75. try{
  76. CacheUtils.put("playlist",carNum,data);
  77. }catch (Exception e){}
  78. }
  79. public void processGpsData(GpsData gpsData){
  80. try{
  81. this.SendData("direct:senddev", JSONUtil.toJsonStr(gpsData), "devtype","-");
  82. }catch (Exception e){
  83. }
  84. gpsDataService.insertData(gpsData);
  85. gpsData.setTs(DateUtils.getNowDate());
  86. //缓存最新数据到redis
  87. RedisUtils.setCacheObject(StringUtils.format("gps_{}", gpsData.getDevicecode()), gpsData);
  88. threadPoolExecutor.execute(new Runnable() {
  89. @Override
  90. public void run() {
  91. TblCarInfoBo carInfoBo = new TblCarInfoBo();
  92. carInfoBo.setDeviceInfos(gpsData.getDevicecode());
  93. List<TblCarInfoVo> carInfoVos = tblCarInfoService.queryList(carInfoBo);
  94. if(carInfoVos.size()>0){
  95. TblCarInfoVo carInfoVo = carInfoVos.get(0);
  96. if(StringUtils.isNotEmpty(carInfoVo.getCarNum())){
  97. //查询车辆信息
  98. TblCarInfoBo carInfoBo1 = new TblCarInfoBo();
  99. carInfoBo1.setCarNum(carInfoVo.getCarNum());
  100. List<TblCarInfoVo> carInfoVos1 = tblCarInfoService.queryList(carInfoBo1);
  101. if(carInfoVos1.size()>0){
  102. // 查询车辆信息
  103. TblCarInfoVo carInfoVo1 = carInfoVos1.get(0);
  104. RedisUtils.setCacheObject(StringUtils.format("gps_{}", carInfoVo1.getId()), gpsData);
  105. TblCarScheduleBo tblCarScheduleBo = new TblCarScheduleBo();
  106. tblCarScheduleBo.setCarNum(carInfoVo1.getCarNum());
  107. Map<String, Object> map = Map.of("scheduleDate", DateUtils.getDate() );
  108. tblCarScheduleBo.setParams(map);
  109. List<TblCarScheduleVo> list = tblCarScheduleService.queryList(tblCarScheduleBo);
  110. if(list.size()>0){
  111. long t0 = 10;
  112. TblCarScheduleVo scheduleVo = null;
  113. for (TblCarScheduleVo vo : list) {
  114. if(vo.getScheduleDate().getTime()-DateUtils.getNowDate().getTime()<0){
  115. if(t0>0){
  116. t0 = vo.getScheduleDate().getTime()-DateUtils.getNowDate().getTime();
  117. scheduleVo = vo;
  118. }
  119. if(t0<vo.getScheduleDate().getTime()-DateUtils.getNowDate().getTime()){
  120. t0 = vo.getScheduleDate().getTime()-DateUtils.getNowDate().getTime();
  121. scheduleVo = vo;
  122. }
  123. }
  124. }
  125. // 查询路线信息
  126. if(scheduleVo!=null){
  127. try{
  128. JSONArray lines = JSONUtil.parseObj(scheduleVo.getPathInfo()).getJSONArray("pathLine");
  129. List<JSONObject> lines1 = new ArrayList<>();
  130. String text = SpringUtils.getBean(ISysConfigService.class).selectConfigByKey("sys.car.text");
  131. RedisUtils.setCacheObject(StringUtils.format("car_{}_{}_current_station",carInfoVo1.getCarNum(),DateFormatUtils.format( scheduleVo.getScheduleDate(),DateUtils.YYYYMMDDHHMMSS)),"");
  132. for (JSONObject jsonObject : lines.toList(JSONObject.class)) {
  133. double distance = DistanceCalculator.calculateDistance(jsonObject.getStr("location"),StringUtils.format("{},{}", gpsData.getLng(),gpsData.getLat()));
  134. String configdistance = SpringUtils.getBean(ISysConfigService.class).selectConfigByKey("sys.car.distance");
  135. if(Double.parseDouble(configdistance)>distance){
  136. String stations = RedisUtils.getCacheObject(StringUtils.format("car_{}_{}_current_station",carInfoVo1.getCarNum(),DateFormatUtils.format( scheduleVo.getScheduleDate(),DateUtils.YYYYMMDDHHMMSS)));
  137. RedisUtils.setCacheObject(StringUtils.format("car_{}_{}_current_station",carInfoVo1.getCarNum(),DateFormatUtils.format( scheduleVo.getScheduleDate(),DateUtils.YYYYMMDDHHMMSS)),stations+","+jsonObject.getStr("stationName"));
  138. //靠近站点 还得计算当前是否跨站点
  139. String stationName = RedisUtils.getCacheObject(StringUtils.format("car_{}_{}_tip",carInfoVo1.getCarNum(),DateFormatUtils.format( scheduleVo.getScheduleDate(),DateUtils.YYYYMMDDHHMMSS) ));
  140. if(stationName!=null && stationName.contains(jsonObject.getStr("stationName"))){
  141. //提报过的不再提报 //离开站记录时间
  142. try {
  143. if (scheduleVo.getExt1() != null) {
  144. //进站点 记录时间
  145. JSONObject datainout = new JSONObject();
  146. datainout = JSONUtil.parseObj(scheduleVo.getExt1());
  147. if (datainout.get(jsonObject.getStr("stationName")) != null) {
  148. JSONObject inout = datainout.getJSONObject(jsonObject.getStr("stationName"));
  149. if (inout.getStr("outtime") == null) {
  150. inout.set("outtime", DateUtil.now());
  151. }
  152. datainout.set(jsonObject.getStr("stationName"), inout);
  153. scheduleVo.setExt1(JSONUtil.toJsonStr(datainout));
  154. TblCarScheduleBo scheduleVo1 = new TblCarScheduleBo();
  155. scheduleVo1.setId(scheduleVo.getId());
  156. scheduleVo1.setExt1(scheduleVo.getExt1());
  157. tblCarScheduleService.updateByBo(scheduleVo1);
  158. }
  159. }
  160. }catch (Exception e){}
  161. }else{
  162. lines1.add(jsonObject);
  163. }
  164. }
  165. }
  166. if(lines1.size()>0){
  167. //先判断是否跨站点
  168. if(lines1.size()>1){
  169. lines1.sort(Comparator.comparingInt((JSONObject o) -> o.getInt("order")));
  170. }
  171. JSONObject jsonObject = lines1.get(0);
  172. String stationName = RedisUtils.getCacheObject(StringUtils.format("car_{}_{}_tip",carInfoVo1.getCarNum(),DateFormatUtils.format( scheduleVo.getScheduleDate(),DateUtils.YYYYMMDDHHMMSS) ));
  173. stationName=stationName==null?"":stationName;
  174. if(!stationName.contains(jsonObject.getStr("stationName"))){
  175. RedisUtils.setCacheObject(StringUtils.format("car_{}_{}_tip",carInfoVo1.getCarNum(), DateFormatUtils.format( scheduleVo.getScheduleDate(),DateUtils.YYYYMMDDHHMMSS) ), stationName+","+jsonObject.getStr("stationName"),Duration.ofSeconds(3600*24));
  176. }
  177. //开始播报
  178. //获取站点设备信息
  179. SysDictDataBo sysDictData = new SysDictDataBo();
  180. sysDictData.setDictLabel(jsonObject.getStr("stationName"));
  181. sysDictData.setDictType("tbl_sites");
  182. List<SysDictDataVo> stations = sysDictDataService.selectDictDataList(sysDictData);
  183. if(stations.size()>0){
  184. try{
  185. //进站点 记录时间
  186. JSONObject datainout = new JSONObject();
  187. if(scheduleVo.getExt1()!=null){
  188. datainout = JSONUtil.parseObj(scheduleVo.getExt1());
  189. }
  190. JSONObject inout = new JSONObject();
  191. inout.set("intime", DateUtil.now());
  192. datainout.set(stations.get(0).getDictLabel(),inout);
  193. scheduleVo.setExt1(JSONUtil.toJsonStr(datainout));
  194. TblCarScheduleBo scheduleVo1 = new TblCarScheduleBo();
  195. scheduleVo1.setId(scheduleVo.getId());
  196. scheduleVo1.setExt1(scheduleVo.getExt1());
  197. tblCarScheduleService.updateByBo(scheduleVo1);
  198. }catch (Exception e){}
  199. //满足条件播报(led or 广播)
  200. String message = StringUtils.format(text, carInfoVo1.getCarNum(),stations.get(0).getDictLabel());
  201. if(StringUtils.isNotEmpty(stations.get(0).getRemark())){
  202. List<JSONObject> devicedatas = JSONUtil.parseArray( stations.get(0).getRemark()).toList(JSONObject.class);
  203. Map<String,String> o = new HashMap<>();
  204. o.put("station",stations.get(0).getDictLabel());
  205. o.put("time",DateUtil.now());
  206. o.put("type",carInfoVo1.getCarType());
  207. o.put("carNum",carInfoVo1.getCarNum());
  208. o.put("msg",message);
  209. CamelDataUtil.setPlayList(carInfoVo1.getCarNum(),o);
  210. for (JSONObject i :devicedatas) {
  211. if(i.getStr("type").equals("led")){
  212. MessageUtils.sendLed(i.getStr("code"), message);
  213. }
  214. if(i.getStr("type").equals("tts")){
  215. MessageUtils.sendTTs(i.getStr("code"), message);
  216. }
  217. }
  218. }
  219. }
  220. }else{
  221. RedisUtils.setCacheObject(StringUtils.format("car_{}_{}_current_station",carInfoVo1.getCarNum(),DateFormatUtils.format( scheduleVo.getScheduleDate(),DateUtils.YYYYMMDDHHMMSS)),"");
  222. }
  223. }catch (Exception e){
  224. log.error("---------------------");
  225. log.error(e.getMessage());
  226. log.error("---------------------");
  227. }
  228. }
  229. }else{
  230. //无路线无排班车辆
  231. String configdistance = SpringUtils.getBean(ISysConfigService.class).selectConfigByKey("sys.car5.distance");
  232. String configtime = SpringUtils.getBean(ISysConfigService.class).selectConfigByKey("sys.car5.time");
  233. String text = SpringUtils.getBean(ISysConfigService.class).selectConfigByKey("sys.car5.text");
  234. if(StrUtil.isEmptyIfStr(configdistance)) configdistance="500";
  235. if(StrUtil.isEmptyIfStr(configtime)) configtime="180000";
  236. //查询所有站点经纬
  237. SysDictDataBo bo =new SysDictDataBo();
  238. bo.setDictType("tbl_sites");
  239. List<SysDictDataVo> allstations = sysDictDataService.selectDictDataList(bo);
  240. //循环计算站点与车的距离
  241. for (SysDictDataVo station : allstations){
  242. if(station.getDictValue()!=null && StrUtil.isNotEmpty(station.getDictValue()) && station.getDictValue().contains(",")){
  243. try{
  244. if(DistanceCalculator.calculateDistance(station.getDictValue(),StringUtils.format("{},{}", gpsData.getLng(),gpsData.getLat()))<Integer.parseInt(configdistance)){
  245. //在范围内
  246. //查看是否在单位时间内播报过
  247. Long time = RedisUtils.getCacheObject(StringUtils.format("car_{}_{}_station",carInfoVo1.getCarNum(),station.getDictCode()));
  248. boolean canbobao = false;
  249. if(time==null){
  250. //未报过
  251. canbobao = true;
  252. }else{
  253. if(System.currentTimeMillis()-time<Integer.parseInt(configtime)){
  254. //在单位时间内播报过
  255. continue;
  256. }else{
  257. //在单位时间内未播报过
  258. canbobao = true;
  259. }
  260. }
  261. if(canbobao){
  262. String lastStationCode = RedisUtils.getCacheObject(StringUtils.format("car_{}_last_bb_station",carInfoVo1.getCarNum()));
  263. if(lastStationCode!=null && lastStationCode.equals(station.getDictCode().toString())){
  264. canbobao = false;
  265. }
  266. }
  267. if(canbobao){
  268. //设置播报站播报时间
  269. RedisUtils.setCacheObject(StringUtils.format("car_{}_{}_station",carInfoVo1.getCarNum(),station.getDictCode()),DateUtil.current());
  270. //设置播报站
  271. RedisUtils.setCacheObject(StringUtils.format("car_{}_last_bb_station",carInfoVo1.getCarNum()),station.getDictCode().toString());
  272. //满足条件播报(led or 广播)
  273. String message = StringUtils.format(text, carInfoVo1.getCarNum(),station.getDictLabel());
  274. if(StringUtils.isNotEmpty(station.getRemark())){
  275. List<JSONObject> devicedatas = JSONUtil.parseArray( station.getRemark()).toList(JSONObject.class);
  276. Map<String,String> o = new HashMap<>();
  277. o.put("station",station.getDictLabel());
  278. o.put("time",DateUtil.now());
  279. o.put("carNum",carInfoVo1.getCarNum());
  280. o.put("type",carInfoVo1.getCarType());
  281. o.put("msg",message);
  282. CamelDataUtil.setPlayList(carInfoVo1.getCarNum(),o);
  283. for (JSONObject i :devicedatas) {
  284. if(i.getStr("type").equals("led")){
  285. MessageUtils.sendLed(i.getStr("code"), message);
  286. }
  287. if(i.getStr("type").equals("tts")){
  288. MessageUtils.sendTTs(i.getStr("code"), message);
  289. }
  290. }
  291. }
  292. }
  293. }else{
  294. continue;
  295. }
  296. }catch (Exception e){
  297. log.error("--------5座车计算经纬错误-------------");
  298. log.error(e.getMessage());
  299. log.error("-------5座车计算经纬错误--------------");
  300. }
  301. }
  302. }
  303. }
  304. }
  305. }
  306. }
  307. }
  308. });
  309. }
  310. public void ReciveData(String body, Exchange exchange){
  311. if(exchange.getMessage().getHeaders().get("CamelMqttTopic").toString().contains("gps")){
  312. String devicecode = exchange.getMessage().getHeaders().get("CamelMqttTopic").toString().split("/")[3];
  313. GpsData gpsData = new GpsData();
  314. gpsData.setDevicecode(devicecode);
  315. gpsData.setLat(JSONUtil.parseObj(body).getDouble("LAT"));
  316. gpsData.setLng(JSONUtil.parseObj(body).getDouble("LNG"));
  317. gpsData.setAlt(JSONUtil.parseObj(body).getDouble("ALT"));
  318. gpsData.setSpeed(JSONUtil.parseObj(body).getDouble("SPD"));
  319. if(JSONUtil.parseObj(body).getDouble("SPD")>0){
  320. processGpsData(gpsData);
  321. }
  322. }
  323. log.info("body:{}",body);
  324. }
  325. public void ReciveTcpData(String body, Exchange exchange) throws UnsupportedEncodingException {
  326. StringBuilder countdatastr= new StringBuilder("");
  327. JSONArray data= JSONUtil.parseArray(body);
  328. for (int i = 0; i < data.size(); i++) {
  329. if( data.get(i) instanceof Integer){
  330. countdatastr.append((char)(((Integer) data.get(i)).byteValue()&0xff));
  331. }
  332. }
  333. if(StrUtil.isNotEmpty(countdatastr.toString())){
  334. try{
  335. this.SendData("direct:senddev", countdatastr.toString(), "devtype","-");
  336. }catch (Exception e){
  337. }
  338. try{
  339. JSONObject countdata = JsonUtils.parseObject(countdatastr.toString(), JSONObject.class);
  340. String sn = countdata.getStr("sn");
  341. String type = countdata.getStr("type");
  342. Long time = countdata.getLong("time");
  343. try {
  344. NettyChannelHandlerContext topic = NettyChannelHandlerContextMapCache.ChannelMapCache.get(((ChannelHandlerContext) (exchange.getIn().getHeader("CamelNettyChannelHandlerContext"))).channel().toString());
  345. if (topic != null) {
  346. topic.setTag(sn);
  347. }
  348. RedisUtils.setCacheObject(StringUtils.format("count_{}", sn), DateUtil.now());
  349. }catch (Exception e){
  350. }
  351. Integer in = 0;
  352. Integer out = 0;
  353. Long iCreatedTime = 0L;
  354. if(type.equals("count")){
  355. //获取数据in out
  356. JSONArray inoutarry = ((JSONObject)(countdata.getJSONArray("data").get(0))).getJSONArray("count");
  357. for (int i = 0; i < inoutarry.size(); i++) {
  358. if(((JSONObject)inoutarry.get(i)).getStr("name").equals("d1")){
  359. in = ((JSONObject)inoutarry.get(i)).getInt("in");
  360. out = ((JSONObject)inoutarry.get(i)).getInt("out");
  361. break;
  362. }
  363. }
  364. iCreatedTime = ((JSONObject)(countdata.getJSONArray("data").get(0))).getLong("iCreatedTime");
  365. if(iCreatedTime*1000>DateUtil.current()-24*3600*1000 && iCreatedTime*1000<DateUtil.current()+24*3600*1000){
  366. //正确的时间
  367. CountData countData = new CountData();
  368. countData.setIncount(in);
  369. countData.setOutcount(out);
  370. countData.setDevicecode(sn);
  371. countData.setTslong(iCreatedTime*1000);
  372. countDataService.insertData(countData);
  373. }else{
  374. log.error("{}:时间错误",iCreatedTime);
  375. }
  376. //存储数据
  377. // log.info("{},{},{},{},{}",sn,type,in,out,iCreatedTime);
  378. }
  379. //组织返回数据
  380. JSONObject result = new JSONObject();
  381. result.put( "sn" , sn) ;
  382. result.put("type", type) ;
  383. if(type.equals("heart")){
  384. JSONObject sub = new JSONObject() ;
  385. sub.put("time", time) ;
  386. result.put("data", sub ) ;
  387. }else{
  388. result.put("time", time ) ;
  389. }
  390. NettyChannelHandlerContext ctx = ChannelMapCache.get(((ChannelHandlerContext)exchange.getIn().getHeader("CamelNettyChannelHandlerContext")).channel().toString());
  391. ByteBuf buf = Unpooled.copiedBuffer(JsonUtils.toJsonString(result).getBytes(CharsetUtil.UTF_8));
  392. ctx.getChannelHandlerContext().writeAndFlush(buf);
  393. }catch (Exception e){}
  394. }
  395. }
  396. // public static void main(String[] args) {
  397. // String ss = "{\"pathLine\": [{\"order\": 1, \"location\": \"119.807462,26.958413\", \"planInTime\": \"00:15:00\", \"planOutTime\": \"01:15:00\", \"stationName\": \"松罗乡\"}, {\"order\": 2, \"location\": \"119.723653,26.841206\", \"planInTime\": \"00:30:00\", \"planOutTime\": \"01:15:00\", \"stationName\": \"福安客运站\"}, {\"order\": 3, \"location\": \"119.852881,26.817088\", \"planInTime\": \"01:15:00\", \"planOutTime\": \"04:15:00\", \"stationName\": \"姚澳村\"}], \"driverInfo\": 2, \"attendantInfo\": \"1763485590079639554\"}";
  398. // JSONArray lines = JSONUtil.parseObj(ss).getJSONArray("pathLine");
  399. // List<JSONObject> lines1 = lines.toList(JSONObject.class);
  400. // lines1.sort(Comparator.comparingInt((JSONObject o) -> o.getInt("order")));
  401. // System.out.println(lines1.get(0).toStringPretty());
  402. // }
  403. }