| New file |
| | |
| | | package com.xiaopeng.account.controller; |
| | | |
| | | |
| | | import cn.hutool.http.HttpRequest; |
| | | import cn.hutool.http.HttpResponse; |
| | | import cn.hutool.http.HttpUtil; |
| | | import com.alibaba.fastjson2.JSON; |
| | | import com.xiaopeng.account.service.impl.SysLoginService; |
| | | import com.xiaopeng.account.vo.OIDCUserInfoVo; |
| | | import com.xiaopeng.account.vo.SSOToken; |
| | | import com.xiaopeng.api.model.account.SysRole; |
| | | import com.xiaopeng.api.vo.account.LoginOperationUser; |
| | | import com.xiaopeng.api.vo.account.LoginUser; |
| | | import com.xiaopeng.common.core.domain.R; |
| | | import com.xiaopeng.common.core.exception.ServiceException; |
| | | import com.xiaopeng.common.security.service.TokenService; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | |
| | | @Slf4j |
| | | @RestController |
| | | @RequestMapping("/ssoAuthSdk") |
| | | public class XtigerSSOController { |
| | | |
| | | @Value("${xiaopeng.xtiger.sso.issuer}") |
| | | private String issuer; |
| | | |
| | | @Value("${xiaopeng.xtiger.sso.appId}") |
| | | private String appId; |
| | | |
| | | @Autowired |
| | | private TokenService tokenService; |
| | | |
| | | @Autowired |
| | | private SysLoginService sysLoginService; |
| | | |
| | | /** |
| | | * 翼虎web登录重定向接口 |
| | | * 通过code换取token |
| | | * |
| | | * @param code |
| | | * @param state |
| | | */ |
| | | @GetMapping("/callback") |
| | | public R<?> callback(String code, String state, HttpServletRequest request) { |
| | | log.info("翼虎登录重定向接口, code: {}, state: {}", code, state); |
| | | HttpRequest post = HttpUtil.createPost(issuer + "/oidc/token/v2"); |
| | | post.form("client_id", appId); |
| | | post.form("code", code); |
| | | post.form("grant_type", "authorization_code"); |
| | | HttpResponse execute = post.execute(); |
| | | if (!execute.isOk()) { |
| | | throw new ServiceException("登录失败,请稍后重试。"); |
| | | } |
| | | String body = execute.body(); |
| | | log.info("翼虎登录重定向接口, 返回结果: {}", body); |
| | | SSOToken ssoToken = JSON.parseObject(body, SSOToken.class); |
| | | String accessToken = ssoToken.getAccessToken(); |
| | | OIDCUserInfoVo userInfo = getUserInfo(accessToken); |
| | | return login(userInfo, request); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 翼虎app登录换取本系统token |
| | | * |
| | | * @param request |
| | | * @return |
| | | */ |
| | | @GetMapping("/appLogin") |
| | | public R<?> appLogin(Integer deviceType, HttpServletRequest request) { |
| | | String accessTokenHeader = request.getHeader("Authorization"); |
| | | String accessToken = StringUtils.isEmpty(accessTokenHeader) ? null : accessTokenHeader.replace("Bearer ", ""); |
| | | if (StringUtils.isEmpty(accessToken)) { |
| | | throw new ServiceException("登录失败,请稍后重试。"); |
| | | } |
| | | OIDCUserInfoVo userInfo = getUserInfo(accessToken); |
| | | return appLogin(userInfo, deviceType, request); |
| | | } |
| | | |
| | | |
| | | public OIDCUserInfoVo getUserInfo(String accessToken) { |
| | | log.info("翼虎登录使用token获取用户信息"); |
| | | HttpRequest post = HttpUtil.createGet(issuer + "/oidc/userinfo"); |
| | | post.header("Authorization", "Bearer " + accessToken); |
| | | HttpResponse execute = post.execute(); |
| | | if (!execute.isOk()) { |
| | | throw new ServiceException("登录失败,请稍后重试。"); |
| | | } |
| | | String body = execute.body(); |
| | | log.info("翼虎登录使用token获取用户信息, 返回结果: {}", body); |
| | | OIDCUserInfoVo ssoToken = JSON.parseObject(body, OIDCUserInfoVo.class); |
| | | return ssoToken; |
| | | } |
| | | |
| | | |
| | | public R<?> login(OIDCUserInfoVo userInfo, HttpServletRequest request) { |
| | | // 用户登录 |
| | | LoginUser loginUser = sysLoginService.login(userInfo.getPhone_number(), request); |
| | | HashMap<String, Object> map = new HashMap<>(); |
| | | map.put("token", tokenService.createToken(loginUser)); |
| | | List<SysRole> roles = loginUser.getSysUser().getRoles(); |
| | | // if (CollectionUtils.isEmpty(roles)) { |
| | | // throw new ServiceException("请关联角色!", I18nKeyConstant.LOGIN_ROLE_NOT_BIND); |
| | | // } |
| | | // map.put("roleName",roles.get(0).getRoleName()); |
| | | map.put("info", userInfo); |
| | | // 修改用户最后登录时间 |
| | | return R.ok(map); |
| | | } |
| | | |
| | | |
| | | public R<?> appLogin(OIDCUserInfoVo userInfo, Integer deviceType, HttpServletRequest request) { |
| | | LoginOperationUser loginUser = sysLoginService.verificationCodeLogin(userInfo.getPhone_number(), deviceType, request); |
| | | HashMap<String, Object> map = new HashMap<>(); |
| | | map.put("token", tokenService.createOperationUserToken(loginUser)); |
| | | // List<SysRole> roles = userInfo.getXpOperationsUser().getRoles(); |
| | | // if (CollectionUtils.isEmpty(roles)) { |
| | | // return R.fail("请关联角色!"); |
| | | // } |
| | | // map.put("roleName", roles.get(0).getRoleName()); |
| | | map.put("info", loginUser); |
| | | return R.ok(map); |
| | | } |
| | | } |
| | |
| | | // recordLogService.recordLogininfor(request, user.getId().intValue(), username, Constants.LOGIN_SUCCESS_STATUS, "登录成功"); |
| | | return userInfo; |
| | | } |
| | | |
| | | /** |
| | | * 登录 |
| | | */ |
| | | public LoginUser login(String username, HttpServletRequest request) { |
| | | username = username.trim(); |
| | | // 查询用户信息 |
| | | SysUser user = userService.selectUserByUserName(username); |
| | | if (StringUtils.isNull(user)) { |
| | | throw new ServiceException("帐号不存在或已被删除", I18nKeyConstant.ACCOUNT_NOT_EXISTS); |
| | | } |
| | | // 角色集合 |
| | | Set<String> roles = permissionService.getRolePermission(user); |
| | | // 权限集合 |
| | | Set<String> menuPermission = permissionService.getMenuPermission(user); |
| | | LoginUser userInfo = new LoginUser(); |
| | | userInfo.setSysUser(user); |
| | | userInfo.setRoles(roles); |
| | | userInfo.setPermissions(menuPermission); |
| | | |
| | | if (StringUtils.isNull(user)) { |
| | | recordLogService.recordLogininfor(request, null, username, Constants.LOGIN_FAIL_STATUS, "登录用户不存在"); |
| | | throw new ServiceException("用户名/密码错误", I18nKeyConstant.LOGIN_USERNAME_PASSWORD); |
| | | } |
| | | |
| | | // 用户名不在指定范围内 错误 |
| | | if (username.length() < UserConstants.USERNAME_MIN_LENGTH |
| | | || username.length() > UserConstants.USERNAME_MAX_LENGTH) { |
| | | recordLogService.recordLogininfor(request, user.getId().intValue(), username, Constants.LOGIN_FAIL_STATUS, "用户名不在指定范围"); |
| | | throw new ServiceException("用户名不在指定范围",I18nKeyConstant.LOGIN_USERNAME_NOT_VALID); |
| | | } |
| | | // IP黑名单校验 |
| | | String blackStr = Convert.toStr(redisService.getCacheObject(CacheConstants.SYS_LOGIN_BLACKIPLIST)); |
| | | if (IpUtils.isMatchedIp(blackStr, IpUtils.getIpAddr())) { |
| | | recordLogService.recordLogininfor(request, user.getId().intValue(), username, Constants.LOGIN_FAIL_STATUS, "很遗憾,访问IP已被列入系统黑名单"); |
| | | throw new ServiceException("很遗憾,访问IP已被列入系统黑名单", I18nKeyConstant.LOGIN_BLACK_LIST); |
| | | } |
| | | |
| | | if (user.getDeleted()) { |
| | | recordLogService.recordLogininfor(request, user.getId().intValue(), username, Constants.LOGIN_FAIL_STATUS, "对不起,您的账号已被删除"); |
| | | throw new ServiceException("对不起,您的账号:" + username + " 已被删除"); |
| | | } |
| | | if (Integer.valueOf("1").equals(user.getStatus())) { |
| | | recordLogService.recordLogininfor(request, user.getId().intValue(), username, Constants.LOGIN_FAIL_STATUS, "用户已停用,请联系管理员"); |
| | | throw new ServiceException("您的账号:" + username + " 已禁用", I18nKeyConstant.LOGIN_ACCOUNT_DISABLED, new Object[]{username}); |
| | | } |
| | | return userInfo; |
| | | } |
| | | |
| | | public void logout(String loginName, HttpServletRequest request) { |
| | | recordLogService.recordLogininfor(request, null, loginName, Constants.LOGIN_SUCCESS_STATUS, "退出成功"); |
| | |
| | | operationsUserService.updateById(operationsUser); |
| | | return loginOperationUser; |
| | | } |
| | | |
| | | |
| | | public LoginOperationUser verificationCodeLogin(String phoneNumber, String code, Integer deviceType, HttpServletRequest request) { |
| | | LoginOperationUser loginOperationUser = new LoginOperationUser(); |
| | | phoneNumber = phoneNumber.trim(); |
| | |
| | | operationsUserService.updateById(operationsUser); |
| | | return loginOperationUser; |
| | | } |
| | | public Boolean verificationCodeUpdate(UpdatePasswordDTO updatePasswordDTO, HttpServletRequest request) { |
| | | |
| | | |
| | | public LoginOperationUser verificationCodeLogin(String phoneNumber, Integer deviceType, HttpServletRequest request) { |
| | | LoginOperationUser loginOperationUser = new LoginOperationUser(); |
| | | phoneNumber = phoneNumber.trim(); |
| | | // 查询运维用户信息 |
| | | XpOperationsUser operationsUser = operationsUserService.lambdaQuery().eq( |
| | | XpOperationsUser::getPhoneNumber, phoneNumber |
| | | ).last("limit 1").one(); |
| | | if (StringUtils.isNull(operationsUser)) { |
| | | throw new ServiceException("验证码错误!"); |
| | | } |
| | | if (!operationsUser.getStatus()){ |
| | | throw new ServiceException("账号已禁用!"); |
| | | } |
| | | loginOperationUser.setXpOperationsUser(operationsUser); |
| | | //更新用户登录设备类型 |
| | | operationsUser.setDeviceType(deviceType); |
| | | operationsUserService.updateById(operationsUser); |
| | | return loginOperationUser; |
| | | } |
| | | |
| | | |
| | | public Boolean verificationCodeUpdate(UpdatePasswordDTO updatePasswordDTO, HttpServletRequest request) { |
| | | String phoneNumber = updatePasswordDTO.getPhoneNumber(); |
| | | String code = updatePasswordDTO.getVerificationCode(); |
| | | phoneNumber = phoneNumber.trim(); |
| New file |
| | |
| | | package com.xiaopeng.account.vo; |
| | | |
| | | import lombok.Data; |
| | | |
| | | @Data |
| | | public class OIDCUserInfoVo { |
| | | /** |
| | | * 用户id |
| | | */ |
| | | private String phone_number; |
| | | /** |
| | | * 用户名 |
| | | */ |
| | | private String username; |
| | | /** |
| | | * 姓名 |
| | | */ |
| | | private String name; |
| | | /** |
| | | * 昵称 |
| | | */ |
| | | private String nickname; |
| | | /** |
| | | * 用户头像图片地址 |
| | | */ |
| | | private String picture; |
| | | /** |
| | | * 工号 |
| | | */ |
| | | private String job_num; |
| | | /** |
| | | * 入职时间,yyyy-MM-dd格式 |
| | | */ |
| | | private String entry_date; |
| | | /** |
| | | * 更新时间, 时间戳, 精确到秒 |
| | | */ |
| | | private Long updated_at; |
| | | /** |
| | | * 更新时间,yyyy-MM-dd HH:mm:ss格式 |
| | | */ |
| | | private String updated_time; |
| | | /** |
| | | * 骁龙接入翼虎使用的用户中心映射uid |
| | | */ |
| | | private Long xuid; |
| | | } |
| New file |
| | |
| | | package com.xiaopeng.account.vo; |
| | | |
| | | import com.fasterxml.jackson.annotation.JsonProperty; |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * 翼虎登录token |
| | | */ |
| | | @Data |
| | | public class SSOToken { |
| | | /** |
| | | * 翼虎登录token |
| | | */ |
| | | @JsonProperty("access_token") |
| | | private String accessToken; |
| | | /** |
| | | * 翼虎登录token过期时间 |
| | | */ |
| | | @JsonProperty("expires_in") |
| | | private Long expireIn; |
| | | /** |
| | | * 翼虎登录token类型 |
| | | */ |
| | | @JsonProperty("token_type") |
| | | private String tokenType; |
| | | /** |
| | | * 翼虎登录token刷新token |
| | | */ |
| | | @JsonProperty("refresh_token") |
| | | private String refreshToken; |
| | | /** |
| | | * 翼虎登录token范围 |
| | | */ |
| | | @JsonProperty("scope") |
| | | private String scope; |
| | | } |
| | |
| | | * @param uid |
| | | * @return |
| | | */ |
| | | @GetMapping("/logan/inner/v1/subscribeMessage/getUserOpenId/{v}") |
| | | @GetMapping("/logan/inner/v1/subscribeMessage/getUserOpenId/{uid}") |
| | | R<String> getUserOpenId(@PathVariable("uid") Integer uid); |
| | | } |
| | |
| | | return new AjaxResult(code, msg, null); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 返回错误消息 |
| | | * |
| | | * @param code 状态码 |
| | | * @param msg 返回内容 |
| | | * @return 错误消息 |
| | | */ |
| | | public static AjaxResult error(int code, String msg, Object data) |
| | | { |
| | | return new AjaxResult(code, msg, data); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 是否为成功消息 |
| | | * |
| | |
| | | package com.xiaopeng.common.security.handler; |
| | | |
| | | import com.alibaba.fastjson2.JSON; |
| | | import com.alibaba.fastjson2.JSONObject; |
| | | import com.fasterxml.jackson.databind.JsonNode; |
| | | import com.fasterxml.jackson.databind.ObjectMapper; |
| | | import com.xiaopeng.common.core.constant.HttpStatus; |
| | |
| | | import com.xiaopeng.common.core.utils.StringUtils; |
| | | import com.xiaopeng.common.core.web.domain.AjaxResult; |
| | | import feign.FeignException; |
| | | import org.apache.commons.lang3.RandomStringUtils; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | |
| | | import org.springframework.web.multipart.MaxUploadSizeExceededException; |
| | | |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import java.util.UUID; |
| | | |
| | | /** |
| | | * 全局异常处理器 |
| | |
| | | private String maxFileSize; |
| | | @Value("${spring.servlet.multipart.max-request-size:100MB}") |
| | | private String maxRequestSize; |
| | | |
| | | @Value("${xiaopeng.xtiger.sso.issuer}") |
| | | private String issuer; |
| | | |
| | | @Value("${xiaopeng.xtiger.sso.appId}") |
| | | private String appId; |
| | | |
| | | @Value("${xiaopeng.xtiger.sso.serverHost}") |
| | | private String serverHost; |
| | | |
| | | @Autowired |
| | | private MessageSource messageSource; |
| | |
| | | public AjaxResult notLoginException(NotLoginException e, HttpServletRequest request) { |
| | | String requestURI = request.getRequestURI(); |
| | | log.error("请求地址'{}',登录校验失败'{}'", requestURI, e.getMessage()); |
| | | return AjaxResult.error(HttpStatus.UNAUTHORIZED, e.getMessage()); |
| | | String s = UUID.randomUUID().toString(); |
| | | String state1 = s.substring(0, 8) + s.substring(9, 13) + s.substring(14, 18) + s.substring(19, 23) + s.substring(24); |
| | | String s1 = UUID.randomUUID().toString(); |
| | | String state2 = s1.substring(0, 8) + s.substring(9, 13) + s.substring(14, 18) + s.substring(19, 23) + s.substring(24); |
| | | String nonce = RandomStringUtils.randomAlphanumeric(6); |
| | | JSONObject jsonObject = JSON.parseObject("{\n" + |
| | | " \"uid\": null,\n" + |
| | | " \"username\": null,\n" + |
| | | " \"authUrl\": \"" + issuer + "/oidc/auth?scope=openid+profile+offline_access+phone+email&response_type=code&redirect_uri=" + serverHost + "/ssoAuthSdk/callback&state=" + state1 + "&nonce=" + nonce + "&client_id=" + appId + "\",\n" + |
| | | " \"logoutUrl\": null,\n" + |
| | | " \"callbackUrl\": \"" + serverHost + "/ssoAuthSdk/callback?state=" + state2 + "\"\n" + |
| | | " }"); |
| | | return AjaxResult.error(HttpStatus.UNAUTHORIZED, e.getMessage(), jsonObject); |
| | | } |
| | | |
| | | /** |
| | |
| | | RouteVo routeRemain = JSON.parseObject(cacheObject.toString(), RouteVo.class); |
| | | Integer xczSyDistance = routeRemain.getDistance();//行程中剩余里程 |
| | | Integer xczSyTime = routeRemain.getDuration();//行程中剩余时间 |
| | | if(systemSetting.getXczSyDistance()<xczSyDistance || systemSetting.getXczSyTime() < xczSyTime){ |
| | | if(systemSetting.getXczSyDistance() > xczSyDistance || systemSetting.getXczSyTime() * 60 > xczSyTime){ |
| | | throw new ServiceException("即将达到终点,禁止修改目的地"); |
| | | } |
| | | } |
| | |
| | | if (!locked) { |
| | | throw new ServiceException("点位编号生成繁忙,请稍后重试", I18nKeyConstant.POINT_NUMBER_LOCK_FAIL); |
| | | } |
| | | validateFencePointCountLimit(pointAddDto.getElectronicAreaId()); |
| | | validateFencePointCountLimit(electronicAreaId); |
| | | String maxPointNumber = this.baseMapper.selectMaxPointNumber(cityPrefix, POINT_BIZ_TYPE); |
| | | int nextSerial = 1; |
| | | if (StringUtils.hasText(maxPointNumber)) { |
| | |
| | | |
| | | import javax.annotation.Resource; |
| | | import java.time.LocalDateTime; |
| | | import java.time.ZoneOffset; |
| | | import java.time.format.DateTimeFormatter; |
| | | import java.util.*; |
| | | import java.util.concurrent.LinkedBlockingQueue; |
| | |
| | | if (servingVehicles.getCode() != 200) { |
| | | continue; |
| | | } |
| | | |
| | | LonLatDto userPostion = new LonLatDto(Double.parseDouble(split[0]), Double.parseDouble(split[1])); |
| | | log.info("连环派单查询车辆结果 {} {}", orderNo, JSON.toJSONString(servingVehicles.getData())); |
| | | |
| | | XpTradingStrategyDetailVO strategyDetailVO = tradingStrategyClient.queryById().getData(); |
| | | |
| | | log.info("连环排查推单逻辑 {} {}", orderNo, JSON.toJSONString(strategyDetailVO)); |
| | | Integer distanceRegardAsEnding = strategyDetailVO.getDistanceRegardAsEnding(); |
| | | Integer timeRegardAsEnding = strategyDetailVO.getTimeRegardAsEnding(); |
| | | |
| | | Integer backupPower = strategyDetailVO.getBackupPower(); |
| | | Integer destToPassenger = strategyDetailVO.getDestToPassenger(); |
| | | Integer endingTimeToUseTime = strategyDetailVO.getEndingTimeToUseTime(); |
| | | LocalDateTime rideTime = xpOrder.getRideTime(); |
| | | LocalDateTime now = LocalDateTime.now(); |
| | | Optional<XpOrder> luckyOrderOpt = servingVehicles.getData().stream() |
| | | //获取位置 |
| | | .map(vin -> mongoTemplate.findOne(new Query(Criteria.where("vin").is(vin)), VehiclePosition.class)) |
| | | .map(VehiclePosition::getOrderId) |
| | | .map(xpOrderClient::queryOrderById) |
| | | .filter(R::isSuccess) |
| | | .map(R::getData) |
| | | .filter(o -> { |
| | | XpVehicle xpVehicle = xpVehicleClient.queryById(o.getVehicleId()).getData(); |
| | | Object cacheObject = redisService.getCacheObject(CacheConstants.navigationEnd(o.getAppUserId().toString())); |
| | | RouteVo routeRemain = JSON.parseObject(cacheObject.toString(), RouteVo.class); |
| | | if (routeRemain.getDuration() / 60 > timeRegardAsEnding) { |
| | | return false; |
| | | } |
| | | if (routeRemain.getDistance() > distanceRegardAsEnding) { |
| | | return false; |
| | | } |
| | | RouteAndFareDto next = new RouteAndFareDto(); |
| | | next.setOrigin(new LonLatDto(o.getStartLon(),o.getStartLat())); |
| | | next.setDestination(new LonLatDto(o.getEndLon(),o.getEndLat())); |
| | | RouteVo route = xpMapClient.getDistanceAndDuration(next).getData(); |
| | | if (route.getDistance() > backupPower + xpVehicle.getMileageRange()) |
| | | return false; |
| | | return routeRemain.getDistance() < destToPassenger |
| | | || now.plusSeconds(routeRemain.getDuration()) |
| | | .plusMinutes(endingTimeToUseTime) |
| | | .isBefore(rideTime); |
| | | }) |
| | | .findAny(); |
| | | |
| | | if (luckyOrderOpt.isPresent()) { |
| | | XpOrder luckyOder = luckyOrderOpt.get(); |
| | | log.info("有空闲车辆 {} 订单 {}", luckyOder.getOrderNumber(), orderNo); |
| | | XpVehicle xpVehicle = xpVehicleClient.queryById(luckyOder.getVehicleId()).getData(); |
| | | // 设置路线信息 |
| | | RouteAndFareDto routeAndFareDto = new RouteAndFareDto(); |
| | | routeAndFareDto.setDestination(userPostion); |
| | | routeAndFareDto.setOrigin(new LonLatDto(luckyOder.getEndLon(),luckyOder.getEndLat())); |
| | | RouteVo routeToOrigin = xpMapClient.getDistanceAndDuration(routeAndFareDto).getData(); |
| | | Object cacheObject = redisService.getCacheObject(CacheConstants.navigationEnd(luckyOder.getAppUserId().toString())); |
| | | for (String vin : servingVehicles.getData()) { |
| | | VehiclePosition vehiclePosition = mongoTemplate.findOne(new Query(Criteria.where("vin").is(vin)), VehiclePosition.class); |
| | | if(null == vehiclePosition){ |
| | | log.info("连环派单 {} 车辆查询定位数据失败 {}", vin, orderNo); |
| | | continue; |
| | | } |
| | | XpOrder xpOrder1 = xpOrderClient.queryOrderById(vehiclePosition.getOrderId()).getData(); |
| | | Object cacheObject = redisService.getCacheObject(CacheConstants.navigationEnd(xpOrder1.getAppUserId().toString())); |
| | | RouteVo routeRemain = JSON.parseObject(cacheObject.toString(), RouteVo.class); |
| | | routeToOrigin.getPolyline().addAll(0, routeRemain.getPolyline()); |
| | | routeToOrigin.setDuration(routeToOrigin.getDuration() + routeRemain.getDuration()); |
| | | routeToOrigin.setDistance(routeToOrigin.getDistance() + routeRemain.getDistance()); |
| | | if (routeRemain.getDuration() / 60 > timeRegardAsEnding && routeRemain.getDistance() / 1000 > distanceRegardAsEnding) { |
| | | log.info("连环派单 {} 车辆订单结束时间不满足条件 {} 秒 {} 米 {}", vin, routeRemain.getDuration(), routeRemain.getDistance(), orderNo); |
| | | continue; |
| | | } |
| | | |
| | | //此处找到车后先不忙给车推送接单消息,先修改订单上的车辆信息 |
| | | xpOrder.setVehicleId(xpVehicle.getId()); |
| | | xpOrder.setAcceptanceTime(LocalDateTime.now()); |
| | | xpOrder.setStatus(2); |
| | | xpOrderClient.updateOrder(xpOrder); |
| | | //剩余里程》=下一单预估里程+50 |
| | | //预估接驾行程+送驾行程 |
| | | RouteAndFareDto next = new RouteAndFareDto(); |
| | | next.setOrigin(new LonLatDto(xpOrder1.getEndLon(),xpOrder1.getEndLat())); |
| | | next.setDestination(new LonLatDto(xpOrder.getStartLon(),xpOrder.getStartLat())); |
| | | RouteVo route = xpMapClient.getDistanceAndDuration(next).getData(); |
| | | Object new_cacheObject = redisService.getCacheObject(CacheConstants.navigationEnd(xpOrder.getAppUserId().toString())); |
| | | RouteVo new_routeRemain = JSON.parseObject(new_cacheObject.toString(), RouteVo.class); |
| | | long xh = (new_routeRemain.getDistance() + route.getDistance()) / 1000 + backupPower; |
| | | if(vehiclePosition.getMileageRange() < xh){ |
| | | log.info("连环派单 {} 车辆剩余续航不满足派车条件 {} KM {}", vin, xh, orderNo); |
| | | continue; |
| | | } |
| | | |
| | | JSONObject jsonObject = new JSONObject(); |
| | | jsonObject.put("orderId", xpOrder.getId()); |
| | | jsonObject.put("endLongitude", xpOrder.getEndLat()); |
| | | jsonObject.put("endLatitude", xpOrder.getEndLat()); |
| | | redisService.setCacheObject(CacheConstants.nextOrder(luckyOder.getId().toString()), jsonObject.toJSONString()); |
| | | redisService.setCacheObject(CacheConstants.navigationStart(xpOrder.getAppUserId().toString()), routeToOrigin); |
| | | redisService.removeByPattern(quoteName,xpOrder.getOrderNumber()); |
| | | log.info("将订单 {} 从队列 {} 弹出去", orderNo, quoteName); |
| | | break; |
| | | //下一单的起点距离本单终点小于X公里,或者下一单的用车时间与本单的预计结束时间偏差小于X分钟 |
| | | next = new RouteAndFareDto(); |
| | | next.setOrigin(new LonLatDto(xpOrder1.getEndLon(),xpOrder1.getEndLat())); |
| | | next.setDestination(new LonLatDto(xpOrder.getStartLon(),xpOrder.getStartLat())); |
| | | route = xpMapClient.getDistanceAndDuration(next).getData(); |
| | | //相差秒时间 |
| | | long time = routeRemain.getDuration() - xpOrder.getCreateTime().toEpochSecond(ZoneOffset.of("+8")); |
| | | if(route.getDistance() / 1000 <= destToPassenger || time / 60 <= endingTimeToUseTime){ |
| | | log.info("连环派单 {} 找到满足条件的车辆 {}", vin, orderNo); |
| | | // 设置接驾导航数据 |
| | | //将上一单的剩余导航添加到接驾导航中 |
| | | route.getPolyline().addAll(0, routeRemain.getPolyline()); |
| | | route.setDuration(route.getDuration() + routeRemain.getDuration()); |
| | | route.setDistance(route.getDistance() + routeRemain.getDistance()); |
| | | |
| | | //此处找到车后先不忙给车推送接单消息,先修改订单上的车辆信息 |
| | | xpOrder.setVehicleId(xpOrder1.getVehicleId()); |
| | | xpOrder.setAcceptanceTime(LocalDateTime.now()); |
| | | xpOrder.setStatus(2); |
| | | xpOrderClient.updateOrder(xpOrder); |
| | | |
| | | JSONObject jsonObject = new JSONObject(); |
| | | jsonObject.put("orderId", xpOrder.getId()); |
| | | jsonObject.put("endLongitude", xpOrder.getEndLat()); |
| | | jsonObject.put("endLatitude", xpOrder.getEndLat()); |
| | | redisService.setCacheObject(CacheConstants.nextOrder(xpOrder1.getId().toString()), jsonObject.toJSONString()); |
| | | redisService.setCacheObject(CacheConstants.navigationStart(xpOrder.getAppUserId().toString()), JSON.toJSONString(route)); |
| | | redisService.removeByPattern(quoteName,xpOrder.getOrderNumber()); |
| | | log.info("将订单 {} 从队列 {} 弹出去", orderNo, quoteName); |
| | | return true; |
| | | } |
| | | } |
| | | } |
| | | return false; |