无关风月
2026-02-28 cb7be09dc82cdc3deed507a7ae3685e81f46e814
Merge remote-tracking branch 'origin/master'
95个文件已删除
30个文件已修改
6312 ■■■■■ 已修改文件
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/XpOperationsUserServiceImpl.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/dto/operation/ReassignOrderDTO.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/order/XpReassignOrderClientFallbackFactory.java 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/order/XpReassignOrderClient.java 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/controller/OrderMissionController.java 234 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/service/KafkaConsumerService.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpShiftController.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpTaskController.java 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpTaskManagementController.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/exportExcel/XpTaskExportExcel.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/model/vo/TaskManagementPreparationDetailVO.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/IXpShiftService.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/XpTaskService.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/impl/XpShiftServiceImpl.java 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/impl/XpTaskServiceImpl.java 224 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/resources/bootstrap.yml 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/pom.xml 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/config/DataUpdateHandlerConfig.java 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/config/MybatisPlusConfig.java 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/constant/I18nKeyConstant.java 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpElectronicFenceManagementController.java 144 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpPointManagementController.java 165 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/dto/NearestDto.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/dto/NotificationDto.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/dto/OpenCityAddDTO.java 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/dto/OpenCityEditDTO.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/dto/PricingAddDTO.java 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/dto/PricingEditDTO.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/dto/PricingSetPriceDTO.java 114 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/dto/PricingSetRuleDTO.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/dto/RoutePlanAddDTO.java 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/dto/RoutePlanEditDTO.java 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/dto/WhitelistAddDto.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/dto/WhitelistEditDto.java 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/dto/XpAgreementAppUserDto.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/dto/XpAgreementDTO.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/dto/XpCruisePlanAddDTO.java 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/dto/XpCruisePlanEditDTO.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/dto/XpFrequentlyAskedQuestionsDTO.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/dto/XpOrderDto.java 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/dto/XpPointSpecialDto.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/dto/XpRideGuideDTO.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/dto/XpTradingStrategyEditDTO.java 120 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/dto/XpUserFeedbackDto.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/job/base/AbstractJob.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/job/base/QuartzManager.java 128 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/job/base/TimeJobType.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/job/exceptions/TimeException.java 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/job/jobs/ElectronicEffectJob.java 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/job/jobs/OrderCancelJob.java 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/job/utils/SpringContextsUtil.java 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/mapper/XpElectronicFenceMapper.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/mapper/XpOpenCityMapper.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/mapper/XpPointMapper.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/mapper/XpRegionMapper.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/mapper/XpSystemSettingMapper.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/query/BannerPageListQuery.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/query/CruisePlanQuery.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/query/InvitationPageListQuery.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/query/OpenCityPageQuery.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/query/PointByNameQuery.java 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/query/PricingPageListQuery.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/query/RoutePlanPageListQuery.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/query/UserFeedBackQuery.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/query/WhitelistLogPageListQuery.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/query/WhitelistPageListQuery.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/query/XpCouponListQuery.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/query/getProvinceQuery.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/XpElectronicFenceService.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/XpOpenCityService.java 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/XpPointService.java 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/XpRegionService.java 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/XpSystemSettingService.java 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/serviceimpl/XpElectronicFenceServiceImpl.java 618 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/serviceimpl/XpOpenCityServiceImpl.java 159 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/serviceimpl/XpPointServiceImpl.java 261 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/serviceimpl/XpRegionServiceImpl.java 173 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/serviceimpl/XpSystemSettingServiceImpl.java 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/utils/PolygonOverlapService.java 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/utils/TimeRangeChecker.java 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/utils/map/map/FastDistanceCalculator.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/utils/map/map/GeodesyUtil.java 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/vo/CustomerServicePhoneVo.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/vo/FileUploadVO.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/vo/IndexDto.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/vo/MetaVo.java 106 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/vo/NearestNextVo.java 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/vo/NearestVo.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/vo/OpenCityListVO.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/vo/OrderDistanceVo.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/vo/PricingPageListVO.java 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/vo/RegionCascaderVO.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/vo/RegionDistrictSyncResultVO.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/vo/RouterVo.java 149 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/vo/SaveOrderVo.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/vo/SpecialPointListVo.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/vo/SpecialPointVo.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/vo/SysOperLogQuery.java 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/vo/TCompanyToUserVo.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/vo/UserRoleVO.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/vo/ViolationListExportVo.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/vo/XpAgreementVo.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/vo/XpAppVersionVO.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/vo/XpBannerListVo.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/vo/XpCruisePlanDetailVO.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/vo/XpCruisePlanPointVO.java 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/vo/XpCruisePlanVehicleVO.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/vo/XpOpenCityNextVo.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/vo/XpOpenCityVo.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/vo/XpPricingCardVo.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/vo/XpRideGuideNextVo.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/vo/XpRideGuideVo.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/vo/XpTradingStrategyDetailVO.java 127 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/vo/XpUserFeedbackVO.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/resources/mapper/XpElectronicFenceMapper.xml 73 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/resources/mapper/XpPointMapper.xml 164 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/resources/mapper/XpRegionMapper.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/ReassignOrderController.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpElectronicFenceController.java 126 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpInvitationCodeController.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpPointManagementController.java 98 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/controller/XpOrderController.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderEvaluateServiceImpl.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java 130 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/XpOperationsUserServiceImpl.java
@@ -1,7 +1,6 @@
package com.xiaopeng.account.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -159,23 +158,20 @@
        }
        // 8. 查询角色信息
        List<XpOperationsRole> xpOperationsRoles = xpOperationsRoleMapper
                .selectList(new LambdaQueryWrapper<XpOperationsRole>().eq(XpOperationsRole::getOperationsUserId, userId));
        if (CollUtil.isNotEmpty(xpOperationsRoles)) {
            List<Long> roleIds = xpOperationsRoles.stream().map(XpOperationsRole::getRoleId).collect(Collectors.toList());
            List<SysRole> sysRoles = sysRoleMapper.selectList(Wrappers.lambdaQuery(SysRole.class)
                    .in(SysRole::getId, roleIds));
            List<XpOperationsUserProfileVO.RoleInfoVO> roleVOs = sysRoles.stream()
                    .filter(r -> r.getId() != null)
        List<XpOperationsUserWithRoleVO> userWithRoles = xpOperationsRoleMapper.selectUsersWithRoleByIds(Collections.singletonList(userId));
        if (!CollectionUtils.isEmpty(userWithRoles)) {
            List<XpOperationsUserProfileVO.RoleInfoVO> roleVOs = userWithRoles.stream()
                    .filter(r -> r.getRoleId() != null)
                    .map(r -> {
                        XpOperationsUserProfileVO.RoleInfoVO roleVO = new XpOperationsUserProfileVO.RoleInfoVO();
                        roleVO.setRoleId(r.getId());
                        roleVO.setRoleId(r.getRoleId());
                        roleVO.setRoleName(r.getRoleName());
                        return roleVO;
                    })
                    .collect(Collectors.toList());
            vo.setRoles(roleVOs);
        }
        return vo;
    }
@@ -187,7 +183,6 @@
        //保存审核记录
        XpQualificationAudit xpQualificationAudit = BeanUtil.copyProperties(dto, XpQualificationAudit.class, "id");
        xpQualificationAudit.setAuditStatus(1);
        xpQualificationAudit.setOperationsUserId(dto.getId());
        xpQualificationAuditService.save(xpQualificationAudit);
    }
xp-robotaxi-api/src/main/java/com/xiaopeng/api/dto/operation/ReassignOrderDTO.java
@@ -21,15 +21,4 @@
    @ApiModelProperty(value = "订单号")
    private String orderNo;
    @ApiModelProperty(value = "订单id")
    private Long orderId;
    @ApiModelProperty(value = "车辆id")
    private Long vehicleId;
    @ApiModelProperty(value = "车队id")
    private Long fleetId;
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/order/XpReassignOrderClientFallbackFactory.java
File was deleted
xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/order/XpReassignOrderClient.java
File was deleted
xp-robotaxi-api/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -36,7 +36,7 @@
com.xiaopeng.api.factory.maintenance.XpClockInClientFallbackFactory
com.xiaopeng.api.factory.account.SysGroupMenuClientFallbackFactory
com.xiaopeng.api.factory.order.XpCruiseOrderClientFallbackFactory
com.xiaopeng.api.factory.order.XpReassignOrderClientFallbackFactory
com.xiaopeng.api.factory.operation.ReassignOrderClientFallbackFactory
com.xiaopeng.api.factory.operation.SmsClientFallbackFactory
com.xiaopeng.api.factory.maintenance.XpTaskHandleDetailRoutineClientFallbackFactory
com.xiaopeng.api.factory.maintenance.XpTaskClientFallbackFactory
xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/controller/OrderMissionController.java
@@ -2,23 +2,49 @@
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.xiaopeng.api.dto.automaticPilot.MqttPublishDto;
import com.xiaopeng.api.dto.automaticPilot.PushOrderDto;
import com.xiaopeng.api.dto.map.OrderRouteAndFareDto;
import com.xiaopeng.api.dto.operation.LonLatDto;
import com.xiaopeng.api.dto.order.PopOrderDto;
import com.xiaopeng.api.dto.pushMessage.PushOrderRouteDTO;
import com.xiaopeng.api.dto.pushMessage.SendMessageDTO;
import com.xiaopeng.api.dto.vehicleConvoy.UpdateVehicleStateDto;
import com.xiaopeng.api.feignClient.map.XpMapClient;
import com.xiaopeng.api.feignClient.order.XpOrderClient;
import com.xiaopeng.api.feignClient.pushMessage.XpPushMessageClient;
import com.xiaopeng.api.feignClient.vehicleConvoy.XpVehicleClient;
import com.xiaopeng.api.model.order.XpOrder;import com.xiaopeng.api.model.vehicleConvoy.XpVehicle;
import com.xiaopeng.api.vo.automaticPilot.VehiclePosition;
import com.xiaopeng.api.vo.automaticPilot.proto.down.cloudCreateOrder.RTTask;
import com.xiaopeng.api.vo.automaticPilot.proto.down.cloudCreateOrder.TaskStatus;
import com.xiaopeng.api.vo.automaticPilot.proto.down.cloudCreateOrder.TaskType;
import com.xiaopeng.api.vo.automaticPilot.protobuf.*;
import com.xiaopeng.api.vo.operation.RouteVo;
import com.xiaopeng.automaticPilot.util.XPUUtil;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.core.enums.OrderStatusEnum;
import com.xiaopeng.common.core.enums.PushMessageTypeEnum;
import com.xiaopeng.common.core.utils.SnowFlake;
import com.xiaopeng.common.core.utils.StringUtils;
import com.xiaopeng.common.redis.service.RedisService;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.geo.GeoJsonPoint;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
@Slf4j
@@ -83,4 +109,212 @@
    }
    //-----------------------------------------------用户测试阶段模拟车机报文调用流程接口实现业务闭环--------------------------------------//
    @Resource
    private XpOrderClient xpOrderClient;
    @Resource
    private XpMapClient xpMapClient;
    @Resource
    private MongoTemplate mongoTemplate;
    @Resource
    public RedisTemplate redisTemplate;
    @Resource
    private XpPushMessageClient xpPushMessageClient;
    /**
     * 模拟接单
     * @param orderId       订单id
     * @param vehicleId     车辆id
     * @param startLon      车子当前位置经度
     * @param startLat      车子当前位置维度
     * @return
     */
    @GetMapping("/base/v1/order/acceptingOrder")
    public R acceptingOrder(Long orderId, Long vehicleId, Double startLon, Double startLat){
        XpVehicle xpVehicle = xpVehicleClient.queryById(vehicleId).getData();
        XpOrder xpOrder = xpOrderClient.queryOrderById(orderId).getData();
        OrderRouteAndFareDto dto = new OrderRouteAndFareDto();
        dto.setOrderId(orderId);
        LonLatDto origin = new LonLatDto();
        origin.setLongitude(startLon);
        origin.setLatitude(startLat);
        dto.setOrigin(origin);
        LonLatDto destination = new LonLatDto();
        destination.setLongitude(xpOrder.getStartLon());
        destination.setLatitude(xpOrder.getStartLat());
        dto.setDestination(destination);
        R<RouteVo> routeVoR = xpMapClient.getOrderDistanceAndDuration(dto);
        if (200 != routeVoR.getCode()) {
            throw new RuntimeException("获取订单线路和运费失败");
        }
        RouteVo routeVo = routeVoR.getData();
        //缓存数据,用于后续推给乘客导航线路
        redisService.setCacheObject("ORDER_NAVIGATION_START_DATA:" + xpOrder.getAppUserId(), com.alibaba.fastjson.JSON.toJSONString(routeVo), 24L, TimeUnit.HOURS);
        PopOrderDto dto1 = new PopOrderDto();
        dto1.setOrderId(Long.valueOf(orderId));
        dto1.setXpVehicleVin(xpVehicle.getVehicleVin());
        dto1.setOrderType(com.xiaopeng.api.vo.OrderType.USER_ORDER);
        R<?> r = xpOrderClient.popOrder(dto1);
        //构建推送消息
        Map<String, Object> params = new HashMap<>();
        Map<String, Object> content = new HashMap<>();
        content.put("orderId", orderId);
        content.put("status", 3);
        params.put("type", PushMessageTypeEnum.ORDER_STATUS.getDesc());
        params.put("content", JSONObject.toJSONString(content));
        params.put("timestamp", System.currentTimeMillis() + "");
        String message = JSONObject.toJSONString(params);
        Long appUserId = xpOrder.getAppUserId();
        SendMessageDTO dto2 = new SendMessageDTO();
        dto2.setAppUserId(appUserId + "");
        dto2.setMessage(message);
        R<String> stringR = xpPushMessageClient.sendStatus(dto2);
        if (R.isError(stringR)) {
            log.error("推送消息失败:{}", stringR.getMsg());
        }
        xpOrderClient.updateOrderStatus(orderId, OrderStatusEnum.PICK_UP.getCode());
        return r;
    }
    /**
     * 推送司机接驾轨迹和实时位置
     * @param orderId
     */
    @GetMapping("/base/v1/order/pushStartDriverLocation")
    private void pushStartDriverLocation(Long vehicleId, Long orderId){
        XpVehicle xpVehicle = xpVehicleClient.queryById(vehicleId).getData();
        XpOrder xpOrder = xpOrderClient.queryOrderById(orderId).getData();
        String vin = xpVehicle.getVehicleVin();
        Long appUserId = xpOrder.getAppUserId();
        Object cacheObject = redisService.getCacheObject("ORDER_NAVIGATION_START_DATA:" + xpOrder.getAppUserId());
        RouteVo routeVo = JSON.parseObject(cacheObject.toString(), RouteVo.class);
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(1000));
        threadPoolExecutor.execute(() -> {
            //等待10秒后开始执行车子位移
            try {
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            List<LonLatDto> polyline = routeVo.getPolyline();
            for (LonLatDto lonLatDto : polyline) {
                Double latitude = lonLatDto.getLatitude();
                Double longitude = lonLatDto.getLongitude();
                //保存车辆实时位置到redis
                redisTemplate.opsForGeo().add("vehiclePosition:" + vin, new GeoJsonPoint(longitude, latitude), vin);
                //保存车辆实时信息到mongodb
                VehiclePosition vehiclePosition = mongoTemplate.findOne(new Query(Criteria.where("vin").is(vin)), VehiclePosition.class);
                if (null == vehiclePosition) {
                    vehiclePosition = new VehiclePosition();
                }
                vehiclePosition.setVin(vin);
                vehiclePosition.setPoint(new GeoJsonPoint(longitude, latitude));
                vehiclePosition.setCourse(60D);
                vehiclePosition.setAlt(100F);
                //车辆动态信息
                vehiclePosition.setSpeed(50F);
                vehiclePosition.setCurrentElectricity(80);
                vehiclePosition.setMileageRange(300f);
                vehiclePosition.setOrderId(orderId);
                mongoTemplate.save(vehiclePosition);
                //调用推送服务接口
                if (null != orderId) {
                    PushOrderRouteDTO dto = new PushOrderRouteDTO();
                    dto.setOrderId(orderId);
                    dto.setRouteType(1);
                    dto.setLongitude(longitude);
                    dto.setLatitude(latitude);
                    //TODO 这两个字段现在拿不到
//            dto.setDuration(rtTripInfo.getRemaining_time());
//            dto.setDistance(rtTripInfo.getRemaining_distance().intValue());
                    xpPushMessageClient.pushOrderRoute(dto);
                }
                //5秒钟循环一次
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
            //构建推送消息
            Map<String, Object> params = new HashMap<>();
            Map<String, Object> content = new HashMap<>();
            content.put("orderId", orderId);
            content.put("status", 4);
            params.put("type", PushMessageTypeEnum.ORDER_STATUS.getDesc());
            params.put("content", JSONObject.toJSONString(content));
            params.put("timestamp", System.currentTimeMillis() + "");
            String message = JSONObject.toJSONString(params);
            SendMessageDTO dto2 = new SendMessageDTO();
            dto2.setAppUserId(appUserId + "");
            dto2.setMessage(message);
            R<String> stringR = xpPushMessageClient.sendStatus(dto2);
            if (R.isError(stringR)) {
                log.error("推送消息失败:{}", stringR.getMsg());
            }
            xpOrderClient.updateOrderStatus(orderId, OrderStatusEnum.PICK_UP_GUESTS.getCode());
        });
    }
    /**
     * 修改订单状态
     * @param orderId
     * @param status
     * @return
     */
    @GetMapping("/base/v1/order/updateOrderStatus")
    public R updateOrderStatus(Long orderId, Integer status) {
        XpOrder xpOrder = xpOrderClient.queryOrderById(orderId).getData();
        //构建推送消息
        Map<String, Object> params = new HashMap<>();
        Map<String, Object> content = new HashMap<>();
        content.put("orderId", orderId);
        content.put("status", status);
        params.put("type", PushMessageTypeEnum.ORDER_STATUS.getDesc());
        params.put("content", JSONObject.toJSONString(content));
        params.put("timestamp", System.currentTimeMillis() + "");
        String message = JSONObject.toJSONString(params);
        SendMessageDTO dto2 = new SendMessageDTO();
        dto2.setAppUserId(xpOrder.getAppUserId() + "");
        dto2.setMessage(message);
        R<String> stringR = xpPushMessageClient.sendStatus(dto2);
        if (R.isError(stringR)) {
            log.error("推送消息失败:{}", stringR.getMsg());
        }
        xpOrderClient.updateOrderStatus(orderId, status);
        return R.ok();
    }
}
xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/service/KafkaConsumerService.java
@@ -30,7 +30,8 @@
import com.xiaopeng.api.vo.automaticPilot.protobuf.*;
import com.xiaopeng.api.vo.automaticPilot.protobuf.AbnormalReason;
import com.xiaopeng.api.vo.automaticPilot.protobuf.GearLevel;
import com.xiaopeng.api.vo.automaticPilot.protobuf.OrderPhase;import com.xiaopeng.api.vo.automaticPilot.protobuf.OrderStatusInfo;
import com.xiaopeng.api.vo.automaticPilot.protobuf.OrderPhase;
import com.xiaopeng.api.vo.automaticPilot.protobuf.OrderStatusInfo;
import com.xiaopeng.api.vo.automaticPilot.protobuf.RealtimePose;
import com.xiaopeng.api.vo.automaticPilot.protobuf.ResponseMessage;
import com.xiaopeng.api.vo.automaticPilot.protobuf.RtTripInfo;
@@ -346,7 +347,7 @@
            log.info("车辆故障,开始处理故障");
            // TODO 添加异常任务
            // 解绑用户与车辆关系
