CamelDataUtil.java 25 KB

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