package com.ssi.model; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.google.common.base.Splitter; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.ssi.constant.RedisKey; import com.ssi.constant.VehicleConstant; import com.ssi.constant.enums.VmsTosOrderStatusEnum; import com.ssi.entity.VmsIndividuationConfig; import com.ssi.entity.dto.Point; import com.ssi.mapper.VmsIndividuationConfigMapper; import com.ssi.utils.ConfigUtils; import com.ssi.utils.FieldUtil; import com.ssi.utils.JsonUtil; import com.ssi.utils.VehicleDataUtil; import com.sun.prism.shader.Solid_TextureYV12_AlphaTest_Loader; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.apache.commons.math3.util.MathUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import java.math.BigDecimal; import java.text.DecimalFormat; import java.time.LocalDateTime; import java.time.temporal.ChronoUnit; import java.util.*; import java.util.stream.Collectors; /** * description: * * @author WangHD * @version 1.0 * @date 2020/3/20 0020 9:59 */ @Component @EnableScheduling @Slf4j public class VehicleLatestDataModel { @Value("${vehicle.latestData.redis.prefix:ivccs:vms:vehicle:latest}") private String latestRedisKeyPrefix; @Value("${vehicle.latestData.redis.postfix:harbor_D00A}") private String latestRedisKeyPostfix; @Value("${vehicle.latestData.redis.001postfix:harbor_D001}") private String latestRedisKeyD001Postfix; @Value("${vehicle.latestData.redis.002postfix:harbor_D002}") private String latestRedisKeyD002Postfix; @Value("${vehicle.status.redis.keyPrefix:harbor:vehicle:online}") private String statusRedisKeyPrefix; @Value("${order.latestOrderKeyPrefix:harbor:command:status}") private String latestOrderKeyPrefix; @Value("${harbor.command.vehicle_path_keyPrefix}") private String vehiclePathKeyPrefix; @Value("${harbor.vehicle.confirm_status_prefix}") private String harborVehicleConfirmStatusPrefix; @Value("${vehicle.cache.key:ivccs:vms:vehicle:cache}") private String vehicleCacheKey; @Value("${harbor.remote.emergencyParking}") private String vehicleEmergencyCacheKey; @Value("${vehicle.latestData.redis.preLocationFix}") private String preLocationFix; @Value("${harbor.command.info_key:harbor:command:vin:info}") private String infoKeyPrefix; @Value("${harbor.vehicle.onstatusKey:harbor:vehicle:onstatus}") private String onstatusKey; @Value("${harbor.vehicle.onlineKey:harbor:vehicle:online}") private String onlineKey; @Value("${harbor.command.twenty_foot:harbor:command:twenty_foot:order_latest_five}") private String orderLatestFiveKey; @Value("${client.onlineTime:60000}") private Long onlineTime; /** * 用于判断在这个时长里面的任务是否推送到前端 */ @Value("${client.pushTime:1800000}") private Long pushTime; @Autowired private VehicleBaseInfoModel vehicleInfoModel; @Autowired private RedisDataModel singleNodeModel; @Autowired private RedisDataModel redisDataModel; @Autowired private VehicleDataUtil vehicleDataUtil; @Autowired private VmsIndividuationConfigMapper individuationConfigMapper; private static Map> vehicleStatusMap = Maps.newHashMap(); /** * 停车时经纬度跳变处理 */ private Map lastMap = Maps.newConcurrentMap(); private static Object STATUS_LOCK = new Object(); public List> getOnlineData(String key) { List> listMap = new ArrayList<>(); List keyList = Splitter.on(",").omitEmptyStrings().trimResults().splitToList(key); List keyList2 = Lists.newArrayList(keyList); if (!keyList.isEmpty()) { try { Set keySet = redisDataModel.keys(String.format("%s:*", latestRedisKeyPrefix)); Set filterVins = keySet.stream() .map(r -> r.replaceAll(String.format("%s:*", latestRedisKeyPrefix), "")) .collect(Collectors.toSet()); //取交集 有最新数据车辆 keyList.retainAll(filterVins); //取差集 无最新数据车辆 keyList2.removeAll(keyList); if (keyList.size() > 0) { //生成最新数据的Keys keyList = keyList.stream() .map(r -> String.format("%s:%s", latestRedisKeyPrefix, r)) .collect(Collectors.toList()); List mget = redisDataModel.mget(keyList.toArray(new String[keyList.size()])); int size = mget.size(); String vin; Integer status; Map record; Map statusMap; Map vehicleInfo; for (int i = 0; i < size; i++) { record = JsonUtil.jsonToMap(mget.get(i)); vin = String.valueOf(record.get("vin")); synchronized (STATUS_LOCK) { statusMap = vehicleStatusMap.get(vin); status = statusMap == null ? 0 : (Integer) statusMap.getOrDefault("state", 0); } if (1 == status) { record.put("isOnline", "在线"); //在线行驶中 Double speed = ConfigUtils.getAsDoubleWithDefault(record, "gpsSpeed", 0.0); if (speed > 0.0) { record.put("isOnline", "在线,行驶中"); } } else { record.put("isOnline", "离线"); } vehicleInfo = vehicleInfoModel.getVehicleBaseInfo(vin); if (vehicleInfo != null) { record.put("plateNo", vehicleInfo.get("plate_no")); record.put("vehicleType", vehicleInfo.get("vehicle_type")); } listMap.add(record); } } if (!keyList2.isEmpty()) { keyList2.stream().forEach(vin -> { Map record = Maps.newHashMap(); record.put("vin", vin); record.put("isOnline", "离线"); Map vehicleInfo = vehicleInfoModel.getVehicleBaseInfo(vin); if (vehicleInfo != null) { record.put("plateNo", vehicleInfo.get("plate_no")); record.put("vehicleType", vehicleInfo.get("vehicle_type")); } listMap.add(record); }); } } catch (Exception e) { log.error(String.format("读取%s失败", key), e); } } return listMap; } public Object getVehicleStatus(String vins, Integer status) { List> resultList = Lists.newArrayList(); try { List keys = getLatestDataKeys(vins, true); List recordJsons = redisDataModel.mget(keys.toArray(new String[keys.size()])); resultList = recordJsons.stream().map(json -> { Map record = JsonUtil.jsonToMap(json); String vin = (String) record.get("vin"); Integer online; synchronized (STATUS_LOCK) { Map statusMap = vehicleStatusMap.get(vin); online = statusMap == null ? 0 : (Integer) statusMap.getOrDefault("state", 0); } if (online == 1) { Double speed = ConfigUtils.getAsDoubleWithDefault(record, "speed", 0.0); if (speed > 0.0) { record.put("vehicleStatus", "在线,行驶中"); record.put("vehicleStatusCode", 2); } else { record.put("vehicleStatus", "在线"); record.put("vehicleStatusCode", 1); } } else { record.put("vehicleStatus", "离线"); record.put("vehicleStatusCode", 0); } return record; }).collect(Collectors.toList()); if (status != null && status >= 0 && status <= 2) { resultList = resultList.stream().filter(record -> { Integer vehicleStatusCode = ConfigUtils.getAsIntegerWithDefault(record, "vehicleStatusCode", -1); return status.equals(vehicleStatusCode); }).collect(Collectors.toList()); } } catch (Exception e) { log.error("查询车辆状态异常", e); } return resultList; } private List getLatestDataKeys(String vins, boolean emptyForAll) { List keys = Lists.newArrayList(); if (StringUtils.isNotBlank(vins)) { String[] split = vins.split(","); for (String vin : split) { keys.add(String.format("%s:%s", latestRedisKeyPrefix, vin.trim())); } } if (keys.isEmpty() && emptyForAll) { String prefix = String.format("%s:*", latestRedisKeyPrefix); keys.addAll(redisDataModel.keys(prefix)); } return keys; } private Map> readLatestStatusFromRedis(Map keysMap) { Map> res = Maps.newHashMap(); keysMap.entrySet().parallelStream().forEach(entry -> { //数据获取 String redisKey = entry.getValue(); // Map record = redisModel.getJson2Map(redisKey); Map record = new HashMap<>(); String state = redisDataModel.get(redisKey); if (StringUtils.isNotBlank(state)) { record.put("state", Integer.parseInt(state)); } res.put(entry.getKey(), record); }); return res; } @Scheduled(fixedRateString = "${spring.websocket.scheduled.time:1000}") public Map> allRealTimeStatus() { Map> res; String prefixStatus = String.format("%s:*", statusRedisKeyPrefix); Set keyStatus = redisDataModel.keys(prefixStatus); if (keyStatus != null && !keyStatus.isEmpty()) { Map keysMap = Maps.newHashMap(); keyStatus.stream().forEach(key -> { String vin = key.replace(String.format("%s:", statusRedisKeyPrefix), ""); keysMap.put(vin, key); }); res = readLatestStatusFromRedis(keysMap); } else { res = Maps.newHashMap(); } synchronized (STATUS_LOCK) { vehicleStatusMap = res; } return res; } public Map> allRealTimeData(boolean checkRepeat) { Map> res; //获取所有vin String prefix = String.format("%s:*", latestRedisKeyPrefix); Set keysUnResolveRepeat = redisDataModel.keys(prefix); Set vins = keysUnResolveRepeat.stream().map(key -> { key = key.replace(String.format("%s:", latestRedisKeyPrefix), ""); key = key.substring(0, key.indexOf("-")); return key; }).collect(Collectors.toSet()); //拼接所有类型key if (vins != null && !vins.isEmpty()) { Map> keysMap = Maps.newHashMap(); vins.stream().forEach(key -> { //判断车辆是否禁用 Map vehicleInfoRecord = redisDataModel.hgetJson2Map(vehicleCacheKey, key); if(vehicleInfoRecord == null || vehicleInfoRecord.get("status") == null || (Integer)vehicleInfoRecord.get("status") == 1){ return; } Map keyPreMap = Maps.newHashMap(); keyPreMap.put("vin", key); keyPreMap.put("latestKey", String.format("%s:%s-%s", latestRedisKeyPrefix, key, latestRedisKeyPostfix)); keyPreMap.put("d001Key", String.format("%s:%s-%s", latestRedisKeyPrefix, key, latestRedisKeyD001Postfix)); keyPreMap.put("d002Key", String.format("%s:%s-%s", latestRedisKeyPrefix, key, latestRedisKeyD002Postfix)); keyPreMap.put("orderKey", String.format("%s:%s", latestOrderKeyPrefix, key)); keyPreMap.put("vehiclePathKey", String.format("%s:%s", vehiclePathKeyPrefix, key)); keyPreMap.put("threeConfirmStatus", String.format("%s:%s", harborVehicleConfirmStatusPrefix, key)); keyPreMap.put("emergencyTypeKey", String.format("%s:%s", vehicleEmergencyCacheKey, key)); keyPreMap.put("onstatusKey",String.format("%s:%s",onstatusKey,key)); keyPreMap.put("onlineKey",String.format("%s:%s",onlineKey,key)); keyPreMap.put("orderLatestFiveKey", String.format("%s:%s", "harbor:command:twenty_foot:order_latest_five", key));//双小箱数据 keysMap.put(key, keyPreMap); }); res = readLatestDataFromRedis(keysMap, checkRepeat); } else { res = Maps.newHashMap(); } return res; } public Map> getVehicleRunData() { Map> res = Maps.newHashMap(); //获取所有vin String prefix = String.format("%s:*", latestRedisKeyPrefix); Set keysUnResolveRepeat = redisDataModel.keys(prefix); Set vins = keysUnResolveRepeat.stream().map(key -> { key = key.replace(String.format("%s:", latestRedisKeyPrefix), ""); key = key.substring(0, key.indexOf("-")); return key; }).collect(Collectors.toSet()); //拼接所有类型key if (vins != null && !vins.isEmpty()) { vins.stream().forEach(key -> { //判断车辆是否禁用 Map vehicleInfoRecord = redisDataModel.hgetJson2Map(vehicleCacheKey, key); if(vehicleInfoRecord == null || vehicleInfoRecord.get("status") == null || (Integer)vehicleInfoRecord.get("status") == 1){ return; } String latestKey = String.format("%s:%s-%s", latestRedisKeyPrefix, key, latestRedisKeyPostfix); Map record = redisDataModel.getJson2Map(latestKey); String emergencyParking = String.format("%s:%s", vehicleEmergencyCacheKey, key); Map emergencyStatusMap = redisDataModel.getJson2Map(emergencyParking); Integer emergencyStatus = 2; if (emergencyStatusMap != null) { emergencyStatus = (Integer) emergencyStatusMap.get("emergencyStatus"); } if (record != null && !record.isEmpty() && checkAndAppendStatus(record) == 1) { record.put("vehicleNum", vehicleInfoRecord == null ? null : vehicleInfoRecord.get("vehicleNum")); record.put("emergencyStatus", emergencyStatus); res.put(key,record); } }); } return res; } public Map> readLatestDataFromRedis(Map> keysMap, boolean checkRepeat) { Map> res = Maps.newHashMap(); keysMap.entrySet().parallelStream().forEach(entry -> { Map redisKeyMap = entry.getValue(); String vin = redisKeyMap.get("vin"); String latestKey = redisKeyMap.get("latestKey"); String orderKey = redisKeyMap.get("orderKey"); String vehiclePathKey = redisKeyMap.get("vehiclePathKey"); String threeConfirmStatusKey = redisKeyMap.get("threeConfirmStatus"); String emergencyTypeKey = redisKeyMap.get("emergencyTypeKey"); String obuStatus = redisDataModel.get(redisKeyMap.get("onstatusKey")); String onlineStatus = redisDataModel.get(redisKeyMap.get("onlineKey")); String craneNo = redisDataModel.get(RedisKey.VEHICLE_TO_CRANE.getKeyPrefix().concat(vin)); orderLatestFiveKey=redisKeyMap.get("orderLatestFiveKey"); String infoKey=String.format("%s:%s",infoKeyPrefix,vin); String vehicleMap = redisDataModel.get(infoKey); vehicleMap = StringUtils.isNotBlank(vehicleMap) ? vehicleMap :singleNodeModel.get(infoKey); Integer vehicleType = 1; //1:X69B ,2:X69C,3:有人集卡两秒 if(vehicleMap != null) {//判断redis是否存在,不存在则查询数据库 JSONObject jsonObject = JSONObject.parseObject(vehicleMap); vehicleType =jsonObject.getInteger("vehicleType"); } Map record = redisDataModel.getJson2Map(latestKey); //record 不为空, 且状态为在线状态 if(vehicleType == 3){ record = redisDataModel.getJson2Map(latestKey); if (record != null && !record.isEmpty() && checkAndAppendStatus(record) == 1) { Map newRecord=Maps.newHashMap(); record.remove("originalMsg"); Map vehicleInfoRecord = singleNodeModel.hgetJson2Map(vehicleCacheKey, vin); String vehiclePath = null; if (!repeatCheck(entry.getKey(), record, checkRepeat)) { double[] locaction = parseLocation(record); if (locaction != null) {//有人集卡暂时不需要任务描述,可以不用推送到前端,减少前端缓存,以后需要可和前端商量需要的字段 newRecord.put("isOnline",1); newRecord.put("clientStatus",record.get("clientStatus")); newRecord.put("vin",record.get("vin")); newRecord.put("vehicleType",vehicleInfoRecord == null ? vehicleType : vehicleInfoRecord.get("vehicleType")); newRecord.put("vehicleNum", vehicleInfoRecord == null ? null : vehicleInfoRecord.get("vehicleNum")); newRecord.put("latitude",record.get("latitude")); newRecord.put("preLocation",record.get("preLocation")); newRecord.put("longitude",record.get("longitude")); newRecord.put("gear",record.get("gear")); newRecord.put("altitude",record.get("altitude")); newRecord.put("speed",record.get("speed")); newRecord.put("location", locaction); newRecord.put("collectTime",record.get("collectTime")); newRecord.put("soc",record.get("soc")); newRecord.put("totalMile",record.get("totalMile")); res.put(entry.getKey(), newRecord); } } } }else if (record != null && !record.isEmpty()){ Map newRecord=Maps.newHashMap(); record.remove("originalMsg"); Map orderRecord = redisDataModel.getJson2Map(orderKey); Map vehicleInfoRecord = redisDataModel.hgetJson2Map(vehicleCacheKey, vin); Map vehicleEmergencyRecord = redisDataModel.getJson2Map(emergencyTypeKey); Map newOrderRecord=new HashMap<>(); newRecord.put("stopExceed",0); if (!repeatCheck(entry.getKey(), record, checkRepeat)) { double[] location = parseLocation(record); if (location == null){ location = new double[]{119.968264,24.458783};//117.9682640,24.4587837 newOrderRecord.put("msg","定位偏移,超出范围"); // newRecord.put("stopExceed",1); } if(orderRecord != null){ int status = (Integer) orderRecord.get("status"); //车辆到达目的地之后不推送规划路径;判断任务是否过期,过期之后不推送路径规划 if ((status == VehicleConstant.PATH_PLANNING || status == VehicleConstant.START_TASK) && (System.currentTimeMillis() - Long.valueOf(orderRecord.get("collectTime").toString()) < VehicleConstant.ORDER_EXPIRATION_TIME)){ String vehiclePath = redisDataModel.get(vehiclePathKey); //添加任务规划点 newOrderRecord.put("vehiclePath", JSONObject.parse(vehiclePath)); } //计算任务是否等待超时 BigDecimal taskTime = calTime(orderRecord.get("startTime"),orderRecord.get("endTime")); if ((status == VehicleConstant.OBU_RECEIVED || status == VehicleConstant.ADCU_RECEIVED) && taskTime != null && taskTime.compareTo(BigDecimal.valueOf(180)) > 0){ newOrderRecord.put("msg","任务等待超时"); } //判断到达目的地车辆,是否状态异常 Integer subTaskType = Objects.isNull(orderRecord.get("subTaskType")) ? null : (Integer) orderRecord.get("subTaskType"); Long lastTime = Objects.nonNull(orderRecord.get("updateTime")) ? (Long) orderRecord.get("updateTime") : null; Long currentTime = System.currentTimeMillis(); VmsIndividuationConfig overtimeValue = individuationConfigMapper.selectOne(new LambdaUpdateWrapper().eq(VmsIndividuationConfig::getConfigKey,"wait_overtime_energy_key")); Integer valueType = 300000; if(Objects.nonNull(overtimeValue)){ valueType = 60000*Integer.valueOf(overtimeValue.getConfigValue()); } /* if(status==3&¤tTime-lastTime>valueType&&(subTaskType == null || subTaskType == 3 || subTaskType == 4 || subTaskType == 6 || subTaskType == 8 || subTaskType == 10 || subTaskType == 12)){ newRecord.put("stopExceed",1); }*/ orderRecord.put("estimatedArriveTime", LocalDateTime.now().plus(10, ChronoUnit.MINUTES)); //添加任务描述 String description = vehicleDataUtil.generateOrderDescription(orderRecord); //判断subTaskType:0去缓冲区1,2 去扭锁站 其他用查询出来的 if (Objects.nonNull(subTaskType)){//判断subTaskType redis是否存在 // int subTaskType = (Integer) orderRecord.get("subTaskType"); if (subTaskType == 0){ newOrderRecord.put("orderDescription","去缓冲区"); }else if(subTaskType ==1 || subTaskType==2){ newOrderRecord.put("orderDescription","去扭锁站"); }else{ newOrderRecord.put("orderDescription",description); } }else{ newOrderRecord.put("orderDescription",description); } //设置双小箱任务数据取第二小箱状态 0:不生效,1生效 newOrderRecord.put("doubleBoxStatus",0); Object containerInfos = orderRecord.get("containerInfos"); if(Objects.nonNull(containerInfos)){ JSONArray containerInfos1 = (JSONArray) containerInfos; if(containerInfos1.size()>1&&status==49&&orderRecord.get("taskLocationType")!=null&&(Integer) orderRecord.get("taskLocationType")==1){//双小箱任务&&停稳锁死&&目的地是堆场 newOrderRecord.put("doubleBoxStatus",1); } } newOrderRecord.put("containerInfos", orderRecord.get("containerInfos")==null?new JSONArray():orderRecord.get("containerInfos")); newOrderRecord.put("vehicleLocation",orderRecord.get("vehicleLocation")==null?"":orderRecord.get("vehicleLocation")); newOrderRecord.put("vehicleTaskLabel",orderRecord.get("vehicleTaskLabel") == null ?"":orderRecord.get("vehicleTaskLabel")); newOrderRecord.put("taskType",orderRecord.get("taskType") == null ?"":orderRecord.get("taskType")); newOrderRecord.put("taskNo",orderRecord.get("taskNo")==null?"":orderRecord.get("taskNo")); newOrderRecord.put("vin",orderRecord.get("vin")==null?"":orderRecord.get("vin")); newOrderRecord.put("longitude",orderRecord.get("longitude") == null?"":orderRecord.get("longitude")); newOrderRecord.put("vehicleTaskType",orderRecord.get("vehicleTaskType") == null?"":orderRecord.get("vehicleTaskType")); newOrderRecord.put("targetType",orderRecord.get("targetType") == null?"":orderRecord.get("targetType")); newOrderRecord.put("lockLabel",orderRecord.get("lockLabel") == null?"":orderRecord.get("lockLabel") ); newOrderRecord.put("status",orderRecord.get("status") == null?"":orderRecord.get("status")); newOrderRecord.put("taskLocationType",orderRecord.get("taskLocationType")==null ? "" : orderRecord.get("taskLocationType")); newOrderRecord.put("collectTime",orderRecord.get("collectTime")== null?"":orderRecord.get("collectTime")); newOrderRecord.put("taskSource",orderRecord.get("taskSource")== null?"":orderRecord.get("taskSource")); newOrderRecord.put("goShipCraneLaneStatus",orderRecord.get("goShipCraneLaneStatus")== null?"":orderRecord.get("goShipCraneLaneStatus")); newOrderRecord.put("msg",orderRecord.get("msg")== null?"":orderRecord.get("msg")); newOrderRecord.put("parkingAreaNo",orderRecord.get("parkingAreaNo")); }else{//没值的话也要给前端空字符串不然前端会崩 newOrderRecord.put("vehicleLocation",""); newOrderRecord.put("vehicleTaskLabel",""); newOrderRecord.put("taskType",""); newOrderRecord.put("taskNo",""); newOrderRecord.put("vin",""); newOrderRecord.put("longitude",""); newOrderRecord.put("vehicleTaskType",""); newOrderRecord.put("targetType",""); newOrderRecord.put("lockLabel",""); newOrderRecord.put("status",""); newOrderRecord.put("taskLocationType",""); newOrderRecord.put("vehiclePath",""); newOrderRecord.put("collectTime",""); newOrderRecord.put("taskSource",""); newOrderRecord.put("containerInfos", new JSONArray()); newOrderRecord.put("doubleBoxStatus",0); newOrderRecord.put("parkingAreaNo",""); } //onlineStatus这个数据是在redis里面,判断是否在线方法1上线0下线 if ((onlineStatus != null && onlineStatus.equals("1")&&obuStatus!=null&&obuStatus.equals("1"))){ newRecord.put("isOnline",1); }else{ newRecord.put("isOnline",0); } newRecord.put("clientStatus",record.get("clientStatus")); newRecord.put("vin",record.get("vin")); newRecord.put("craneNo",StringUtils.isNotBlank(craneNo)?craneNo:""); newRecord.put("vehicleType",vehicleInfoRecord == null ? "" : vehicleInfoRecord.get("vehicleType")); newRecord.put("vehicleNum", vehicleInfoRecord == null ? "" : vehicleInfoRecord.get("vehicleNum")); newRecord.put("gear",record.get("gear")); newRecord.put("altitude",record.get("altitude")); newRecord.put("speed",record.get("speed")); //判断当前的任务时间是否超过配置的时长,超过不推送数据 newRecord.put("direction",record==null?"":record.get("direction")); if (!"".equals(newOrderRecord.get("collectTime")) && checkTime(newOrderRecord) == 1) { newRecord.put("orderData", newOrderRecord); newRecord.put("status", VmsTosOrderStatusEnum.find(Integer.valueOf(newOrderRecord.get("status")+""))==null?"":VmsTosOrderStatusEnum.find(Integer.valueOf(newOrderRecord.get("status")+"")).getDescription()); Integer vehicleTaskLabel = (Integer)newOrderRecord.get("vehicleTaskLabel"); Object o = Objects.isNull(vehicleTaskLabel) ? newRecord.put("vinFlag", 1) : (1==vehicleTaskLabel ? newRecord.put("vinFlag", 3) : (2==vehicleTaskLabel ? newRecord.put("vinFlag", 4) : newRecord.put("vinFlag", 5))); } else { newRecord.put("orderData", ""); newRecord.put("craneNo",""); newRecord.put("status","-");//没有订单就没有订单状态 Object o = (Integer) newRecord.get("isOnline") == 0 ? newRecord.put("vinFlag", 0) : newRecord.put("vinFlag", 2); } newRecord.put("collectTime",record.get("collectTime")); newRecord.put("soc",record.get("soc")); //判断车辆的速度是否为0,速度为0的情况,判断车辆位置信息 newRecord.put("location", location); //以上的字段都是重新封装成前端需要的字段,如需要其他字段可在record这里面获取,orderRecord这个map里面是redis里面全部的任务信息字段 res.put(entry.getKey(), newRecord); } } }); return res; } private BigDecimal calTime(Object startTime, Object endTime) { if (startTime != null) { Long startDate = (Long) startTime; BigDecimal timeSeconds = null; if(endTime == null){ timeSeconds = new BigDecimal(System.currentTimeMillis() - startDate).divide(new BigDecimal(1000), 0, BigDecimal.ROUND_CEILING); }else{ Long endDate = (Long) endTime; timeSeconds = new BigDecimal(endDate - startDate).divide(new BigDecimal(1000), 0, BigDecimal.ROUND_CEILING); } return timeSeconds; } return null; } private String formatTime(BigDecimal seconds) { int sec = seconds.intValue(); if(sec < 0 ){ return "0秒"; } StringBuilder sb = new StringBuilder(); if (sec < 60) { sb.append(seconds + "秒"); }else if (sec >= 60 && sec < 3600) { int m = sec/60; int s = sec%60; sb.append(m + "分"); if(s > 0){ sb.append(s + "秒"); } }else { int h = sec/3600; int m = (sec%3600)/60; int s = (sec%3600)%60; sb.append(h + "小时"); if(m > 0){ sb.append(m + "分"); } if(s > 0){ sb.append(s + "秒"); } } return sb.toString(); } private boolean repeatCheck(String vin, Map record, boolean checkRepeat) { boolean repeat = false; if (checkRepeat) { Object speed = record.get("speed"); // if(speed != null && (Float)speed <= 0){ // return false; // } Object collectTime = record.get("collectTime"); Object latitude = record.get("latitude"); Object longitude = record.get("longitude"); String format = String.format("%s,%s,%s", collectTime, latitude, longitude); repeat = (format.equals(lastMap.get(vin))); if (!repeat) { lastMap.put(vin, format); } } // return repeat; return false; } private int checkAndAppendStatus(Map record) { Integer status; synchronized (STATUS_LOCK) { Map statusMap = vehicleStatusMap.get(record.get("vin")); status = statusMap == null ? -1 : (Integer) statusMap.getOrDefault("state", -1); } Long time = ConfigUtils.getAsLong(record, "collectTime"); /** 检查终端状态*/ boolean dataOnline = (time != null && System.currentTimeMillis() - time < onlineTime); boolean isOnline = dataOnline; //&& status == 1; record.put("clientStatus", isOnline ? "在线" : "离线"); record.put("state", isOnline ? 1 : 0); return isOnline ? 1 : 0; } /** * 检查当前时间是否在半个小时内时间orderData里面的字段 * */ private int checkTime(Map record) { Long time = ConfigUtils.getAsLong(record, "collectTime"); /** 检查当前时间是否在半个小时内*/ boolean dataOnline = (time != null && System.currentTimeMillis() - time < pushTime); return dataOnline ? 1 : 0; } private double[] parseLocation(Map record) { Double longitude = ConfigUtils.getAsDoubleWithDefault(record, "longitude", 0.0); Double latitude = ConfigUtils.getAsDoubleWithDefault(record, "latitude", 0.0); double[] location = null; //中国境内 if (longitude < 135 && longitude >= 73 && latitude >= 4 && latitude < 53) { BigDecimal longitudeDecimal = new BigDecimal(longitude); longitudeDecimal = longitudeDecimal.setScale(6, BigDecimal.ROUND_DOWN); BigDecimal latitudeDecimal = new BigDecimal(latitude); latitudeDecimal= latitudeDecimal.setScale(6, BigDecimal.ROUND_DOWN); location = new double[]{longitudeDecimal.doubleValue(), latitudeDecimal.doubleValue()}; } else { // log.warn(String.format("记录中的经纬度不在国内: %s", record)); } return location; } public String getLatestRedisKeyPrefix() { return latestRedisKeyPrefix; } public String getLatestRedisKeyPostfix() { return latestRedisKeyPostfix; } public String getLatestRedisKeyD001Postfix() { return latestRedisKeyD001Postfix; } public String getLatestRedisKeyD002Postfix() { return latestRedisKeyD002Postfix; } public RedisDataModel getRedisModel() { return redisDataModel; } public String getStatusRedisKeyPrefix() { return statusRedisKeyPrefix; } public VehicleBaseInfoModel getVehicleInfoModel() { return vehicleInfoModel; } }