//            CancelTaxiPassengerVo cancelTaxiPassengerVo = new CancelTaxiPassengerVo();
            CancelTaxiPassengerVo cancelTaxiPassengerVo = new CancelTaxiPassengerVo();
            String orderId = systemRuntimeStatus.getRunningOrderStatusInfo().getOrderId();
            XpOrder xpOrder = xpOrderClient.queryOrderById(Long.parseLong(orderId)).getData();
            XpVehicle vehicle = xpVehicleClient.queryById(xpOrder.getVehicleId()).getData();
@@ -354,17 +355,11 @@
                // 修改车辆状态
                vehicle.setOperatingStatus(4);
                xpVehicleClient.updateVehicleById(vehicle);
//                cancelTaxiPassengerVo.setVin(vehicle.getVehicleVin());
//                cancelTaxiPassengerVo.setUid(xpOrder.getAppUserId().toString());
//                cancelTaxiPassengerVo.setOrderNo(xpOrder.getOrderNumber());
//                // TODO
////            cancelTaxiPassengerVo.setAppId();
//                userVehicleClient.cancelTaxiPassenger(cancelTaxiPassengerVo);
                cancelTaxiPassengerVo.setVin(vehicle.getVehicleVin());
                cancelTaxiPassengerVo.setUid(xpOrder.getAppUserId().toString());
                cancelTaxiPassengerVo.setOrderNo(xpOrder.getOrderNumber());
                userVehicleClient.cancelTaxiPassenger(cancelTaxiPassengerVo);
            }
            // 取消订单
//            R<?> r = xpOrderClient.cancelOrder(String.valueOf(xpOrder.getId()));
//            if (r.getCode() == R.SUCCESS){
            log.info("取消订单成功");
            // TODO 重新派单
            ReassignOrderDTO reassignOrderDTO = new ReassignOrderDTO();
            reassignOrderDTO.setUid(xpOrder.getAppUserId().toString());
@@ -376,15 +371,7 @@
            Double longitude = naviPose.getLongitude();
            reassignOrderDTO.setLongitude(longitude);
            reassignOrderDTO.setLatitude(latitude);
            reassignOrderDTO.setVehicleId(xpOrder.getVehicleId());
            reassignOrderDTO.setOrderId(xpOrder.getId());
            reassignOrderDTO.setFleetId(xpOrder.getFleetId());
            reassignOrderClient.reassignOrder(reassignOrderDTO);
//            }
        }
    }
@@ -873,7 +860,7 @@
                            com.xiaopeng.api.vo.automaticPilot.protobuf.RtTask.Builder taskBuilder = com.xiaopeng.api.vo.automaticPilot.protobuf.RtTask.newBuilder();
                            RtTask.Builder taskBuilder = RtTask.newBuilder();
                            taskBuilder.setOrderId(lastXpCruiseOrder.getId());
                            taskBuilder.setTaskId("MISSION_"+ IdUtil.fastUUID());
                            taskBuilder.setTaskType(com.xiaopeng.api.vo.automaticPilot.protobuf.OrderType.ORDER_TYPE_CRUISE);
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpShiftController.java
@@ -43,15 +43,13 @@
    @ApiOperation(value = "班次管理新增", tags = "管理后台-运维执行")
    @PostMapping("/api/v1/shift/add")
    public R<String> add(@RequestBody XpShift dto) {
        xpShiftService.save(dto);
        return R.ok();
        return xpShiftService.add(dto);
    }
    @ApiOperation(value = "班次管理编辑", tags = "管理后台-运维执行")
    @PostMapping("/api/v1/shift/edit")
    public R<String> edit(@RequestBody XpShift dto) {
        xpShiftService.updateById(dto);
        return R.ok();
        return xpShiftService.edit(dto);
    }
    @ApiOperation(value = "班次管理删除", tags = "管理后台-运维执行")
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpTaskController.java
@@ -125,7 +125,6 @@
        xpTaskService.saveVehicleAccident(dto, xpOperationsUser);
        return R.ok();
    }
    @ApiOperation(value = "车辆事故任务详情", tags = "运维APP-任务中心")
    @GetMapping("/api/v1/task/vehicleAccidentDetail")
    public R<TaskAccidentDetailVO> vehicleAccidentDetail(Long id) {
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpTaskManagementController.java
@@ -167,9 +167,6 @@
        xpTaskService.saveTask(dto, reportUserId);
        return R.ok();
    }
    @ApiOperation(value = "任务详情")
    @GetMapping("/taskDetail")
    public R<TaskManagementDetailVO> taskDetail(Long id) {
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/exportExcel/XpTaskExportExcel.java
@@ -25,7 +25,7 @@
    @Excel(name = "车牌号",width = 20)
    private String plateNumber;
    @ApiModelProperty(value = "任务类别1常规 2事故")
    @Excel(name = "任务类别",width = 20,replace = {"常规_1","事故_2"})
    @Excel(name = "任务类别",width = 20)
    private Integer taskCategory;
    @ApiModelProperty(value = "类型")
    @Excel(name = "类型",width = 40)
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/model/vo/TaskManagementPreparationDetailVO.java
@@ -69,8 +69,6 @@
    @ApiModelProperty(value = "遗失物品")
    private String lostItems;
    @ApiModelProperty(value = "遗失物品说明")
    private String lostItemsDetail;
    @ApiModelProperty(value = "备注")
    private String remarks;
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/IXpShiftService.java
@@ -2,6 +2,7 @@
import com.xiaopeng.api.model.maintenance.XpShift;
import com.baomidou.mybatisplus.extension.service.IService;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.core.web.page.PageInfo;
import com.xiaopeng.maintenance.model.query.XpShiftQuery;
@@ -31,4 +32,18 @@
     * @return
     */
    List<XpShift> queryList();
    /**
     * 新增
     * @param dto
     * @return
     */
    R<String> add(XpShift dto);
    /**
     * 编辑
     * @param dto
     * @return
     */
    R<String> edit(XpShift dto);
}
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/XpTaskService.java
@@ -91,7 +91,4 @@
     */
    XpTask queryInfoByVehicleId(Long vehicleId);
    void saveVehicleAccidentError(Long vehicleId);
}
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/impl/XpShiftServiceImpl.java
@@ -46,4 +46,46 @@
    public List<XpShift> queryList() {
        return this.list(new LambdaQueryWrapper<XpShift>().eq(XpShift::getDeleted, 0));
    }
    @Override
    public R<String> add(XpShift dto) {
        // 判断结束时间是否大于开始时间 格式为 HH:mm
        if (dto.getEndTime().compareTo(dto.getStartTime()) < 0) {
            return R.fail("结束时间不能小于开始时间");
        }
        // 判断休息结束时间是否大于休息开始时间 格式为 HH:mm
        if (dto.getRestEndTime() != null && dto.getRestStartTime() != null && dto.getRestEndTime().compareTo(dto.getRestStartTime()) < 0) {
            return R.fail("休息结束时间不能小于休息开始时间");
        }
        if (this.count(new LambdaQueryWrapper<XpShift>().eq(XpShift::getShiftName, dto.getShiftName())) > 0) {
            return R.fail("班次名称已存在");
        }
        this.save(dto);
        return R.ok();
    }
    @Override
    public R<String> edit(XpShift dto) {
        // 判断结束时间是否大于开始时间 格式为 HH:mm
        if (dto.getEndTime().compareTo(dto.getStartTime()) < 0) {
            return R.fail("结束时间不能小于开始时间");
        }
        // 判断休息结束时间是否大于休息开始时间 格式为 HH:mm
        if (dto.getRestEndTime() != null && dto.getRestStartTime() != null && dto.getRestEndTime().compareTo(dto.getRestStartTime()) < 0) {
            return R.fail("休息结束时间不能小于休息开始时间");
        }
        if (this.count(new LambdaQueryWrapper<XpShift>().eq(XpShift::getShiftName, dto.getShiftName()).ne(XpShift::getId, dto.getId())) > 0) {
            return R.fail("班次名称已存在");
        }
        this.updateById(dto);
        return R.ok();
    }
}
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/impl/XpTaskServiceImpl.java
@@ -4,7 +4,6 @@
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xiaopeng.api.dto.pushMessage.AliPushMessageDTO;
@@ -89,8 +88,6 @@
    private XpVehicleRepairMapper vehicleRepairMapper;
    @Autowired
    private XpVehiclePreparationMapper vehiclePreparationMapper;
    @Autowired
    private XpVehicleDescriptionMapper vehicleDescriptionMapper;
    @Autowired
    private XpVehicleDetectionMapper vehicleDetectionMapper;
