| package com.xzx.gc.order.service;  | 
|   | 
|   | 
| import cn.hutool.core.bean.BeanUtil;  | 
| import cn.hutool.core.collection.CollUtil;  | 
| import cn.hutool.core.convert.Convert;  | 
| import cn.hutool.core.thread.ThreadUtil;  | 
| import cn.hutool.core.util.NumberUtil;  | 
| import cn.hutool.core.util.StrUtil;  | 
| import cn.hutool.json.JSONArray;  | 
| import cn.hutool.json.JSONObject;  | 
| import cn.hutool.json.JSONUtil;  | 
| import com.xzx.gc.common.Result;  | 
| import com.xzx.gc.common.constant.Constants;  | 
| import com.xzx.gc.common.constant.ExceptionEnum;  | 
| import com.xzx.gc.common.constant.OrderEnum;  | 
| import com.xzx.gc.common.constant.RedisKeyConstant;  | 
| import com.xzx.gc.common.dto.gdmap.GdReverseGEODto;  | 
| import com.xzx.gc.common.dto.gdmap.UploadTraceDto;  | 
| import com.xzx.gc.common.dto.gdmap.UploadTraceLocationDto;  | 
| import com.xzx.gc.common.utils.RedisUtil;  | 
| import com.xzx.gc.common.utils.gdmap.GdTraceUtil;  | 
| import com.xzx.gc.entity.CityPartner;  | 
| import com.xzx.gc.entity.OtherUserInfo;  | 
| import com.xzx.gc.entity.PartnerTrace;  | 
| import com.xzx.gc.entity.UserTraceInfo;  | 
| import com.xzx.gc.order.dto.TraceAllDto;  | 
| import com.xzx.gc.order.dto.TraceLocationDto;  | 
| import com.xzx.gc.order.dto.TraceUploadDto;  | 
| import lombok.extern.slf4j.Slf4j;  | 
| import org.springframework.beans.factory.annotation.Autowired;  | 
| import org.springframework.stereotype.Service;  | 
| import org.springframework.transaction.annotation.Transactional;  | 
|   | 
| import java.math.RoundingMode;  | 
| import java.util.ArrayList;  | 
| import java.util.Comparator;  | 
| import java.util.Iterator;  | 
| import java.util.List;  | 
| import java.util.stream.Collectors;  | 
|   | 
|   | 
| @Service  | 
| @Transactional  | 
| @Slf4j  | 
| public class TraceService {  | 
|   | 
|     @Autowired  | 
|     private PartnerTraceService partnerTraceService;  | 
|   | 
|   | 
|     @Autowired  | 
|     private RedisUtil redisUtil;  | 
|   | 
|     @Autowired  | 
|     private OtherUserService otherUserService;  | 
|   | 
|     @Autowired  | 
|     private UserTraceInfoService userTraceInfoService;  | 
|   | 
|   | 
|     public Result upload(TraceAllDto traceAllDto){  | 
|         List<TraceUploadDto> list = traceAllDto.getList();  | 
|   | 
|         String userType=null;  | 
|         String type=traceAllDto.getType();  | 
|         //兼容原来的接口 自定义负值类型  | 
|         if(OrderEnum.回收员全天轨迹.getValue().equals(type)){  | 
|             userType=Constants.DEFAULT_ID;  | 
|         }  | 
|   | 
|   | 
|         String userId = traceAllDto.getUserId();  | 
|         //删除轨迹为空的数据  | 
|         for (Iterator<TraceUploadDto> iterator = list.iterator(); iterator.hasNext(); ) {  | 
|             TraceUploadDto traceUploadDto=iterator.next();  | 
|             if(StrUtil.isBlank(traceUploadDto.getTrids())){  | 
|                 iterator.remove();  | 
|             }  | 
|         }  | 
|   | 
|         //删除轨迹点为空的数据并处理经纬度  | 
|         if(CollUtil.isNotEmpty(list)){  | 
|             for (Iterator<TraceUploadDto> iterator = list.iterator(); iterator.hasNext(); ) {  | 
|                 TraceUploadDto traceUploadDto =  iterator.next();  | 
|                 List<TraceLocationDto> locations = traceUploadDto.getLocations();  | 
|                 for (Iterator<TraceLocationDto> iterator2 = locations.iterator(); iterator2.hasNext(); ) {  | 
|                     TraceLocationDto next =  iterator2.next();  | 
|                     if(StrUtil.isBlank(next.getLatitude())||StrUtil.isBlank(next.getLongitude())){  | 
|                         iterator2.remove();  | 
|                     }else {  | 
|                         next.setLatitude(NumberUtil.roundStr(next.getLatitude(), 6, RoundingMode.DOWN));  | 
|                         next.setLongitude(NumberUtil.roundStr(next.getLongitude(), 6, RoundingMode.DOWN));  | 
|                     }  | 
|                 }  | 
|   | 
|                 if(CollUtil.isEmpty(locations)){  | 
|                     iterator.remove();  | 
|                 }  | 
|             }  | 
|         }  | 
|   | 
|         String redisKey=RedisKeyConstant.TRACE_ERROR;  | 
|         //轨迹错误次数  | 
|         int errNum=3;  | 
|         if(CollUtil.isNotEmpty(list)){  | 
|   | 
|             //更新回收员的实时轨迹  | 
|             if(OrderEnum.回收员全天轨迹.getValue().equals(type)) {  | 
|                 List<TraceLocationDto> locationList = new ArrayList<>();  | 
|                 for (TraceUploadDto traceUploadDto : list) {  | 
|                     locationList.addAll(traceUploadDto.getLocations());  | 
|                 }  | 
|                 TraceLocationDto traceLocationDto1 = locationList.stream().sorted(Comparator.comparing(TraceLocationDto::getTime).reversed()).collect(Collectors.toList()).get(0);  | 
|                 OtherUserInfo otherUserInfo = new OtherUserInfo();  | 
|                 otherUserInfo.setUserId(userId);  | 
|                 otherUserInfo.setLatitude(traceLocationDto1.getLatitude());  | 
|                 otherUserInfo.setLongitude(traceLocationDto1.getLongitude());  | 
|                 otherUserService.updateById(otherUserInfo);  | 
|             }  | 
|   | 
|             PartnerTrace partnerTrace = partnerTraceService.findByUserIdAndType(userId, userType);  | 
|             if (partnerTrace != null) {  | 
|                 String key = partnerTrace.getPartnerKey();  | 
|                 String sid = partnerTrace.getPartnerServiceId();  | 
|   | 
|                 OtherUserInfo byId = partnerTrace.getOtherUserInfo();  | 
|                 String tid;  | 
|                 if(OrderEnum.回收员全天轨迹.getValue().equals(type)){  | 
|                     tid=byId.getTerminalDayId();  | 
|                 }else {  | 
|                     tid = byId.getTerminalId();  | 
|                 }  | 
|   | 
|                 for (TraceUploadDto traceUploadDto : list) {  | 
|                     String trid = traceUploadDto.getTrids();  | 
|                     String redisField=userId+"_"+trid;  | 
|                     String hget = redisUtil.hget(redisKey, redisField);  | 
|                     if(StrUtil.isNotBlank(hget)&&Convert.toInt(hget)>=errNum){  | 
|                         continue;  | 
|                     }  | 
|                     UploadTraceDto uploadTraceDto = new UploadTraceDto();  | 
|                     uploadTraceDto.setKey(key);  | 
|                     uploadTraceDto.setSid(sid);  | 
|                     uploadTraceDto.setTid(tid);  | 
|                     uploadTraceDto.setTrid(trid);  | 
|                     JSONArray jsonArray = new JSONArray();  | 
|                     List<TraceLocationDto> locations = traceUploadDto.getLocations();  | 
|   | 
|                     //处理相邻的相同的点只传最新的那个  | 
|                     List<TraceLocationDto> collect = locations.stream().sorted(Comparator.comparing(TraceLocationDto::getTime)).collect(Collectors.toList());  | 
|                     List<TraceLocationDto> list2 = new ArrayList<>();  | 
|                     list2.add(collect.get(0));  | 
|                     for(int i=1;i<collect.size();i++) {  | 
|   | 
|                         TraceLocationDto trackDetailResultDto1 = collect.get(i);  | 
|                         String address = trackDetailResultDto1.getAddress();  | 
|   | 
|                         //取list集合的最后1个进行地址比较  | 
|                         TraceLocationDto trackDetailResultDto2 = list2.get(list2.size() - 1);  | 
|   | 
|                         String address1 = trackDetailResultDto2.getAddress();  | 
|   | 
|                         if (!address.equals(address1)) {  | 
|                             list2.add(trackDetailResultDto1);  | 
|                         } else {  | 
|                             BeanUtil.copyProperties(trackDetailResultDto1,trackDetailResultDto2);  | 
|                         }  | 
|                     }  | 
|   | 
|                     //上传轨迹点  | 
|                     for (TraceLocationDto traceLocationDto : list2) {  | 
|                         UploadTraceLocationDto uploadTraceLocationDto = new UploadTraceLocationDto();  | 
|                         String location = traceLocationDto.getLongitude() + "," + traceLocationDto.getLatitude();  | 
|                         uploadTraceLocationDto.setLocation(location);  | 
|                         uploadTraceLocationDto.setLocatetime(traceLocationDto.getTime());  | 
|                         JSONObject jsonObject = new JSONObject();  | 
|                         GdReverseGEODto gdReverseGEODto = new GdReverseGEODto();  | 
|                         gdReverseGEODto.setLocation(location);  | 
|                         jsonObject.put("address",traceLocationDto.getAddress());  | 
|                         uploadTraceLocationDto.setProps(JSONUtil.toJsonStr(jsonObject));  | 
|                         jsonArray.add(JSONUtil.parseObj(uploadTraceLocationDto));  | 
|                     }  | 
|   | 
|                     if (jsonArray.size() > 0) {  | 
|                         uploadTraceDto.setPoints(JSONUtil.toJsonStr(jsonArray));  | 
|                         Result result = GdTraceUtil.uploadTrace(uploadTraceDto);  | 
|                         if(result.getCode()!=0){  | 
|                             if(StrUtil.isNotBlank(hget)){  | 
|                                 redisUtil.hset(redisKey,redisField,Convert.toStr(Convert.toInt(hget)+1));  | 
|                             }else {  | 
|                                 redisUtil.hset(redisKey,redisField,Convert.toStr(1));  | 
|                             }  | 
|                             log.warn("轨迹上传失败,ID:{},原因:{}",trid,result.getMsg());  | 
|                         }else {  | 
|                             if(StrUtil.isNotBlank(hget)) {  | 
|                                 redisUtil.hdel(redisKey, redisField);  | 
|                             }  | 
|                         }  | 
|                     }  | 
|                 }  | 
|   | 
|             }  | 
|         }else {  | 
|             return Result.error(Convert.toInt(ExceptionEnum.可忽略异常.getValue()),"轨迹数据为空");  | 
|         }  | 
|         return Result.success();  | 
|     }  | 
|   | 
|     /**  | 
|      * 修复高德服务  | 
|      */  | 
| //    public void fixService() {  | 
| //        List<CityPartner> byType = cityPartnerService.findByType(OrderEnum.合伙人.getValue());  | 
| //        int i=0;  | 
| //        for (CityPartner cityPartner : byType) {  | 
| //            i++;  | 
| //            String partnerId=cityPartner.getId().toString();  | 
| //            String key=cityPartner.getPartnerKey();  | 
| //            if(i==1) {  | 
| //                //只删一次 因为同一账号下的 Key可以查出所有service。  | 
| //                Result<JSONArray> service = GdTraceUtil.findService(key);  | 
| //                if (service.getCode() == 0) {  | 
| //                    JSONArray data = service.getData();  | 
| //                    for (Object result : data) {  | 
| //                        JSONObject jsonObject1= (JSONObject) result;  | 
| //                        String sid = jsonObject1.getStr("sid");  | 
| //                        String name = jsonObject1.getStr("name");  | 
| //                        GdTraceUtil.deleteService(key, sid);  | 
| //                    }  | 
| //  | 
| //                }  | 
| //            }  | 
| //            List<PartnerTrace> byPartnerId1 = partnerTraceService.findByPartnerId(partnerId);  | 
| //            List<OtherUserInfo> byPartnerId = otherUserService.findByPartnerId(partnerId);  | 
| //            for (PartnerTrace partnerTrace : byPartnerId1) {  | 
| //                Short partnerServiceType = partnerTrace.getPartnerServiceType();  | 
| //                if(1==Convert.toInt(partnerServiceType)){  | 
| //                    fixTerminalId(key,OrderEnum.回收员订单轨迹,partnerTrace,byPartnerId);  | 
| //                }else if(2==Convert.toInt(partnerServiceType)){  | 
| //                    fixTerminalId(key,OrderEnum.推广员全天轨迹,partnerTrace,byPartnerId);  | 
| //                }else if(3==Convert.toInt(partnerServiceType)){  | 
| //                    fixTerminalId(key,OrderEnum.回收员全天轨迹,partnerTrace,byPartnerId);  | 
| //                }  | 
| //  | 
| //            }  | 
| //        }  | 
| //  | 
| //        log.debug("修复高德服务成功");  | 
| //    }  | 
|   | 
|   | 
|     private void fixTerminalId(String key,OrderEnum orderEnum,PartnerTrace partnerTrace, List<OtherUserInfo> byPartnerId){  | 
|   | 
|         String extra="";  | 
|         Result service = GdTraceUtil.createService(key, key+"_"+orderEnum.name());  | 
|         if (service.getCode() == 0) {  | 
|             String serviceId = service.getData().toString();  | 
|             //创建自定义字段  | 
|             GdTraceUtil.createTraceProp(key,serviceId,"address","string");  | 
|             //更新服务id  | 
|             PartnerTrace obj=new PartnerTrace();  | 
|             obj.setId(partnerTrace.getId());  | 
|             obj.setPartnerServiceId(serviceId);  | 
|             partnerTraceService.updateById(obj);  | 
|   | 
|             String userType;  | 
|             if(orderEnum.getValue().equals("1")||orderEnum.getValue().equals("3")){  | 
|                 userType="2";  | 
|             }else{  | 
|                 userType = "6";  | 
|             }  | 
|   | 
|   | 
|   | 
|             for (OtherUserInfo otherUserInfo : byPartnerId) {  | 
|   | 
|                 if(otherUserInfo.getUserType().equals(userType)) {  | 
|   | 
|                     Result<String> terminal = GdTraceUtil.createTerminal(key, serviceId, otherUserInfo.getUserId() + extra);  | 
|                     if (terminal.getCode() == 0) {  | 
|                         String termianlId = terminal.getData();  | 
|                         OtherUserInfo obj2 = new OtherUserInfo();  | 
|                         obj2.setUserId(otherUserInfo.getUserId());  | 
|                         if (orderEnum.getValue().equals("1") || orderEnum.getValue().equals("2")) {  | 
|                             obj2.setTerminalId(termianlId);  | 
|                         } else if (orderEnum.getValue().equals("3")) {  | 
|                             obj2.setTerminalDayId(termianlId);  | 
|   | 
|                             Result<String> trace = GdTraceUtil.createTrace(key, serviceId, termianlId);  | 
|                             if(trace.getCode()==0){  | 
|                                 String data = trace.getData();  | 
|                                 UserTraceInfo byUserAndDate = userTraceInfoService.findByUserAndDate(otherUserInfo.getUserId(), "2020-07-04");  | 
|                                 if(byUserAndDate!=null) {  | 
|                                     byUserAndDate.setKeyId(key);  | 
|                                     byUserAndDate.setServiceId(serviceId);  | 
|                                     byUserAndDate.setTraceId(data);  | 
|                                     byUserAndDate.setTerminalId(termianlId);  | 
|                                     userTraceInfoService.updateById(byUserAndDate);  | 
|                                 }else {  | 
|                                     byUserAndDate=new UserTraceInfo();  | 
|                                     byUserAndDate.setUserId(otherUserInfo.getUserId());  | 
|                                     byUserAndDate.setKeyId(key);  | 
|                                     byUserAndDate.setServiceId(serviceId);  | 
|                                     byUserAndDate.setTraceId(data);  | 
|                                     byUserAndDate.setTerminalId(termianlId);  | 
|                                     userTraceInfoService.add(byUserAndDate);  | 
|   | 
|                                 }  | 
|                             }  | 
|                         }  | 
|   | 
|                         otherUserService.updateById(obj2);  | 
|                     }  | 
|                 }  | 
|             }  | 
|   | 
|         }  | 
|     }  | 
|   | 
|   | 
| }  |