| package com.xzx.gc.order.controller;  | 
|   | 
| import cn.hutool.core.collection.CollUtil;  | 
| import cn.hutool.core.convert.Convert;  | 
| import cn.hutool.core.date.DateUtil;  | 
| import cn.hutool.core.text.StrBuilder;  | 
| import cn.hutool.core.thread.ThreadUtil;  | 
| import cn.hutool.core.util.NumberUtil;  | 
| import cn.hutool.core.util.StrUtil;  | 
| import cn.hutool.json.JSONObject;  | 
| import cn.hutool.json.JSONUtil;  | 
| import com.xzx.gc.common.Result;  | 
| import com.xzx.gc.common.constant.*;  | 
| import com.xzx.gc.common.dto.gdmap.CommonTraceDto;  | 
| import com.xzx.gc.common.dto.gdmap.FindTraceDto;  | 
| import com.xzx.gc.common.dto.gdmap.TrackDto;  | 
| import com.xzx.gc.common.dto.gdmap.UploadTraceLocationDto;  | 
| import com.xzx.gc.common.request.BaseController;  | 
| import com.xzx.gc.common.utils.BusinessUtil;  | 
| import com.xzx.gc.common.utils.DateUtils;  | 
| import com.xzx.gc.common.utils.RedisUtil;  | 
| import com.xzx.gc.common.utils.gdmap.GdTraceUtil;  | 
| import com.xzx.gc.entity.ConfigInfo;  | 
| import com.xzx.gc.entity.OrderInfo;  | 
| import com.xzx.gc.entity.PartnerTrace;  | 
| import com.xzx.gc.entity.UserTraceInfo;  | 
| import com.xzx.gc.model.JsonResult;  | 
| import com.xzx.gc.model.admin.XzxCityPartnerModel;  | 
| import com.xzx.gc.model.order.OrderTraceCreateByTimeDTO;  | 
| import com.xzx.gc.model.system.ConfigInfoReq;  | 
| import com.xzx.gc.model.system.ConfigInfoVo;  | 
| import com.xzx.gc.order.dto.TraceAllDto;  | 
| import com.xzx.gc.order.dto.TraceInfoDto;  | 
| import com.xzx.gc.order.dto.TrackDetailResultDto;  | 
| import com.xzx.gc.order.dto.TrackResultDto;  | 
| import com.xzx.gc.order.service.*;  | 
| import io.swagger.annotations.Api;  | 
| import io.swagger.annotations.ApiImplicitParam;  | 
| import io.swagger.annotations.ApiImplicitParams;  | 
| import io.swagger.annotations.ApiOperation;  | 
| import lombok.extern.slf4j.Slf4j;  | 
| import org.springframework.beans.factory.annotation.Autowired;  | 
| import org.springframework.web.bind.annotation.PostMapping;  | 
| import org.springframework.web.bind.annotation.RequestBody;  | 
| import org.springframework.web.bind.annotation.ResponseBody;  | 
| import org.springframework.web.bind.annotation.RestController;  | 
|   | 
| import javax.servlet.http.HttpServletRequest;  | 
| import java.math.BigDecimal;  | 
| import java.math.RoundingMode;  | 
| import java.util.*;  | 
| import java.util.stream.Collectors;  | 
|   | 
| /**  | 
|  * @author :zz  | 
|  */  | 
| @RestController  | 
| @Api(tags = {"轨迹管理"})  | 
| @Slf4j  | 
| public class TraceController extends BaseController {  | 
|   | 
|   | 
|     @Autowired  | 
|     private RedisUtil redisUtil;  | 
|   | 
|     @Autowired  | 
|     private UserTraceInfoService userTraceInfoService;  | 
|   | 
|     @Autowired  | 
|     private PartnerTraceService partnerTraceService;  | 
|   | 
|     @Autowired  | 
|     private ConfigService configService;  | 
|   | 
|     @Autowired  | 
|     private BusinessUtil businessUtil;  | 
|   | 
|     @Autowired  | 
|     private OrderService orderService;  | 
|   | 
|     @Autowired  | 
|     private TraceService traceService;  | 
|   | 
|     @Autowired  | 
|     private CityPartnerService cityPartnerService;  | 
|   | 
|     @Autowired  | 
|     private OtherUserService otherUserService;  | 
|   | 
|     @PostMapping({"/trace/info",Constants.ADMIN_VIEW_PREFIX+"/trace/info"})  | 
|     @ApiOperation(value = "轨迹清单")  | 
|     public Result<TrackResultDto> add(@RequestBody TraceInfoDto traceInfoDto, HttpServletRequest request) {  | 
|         //兼容原来的接口 自定义负值类型  | 
|         String type=traceInfoDto.getType();  | 
|         String userType=traceInfoDto.getUserType();  | 
|         String userId = traceInfoDto.getUserId();  | 
|         String time1 = traceInfoDto.getTime();  | 
|         //兼容原来的接口 自定义负值类型  | 
|         if(OrderEnum.回收员全天轨迹.getValue().equals(type)){  | 
|             userType=Constants.DEFAULT_ID;  | 
|         }  | 
|   | 
|         PartnerTrace partnerTrace = partnerTraceService.findByUserIdAndType(userId, userType);  | 
|   | 
| //        if(SpringUtil.isDev()){  | 
| //            partnerTrace=new PartnerTrace();  | 
| //            partnerTrace.setPartnerServiceType(Convert.toShort(3));  | 
| //            partnerTrace.setPartnerServiceId("160878");  | 
| //            partnerTrace.setPartnerKey("a64d28b2e036f4688b05916ef321b17d");  | 
| //            OtherUserInfo otherUserInfo=new OtherUserInfo();  | 
| //            otherUserInfo.setTerminalDayId("268834485");  | 
| //            partnerTrace.setOtherUserInfo(otherUserInfo);  | 
| //        }  | 
|   | 
|         if (partnerTrace != null) {  | 
|   | 
|   | 
|             String key = partnerTrace.getPartnerKey();  | 
|             String sid = partnerTrace.getPartnerServiceId();  | 
|   | 
|             FindTraceDto findTraceDto = new FindTraceDto();  | 
|             findTraceDto.setKey(key);  | 
|             findTraceDto.setSid(sid);  | 
|   | 
|             String tid ;  | 
|             if(OrderEnum.回收员全天轨迹.getValue().equals(type)){  | 
|                 tid=partnerTrace.getOtherUserInfo().getTerminalDayId();  | 
|             }else {  | 
|                 tid = partnerTrace.getOtherUserInfo().getTerminalId();  | 
|             }  | 
|   | 
| //  | 
| //            if(SpringUtil.isDev()){  | 
| //                tid="251615392";  | 
| ////                findTraceDto.setTrid("80");  | 
| //            }  | 
|             findTraceDto.setTid(tid);  | 
|   | 
|   | 
|             String trid = traceInfoDto.getTraceId();  | 
|             if (StrUtil.isNotBlank(trid)) {  | 
|                 findTraceDto.setTrid(trid);  | 
|             } else {  | 
|   | 
|                 UserTraceInfo byUserAndDate = userTraceInfoService.findByUserAndDate(userId, time1);  | 
|                 if(byUserAndDate!=null){  | 
|                     findTraceDto.setTrid(byUserAndDate.getTraceId());  | 
|                 }  | 
|   | 
|                 ConfigInfoReq configInfoReq = new ConfigInfoReq();  | 
|                 configInfoReq.setConfigTypeCode("WORK_TIME");  | 
|                 List<ConfigInfoVo> configInfoVos = configService.configInfoQuery(configInfoReq);  | 
|                 String configValue = configInfoVos.get(0).getConfigValue();  | 
|                 String[] split = configValue.split("-");  | 
|   | 
|                 //Unix时间戳(轨迹点的定位时间),需要精准到毫秒  | 
|                 String startTime = time1 + " " + split[0] + ":00";  | 
|                 String endTime = time1 + " " + split[1] + ":00";  | 
|   | 
|                 findTraceDto.setStarttime(DateUtil.parse(startTime, DateUtils.DATE_FORMAT_YMDHMS).getTime());  | 
|                 findTraceDto.setEndtime(DateUtil.parse(endTime, DateUtils.DATE_FORMAT_YMDHMS).getTime());  | 
|             }  | 
|   | 
|             Result<List<TrackDto>> trace = GdTraceUtil.findTrace(findTraceDto);  | 
|   | 
|             if (trace.getCode() == 0) {  | 
|                 List<TrackDto> data = trace.getData();  | 
|                 TrackDto trackDto = data.get(0);  | 
|                 TrackResultDto trackResultDto = new TrackResultDto();  | 
|                 trackResultDto.setCounts(trackDto.getCounts());  | 
|                 trackResultDto.setTime(NumberUtil.round(Convert.toDouble(trackDto.getTime()) / 1000 /60 , 1, RoundingMode.DOWN));  | 
|                 if (trackDto.getDistance() != 0) {  | 
|                     String s = businessUtil.changeWeight(Convert.toStr(Convert.toDouble(trackDto.getDistance()) / 1000));  | 
|                     trackResultDto.setDistance(s);  | 
|                 } else {  | 
|                     trackResultDto.setDistance("0.000");  | 
|                 }  | 
|   | 
|                 List<UploadTraceLocationDto> points = trackDto.getPoints();  | 
|   | 
|                 List<TrackDetailResultDto> details = new ArrayList<>();  | 
|                 if (CollUtil.isNotEmpty(points)) {  | 
|                     for (UploadTraceLocationDto point : points) {  | 
|                         Long locatetime = point.getLocatetime();  | 
|                         String location = point.getLocation();  | 
|                         TrackDetailResultDto trackDetailResultDto = new TrackDetailResultDto();  | 
|                         trackDetailResultDto.setLocation(location);  | 
|                         trackDetailResultDto.setLocatetime(locatetime.toString());  | 
|                         String props = point.getProps();  | 
|                         if (StrUtil.isNotBlank(props)) {  | 
|                             JSONObject jsonObject = JSONUtil.parseObj(props);  | 
|                             trackDetailResultDto.setAddress(jsonObject.getStr("address"));  | 
|                         }  | 
|   | 
|                         details.add(trackDetailResultDto);  | 
|                     }  | 
|   | 
|   | 
|                     //将连续的数据进行合并统计逗留时间  | 
|                     if(CollUtil.isNotEmpty(details)){  | 
|   | 
|                         List<TrackDetailResultDto> collect = details.stream().sorted(Comparator.comparing(TrackDetailResultDto::getLocatetime)).collect(Collectors.toList());  | 
|   | 
|                         List<TrackDetailResultDto> list2 = new ArrayList<>();  | 
|                         list2.add(collect.get(0));  | 
|                         for(int i=1;i<collect.size();i++){  | 
|   | 
|                             TrackDetailResultDto trackDetailResultDto1 = collect.get(i);  | 
|                             String address = trackDetailResultDto1.getAddress();  | 
|                             String locatetime = trackDetailResultDto1.getLocatetime();  | 
|   | 
|                             //取list集合的最后1个进行地址比较  | 
|                             TrackDetailResultDto trackDetailResultDto2 = list2.get(list2.size() - 1);  | 
|   | 
|                             String address1 = trackDetailResultDto2.getAddress();  | 
|                             String locatetime1 = trackDetailResultDto2.getLocatetime();  | 
|                             String lingerLocateTime = trackDetailResultDto2.getLingerLocateTime();  | 
|   | 
|                             if(!address.equals(address1)){  | 
|                                 String time=StrUtil.isNotBlank(lingerLocateTime)?lingerLocateTime:locatetime1;  | 
|                                 //相差的毫秒数  | 
|                                 BigDecimal sub = NumberUtil.sub(Convert.toLong(locatetime), Convert.toLong(time));  | 
|                                 //相差大于30秒  | 
|                                 if(Convert.toLong(sub)>30000){  | 
|                                     trackDetailResultDto2.setOffline(true);  | 
|                                 }  | 
|                                 list2.add(trackDetailResultDto1);  | 
|                             }else {  | 
|                                 trackDetailResultDto2.setLingerTime(NumberUtil.sub(Convert.toLong(locatetime), Convert.toLong(locatetime1)).toString());  | 
|                                 trackDetailResultDto2.setLingerLocateTime(locatetime);  | 
|                             }  | 
|   | 
|                         }  | 
|   | 
|                         //处理轨迹时间的数据  | 
|                         for (TrackDetailResultDto trackDetailResultDto : list2) {  | 
|                             Date locatetime = new Date(Convert.toLong(trackDetailResultDto.getLocatetime()));  | 
|                             trackDetailResultDto.setLocatetime(DateUtil.format(locatetime, DateUtils.DATE_FORMAT_HM));  | 
|   | 
|                             String lingerTime = trackDetailResultDto.getLingerTime();  | 
|                             if (StrUtil.isNotBlank(lingerTime)) {  | 
|                                 double l = Convert.toDouble(lingerTime) / 1000 / 60;  | 
|                                 BigDecimal round = NumberUtil.round(l, 1, RoundingMode.DOWN);  | 
|                                 trackDetailResultDto.setLingerTime(Convert.toStr(round));  | 
|                             }  | 
|                         }  | 
|                         details=list2;  | 
|                         //重置轨迹点数为处理后的点数  | 
|                         trackResultDto.setCounts(list2.size());  | 
|   | 
|                     }  | 
|                 }  | 
|                 trackResultDto.setDetails(details);  | 
|   | 
|                 //当前时间戳  | 
|                 trackResultDto.setTimestamp(System.currentTimeMillis());  | 
|                 return Result.success(trackResultDto);  | 
|             }else {  | 
|                 return Result.error(-1, trace.getMsg());  | 
|             }  | 
|         } else {  | 
|             return Result.error(-1, "合伙人没有分配对应的服务轨迹");  | 
|         }  | 
|     }  | 
|   | 
|   | 
|   | 
|     @PostMapping("/trace/upload")  | 
|     @ApiOperation(value = "上传轨迹")  | 
|     public Result upload(@RequestBody TraceAllDto traceAllDto, HttpServletRequest request) {  | 
|         Runnable callable=()->{  | 
|             traceService.upload(traceAllDto);  | 
|         };  | 
|         ThreadUtil.execAsync(callable);  | 
|         return Result.success();  | 
|     }  | 
|   | 
|   | 
|   | 
|     @PostMapping("/trace/createByTime")  | 
|     @ApiOperation(value = "根据时间创建轨迹")  | 
|     public Result createByTime(HttpServletRequest request,@RequestBody OrderTraceCreateByTimeDTO orderTraceCreateByTimeDTO) {  | 
|         String userId = getUserId(request);  | 
|         //外部骑手  | 
|         Short originType = otherUserService.findById(userId).getOriginType();  | 
|         if(originType!=null&&originType.intValue()==1){  | 
|             return Result.success(-1);  | 
|         }  | 
|         if(redisUtil.setnx(RedisKeyConstant.CREATE_TRACE+userId,"0")){  | 
|   | 
|             try {  | 
|                 String type = orderTraceCreateByTimeDTO.getType();  | 
|                 String userType=null;  | 
|   | 
|                 UserTraceInfo byUserAndDate = userTraceInfoService.findByUserAndDate(userId, DateUtil.today());  | 
|                 if(byUserAndDate==null){  | 
|                     //创建轨迹  | 
|                     if(OrderEnum.回收员全天轨迹.getValue().equals(type)){  | 
|                         userType=Constants.DEFAULT_ID;  | 
|                     }  | 
|   | 
|                     PartnerTrace partnerTrace = partnerTraceService.findByUserIdAndType(userId, userType);  | 
|                     if(partnerTrace!=null){  | 
|                         String terminalId;  | 
|                         if(OrderEnum.回收员全天轨迹.getValue().equals(type)){  | 
|                             terminalId = partnerTrace.getOtherUserInfo().getTerminalDayId();  | 
|                         }else {  | 
|                             terminalId = partnerTrace.getOtherUserInfo().getTerminalId();  | 
|                         }  | 
|                         String key=partnerTrace.getPartnerKey();  | 
|                         String partnerServiceId = partnerTrace.getPartnerServiceId();  | 
|                         Result traceCreate = GdTraceUtil.createTrace(key, partnerServiceId, terminalId);  | 
|                         if(traceCreate.getCode()==0){  | 
|                             String traceId=traceCreate.getData().toString();  | 
|                             UserTraceInfo obj=new UserTraceInfo();  | 
|                             obj.setUserId(userId);  | 
|                             obj.setTerminalId(terminalId);  | 
|                             obj.setTraceId(traceId);  | 
|                             obj.setKeyId(key);  | 
|                             obj.setServiceId(partnerServiceId);  | 
|                             try {  | 
|                                 userTraceInfoService.add(obj);  | 
|                             } catch (Exception e) {  | 
|                                 CommonTraceDto commonTraceDto = new CommonTraceDto();  | 
|                                 commonTraceDto.setKey(key);  | 
|                                 commonTraceDto.setSid(partnerServiceId);  | 
|                                 commonTraceDto.setTid(terminalId);  | 
|                                 commonTraceDto.setTrid(traceId);  | 
|                                 GdTraceUtil.deleteTrace(commonTraceDto);  | 
|                                 return Result.error(Convert.toInt(ExceptionEnum.可忽略异常.getValue()),"创建轨迹失败:数据库操作异常");  | 
|                             }  | 
|                             return Result.success(traceId);  | 
|                         }else {  | 
|                             return Result.error(Convert.toInt(ExceptionEnum.可忽略异常.getValue()),"创建轨迹失败:"+traceCreate.getMsg());  | 
|                         }  | 
|                     }else {  | 
|                         return Result.error(Convert.toInt(ExceptionEnum.可忽略异常.getValue()),"未找到对应的合伙人");  | 
|                     }  | 
|                 }else {  | 
|                     return Result.success(byUserAndDate.getTraceId());  | 
|                 }  | 
|             }catch (Exception e){  | 
|                 throw e;  | 
|             }finally {  | 
|                 redisUtil.del(RedisKeyConstant.CREATE_TRACE+userId);  | 
|             }  | 
|         }  | 
|         return Result.error(Convert.toInt(ExceptionEnum.可忽略异常.getValue()),"创建轨迹失败:重复操作");  | 
|     }  | 
|   | 
|   | 
|     @PostMapping("/trace/findByReceiver")  | 
|     @ApiOperation(value = "查询回收员当前正在进行的轨迹")  | 
|     public Result findByReceiver(HttpServletRequest request) {  | 
|         List<OrderInfo> detailByReceiverAndStatus = orderService.findDetailByReceiverAndStatus(getUserId(request), OrderEnum.服务中.getValue());  | 
|         StrBuilder strBuilder = StrBuilder.create();  | 
|         if(CollUtil.isNotEmpty(detailByReceiverAndStatus)){  | 
|             for (OrderInfo byReceiverAndStatus : detailByReceiverAndStatus) {  | 
|                 if(StrUtil.isNotBlank(byReceiverAndStatus.getTraceId())) {  | 
|                     strBuilder.append(byReceiverAndStatus.getTraceId() + ",");  | 
|                 }  | 
|             }  | 
|         }  | 
|         if(strBuilder.length()>0){  | 
|             String s = strBuilder.toString();  | 
|             String s1 = StrUtil.removeSuffix(s, ",");  | 
|             return Result.success(s1);  | 
|         }  | 
|         return Result.success(null);  | 
|     }  | 
|   | 
|   | 
| //    @PostMapping({"/trace/info2",Constants.ADMIN_VIEW_PREFIX+"/trace/info"})  | 
| //    @ApiOperation(value = "修复高德服务")  | 
| //    public Result findByReceiver2(HttpServletRequest request) {  | 
| //        traceService.fixService();  | 
| //        return Result.success();  | 
| //    }  | 
|   | 
|     @PostMapping( "/admin/front/trace/queryGaodeByUserId.json")  | 
|     @ApiOperation(value="查询轨迹接口", notes="test: 仅0有正确返回")  | 
|     @ApiImplicitParams({  | 
|             @ApiImplicitParam(paramType="query", name ="userId", value = "用户Id", required = true, dataType = "String"),  | 
|             @ApiImplicitParam(paramType="query", name ="orderId", value = "订单Id", required = true, dataType = "String"),  | 
|             @ApiImplicitParam(paramType="query", name ="dayTime", value = "日期", required = true, dataType = "String"),  | 
|             @ApiImplicitParam(paramType="query", name ="dateTime", value = "时间段", required = true, dataType = "String")  | 
|   | 
|     })  | 
|     public JsonResult<List<Map<String,Object>>> queryGaodeByUserId(@RequestBody XzxCityPartnerModel model){  | 
|   | 
|         List<Map<String,Object>> list =  cityPartnerService.queryGaodeByUserId(model);  | 
|         return JsonResult.success(list);  | 
|     }  | 
| }  |