@@ -939,151 +936,12 @@
    @Override
    public List<TaskManagementPageListVO> exportList(TaskManagementPageListQuery query) {
        List<TaskManagementPageListVO> list = this.baseMapper.exportList(query);
        for (TaskManagementPageListVO taskManagementPageListVO : list) {
            if (org.springframework.util.StringUtils.hasLength(taskManagementPageListVO.getHandleUserId())){
                String[] split = taskManagementPageListVO.getHandleUserId().split(",");
                List<XpOperationsUser> users = operationUserClient.listByIds(Arrays.stream(split).map(Long::parseLong).collect(Collectors.toList())).getData();
                if (users!=null){
                    StringBuilder handleUserName = new StringBuilder();
                    for (XpOperationsUser user : users) {
                        handleUserName.append(user.getNickName()).append(";");
                    }
                    taskManagementPageListVO.setHandleUserName(handleUserName.toString());
                }
            }
            if (taskManagementPageListVO.getTaskCategory() == 1) {
                switch (taskManagementPageListVO.getTaskTypeId()) {
                    case "1":
                        taskManagementPageListVO.setTaskTypeName("车辆检查");
                        break;
                    case "2":
                        taskManagementPageListVO.setTaskTypeName("车辆充电");
                        break;
                    case "3":
                        taskManagementPageListVO.setTaskTypeName("车辆整备");
                        break;
                    case "4":
                        taskManagementPageListVO.setTaskTypeName("整备洗车");
                        break;
                    case "5":
                        taskManagementPageListVO.setTaskTypeName("车辆维修");
                        break;
                    case "6":
                        taskManagementPageListVO.setTaskTypeName("车辆保养");
                        break;
                    case "7":
                        taskManagementPageListVO.setTaskTypeName("车辆保险到期");
                        break;
                    case "8":
                        taskManagementPageListVO.setTaskTypeName("车辆年检到期");
                        break;
                    case "9":
                        taskManagementPageListVO.setTaskTypeName("车辆运营资质到期");
                        break;
                    default:
                        taskManagementPageListVO.setTaskTypeName("");
                        break;
                }
            } else {
                StringBuilder taskTypeName = new StringBuilder();
                String[] typeIds = taskManagementPageListVO.getTaskTypeId().split(",");
                List<XpErrorType> xpErrorTypes = errorTypeMapper.selectList(new LambdaQueryWrapper<XpErrorType>()
                        .in(XpErrorType::getId, Arrays.asList(typeIds)).orderByAsc(XpErrorType::getParentId));
                List<XpErrorType> parents = new ArrayList<>();
                for (XpErrorType xpErrorType : xpErrorTypes) {
                    if (xpErrorType.getParentId() == 0) {
                        parents.add(xpErrorType);
                    }
                }
                for (XpErrorType parent : parents) {
                    List<XpErrorType> children = xpErrorTypes.stream().filter(e -> e.getParentId().equals(parent.getId())).collect(Collectors.toList());
                    taskTypeName.append(parent.getErrorName()).append(">");
                    for (XpErrorType child : children) {
                        taskTypeName.append(child.getErrorName()).append(";");
                    }
                }
                taskManagementPageListVO.setTaskTypeName(taskTypeName.substring(0, taskTypeName.length() - 1));
            }
        }
        return list;
    }
    @Override
    public XpTask queryInfoByVehicleId(Long vehicleId) {
        return this.baseMapper.queryInfoByVehicleId(vehicleId);
    }
    @Override
    public void saveVehicleAccidentError(Long vehicleId) {
        XpTask xpTask = new XpTask();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
        String code = sdf.format(new Date()) + UUIDUtil.getNumberRandom(5);
        xpTask.setTaskCode(code);
        xpTask.setTaskCategory(2);
        // todo 事故类型待客户确定
        xpTask.setTaskTypeId("1");
        xpTask.setTaskUrgencyLevel(0);
        xpTask.setTaskDescription("车辆发生异常");
        XpVehicle vehicle = xpVehicleClient.queryById(xpTask.getVehicleId()).getData();
        if (vehicle!=null){
            VehiclePosition vehiclePosition = mongoTemplate.findOne(new Query(Criteria.where("vin").is(vehicle.getVehicleVin())), VehiclePosition.class);
            if (vehiclePosition != null) {
                double x = vehiclePosition.getPoint().getX();
                double y = vehiclePosition.getPoint().getY();
                xpTask.setVehicleLon(new BigDecimal(x));
                xpTask.setVehicleLat(new BigDecimal(y));
            }
        }
        xpTask.setVehicleId(vehicleId);
        // 系统上传异常任务标识
        xpTask.setReportUserId(0L);
        xpTask.setReportTime(LocalDateTime.now());
        xpTask.setStatus(0);
        xpTask.setCreateBy("admin");
        XpTaskRule taskRule = xpTaskRuleService.lambdaQuery().last("limit 1").one();
        XpTaskRuleRole taskRuleRole = xpTaskRuleRoleService.lambdaQuery().eq(XpTaskRuleRole::getRuleType, 9).last("limit 1").one();
        if (Objects.isNull(taskRuleRole) || Objects.isNull(taskRule)) {
            throw new ServiceException("未配置车辆事故任务分配规则");
        }
        R<List<XpOperationsRole>> xpOperationsRoleResult = xpOperationUserClient.getXpOperationsRoleByRoleId(taskRuleRole.getRoleId());
        if (CollUtil.isNotEmpty(xpOperationsRoleResult.getData())) {
            List<Long> userIds = xpOperationsRoleResult.getData().stream().map(XpOperationsRole::getOperationsUserId).collect(Collectors.toList());
            xpTask.setHandleUserId(StringUtils.join(userIds, ","));
        }
        // 根据事故处理限时配置设置任务截止时间
        LocalDateTime endTime = LocalDateTime.now().plusMinutes(taskRule.getProcessingTimeLimit());
        xpTask.setEndTime(endTime);
        this.save(xpTask);
        // 发送消息通知
        List<Long> userIds = Arrays.stream(xpTask.getHandleUserId().split(",")).map(Long::valueOf).collect(Collectors.toList());
        if (CollUtil.isNotEmpty(userIds)) {
            R<List<XpOperationsUser>> xpOperationUserResult = xpOperationUserClient.listByIds(userIds);
            List<XpOperationsUser> data = xpOperationUserResult.getData();
            if (CollUtil.isNotEmpty(data)) {
                String plateNumber = Objects.nonNull(vehicle) ? vehicle.getPlateNumber() : "";
                // 车辆${车牌号}在${车辆位置信息}发生了紧急事故,请在${到达现场限时}内到达现场!${APP链接}
                String content = String.format("车辆%s在%s发生了紧急事故,请在%d分钟内到达现场!", plateNumber, xpTask.getVehicleLocation(), taskRule.getProcessingTimeLimit());
                List<XpOperationsUserNotification> notifications = data.stream().map(item -> {
                    XpOperationsUserNotification notification = new XpOperationsUserNotification();
                    notification.setOperationsUserId(item.getId());
                    notification.setNotificationContent(content);
                    notification.setReadStatus(0);
                    notification.setCreateTime(LocalDateTime.now());
                    return notification;
                }).collect(Collectors.toList());
                xpOperationUserNotificationClient.addNotificationBatch(notifications);
                // 发送阿里云推送
                Map<Integer, List<XpOperationsUser>> operationUserMap = data.stream().collect(Collectors.groupingBy(XpOperationsUser::getDeviceType));
                for (Map.Entry<Integer, List<XpOperationsUser>> integerListEntry : operationUserMap.entrySet()) {
                    List<XpOperationsUser> value = integerListEntry.getValue();
                    pushAliMessage(value, content, xpTask);
                }
            }
        }
    }
    @Override
@@ -1099,8 +957,7 @@
    @Override
    public void saveTask(SaveErrorTaskDto dto, Long reportUserId) {
        List<Long> vehicleIds = dto.getVehicleIds();
        List<XpVehicle> vehicles = xpVehicleClient.listByIds(vehicleIds).getData();
        List<XpTask> saveTask = new ArrayList<>();
        for (Long vehicleId : dto.getVehicleIds()) {
            XpTask task = new XpTask();
@@ -1116,18 +973,8 @@
                task.setEndTime(LocalDateTime.now().plusMinutes(taskRule.getProcessingTimeLimit()));
            }
            task.setTaskCategory(2);
            XpTaskRuleRole taskRuleRole = xpTaskRuleRoleService.lambdaQuery().eq(XpTaskRuleRole::getRuleType, 9).last("limit 1").one();
            if (Objects.isNull(taskRuleRole) || Objects.isNull(taskRule)) {
                throw new ServiceException("未配置车辆事故任务分配规则");
            }
            R<List<XpOperationsRole>> xpOperationsRoleResult = xpOperationUserClient.getXpOperationsRoleByRoleId(taskRuleRole.getRoleId());
            if (CollUtil.isNotEmpty(xpOperationsRoleResult.getData())) {
                List<Long> userIds = xpOperationsRoleResult.getData().stream().map(XpOperationsRole::getOperationsUserId).collect(Collectors.toList());
                task.setHandleUserId(StringUtils.join(userIds, ","));
            }
            // 根据事故处理限时配置设置任务截止时间
            LocalDateTime endTime = LocalDateTime.now().plusMinutes(taskRule.getProcessingTimeLimit());
            task.setEndTime(endTime);
            // todo 临时处理
            task.setHandleUserId("1");
            task.setTaskTypeId(dto.getTaskTypeId());
            task.setTaskUrgencyLevel(dto.getTaskUrgencyLevel());
            task.setTaskDescription(dto.getTaskDescription());
@@ -1139,39 +986,8 @@
            task.setReportUserId(reportUserId);
            task.setReportTime(LocalDateTime.now());
            saveTask.add(task);
            // 发送消息通知
            List<Long> userIds = Arrays.stream(task.getHandleUserId().split(",")).map(Long::valueOf).collect(Collectors.toList());
            if (CollUtil.isNotEmpty(userIds)) {
                XpVehicle vehicle = vehicles.stream().filter(e -> e.getId().equals(vehicleId)).findFirst().orElse(null);
                R<List<XpOperationsUser>> xpOperationUserResult = xpOperationUserClient.listByIds(userIds);
                List<XpOperationsUser> data = xpOperationUserResult.getData();
                if (CollUtil.isNotEmpty(data)) {
                    String plateNumber = Objects.nonNull(vehicle) ? vehicle.getPlateNumber() : "";
                    // 车辆${车牌号}在${车辆位置信息}发生了紧急事故,请在${到达现场限时}内到达现场!${APP链接}
                    String content = String.format("车辆%s在%s发生了紧急事故,请在%d分钟内到达现场!", plateNumber, task.getVehicleLocation(), taskRule.getProcessingTimeLimit());
                    List<XpOperationsUserNotification> notifications = data.stream().map(item -> {
                        XpOperationsUserNotification notification = new XpOperationsUserNotification();
                        notification.setOperationsUserId(item.getId());
                        notification.setNotificationContent(content);
                        notification.setReadStatus(0);
                        notification.setCreateTime(LocalDateTime.now());
                        return notification;
                    }).collect(Collectors.toList());
                    xpOperationUserNotificationClient.addNotificationBatch(notifications);
                    // 发送阿里云推送
                    Map<Integer, List<XpOperationsUser>> operationUserMap = data.stream().collect(Collectors.groupingBy(XpOperationsUser::getDeviceType));
                    for (Map.Entry<Integer, List<XpOperationsUser>> integerListEntry : operationUserMap.entrySet()) {
                        List<XpOperationsUser> value = integerListEntry.getValue();
                        pushAliMessage(value, content, task);
                    }
                }
            }
        }
        this.saveBatch(saveTask);
    }
