xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/controller/TokenController.java
@@ -1,5 +1,6 @@ package com.xiaopeng.account.controller; import com.xiaopeng.account.constant.I18nKeyConstant; import com.xiaopeng.account.service.ISysUserService; import com.xiaopeng.account.service.IXpOperationsUserService; import com.xiaopeng.account.service.impl.SysLoginService; @@ -11,8 +12,10 @@ import com.xiaopeng.api.model.account.XpOperationsUser; import com.xiaopeng.api.vo.account.LoginOperationUser; import com.xiaopeng.api.vo.account.LoginUser; import com.xiaopeng.api.vo.operation.SmsVo; import com.xiaopeng.common.core.constant.VerificationCodeConstants; import com.xiaopeng.common.core.domain.R; import com.xiaopeng.common.core.exception.ServiceException; import com.xiaopeng.common.core.utils.JwtUtils; import com.xiaopeng.common.core.utils.StringUtils; import com.xiaopeng.common.redis.service.RedisService; @@ -151,7 +154,6 @@ if (!xpOperationsUser.getStatus()) { return R.fail("账号已禁用!"); } // todo 后续补充验证码 // 生成6位数短信验证码 String code = String.valueOf((int) (Math.random() * 1000000)); String codeType = ""; @@ -167,19 +169,18 @@ codeType = VerificationCodeConstants.UPDATE_PASSWORD_CODE; break; } //TODO 短信服务开通后再开启 // SmsVo vo = new SmsVo(); // vo.setAppId(sms_appid); // vo.setPushType(1); // vo.setReceivers(appLoginPasswordDTO.getPhoneNumber()); // vo.setTemplateCode("RobotaxiVerifyCodeSmsTpl"); // vo.setAppPushConfigCode("RobotaxiVerifyCodeSms"); // vo.setParams(new HashMap<>()); // vo.getParams().put("code", code); // SmsDto smsDto = smsClient.pushSms(vo); // if(null == smsDto || smsDto.getCode() != 200){ // throw new ServiceException("短信发送失败", I18nKeyConstant.SMS_PUSH_FAILED); // } SmsVo vo = new SmsVo(); vo.setAppId(sms_appid); vo.setPushType(1); vo.setReceivers(appLoginPasswordDTO.getPhoneNumber()); vo.setTemplateCode("RobotaxiVerifyCodeSmsTpl"); vo.setAppPushConfigCode("RobotaxiVerifyCodeSms"); vo.setParams(new HashMap<>()); vo.getParams().put("code", code); SmsDto smsDto = smsClient.pushSms(vo); if(null == smsDto || smsDto.getCode() != 200){ throw new ServiceException("短信发送失败", I18nKeyConstant.SMS_PUSH_FAILED); } redisService.setCacheObject(codeType+appLoginPasswordDTO.getPhoneNumber(), code, 60L, TimeUnit.SECONDS); return R.ok(); } xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/controller/XpOperationsRoleController.java
@@ -6,9 +6,7 @@ import com.xiaopeng.api.model.account.XpOperationsRole; import com.xiaopeng.common.core.domain.R; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @@ -43,5 +41,17 @@ return R.ok(list); } /** * 内部调用 * 查询运维人员关联的角色列表 * * @param operationUserId 运维人员id */ @GetMapping("/inner/xp-operations-role/listByOperationUserId") public R<List<XpOperationsRole>> listByOperationUserId(@RequestParam("operationUserId") Long operationUserId) { List<XpOperationsRole> list = xpOperationsRoleService.list(new QueryWrapper<XpOperationsRole>() .eq("operations_user_id", operationUserId)); return R.ok(list); } } xp-robotaxi-account-boot/src/main/resources/mapper/account/XpOperationsRoleMapper.xml
@@ -48,7 +48,7 @@ ur.operations_user_id AS operationsUserId, ur.role_id AS roleId FROM xp_operations_role ur WHERE ur.operations_user_id = #{operationsUserId} WHERE ur.operations_user_id = #{userId} </select> </mapper> xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/operation/ReassignOrderClientFallbackFactory.java
File was deleted xp-robotaxi-api/src/main/java/com/xiaopeng/api/query/operation/PointPageListQuery.java
File was deleted xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/down/MessageType.java
File was deleted xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/down/MsgContent.java
File was deleted xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/down/RTCmdType.java
File was deleted xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/down/RtMsgHeader.java
File was deleted xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/down/cloudCreateOrder/RtTaskListResponse.java
File was deleted xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/down/cloudCreateOrder/RtTaskResult.java
File was deleted xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/down/cloudCreateOrder/TaskResultStatus.java
File was deleted xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/down/cloudOrderOperation/OrderOperationState.java
File was deleted xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/down/cloudOrderOperation/OrderOperationStatus.java
File was deleted xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/MessageType.java
File was deleted xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/MsgContent.java
File was deleted xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/RTCmdType.java
File was deleted xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/RtMsgHeader.java
File was deleted xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/navigationDeviationEvent/NavigationDeviationEvent.java
File was deleted xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/systemStatusXpu/AbnormalReason.java
File was deleted xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/systemStatusXpu/DrivingMode.java
File was deleted xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/systemStatusXpu/GearLevel.java
File was deleted xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/systemStatusXpu/ServiceAvailability.java
File was deleted xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/systemStatusXpu/SystemPhase.java
File was deleted xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/systemStatusXpu/SystemRuntimeStatus.java
File was deleted xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/systemStatusXpu/SystemStatus.java
File was deleted xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/systemStatusXpu/VehicleDynamicStatus.java
File was deleted xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/systemStatusXpu/VehicleStaticInfo.java
File was deleted xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/systemStatusXpu/VehicleStatus.java
File was deleted xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/xpuNavigationRequest/NavigationRequest.java
File was deleted xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/xpuNavigationRequest/NavigationType.java
File was deleted xp-robotaxi-api/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -1,5 +1,6 @@ com.xiaopeng.api.factory.operation.SysLogClientFallbackFactory com.xiaopeng.api.factory.account.XpAppUserCouponClientFallbackFactory com.xiaopeng.api.factory.account.XpOperationsRoleClientFallbackFactory com.xiaopeng.api.factory.account.XpAppUserClientFallbackFactory com.xiaopeng.api.factory.map.XpMapClientFallbackFactory com.xiaopeng.api.factory.operation.RemoteMenuFallbackFactory xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/controller/KafkaTestController.java
@@ -24,7 +24,6 @@ * * @param message 消息内容 */ @PostMapping("/test/kafka/xpu-high") @KafkaListener(topics = "topic-prod-robotaxi-xpu-high", groupId = "group-robotaxi-xpu") public void topicProdRobotaxiXpuHigh(String message) { log.info("收到XPU上报高优先级主题消息: {}", message); @@ -36,22 +35,9 @@ * * @param message 消息内容 */ @PostMapping("/test/kafka/xpu-normal") @KafkaListener(topics = "topic-prod-robotaxi-xpu-normal", groupId = "group-robotaxi-xpu") public void topicProdRobotaxiXpuNormal(String message) { log.info("收到XPU上报低优先级主题消息: {}", message); kafkaConsumerService.topicProdRobotaxiXpuNormal(message); } /** * 模拟推送XPU消息 * @param message * @return */ @PostMapping("/base/v1/pushXPUMessage") public R pushXPUMessage(String message) { log.info("收到XPU推送消息: {}", message); kafkaConsumerService.topicProdRobotaxiXpuHigh(message); return R.ok(); } } xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/service/KafkaConsumerService.java
@@ -273,6 +273,21 @@ //保存车辆实时位置到redis redisTemplate.opsForGeo().add("vehiclePosition:" + vin, new Point(longitude, latitude), vin); VehicleStatus vehicleStatus = systemRuntimeStatus.getVehicleStatus(); OrderStatusInfo runningOrderStatusInfo = systemRuntimeStatus.getRunningOrderStatusInfo(); String order_id = runningOrderStatusInfo.getOrderId(); //车辆动态信息 VehicleDynamicStatus dynamicStatus = vehicleStatus.getDynamicStatus(); Long orderId = null; Integer hasOrder = 0; if (StringUtils.isNotEmpty(order_id)) { if (order_id.contains("XU")) { hasOrder = 1; orderId = Long.parseLong(order_id.substring(2)); } else { orderId = Long.parseLong(order_id); } } //保存车辆实时信息到mongodb VehiclePosition vehiclePosition = mongoTemplate.findOne(new Query(Criteria.where("vin").is(vin)), VehiclePosition.class); if (null == vehiclePosition) { @@ -281,40 +296,12 @@ vehiclePosition.setPoint(new GeoJsonPoint(longitude, latitude)); vehiclePosition.setCourse(course); vehiclePosition.setAlt(alt); VehicleStatus vehicleStatus = systemRuntimeStatus.getVehicleStatus(); //车辆动态信息 VehicleDynamicStatus dynamicStatus = vehicleStatus.getDynamicStatus(); vehiclePosition.setSpeed(dynamicStatus.getSpeed()); vehiclePosition.setCurrentElectricity(dynamicStatus.getBmsSocDisp()); vehiclePosition.setMileageRange(dynamicStatus.getDstBatDisp()); //订单信息 OrderStatusInfo runningOrderStatusInfo = systemRuntimeStatus.getRunningOrderStatusInfo(); Long orderId = null; String order_id = runningOrderStatusInfo.getOrderId(); vehiclePosition.setHasOrder(0); if (StringUtils.isNotEmpty(order_id)) { if (order_id.contains("XU")) { vehiclePosition.setHasOrder(1); orderId = Long.parseLong(order_id.substring(2)); } else { orderId = Long.parseLong(order_id); } } vehiclePosition.setOrderId(orderId); mongoTemplate.save(vehiclePosition); }else{ VehicleDynamicStatus dynamicStatus = vehicleStatus.getDynamicStatus(); String order_id = runningOrderStatusInfo.getOrderId(); Long orderId = null; Integer hasOrder = 0; if (StringUtils.isNotEmpty(order_id)) { if (order_id.contains("XU")) { hasOrder = 1; orderId = Long.parseLong(order_id.substring(2)); } else { orderId = Long.parseLong(order_id); } } vehiclePosition.setOrderId(orderId); Update update = new Update() .set("point", new GeoJsonPoint(longitude, latitude)) xp-robotaxi-automatic-pilot-boot/src/main/resources/bootstrap.yml
@@ -29,6 +29,7 @@ namespace: 5185ac4b-6369-48eb-a21b-a7cbc441c5f1 username: nacos password: nacos ip: 192.168.110.85 config: # 配置中心地址 server-addr: 192.168.110.80:8848 xp-robotaxi-automatic-pilot-boot/src/test/java/com/ruoyi/account/RuoYiAccountApplicationTests.java
File was deleted xp-robotaxi-automatic-pilot-boot/xp-modules-account.iml
File was deleted xp-robotaxi-common/xp-common-redis/src/main/java/com/xiaopeng/common/redis/service/RedisService.java
@@ -149,7 +149,7 @@ * @param key 缓存的键值 * @return 缓存的对象 */ public Long addToHead(String key, Long value) { public Long addToHead(String key, Object value) { return redisTemplate.opsForList().leftPush(key, value); } /** xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/service/impl/XpPricingServiceImpl.java
@@ -469,6 +469,7 @@ // 判断当天取消的次数 后台配置 redis 查询 Object cancelOrder = redisService.getCacheObject("CANCEL_ORDER_" + uid); log.info("取消次数:{}", cancelOrder); // 静默处理 boolean isSilent = false; if (cancelOrder != null) { @@ -501,7 +502,7 @@ // 生成订单数据 XpOrder xpOrder = new XpOrder(); xpOrder.setVehicleId(1l); // xpOrder.setVehicleId(1l); // xpOrder.setStartMileage(Double.valueOf(startMileage)); @@ -589,18 +590,22 @@ // 找出现在所有的队列 通过计算距离 算出目前应该放在那个队列 如果没有符合的新增一个队列 符合后看是否白名单账号 是则直接放在队列前端 Set<String> quoteMatchName = redisService.getQuoteMatchName(CacheConstants.QUEUE_POINT_ID); log.info("当前队列:{}", quoteMatchName); for (String s : quoteMatchName) { // QUEUE_POINT_ID-1-30.233,120.233 String lonLat = s.split("-")[2]; // 和上车点进行判断是否<maxPushDistance double v = FastDistanceCalculator.distanceFast(Double.parseDouble(lonLat.split(",")[1]), Double.parseDouble(lonLat.split(",")[0]), xpPoint.getPointLat(), xpPoint.getPointLon()); if (v < maxPushDistance) { String value = orderId + "_" + xpPoint.getPointLon() + "," + xpPoint.getPointLat() + "_0" + "_" + uid + "_" + xpOrder.getOrderNumber() + "_" + distance + "_" + duration + "_" + routeAndFareDto.getRoutePlanRule(); if (isPriorityDispatch) { // 头部 value 订单_经纬度_状态_用户id_订单编号_距离_时间 redisService.addToTail(s, orderId + "_" + xpPoint.getPointLon() + "," + xpPoint.getPointLat() + "_0" + "_" + uid + "_" + xpOrder.getOrderNumber() + "_" + distance + "_" + duration + "_" + routeAndFareDto.getRoutePlanRule()); redisService.addToHead(s, value); log.info("添加到队列头部:{} {}", s, value); } else { // 尾部 redisService.addToTail(s, orderId + "_" + xpPoint.getPointLon() + "," + xpPoint.getPointLat() + "_0" + "_" + uid + "_" + xpOrder.getOrderNumber() + "_" + distance + "_" + duration + "_" + routeAndFareDto.getRoutePlanRule()); redisService.addToTail(s, value); log.info("添加到队列尾部:{} {}", s, value); } xpOrder.setQueueName(s); xpOrderClient.updateOrder(xpOrder); @@ -621,6 +626,7 @@ String key = CacheConstants.QUEUE_POINT_ID + "-" + xpPoint.getId() + "-" + xpPoint.getPointLon() + "," + xpPoint.getPointLat(); redisService.setCacheList(key, Arrays.asList(orderId + "_" + xpPoint.getPointLon() + "," + xpPoint.getPointLat() + "_0" + "_" + uid + "_" + xpOrder.getOrderNumber() + "_" + distance + "_" + duration + "_" + routeAndFareDto.getRoutePlanRule())); log.info("订单推单:{} {}", key, redisService.getCacheList(key)); xpOrder.setQueueName(key); xpOrderClient.updateOrder(xpOrder); xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/utils/XpPricingUtil.java
@@ -231,6 +231,7 @@ rule.put("num3", startingFare.get("num5")); rule.put("num4", startingFare.get("num6")); rule.put("num5", startingFare.get("num7")); rule.put("num6", startingFare.get("num4")); rule.put("startTime", startingFare.getString("num1")); rule.put("endTime", startingFare.getString("num2")); xp-robotaxi-itinerary-boot/xp-modules-account.iml
File was deleted xp-robotaxi-maintenance-boot/xp-modules-account.iml
File was deleted xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/constant/I18nKeyConstant.java
@@ -86,4 +86,15 @@ String CRUISE_PLAN_ADD_FAIL = "cruise.plan.add.fail"; // 编辑巡游计划失败 String CRUISE_PLAN_EDIT_FAIL = "cruise.plan.edit.fail"; // 点位-运营区域ID不能为空 String POINT_ELECTRONIC_AREA_ID_EMPTY = "point.electronic.area.id.empty"; // 点位-运营区域不存在 String POINT_ELECTRONIC_AREA_NOT_EXIST = "point.electronic.area.not.exist"; // 点位-城市信息不存在 String POINT_CITY_NOT_EXIST = "point.city.not.exist"; // 点位-编号锁获取失败 String POINT_NUMBER_LOCK_FAIL = "point.number.lock.fail"; // 点位-编号解析失败 String POINT_NUMBER_PARSE_FAIL = "point.number.parse.fail"; } xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpPointManagementController.java
@@ -88,11 +88,8 @@ @ApiOperation(value = "新增点位") // @Transactional // @ShardingSphereTransactionType(TransactionType.BASE) public R add(@Validated @RequestBody PointAddDto pointAddDto) { XpPoint xpPoint = new XpPoint(); BeanUtils.copyProperties(pointAddDto, xpPoint); xpPointService.save(xpPoint); return R.ok(); public R<XpPoint> add(@Validated @RequestBody PointAddDto pointAddDto) { return R.ok(xpPointService.addPointWithGeneratedNumber(pointAddDto)); } /** xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/mapper/XpPointMapper.java
@@ -9,6 +9,7 @@ import com.xiaopeng.api.vo.order.XpPointsListVo; import com.xiaopeng.common.core.web.page.PageInfo; import com.xiaopeng.map.query.PointByNameQuery; import org.apache.ibatis.annotations.Select; import org.apache.ibatis.annotations.Param; import java.util.List; @@ -31,4 +32,7 @@ List<XpPointsListVo> queryPointByName(@Param("query") PointByNameQuery query); List<XpPoint> pageList(@Param("pageInfo") PageInfo<XpPoint> pageInfo, @Param("query") PointPageListListQuery query); @Select("SELECT point_number FROM xp_point WHERE point_number LIKE CONCAT(#{cityPrefix}, '-', #{bizType}, '-%') ORDER BY point_number DESC LIMIT 1") String selectMaxPointNumber(@Param("cityPrefix") String cityPrefix, @Param("bizType") String bizType); } xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/XpPointService.java
@@ -2,6 +2,7 @@ import com.baomidou.mybatisplus.extension.service.IService; import com.xiaopeng.api.dto.operation.PointAddDto; import com.xiaopeng.api.dto.operation.PointMapQuery; import com.xiaopeng.api.dto.order.HistoryEndPointsDto; import com.xiaopeng.api.dto.order.HistoryStartPointsDto; @@ -33,6 +34,11 @@ public interface XpPointService extends IService<XpPoint> { /** * 新增点位并根据规则生成点位编号 */ XpPoint addPointWithGeneratedNumber(@Valid PointAddDto pointAddDto); /** * 获取附近上车站点 */ NearestVo nearest(@Valid NearestDto dto); xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/serviceimpl/XpPointServiceImpl.java
@@ -3,10 +3,13 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.xiaopeng.api.dto.operation.PointAddDto; import com.xiaopeng.api.dto.operation.PointMapQuery; import com.xiaopeng.api.dto.order.HistoryEndPointsDto; import com.xiaopeng.api.dto.order.HistoryStartPointsDto; import com.xiaopeng.api.model.operation.XpElectronicFenceArea; import com.xiaopeng.api.model.operation.XpPoint; import com.xiaopeng.api.model.operation.XpRegion; import com.xiaopeng.api.model.operation.XpSystemSetting; import com.xiaopeng.api.query.operation.PointListQuery; import com.xiaopeng.api.query.operation.PointPageListListQuery; @@ -15,12 +18,17 @@ import com.xiaopeng.api.vo.order.XpPointsListVo; import com.xiaopeng.api.vo.order.XpPointsSearchVo; import com.xiaopeng.common.core.constant.CacheConstants; import com.xiaopeng.common.core.exception.ServiceException; import com.xiaopeng.common.core.utils.StringUtils; import com.xiaopeng.common.core.web.page.PageInfo; import com.xiaopeng.common.redis.service.RedisService; import com.xiaopeng.map.constant.I18nKeyConstant; import com.xiaopeng.map.dto.NearestDto; import com.xiaopeng.map.mapper.XpPointMapper; import com.xiaopeng.map.mapper.XpRegionMapper; import com.xiaopeng.map.mapper.XpSystemSettingMapper; import com.xiaopeng.map.query.PointByNameQuery; import com.xiaopeng.map.service.XpElectronicFenceAreaService; import com.xiaopeng.map.service.XpPointService; import com.xiaopeng.map.utils.TimeRangeChecker; import com.xiaopeng.map.utils.holiday.HolidayUtil; @@ -28,6 +36,12 @@ import com.xiaopeng.map.vo.NearestNextVo; import com.xiaopeng.map.vo.NearestVo; import com.xiaopeng.map.vo.OrderDistanceVo; import lombok.extern.slf4j.Slf4j; import net.sourceforge.pinyin4j.PinyinHelper; import org.redisson.api.RLock; import org.redisson.api.RedissonClient; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import javax.annotation.Resource; @@ -35,6 +49,7 @@ import java.util.ArrayList; import java.util.Comparator; import java.util.List; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; /** @@ -47,7 +62,13 @@ * @since 2026-02-03 */ @Service @Slf4j public class XpPointServiceImpl extends ServiceImpl<XpPointMapper, XpPoint> implements XpPointService { private static final String POINT_BIZ_TYPE = "PUD"; private static final int SERIAL_WIDTH = 6; private static final int LOCK_WAIT_SECONDS = 5; private static final int LOCK_LEASE_SECONDS = 30; @Resource private XpSystemSettingMapper xpSystemSettingMapper; @@ -58,6 +79,60 @@ @Resource private HolidayUtil holidayUtil; @Resource private XpElectronicFenceAreaService xpElectronicFenceAreaService; @Resource private XpRegionMapper xpRegionMapper; @Autowired private RedissonClient redissonClient; @Override public XpPoint addPointWithGeneratedNumber(PointAddDto pointAddDto) { if (pointAddDto == null) { throw new ServiceException("参数不能为空", I18nKeyConstant.SYSTEM_EXCEPTION); } if (pointAddDto.getElectronicAreaId() == null) { throw new ServiceException("运营区域ID不能为空", I18nKeyConstant.POINT_ELECTRONIC_AREA_ID_EMPTY); } String cityPrefix = buildCityPrefix(pointAddDto.getElectronicAreaId()); String lockKey = buildPointNumberLockKey(cityPrefix, POINT_BIZ_TYPE); RLock lock = redissonClient.getLock(lockKey); boolean locked = false; String pointNumber; try { locked = lock.tryLock(LOCK_WAIT_SECONDS, LOCK_LEASE_SECONDS, TimeUnit.SECONDS); if (!locked) { throw new ServiceException("点位编号生成繁忙,请稍后重试", I18nKeyConstant.POINT_NUMBER_LOCK_FAIL); } String maxPointNumber = this.baseMapper.selectMaxPointNumber(cityPrefix, POINT_BIZ_TYPE); int nextSerial = 1; if (StringUtils.hasText(maxPointNumber)) { nextSerial = parseSerialOrThrow(maxPointNumber) + 1; } pointNumber = cityPrefix + "-" + POINT_BIZ_TYPE + "-" + String.format("%0" + SERIAL_WIDTH + "d", nextSerial); } catch (InterruptedException e) { Thread.currentThread().interrupt(); throw new ServiceException("点位编号生成繁忙,请稍后重试", I18nKeyConstant.POINT_NUMBER_LOCK_FAIL); } finally { try { if (locked && lock.isHeldByCurrentThread()) { lock.unlock(); } } catch (Exception e) { log.warn("释放点位编号生成锁失败 lockKey={}", lockKey, e); } } XpPoint xpPoint = new XpPoint(); BeanUtils.copyProperties(pointAddDto, xpPoint); xpPoint.setPointNumber(pointNumber); this.save(xpPoint); return xpPoint; } @Override public NearestVo nearest(NearestDto dto) { @@ -112,6 +187,57 @@ } private String buildCityPrefix(Long electronicAreaId) { XpElectronicFenceArea area = xpElectronicFenceAreaService.getById(electronicAreaId); if (area == null) { throw new ServiceException("运营区域不存在", I18nKeyConstant.POINT_ELECTRONIC_AREA_NOT_EXIST); } if (!StringUtils.hasText(area.getCityCode())) { throw new ServiceException("城市信息不存在", I18nKeyConstant.POINT_CITY_NOT_EXIST); } XpRegion region = xpRegionMapper.selectOne(new LambdaQueryWrapper<XpRegion>() .eq(XpRegion::getCode, area.getCityCode())); if (region == null || !StringUtils.hasText(region.getName())) { throw new ServiceException("城市信息不存在", I18nKeyConstant.POINT_CITY_NOT_EXIST); } String name = region.getName(); String prefix = name.length() <= 2 ? name : name.substring(0, 2); return getPinyinInitials(prefix).toUpperCase(); } private static String buildPointNumberLockKey(String cityPrefix, String bizType) { return "xp:point:number:" + cityPrefix + ":" + bizType; } private static String getPinyinInitials(String chinese) { StringBuilder pinyinInitials = new StringBuilder(); for (char c : chinese.toCharArray()) { String[] pinyinArray = PinyinHelper.toHanyuPinyinStringArray(c); if (pinyinArray != null && pinyinArray.length > 0) { pinyinInitials.append(pinyinArray[0].charAt(0)); } } return pinyinInitials.toString(); } private static int parseSerialOrThrow(String pointNumber) { String[] parts = pointNumber.split("-"); if (parts.length < 3) { throw new ServiceException("点位编号生成失败(历史编号格式异常)", I18nKeyConstant.POINT_NUMBER_PARSE_FAIL); } String serialPart = parts[parts.length - 1]; if (serialPart.length() != SERIAL_WIDTH) { throw new ServiceException("点位编号生成失败(历史编号格式异常)", I18nKeyConstant.POINT_NUMBER_PARSE_FAIL); } try { return Integer.parseInt(serialPart); } catch (NumberFormatException e) { throw new ServiceException("点位编号生成失败(历史编号格式异常)", I18nKeyConstant.POINT_NUMBER_PARSE_FAIL); } } public boolean getInTime(LocalTime now, Integer effectivePeriod, String effectiveTimePeriod){ xp-robotaxi-map-boot/src/main/resources/i18n/messages.properties
@@ -34,3 +34,8 @@ cruise.plan.vehicle.already.bound=车辆已关联其他巡游计划 cruise.plan.add.fail=新增巡游计划失败 cruise.plan.edit.fail=编辑巡游计划失败 point.electronic.area.id.empty=运营区域ID不能为空 point.electronic.area.not.exist=运营区域不存在 point.city.not.exist=城市信息不存在 point.number.lock.fail=点位编号生成繁忙,请稍后重试 point.number.parse.fail=点位编号生成失败(历史编号格式异常) xp-robotaxi-map-boot/src/main/resources/i18n/messages_en_US.properties
@@ -27,3 +27,8 @@ cruise.plan.vehicle.duplicate=Duplicate vehicle ID cruise.plan.vehicle.already.bound=Vehicle [{0}] has been associated with other cruising plans cruise.plan.add.fail=The new cruise plan failed point.electronic.area.id.empty=Electronic fence area ID cannot be empty point.electronic.area.not.exist=Electronic fence area does not exist point.city.not.exist=City information does not exist point.number.lock.fail=Point number generation is busy, please try again later point.number.parse.fail=Point number generation failed (invalid historical number format) xp-robotaxi-map-boot/src/main/resources/i18n/messages_zh_CN.properties
@@ -27,3 +27,8 @@ cruise.plan.vehicle.duplicate=车辆ID重复 cruise.plan.vehicle.already.bound=车辆[{0}]已关联其他巡游计划 cruise.plan.add.fail=新增巡游计划失败 point.electronic.area.id.empty=运营区域ID不能为空 point.electronic.area.not.exist=运营区域不存在 point.city.not.exist=城市信息不存在 point.number.lock.fail=点位编号生成繁忙,请稍后重试 point.number.parse.fail=点位编号生成失败(历史编号格式异常) xp-robotaxi-map-boot/xp-modules-account.iml
File was deleted xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/SysMenuController.java
@@ -5,10 +5,8 @@ import com.xiaopeng.common.core.web.controller.BaseController; import com.xiaopeng.operation.service.ISysMenuService; import io.swagger.annotations.ApiOperation; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; import io.swagger.annotations.ApiParam; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import java.util.ArrayList; @@ -46,10 +44,10 @@ * 获取全部菜单树 * @return */ @GetMapping("/api/v1/getMenuTree") @GetMapping("/api/v1/getMenuTree/{type}") @ApiOperation(value = "获取全部菜单树", tags = {"管理后台-权限组设置"}) public R<List<SysMenu>> getMenuTree() { List<SysMenu> menus = menuService.getMenuTree(); public R<List<SysMenu>> getMenuTree(@ApiParam(name = "type", value = "1=管理端 2=运维app") @PathVariable Integer type) { List<SysMenu> menus = menuService.getMenuTree(type); return R.ok(menus); } @@ -59,4 +57,10 @@ return R.ok(menuService.getPermission()); } @GetMapping("/api/v1/getAppPermission") @ApiOperation(value = "获取获取当前登录用户权限列表", tags = {"运维APP-个人中心"}) public R<List<SysMenu>> getAppPermission(){ return R.ok(menuService.getAppPermission()); } } xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/ISysMenuService.java
@@ -27,11 +27,17 @@ *获取全部菜单树 * @return */ List<SysMenu> getMenuTree(); List<SysMenu> getMenuTree(Integer type); /** *获取获取当前登录用户菜单列表 * @return */ List<SysMenu> getPermission(); /** * 获取运维人员权限列表 * @return */ List<SysMenu> getAppPermission(); } xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/SysMenuServiceImpl.java
@@ -4,8 +4,10 @@ import com.xiaopeng.api.feignClient.account.SysGroupMenuClient; import com.xiaopeng.api.feignClient.account.SysRoleClient; import com.xiaopeng.api.feignClient.account.SysUserRoleClient; import com.xiaopeng.api.feignClient.account.XpOperationsRoleClient; import com.xiaopeng.api.model.account.SysRole; import com.xiaopeng.api.model.account.SysUserRole; import com.xiaopeng.api.model.account.XpOperationsRole; import com.xiaopeng.api.model.operation.SysMenu; import com.xiaopeng.common.core.domain.R; import com.xiaopeng.common.security.service.TokenService; @@ -42,6 +44,9 @@ @Autowired private SysGroupMenuClient sysGroupMenuClient; @Autowired private XpOperationsRoleClient xpOperationsRoleClient; /** * 根据菜单ID列表查询菜单列表 * @@ -59,8 +64,8 @@ } @Override public List<SysMenu> getMenuTree() { List<SysMenu> all = list(); public List<SysMenu> getMenuTree(Integer type) { List<SysMenu> all = lambdaQuery().eq(SysMenu::getGroupType, type).list(); if (all == null || all.isEmpty()) { return Collections.emptyList(); } @@ -184,4 +189,139 @@ return Collections.emptyList(); } } @Override public List<SysMenu> getAppPermission() { // 1. 获取当前登录用户ID Long operationUserId = tokenService.getLoginOperationUser().getId(); if (operationUserId == null) { log.warn("获取当前登录用户ID失败"); return Collections.emptyList(); } // 2. 查询运维APP菜单(group_type=2) List<SysMenu> appMenus = this.lambdaQuery() .eq(SysMenu::getGroupType, 2) .list(); if (appMenus == null || appMenus.isEmpty()) { return Collections.emptyList(); } // 3. 查询运维人员关联的角色(一个用户可多个角色) Set<Long> roleIds = new HashSet<>(); try { R<List<XpOperationsRole>> rolesResult = xpOperationsRoleClient.listByOperationUserId(operationUserId); if (rolesResult != null && rolesResult.getData() != null) { for (XpOperationsRole r : rolesResult.getData()) { if (r != null && r.getRoleId() != null) { roleIds.add(r.getRoleId()); } } } } catch (Exception e) { log.error("查询运维人员角色关联异常, operationUserId={}", operationUserId, e); } // 4. 通过 role -> groupId -> group_menu 获取允许的菜单ID集合 Set<Long> allowedMenuIds = new HashSet<>(); if (!roleIds.isEmpty()) { Set<Long> groupIds = new HashSet<>(); for (Long roleId : roleIds) { try { R<SysRole> roleResult = sysRoleClient.getRoleById(roleId); if (roleResult != null && roleResult.getData() != null && roleResult.getData().getGroupId() != null) { groupIds.add(roleResult.getData().getGroupId()); } } catch (Exception e) { log.error("查询角色信息异常, roleId={}", roleId, e); } } for (Long groupId : groupIds) { try { R<List<Long>> menuIdsResult = sysGroupMenuClient.selectMenuIdsByGroupId(groupId); if (menuIdsResult != null && menuIdsResult.getData() != null) { allowedMenuIds.addAll(menuIdsResult.getData()); } } catch (Exception e) { log.error("查询权限组菜单ID异常, groupId={}", groupId, e); } } } // 5. 仅保留运维APP的菜单ID,避免无关ID影响 visible Set<Long> appMenuIds = appMenus.stream() .filter(Objects::nonNull) .map(SysMenu::getId) .filter(Objects::nonNull) .collect(Collectors.toSet()); allowedMenuIds.retainAll(appMenuIds); // 6. 组装树形结构,并用 visible 体现权限可见性(0可见 1不可见) return buildAppMenuTreeWithVisible(appMenus, allowedMenuIds); } private List<SysMenu> buildAppMenuTreeWithVisible(List<SysMenu> menus, Set<Long> allowedMenuIds) { Map<Long, SysMenu> idMap = new HashMap<>(); for (SysMenu m : menus) { if (m != null && m.getId() != null) { idMap.put(m.getId(), m); } } Map<Long, List<SysMenu>> childrenMap = menus.stream() .filter(Objects::nonNull) .filter(m -> m.getId() != null) .collect(Collectors.groupingBy(m -> { Long pid = m.getParentId(); return pid == null ? 0L : pid; })); // 根节点:parentId 为 0/null,或父节点不在当前 group_type=2 集合内 List<SysMenu> roots = menus.stream() .filter(Objects::nonNull) .filter(m -> m.getId() != null) .filter(m -> { Long pid = m.getParentId(); if (pid == null || pid == 0L) { return true; } return !idMap.containsKey(pid); }) .sorted(Comparator.comparing(SysMenu::getOrderNum, Comparator.nullsLast(Integer::compareTo))) .collect(Collectors.toList()); for (SysMenu root : roots) { fillChildrenAndVisible(root, childrenMap, allowedMenuIds, new HashSet<>()); } return roots; } private boolean fillChildrenAndVisible(SysMenu node, Map<Long, List<SysMenu>> childrenMap, Set<Long> allowedMenuIds, Set<Long> path) { Long id = node.getId(); if (id != null && !path.add(id)) { boolean visible = allowedMenuIds.contains(id); node.setChildren(Collections.emptyList()); node.setVisible(visible ? "0" : "1"); return visible; } List<SysMenu> children = childrenMap.getOrDefault(id == null ? 0L : id, Collections.emptyList()).stream() .filter(Objects::nonNull) .sorted(Comparator.comparing(SysMenu::getOrderNum, Comparator.nullsLast(Integer::compareTo))) .collect(Collectors.toList()); boolean anyChildVisible = false; for (SysMenu child : children) { anyChildVisible |= fillChildrenAndVisible(child, childrenMap, allowedMenuIds, path); } node.setChildren(children); boolean selfVisible = id != null && allowedMenuIds.contains(id); boolean visible = selfVisible || anyChildVisible; node.setVisible(visible ? "0" : "1"); if (id != null) { path.remove(id); } return visible; } } xp-robotaxi-operation-boot/xp-modules-account.iml
File was deleted xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java
@@ -4,8 +4,8 @@ import cn.hutool.core.util.IdUtil; import cn.hutool.json.JSONUtil; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSON; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; @@ -25,6 +25,7 @@ import com.xiaopeng.api.dto.statistics.StatisticsQueryDTO; import com.xiaopeng.api.dto.vehicleConvoy.BaseVehicleUserDto; import com.xiaopeng.api.feignClient.account.UserResourcesClient; import com.xiaopeng.api.feignClient.account.XpAppUserClient; import com.xiaopeng.api.feignClient.account.XpAppUserCouponClient; import com.xiaopeng.api.feignClient.automaticPilot.OrderMissionClient; import com.xiaopeng.api.feignClient.maintenance.XpTaskRuleClient; @@ -32,17 +33,20 @@ import com.xiaopeng.api.feignClient.operation.XpPointClient; import com.xiaopeng.api.feignClient.operation.XpPricingClient; import com.xiaopeng.api.feignClient.operation.XpSystemSettingClient; import com.xiaopeng.api.feignClient.order.XpCruiseOrderClient; import com.xiaopeng.api.feignClient.pushMessage.XpPushMessageClient; import com.xiaopeng.api.feignClient.vehicleConvoy.UserVehicleClient; import com.xiaopeng.api.feignClient.vehicleConvoy.XpFleetClient; import com.xiaopeng.api.feignClient.vehicleConvoy.XpFleetVehicleClient; import com.xiaopeng.api.feignClient.vehicleConvoy.XpVehicleClient; import com.xiaopeng.api.model.account.XpAppUser; import com.xiaopeng.api.model.maintenance.XpTaskRule; import com.xiaopeng.api.model.operation.*; import com.xiaopeng.api.model.order.*; import com.xiaopeng.api.model.vehicleConvoy.XpFleet; import com.xiaopeng.api.model.vehicleConvoy.XpVehicle; import com.xiaopeng.api.vo.OrderType; import com.xiaopeng.api.vo.account.GetUserListByUidsVo; import com.xiaopeng.api.vo.account.UserCouponVo; import com.xiaopeng.api.vo.automaticPilot.VehiclePosition; import com.xiaopeng.api.vo.automaticPilot.proto.down.cloudOrderOperation.OrderOperationType; @@ -85,10 +89,13 @@ import com.xiaopeng.order.service.IXpOrderReassignService; import com.xiaopeng.order.service.IXpOrderService; import com.xiaopeng.order.utils.TaxiPricingDemoService; import com.xiaopeng.order.utils.TrajectoryGenerator; import com.xiaopeng.order.utils.holiday.HolidayUtil; import com.xiaopeng.order.vo.OrderDetailVo; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.shardingsphere.transaction.annotation.ShardingSphereTransactionType; import org.apache.shardingsphere.transaction.core.TransactionType; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Lazy; @@ -96,6 +103,7 @@ import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.Query; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; @@ -362,7 +370,10 @@ return new JSONObject(); } try { UserResourcesDto userListByUids = userResourcesClient.getUserListByUids(new ArrayList<>(userIds), false); GetUserListByUidsVo getUserListByUidsVo = new GetUserListByUidsVo(); getUserListByUidsVo.setUids(new ArrayList<>(userIds)); getUserListByUidsVo.setGetPreCarOwner(Boolean.TRUE); UserResourcesDto userListByUids = userResourcesClient.getUserListByUids(getUserListByUidsVo); if (userListByUids.getCode().equals(HttpStatus.SUCCESS)) { return JSONObject.parseObject(userListByUids.getData().toString()); } @@ -851,13 +862,13 @@ // 保留2位数小数 Double distance = datum.getDistance(); datum.setDistance(BigDecimal.valueOf(distance).setScale(2, RoundingMode.HALF_UP).doubleValue()); xpOrders.stream().filter(e -> e.getEndPointId().equals(datum.getId())).findFirst().ifPresent( order -> { xpOrders.stream().filter(e->e.getStartPointId().equals(datum.getId())).findFirst().ifPresent( order->{ datum.setNum(order.getNum()); } ); } data = data.stream().sorted(Comparator.comparingInt(XpHistoryStartPointsVo::getNum).reversed()).collect(Collectors.toList()); data = data.stream().sorted(Comparator.comparingInt(XpHistoryStartPointsVo::getNum).reversed()).collect(Collectors.toList()); return data; @@ -882,13 +893,13 @@ // 保留2位数小数 Double distance = datum.getDistance(); datum.setDistance(BigDecimal.valueOf(distance).setScale(2, RoundingMode.HALF_UP).doubleValue()); xpOrders.stream().filter(e -> e.getEndPointId().equals(datum.getId())).findFirst().ifPresent( order -> { xpOrders.stream().filter(e->e.getEndPointId().equals(datum.getId())).findFirst().ifPresent( order->{ datum.setNum(order.getNum()); } ); } data = data.stream().sorted(Comparator.comparingInt(XpHistoryEndPointsVo::getNum).reversed()).collect(Collectors.toList()); data = data.stream().sorted(Comparator.comparingInt(XpHistoryEndPointsVo::getNum).reversed()).collect(Collectors.toList()); return data; @@ -906,7 +917,7 @@ Page<XpOrderHistoryListVO> page = new Page<>(query.getPageNum(), query.getPageSize()); List<XpOrderHistoryListVO> list = this.baseMapper.getHistoryOrderList(page, query, Long.parseLong(uid)); XpOrderHistoryVO xpOrderHistoryVO = new XpOrderHistoryVO(); if (list.isEmpty()) { if(list.isEmpty()){ return xpOrderHistoryVO; } @@ -930,7 +941,7 @@ for (XpOrderHistoryListVO xpOrderHistoryListVO : value) { XpPoint xpPoint = pointList.stream().filter(e -> e.getId().equals(xpOrderHistoryListVO.getStartPointId())).findFirst().orElse(null); if (xpPoint != null) { if(xpPoint!=null){ xpOrderHistoryListVO.setStartPointName(xpPoint.getPointName()); xpOrderHistoryListVO.setStartLat(xpPoint.getPointLat()); xpOrderHistoryListVO.setStartLon(xpPoint.getPointLon()); @@ -939,7 +950,7 @@ } xpPoint = pointList.stream().filter(e -> e.getId().equals(xpOrderHistoryListVO.getEndPointId())).findFirst().orElse(null); if (xpPoint != null) { if(xpPoint!=null){ xpOrderHistoryListVO.setEndPointName(xpPoint.getPointName()); xpOrderHistoryListVO.setEndLat(xpPoint.getPointLat()); xpOrderHistoryListVO.setEndLon(xpPoint.getPointLon()); @@ -969,15 +980,15 @@ public void cancelOrder(Long orderId, String uid) { XpOrder order = this.getById(orderId); if (order == null) { throw new ServiceException("订单不存在", I18nKeyConstant.ORDER_NOT_EXISTS); throw new ServiceException("订单不存在",I18nKeyConstant.ORDER_NOT_EXISTS); } if (!order.getAppUserId().toString().equals(uid)) { throw new ServiceException("订单不存在", I18nKeyConstant.ORDER_NOT_EXISTS); throw new ServiceException("订单不存在",I18nKeyConstant.ORDER_NOT_EXISTS); } if (order.getStatus() > 5 || order.getStatus() < 1) { throw new ServiceException("订单状态错误", I18nKeyConstant.ORDER_STATUS_ERROR); throw new ServiceException("订单状态错误",I18nKeyConstant.ORDER_STATUS_ERROR); } if (order.getStatus() == 1) { if(order.getStatus()==1){ order.setStatus(0); order.setAppUserId(null); baseMapper.updateById(order); @@ -991,7 +1002,7 @@ R<XpVehicle> xpVehicleR = xpVehicleClient.queryById(vehicleId); XpVehicle xpVehicle = xpVehicleR.getData(); if (xpVehicle == null) { throw new ServiceException("车辆不存在", I18nKeyConstant.VEHICLE_NOT_EXISTS); throw new ServiceException("车辆不存在",I18nKeyConstant.VEHICLE_NOT_EXISTS); } cancelTaxiPassengerVo.setVin(xpVehicle.getVehicleVin()); cancelTaxiPassengerVo.setUid(order.getAppUserId().toString()); @@ -1000,7 +1011,7 @@ cancelTaxiPassengerVo.setAppId(""); BaseVehicleUserDto baseVehicleUserDto = userVehicleClient.cancelTaxiPassenger(cancelTaxiPassengerVo); if (baseVehicleUserDto == null) { if (baseVehicleUserDto==null) { // TODO 本地无法调通 // throw new RuntimeException("取消订单失败"); } @@ -1024,7 +1035,7 @@ } // 下发命令 if (order.getStatus() > 1) { if(order.getStatus()>1){ PushOrderDto pushOrderDto = new PushOrderDto(); pushOrderDto.setOrderId(order.getId().toString()); pushOrderDto.setVin(xpVehicle.getVehicleVin()); @@ -1039,7 +1050,7 @@ public void cancelOrder(String orderId) { XpOrder order = this.getById(orderId); if (order == null) { throw new ServiceException("订单不存在", I18nKeyConstant.ORDER_NOT_EXISTS); throw new ServiceException("订单不存在",I18nKeyConstant.ORDER_NOT_EXISTS); } order.setStatus(0); order.setAppUserId(null); @@ -1073,7 +1084,7 @@ log.info("订单取消消息推送完毕"); // 下发命令 if (order.getStatus() > 1) { if(order.getStatus()>1){ PushOrderDto pushOrderDto = new PushOrderDto(); pushOrderDto.setOrderId(order.getId().toString()); pushOrderDto.setVin(xpVehicle.getVehicleVin()); @@ -1094,13 +1105,13 @@ public void comment(XpOrderCommentDto dto, String uid) { XpOrder xpOrder = this.getById(dto.getOrderId()); if (xpOrder == null) { throw new ServiceException("订单不存在", I18nKeyConstant.ORDER_NOT_EXISTS); throw new ServiceException("订单不存在",I18nKeyConstant.ORDER_NOT_EXISTS); } if (!xpOrder.getAppUserId().toString().equals(uid)) { throw new ServiceException("订单不存在", I18nKeyConstant.ORDER_NOT_EXISTS); throw new ServiceException("订单不存在",I18nKeyConstant.ORDER_NOT_EXISTS); } if (xpOrder.getStatus() != 9) { throw new ServiceException("订单状态错误", I18nKeyConstant.ORDER_STATUS_ERROR); throw new ServiceException("订单状态错误",I18nKeyConstant.ORDER_STATUS_ERROR); } xpOrder.setAppUserId(null); xpOrder.setStatus(10); @@ -1221,6 +1232,7 @@ } // 根据订单所属开通城市id 查询定价 R<XpPricing> pricingByCityId = xpPricingClient.getPricingByCid(order.getCityId()); XpPricing pricing = pricingByCityId.getData(); @@ -1239,13 +1251,13 @@ // TaxiPricingDemoService.GpsPoint point = new TaxiPricingDemoService.GpsPoint(trajectory.getDistance(), trajectory.getLocatetime()); // gpsPoints.add(point); // } // 补充临时轨迹数据 // 补充临时轨迹数据 List<TaxiPricingDemoService.GpsPoint> gpsPoints = TaxiPricingDemoService.createMockGpsPoints(DateUtils.toDate(order.getCreateTime())); TaxiPricingDemoService.PricingConfig config = new TaxiPricingDemoService.PricingConfig(); JSONArray startingFareJsonArray = JSONArray.parseArray(pricing.getStartingFareJson()); if (pricing.getPricingType() == 1) { if(pricing.getPricingType()==1){ JSONObject basicPricingJson = JSONObject.parseObject(pricing.getBasicPricingJson()); config.peaks.add(new TaxiPricingDemoService.PricingRule("高峰期", basicPricingJson.getString("num21").split(" - ")[0], basicPricingJson.getString("num21").split(" - ")[1], Double.parseDouble(basicPricingJson.getString("num24")), Double.parseDouble(basicPricingJson.getString("num25")), Double.parseDouble(basicPricingJson.getString("num26")), Double.parseDouble(basicPricingJson.getString("num27")), Double.parseDouble(basicPricingJson.getString("num28")))); config.peaks.add(new TaxiPricingDemoService.PricingRule("高峰期", basicPricingJson.getString("num22").split(" - ")[0], basicPricingJson.getString("num22").split(" - ")[1], Double.parseDouble(basicPricingJson.getString("num24")), Double.parseDouble(basicPricingJson.getString("num25")), Double.parseDouble(basicPricingJson.getString("num26")), Double.parseDouble(basicPricingJson.getString("num27")), Double.parseDouble(basicPricingJson.getString("num28")))); @@ -1280,7 +1292,7 @@ System.err.println("--------------------------"); System.err.println("应付总额: " + totalAmount + " 元"); BigDecimal startMoney = BigDecimal.ZERO; // 默认费率1 // 默认费率1 double priceRate = 1; if (pricing.getIsDynamicPrice() == 1) { // 先判断是否已经调价过了 @@ -1428,11 +1440,11 @@ xpOrderDetailMapper.insert(xpOrderDetail); } for (XpOrderDetail xpOrderDetail : xpOrderDetails) { if (xpOrderDetail.getDetailType() == 1) { if (xpOrderDetail.getDetailType() == 1){ order.setDurationType(xpOrderDetail.getType()); order.setDurationMoney(xpOrderDetail.getMoney()); order.setDuration(Double.parseDouble(xpOrderDetail.getDuration() + "")); } else { }else{ order.setLongDistanceType(order.getDurationType()); order.setLongDistance(xpOrderDetail.getMileage().doubleValue()); order.setLongDistancemoney(xpOrderDetail.getMoney()); @@ -1442,7 +1454,7 @@ BigDecimal orderMoney = startMoney.add(mileageMoney).add(order.getDurationMoney() != null ? order.getDurationMoney() : BigDecimal.ZERO) .add(order.getLongDistancemoney() != null ? order.getLongDistancemoney() : BigDecimal.ZERO) .add(order.getWaitMoney() != null ? order.getWaitMoney() : BigDecimal.ZERO); .add(order.getWaitMoney()!=null?order.getWaitMoney():BigDecimal.ZERO); order.setOrderMoney(orderMoney); order.setAppUserId(null); baseMapper.updateById(order); @@ -1455,7 +1467,7 @@ useUserCouponDto.setUserCouponId(order.getCouponId()); xpAppUserCouponClient.useUserCoupon(useUserCouponDto); } // 计算完价格后 挑选优惠券 // 计算完价格后 挑选优惠券 GetUserCouponDto getUserCouponDto = new GetUserCouponDto(); getUserCouponDto.setUserId(Long.valueOf(uid)); getUserCouponDto.setTotalAmount(order.getOrderMoney().doubleValue()); @@ -1469,13 +1481,16 @@ baseMapper.updateById(order); // 结束后的车辆操作 if (vehicle != null) { if(vehicle!=null){ // 修改车辆状态 vehicle.setState(0); addCruiseMission(vehicle, order); addCruiseMission(vehicle,order); // // 获取配置 根据配置判断是否该收车 如果是则找到收车点位进行收车操作 // R<XpTaskRule> xpTaskRuleR = xpTaskRuleClient.queryDetail(); // XpTaskRule xpTaskRule = xpTaskRuleR.getData(); @@ -1554,20 +1569,19 @@ /** * 添加巡游任务下发命令 * * @param vehicle * @param order */ public void addCruiseMission(XpVehicle vehicle, XpOrder order) { if (vehicle.getState() != 0 || vehicle.getOperatingStatus() != 1) { if(vehicle.getState()!=0 || vehicle.getOperatingStatus()!=1){ return; } // 判断是否有计划 R<XpCruisePlanVehicle> xpCruisePlanR = xpCruisePlanClient.getCruisePlan(vehicle.getId()); if (xpCruisePlanR == null || xpCruisePlanR.getData() == null) { if(xpCruisePlanR==null || xpCruisePlanR.getData()==null){ return; } @@ -1577,11 +1591,11 @@ // 生成新的巡游单子 回到最新巡游的初始起点位置 XpCruiseOrder xpCruiseOrders = xpCruiseOrderMapper.selectOne(new LambdaQueryWrapper<XpCruiseOrder>().eq(XpCruiseOrder::getVehicleId, vehicle.getId()).eq(XpCruiseOrder::getStatus, 2).orderByDesc(BaseModel::getCreateTime).last("limit 1")); int temp = 0; if (xpCruiseOrders == null) { temp = 1; int temp=0; if(xpCruiseOrders==null){ temp=1; //特殊情况 可能没有产生终止的订单 (到站点就被正常接单了)所以找正常订单 xpCruiseOrders = xpCruiseOrderMapper.selectOne(new LambdaQueryWrapper<XpCruiseOrder>().eq(XpCruiseOrder::getVehicleId, vehicle.getId()).eq(XpCruiseOrder::getStatus, 3).orderByDesc(BaseModel::getCreateTime).last("limit 1")); xpCruiseOrders=xpCruiseOrderMapper.selectOne(new LambdaQueryWrapper<XpCruiseOrder>().eq(XpCruiseOrder::getVehicleId, vehicle.getId()).eq(XpCruiseOrder::getStatus, 3).orderByDesc(BaseModel::getCreateTime).last("limit 1")); } XpCruiseOrder xpCruiseOrder = new XpCruiseOrder(); xpCruiseOrder.setVehicleId(vehicle.getId()); @@ -1595,12 +1609,12 @@ xpCruiseOrder.setStartLat(order.getEndLat()); // 完成的直接走终点 终止的走起点 if (temp == 0) { if(temp==0){ xpCruiseOrder.setEndPointId(xpCruiseOrders.getStartPointId()); xpCruiseOrder.setEndPointName(xpCruiseOrders.getStartPointName()); xpCruiseOrder.setEndLon(xpCruiseOrders.getStartLon()); xpCruiseOrder.setEndLat(xpCruiseOrders.getStartLat()); } else { }else { xpCruiseOrder.setEndPointId(xpCruiseOrders.getEndPointId()); xpCruiseOrder.setEndPointName(xpCruiseOrders.getEndPointName()); xpCruiseOrder.setEndLon(xpCruiseOrders.getEndLon()); @@ -1611,7 +1625,7 @@ xpCruiseOrder.setStatus(0); xpCruiseOrder.setLastOrderId(xpCruiseOrders.getId()); xpCruiseOrder.setCreateTime(LocalDateTime.now()); xpCruiseOrder.setId("XU" + IdUtil.fastUUID()); xpCruiseOrder.setId("XU"+ IdUtil.fastUUID()); // 判断当前时分秒是否大于收车时间 LocalTime vehicleCollectionTime = xpTaskRule.getVehicleCollectionTime(); @@ -1862,14 +1876,14 @@ detail.setTime(xpOrderDetail.getTime()); detail.setMileage(xpOrderDetail.getMileage()); detail.setDuration(xpOrderDetail.getDuration()); if (xpOrderDetail.getDetailType() == 1) { if (xpOrderDetail.getDetailType() == 1){ start.add(detail); } else { }else{ mileage.add(detail); } } List<FareBreakdownDetailVo> duration = new ArrayList<>(); if (order.getDuration() != null && order.getDuration() > 0) { if (order.getDuration()!=null&&order.getDuration()>0){ FareBreakdownDetailVo durationDetail = new FareBreakdownDetailVo(); durationDetail.setType(order.getDurationType()); durationDetail.setDuration(order.getDuration()); @@ -1878,24 +1892,24 @@ } List<FareBreakdownDetailVo> longDistance = new ArrayList<>(); if (order.getLongDistance() != null && order.getLongDistance() > 0) { if (order.getLongDistance()!=null&&order.getLongDistance()>0){ FareBreakdownDetailVo longDistanceDetail = new FareBreakdownDetailVo(); longDistanceDetail.setType(order.getLongDistanceType()); longDistanceDetail.setMileage(BigDecimal.valueOf(order.getLongDistance())); longDistanceDetail.setMoney(order.getLongDistancemoney()); longDistance.add(longDistanceDetail); } res.setStart(start); res.setMileage(mileage); res.setDuration(duration); res.setLongDistance(longDistance); res.setStart( start); res.setMileage( mileage); res.setDuration( duration); res.setLongDistance( longDistance); res.setRedPacketMoney(order.getRedPacketMoney()); res.setCouponMoney(order.getCouponMoney()); res.setOrderMoney(order.getOrderMoney()); res.setKilometer(order.getMileageKilometers() == null ? BigDecimal.ZERO : BigDecimal.valueOf(order.getMileageKilometers())); res.setKilometer(order.getMileageKilometers()==null?BigDecimal.ZERO:BigDecimal.valueOf(order.getMileageKilometers())); LocalDateTime createTime = order.getCreateTime(); LocalDateTime tripEnd = order.getTripEnd(); if (tripEnd == null) { if (tripEnd==null){ tripEnd = LocalDateTime.now(); order.setTripEnd(tripEnd); this.updateById(order); @@ -2046,7 +2060,7 @@ XpPricing pricing = pricingByCityId.getData(); if (pricing == null) { throw new ServiceException("当前城市未配置定价规则", I18nKeyConstant.ORDER_PRICING_NOT_EXISTS); } else { }else{ return R.ok(pricing.getPriceRule()); } } @@ -2058,15 +2072,15 @@ * @param dto */ @Override // @Transactional // @ShardingSphereTransactionType(TransactionType.BASE) @Transactional @ShardingSphereTransactionType(TransactionType.BASE) public void popOrder(PopOrderDto dto) { String orderType = dto.getOrderType(); Long orderId = dto.getOrderId(); //巡游单处理逻辑 if (OrderType.CRUISE_ORDER.equals(orderType)) { if(OrderType.CRUISE_ORDER.equals(orderType)){ XpCruiseOrder xpCruiseOrder = xpCruiseOrderMapper.selectById(orderId); if (xpCruiseOrder != null) { if(xpCruiseOrder!=null){ xpCruiseOrder.setStatus(1); xpCruiseOrderMapper.updateById(xpCruiseOrder); } @@ -2074,11 +2088,11 @@ } //乘客单处理逻辑 if (OrderType.USER_ORDER.equals(orderType)) { if(OrderType.USER_ORDER.equals(orderType)){ XpOrder order = this.getById(orderId); Long appUserId = order.getAppUserId(); //订单为待接单状态 if (order.getStatus() < 4) { if(order.getStatus() < 4){ AddTaxiPassengerVo addTaxiPassengerVo = new AddTaxiPassengerVo(); order.setAcceptanceTime(LocalDateTime.now()); R<XpVehicle> byVehicleVin = xpVehicleClient.findByVehicleVin(dto.getXpVehicleVin()); @@ -2116,7 +2130,7 @@ userVehicleClient.addTaxiPassenger(addTaxiPassengerVo); //推送乘客车辆到达预约点的导航数据 sendRoute(addTaxiPassengerVo.getUid(), orderId, "ORDER_NAVIGATION_START_DATA", dto.getXpVehicleVin()); } else { }else{ //推送行起点到终点的驶轨迹给乘客端 sendRoute(appUserId.toString(), orderId, "ORDER_NAVIGATION_END_DATA", dto.getXpVehicleVin()); } @@ -2126,14 +2140,13 @@ /** * 发送乘客导航路径数据 * * @param appUserId * @param keyStr */ public void sendRoute(String appUserId, Long orderId, String keyStr, String vin) { public void sendRoute(String appUserId, Long orderId, String keyStr, String vin){ VehiclePosition vehiclePosition = mongoTemplate.findOne(new Query(Criteria.where("vin").is(vin)), VehiclePosition.class); Object cacheObject = redisService.getCacheObject(keyStr + ":" + appUserId); if (null != cacheObject) { if(null != cacheObject){ RouteVo routeVo = JSON.parseObject(cacheObject.toString(), RouteVo.class); JSONObject jsonObject = new JSONObject(); jsonObject.put("type", "ORDER_ROUTE"); @@ -2147,7 +2160,7 @@ route.put("duration", routeVo.getDuration()); route.put("routeID", routeVo.getRouteID()); List<JSONObject> collect = routeVo.getPolyline().stream().map(item -> { List<JSONObject> collect = routeVo.getPolyline().stream().map(item->{ JSONObject point = new JSONObject(); point.put("latitude", item.getLatitude()); point.put("longitude", item.getLongitude()); @@ -2166,6 +2179,8 @@ } /** * 获取当前用户正在执行的订单 * @@ -2175,7 +2190,7 @@ @Override public XpOrderDetailVO getActiveOrder(String uid) { XpOrderDetailVO xpOrderDetailVO = new XpOrderDetailVO(); XpOrder xpOrder = this.baseMapper.selectOne(new LambdaQueryWrapper<XpOrder>().eq(XpOrder::getAppUserId, Long.parseLong(uid)).in(XpOrder::getStatus, Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8)).orderByDesc(BaseModel::getCreateTime).last("LIMIT 1")); XpOrder xpOrder = this.baseMapper.selectOne(new LambdaQueryWrapper<XpOrder>().eq(XpOrder::getAppUserId, Long.parseLong(uid)).in(XpOrder::getStatus, Arrays.asList(1,2,3, 4, 5, 6, 7, 8)).orderByDesc(BaseModel::getCreateTime).last("LIMIT 1")); if (xpOrder == null) { return null; } @@ -2203,7 +2218,7 @@ } if (xpOrder.getVehicleId() != null) { if(xpOrder.getVehicleId()!=null){ R<XpVehicle> xpVehicleR = xpVehicleClient.queryById(xpOrder.getVehicleId()); xpOrderDetailVO.setPlateNumber(xpVehicleR.getData().getPlateNumber()); } xp-robotaxi-order-boot/xp-modules-account.iml
File was deleted xp-robotaxi-payment-boot/xp-modules-account.iml
File was deleted xp-robotaxi-push-message-boot/xp-modules-account.iml
File was deleted xp-robotaxi-remote-driving-boot/xp-modules-account.iml
File was deleted xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/impl/XpFleetServiceImpl.java
@@ -124,6 +124,12 @@ }).collect(Collectors.toList()); if (!CollectionUtils.isEmpty(vehicleList)) { xpFleetVehicleService.saveBatch(vehicleList); //推送车辆和区域的绑定关系个车端 } return R.ok(); xp-robotaxi-vehicle-convoy-boot/xp-modules-account.iml
File was deleted