@@ -1297,12 +1113,6 @@
                    XpVehiclePreparation vehiclePreparation = vehiclePreparationMapper.selectOne(new LambdaQueryWrapper<XpVehiclePreparation>()
                            .eq(XpVehiclePreparation::getTaskId, id).last("limit 1"));
                    XpVehicleDescription xpVehicleDescription = vehicleDescriptionMapper.selectOne(
                            new LambdaQueryWrapper<XpVehicleDescription>().eq(XpVehicleDescription::getDescriptionType, 5)
                    );
                    if (xpVehicleDescription != null)      {
                        taskManagementPreparationDetailVO.setLostItemsDetail(xpVehicleDescription.getDescriptionContent());
                    }
                    if (vehiclePreparation != null) {
                        taskManagementPreparationDetailVO.setLeftFrontWheel(vehiclePreparation.getLeftFrontWheel());
                        taskManagementPreparationDetailVO.setRightFrontWheel(vehiclePreparation.getRightFrontWheel());
@@ -1464,26 +1274,16 @@
            res.setVehicleCode(vehicle.getVehicleCode());
            res.setVehicleLocation(task.getVehicleLocation());
            res.setVehicleVin(vehicle.getVehicleVin());
            if (task.getReportUserId().equals(0L)){
                // 系统补偿上传车辆异常任务 为系统创建
                res.setReportUserId(0L);
                res.setReportUserName("系统");
                // todo 临时设置 待客户确认默认头像和电话号码
                res.setReportUserPhone("111111");
                res.setReportUserAvatar("[]");
            }else{
                List<Long> reportUserIds = new ArrayList<>();
                reportUserIds.add(task.getReportUserId());
                List<SysUser> sysUsers = sysUserClient.listByIds(reportUserIds).getData();
                if (sysUsers != null && !sysUsers.isEmpty()) {
                    SysUser sysUser = sysUsers.get(0);
                    res.setReportUserId(sysUser.getId());
                    res.setReportUserName(sysUser.getNickName());
                    res.setReportUserPhone(sysUser.getPhoneNumber());
                    res.setReportUserAvatar(sysUser.getAvatar());
                }
            List<Long> reportUserIds = new ArrayList<>();
            reportUserIds.add(task.getReportUserId());
            List<SysUser> sysUsers = sysUserClient.listByIds(reportUserIds).getData();
            if (sysUsers != null && !sysUsers.isEmpty()) {
                SysUser sysUser = sysUsers.get(0);
                res.setReportUserId(sysUser.getId());
                res.setReportUserName(sysUser.getNickName());
                res.setReportUserPhone(sysUser.getPhoneNumber());
                res.setReportUserAvatar(sysUser.getAvatar());
            }
            if (task.getHandleUserId().split(",").length == 1) {
                XpOperationsUser operationsUser = xpOperationUserClient.queryById(Long.valueOf(task.getHandleUserId())).getData();
                if (operationsUser != null) {
xp-robotaxi-maintenance-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-map-boot/pom.xml
@@ -15,11 +15,7 @@
    </description>
    <dependencies>
        <dependency>
            <groupId>com.belerweb</groupId>
            <artifactId>pinyin4j</artifactId>
            <version>2.5.1</version>
        </dependency>
        <!-- easypoi -->
        <!-- Apache POI 核心依赖 -->
        <dependency>
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/config/DataUpdateHandlerConfig.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/config/MybatisPlusConfig.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/constant/I18nKeyConstant.java
@@ -8,82 +8,4 @@
public interface I18nKeyConstant {
    String NO_WALKING_ROUTE_FOUND = "no.walking.route.found";
    String CITY_INFORMATION_DOES_NOT_EXIST = "city.information.does.not.exist";
    String NO_CURRENT_REGION = "no.current.region";
    String NO_CURRENT_POINT = "no.current.point";
    String SYSTEM_EXCEPTION = "system.exception";
    String TO_WORK = "to.work";
    String WAITING_TIME = "wait.time";
    // 编辑电子围栏失败
    String EDIT_ELECTRONIC_ERROR = "edit.electronic.error";
    // 添加电子围栏失败
    String ADD_ELECTRONIC_ERROR = "add.electronic.error";
    // 区域重叠
    String AREA_OVERLAP = "area.overlap";
    // 围栏构成不存在
    String FENCE_STRUCTURE_NOT_EXIST = "fence.structure.not.exist";
    // 围栏不存在
    String FENCE_NOT_EXIST = "fence.not.exist";
    // 围栏启用状态不可复制
    String FENCE_STATUS_CANNOT_COPIED = "fence.status.cannot.copied";
    // 订单创建失败
    String ORDER_CREATE_FAIL = "order.create.fail";
    //开通城市已存在
    String OPEN_CITY_EXISTS = "open.city.exists";
    //定价已存在
    String PRICING_EXISTS = "pricing.exists";
    //定价不存在
    String PRICING_NOT_EXIST = "pricing.not.exist";
    //价格配置json格式错误
    String PRICING_JSON_INVALID = "pricing.json.invalid";
    //价格规则不能为空
    String PRICING_RULE_EMPTY = "pricing.rule.empty";
    // 路径不存在
    String PATH_NOT_FOUND = "path.not.found";
    // 存在进行中的订单
    String HAS_UNPAID_ORDER = "has.unpaid.order";
    // 巡游计划名称不能为空
    String CRUISE_PLAN_NAME_EMPTY = "cruise.plan.name.empty";
    // 巡游计划ID不能为空
    String CRUISE_PLAN_ID_EMPTY = "cruise.plan.id.empty";
    // 巡游计划名称已存在
    String CRUISE_PLAN_NAME_EXISTS = "cruise.plan.name.exists";
    // 巡游计划不存在
    String CRUISE_PLAN_NOT_EXIST = "cruise.plan.not.exist";
    // 巡游计划点位列表不能为空
    String CRUISE_PLAN_POINT_EMPTY = "cruise.plan.point.empty";
    // 巡游计划车辆列表不能为空
    String CRUISE_PLAN_VEHICLE_EMPTY = "cruise.plan.vehicle.empty";
    // 巡游计划点位参数不完整
    String CRUISE_PLAN_POINT_INCOMPLETE = "cruise.plan.point.incomplete";
    // 巡游计划点位停车标识不合法
    String CRUISE_PLAN_STOP_FLAG_INVALID = "cruise.plan.stop.flag.invalid";
    // 巡游计划点位ID重复
    String CRUISE_PLAN_POINT_DUPLICATE = "cruise.plan.point.duplicate";
    // 巡游计划车辆参数不完整
    String CRUISE_PLAN_VEHICLE_INCOMPLETE = "cruise.plan.vehicle.incomplete";
    // 巡游计划车辆ID重复
    String CRUISE_PLAN_VEHICLE_DUPLICATE = "cruise.plan.vehicle.duplicate";
    // 巡游计划车辆已绑定其他计划
    String CRUISE_PLAN_VEHICLE_ALREADY_BOUND = "cruise.plan.vehicle.already.bound";
    // 新增巡游计划失败
    String CRUISE_PLAN_ADD_FAIL = "cruise.plan.add.fail";
    // 编辑巡游计划失败
    String CRUISE_PLAN_EDIT_FAIL = "cruise.plan.edit.fail";
}
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpElectronicFenceManagementController.java
@@ -1,7 +1,6 @@
package com.xiaopeng.map.controller;
import cn.hutool.core.collection.CollUtil;
import com.xiaopeng.api.dto.operation.ElectronicFenceAddDto;
import com.xiaopeng.api.dto.operation.ElectronicFenceAreaUpdateStatusDto;
import com.xiaopeng.api.dto.operation.ElectronicFenceUpdateDto;
@@ -9,7 +8,6 @@
import com.xiaopeng.api.model.operation.XpElectronicFence;
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.query.operation.ElectronicPageListQuery;
import com.xiaopeng.api.vo.operation.ElectronicFenceDetailVo;
import com.xiaopeng.common.core.domain.R;
@@ -17,10 +15,6 @@
import com.xiaopeng.common.core.utils.bean.BeanUtils;
import com.xiaopeng.common.core.web.page.PageInfo;
import com.xiaopeng.common.security.service.TokenService;
import com.xiaopeng.map.constant.I18nKeyConstant;
import com.xiaopeng.map.service.XpElectronicFenceAreaService;
import com.xiaopeng.map.service.XpElectronicFenceService;
import com.xiaopeng.map.service.XpRegionService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
@@ -31,8 +25,6 @@
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
/**
@@ -51,38 +43,17 @@
    @Resource
    private XpElectronicFenceService xpElectronicFenceService;
    private TokenService tokenService;
    @Resource
    private XpElectronicFenceAreaService xpElectronicFenceAreaService;
    private XpElectronicClient xpElectronicClient;
    @Resource
    private XpRegionService regionService;
    /**
     * 查询省市管理
     */
    @ApiOperation(value = "查询省市区",response = XpRegion.class)
    @GetMapping(value = "/getRegion")
    public R<List<List<XpRegion>>> geXpRegion() {
        return R.ok(regionService.getXpRegion());
    }
    @ApiOperation(value = "电子围栏管理列表", response = XpElectronicFence.class)
    @ApiOperation(value = "电子围栏管理列表", response = XpPoint.class)
    @PostMapping("/pageList")
    public R<PageInfo<XpElectronicFence>> pageList(@RequestBody ElectronicPageListQuery query) {
        PageInfo<XpElectronicFence> pageList = xpElectronicFenceService.pageList(query);
        return R.ok(pageList);
        return R.ok(xpElectronicClient.pageList(query).getData());
    }
    /**
     * 电子围栏列表接口
     *
     * @return 电子围栏列表
     */
    @ApiOperation(value = "电子围栏列表接口", tags = {"运维APP-车辆管理"})
    @GetMapping("/api/v1/electronicFence/list")
    public R<List<XpElectronicFence>> vehicleMap() {
        List<XpElectronicFence> list = xpElectronicFenceService.list();
        return R.ok(list);
    }
    /**
     * 新增电子围栏
     */
@@ -91,7 +62,8 @@
//    @Transactional
//    @ShardingSphereTransactionType(TransactionType.BASE)
    public R add(@Validated @RequestBody ElectronicFenceAddDto dto) {
        return xpElectronicFenceService.addElectronic(dto);
        return xpElectronicClient.add(dto);
    }
@@ -105,47 +77,30 @@
//    @Transactional
//    @ShardingSphereTransactionType(TransactionType.BASE)
    public R updateStatus(@RequestBody ElectronicFenceAreaUpdateStatusDto dto) {
        XpElectronicFenceArea electronicFenceArea = xpElectronicFenceAreaService.getById(dto.getId());
        if (electronicFenceArea == null) {
            throw new ServiceException(
                    "围栏构成不存在,请刷新重试",
                    I18nKeyConstant.FENCE_STRUCTURE_NOT_EXIST
            );
        }
        xpElectronicFenceAreaService.updateById(electronicFenceArea);
        return R.ok();
        return xpElectronicClient.updateStatus(dto);
    }
    /**
     * 电子围栏详情
     */
    @PostMapping("/queryById")
    @ResponseBody
    @ApiOperation(value = "电子围栏详情")
    public R<ElectronicFenceDetailVo> queryById(@RequestParam("id")Long id) {
        ElectronicFenceDetailVo res = new ElectronicFenceDetailVo();
        XpElectronicFence electronicFence = xpElectronicFenceService.getById(id);
        if (electronicFence == null) {
            throw new ServiceException(
                    "电子围栏不存在,请刷新重试",
                    I18nKeyConstant.FENCE_NOT_EXIST
            );
        }
        BeanUtils.copyProperties(electronicFence, res);
        List<XpElectronicFenceArea> electronicFenceAreaList = xpElectronicFenceAreaService.lambdaQuery().eq(XpElectronicFenceArea::getElectronicId, id)
                .list();
        res.setElectronicFenceAreas(electronicFenceAreaList);
        return R.ok(res);
        return xpElectronicClient.queryById(id);
    }
    /**
     * 编辑电子围栏
     */
    @PostMapping("/edit")
    @ResponseBody
    @ApiOperation(value = "编辑电子围栏")
//    @Transactional
//    @ShardingSphereTransactionType(TransactionType.BASE)
    public R edit(@Validated @RequestBody ElectronicFenceUpdateDto dto) {
        return xpElectronicFenceService.editElectronic(dto);
        return xpElectronicClient.edit(dto);
    }
    /**
@@ -156,77 +111,6 @@
//    @Transactional
//    @ShardingSphereTransactionType(TransactionType.BASE)
    public R<Long> copy(@RequestParam("id") Integer id) {
        XpElectronicFence electronicFence = xpElectronicFenceService.getById(id);
        if (electronicFence.getStatus()==2){
            throw new ServiceException(
                    "当前电子围栏状态为启用中,不可复制",
                    I18nKeyConstant.FENCE_STATUS_CANNOT_COPIED
            );
        }
        electronicFence.setElectronicName("副本_"+electronicFence.getElectronicName());
        electronicFence.setId(null);
        electronicFence.setStatus(0);
        xpElectronicFenceService.save(electronicFence);
        List<XpElectronicFenceArea> electronicFenceAreaList = xpElectronicFenceAreaService.lambdaQuery().eq(XpElectronicFenceArea::getElectronicId, id)
                .list();
        for (XpElectronicFenceArea area : electronicFenceAreaList) {
            area.setId(null);
            area.setElectronicId(electronicFence.getId());
            area.setAreaStatus(2);
            area.setAreaName("副本_"+area.getAreaName());
        }
        xpElectronicFenceAreaService.saveBatch(electronicFenceAreaList);
        return R.ok(electronicFence.getId());
    }
    /**
     * 根据ID列表批量查询电子围栏
     *
     * @param electronicIdSet
     * @return
     */
    @PostMapping("/listByIds")
    R<List<XpElectronicFence>> listByIds(@RequestBody Collection<Long> electronicIdSet) {
        if (CollUtil.isEmpty(electronicIdSet)) {
            return R.ok(Collections.emptyList());
        }
        return R.ok(xpElectronicFenceService.listByIds(electronicIdSet));
    }
    @ApiOperation(value = "获取已启用的电子围栏列表",tags = {"管理后台-在库车辆管理"})
    @GetMapping("/available/list")
    R<List<XpElectronicFence>> getAvailableList(){
        return R.ok(xpElectronicFenceService.getAvailableList());
    }
    @ApiOperation(value = "获取不分页的电子围栏列表",tags = {"管理后台-在库车辆管理"})
    @GetMapping("/list")
    R<List<XpElectronicFence>> getList(){
        return R.ok(xpElectronicFenceService.getList());
    }
    /**
     * 批量查询电子围栏
     * @param fenceIds
     * @return
     */
    @PostMapping("/inner/xpElectronicFence/selectBatchIds")
    public R<List<XpElectronicFence>> selectBatchIds(@RequestBody List<String> fenceIds){
        List<XpElectronicFence> xpElectronicFences = xpElectronicFenceService.listByIds(fenceIds);
        return R.ok(xpElectronicFences);
    }
    /**
     * 根据ID查询电子围栏
     * @param fenceId
     * @return
     */
    @GetMapping("/inner/xpElectronicFence/selectById")
    public R<XpElectronicFence> selectById(@RequestParam String fenceId){
        XpElectronicFence xpElectronicFence = xpElectronicFenceService.getById(fenceId);
        return R.ok(xpElectronicFence);
        return xpElectronicClient.copy(id);
    }
}
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpPointManagementController.java
@@ -1,34 +1,45 @@
package com.xiaopeng.map.controller;
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import com.xiaopeng.api.dto.operation.PointAddDto;
import com.xiaopeng.api.dto.operation.PointUpdateDto;
import com.xiaopeng.api.dto.operation.XpPointEnableDisableDto;
import com.xiaopeng.api.model.operation.XpElectronicFence;
import com.xiaopeng.api.feignClient.operation.XpPointClient;
import com.xiaopeng.api.model.operation.XpElectronicFenceArea;
import com.xiaopeng.api.model.operation.XpPoint;
import com.xiaopeng.api.query.operation.PointListQuery;
import com.xiaopeng.api.query.operation.PointPageListListQuery;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.core.utils.WebUtils;
import com.xiaopeng.common.core.web.controller.BaseController;
import com.xiaopeng.common.core.web.page.PageInfo;
import com.xiaopeng.common.security.service.TokenService;
import com.xiaopeng.map.exportExcel.XpPointExportExcel;
import com.xiaopeng.api.dto.map.XpPointExportExcelQuery;
import com.xiaopeng.map.service.XpElectronicFenceAreaService;
import com.xiaopeng.map.service.XpElectronicFenceService;
import com.xiaopeng.map.service.XpPointService;
import io.seata.spring.annotation.GlobalTransactional;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.shardingsphere.transaction.annotation.ShardingSphereTransactionType;
import org.apache.shardingsphere.transaction.core.TransactionType;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
@Slf4j
@RestController
@@ -37,76 +48,85 @@
public class XpPointManagementController extends BaseController {
    @Resource
    private XpPointService xpPointService;
    private XpPointClient xpPointClient;
    @Resource
    private XpElectronicFenceAreaService xpElectronicFenceAreaService;
    @Resource
    private XpElectronicFenceService xpElectronicFenceService;
    private TokenService tokenService;
    @ApiOperation(value = "获取所有运营中的区域", response = XpElectronicFenceArea.class)
    @PostMapping("/listElectronicFenceArea")
    public R<List<XpElectronicFenceArea>> listElectronicFenceArea() {
        // 获取所有启用的电子围栏
        List<XpElectronicFence> electronicFences = xpElectronicFenceService.lambdaQuery().eq(XpElectronicFence::getStatus, 2).list();
        List<Long> electronicFenceIds = electronicFences.stream().map(XpElectronicFence::getId).collect(Collectors.toList());
        if (electronicFenceIds.isEmpty()) {
            return R.ok(new ArrayList<XpElectronicFenceArea>());
        }
        // 获取电子围栏下启用的运营区域
        List<XpElectronicFenceArea> electronicFenceAreaList = xpElectronicFenceAreaService.lambdaQuery().in(XpElectronicFenceArea::getElectronicId, electronicFenceIds)
                .eq(XpElectronicFenceArea::getAreaStatus, 1).list();
        return R.ok(electronicFenceAreaList);
    }
        R<List<XpElectronicFenceArea>> listR = xpPointClient.listElectronicFenceArea();
    @ApiOperation(value = "点位管理列表", response = XpPoint.class)
    @PostMapping("/list")
    public R<List<XpPoint>> list(@RequestBody PointListQuery query) {
        List<XpPoint> pageList = xpPointService.listAll(query);
        return R.ok(pageList);
    }
        return listR;
    }
    @ApiOperation(value = "点位管理分页列表", response = XpPoint.class)
    @PostMapping("/pageList")
    public R<PageInfo<XpPoint>> pageList(@RequestBody PointPageListListQuery query) {
        PageInfo<XpPoint> pageList = xpPointService.pageList(query);
        return R.ok(pageList);
        return xpPointClient.pageList(query);
    }
    @ApiOperation(value = "点位导出")
    @PostMapping(value = "/exportExcel")
    public void exportExcel(@RequestBody XpPointExportExcelQuery query) {
        List<XpPoint> exportList = xpPointClient.getByIds(query).getData();
        List<XpPointExportExcel> xpPointExportExcels = new ArrayList<>();
        for (XpPoint xpPoint : exportList) {
            XpPointExportExcel xpPointExportExcel = new XpPointExportExcel();
            xpPointExportExcel.setPointNumber(xpPoint.getPointNumber());
            xpPointExportExcel.setPointName(xpPoint.getPointName());
            xpPointExportExcel.setStatus(xpPoint.getOperationStatus());
            xpPointExportExcel.setParkingTimeLimit(xpPoint.getParkingTimeLimit()+"分钟");
            xpPointExportExcel.setPointLon(xpPoint.getPointLon());
            xpPointExportExcel.setPointLat(xpPoint.getPointLat());
            xpPointExportExcel.setCreateBy(xpPoint.getCreateBy());
            xpPointExportExcel.setCreateTime(xpPoint.getCreateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            xpPointExportExcels.add(xpPointExportExcel);
        }
        //1.获取excel模板
        Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(), XpPointExportExcel.class, xpPointExportExcels);
        HttpServletResponse response = WebUtils.response();
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        ServletOutputStream outputStream = null;
        try {
            String fileName = URLEncoder.encode("点位列表.csv", "utf-8");
            response.setHeader("Content-dispodition", "attachment;filename=" + fileName);
            outputStream = response.getOutputStream();
            workbook.write(outputStream);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                outputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    @PostMapping("/getByIds")
    public R<List<XpPoint>> getByIds(@RequestBody XpPointExportExcelQuery query) {
        List<XpPoint> list = xpPointService.lambdaQuery().in(XpPoint::getId, query.getPointIds()).list();
        return R.ok(list);
    }
    @ApiOperation(value = "点位管理列表", response = XpPoint.class)
    @PostMapping("/list")
    public R<List<XpPoint>> list(@RequestBody PointListQuery query) {
        if (StringUtils.hasLength(query.getOperationStatus())){
            List<Integer> operationStatusIds = Arrays.stream(query.getOperationStatus().split(",")).map(Integer::parseInt).collect(Collectors.toList());
            query.setOperationStatusIds(operationStatusIds);
        }
        return xpPointClient.list( query);
    }
    /**
     * 新增点位
     */
    @PostMapping("/add")
    @ResponseBody
    @ApiOperation(value = "新增点位")
//    @Transactional
//    @ShardingSphereTransactionType(TransactionType.BASE)
    public R add(@Validated @RequestBody PointAddDto pointAddDto) {
        XpPoint xpPoint = new XpPoint();
        BeanUtils.copyProperties(pointAddDto, xpPoint);
        xpPointService.save(xpPoint);
    public R add(@Validated  @RequestBody PointAddDto pointAddDto) {
        xpPointClient.add(pointAddDto);
        return R.ok();
    }
    /**
     * 批量删除点位
     */
    @GetMapping("/delete")
    @ResponseBody
    @ApiOperation(value = "删除点位")
//    @Transactional
//    @ShardingSphereTransactionType(TransactionType.BASE)
    public R deletePoint(@RequestParam("ids") String ids) {
        xpPointService.removeBatchByIds(Arrays.stream(ids.split(",")).map(Long::parseLong).collect(Collectors.toList()));
        return R.ok();
    }
    /**
     * 编辑点位
     */
@@ -114,36 +134,39 @@
    @ApiOperation(value = "编辑点位")
//    @Transactional
//    @ShardingSphereTransactionType(TransactionType.BASE)
    public R edit(@Validated @RequestBody PointUpdateDto pointAddDto) {
        XpPoint xpPoint = new XpPoint();
        BeanUtils.copyProperties(pointAddDto, xpPoint);
        xpPointService.updateById(xpPoint);
    public R edit(@Validated@RequestBody PointUpdateDto pointAddDto) {
        xpPointClient.edit(pointAddDto);
        return R.ok();
    }
    /**
     * 点位详情
     * 批量删除点位
     */
    @GetMapping("/api/v1/point/queryById")
    @ApiOperation(value = "点位详情")
    public R<XpPoint> queryById(@RequestParam Long id) {
        return R.ok(xpPointService.getById(id));
    @GetMapping("/deletePoint")
    @ApiOperation(value = "删除点位")
//    @Transactional
//    @ShardingSphereTransactionType(TransactionType.BASE)
    public R deletePoint(@RequestParam("ids") String ids) {
        xpPointClient.deletePoint(ids);
        return R.ok();
    }
    /**
     * 编辑点位
     */
    @GetMapping("/queryById")
    @ResponseBody
    @ApiOperation(value = "点位详情")
    public R queryById(@RequestParam Long id) {
        return xpPointClient.queryById( id);
    }
    /**
     * 启用/禁用
     */
    @PostMapping("/enableDisable")
    @ResponseBody
    @ApiOperation(value = "启用/禁用")
//    @Transactional
//    @ShardingSphereTransactionType(TransactionType.BASE)
    public R enableDisable(@RequestBody XpPointEnableDisableDto dto) {
        XpPoint xpPoint = xpPointService.getById(dto.getId());
        xpPoint.setOperationStatus(dto.getOperationStatus());
        xpPoint.setElectronicAreaId(null);
        xpPointService.updateById(xpPoint);
        return R.ok();
        return xpPointClient.enableDisable(dto);
    }
}
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/dto/NearestDto.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/dto/NotificationDto.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/dto/OpenCityAddDTO.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/dto/OpenCityEditDTO.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/dto/PricingAddDTO.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/dto/PricingEditDTO.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/dto/PricingSetPriceDTO.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/dto/PricingSetRuleDTO.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/dto/RoutePlanAddDTO.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/dto/RoutePlanEditDTO.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/dto/WhitelistAddDto.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/dto/WhitelistEditDto.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/dto/XpAgreementAppUserDto.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/dto/XpAgreementDTO.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/dto/XpCruisePlanAddDTO.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/dto/XpCruisePlanEditDTO.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/dto/XpFrequentlyAskedQuestionsDTO.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/dto/XpOrderDto.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/dto/XpPointSpecialDto.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/dto/XpRideGuideDTO.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/dto/XpTradingStrategyEditDTO.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/dto/XpUserFeedbackDto.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/job/base/AbstractJob.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/job/base/QuartzManager.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/job/base/TimeJobType.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/job/exceptions/TimeException.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/job/jobs/ElectronicEffectJob.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/job/jobs/OrderCancelJob.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/job/utils/SpringContextsUtil.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/mapper/XpElectronicFenceMapper.java
@@ -3,11 +3,6 @@
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.xiaopeng.api.model.operation.XpElectronicFence;
import com.xiaopeng.api.query.operation.ElectronicPageListQuery;
import com.xiaopeng.common.core.web.page.PageInfo;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
 * <p>
@@ -18,6 +13,5 @@
 * @since 2026-02-03
 */
public interface XpElectronicFenceMapper extends BaseMapper<XpElectronicFence> {
    List<XpElectronicFence> pageList(@Param("pageInfo") PageInfo<XpElectronicFence> pageInfo, @Param("query") ElectronicPageListQuery query);
}
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/mapper/XpOpenCityMapper.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/mapper/XpPointMapper.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/mapper/XpRegionMapper.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/mapper/XpSystemSettingMapper.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/query/BannerPageListQuery.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/query/CruisePlanQuery.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/query/InvitationPageListQuery.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/query/OpenCityPageQuery.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/query/PointByNameQuery.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/query/PricingPageListQuery.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/query/RoutePlanPageListQuery.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/query/UserFeedBackQuery.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/query/WhitelistLogPageListQuery.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/query/WhitelistPageListQuery.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/query/XpCouponListQuery.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/query/getProvinceQuery.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/XpElectronicFenceService.java
@@ -2,14 +2,7 @@
import com.baomidou.mybatisplus.extension.service.IService;
import com.xiaopeng.api.dto.operation.ElectronicFenceAddDto;
import com.xiaopeng.api.dto.operation.ElectronicFenceUpdateDto;
import com.xiaopeng.api.model.operation.XpElectronicFence;
import com.xiaopeng.api.query.operation.ElectronicPageListQuery;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.core.web.page.PageInfo;
import java.util.List;
/**
 * <p>
@@ -20,23 +13,7 @@
 * @since 2026-02-03
 */
public interface XpElectronicFenceService extends IService<XpElectronicFence> {
    PageInfo<XpElectronicFence> pageList(ElectronicPageListQuery query);
    R addElectronic(ElectronicFenceAddDto dto);
    R editElectronic(ElectronicFenceUpdateDto dto);
    /**
     * 查询启用的电子围栏列表
     * @return
     */
    List<XpElectronicFence> getAvailableList();
    /**
     * 获取不分页的围栏列表
     * @return
     */
    List<XpElectronicFence> getList();
}
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/XpOpenCityService.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/XpPointService.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/XpRegionService.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/XpSystemSettingService.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/serviceimpl/XpElectronicFenceServiceImpl.java
@@ -2,48 +2,18 @@
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.ImmutableMap;
import com.xiaopeng.api.dto.operation.ElectronicFenceAddDto;
import com.xiaopeng.api.dto.operation.ElectronicFenceUpdateDto;
import com.xiaopeng.api.model.map.XpGeoFencingPolygon;
import com.xiaopeng.api.model.map.XpGeoFencingProhibitedPolygon;
import com.xiaopeng.api.model.operation.*;
import com.xiaopeng.api.query.operation.ElectronicPageListQuery;
import com.xiaopeng.api.model.operation.XpElectronicFence;
import com.xiaopeng.api.model.operation.XpOpenCity;
import com.xiaopeng.api.vo.operation.XpElectronicFenceVo;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.core.exception.ServiceException;
import com.xiaopeng.common.core.utils.DateUtils;
import com.xiaopeng.common.core.utils.StringUtils;
import com.xiaopeng.common.core.utils.bean.BeanUtils;
import com.xiaopeng.common.core.web.page.PageInfo;
import com.xiaopeng.map.constant.I18nKeyConstant;
import com.xiaopeng.map.job.base.QuartzManager;
import com.xiaopeng.map.job.base.TimeJobType;
import com.xiaopeng.map.job.jobs.ElectronicEffectJob;
import com.xiaopeng.map.mapper.XpElectronicFenceAreaMapper;
import com.xiaopeng.map.mapper.XpElectronicFenceMapper;
import com.xiaopeng.map.mapper.XpPointMapper;
import com.xiaopeng.map.mapper.XpRegionMapper;
import com.xiaopeng.map.service.XpElectronicFenceService;
import com.xiaopeng.map.utils.PolygonOverlapService;
import lombok.extern.slf4j.Slf4j;
import net.sourceforge.pinyin4j.PinyinHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.geo.Point;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.geo.GeoJsonPolygon;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
@@ -55,593 +25,9 @@
 * @since 2026-02-03
 */
@Service
@Slf4j
public class XpElectronicFenceServiceImpl extends ServiceImpl<XpElectronicFenceMapper, XpElectronicFence> implements XpElectronicFenceService {
    @Resource
    private PolygonOverlapService polygonOverlapService;
    @Resource
    private XpElectronicFenceAreaMapper xpElectronicFenceAreaMapper;
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private XpPointMapper xpPointMapper;
    @Autowired
    private XpRegionMapper xpRegionMapper;
    @Override
    public PageInfo<XpElectronicFence> pageList(ElectronicPageListQuery query) {
        PageInfo<XpElectronicFence> pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize());
        if (StringUtils.isEmpty(query.getCreateSort())&& StringUtils.isEmpty(query.getUpdateSort())){
            query.setCreateSort("2");
        }
        List<XpElectronicFence> list = this.baseMapper.pageList(pageInfo, query);
        if (list.isEmpty()) {
            return new PageInfo<>();
        }
        List<Long> electronicIds = list.stream().map(XpElectronicFence::getId).collect(Collectors.toList());
        Map<Long, List<XpElectronicFenceArea>> electronicFenceAreaMap = xpElectronicFenceAreaMapper.selectList(new LambdaQueryWrapper<XpElectronicFenceArea>()
                        .in(XpElectronicFenceArea::getElectronicId, electronicIds)).stream()
                .collect(Collectors.groupingBy(XpElectronicFenceArea::getElectronicId));
        for (XpElectronicFence xpElectronicFence : list) {
            List<XpElectronicFenceArea> xpElectronicFenceAreas = electronicFenceAreaMap.get(xpElectronicFence.getId());
            if (xpElectronicFenceAreas != null) {
                xpElectronicFence.setOperatingAreaCount(xpElectronicFenceAreas.stream().filter(xpElectronicFenceArea -> xpElectronicFenceArea.getAreaType() == 1).count());
                xpElectronicFence.setProhibitedAreaCount(xpElectronicFenceAreas.stream().filter(xpElectronicFenceArea -> xpElectronicFenceArea.getAreaType() == 2).count());
            }else{
                xpElectronicFence.setOperatingAreaCount(0L);
                xpElectronicFence.setProhibitedAreaCount(0L);
            }
        }
        pageInfo.setRecords(list);
        return pageInfo;
    }
    public 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();
    }
    @Override
    public R addElectronic(ElectronicFenceAddDto dto) {
        try {
            // 获取现有的运营区域(areaType=1)
            LambdaQueryWrapper<XpElectronicFenceArea> xpElectronicFenceAreaLambdaQueryWrapper = new LambdaQueryWrapper<>();
            xpElectronicFenceAreaLambdaQueryWrapper.eq(XpElectronicFenceArea::getAreaType, 1);
            List<XpElectronicFenceArea> existingOperationAreas = xpElectronicFenceAreaMapper.selectList(xpElectronicFenceAreaLambdaQueryWrapper);
            // 获取待添加的新区域
            List<XpElectronicFenceArea> newElectronicFenceAreas = dto.getElectronicFenceAreas();
            // 检查新区域与现有运营区域是否有重叠
            for (XpElectronicFenceArea newArea : newElectronicFenceAreas) {
                if (newArea.getAreaType() == 1) { // 只检查运营区域
                    for (XpElectronicFenceArea existingArea : existingOperationAreas) {
                        if (polygonOverlapService.checkPolygonOverlap(
                                newArea.getFencePoints(),
                                existingArea.getFencePoints())) {
                            throw new ServiceException(
                                    "运营区域{}与现有运营区域{}发生重叠",
                                    I18nKeyConstant.EDIT_ELECTRONIC_ERROR,
                                    new Object[]{existingArea.getAreaName(), existingArea.getAreaName()}
                            );
                        }
                    }
                }
            }
            // 保存主表数据
            XpElectronicFence xpElectronicFence = new XpElectronicFence();
            BeanUtils.copyProperties(dto, xpElectronicFence);
            xpElectronicFence.setStatus(0);
            if (dto.getStatus() == 0) {
                xpElectronicFence.setStatus(0);
            } else if (dto.getStatus() == 1) {
                if (dto.getEffectType() == 1) {
                    // 设置为启用中
                    xpElectronicFence.setStatus(2);
                    xpElectronicFence.setEffectTime(LocalDateTime.now());
                } else {
                    if (dto.getEffectTime().isBefore(LocalDateTime.now())) {
                        // 设置为启用中
                        xpElectronicFence.setStatus(2);
                    } else {
                        xpElectronicFence.setStatus(1);
                    }
                }
            }
            xpElectronicFence.setCityCode(dto.getCityCode());
            // 生成围栏id 规则:城市首字母-类型简写-4位自增流水号(如 SZ-OP-001),支持复制;数据停用或删除后,流水号不回收
            XpRegion xpRegion = xpRegionMapper.selectOne(new LambdaQueryWrapper<XpRegion>()
                    .eq(XpRegion::getCode, dto.getCityCode()));
            String name = xpRegion.getName();
            this.save(xpElectronicFence);
            // 根据城市中文名,截取前两位的首字母并且大写
            // 截取前两个字符
            String prefix = name.substring(0, 2);
            // 获取拼音首字母并大写
            String result = getPinyinInitials(prefix).toUpperCase();
            xpElectronicFence.setElectronicNumber(result + "-OP-" + String.format("%04d", xpElectronicFence.getId()));
            if (dto.getStatus() == 0) {
                xpElectronicFence.setStatus(0);
            } else if (dto.getStatus() == 1) {
                if (dto.getEffectType() == 1) {
                    // 设置为启用中
                    xpElectronicFence.setStatus(2);
                    xpElectronicFence.setEffectTime(LocalDateTime.now());
                } else {
                    if (dto.getEffectTime().isBefore(LocalDateTime.now())) {
                        // 设置为启用中
                        xpElectronicFence.setStatus(2);
                    } else {
                        // 添加定时任务job type=1电子围栏生效 type=2电子围栏失效
                        Map<String, ? extends Object> maps =
                                new ImmutableMap.Builder<String, Long>().
                                        put("type", 1L)
                                        .put("id", xpElectronicFence.getId())
                                        .build();
                        QuartzManager.addJob(
                                ElectronicEffectJob.class,
                                (ElectronicEffectJob.effect + xpElectronicFence.getId()).toUpperCase(),
                                TimeJobType.ELECTRONIC_EFFECT,
                                DateUtils.localDateTimeToDate(dto.getEffectTime()),
                                maps
                        );
                        xpElectronicFence.setStatus(1);
                    }
                }
                if (dto.getFailureType() != null && dto.getFailureType() == 2) {
                    if (dto.getFailureTime().isBefore(LocalDateTime.now())) {
                        // 设置待启用
                        xpElectronicFence.setStatus(1);
                    } else {
                        // 添加定时任务job type=1电子围栏生效 type=2电子围栏失效
                        Map<String, ? extends Object> maps =
                                new ImmutableMap.Builder<String, Long>().
                                        put("type", 2L)
                                        .put("id", xpElectronicFence.getId())
                                        .build();
                        QuartzManager.addJob(
                                ElectronicEffectJob.class,
                                (ElectronicEffectJob.failure + xpElectronicFence.getId()).toUpperCase(),
                                TimeJobType.ELECTRONIC_FAILURE,
                                DateUtils.localDateTimeToDate(dto.getEffectTime()),
                                maps
                        );
                        xpElectronicFence.setStatus(1);
                    }
                }
            }
            this.updateById(xpElectronicFence);
            if (xpElectronicFence.getStatus() == 2) {
                // 设置电子围栏ID并保存区域数据
                for (XpElectronicFenceArea area : newElectronicFenceAreas) {
                    area.setElectronicId(xpElectronicFence.getId());
                    area.setAreaStatus(1);
                    area.setArea(area.getArea());
                    area.setCityCode(dto.getCityCode());
                    xpElectronicFenceAreaMapper.insert(area);
                }
            }else{
                // 设置电子围栏ID并保存区域数据
                for (XpElectronicFenceArea area : newElectronicFenceAreas) {
                    area.setElectronicId(xpElectronicFence.getId());
                    area.setAreaStatus(2);
                    area.setArea(area.getArea());
                    area.setCityCode(dto.getCityCode());
                    xpElectronicFenceAreaMapper.insert(area);
                }
            }
            if (xpElectronicFence.getStatus() == 2) {
                for (XpElectronicFenceArea newElectronicFenceArea : newElectronicFenceAreas) {
                    if (newElectronicFenceArea.getAreaType() == 1
                            && newElectronicFenceArea.getAreaStatus() == 1) {
                        XpGeoFencingPolygon xpGeoFencingPolygon = new XpGeoFencingPolygon();
                        xpGeoFencingPolygon.setFenceId(String.valueOf(xpElectronicFence.getId()));
                        xpGeoFencingPolygon.setName(xpElectronicFence.getElectronicName());
                        xpGeoFencingPolygon.setAreaId(String.valueOf(newElectronicFenceArea.getId()));
                        xpGeoFencingPolygon.setCityCode(xpElectronicFence.getCityCode());
                        xpGeoFencingPolygon.setOperationStrategy(xpElectronicFence.getOperationStrategy());
                        // 将围栏点转换为GeoJSON多边形
                        GeoJsonPolygon geoJsonPolygon = convertToGeoJsonPolygon(newElectronicFenceArea.getFencePoints());
                        xpGeoFencingPolygon.setPoints(geoJsonPolygon);
                        mongoTemplate.insert(xpGeoFencingPolygon);
                    }
                    if (newElectronicFenceArea.getAreaType() == 2
                            && newElectronicFenceArea.getAreaStatus() == 1) {
                        XpGeoFencingProhibitedPolygon xpGeoFencingProhibitedPolygon = new XpGeoFencingProhibitedPolygon();
                        xpGeoFencingProhibitedPolygon.setFenceId(String.valueOf(xpElectronicFence.getId()));
                        xpGeoFencingProhibitedPolygon.setName(xpElectronicFence.getElectronicName());
                        xpGeoFencingProhibitedPolygon.setAreaId(String.valueOf(newElectronicFenceArea.getId()));
                        // 将围栏点转换为GeoJSON多边形
                        GeoJsonPolygon geoJsonPolygon = convertToGeoJsonPolygon(newElectronicFenceArea.getFencePoints());
                        xpGeoFencingProhibitedPolygon.setPoints(geoJsonPolygon);
                        mongoTemplate.save(xpGeoFencingProhibitedPolygon);
                    }
                }
            }
            return R.ok();
        } catch (Exception e) {
            log.error("新增电子围栏失败", e);
            throw new ServiceException("新增电子围栏失败", I18nKeyConstant.ADD_ELECTRONIC_ERROR);
        }
    }
    @Override
    public R editElectronic(ElectronicFenceUpdateDto dto) {
        try {
            // 获取现有的运营区域(areaType=1),排除当前正在编辑的电子围栏
            LambdaQueryWrapper<XpElectronicFenceArea> xpElectronicFenceAreaLambdaQueryWrapper = new LambdaQueryWrapper<>();
            xpElectronicFenceAreaLambdaQueryWrapper.eq(XpElectronicFenceArea::getAreaType, 1);
            xpElectronicFenceAreaLambdaQueryWrapper.ne(XpElectronicFenceArea::getElectronicId, dto.getId());
            List<XpElectronicFenceArea> existingOperationAreas = xpElectronicFenceAreaMapper.selectList(xpElectronicFenceAreaLambdaQueryWrapper);
            // 获取待更新的区域
            List<XpElectronicFenceArea> updatedElectronicFenceAreas = dto.getElectronicFenceAreas();
            // 检查更新后的区域与现有运营区域是否有重叠
            for (XpElectronicFenceArea updatedArea : updatedElectronicFenceAreas) {
                if (updatedArea.getAreaType() == 1) { // 只检查运营区域
                    for (XpElectronicFenceArea existingArea : existingOperationAreas) {
                        if (polygonOverlapService.checkPolygonOverlap(
                                updatedArea.getFencePoints(),
                                existingArea.getFencePoints())) {
                            throw new ServiceException(
                                    "运营区域{}与现有运营区域{}发生重叠",
                                    I18nKeyConstant.AREA_OVERLAP,
                                    new Object[]{existingArea.getAreaName(), existingArea.getAreaName()}
                            );
                        }
                    }
                }
            }
            // 更新主表数据
            XpElectronicFence xpElectronicFence = new XpElectronicFence();
            BeanUtils.copyProperties(dto, xpElectronicFence);
            if (dto.getStatus() == 0) {
                xpElectronicFence.setStatus(0);
            } else if (dto.getStatus() == 1) {
                if (dto.getEffectType() == 1) {
                    // 设置为启用中
                    xpElectronicFence.setStatus(2);
                    xpElectronicFence.setEffectTime(LocalDateTime.now());
                } else {
                    if (dto.getEffectTime().isBefore(LocalDateTime.now())) {
                        // 设置为启用中
                        xpElectronicFence.setStatus(2);
                    } else {
                        // 先删除以前的定时任务
                        QuartzManager.removeJob((ElectronicEffectJob.effect + xpElectronicFence.getId()).toUpperCase(), TimeJobType.ELECTRONIC_EFFECT);
                        // 添加定时任务job type=1电子围栏生效 type=2电子围栏失效
                        Map<String, ? extends Object> maps =
                                new ImmutableMap.Builder<String, Long>().
                                        put("type", 1L)
                                        .put("id", xpElectronicFence.getId())
                                        .build();
                        QuartzManager.addJob(
                                ElectronicEffectJob.class,
                                (ElectronicEffectJob.effect + xpElectronicFence.getId()).toUpperCase(),
                                TimeJobType.ELECTRONIC_EFFECT,
                                DateUtils.localDateTimeToDate(dto.getEffectTime()),
                                maps
                        );
                        xpElectronicFence.setStatus(1);
                    }
                }
                if (dto.getFailureType() != null && dto.getFailureType() == 2) {
                    if (dto.getFailureTime().isBefore(LocalDateTime.now())) {
                        // 设置待启用
                        xpElectronicFence.setStatus(1);
                    } else {
                        // 先删除以前的定时任务
                        QuartzManager.removeJob((ElectronicEffectJob.failure + xpElectronicFence.getId()).toUpperCase(), TimeJobType.ELECTRONIC_FAILURE);
                        // 添加定时任务job type=1电子围栏生效 type=2电子围栏失效
                        Map<String, ? extends Object> maps =
                                new ImmutableMap.Builder<String, Long>().
                                        put("type", 2L)
                                        .put("id", xpElectronicFence.getId())
                                        .build();
                        QuartzManager.addJob(
                                ElectronicEffectJob.class,
                                (ElectronicEffectJob.failure + xpElectronicFence.getId()).toUpperCase(),
                                TimeJobType.ELECTRONIC_FAILURE,
                                DateUtils.localDateTimeToDate(dto.getEffectTime()),
                                maps
                        );
                        xpElectronicFence.setStatus(1);
                    }
                }
            }
            xpElectronicFence.setCityCode(dto.getCityCode());
            this.updateById(xpElectronicFence);
            // 删除旧的区域数据,然后保存新的区域数据
            xpElectronicFenceAreaMapper.delete(new LambdaQueryWrapper<XpElectronicFenceArea>()
                    .eq(XpElectronicFenceArea::getElectronicId, dto.getId()));
            if (xpElectronicFence.getStatus() == 2) {
                // 设置电子围栏ID并保存区域数据
                for (XpElectronicFenceArea area : updatedElectronicFenceAreas) {
                    area.setElectronicId(xpElectronicFence.getId());
                    area.setAreaStatus(1);
                    area.setArea(area.getArea());
                    area.setCityCode(dto.getCityCode());
                    xpElectronicFenceAreaMapper.insert(area);
                }
            }else{
                // 设置电子围栏ID并保存区域数据
                for (XpElectronicFenceArea area : updatedElectronicFenceAreas) {
                    area.setElectronicId(xpElectronicFence.getId());
                    area.setAreaStatus(2);
                    area.setArea(area.getArea());
                    area.setCityCode(dto.getCityCode());
                    xpElectronicFenceAreaMapper.insert(area);
                }
            }
            if (dto.getStatus() == 2) {
                for (XpElectronicFenceArea newElectronicFenceArea : updatedElectronicFenceAreas) {
                    if (newElectronicFenceArea.getAreaType() == 1
                            && newElectronicFenceArea.getAreaStatus() == 1) {
                        // 先查询出mongo里围栏相同的数据 如果有 那么更新数据
                        Query query = new Query();
                        query.addCriteria(Criteria.where("fenceId").is(String.valueOf(xpElectronicFence.getId())));
                        query.addCriteria(Criteria.where("areaId").is(String.valueOf(newElectronicFenceArea.getId())));
                        XpGeoFencingPolygon old = mongoTemplate.findOne(query, XpGeoFencingPolygon.class);
                        if (old == null) {
                            XpGeoFencingPolygon xpGeoFencingPolygon = new XpGeoFencingPolygon();
                            xpGeoFencingPolygon.setFenceId(String.valueOf(xpElectronicFence.getId()));
                            xpGeoFencingPolygon.setName(xpElectronicFence.getElectronicName());
                            xpGeoFencingPolygon.setAreaId(String.valueOf(newElectronicFenceArea.getId()));
                            xpGeoFencingPolygon.setOperationStrategy(xpElectronicFence.getOperationStrategy());
                            // 将围栏点转换为GeoJSON多边形
                            GeoJsonPolygon geoJsonPolygon = convertToGeoJsonPolygon(newElectronicFenceArea.getFencePoints());
                            xpGeoFencingPolygon.setPoints(geoJsonPolygon);
                            mongoTemplate.insert(xpGeoFencingPolygon);
                        } else {
                            // 如果存在,则更新已有文档
                            old.setFenceId(String.valueOf(xpElectronicFence.getId()));
                            old.setName(xpElectronicFence.getElectronicName());
                            old.setAreaId(String.valueOf(newElectronicFenceArea.getId()));
                            old.setOperationStrategy(xpElectronicFence.getOperationStrategy());
                            // 将围栏点转换为GeoJSON多边形
                            GeoJsonPolygon geoJsonPolygon = convertToGeoJsonPolygon(newElectronicFenceArea.getFencePoints());
                            old.setPoints(geoJsonPolygon);
                            // 执行更新操作
                            mongoTemplate.save(old); // save() 会根据 _id 自动判断是插入还是更新
                        }
                    }
                    if (newElectronicFenceArea.getAreaType() == 2
                            && newElectronicFenceArea.getAreaStatus() == 1) {
                        // 先查询出mongo里围栏相同的数据 如果有 那么更新数据
                        Query query = new Query();
                        query.addCriteria(Criteria.where("fenceId").is(String.valueOf(xpElectronicFence.getId())));
                        query.addCriteria(Criteria.where("areaId").is(String.valueOf(newElectronicFenceArea.getId())));
                        XpGeoFencingProhibitedPolygon old = mongoTemplate.findOne(query, XpGeoFencingProhibitedPolygon.class);
                        if (old == null) {
                            XpGeoFencingProhibitedPolygon xpGeoFencingProhibitedPolygon = new XpGeoFencingProhibitedPolygon();
                            xpGeoFencingProhibitedPolygon.setFenceId(String.valueOf(xpElectronicFence.getId()));
                            xpGeoFencingProhibitedPolygon.setName(xpElectronicFence.getElectronicName());
                            xpGeoFencingProhibitedPolygon.setAreaId(String.valueOf(newElectronicFenceArea.getId()));
                            // 将围栏点转换为GeoJSON多边形
                            GeoJsonPolygon geoJsonPolygon = convertToGeoJsonPolygon(newElectronicFenceArea.getFencePoints());
                            xpGeoFencingProhibitedPolygon.setPoints(geoJsonPolygon);
                            mongoTemplate.save(xpGeoFencingProhibitedPolygon);
                        } else {
                            old.setFenceId(String.valueOf(xpElectronicFence.getId()));
                            old.setName(xpElectronicFence.getElectronicName());
                            old.setAreaId(String.valueOf(newElectronicFenceArea.getId()));
                            // 将围栏点转换为GeoJSON多边形
                            GeoJsonPolygon geoJsonPolygon = convertToGeoJsonPolygon(newElectronicFenceArea.getFencePoints());
                            old.setPoints(geoJsonPolygon);
                            mongoTemplate.save(old);
                        }
                    }
                }
            }
            // 判断区域下的所有运营点位是否处于运营区域内 如果不是则更新为测试点位
            List<Long> areaIds = updatedElectronicFenceAreas.stream().map(XpElectronicFenceArea::getId).collect(Collectors.toList());
            LambdaQueryWrapper<XpPoint> pointLambdaQueryWrapper = new LambdaQueryWrapper<>();
            pointLambdaQueryWrapper.in(XpPoint::getElectronicAreaId, areaIds).eq(XpPoint::getPointType, 1);
            List<XpPoint> xpPoints = xpPointMapper.selectList(pointLambdaQueryWrapper);
            List<XpPoint> updatePoints = new ArrayList<>();
            if (!xpPoints.isEmpty()) {
                List<Long> electronicAreaId = xpPoints.stream().map(XpPoint::getElectronicAreaId).distinct().collect(Collectors.toList());
                if (!electronicAreaId.isEmpty()) {
                    Map<Long, XpElectronicFenceArea> longXpElectronicFenceAreaMap = updatedElectronicFenceAreas
                            .stream().collect(Collectors.toMap(XpElectronicFenceArea::getId, e -> e));
                    for (XpPoint xpPoint : xpPoints) {
                        XpElectronicFenceArea xpElectronicFenceArea = longXpElectronicFenceAreaMap.get(xpPoint.getElectronicAreaId());
                        if (xpElectronicFenceArea != null) {
                            String fencePoints = xpElectronicFenceArea.getFencePoints();
                            Double pointLat = xpPoint.getPointLat();
                            Double pointLon = xpPoint.getPointLon();
                            // 判断这个点位有没有处于当前区域 由多个经纬度点构成的面里
                            if (fencePoints != null && !fencePoints.trim().isEmpty() &&
                                    pointLat != null && pointLon != null) {
                                boolean isInside = isPointInPolygon(fencePoints, pointLon, pointLat);
                                // 如果点不在区域内,更新为测试点位
                                if (!isInside) {
                                    xpPoint.setPointType(2); //
                                    log.info("点位ID: {} 经纬度: ({}, {}) 不在电子围栏区域内,已更新为测试点位",
                                            xpPoint.getId(), pointLon, pointLat);
                                    UpdateWrapper<XpPoint> xpPointUpdateWrapper = new UpdateWrapper<>();
                                    xpPointUpdateWrapper.eq("id", xpPoint.getId());
                                    xpPointUpdateWrapper.set("point_type", 2);
                                    xpPointUpdateWrapper.set("electronic_areaId", null);
                                    xpPointMapper.update(xpPoint, xpPointUpdateWrapper);
                                }
                            }
                        }
                    }
                }
            }
            return R.ok();
        } catch (Exception e) {
            log.error("编辑电子围栏失败", e);
            throw new ServiceException("编辑电子围栏失败", I18nKeyConstant.EDIT_ELECTRONIC_ERROR);
        }
    }
    /**
     * 判断点是否在多边形内
     *
     * @param fencePointsStr 多边形顶点字符串,格式:经度_维度,经度_维度
     * @param pointLon       待检测点的经度
     * @param pointLat       待检测点的纬度
     * @return true表示在多边形内,false表示在多边形外
     */
    private boolean isPointInPolygon(String fencePointsStr, double pointLon, double pointLat) {
        if (fencePointsStr == null || fencePointsStr.trim().isEmpty()) {
            return false;
        }
        // 解析多边形顶点
        String[] pointPairs = fencePointsStr.split(",");
        List<double[]> polygonVertices = new ArrayList<>();
        for (String pointPair : pointPairs) {
            String[] lngLat = pointPair.trim().split("_");
            if (lngLat.length >= 2) {
                try {
                    double longitude = Double.parseDouble(lngLat[0]);
                    double latitude = Double.parseDouble(lngLat[1]);
                    polygonVertices.add(new double[]{longitude, latitude});
                } catch (NumberFormatException e) {
                    log.error("解析多边形顶点坐标失败: {}", pointPair, e);
                    return false;
                }
            }
        }
        if (polygonVertices.size() < 3) {
            return false; // 至少需要3个点才能构成多边形
        }
        return isPointInPolygon(polygonVertices, pointLon, pointLat);
    }
    /**
     * 使用射线法判断点是否在多边形内
     *
     * @param polygonVertices 多边形顶点列表
     * @param pointLon        待检测点的经度
     * @param pointLat        待检测点的纬度
     * @return true表示在多边形内,false表示在多边形外
     */
    private boolean isPointInPolygon(List<double[]> polygonVertices, double pointLon, double pointLat) {
        int n = polygonVertices.size();
        boolean inside = false;
        // 射线法判断点是否在多边形内
        double x = pointLon, y = pointLat;
        for (int i = 0, j = n - 1; i < n; j = i++) {
            double xi = polygonVertices.get(i)[0], yi = polygonVertices.get(i)[1];
            double xj = polygonVertices.get(j)[0], yj = polygonVertices.get(j)[1];
            // 判断当前边是否与水平射线相交
            boolean intersect = ((yi > y) != (yj > y)) &&
                    (x < (xj - xi) * (y - yi) / (yj - yi) + xi);
            if (intersect) {
                inside = !inside;
            }
        }
        return inside;
    }
    /**
     * 将围栏点字符串转换为GeoJsonPolygon
     * 格式:经度_维度,经度_维度
     */
    private GeoJsonPolygon convertToGeoJsonPolygon(String fencePointsStr) {
        if (fencePointsStr == null || fencePointsStr.trim().isEmpty()) {
            return null;
        }
        // 分割多个点对
        String[] pointPairs = fencePointsStr.split(",");
        List<Point> points = new ArrayList<>();
        for (String pointPair : pointPairs) {
            String[] lngLat = pointPair.trim().split("_");
            if (lngLat.length >= 2) {
                try {
                    double longitude = Double.parseDouble(lngLat[0]);
                    double latitude = Double.parseDouble(lngLat[1]);
                    points.add(new Point(longitude, latitude)); // Point 构造函数是 (x, y) -> (longitude, latitude)
                } catch (NumberFormatException e) {
                    log.error("解析经纬度坐标失败: {}", pointPair, e);
                    throw new IllegalArgumentException("经纬度格式错误: " + pointPair);
                }
            }
        }
        // 如果没有足够的点构成多边形,至少需要3个点
        if (points.size() < 3) {
            throw new IllegalArgumentException("围栏点数量不足,至少需要3个点构成多边形");
        }
        // 确保多边形是闭合的(如果最后一个点不等于第一个点,则添加第一个点)
        if (!points.get(0).equals(points.get(points.size() - 1))) {
            points.add(points.get(0)); // 添加第一个点作为最后一个点,闭合多边形
        }
        return new GeoJsonPolygon(points);
    }
    /**
     * 检查新添加的区域之间是否有重叠
     */
    private boolean hasOverlapWithinNewAreas(List<XpElectronicFenceArea> newAreas) {
        for (int i = 0; i < newAreas.size(); i++) {
            XpElectronicFenceArea area1 = newAreas.get(i);
            if (area1.getAreaType() != 1) continue; // 只检查运营区域
            for (int j = i + 1; j < newAreas.size(); j++) {
                XpElectronicFenceArea area2 = newAreas.get(j);
                if (area2.getAreaType() == 1) {
                    if (polygonOverlapService.checkPolygonOverlap(
                            area1.getFencePoints(),
                            area2.getFencePoints())) {
                        return true;
                    }
                }
            }
        }
        return false;
    }
    /**
     * @return
     */
    @Override
    public List<XpElectronicFence> getAvailableList() {
        return lambdaQuery().eq(XpElectronicFence::getStatus, 2).list(); //查询已启用的围栏
    }
    @Override
    public List<XpElectronicFence> getList() {
        return list();
    }
}
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/serviceimpl/XpOpenCityServiceImpl.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/serviceimpl/XpPointServiceImpl.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/serviceimpl/XpRegionServiceImpl.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/serviceimpl/XpSystemSettingServiceImpl.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/utils/PolygonOverlapService.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/utils/TimeRangeChecker.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/utils/map/map/FastDistanceCalculator.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/utils/map/map/GeodesyUtil.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/vo/CustomerServicePhoneVo.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/vo/FileUploadVO.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/vo/IndexDto.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/vo/MetaVo.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/vo/NearestNextVo.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/vo/NearestVo.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/vo/OpenCityListVO.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/vo/OrderDistanceVo.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/vo/PricingPageListVO.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/vo/RegionCascaderVO.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/vo/RegionDistrictSyncResultVO.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/vo/RouterVo.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/vo/SaveOrderVo.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/vo/SpecialPointListVo.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/vo/SpecialPointVo.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/vo/SysOperLogQuery.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/vo/TCompanyToUserVo.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/vo/UserRoleVO.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/vo/ViolationListExportVo.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/vo/XpAgreementVo.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/vo/XpAppVersionVO.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/vo/XpBannerListVo.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/vo/XpCruisePlanDetailVO.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/vo/XpCruisePlanPointVO.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/vo/XpCruisePlanVehicleVO.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/vo/XpOpenCityNextVo.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/vo/XpOpenCityVo.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/vo/XpPricingCardVo.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/vo/XpRideGuideNextVo.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/vo/XpRideGuideVo.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/vo/XpTradingStrategyDetailVO.java
File was deleted
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/vo/XpUserFeedbackVO.java
File was deleted
xp-robotaxi-map-boot/src/main/resources/mapper/XpElectronicFenceMapper.xml
@@ -24,78 +24,5 @@
    <sql id="Base_Column_List">
        id, electronic_name, electronic_number, status, effect_type, effect_time, failure_type, failure_time, operation_strategy, is_deleted, create_time, update_time, create_by, update_by
    </sql>
    <select id="pageList" resultType="com.xiaopeng.api.model.operation.XpElectronicFence">
        select ef.id, ef.electronic_name as electronicName, ef.electronic_number as electronicNumber, ef.status, ef.effect_type as effectType, ef.effect_time as effectTime, ef.failure_type as failureType, ef.failure_time as failureTime, ef.operation_strategy as operationStrategy
        , ef.create_time as createTime, ef.update_time as updateTime, ef.create_by as createBy, ef.update_by as updateBy
        from xp_electronic_fence ef
        left join xp_electronic_fence_area efa on efa.electronic_id = ef.id
        where ef.is_deleted = 0
        <if test="query.electronicNumberOrName != null">
            and( ef.electronic_name like concat('%',#{query.electronicNumberOrName},'%')
            or ef.electronic_number like concat('%',#{query.electronicNumberOrName},'%')
            )
        </if>
        <if test="query.electronicAreaId != null">
            and efa.id = #{query.electronicAreaId}
        </if>
        <if test="query.status != null">
            and ef.status = #{query.status}
        </if>
        <if test="query.createBy != null and query.createBy!=''">
            and ef.create_by like concat('%',#{query.createBy},'%')
        </if>
        <if test="query.createStartTime != null and query.createStartTime!=''">
            and ef.create_time >= #{query.createStartTime}
        </if>
        <if test="query.createEndTime != null and query.createEndTime!=''">
            and #{query.createEndTime} >= ef.create_time
        </if>
        <if test="query.updateBy != null and query.updateBy!=''">
            and ef.update_by like concat('%',#{query.updateBy},'%')
        </if>
        <if test="query.updateStartTime != null and query.updateStartTime!=''">
            and ef.update_time >= #{query.updateStartTime}
        </if>
        <if test="query.updateEndTime != null and query.updateEndTime!=''">
            and #{query.updateEndTime} >= ef.update_time
        </if>
        group by ef.id
        <if test="query.createSort != null and query.updateSort != null">
            order by
            <if test="query.createSort == 1">
                ef.create_time asc,
            </if>
            <if test="query.createSort == 2">
                ef.create_time desc,
            </if>
            <if test="query.updateSort == 1">
                ef.update_time asc
            </if>
            <if test="query.updateSort == 2">
                ef.update_time desc
            </if>
        </if>
        <if test="query.createSort != null">
            order by
            <if test="query.createSort == 1">
                ef.create_time asc
            </if>
            <if test="query.createSort == 2">
                ef.create_time desc
            </if>
        </if>
        <if test="query.updateSort != null">
            order by
            <if test="query.updateSort == 1">
                ef.update_time asc
            </if>
            <if test="query.updateSort == 2">
                ef.update_time desc
            </if>
        </if>
    </select>
</mapper>
xp-robotaxi-map-boot/src/main/resources/mapper/XpPointMapper.xml
File was deleted
xp-robotaxi-map-boot/src/main/resources/mapper/XpRegionMapper.xml
File was deleted
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/ReassignOrderController.java
@@ -1,8 +1,5 @@
package com.xiaopeng.operation.controller;
import com.xiaopeng.api.feignClient.order.XpOrderClient;
import com.xiaopeng.api.feignClient.order.XpReassignOrderClient;
import com.xiaopeng.api.model.order.XpOrderReassign;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.api.dto.operation.ReassignOrderDTO;
import com.xiaopeng.operation.utils.TaskOrderUtil;
@@ -11,8 +8,6 @@
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import java.time.LocalDateTime;
/**
 * token 控制
@@ -24,21 +19,9 @@
public class ReassignOrderController {
    @Autowired
    private TaskOrderUtil taskOrderUtil;
    @Autowired
    private XpReassignOrderClient xpReassignOrderClient;
    @PostMapping("/inner/v1/order/reassignOrder")
    public R<String> reassignOrder(@RequestBody ReassignOrderDTO dto) {
        //新增改派数据
        XpOrderReassign xpOrderReassign = new XpOrderReassign();
        xpOrderReassign.setOrderId(dto.getOrderId());
        xpOrderReassign.setOperationTime(LocalDateTime.now());
        xpOrderReassign.setOldVehicleId(dto.getVehicleId());
        xpOrderReassign.setOldFleetId(dto.getFleetId());
        xpOrderReassign.setReassignReason("异常改派");
        xpReassignOrderClient.saveReassignOrder(xpOrderReassign);
        taskOrderUtil.reassignPushOrder(dto.getCount(),dto.getUid(),dto.getLongitude(),dto.getLatitude(),dto.getOrderNo());
        return R.ok();
    }
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpElectronicFenceController.java
@@ -44,10 +44,136 @@
@RequestMapping("/api/v1/electronicFence")
public class XpElectronicFenceController {
    @Resource
    private IXpElectronicFenceService xpElectronicFenceService;
    @Resource
    private IXpElectronicFenceAreaService xpElectronicFenceAreaService;
    @Resource
    private XpRegionService regionService;
    /**
     * 查询省市管理
     */
    @ApiOperation(value = "查询省市区",response = XpRegion.class)
    @GetMapping(value = "/getRegion")
    public R<List<List<XpRegion>>> geXpRegion() {
        return R.ok(regionService.getXpRegion());
    }
    @ApiOperation(value = "电子围栏管理列表", response = XpElectronicFence.class)
    @PostMapping("/pageList")
    public R<PageInfo<XpElectronicFence>> pageList(@RequestBody ElectronicPageListQuery query) {
        PageInfo<XpElectronicFence> pageList = xpElectronicFenceService.pageList(query);
        return R.ok(pageList);
    }
    /**
     * 电子围栏列表接口
     *
     * @return 电子围栏列表
     */
    @ApiOperation(value = "电子围栏列表接口", tags = {"运维APP-车辆管理"})
    @GetMapping("/api/v1/electronicFence/list")
    public R<List<XpElectronicFence>> vehicleMap() {
        List<XpElectronicFence> list = xpElectronicFenceService.list();
        return R.ok(list);
    }
    /**
     * 新增电子围栏
     */
    @PostMapping("/add")
    @ApiOperation(value = "新增电子围栏")
//    @Transactional
//    @ShardingSphereTransactionType(TransactionType.BASE)
    public R add(@Validated @RequestBody ElectronicFenceAddDto dto) {
        return xpElectronicFenceService.addElectronic(dto);
    }
    /**
     * 修改状态
     */
    @PostMapping("/updateStatus")
    @ResponseBody
    @ApiOperation(value = "修改状态")
//    @Transactional
//    @ShardingSphereTransactionType(TransactionType.BASE)
    public R updateStatus(@RequestBody ElectronicFenceAreaUpdateStatusDto dto) {
        XpElectronicFenceArea electronicFenceArea = xpElectronicFenceAreaService.getById(dto.getId());
        if (electronicFenceArea == null) {
            throw new ServiceException(
                    "围栏构成不存在,请刷新重试",
                    I18nKeyConstant.FENCE_STRUCTURE_NOT_EXIST
            );
        }
        xpElectronicFenceAreaService.updateById(electronicFenceArea);
        return R.ok();
    }
    /**
     * 电子围栏详情
     */
    @PostMapping("/queryById")
    @ApiOperation(value = "电子围栏详情")
    public R<ElectronicFenceDetailVo> queryById(@RequestParam("id")Long id) {
        ElectronicFenceDetailVo res = new ElectronicFenceDetailVo();
        XpElectronicFence electronicFence = xpElectronicFenceService.getById(id);
        if (electronicFence == null) {
            throw new ServiceException(
                    "电子围栏不存在,请刷新重试",
                    I18nKeyConstant.FENCE_NOT_EXIST
            );
        }
        BeanUtils.copyProperties(electronicFence, res);
        List<XpElectronicFenceArea> electronicFenceAreaList = xpElectronicFenceAreaService.lambdaQuery().eq(XpElectronicFenceArea::getElectronicId, id)
                .list();
        res.setElectronicFenceAreas(electronicFenceAreaList);
        return R.ok(res);
    }
    /**
     * 编辑电子围栏
     */
    @PostMapping("/edit")
    @ApiOperation(value = "编辑电子围栏")
//    @Transactional
//    @ShardingSphereTransactionType(TransactionType.BASE)
    public R edit(@Validated @RequestBody ElectronicFenceUpdateDto dto) {
        return xpElectronicFenceService.editElectronic(dto);
    }
    /**
     * 复制电子围栏
     */
    @PostMapping("/copy")
    @ApiOperation(value = "复制电子围栏")
//    @Transactional
//    @ShardingSphereTransactionType(TransactionType.BASE)
    public R<Long> copy(@RequestParam("id") Integer id) {
        XpElectronicFence electronicFence = xpElectronicFenceService.getById(id);
        if (electronicFence.getStatus()==2){
            throw new ServiceException(
                    "当前电子围栏状态为启用中,不可复制",
                    I18nKeyConstant.FENCE_STATUS_CANNOT_COPIED
            );
        }
        electronicFence.setElectronicName("副本_"+electronicFence.getElectronicName());
        electronicFence.setId(null);
        electronicFence.setStatus(0);
        xpElectronicFenceService.save(electronicFence);
        List<XpElectronicFenceArea> electronicFenceAreaList = xpElectronicFenceAreaService.lambdaQuery().eq(XpElectronicFenceArea::getElectronicId, id)
                .list();
        for (XpElectronicFenceArea area : electronicFenceAreaList) {
            area.setId(null);
            area.setElectronicId(electronicFence.getId());
            area.setAreaStatus(2);
            area.setAreaName("副本_"+area.getAreaName());
        }
        xpElectronicFenceAreaService.saveBatch(electronicFenceAreaList);
        return R.ok(electronicFence.getId());
    }
    /**
     * 根据ID列表批量查询电子围栏
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpInvitationCodeController.java
@@ -58,7 +58,7 @@
@RestController
@Api(tags = "邀请码管理")
@Slf4j
@RequestMapping("/api/v1/invitation")
@RequestMapping("")
public class XpInvitationCodeController {
    @Resource
    private IXpInvitationCodeService xpInvitationCodeService;
@@ -66,7 +66,7 @@
    private IXpWhitelistService xpWhitelistService;
    @ApiOperation(value = "邀请码管理分页列表",response = XpInvitationCode.class)
    @PostMapping("/pageList")
    @PostMapping("/api/v1/invitation/pageList")
    public R<PageInfo<XpInvitationCode>> pageList(@RequestBody InvitationPageListQuery query) {
        PageInfo<XpInvitationCode> pageList = xpInvitationCodeService.pageList(query);
        return R.ok(pageList);
@@ -74,7 +74,7 @@
    /**
     * 生成邀请码
     */
    @PutMapping("/add")
    @PutMapping("/api/v1/invitation/add")
    @ResponseBody
    @ApiOperation(value = "生成邀请码")
    @ApiImplicitParams({
@@ -87,7 +87,7 @@
    /**
     * 解绑
     */
    @PutMapping("/unbind")
    @PutMapping("/api/v1/invitation/unbind")
    @ResponseBody
    @ApiOperation(value = "解绑")
    @ApiImplicitParams({
@@ -102,7 +102,7 @@
        return R.ok();
    }
    @ApiOperation(value = "点位导入模板下载")
    @GetMapping("/import-template")
    @GetMapping("/api/v1/invitation/import-template")
    public void importTemplate() {
        List<InvitationCodeImportExcel> invitationCodeImportExcels = new ArrayList<>();
        InvitationCodeImportExcel invitationCodeImportExcel = new InvitationCodeImportExcel();
@@ -130,7 +130,7 @@
        }
    }
    @ApiOperation(value = "邀请码导入")
    @PostMapping("/importExcel")
    @PostMapping("/base/v1/invitation/importExcel")
    public R<String> importExcel(@RequestPart("file") MultipartFile file) {
        ImportParams params = new ImportParams();
        params.setHeadRows(1); //表头行数
@@ -203,7 +203,7 @@
        return R.ok();
    }
    @ApiOperation(value = "邀请码导出")
    @PostMapping(value = "/exportExcel")
    @PostMapping(value = "/api/v1/invitation/exportExcel")
    public void exportExcel(@RequestBody InvitationPageListQuery query) {
        List<XpInvitationCode> list = xpInvitationCodeService.exportList(query);
        List<XpInvitationCodeExportExcel> xpWhitelistExportExcels = new ArrayList<>();
@@ -244,7 +244,7 @@
    /**
     * 批量删除
     */
    @GetMapping("/deleteByIds")
    @GetMapping("/api/v1/invitation/deleteByIds")
    @ResponseBody
    @ApiOperation(value = "批量删除")
    public R deleteByIds(String ids){
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpPointManagementController.java
@@ -43,6 +43,104 @@
    @Resource
    private  XpPointService xpPointService;
    @Resource
    private  IXpElectronicFenceAreaService xpElectronicFenceAreaService;
    @Resource
    private  IXpElectronicFenceService xpElectronicFenceService;
    @ApiOperation(value = "获取所有运营中的区域", response = XpElectronicFenceArea.class)
    @PostMapping("/listElectronicFenceArea")
    public R<List<XpElectronicFenceArea>> listElectronicFenceArea() {
        // 获取所有启用的电子围栏
        List<XpElectronicFence> electronicFences = xpElectronicFenceService.lambdaQuery().eq(XpElectronicFence::getStatus, 2).list();
        List<Long> electronicFenceIds = electronicFences.stream().map(XpElectronicFence::getId).collect(Collectors.toList());
        if (electronicFenceIds.isEmpty()){
            return R.ok(new ArrayList<XpElectronicFenceArea>());
        }
        // 获取电子围栏下启用的运营区域
        List<XpElectronicFenceArea> electronicFenceAreaList = xpElectronicFenceAreaService.lambdaQuery().in(XpElectronicFenceArea::getElectronicId, electronicFenceIds)
                .eq(XpElectronicFenceArea::getAreaStatus, 1).list();
        return R.ok(electronicFenceAreaList);
    }
    @ApiOperation(value = "点位管理列表", response = XpPoint.class)
    @PostMapping("/listPoint")
    public R<List<XpPoint>> list(@RequestBody PointListQuery query) {
        List<XpPoint> pageList = xpPointService.listAll(query);
        return R.ok(pageList);
    }
    @ApiOperation(value = "点位管理分页列表", response = XpPoint.class)
    @PostMapping("/pageList")
    public R<PageInfo<XpPoint>> pageList(@RequestBody PointPageListListQuery query) {
        PageInfo<XpPoint> pageList = xpPointService.pageList(query);
        return R.ok(pageList);
    }
    @PostMapping("/getByIds")
    public R<List<XpPoint>> getByIds(@RequestBody XpPointExportExcelQuery query){
        List<XpPoint> list = xpPointService.lambdaQuery().in(XpPoint::getId, query.getPointIds()).list();
        return R.ok(list);
    }
    /**
     * 新增点位
     */
    @PostMapping("/addPoint")
    @ResponseBody
    @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();
    }
    /**
     * 批量删除点位
     */
    @GetMapping("/deletePoint")
    @ResponseBody
    @ApiOperation(value = "删除点位")
//    @Transactional
//    @ShardingSphereTransactionType(TransactionType.BASE)
    public R deletePoint(@RequestParam("ids") String ids) {
        xpPointService.removeBatchByIds(Arrays.stream(ids.split(",")).map(Long::parseLong).collect(Collectors.toList()));
        return R.ok();
    }
    /**
     * 编辑点位
     */
    @PostMapping("/editPoint")
    @ApiOperation(value = "编辑点位")
//    @Transactional
//    @ShardingSphereTransactionType(TransactionType.BASE)
    public R edit(@Validated@RequestBody PointUpdateDto pointAddDto) {
        XpPoint xpPoint = new XpPoint();
        BeanUtils.copyProperties(pointAddDto, xpPoint);
        xpPointService.updateById(xpPoint);
        return R.ok();
    }
    /**
     * 点位详情
     */
    @GetMapping("/queryPointById")
    @ApiOperation(value = "点位详情")
    public R<XpPoint> queryById(@RequestParam Long id) {
        return R.ok(xpPointService.getById(id));
    }
    /**
     * 启用/禁用
     */
    @PostMapping("/enableDisablePoint")
    @ApiOperation(value = "启用/禁用")
//    @Transactional
//    @ShardingSphereTransactionType(TransactionType.BASE)
    public R enableDisable(@RequestBody XpPointEnableDisableDto dto) {
        XpPoint xpPoint = xpPointService.getById(dto.getId());
        xpPoint.setOperationStatus(dto.getOperationStatus());
        xpPoint.setElectronicAreaId(null);
        xpPointService.updateById(xpPoint);
        return R.ok();
    }
    /**
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/controller/XpOrderController.java
@@ -10,7 +10,6 @@
import com.xiaopeng.api.dto.statistics.OrderStatisticsDTO;
import com.xiaopeng.api.dto.statistics.StatisticsQueryDTO;
import com.xiaopeng.api.model.order.XpOrder;
import com.xiaopeng.api.model.order.XpOrderReassign;
import com.xiaopeng.api.model.vehicleConvoy.XpVehicle;
import com.xiaopeng.api.vo.operation.RouteVo;
import com.xiaopeng.api.vo.order.FareBreakdownVo;
@@ -33,7 +32,6 @@
import com.xiaopeng.order.model.vo.XpOrderDetailVO;
import com.xiaopeng.order.model.vo.XpOrderHistoryVO;
import com.xiaopeng.order.model.vo.XpOrderPageVO;
import com.xiaopeng.order.service.IXpOrderReassignService;
import com.xiaopeng.order.service.IXpOrderService;
import com.xiaopeng.order.vo.OrderDetailVo;
import com.xiaopeng.unifiedverification.interceptor.XpClientCheck;
@@ -69,7 +67,6 @@
    private final IXpOrderService xpOrderService;
    private final RedisService redisService;
    private final IXpOrderReassignService   xpOrderReassignService;
    /**
     * 获取订单统计数据(内部接口)
@@ -282,18 +279,6 @@
            dto.getReassignReason()
        );
        return R.ok();
    }
    /**
     * 保存改派
     * @param xpOrderReassign
     * @return
     */
    @PostMapping("/inner/v1/order/reassignOrder")
    public R<Long> saveReassignOrder(@RequestBody XpOrderReassign xpOrderReassign){
        xpOrderReassignService.save(xpOrderReassign);
        return R.ok(xpOrderReassign.getId());
    }
    /**
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderEvaluateServiceImpl.java
@@ -11,7 +11,6 @@
import com.xiaopeng.api.feignClient.operation.XpSystemSettingClient;
import com.xiaopeng.api.feignClient.vehicleConvoy.XpVehicleClient;
import com.xiaopeng.api.model.account.XpAppUser;
import com.xiaopeng.api.model.operation.XpFeedbackType;
import com.xiaopeng.api.model.operation.XpInvitationCode;
import com.xiaopeng.api.model.vehicleConvoy.XpVehicle;
import com.xiaopeng.api.model.order.XpOrder;
@@ -139,26 +138,22 @@
        GetUserListByUidsVo getUserListByUidsVo = new GetUserListByUidsVo();
        getUserListByUidsVo.setUids(userIds);
        getUserListByUidsVo.setGetPreCarOwner(false);
        // todo 查不到用户信息
//        UserResourcesDto userListByUids = userResourcesClient.getUserListByUids(getUserListByUidsVo);
        UserResourcesDto userListByUids = userResourcesClient.getUserListByUids(getUserListByUidsVo);
        for (OrderEvaluateManagementPageListVO orderEvaluateManagementPageListVO : list) {
//            Object data = userListByUids.getData();
            Object data = userListByUids.getData();
            // 转化为jsonArray
//            JSONArray jsonArray = JSON.parseArray(JSON.toJSONString(data));
//            for (Object o : jsonArray) {
//                // 转化为JsonObject
//                JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(o));
//                String mobile = jsonObject.getString("mobile");
//                String nickName = jsonObject.getString("nickName");
//                String headImage = jsonObject.getString("headImage");
//                orderEvaluateManagementPageListVO.setPhoneNumber(mobile);
//                orderEvaluateManagementPageListVO.setNickName(nickName);
//                orderEvaluateManagementPageListVO.setHeadImage(headImage);
//            }
            XpFeedbackType feedbackType = systemSettingClient.getFeedbackTypeById(orderEvaluateManagementPageListVO.getFeedbackTypeId()).getData();
            if (feedbackType!=null){
                orderEvaluateManagementPageListVO.setFeedbackTypeName(feedbackType.getFeedbackType());
            JSONArray jsonArray = JSON.parseArray(JSON.toJSONString(data));
            for (Object o : jsonArray) {
                // 转化为JsonObject
                JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(o));
                String mobile = jsonObject.getString("mobile");
                String nickName = jsonObject.getString("nickName");
                String headImage = jsonObject.getString("headImage");
                orderEvaluateManagementPageListVO.setPhoneNumber(mobile);
                orderEvaluateManagementPageListVO.setNickName(nickName);
                orderEvaluateManagementPageListVO.setHeadImage(headImage);
            }
            systemSettingClient.getFeedbackTypeById(orderEvaluateManagementPageListVO.getFeedbackTypeId());
        }
        pageInfo.setRecords(list);
        return pageInfo;
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java
@@ -870,7 +870,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;
        }
@@ -894,7 +894,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());
@@ -903,7 +903,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());
@@ -933,13 +933,13 @@
    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);
        }
        order.setStatus(0);
@@ -949,7 +949,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());
@@ -958,7 +958,7 @@
        cancelTaxiPassengerVo.setAppId("");
        BaseVehicleUserDto baseVehicleUserDto = userVehicleClient.cancelTaxiPassenger(cancelTaxiPassengerVo);
        if (baseVehicleUserDto == null) {
        if (baseVehicleUserDto==null) {
            // TODO 本地无法调通
//            throw new RuntimeException("取消订单失败");
        }
@@ -982,7 +982,7 @@
        }
        // 下发命令
        if (order.getStatus() > 1) {
        if(order.getStatus()>1){
            PushOrderDto pushOrderDto = new PushOrderDto();
            pushOrderDto.setOrderId(order.getId().toString());
            pushOrderDto.setVin(xpVehicle.getVehicleVin());
@@ -997,7 +997,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);
        baseMapper.updateById(order);
@@ -1030,7 +1030,7 @@
        log.info("订单取消消息推送完毕");
        // 下发命令
        if (order.getStatus() > 1) {
        if(order.getStatus()>1){
            PushOrderDto pushOrderDto = new PushOrderDto();
            pushOrderDto.setOrderId(order.getId().toString());
            pushOrderDto.setVin(xpVehicle.getVehicleVin());
@@ -1051,13 +1051,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);
@@ -1176,6 +1176,7 @@
        }
        // 根据订单所属开通城市id 查询定价
        R<XpPricing> pricingByCityId = xpPricingClient.getPricingByCid(order.getCityId());
        XpPricing pricing = pricingByCityId.getData();
@@ -1194,13 +1195,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"))));
@@ -1235,7 +1236,7 @@
        System.err.println("--------------------------");
        System.err.println("应付总额: " + totalAmount + " 元");
        BigDecimal startMoney = BigDecimal.ZERO;
        // 默认费率1
         // 默认费率1
        double priceRate = 1;
        if (pricing.getIsDynamicPrice() == 1) {
            // 先判断是否已经调价过了
@@ -1383,11 +1384,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());
@@ -1397,7 +1398,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);
@@ -1410,7 +1411,7 @@
            useUserCouponDto.setUserCouponId(order.getCouponId());
            xpAppUserCouponClient.useUserCoupon(useUserCouponDto);
        }
        // 计算完价格后 挑选优惠券
       // 计算完价格后 挑选优惠券
        GetUserCouponDto getUserCouponDto = new GetUserCouponDto();
        getUserCouponDto.setUserId(Long.valueOf(uid));
        getUserCouponDto.setTotalAmount(order.getOrderMoney().doubleValue());
@@ -1424,8 +1425,11 @@
        baseMapper.updateById(order);
        // 结束后的车辆操作
        if (vehicle != null) {
        if(vehicle!=null){
            // 修改车辆状态
            vehicle.setState(0);
@@ -1435,11 +1439,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());
@@ -1453,12 +1457,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());
@@ -1469,7 +1473,7 @@
            xpCruiseOrder.setStatus(1);
            xpCruiseOrder.setLastOrderId(xpCruiseOrders.getId());
            xpCruiseOrder.setCreateTime(LocalDateTime.now());
            xpCruiseOrder.setId("XU" + IdUtil.fastUUID());
            xpCruiseOrder.setId("XU"+ IdUtil.fastUUID());
            // 判断当前时分秒是否大于收车时间
            LocalTime vehicleCollectionTime = xpTaskRule.getVehicleCollectionTime();
@@ -1502,6 +1506,15 @@
        }
    }
@@ -1726,14 +1739,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());
@@ -1742,24 +1755,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);
@@ -1912,7 +1925,7 @@
        XpPricing pricing = pricingByCityId.getData();
        if (pricing == null) {
            throw new ServiceException("当前城市未配置定价规则", I18nKeyConstant.ORDER_PRICING_NOT_EXISTS);
        } else {
        }else{
            return R.ok(pricing.getPriceRule());
        }
    }
@@ -1930,34 +1943,17 @@
        String orderType = dto.getOrderType();
        Long orderId = dto.getOrderId();
        //巡游单处理逻辑
        if (OrderType.CRUISE_ORDER.equals(orderType)) {
        if(OrderType.CRUISE_ORDER.equals(orderType)){
            // todo 需要处理巡游的逻辑
        }
        //乘客单处理逻辑
        if (OrderType.USER_ORDER.equals(orderType)) {
        if(OrderType.USER_ORDER.equals(orderType)){
            XpOrder order = this.getById(orderId);
            // 判断是否改派的 查看是否有车信息
            if (order.getVehicleId() != null) {
                R<XpVehicle> oldVehicleR = xpVehicleClient.queryById(order.getVehicleId());
                XpVehicle oldVehicle = oldVehicleR.getData();
                if (oldVehicle != null) {
                    // 解绑
                    CancelTaxiPassengerVo cancelTaxiPassengerVo = new CancelTaxiPassengerVo();
                    cancelTaxiPassengerVo.setVin(oldVehicle.getVehicleVin());
                    cancelTaxiPassengerVo.setUid(order.getAppUserId().toString());
                    cancelTaxiPassengerVo.setOrderNo(order.getOrderNumber());
                    // TODO
                    cancelTaxiPassengerVo.setAppId("");
                    userVehicleClient.cancelTaxiPassenger(cancelTaxiPassengerVo);
                }
            }
            //订单为待接单状态
            if (order.getStatus() == 1) {
            if(order.getStatus() == 1){
                AddTaxiPassengerVo addTaxiPassengerVo = new AddTaxiPassengerVo();
                order.setAcceptanceTime(LocalDateTime.now());
                R<XpVehicle> byVehicleVin = xpVehicleClient.findByVehicleVin(dto.getXpVehicleVin());
@@ -1992,7 +1988,7 @@
                userVehicleClient.addTaxiPassenger(addTaxiPassengerVo);
                //推送乘客车辆到达预约点的导航数据
                sendRoute(order.getAppUserId().toString(), orderId, "ORDER_NAVIGATION_START_DATA");
            } else {
            }else{
                //推送行起点到终点的驶轨迹给乘客端
                sendRoute(order.getAppUserId().toString(), orderId, "ORDER_NAVIGATION_END_DATA");
            }
@@ -2005,9 +2001,9 @@
     * @param appUserId
     * @param keyStr
     */
    public void sendRoute(String appUserId, Long orderId, String keyStr) {
    public void sendRoute(String appUserId, Long orderId, String keyStr){
        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");
@@ -2020,7 +2016,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());
@@ -2038,6 +2034,8 @@
    }
    /**
     * 获取当前用户正在执行的订单
     *
@@ -2047,7 +2045,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;
        }